From 25a556b49a40f041982e9ab31695dd97c1701e76 Mon Sep 17 00:00:00 2001 From: Adrian Stobbe Date: Wed, 20 Sep 2023 14:31:48 +0200 Subject: [PATCH] make cache window size customizable for e2e test --- .../attestationconfigapi/cli/e2e/test.sh.in | 26 +++++++------- internal/api/attestationconfigapi/cli/main.go | 36 ++++++++++++------- internal/api/attestationconfigapi/client.go | 18 +++++----- internal/api/attestationconfigapi/reporter.go | 13 +++---- 4 files changed, 53 insertions(+), 40 deletions(-) diff --git a/internal/api/attestationconfigapi/cli/e2e/test.sh.in b/internal/api/attestationconfigapi/cli/e2e/test.sh.in index f5a2bcd17b..ef13d40d11 100755 --- a/internal/api/attestationconfigapi/cli/e2e/test.sh.in +++ b/internal/api/attestationconfigapi/cli/e2e/test.sh.in @@ -55,22 +55,22 @@ cat << EOF > "$older_claim_path" EOF # report 3 versions with different dates to fill the reporter cache -readonly date_yet_older="2023-02-01-03-04" -${configapi_cli} --maa-claims-path "$older_claim_path" --upload-date "$date_yet_older" --region "$region" --bucket "$bucket" --distribution "$distribution" +readonly date_oldest="2023-02-01-03-04" +${configapi_cli} --maa-claims-path "$older_claim_path" --upload-date "$date_oldest" --region "$region" --bucket "$bucket" --distribution "$distribution" --cache-window-size 3 readonly date_older="2023-02-02-03-04" -${configapi_cli} --maa-claims-path "$older_claim_path" --upload-date "$date_older" --region "$region" --bucket "$bucket" --distribution "$distribution" +${configapi_cli} --maa-claims-path "$older_claim_path" --upload-date "$date_older" --region "$region" --bucket "$bucket" --distribution "$distribution" --cache-window-size 3 readonly date="2023-02-03-03-04" -${configapi_cli} --maa-claims-path "$claim_path" --upload-date "$date" --region "$region" --bucket "$bucket" --distribution "$distribution" +${configapi_cli} --maa-claims-path "$claim_path" --upload-date "$date" --region "$region" --bucket "$bucket" --distribution "$distribution" --cache-window-size 3 # expect that the older version was expected as new latest version baseurl="https://d33dzgxuwsgbpw.cloudfront.net/constellation/v1/attestation/azure-sev-snp" -if ! curl -fsSL ${baseurl}/${date_yet_older}.json > /dev/null; then - echo "Checking for uploaded version file constellation/v1/attestation/azure-sev-snp/${date_yet_older}.json: request returned ${?}" +if ! curl -fsSL ${baseurl}/${date_oldest}.json > /dev/null; then + echo "Checking for uploaded version file constellation/v1/attestation/azure-sev-snp/${date_oldest}.json: request returned ${?}" exit 1 fi -if ! curl -fsSL ${baseurl}/${date_yet_older}.json.sig > /dev/null; then - echo "Checking for uploaded version signature file constellation/v1/attestation/azure-sev-snp/${date_yet_older}.json.sig: request returned ${?}" +if ! curl -fsSL ${baseurl}/${date_oldest}.json.sig > /dev/null; then + echo "Checking for uploaded version signature file constellation/v1/attestation/azure-sev-snp/${date_oldest}.json.sig: request returned ${?}" exit 1 fi @@ -78,17 +78,17 @@ if ! curl -fsSL ${baseurl}/list > /dev/null; then echo "Checking for uploaded list file constellation/v1/attestation/azure-sev-snp/list: request returned ${?}" exit 1 fi -${configapi_cli} delete --version "$date_yet_older" --region "$region" --bucket "$bucket" --distribution "$distribution" +${configapi_cli} delete --version "$date_oldest" --region "$region" --bucket "$bucket" --distribution "$distribution" # Omit -f to check for 404. We want to check that a file was deleted, therefore we expect the query to fail. -http_code=$(curl -sSL -w '%{http_code}\n' -o /dev/null ${baseurl}/${date_yet_older}.json) +http_code=$(curl -sSL -w '%{http_code}\n' -o /dev/null ${baseurl}/${date_oldest}.json) if [[ $http_code -ne 404 ]]; then - echo "Expected HTTP code 404 for: constellation/v1/attestation/azure-sev-snp/${date_yet_older}.json, but got ${http_code}" + echo "Expected HTTP code 404 for: constellation/v1/attestation/azure-sev-snp/${date_oldest}.json, but got ${http_code}" exit 1 fi # Omit -f to check for 404. We want to check that a file was deleted, therefore we expect the query to fail. -http_code=$(curl -sSL -w '%{http_code}\n' -o /dev/null ${baseurl}/${date_yet_older}.json.sig) +http_code=$(curl -sSL -w '%{http_code}\n' -o /dev/null ${baseurl}/${date_oldest}.json.sig) if [[ $http_code -ne 404 ]]; then - echo "Expected HTTP code 404 for: constellation/v1/attestation/azure-sev-snp/${date_yet_older}.json, but got ${http_code}" + echo "Expected HTTP code 404 for: constellation/v1/attestation/azure-sev-snp/${date_oldest}.json, but got ${http_code}" exit 1 fi diff --git a/internal/api/attestationconfigapi/cli/main.go b/internal/api/attestationconfigapi/cli/main.go index b5e6cac7bf..e2aa7f4c1e 100644 --- a/internal/api/attestationconfigapi/cli/main.go +++ b/internal/api/attestationconfigapi/cli/main.go @@ -74,8 +74,9 @@ func newRootCmd() *cobra.Command { rootCmd.PersistentFlags().StringP("bucket", "b", awsBucket, "bucket targeted by all operations.") rootCmd.PersistentFlags().StringP("distribution", "i", distributionID, "cloudflare distribution used.") must(rootCmd.MarkFlagRequired("maa-claims-path")) - rootCmd.PersistentFlags().BoolP("force", "f", false, "Use force to manually push a new latest version."+ + rootCmd.LocalFlags().BoolP("force", "f", false, "Use force to manually push a new latest version."+ " The version gets reported in the cache but the version selection logic is skipped.") + rootCmd.LocalFlags().IntP("cache-window-size", "s", 0, "Number of versions to be considered for the latest version.") rootCmd.AddCommand(newDeleteCmd()) return rootCmd } @@ -129,6 +130,9 @@ func runCmd(cmd *cobra.Command, _ []string) (retErr error) { retErr = errors.Join(retErr, fmt.Errorf("failed to invalidate cache: %w", err)) } }() + if flags.cacheWindowSize != 0 { + client.SetCacheVersionSize(flags.cacheWindowSize) + } if err != nil { return fmt.Errorf("creating client: %w", err) @@ -143,12 +147,13 @@ func runCmd(cmd *cobra.Command, _ []string) (retErr error) { } type cliFlags struct { - maaFilePath string - uploadDate time.Time - region string - bucket string - distribution string - force bool + maaFilePath string + uploadDate time.Time + region string + bucket string + distribution string + force bool + cacheWindowSize int } func parseCliFlags(cmd *cobra.Command) (cliFlags, error) { @@ -189,13 +194,18 @@ func parseCliFlags(cmd *cobra.Command) (cliFlags, error) { return cliFlags{}, fmt.Errorf("getting force: %w", err) } + cacheWindowSize, err := cmd.Flags().GetInt("cache-window-size") + if err != nil { + return cliFlags{}, fmt.Errorf("getting cache window size: %w", err) + } return cliFlags{ - maaFilePath: maaFilePath, - uploadDate: uploadDate, - region: region, - bucket: bucket, - distribution: distribution, - force: force, + maaFilePath: maaFilePath, + uploadDate: uploadDate, + region: region, + bucket: bucket, + distribution: distribution, + force: force, + cacheWindowSize: cacheWindowSize, }, nil } diff --git a/internal/api/attestationconfigapi/client.go b/internal/api/attestationconfigapi/client.go index b91edac5a5..0794d52f32 100644 --- a/internal/api/attestationconfigapi/client.go +++ b/internal/api/attestationconfigapi/client.go @@ -22,10 +22,11 @@ const VersionFormat = "2006-01-02-15-04" // Client manages (modifies) the version information for the attestation variants. type Client struct { - s3Client *apiclient.Client - s3ClientClose func(ctx context.Context) error - bucketID string - signer sigstore.Signer + s3Client *apiclient.Client + s3ClientClose func(ctx context.Context) error + bucketID string + signer sigstore.Signer + cacheWindowSize int } // NewClient returns a new Client. @@ -36,10 +37,11 @@ func NewClient(ctx context.Context, cfg staticupload.Config, cosignPwd, privateK } repo := &Client{ - s3Client: s3Client, - s3ClientClose: clientClose, - signer: sigstore.NewSigner(cosignPwd, privateKey), - bucketID: cfg.Bucket, + s3Client: s3Client, + s3ClientClose: clientClose, + signer: sigstore.NewSigner(cosignPwd, privateKey), + bucketID: cfg.Bucket, + cacheWindowSize: versionWindowSize, } return repo, clientClose, nil } diff --git a/internal/api/attestationconfigapi/reporter.go b/internal/api/attestationconfigapi/reporter.go index 2810673acb..2219468f02 100644 --- a/internal/api/attestationconfigapi/reporter.go +++ b/internal/api/attestationconfigapi/reporter.go @@ -26,15 +26,11 @@ import ( ) // cachedVersionsSubDir is the subdirectory in the bucket where the cached versions are stored. -// TODO(elchead): store in a different directory so that it is not mirrored to the CDN? const cachedVersionsSubDir = "cached-versions" // versionWindowSize defines the number of versions to be considered for the latest version. Each week 5 versions are uploaded for each node of the verify cluster. const versionWindowSize = 15 -// timeFrameForCachedVersions defines the time frame for reported versions which are considered to define the latest version. -const timeFrameForCachedVersions = 21 * 24 * time.Hour - var reportVersionDir = path.Join(attestationURLPath, variant.AzureSEVSNP{}.String(), cachedVersionsSubDir) // UpdateLatestVersion reports the given version, checks the reported version values @@ -52,7 +48,7 @@ func (c Client) UpdateLatestVersion(ctx context.Context, inputVersion, } return nil } - versionDates, err := c.listReportedVersions(ctx, timeFrameForCachedVersions, now) + versionDates, err := c.listReportedVersions(ctx) if err != nil { return fmt.Errorf("list reported versions: %w", err) } @@ -81,6 +77,11 @@ func (c Client) UpdateLatestVersion(ctx context.Context, inputVersion, return nil } +// SetCacheVersionSize sets a custom number of versions to be considered for the latest version. +func (c *Client) SetCacheVersionSize(size int) { + c.cacheWindowSize = size +} + // reportAzureSEVSNPVersion uploads the latest observed version numbers of the Azure SEVSNP. This version is used to later report the latest version numbers to the API. func (c Client) reportAzureSEVSNPVersion(ctx context.Context, version AzureSEVSNPVersion, date time.Time) error { dateStr := date.Format(VersionFormat) + ".json" @@ -90,7 +91,7 @@ func (c Client) reportAzureSEVSNPVersion(ctx context.Context, version AzureSEVSN return res.Execute(ctx, c.s3Client) } -func (c Client) listReportedVersions(ctx context.Context, _ time.Duration, _ time.Time) ([]string, error) { +func (c Client) listReportedVersions(ctx context.Context) ([]string, error) { list, err := c.s3Client.ListObjectsV2(ctx, &s3.ListObjectsV2Input{ Bucket: aws.String(c.bucketID), Prefix: aws.String(reportVersionDir),