diff --git a/actions/etcdsnapshot/s3bucket.go b/actions/etcdsnapshot/s3bucket.go new file mode 100644 index 000000000..2712f9ef5 --- /dev/null +++ b/actions/etcdsnapshot/s3bucket.go @@ -0,0 +1,111 @@ +package etcdsnapshot + +import ( + "context" + "fmt" + "time" + + "github.com/aws/aws-sdk-go-v2/aws" + awsconfig "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go-v2/credentials" + "github.com/aws/aws-sdk-go-v2/service/s3" + s3types "github.com/aws/aws-sdk-go-v2/service/s3/types" +) + +// awsS3Config builds AWS config using static credentials and region +func awsS3Config(ctx context.Context, region, accessKey, secretKey string) (aws.Config, error) { + creds := credentials.NewStaticCredentialsProvider(accessKey, secretKey, "") + + return awsconfig.LoadDefaultConfig( + ctx, + awsconfig.WithRegion(region), + awsconfig.WithCredentialsProvider(creds), + ) +} + +// CreateS3Bucket creates an S3 bucket and waits until it exists +func CreateS3Bucket(bucketName, region, accessKey, secretKey string) error { + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) + defer cancel() + + cfg, err := awsS3Config(ctx, region, accessKey, secretKey) + if err != nil { + return err + } + + client := s3.NewFromConfig(cfg) + + input := &s3.CreateBucketInput{ + Bucket: &bucketName, + CreateBucketConfiguration: &s3types.CreateBucketConfiguration{ + LocationConstraint: s3types.BucketLocationConstraint(region), + }, + } + + _, err = client.CreateBucket(ctx, input) + if err != nil { + return err + } + + waiter := s3.NewBucketExistsWaiter(client) + return waiter.Wait(ctx, &s3.HeadBucketInput{Bucket: &bucketName}, 2*time.Minute) +} + +// DeleteS3Bucket deletes all objects in the bucket and then deletes the bucket +func DeleteS3Bucket(bucketName, region, accessKey, secretKey string) error { + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute) + defer cancel() + + cfg, err := awsS3Config(ctx, region, accessKey, secretKey) + if err != nil { + return err + } + + client := s3.NewFromConfig(cfg) + + paginator := s3.NewListObjectsV2Paginator(client, &s3.ListObjectsV2Input{ + Bucket: &bucketName, + }) + + for paginator.HasMorePages() { + page, err := paginator.NextPage(ctx) + if err != nil { + return err + } + + if len(page.Contents) == 0 { + continue + } + + objects := make([]s3types.ObjectIdentifier, 0, len(page.Contents)) + for _, obj := range page.Contents { + objects = append(objects, s3types.ObjectIdentifier{Key: obj.Key}) + } + + quiet := true + out, err := client.DeleteObjects(ctx, &s3.DeleteObjectsInput{ + Bucket: &bucketName, + Delete: &s3types.Delete{ + Objects: objects, + Quiet: &quiet, + }, + }) + if err != nil { + return err + } + + if len(out.Errors) > 0 { + return fmt.Errorf("failed to delete one or more S3 objects from bucket %s", bucketName) + } + } + + _, err = client.DeleteBucket(ctx, &s3.DeleteBucketInput{ + Bucket: &bucketName, + }) + if err != nil { + return err + } + + waiter := s3.NewBucketNotExistsWaiter(client) + return waiter.Wait(ctx, &s3.HeadBucketInput{Bucket: &bucketName}, 2*time.Minute) +} diff --git a/actions/go.mod b/actions/go.mod index fe13f1c2f..9dbcf1281 100644 --- a/actions/go.mod +++ b/actions/go.mod @@ -64,6 +64,10 @@ require ( require ( github.com/aws/aws-sdk-go v1.55.8 + github.com/aws/aws-sdk-go-v2 v1.41.5 + github.com/aws/aws-sdk-go-v2/config v1.31.16 + github.com/aws/aws-sdk-go-v2/credentials v1.18.20 + github.com/aws/aws-sdk-go-v2/service/s3 v1.97.3 github.com/pkg/errors v0.9.1 github.com/rancher/norman v0.8.1 github.com/rancher/rancher v0.0.0-20251223145833-24cecce3325e @@ -101,6 +105,20 @@ require ( github.com/Microsoft/go-winio v0.6.2 // indirect github.com/Microsoft/hcsshim v0.12.0-rc.3 // indirect github.com/apparentlymart/go-cidr v1.1.0 // indirect + github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.8 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.12 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.21 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.21 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.22 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.13 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.21 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.21 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.30.0 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.4 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.39.0 // indirect + github.com/aws/smithy-go v1.24.2 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver v3.5.1+incompatible // indirect github.com/blang/semver/v4 v4.0.0 // indirect diff --git a/actions/go.sum b/actions/go.sum index 35418feec..3ccf3f8da 100644 --- a/actions/go.sum +++ b/actions/go.sum @@ -22,6 +22,42 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPd github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/aws/aws-sdk-go v1.55.8 h1:JRmEUbU52aJQZ2AjX4q4Wu7t4uZjOu71uyNmaWlUkJQ= github.com/aws/aws-sdk-go v1.55.8/go.mod h1:ZkViS9AqA6otK+JBBNH2++sx1sgxrPKcSzPPvQkUtXk= +github.com/aws/aws-sdk-go-v2 v1.41.5 h1:dj5kopbwUsVUVFgO4Fi5BIT3t4WyqIDjGKCangnV/yY= +github.com/aws/aws-sdk-go-v2 v1.41.5/go.mod h1:mwsPRE8ceUUpiTgF7QmQIJ7lgsKUPQOUl3o72QBrE1o= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.8 h1:eBMB84YGghSocM7PsjmmPffTa+1FBUeNvGvFou6V/4o= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.8/go.mod h1:lyw7GFp3qENLh7kwzf7iMzAxDn+NzjXEAGjKS2UOKqI= +github.com/aws/aws-sdk-go-v2/config v1.31.16 h1:E4Tz+tJiPc7kGnXwIfCyUj6xHJNpENlY11oKpRTgsjc= +github.com/aws/aws-sdk-go-v2/config v1.31.16/go.mod h1:2S9hBElpCyGMifv14WxQ7EfPumgoeCPZUpuPX8VtW34= +github.com/aws/aws-sdk-go-v2/credentials v1.18.20 h1:KFndAnHd9NUuzikHjQ8D5CfFVO+bgELkmcGY8yAw98Q= +github.com/aws/aws-sdk-go-v2/credentials v1.18.20/go.mod h1:9mCi28a+fmBHSQ0UM79omkz6JtN+PEsvLrnG36uoUv0= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.12 h1:VO3FIM2TDbm0kqp6sFNR0PbioXJb/HzCDW6NtIZpIWE= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.12/go.mod h1:6C39gB8kg82tx3r72muZSrNhHia9rjGkX7ORaS2GKNE= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.21 h1:Rgg6wvjjtX8bNHcvi9OnXWwcE0a2vGpbwmtICOsvcf4= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.21/go.mod h1:A/kJFst/nm//cyqonihbdpQZwiUhhzpqTsdbhDdRF9c= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.21 h1:PEgGVtPoB6NTpPrBgqSE5hE/o47Ij9qk/SEZFbUOe9A= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.21/go.mod h1:p+hz+PRAYlY3zcpJhPwXlLC4C+kqn70WIHwnzAfs6ps= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 h1:WKuaxf++XKWlHWu9ECbMlha8WOEGm0OUEZqm4K/Gcfk= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4/go.mod h1:ZWy7j6v1vWGmPReu0iSGvRiise4YI5SkR3OHKTZ6Wuc= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.22 h1:rWyie/PxDRIdhNf4DzRk0lvjVOqFJuNnO8WwaIRVxzQ= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.22/go.mod h1:zd/JsJ4P7oGfUhXn1VyLqaRZwPmZwg44Jf2dS84Dm3Y= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7 h1:5EniKhLZe4xzL7a+fU3C2tfUN4nWIqlLesfrjkuPFTY= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7/go.mod h1:x0nZssQ3qZSnIcePWLvcoFisRXJzcTVvYpAAdYX8+GI= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.13 h1:JRaIgADQS/U6uXDqlPiefP32yXTda7Kqfx+LgspooZM= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.13/go.mod h1:CEuVn5WqOMilYl+tbccq8+N2ieCy0gVn3OtRb0vBNNM= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.21 h1:c31//R3xgIJMSC8S6hEVq+38DcvUlgFY0FM6mSI5oto= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.21/go.mod h1:r6+pf23ouCB718FUxaqzZdbpYFyDtehyZcmP5KL9FkA= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.21 h1:ZlvrNcHSFFWURB8avufQq9gFsheUgjVD9536obIknfM= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.21/go.mod h1:cv3TNhVrssKR0O/xxLJVRfd2oazSnZnkUeTf6ctUwfQ= +github.com/aws/aws-sdk-go-v2/service/s3 v1.97.3 h1:HwxWTbTrIHm5qY+CAEur0s/figc3qwvLWsNkF4RPToo= +github.com/aws/aws-sdk-go-v2/service/s3 v1.97.3/go.mod h1:uoA43SdFwacedBfSgfFSjjCvYe8aYBS7EnU5GZ/YKMM= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.0 h1:xHXvxst78wBpJFgDW07xllOx0IAzbryrSdM4nMVQ4Dw= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.0/go.mod h1:/e8m+AO6HNPPqMyfKRtzZ9+mBF5/x1Wk8QiDva4m07I= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.4 h1:tBw2Qhf0kj4ZwtsVpDiVRU3zKLvjvjgIjHMKirxXg8M= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.4/go.mod h1:Deq4B7sRM6Awq/xyOBlxBdgW8/Z926KYNNaGMW2lrkA= +github.com/aws/aws-sdk-go-v2/service/sts v1.39.0 h1:C+BRMnasSYFcgDw8o9H5hzehKzXyAb9GY5v/8bP9DUY= +github.com/aws/aws-sdk-go-v2/service/sts v1.39.0/go.mod h1:4EjU+4mIx6+JqKQkruye+CaigV7alL3thVPfDd9VlMs= +github.com/aws/smithy-go v1.24.2 h1:FzA3bu/nt/vDvmnkg+R8Xl46gmzEDam6mZ1hzmwXFng= +github.com/aws/smithy-go v1.24.2/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= diff --git a/go.mod b/go.mod index 1813fe2f7..fc83bf3b4 100644 --- a/go.mod +++ b/go.mod @@ -79,9 +79,9 @@ require ( github.com/Masterminds/semver/v3 v3.4.0 github.com/Masterminds/sprig/v3 v3.3.0 // indirect github.com/aws/aws-sdk-go v1.55.8 - github.com/aws/aws-sdk-go-v2 v1.39.5 // indirect + github.com/aws/aws-sdk-go-v2 v1.41.5 // indirect github.com/aws/aws-sdk-go-v2/config v1.31.16 - github.com/aws/aws-sdk-go-v2/service/s3 v1.69.0 + github.com/aws/aws-sdk-go-v2/service/s3 v1.97.3 github.com/blang/semver v3.5.1+incompatible // indirect github.com/coreos/go-semver v0.3.1 // indirect github.com/creasty/defaults v1.5.2 // indirect @@ -142,21 +142,21 @@ require ( dario.cat/mergo v1.0.1 // indirect github.com/agext/levenshtein v1.2.3 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect - github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7 // indirect + github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.8 // indirect github.com/aws/aws-sdk-go-v2/credentials v1.18.20 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.12 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.12 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.12 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.21 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.21 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 // indirect - github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.24 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.2 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.5 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.12 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.5 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.22 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.13 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.21 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.21 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.30.0 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.4 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.39.0 // indirect - github.com/aws/smithy-go v1.23.1 // indirect + github.com/aws/smithy-go v1.24.2 // indirect github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect github.com/containerd/cgroups/v3 v3.0.2 // indirect github.com/containerd/errdefs v1.0.0 // indirect diff --git a/go.sum b/go.sum index 2a3db0a91..01e08ef9d 100644 --- a/go.sum +++ b/go.sum @@ -1398,42 +1398,42 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPd github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/aws/aws-sdk-go v1.55.8 h1:JRmEUbU52aJQZ2AjX4q4Wu7t4uZjOu71uyNmaWlUkJQ= github.com/aws/aws-sdk-go v1.55.8/go.mod h1:ZkViS9AqA6otK+JBBNH2++sx1sgxrPKcSzPPvQkUtXk= -github.com/aws/aws-sdk-go-v2 v1.39.5 h1:e/SXuia3rkFtapghJROrydtQpfQaaUgd1cUvyO1mp2w= -github.com/aws/aws-sdk-go-v2 v1.39.5/go.mod h1:yWSxrnioGUZ4WVv9TgMrNUeLV3PFESn/v+6T/Su8gnM= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7 h1:lL7IfaFzngfx0ZwUGOZdsFFnQ5uLvR0hWqqhyE7Q9M8= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7/go.mod h1:QraP0UcVlQJsmHfioCrveWOC1nbiWUl3ej08h4mXWoc= +github.com/aws/aws-sdk-go-v2 v1.41.5 h1:dj5kopbwUsVUVFgO4Fi5BIT3t4WyqIDjGKCangnV/yY= +github.com/aws/aws-sdk-go-v2 v1.41.5/go.mod h1:mwsPRE8ceUUpiTgF7QmQIJ7lgsKUPQOUl3o72QBrE1o= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.8 h1:eBMB84YGghSocM7PsjmmPffTa+1FBUeNvGvFou6V/4o= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.8/go.mod h1:lyw7GFp3qENLh7kwzf7iMzAxDn+NzjXEAGjKS2UOKqI= github.com/aws/aws-sdk-go-v2/config v1.31.16 h1:E4Tz+tJiPc7kGnXwIfCyUj6xHJNpENlY11oKpRTgsjc= github.com/aws/aws-sdk-go-v2/config v1.31.16/go.mod h1:2S9hBElpCyGMifv14WxQ7EfPumgoeCPZUpuPX8VtW34= github.com/aws/aws-sdk-go-v2/credentials v1.18.20 h1:KFndAnHd9NUuzikHjQ8D5CfFVO+bgELkmcGY8yAw98Q= github.com/aws/aws-sdk-go-v2/credentials v1.18.20/go.mod h1:9mCi28a+fmBHSQ0UM79omkz6JtN+PEsvLrnG36uoUv0= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.12 h1:VO3FIM2TDbm0kqp6sFNR0PbioXJb/HzCDW6NtIZpIWE= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.12/go.mod h1:6C39gB8kg82tx3r72muZSrNhHia9rjGkX7ORaS2GKNE= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.12 h1:p/9flfXdoAnwJnuW9xHEAFY22R3A6skYkW19JFF9F+8= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.12/go.mod h1:ZTLHakoVCTtW8AaLGSwJ3LXqHD9uQKnOcv1TrpO6u2k= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.12 h1:2lTWFvRcnWFFLzHWmtddu5MTchc5Oj2OOey++99tPZ0= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.12/go.mod h1:hI92pK+ho8HVcWMHKHrK3Uml4pfG7wvL86FzO0LVtQQ= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.21 h1:Rgg6wvjjtX8bNHcvi9OnXWwcE0a2vGpbwmtICOsvcf4= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.21/go.mod h1:A/kJFst/nm//cyqonihbdpQZwiUhhzpqTsdbhDdRF9c= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.21 h1:PEgGVtPoB6NTpPrBgqSE5hE/o47Ij9qk/SEZFbUOe9A= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.21/go.mod h1:p+hz+PRAYlY3zcpJhPwXlLC4C+kqn70WIHwnzAfs6ps= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 h1:WKuaxf++XKWlHWu9ECbMlha8WOEGm0OUEZqm4K/Gcfk= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4/go.mod h1:ZWy7j6v1vWGmPReu0iSGvRiise4YI5SkR3OHKTZ6Wuc= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.24 h1:JX70yGKLj25+lMC5Yyh8wBtvB01GDilyRuJvXJ4piD0= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.24/go.mod h1:+Ln60j9SUTD0LEwnhEB0Xhg61DHqplBrbZpLgyjoEHg= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.2 h1:xtuxji5CS0JknaXoACOunXOYOQzgfTvGAc9s2QdCJA4= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.2/go.mod h1:zxwi0DIR0rcRcgdbl7E2MSOvxDyyXGBlScvBkARFaLQ= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.5 h1:gvZOjQKPxFXy1ft3QnEyXmT+IqneM9QAUWlM3r0mfqw= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.5/go.mod h1:DLWnfvIcm9IET/mmjdxeXbBKmTCm0ZB8p1za9BVteM8= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.12 h1:MM8imH7NZ0ovIVX7D2RxfMDv7Jt9OiUXkcQ+GqywA7M= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.12/go.mod h1:gf4OGwdNkbEsb7elw2Sy76odfhwNktWII3WgvQgQQ6w= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.5 h1:P1doBzv5VEg1ONxnJss1Kh5ZG/ewoIE4MQtKKc6Crgg= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.5/go.mod h1:NOP+euMW7W3Ukt28tAxPuoWao4rhhqJD3QEBk7oCg7w= -github.com/aws/aws-sdk-go-v2/service/s3 v1.69.0 h1:Q2ax8S21clKOnHhhr933xm3JxdJebql+R7aNo7p7GBQ= -github.com/aws/aws-sdk-go-v2/service/s3 v1.69.0/go.mod h1:ralv4XawHjEMaHOWnTFushl0WRqim/gQWesAMF6hTow= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.22 h1:rWyie/PxDRIdhNf4DzRk0lvjVOqFJuNnO8WwaIRVxzQ= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.22/go.mod h1:zd/JsJ4P7oGfUhXn1VyLqaRZwPmZwg44Jf2dS84Dm3Y= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7 h1:5EniKhLZe4xzL7a+fU3C2tfUN4nWIqlLesfrjkuPFTY= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7/go.mod h1:x0nZssQ3qZSnIcePWLvcoFisRXJzcTVvYpAAdYX8+GI= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.13 h1:JRaIgADQS/U6uXDqlPiefP32yXTda7Kqfx+LgspooZM= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.13/go.mod h1:CEuVn5WqOMilYl+tbccq8+N2ieCy0gVn3OtRb0vBNNM= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.21 h1:c31//R3xgIJMSC8S6hEVq+38DcvUlgFY0FM6mSI5oto= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.21/go.mod h1:r6+pf23ouCB718FUxaqzZdbpYFyDtehyZcmP5KL9FkA= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.21 h1:ZlvrNcHSFFWURB8avufQq9gFsheUgjVD9536obIknfM= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.21/go.mod h1:cv3TNhVrssKR0O/xxLJVRfd2oazSnZnkUeTf6ctUwfQ= +github.com/aws/aws-sdk-go-v2/service/s3 v1.97.3 h1:HwxWTbTrIHm5qY+CAEur0s/figc3qwvLWsNkF4RPToo= +github.com/aws/aws-sdk-go-v2/service/s3 v1.97.3/go.mod h1:uoA43SdFwacedBfSgfFSjjCvYe8aYBS7EnU5GZ/YKMM= github.com/aws/aws-sdk-go-v2/service/sso v1.30.0 h1:xHXvxst78wBpJFgDW07xllOx0IAzbryrSdM4nMVQ4Dw= github.com/aws/aws-sdk-go-v2/service/sso v1.30.0/go.mod h1:/e8m+AO6HNPPqMyfKRtzZ9+mBF5/x1Wk8QiDva4m07I= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.4 h1:tBw2Qhf0kj4ZwtsVpDiVRU3zKLvjvjgIjHMKirxXg8M= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.4/go.mod h1:Deq4B7sRM6Awq/xyOBlxBdgW8/Z926KYNNaGMW2lrkA= github.com/aws/aws-sdk-go-v2/service/sts v1.39.0 h1:C+BRMnasSYFcgDw8o9H5hzehKzXyAb9GY5v/8bP9DUY= github.com/aws/aws-sdk-go-v2/service/sts v1.39.0/go.mod h1:4EjU+4mIx6+JqKQkruye+CaigV7alL3thVPfDd9VlMs= -github.com/aws/smithy-go v1.23.1 h1:sLvcH6dfAFwGkHLZ7dGiYF7aK6mg4CgKA/iDKjLDt9M= -github.com/aws/smithy-go v1.23.1/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0= +github.com/aws/smithy-go v1.24.2 h1:FzA3bu/nt/vDvmnkg+R8Xl46gmzEDam6mZ1hzmwXFng= +github.com/aws/smithy-go v1.24.2/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc= github.com/bazelbuild/rules_go v0.49.0/go.mod h1:Dhcz716Kqg1RHNWos+N6MlXNkjNP2EwZQ0LukRKJfMs= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= diff --git a/validation/snapshot/k3s/README.md b/validation/snapshot/k3s/README.md index 9e73d1edc..04b512edb 100644 --- a/validation/snapshot/k3s/README.md +++ b/validation/snapshot/k3s/README.md @@ -76,7 +76,7 @@ The snapshot S3 test validates that snapshots can be stored and restored from an 1. `K3S_S3_Snapshot` #### Run Commands: -1. `gotestsum --format standard-verbose --packages=github.com/rancher/tests/validation/snapshot/k3s --junitfile results.xml --jsonfile results.json -- -tags=validation -run TestS3SnapshotRestoreTestSuite/TestS3Snapshot -timeout=1h -v` +1. `gotestsum --format standard-verbose --packages=github.com/rancher/tests/validation/snapshot/k3s --junitfile results.xml --jsonfile results.json -- -tags=validation -run TestS3SnapshotRestoreTestSuite/TestS3SnapshotRestore -timeout=1h -v` ## Configurations diff --git a/validation/snapshot/k3s/snapshot_s3_restore_test.go b/validation/snapshot/k3s/snapshot_s3_restore_test.go index ecba26cae..eb560aefe 100644 --- a/validation/snapshot/k3s/snapshot_s3_restore_test.go +++ b/validation/snapshot/k3s/snapshot_s3_restore_test.go @@ -1,17 +1,22 @@ -//go:build (validation || extended || infra.any || cluster.any) && !sanity && !stress +//go:build validation || recurring package k3s import ( + "fmt" "os" "testing" + "time" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" "github.com/rancher/shepherd/clients/rancher" v1 "github.com/rancher/shepherd/clients/rancher/v1" + "github.com/rancher/shepherd/extensions/cloudcredentials" extClusters "github.com/rancher/shepherd/extensions/clusters" "github.com/rancher/shepherd/extensions/defaults/stevetypes" "github.com/rancher/shepherd/pkg/config" "github.com/rancher/shepherd/pkg/config/operations" + "github.com/rancher/shepherd/pkg/namegenerator" "github.com/rancher/shepherd/pkg/session" "github.com/rancher/tests/actions/clusters" "github.com/rancher/tests/actions/config/defaults" @@ -19,20 +24,35 @@ import ( "github.com/rancher/tests/actions/logging" "github.com/rancher/tests/actions/provisioning" "github.com/rancher/tests/actions/qase" + resources "github.com/rancher/tests/validation/provisioning/resources/provisioncluster" standard "github.com/rancher/tests/validation/provisioning/resources/standarduser" "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" ) type S3SnapshotRestoreTestSuite struct { suite.Suite - session *session.Session - client *rancher.Client - cattleConfig map[string]any - cluster *v1.SteveAPIObject + session *session.Session + client *rancher.Client + cattleConfig map[string]any + cluster *v1.SteveAPIObject + s3BucketName string + s3Region string + s3Endpoint string + s3CloudCredName string + createdTestBucket bool + awsAccessKey string + awsSecretKey string +} + +type awsCredentialsConfig struct { + SecretKey string `json:"secretKey" yaml:"secretKey"` + AccessKey string `json:"accessKey" yaml:"accessKey"` + DefaultRegion string `json:"defaultRegion" yaml:"defaultRegion"` } func (s *S3SnapshotRestoreTestSuite) TearDownSuite() { @@ -68,11 +88,41 @@ func (s *S3SnapshotRestoreTestSuite) SetupSuite() { rancherConfig := new(rancher.Config) operations.LoadObjectFromMap(defaults.RancherConfigKey, s.cattleConfig, rancherConfig) + awsCredsConfig := new(awsCredentialsConfig) + operations.LoadObjectFromMap("awsCredentials", s.cattleConfig, awsCredsConfig) + + s.awsAccessKey = awsCredsConfig.AccessKey + s.awsSecretKey = awsCredsConfig.SecretKey + if rancherConfig.ClusterName == "" { provider := provisioning.CreateProvider(clusterConfig.Provider) machineConfigSpec := provider.LoadMachineConfigFunc(s.cattleConfig) - logrus.Info("Provisioning K3S cluster") + credentialSpec := cloudcredentials.LoadCloudCredential(string(provider.Name)) + cloudCredential, err := provider.CloudCredFunc(standardUserClient, credentialSpec) + require.NoError(s.T(), err) + + s.s3CloudCredName = cloudCredential.Namespace + ":" + cloudCredential.Name + s.s3Region = awsCredsConfig.DefaultRegion + s.s3Endpoint = fmt.Sprintf("s3.%s.amazonaws.com", s.s3Region) + s.s3BucketName = fmt.Sprintf("snapshot-restore-s3-%d-%s", time.Now().Unix(), namegenerator.RandStringLower(5)) + + err = etcdsnapshot.CreateS3Bucket(s.s3BucketName, s.s3Region, awsCredsConfig.AccessKey, awsCredsConfig.SecretKey) + require.NoError(s.T(), err) + s.createdTestBucket = true + + clusterConfig.ETCD = &rkev1.ETCD{ + SnapshotRetention: 5, + SnapshotScheduleCron: "0 */5 * * *", + S3: &rkev1.ETCDSnapshotS3{ + Bucket: s.s3BucketName, + CloudCredentialName: s.s3CloudCredName, + Endpoint: s.s3Endpoint, + Region: s.s3Region, + SkipSSLVerify: true, + }, + } + s.cluster, err = resources.ProvisionRKE2K3SCluster(s.T(), standardUserClient, extClusters.K3SClusterType.String(), provider, *clusterConfig, machineConfigSpec, nil, false, false) require.NoError(s.T(), err) @@ -108,6 +158,11 @@ func (s *S3SnapshotRestoreTestSuite) TestS3SnapshotRestore() { err = etcdsnapshot.CreateAndValidateSnapshotRestore(s.client, cluster.Name, tt.etcdSnapshot, containerImage) require.NoError(s.T(), err) + + if s.createdTestBucket && s.s3BucketName != "" { + err := etcdsnapshot.DeleteS3Bucket(s.s3BucketName, s.s3Region, s.awsAccessKey, s.awsSecretKey) + assert.NoError(s.T(), err) + } }) params := provisioning.GetProvisioningSchemaParams(s.client, s.cattleConfig) diff --git a/validation/snapshot/rke2/README.md b/validation/snapshot/rke2/README.md index 81b704afb..23bd1725e 100644 --- a/validation/snapshot/rke2/README.md +++ b/validation/snapshot/rke2/README.md @@ -97,7 +97,7 @@ The snapshot S3 test validates that snapshots can be stored and restored from an 1. `RKE2_S3_Restore` #### Run Commands: -1. `gotestsum --format standard-verbose --packages=github.com/rancher/tests/validation/snapshot/rke2 --junitfile results.xml --jsonfile results.json -- -tags=validation -run TestS3SnapshotRestoreTestSuite/TestS3Snapshot -timeout=1h -v` +1. `gotestsum --format standard-verbose --packages=github.com/rancher/tests/validation/snapshot/rke2 --junitfile results.xml --jsonfile results.json -- -tags=validation -run TestS3SnapshotRestoreTestSuite/TestS3SnapshotRestore -timeout=1h -v` ## Configurations diff --git a/validation/snapshot/rke2/snapshot_s3_restore_test.go b/validation/snapshot/rke2/snapshot_s3_restore_test.go index d8636c796..0f5d01b58 100644 --- a/validation/snapshot/rke2/snapshot_s3_restore_test.go +++ b/validation/snapshot/rke2/snapshot_s3_restore_test.go @@ -1,17 +1,22 @@ -//go:build (validation || extended || infra.any || cluster.any) && !sanity && !stress +//go:build validation || recurring package rke2 import ( + "fmt" "os" "testing" + "time" + rkev1 "github.com/rancher/rancher/pkg/apis/rke.cattle.io/v1" "github.com/rancher/shepherd/clients/rancher" v1 "github.com/rancher/shepherd/clients/rancher/v1" + "github.com/rancher/shepherd/extensions/cloudcredentials" extClusters "github.com/rancher/shepherd/extensions/clusters" "github.com/rancher/shepherd/extensions/defaults/stevetypes" "github.com/rancher/shepherd/pkg/config" "github.com/rancher/shepherd/pkg/config/operations" + "github.com/rancher/shepherd/pkg/namegenerator" "github.com/rancher/shepherd/pkg/session" "github.com/rancher/tests/actions/clusters" "github.com/rancher/tests/actions/config/defaults" @@ -23,16 +28,30 @@ import ( standard "github.com/rancher/tests/validation/provisioning/resources/standarduser" "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" ) type S3SnapshotRestoreTestSuite struct { suite.Suite - session *session.Session - client *rancher.Client - cattleConfig map[string]any - cluster *v1.SteveAPIObject + session *session.Session + client *rancher.Client + cattleConfig map[string]any + cluster *v1.SteveAPIObject + s3BucketName string + s3Region string + s3Endpoint string + s3CloudCredName string + createdTestBucket bool + awsAccessKey string + awsSecretKey string +} + +type awsCredentialsConfig struct { + SecretKey string `json:"secretKey" yaml:"secretKey"` + AccessKey string `json:"accessKey" yaml:"accessKey"` + DefaultRegion string `json:"defaultRegion" yaml:"defaultRegion"` } func (s *S3SnapshotRestoreTestSuite) TearDownSuite() { @@ -68,11 +87,41 @@ func (s *S3SnapshotRestoreTestSuite) SetupSuite() { rancherConfig := new(rancher.Config) operations.LoadObjectFromMap(defaults.RancherConfigKey, s.cattleConfig, rancherConfig) + awsCredsConfig := new(awsCredentialsConfig) + operations.LoadObjectFromMap("awsCredentials", s.cattleConfig, awsCredsConfig) + + s.awsAccessKey = awsCredsConfig.AccessKey + s.awsSecretKey = awsCredsConfig.SecretKey + if rancherConfig.ClusterName == "" { provider := provisioning.CreateProvider(clusterConfig.Provider) machineConfigSpec := provider.LoadMachineConfigFunc(s.cattleConfig) - logrus.Info("Provisioning RKE2 cluster") + credentialSpec := cloudcredentials.LoadCloudCredential(string(provider.Name)) + cloudCredential, err := provider.CloudCredFunc(standardUserClient, credentialSpec) + require.NoError(s.T(), err) + + s.s3CloudCredName = cloudCredential.Namespace + ":" + cloudCredential.Name + s.s3Region = awsCredsConfig.DefaultRegion + s.s3Endpoint = fmt.Sprintf("s3.%s.amazonaws.com", s.s3Region) + s.s3BucketName = fmt.Sprintf("snapshot-restore-s3-%d-%s", time.Now().Unix(), namegenerator.RandStringLower(5)) + + err = etcdsnapshot.CreateS3Bucket(s.s3BucketName, s.s3Region, awsCredsConfig.AccessKey, awsCredsConfig.SecretKey) + require.NoError(s.T(), err) + s.createdTestBucket = true + + clusterConfig.ETCD = &rkev1.ETCD{ + SnapshotRetention: 5, + SnapshotScheduleCron: "0 */5 * * *", + S3: &rkev1.ETCDSnapshotS3{ + Bucket: s.s3BucketName, + CloudCredentialName: s.s3CloudCredName, + Endpoint: s.s3Endpoint, + Region: s.s3Region, + SkipSSLVerify: true, + }, + } + s.cluster, err = resources.ProvisionRKE2K3SCluster(s.T(), standardUserClient, extClusters.RKE2ClusterType.String(), provider, *clusterConfig, machineConfigSpec, nil, false, false) require.NoError(s.T(), err) @@ -108,6 +157,11 @@ func (s *S3SnapshotRestoreTestSuite) TestS3SnapshotRestore() { err = etcdsnapshot.CreateAndValidateSnapshotRestore(s.client, cluster.Name, tt.etcdSnapshot, containerImage) require.NoError(s.T(), err) + + if s.createdTestBucket && s.s3BucketName != "" { + err := etcdsnapshot.DeleteS3Bucket(s.s3BucketName, s.s3Region, s.awsAccessKey, s.awsSecretKey) + assert.NoError(s.T(), err) + } }) params := provisioning.GetProvisioningSchemaParams(s.client, s.cattleConfig)