Skip to content

Commit

Permalink
recursive delete e2e
Browse files Browse the repository at this point in the history
  • Loading branch information
elchead committed Sep 22, 2023
1 parent 7a2c1f2 commit 64416bd
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 7 deletions.
3 changes: 3 additions & 0 deletions internal/api/attestationconfigapi/cli/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ go_library(
"//internal/constants",
"//internal/logger",
"//internal/staticupload",
"@com_github_aws_aws_sdk_go//aws",
"@com_github_aws_aws_sdk_go//aws/session",
"@com_github_aws_aws_sdk_go//service/s3",
"@com_github_spf13_cobra//:cobra",
"@org_uber_go_zap//:zap",
],
Expand Down
65 changes: 65 additions & 0 deletions internal/api/attestationconfigapi/cli/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ import (
"context"
"errors"
"fmt"
"os"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3"
"github.com/edgelesssys/constellation/v2/internal/api/attestationconfigapi"
"github.com/edgelesssys/constellation/v2/internal/logger"
"github.com/edgelesssys/constellation/v2/internal/staticupload"
Expand All @@ -27,6 +31,13 @@ func newDeleteCmd() *cobra.Command {
}
cmd.Flags().StringP("version", "v", "", "Name of the version to delete (without .json suffix)")
must(cmd.MarkFlagRequired("version"))

recursivelyCmd := &cobra.Command{
Use: "recursive",
Short: "delete all objects from the API path",
RunE: runRecursiveDelete,
}
cmd.AddCommand(recursivelyCmd)
return cmd
}

Expand Down Expand Up @@ -85,3 +96,57 @@ func runDelete(cmd *cobra.Command, _ []string) (retErr error) {
}
return deleteCmd.delete(cmd)
}

func runRecursiveDelete(cmd *cobra.Command, _ []string) (retErr error) {
region, err := cmd.Flags().GetString("region")
if err != nil {
return fmt.Errorf("getting region: %w", err)
}

bucket, err := cmd.Flags().GetString("bucket")
if err != nil {
return fmt.Errorf("getting bucket: %w", err)
}

sess, err := session.NewSession(&aws.Config{
Region: aws.String(region),
})
if err != nil {
return
}

// Create an S3 client.
svc := s3.New(sess)

path := "constellation/v1/attestation/azure-sev-snp"
// List all objects in the path.
resp, err := svc.ListObjectsV2(&s3.ListObjectsV2Input{
Bucket: aws.String(bucket),
Prefix: aws.String(path),
})
if err != nil {
fmt.Println("Error listing objects:", err)
os.Exit(1)
}

// Delete all objects in the path.
var keys []*s3.ObjectIdentifier
for _, obj := range resp.Contents {
keys = append(keys, &s3.ObjectIdentifier{
Key: obj.Key,
})
}
if len(keys) > 0 {
_, err = svc.DeleteObjects(&s3.DeleteObjectsInput{
Bucket: aws.String(bucket),
Delete: &s3.Delete{
Objects: keys,
Quiet: aws.Bool(true),
},
})
if err != nil {
return err
}
}
return nil
}
28 changes: 23 additions & 5 deletions internal/api/attestationconfigapi/cli/e2e/test.sh.in
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,24 @@ tmpdir=$(mktemp -d)
readonly tmpdir
registerExitHandler "rm -rf $tmpdir"

# empty the bucket version state
${configapi_cli} delete recursive --region "$region" --bucket "$bucket" --distribution "$distribution"

# the high version numbers ensure that it's newer than the current latest value
readonly current_claim_path="$tmpdir/currentMaaClaim.json"
cat << EOF > "$current_claim_path"
{
"x-ms-isolation-tee": {
"x-ms-sevsnpvm-tee-svn": 1,
"x-ms-sevsnpvm-snpfw-svn": 1,
"x-ms-sevsnpvm-microcode-svn": 1,
"x-ms-sevsnpvm-bootloader-svn": 1
}
}
EOF
# upload a fake latest version for the fetcher
${configapi_cli} --force --maa-claims-path "$current_claim_path" --upload-date "2000-01-01-01-01" --region "$region" --bucket "$bucket" --distribution "$distribution"

# the high version numbers ensure that it's newer than the current latest value
readonly claim_path="$tmpdir/maaClaim.json"
cat << EOF > "$claim_path"
Expand Down Expand Up @@ -70,11 +88,11 @@ if ! curl -fsSL ${baseurl}/${date_oldest}.json > version.json; then
fi
# check that version values are equal to expected
if ! cmp -s <(echo -n '{"bootloader":255,"tee":255,"snp":255,"microcode":254}') version.json; then
echo "The version content:"
cat version.json
echo " is not equal to the expected version content:"
echo '{"bootloader":255,"tee":255,"snp":255,"microcode":254}'
exit 1
echo "The version content:"
cat version.json
echo " is not equal to the expected version content:"
echo '{"bootloader":255,"tee":255,"snp":255,"microcode":254}'
exit 1
fi
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 ${?}"
Expand Down
4 changes: 4 additions & 0 deletions internal/api/attestationconfigapi/cli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ func runCmd(cmd *cobra.Command, _ []string) (retErr error) {
return fmt.Errorf("creating client: %w", err)
}
if err := client.UploadAzureSEVSNPVersionLatest(ctx, inputVersion, latestAPIVersion, flags.uploadDate, flags.force); err != nil {
if errors.Is(err, attestationconfigapi.ErrNoNewerVersion) {
log.Infof("Input version: %+v is not newer than latest API version: %+v", inputVersion, latestAPIVersion)
return nil
}
return fmt.Errorf("updating latest version: %w", err)
}
return nil
Expand Down
6 changes: 6 additions & 0 deletions internal/api/attestationconfigapi/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ package attestationconfigapi

import (
"context"
"errors"
"fmt"
"time"

apiclient "github.com/edgelesssys/constellation/v2/internal/api/client"
"github.com/edgelesssys/constellation/v2/internal/attestation/variant"
"github.com/edgelesssys/constellation/v2/internal/logger"
"github.com/edgelesssys/constellation/v2/internal/sigstore"

"github.com/edgelesssys/constellation/v2/internal/staticupload"
)

Expand Down Expand Up @@ -75,6 +77,10 @@ func (a Client) List(ctx context.Context, attestation variant.Variant) ([]string
if attestation.Equal(variant.AzureSEVSNP{}) {
versions, err := apiclient.Fetch(ctx, a.s3Client, AzureSEVSNPVersionList{})
if err != nil {
var notFoundErr *apiclient.NotFoundError
if errors.As(err, &notFoundErr) {
return nil, nil
}
return nil, err
}
return versions, nil
Expand Down
9 changes: 7 additions & 2 deletions internal/api/attestationconfigapi/reporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ package attestationconfigapi

import (
"context"
"errors"
"fmt"
"path"
"sort"
Expand All @@ -33,6 +34,9 @@ const versionWindowSize = 15

var reportVersionDir = path.Join(attestationURLPath, variant.AzureSEVSNP{}.String(), cachedVersionsSubDir)

// ErrNoNewerVersion is returned if the input version is not newer than the latest API version.
var ErrNoNewerVersion = errors.New("input version is not newer than latest API version")

// UploadAzureSEVSNPVersionLatest saves the given version to the cache, determines the smallest
// TCB version in the cache among the last cacheWindowSize versions and updates
// the latest version in the API if there is an update.
Expand Down Expand Up @@ -61,7 +65,7 @@ func (c Client) UploadAzureSEVSNPVersionLatest(ctx context.Context, inputVersion
c.s3Client.Logger.Infof("Found minimal version: %+v with date: %s", minVersion, minDate)
shouldUpdateAPI, err := isInputNewerThanOtherVersion(minVersion, latestAPIVersion)
if err != nil {
return fmt.Errorf("comparing new and other versions: %w", err)
return ErrNoNewerVersion
}
if !shouldUpdateAPI {
c.s3Client.Logger.Infof("Input version: %+v is not newer than latest API version: %+v", minVersion, latestAPIVersion)
Expand Down Expand Up @@ -115,8 +119,9 @@ func (c Client) listCachedVersions(ctx context.Context) ([]string, error) {
func (c Client) findMinVersion(ctx context.Context, versionDates []string) (AzureSEVSNPVersion, string, error) {
var minimalVersion *AzureSEVSNPVersion
var minimalDate string
sort.Strings(versionDates) // the oldest date with the minimal version should be taken
sort.Sort(sort.Reverse(sort.StringSlice(versionDates))) // sort in reverse order to slice the latest versions
versionDates = versionDates[:c.cacheWindowSize]
sort.Strings(versionDates) // sort with oldest first to to take the minimal version with the oldest date
for _, date := range versionDates {
obj, err := client.Fetch(ctx, c.s3Client, reportedAzureSEVSNPVersionAPI{Version: date + ".json"})
if err != nil {
Expand Down

0 comments on commit 64416bd

Please sign in to comment.