From adf03a5460cd997e8ed254abd4a14f67042f9215 Mon Sep 17 00:00:00 2001 From: Emilia Grant Date: Tue, 21 Oct 2025 12:00:11 -0600 Subject: [PATCH 1/5] update to aws sdk v2 --- .gitignore | 2 + wrappers/awskms/awskms.go | 108 ++++++++------- wrappers/awskms/awskms_test.go | 131 +++++++++++++----- wrappers/awskms/go.mod | 47 ++++--- wrappers/awskms/go.sum | 122 ++++++++-------- .../awskms/{testing.go => mockclient_test.go} | 44 +++--- 6 files changed, 268 insertions(+), 186 deletions(-) rename wrappers/awskms/{testing.go => mockclient_test.go} (53%) diff --git a/.gitignore b/.gitignore index 77982bf1..7991e904 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ .idea go.work go.work.sum +.env +.envrc diff --git a/wrappers/awskms/awskms.go b/wrappers/awskms/awskms.go index 4b1f6c73..8055ebd0 100644 --- a/wrappers/awskms/awskms.go +++ b/wrappers/awskms/awskms.go @@ -10,20 +10,20 @@ import ( "os" "sync/atomic" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/session" - "github.com/aws/aws-sdk-go/service/kms" - "github.com/aws/aws-sdk-go/service/kms/kmsiface" + "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go-v2/service/kms" cleanhttp "github.com/hashicorp/go-cleanhttp" "github.com/hashicorp/go-hclog" wrapping "github.com/hashicorp/go-kms-wrapping/v2" - "github.com/hashicorp/go-secure-stdlib/awsutil" + "github.com/hashicorp/go-secure-stdlib/awsutil/v2" ) // These constants contain the accepted env vars; the Vault one is for backwards compat const ( - EnvAwsKmsWrapperKeyId = "AWSKMS_WRAPPER_KEY_ID" - EnvVaultAwsKmsSealKeyId = "VAULT_AWSKMS_SEAL_KEY_ID" + EnvAwsKmsWrapperKeyId = "AWSKMS_WRAPPER_KEY_ID" + EnvVaultAwsKmsSealKeyId = "VAULT_AWSKMS_SEAL_KEY_ID" + DeprecatedEnvAwsKmsEndpoint = "AWS_KMS_ENDPOINT" + EnvAwsKmsEndpoint = "AWSKMS_ENDPOINT" ) const ( @@ -52,11 +52,18 @@ type Wrapper struct { currentKeyId *atomic.Value - client kmsiface.KMSAPI + client KmsApi logger hclog.Logger } +// Replaces aws-sdk v1's iface package interfaces +type KmsApi interface { + Encrypt(ctx context.Context, input *kms.EncryptInput, opts ...func(*kms.Options)) (*kms.EncryptOutput, error) + Decrypt(ctx context.Context, input *kms.DecryptInput, opts ...func(*kms.Options)) (*kms.DecryptOutput, error) + DescribeKey(ctx context.Context, inpput *kms.DescribeKeyInput, opts ...func(*kms.Options)) (*kms.DescribeKeyOutput, error) +} + // Ensure that we are implementing Wrapper var _ wrapping.Wrapper = (*Wrapper)(nil) @@ -77,7 +84,7 @@ func NewWrapper() *Wrapper { // * Passed in config map // * Instance metadata role (access key and secret key) // * Default values -func (k *Wrapper) SetConfig(_ context.Context, opt ...wrapping.Option) (*wrapping.WrapperConfig, error) { +func (k *Wrapper) SetConfig(ctx context.Context, opt ...wrapping.Option) (*wrapping.WrapperConfig, error) { opts, err := getOpts(opt...) if err != nil { return nil, err @@ -103,7 +110,7 @@ func (k *Wrapper) SetConfig(_ context.Context, opt ...wrapping.Option) (*wrappin k.currentKeyId.Store(k.keyId) // Please see GetRegion for an explanation of the order in which region is parsed. - k.region, err = awsutil.GetRegion(opts.withRegion) + k.region, err = awsutil.GetRegion(ctx, opts.withRegion) if err != nil { return nil, err } @@ -119,7 +126,11 @@ func (k *Wrapper) SetConfig(_ context.Context, opt ...wrapping.Option) (*wrappin k.roleArn = opts.withRoleArn if !opts.withDisallowEnvVars { - k.endpoint = os.Getenv("AWS_KMS_ENDPOINT") + ep := os.Getenv(EnvAwsKmsEndpoint) + if ep == "" { + ep = os.Getenv(DeprecatedEnvAwsKmsEndpoint) + } + k.endpoint = ep } if k.endpoint == "" { k.endpoint = opts.withEndpoint @@ -127,15 +138,15 @@ func (k *Wrapper) SetConfig(_ context.Context, opt ...wrapping.Option) (*wrappin // Check and set k.client if k.client == nil { - client, err := k.GetAwsKmsClient() + client, err := k.GetAwsKmsClient(ctx) if err != nil { return nil, fmt.Errorf("error initializing AWS KMS wrapping client: %w", err) } if !k.keyNotRequired { // Test the client connection using provided key ID - keyInfo, err := client.DescribeKey(&kms.DescribeKeyInput{ - KeyId: aws.String(k.keyId), + keyInfo, err := client.DescribeKey(ctx, &kms.DescribeKeyInput{ + KeyId: &k.keyId, }) if err != nil { return nil, fmt.Errorf("error fetching AWS KMS wrapping key information: %w", err) @@ -143,7 +154,7 @@ func (k *Wrapper) SetConfig(_ context.Context, opt ...wrapping.Option) (*wrappin if keyInfo == nil || keyInfo.KeyMetadata == nil || keyInfo.KeyMetadata.KeyId == nil { return nil, errors.New("no key information returned") } - k.currentKeyId.Store(aws.StringValue(keyInfo.KeyMetadata.KeyId)) + k.currentKeyId.Store(*keyInfo.KeyMetadata.KeyId) } k.client = client @@ -174,7 +185,7 @@ func (k *Wrapper) KeyId(_ context.Context) (string, error) { // Encrypt is used to encrypt the master key using the the AWS CMK. // This returns the ciphertext, and/or any errors from this // call. This should be called after the KMS client has been instantiated. -func (k *Wrapper) Encrypt(_ context.Context, plaintext []byte, opt ...wrapping.Option) (*wrapping.BlobInfo, error) { +func (k *Wrapper) Encrypt(ctx context.Context, plaintext []byte, opt ...wrapping.Option) (*wrapping.BlobInfo, error) { if plaintext == nil { return nil, fmt.Errorf("given plaintext for encryption is nil") } @@ -189,10 +200,10 @@ func (k *Wrapper) Encrypt(_ context.Context, plaintext []byte, opt ...wrapping.O } input := &kms.EncryptInput{ - KeyId: aws.String(k.keyId), + KeyId: &k.keyId, Plaintext: env.Key, } - output, err := k.client.Encrypt(input) + output, err := k.client.Encrypt(ctx, input) if err != nil { return nil, fmt.Errorf("error encrypting data: %w", err) } @@ -203,8 +214,8 @@ func (k *Wrapper) Encrypt(_ context.Context, plaintext []byte, opt ...wrapping.O // used for encryption. This is helpful if you are looking to reencyrpt // your data when it is not using the latest key id. See these docs relating // to key rotation https://docs.aws.amazon.com/kms/latest/developerguide/rotate-keys.html - keyId := aws.StringValue(output.KeyId) - k.currentKeyId.Store(keyId) + keyId := output.KeyId + k.currentKeyId.Store(*keyId) ret := &wrapping.BlobInfo{ Ciphertext: env.Ciphertext, @@ -214,7 +225,7 @@ func (k *Wrapper) Encrypt(_ context.Context, plaintext []byte, opt ...wrapping.O // Even though we do not use the key id during decryption, store it // to know exactly the specific key used in encryption in case we // want to rewrap older entries - KeyId: keyId, + KeyId: *keyId, WrappedKey: output.CiphertextBlob, }, } @@ -223,7 +234,7 @@ func (k *Wrapper) Encrypt(_ context.Context, plaintext []byte, opt ...wrapping.O } // Decrypt is used to decrypt the ciphertext. This should be called after Init. -func (k *Wrapper) Decrypt(_ context.Context, in *wrapping.BlobInfo, opt ...wrapping.Option) ([]byte, error) { +func (k *Wrapper) Decrypt(ctx context.Context, in *wrapping.BlobInfo, opt ...wrapping.Option) ([]byte, error) { if in == nil { return nil, fmt.Errorf("given input for decryption is nil") } @@ -242,7 +253,7 @@ func (k *Wrapper) Decrypt(_ context.Context, in *wrapping.BlobInfo, opt ...wrapp CiphertextBlob: in.Ciphertext, } - output, err := k.client.Decrypt(input) + output, err := k.client.Decrypt(ctx, input) if err != nil { return nil, fmt.Errorf("error decrypting data: %w", err) } @@ -254,7 +265,7 @@ func (k *Wrapper) Decrypt(_ context.Context, in *wrapping.BlobInfo, opt ...wrapp input := &kms.DecryptInput{ CiphertextBlob: in.KeyInfo.WrappedKey, } - output, err := k.client.Decrypt(input) + output, err := k.client.Decrypt(ctx, input) if err != nil { return nil, fmt.Errorf("error decrypting data encryption key: %w", err) } @@ -277,48 +288,47 @@ func (k *Wrapper) Decrypt(_ context.Context, in *wrapping.BlobInfo, opt ...wrapp } // Client returns the AWS KMS client used by the wrapper. -func (k *Wrapper) Client() kmsiface.KMSAPI { +func (k *Wrapper) Client() KmsApi { return k.client } // GetAwsKmsClient returns an instance of the KMS client. -func (k *Wrapper) GetAwsKmsClient() (*kms.KMS, error) { - credsConfig := &awsutil.CredentialsConfig{} - - credsConfig.AccessKey = k.accessKey - credsConfig.SecretKey = k.secretKey - credsConfig.SessionToken = k.sessionToken - credsConfig.Filename = k.sharedCredsFilename - credsConfig.Profile = k.sharedCredsProfile - credsConfig.RoleARN = k.roleArn - credsConfig.RoleSessionName = k.roleSessionName - credsConfig.WebIdentityTokenFile = k.webIdentityTokenFile - credsConfig.Region = k.region - credsConfig.Logger = k.logger - - credsConfig.HTTPClient = cleanhttp.DefaultClient() - - creds, err := credsConfig.GenerateCredentialChain() +func (k *Wrapper) GetAwsKmsClient(ctx context.Context) (*kms.Client, error) { + credsConfig := &awsutil.CredentialsConfig{ + AccessKey: k.accessKey, + SecretKey: k.secretKey, + SessionToken: k.sessionToken, + Filename: k.sharedCredsFilename, + Profile: k.sharedCredsProfile, + RoleARN: k.roleArn, + RoleSessionName: k.roleSessionName, + WebIdentityTokenFile: k.webIdentityTokenFile, + Region: k.region, + Logger: k.logger, + HTTPClient: cleanhttp.DefaultClient(), + } + + creds, err := credsConfig.GenerateCredentialChain(ctx) if err != nil { return nil, err } - awsConfig := &aws.Config{ - Credentials: creds, - Region: aws.String(credsConfig.Region), - HTTPClient: cleanhttp.DefaultClient(), + clientOpts := []func(*config.LoadOptions) error{ + config.WithCredentialsProvider(creds.Credentials), + config.WithRegion(k.region), + config.WithHTTPClient(cleanhttp.DefaultClient()), } if k.endpoint != "" { - awsConfig.Endpoint = aws.String(k.endpoint) + clientOpts = append(clientOpts, config.WithBaseEndpoint(k.endpoint)) } - sess, err := session.NewSession(awsConfig) + cfg, err := config.LoadDefaultConfig(ctx, clientOpts...) if err != nil { return nil, err } - client := kms.New(sess) + client := kms.NewFromConfig(cfg) return client, nil } diff --git a/wrappers/awskms/awskms_test.go b/wrappers/awskms/awskms_test.go index 6a7d83af..6b6f00ff 100644 --- a/wrappers/awskms/awskms_test.go +++ b/wrappers/awskms/awskms_test.go @@ -9,28 +9,37 @@ import ( "reflect" "testing" - "github.com/aws/aws-sdk-go/aws" wrapping "github.com/hashicorp/go-kms-wrapping/v2" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) +const ( + awsTestKeyId = "foo" + envAwsProfile = "AWS_PROFILE" + envAwsRegion = "AWS_REGION" +) + func TestAwsKmsWrapper(t *testing.T) { + // Test with empty key, expect error + oldKeyId := os.Getenv(EnvAwsKmsWrapperKeyId) + os.Setenv(EnvAwsKmsWrapperKeyId, "") + defer os.Setenv(EnvAwsKmsWrapperKeyId, oldKeyId) + s := NewWrapper() s.client = &mockClient{ - keyId: aws.String(awsTestKeyId), + keyId: awsTestKeyId, } - _, err := s.SetConfig(nil) + _, err := s.SetConfig(t.Context()) if err == nil { t.Fatal("expected error when AwsKms wrapping key ID is not provided") } - // Set the key - oldKeyId := os.Getenv(EnvAwsKmsWrapperKeyId) - os.Setenv(EnvAwsKmsWrapperKeyId, awsTestKeyId) - defer os.Setenv(EnvAwsKmsWrapperKeyId, oldKeyId) - _, err = s.SetConfig(nil) + // Test with set key, expect no error + os.Setenv(EnvAwsKmsWrapperKeyId, oldKeyId) + + _, err = s.SetConfig(t.Context()) if err != nil { t.Fatal(err) } @@ -40,7 +49,7 @@ func TestAwsKmsWrapper_IgnoreEnv(t *testing.T) { wrapper := NewAwsKmsTestWrapper() // Setup environment values to ignore for the following values - for _, envVar := range []string{EnvAwsKmsWrapperKeyId, EnvVaultAwsKmsSealKeyId, "AWS_KMS_ENDPOINT"} { + for _, envVar := range []string{EnvAwsKmsWrapperKeyId, EnvVaultAwsKmsSealKeyId, EnvAwsKmsEndpoint, DeprecatedEnvAwsKmsEndpoint} { oldVal := os.Getenv(envVar) os.Setenv(envVar, "envValue") defer os.Setenv(envVar, oldVal) @@ -67,10 +76,7 @@ func TestAwsKmsWrapper_Lifecycle(t *testing.T) { if os.Getenv(EnvAwsKmsWrapperKeyId) == "" && os.Getenv(EnvVaultAwsKmsSealKeyId) == "" { t.SkipNow() } - s := NewWrapper() - s.client = &mockClient{ - keyId: aws.String(awsTestKeyId), - } + s := NewAwsKmsTestWrapper() oldKeyId := os.Getenv(EnvAwsKmsWrapperKeyId) os.Setenv(EnvAwsKmsWrapperKeyId, awsTestKeyId) defer os.Setenv(EnvAwsKmsWrapperKeyId, oldKeyId) @@ -115,7 +121,6 @@ func testEncryptionRoundTrip(t *testing.T, w *Wrapper) { func TestAwsKmsWrapper_custom_endpoint(t *testing.T) { customEndpoint := "https://custom.endpoint" customEndpoint2 := "https://custom.endpoint.2" - endpointENV := "AWS_KMS_ENDPOINT" // unset at end of test os.Setenv(EnvAwsKmsWrapperKeyId, awsTestKeyId) @@ -132,7 +137,7 @@ func TestAwsKmsWrapper_custom_endpoint(t *testing.T) { Title string Env string Config map[string]string - Expected *string + Expected string }{ { // Default will have nil for the config endpoint, and be looked up @@ -142,32 +147,28 @@ func TestAwsKmsWrapper_custom_endpoint(t *testing.T) { { Title: "Environment", Env: customEndpoint, - Expected: aws.String(customEndpoint), + Expected: customEndpoint, }, { Title: "Config", Config: cfg, - Expected: aws.String(customEndpoint), + Expected: customEndpoint, }, { // Expect environment to take precedence over configuration Title: "Env-Config", Env: customEndpoint2, Config: cfg, - Expected: aws.String(customEndpoint2), + Expected: customEndpoint2, }, } for _, tc := range testCases { t.Run(tc.Title, func(t *testing.T) { - s := NewWrapper() - - s.client = &mockClient{ - keyId: aws.String(awsTestKeyId), - } + s := NewAwsKmsTestWrapper() if tc.Env != "" { - if err := os.Setenv(endpointENV, tc.Env); err != nil { + if err := os.Setenv(EnvAwsKmsEndpoint, tc.Env); err != nil { t.Fatal(err) } } @@ -182,30 +183,92 @@ func TestAwsKmsWrapper_custom_endpoint(t *testing.T) { t.Fatalf("error setting config: %s", err) } - // call GetAwsKmsClient() to get the configured client and verify it's + // call GetAwsKmsClient() to get the configured client and verify its // endpoint - k, err := s.GetAwsKmsClient() + k, err := s.GetAwsKmsClient(t.Context()) if err != nil { t.Fatal(err) } - - if tc.Expected == nil && k.Config.Endpoint != nil { - t.Fatalf("Expected nil endpoint, got: (%s)", *k.Config.Endpoint) + actualEndpoint := k.Options().BaseEndpoint + if tc.Expected == "" && actualEndpoint != nil { + t.Fatalf("Expected nil endpoint, got: (%s)", *actualEndpoint) } - if tc.Expected != nil { - if k.Config.Endpoint == nil { + if tc.Expected != "" { + if *actualEndpoint == "" { t.Fatal("expected custom endpoint, but config was nil") } - if *k.Config.Endpoint != *tc.Expected { - t.Fatalf("expected custom endpoint (%s), got: (%s)", *tc.Expected, *k.Config.Endpoint) + if *actualEndpoint != tc.Expected { + t.Fatalf("expected custom endpoint (%s), got: (%s)", tc.Expected, *actualEndpoint) } } // clear endpoint env after each test - if err := os.Unsetenv(endpointENV); err != nil { + if err := os.Unsetenv(EnvAwsKmsEndpoint); err != nil { t.Fatal(err) } }) } } + +func TestSharedProfiles(t *testing.T) { + if os.Getenv(envAwsRegion) == "" { + t.Skip("AWS_REGION required for shared profiles tests") + } + if os.Getenv(EnvAwsKmsWrapperKeyId) == "" && os.Getenv(EnvVaultAwsKmsSealKeyId) == "" { + t.Skip("AWSKMS_WRAPPER_KEY_ID or VAULT_AWSKMS_SEAL_KEY_ID required for shared profiles tests") + } + // Test fail when shared profile doesn't exist + old := "" + if old = os.Getenv(envAwsProfile); old != "" { + os.Setenv(envAwsProfile, "") + } + + w := NewWrapper() + + _, err := w.SetConfig(t.Context(), WithSharedCredsProfile("this-profile-definitely-doesn't-exist")) + require.Error(t, err) + + // Test shared profile from WithSharedCredsProfile + // Shared profile test setup: + // - Create a role in AWS that whatever role/user you're authenticating as has permission to sts::SetSourceIdentity as + // - Create two profiles in ~/.aws/config + // - A source profile that has credentials or some method of logging in + // - A sink profile that uses `source_profile=$YOUR_SOURCE_PROFILE` and `role_arn=$YOUR_NEW_ROLE` + // + // - Set AWS_PROFILE=$SINK_PROFILE (for shared profile through AWS_PROFILE) + // - Set TEST_PROFILE=$SINK_PROFILE (for shared profile through WithSharedCredsProfile) + // - Set AWS_REGION and AWS_KMS_WRAPPER_KEY_ID as above + prof := os.Getenv("TEST_PROFILE") + if prof == "" { + t.Skip("TEST_PROFILE required for shared profile from WithSharedCredsProfile test") + } + + w = NewWrapper() + + _, err = w.SetConfig(t.Context(), WithSharedCredsProfile(prof)) + require.NoError(t, err) + + testEncryptionRoundTrip(t, w) + + os.Setenv(envAwsProfile, old) + + // Test shared profile from env + // Default awskms config pulls shared creds from AWS_PROFILE if it's set + if os.Getenv(envAwsProfile) == "" { + t.Skip("AWS_PROFILE required for shared profile from AWS_PROFILE test") + } + + w = NewWrapper() + _, err = w.SetConfig(t.Context()) + require.NoError(t, err) + testEncryptionRoundTrip(t, w) +} + +func NewAwsKmsTestWrapper() *Wrapper { + s := NewWrapper() + s.client = &mockClient{ + keyId: awsTestKeyId, + } + return s +} diff --git a/wrappers/awskms/go.mod b/wrappers/awskms/go.mod index 6a5a9904..59309880 100644 --- a/wrappers/awskms/go.mod +++ b/wrappers/awskms/go.mod @@ -1,33 +1,48 @@ -module github.com/hashicorp/go-kms-wrapping/wrappers/awskms/v2 +module github.com/hashicorp/go-kms-wrapping/wrappers/awskms/v3 -go 1.20 +go 1.24.0 require ( - github.com/aws/aws-sdk-go v1.55.5 + github.com/aws/aws-sdk-go-v2 v1.39.2 + github.com/aws/aws-sdk-go-v2/config v1.31.12 + github.com/aws/aws-sdk-go-v2/service/kms v1.45.6 github.com/hashicorp/go-cleanhttp v0.5.2 - github.com/hashicorp/go-hclog v1.5.0 - github.com/hashicorp/go-kms-wrapping/v2 v2.0.17 - github.com/hashicorp/go-secure-stdlib/awsutil v0.1.6 - github.com/stretchr/testify v1.8.4 + github.com/hashicorp/go-hclog v1.6.3 + github.com/hashicorp/go-kms-wrapping/v2 v2.0.18 + github.com/hashicorp/go-secure-stdlib/awsutil/v2 v2.1.0 + github.com/stretchr/testify v1.11.1 + go.uber.org/mock v0.6.0 ) require ( + github.com/aws/aws-sdk-go-v2/credentials v1.18.16 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.9 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.9 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.9 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect + github.com/aws/aws-sdk-go-v2/service/iam v1.47.7 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.1 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.9 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.29.6 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.1 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.38.6 // indirect + github.com/aws/smithy-go v1.23.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/fatih/color v1.14.1 // indirect + github.com/fatih/color v1.18.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/go-secure-stdlib/parseutil v0.1.9 // indirect + github.com/hashicorp/go-secure-stdlib/parseutil v0.2.0 // indirect github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect - github.com/hashicorp/go-sockaddr v1.0.6 // indirect + github.com/hashicorp/go-sockaddr v1.0.7 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect - github.com/jmespath/go-jmespath v0.4.0 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.17 // indirect + github.com/kr/text v0.2.0 // indirect + github.com/mattn/go-colorable v0.1.14 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect - github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/rogpeppe/go-internal v1.14.1 // indirect github.com/ryanuber/go-glob v1.0.0 // indirect - golang.org/x/sys v0.29.0 // indirect - google.golang.org/protobuf v1.33.0 // indirect + golang.org/x/sys v0.36.0 // indirect + google.golang.org/protobuf v1.36.10 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/wrappers/awskms/go.sum b/wrappers/awskms/go.sum index 1f565df3..aaa17d0d 100644 --- a/wrappers/awskms/go.sum +++ b/wrappers/awskms/go.sum @@ -1,103 +1,101 @@ -github.com/aws/aws-sdk-go v1.30.27/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= -github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU= -github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= +github.com/aws/aws-sdk-go-v2 v1.39.2 h1:EJLg8IdbzgeD7xgvZ+I8M1e0fL0ptn/M47lianzth0I= +github.com/aws/aws-sdk-go-v2 v1.39.2/go.mod h1:sDioUELIUO9Znk23YVmIk86/9DOpkbyyVb1i/gUNFXY= +github.com/aws/aws-sdk-go-v2/config v1.31.12 h1:pYM1Qgy0dKZLHX2cXslNacbcEFMkDMl+Bcj5ROuS6p8= +github.com/aws/aws-sdk-go-v2/config v1.31.12/go.mod h1:/MM0dyD7KSDPR+39p9ZNVKaHDLb9qnfDurvVS2KAhN8= +github.com/aws/aws-sdk-go-v2/credentials v1.18.16 h1:4JHirI4zp958zC026Sm+V4pSDwW4pwLefKrc0bF2lwI= +github.com/aws/aws-sdk-go-v2/credentials v1.18.16/go.mod h1:qQMtGx9OSw7ty1yLclzLxXCRbrkjWAM7JnObZjmCB7I= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.9 h1:Mv4Bc0mWmv6oDuSWTKnk+wgeqPL5DRFu5bQL9BGPQ8Y= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.9/go.mod h1:IKlKfRppK2a1y0gy1yH6zD+yX5uplJ6UuPlgd48dJiQ= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.9 h1:se2vOWGD3dWQUtfn4wEjRQJb1HK1XsNIt825gskZ970= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.9/go.mod h1:hijCGH2VfbZQxqCDN7bwz/4dzxV+hkyhjawAtdPWKZA= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.9 h1:6RBnKZLkJM4hQ+kN6E7yWFveOTg8NLPHAkqrs4ZPlTU= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.9/go.mod h1:V9rQKRmK7AWuEsOMnHzKj8WyrIir1yUJbZxDuZLFvXI= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo= +github.com/aws/aws-sdk-go-v2/service/iam v1.47.7 h1:0EDAdmMTzsgXl++8a0JZ+Yx0/dOqT8o/EONknxlQK94= +github.com/aws/aws-sdk-go-v2/service/iam v1.47.7/go.mod h1:NkNbn/8/mFrPUq0Kg6EM6c0+GaTLG+aPzXxwB7RF5xo= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.1 h1:oegbebPEMA/1Jny7kvwejowCaHz1FWZAQ94WXFNCyTM= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.1/go.mod h1:kemo5Myr9ac0U9JfSjMo9yHLtw+pECEHsFtJ9tqCEI8= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.9 h1:5r34CgVOD4WZudeEKZ9/iKpiT6cM1JyEROpXjOcdWv8= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.9/go.mod h1:dB12CEbNWPbzO2uC6QSWHteqOg4JfBVJOojbAoAUb5I= +github.com/aws/aws-sdk-go-v2/service/kms v1.45.6 h1:Br3kil4j7RPW+7LoLVkYt8SuhIWlg6ylmbmzXJ7PgXY= +github.com/aws/aws-sdk-go-v2/service/kms v1.45.6/go.mod h1:FKXkHzw1fJZtg1P1qoAIiwen5thz/cDRTTDCIu8ljxc= +github.com/aws/aws-sdk-go-v2/service/sso v1.29.6 h1:A1oRkiSQOWstGh61y4Wc/yQ04sqrQZr1Si/oAXj20/s= +github.com/aws/aws-sdk-go-v2/service/sso v1.29.6/go.mod h1:5PfYspyCU5Vw1wNPsxi15LZovOnULudOQuVxphSflQA= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.1 h1:5fm5RTONng73/QA73LhCNR7UT9RpFH3hR6HWL6bIgVY= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.1/go.mod h1:xBEjWD13h+6nq+z4AkqSfSvqRKFgDIQeaMguAJndOWo= +github.com/aws/aws-sdk-go-v2/service/sts v1.38.6 h1:p3jIvqYwUZgu/XYeI48bJxOhvm47hZb5HUQ0tn6Q9kA= +github.com/aws/aws-sdk-go-v2/service/sts v1.38.6/go.mod h1:WtKK+ppze5yKPkZ0XwqIVWD4beCwv056ZbPQNoeHqM8= +github.com/aws/smithy-go v1.23.0 h1:8n6I3gXzWJB2DxBDnfxgBaSX6oe0d/t10qGz7OKqMCE= +github.com/aws/smithy-go v1.23.0/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w= -github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg= -github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= +github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-hclog v0.16.2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= -github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= -github.com/hashicorp/go-kms-wrapping/v2 v2.0.17 h1:UjjwDABbv2Usc+ESZTC4DXimCRIyWUDBJe/LOUFxe/M= -github.com/hashicorp/go-kms-wrapping/v2 v2.0.17/go.mod h1:M79wTAvbhiVLo1WmglCPBgI5CEETtZWh18B3eXipmFc= +github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= +github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-kms-wrapping/v2 v2.0.18 h1:DLfC677GfKEpSAFpEWvl1vXsGpEcSHmbhBaPLrdDQHc= +github.com/hashicorp/go-kms-wrapping/v2 v2.0.18/go.mod h1:t/eaR/mi2mw3klfl1WEAuiLKrlZ/Q8cosmsT+RIPLu0= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-secure-stdlib/awsutil v0.1.6 h1:W9WN8p6moV1fjKLkeqEgkAMu5rauy9QeYDAmIaPuuiA= -github.com/hashicorp/go-secure-stdlib/awsutil v0.1.6/go.mod h1:MpCPSPGLDILGb4JMm94/mMi3YysIqsXzGCzkEZjcjXg= -github.com/hashicorp/go-secure-stdlib/parseutil v0.1.9 h1:FW0YttEnUNDJ2WL9XcrrfteS1xW8u+sh4ggM8pN5isQ= -github.com/hashicorp/go-secure-stdlib/parseutil v0.1.9/go.mod h1:Ll013mhdmsVDuoIXVfBtvgGJsXDYkTw1kooNcoCXuE0= +github.com/hashicorp/go-secure-stdlib/awsutil/v2 v2.1.0 h1:V3TJFolOHYSDqQLbTUBygXtbX4jKXyBcDoU+KNZE1Ak= +github.com/hashicorp/go-secure-stdlib/awsutil/v2 v2.1.0/go.mod h1:OeRwM2eWNW62L1Z+8GvoZM5nQJMRWBewHSoo77qmb4Y= +github.com/hashicorp/go-secure-stdlib/parseutil v0.2.0 h1:U+kC2dOhMFQctRfhK0gRctKAPTloZdMU5ZJxaesJ/VM= +github.com/hashicorp/go-secure-stdlib/parseutil v0.2.0/go.mod h1:Ll013mhdmsVDuoIXVfBtvgGJsXDYkTw1kooNcoCXuE0= github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts= github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4= -github.com/hashicorp/go-sockaddr v1.0.6 h1:RSG8rKU28VTUTvEKghe5gIhIQpv8evvNpnDEyqO4u9I= -github.com/hashicorp/go-sockaddr v1.0.6/go.mod h1:uoUUmtwU7n9Dv3O4SNLeFvg0SxQ3lyjsj6+CCykpaxI= +github.com/hashicorp/go-sockaddr v1.0.7 h1:G+pTkSO01HpR5qCxg7lxfsFEZaG+C0VssTy/9dbT+Fw= +github.com/hashicorp/go-sockaddr v1.0.7/go.mod h1:FZQbEYa1pxkQ7WLpyXJ6cbjpT8q0YgQaK/JakXqGyWw= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= -github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= -github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= -github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= -github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= +github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= +github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= -github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= -github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y= +go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= -golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= +google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/wrappers/awskms/testing.go b/wrappers/awskms/mockclient_test.go similarity index 53% rename from wrappers/awskms/testing.go rename to wrappers/awskms/mockclient_test.go index 76160f8d..de677194 100644 --- a/wrappers/awskms/testing.go +++ b/wrappers/awskms/mockclient_test.go @@ -4,32 +4,22 @@ package awskms import ( + "context" "encoding/base64" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/awserr" - "github.com/aws/aws-sdk-go/service/kms" - "github.com/aws/aws-sdk-go/service/kms/kmsiface" + "github.com/aws/aws-sdk-go-v2/service/kms" + "github.com/aws/aws-sdk-go-v2/service/kms/types" + "github.com/hashicorp/go-secure-stdlib/awsutil/v2" ) -const awsTestKeyId = "foo" - -func NewAwsKmsTestWrapper() *Wrapper { - s := NewWrapper() - s.client = &mockClient{ - keyId: aws.String(awsTestKeyId), - } - return s -} - type mockClient struct { - kmsiface.KMSAPI - keyId *string + KmsApi + keyId string } // Encrypt is a mocked call that returns a base64 encoded string. -func (m *mockClient) Encrypt(input *kms.EncryptInput) (*kms.EncryptOutput, error) { - m.keyId = input.KeyId +func (m *mockClient) Encrypt(_ context.Context, input *kms.EncryptInput, _ ...func(*kms.Options)) (*kms.EncryptOutput, error) { + m.keyId = *input.KeyId encoded := make([]byte, base64.StdEncoding.EncodedLen(len(input.Plaintext))) base64.StdEncoding.Encode(encoded, input.Plaintext) @@ -41,7 +31,7 @@ func (m *mockClient) Encrypt(input *kms.EncryptInput) (*kms.EncryptOutput, error } // Decrypt is a mocked call that returns a decoded base64 string. -func (m *mockClient) Decrypt(input *kms.DecryptInput) (*kms.DecryptOutput, error) { +func (m *mockClient) Decrypt(_ context.Context, input *kms.DecryptInput, _ ...func(*kms.Options)) (*kms.DecryptOutput, error) { decLen := base64.StdEncoding.DecodedLen(len(input.CiphertextBlob)) decoded := make([]byte, decLen) len, err := base64.StdEncoding.Decode(decoded, input.CiphertextBlob) @@ -54,20 +44,24 @@ func (m *mockClient) Decrypt(input *kms.DecryptInput) (*kms.DecryptOutput, error } return &kms.DecryptOutput{ - KeyId: m.keyId, + KeyId: &m.keyId, Plaintext: decoded, }, nil } // DescribeKey is a mocked call that returns the keyId. -func (m *mockClient) DescribeKey(input *kms.DescribeKeyInput) (*kms.DescribeKeyOutput, error) { - if m.keyId == nil { - return nil, awserr.New(kms.ErrCodeNotFoundException, "key not found", nil) +func (m *mockClient) DescribeKey(_ context.Context, inpput *kms.DescribeKeyInput, _ ...func(*kms.Options)) (*kms.DescribeKeyOutput, error) { + if m.keyId == "" { + return nil, &awsutil.MockAWSErr{ + Code: "ErrCodeNotFoundException", + Message: "Key not found", + } + } return &kms.DescribeKeyOutput{ - KeyMetadata: &kms.KeyMetadata{ - KeyId: m.keyId, + KeyMetadata: &types.KeyMetadata{ + KeyId: &m.keyId, }, }, nil } From ffca6ce0b3a53898b8246d4362dcc8111199446d Mon Sep 17 00:00:00 2001 From: Emilia Grant Date: Tue, 21 Oct 2025 12:00:48 -0600 Subject: [PATCH 2/5] restruct tests into suite --- wrappers/awskms/awskms_test.go | 428 ++++++++++++++++----------------- 1 file changed, 209 insertions(+), 219 deletions(-) diff --git a/wrappers/awskms/awskms_test.go b/wrappers/awskms/awskms_test.go index 6b6f00ff..c62043c7 100644 --- a/wrappers/awskms/awskms_test.go +++ b/wrappers/awskms/awskms_test.go @@ -6,12 +6,12 @@ package awskms import ( "context" "os" - "reflect" "testing" wrapping "github.com/hashicorp/go-kms-wrapping/v2" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + + "go.uber.org/mock/gomock" ) const ( @@ -20,255 +20,245 @@ const ( envAwsRegion = "AWS_REGION" ) -func TestAwsKmsWrapper(t *testing.T) { - // Test with empty key, expect error - oldKeyId := os.Getenv(EnvAwsKmsWrapperKeyId) - os.Setenv(EnvAwsKmsWrapperKeyId, "") - defer os.Setenv(EnvAwsKmsWrapperKeyId, oldKeyId) +type AwsKmsSuite struct { + suite.Suite + ctrl *gomock.Controller + wrapperWithMock *Wrapper +} + +func TestSuite(t *testing.T) { + suite.Run(t, new(AwsKmsSuite)) +} - s := NewWrapper() - s.client = &mockClient{ +func (s *AwsKmsSuite) SetupSubTest() { + s.ctrl = gomock.NewController(s.T()) + s.wrapperWithMock = NewWrapper() + s.wrapperWithMock.client = &mockClient{ keyId: awsTestKeyId, } +} - _, err := s.SetConfig(t.Context()) - if err == nil { - t.Fatal("expected error when AwsKms wrapping key ID is not provided") +func (s *AwsKmsSuite) TestSetConfig() { + // Works around lack of AWS_REGION var in CI + if os.Getenv(envAwsRegion) == "" { + os.Setenv(envAwsRegion, "us-west-2") + defer os.Setenv(envAwsRegion, "") } - // Test with set key, expect no error - os.Setenv(EnvAwsKmsWrapperKeyId, oldKeyId) + s.Run("Failure - No wrapper key ID", func() { + oldKeyId := os.Getenv(EnvAwsKmsWrapperKeyId) + os.Setenv(EnvAwsKmsWrapperKeyId, "") + defer os.Setenv(EnvAwsKmsWrapperKeyId, oldKeyId) + + _, err := s.wrapperWithMock.SetConfig(context.Background()) + s.Require().Error(err, "expected error when AwsKms wrapping key ID is not provided") + }) + + s.Run("Success - Test key ID pulled from environment variables", func() { + oldKeyId := os.Getenv(EnvAwsKmsWrapperKeyId) + os.Setenv(EnvAwsKmsWrapperKeyId, awsTestKeyId) + defer os.Setenv(EnvAwsKmsWrapperKeyId, oldKeyId) + + _, err := s.wrapperWithMock.SetConfig(context.Background()) + s.Require().NoError(err) + }) + + s.Run("Success - Ignore environment variables", func() { + // Setup environment values to ignore for the following values + for _, envVar := range []string{EnvAwsKmsWrapperKeyId, EnvVaultAwsKmsSealKeyId, EnvAwsKmsEndpoint, EnvAwsKmsEndpoint} { + oldVal := os.Getenv(envVar) + os.Setenv(envVar, "") + defer os.Setenv(envVar, oldVal) + } - _, err = s.SetConfig(t.Context()) - if err != nil { - t.Fatal(err) - } -} + config := map[string]string{ + "disallow_env_vars": "true", + "kms_key_id": "a-key-key", + "access_key": "a-access-key", + "secret_key": "a-secret-key", + "endpoint": "my-endpoint", + } -func TestAwsKmsWrapper_IgnoreEnv(t *testing.T) { - wrapper := NewAwsKmsTestWrapper() + _, err := s.wrapperWithMock.SetConfig(context.Background(), wrapping.WithConfigMap(config)) + s.Require().NoError(err) - // Setup environment values to ignore for the following values - for _, envVar := range []string{EnvAwsKmsWrapperKeyId, EnvVaultAwsKmsSealKeyId, EnvAwsKmsEndpoint, DeprecatedEnvAwsKmsEndpoint} { - oldVal := os.Getenv(envVar) - os.Setenv(envVar, "envValue") - defer os.Setenv(envVar, oldVal) - } + s.Require().Equal(config["access_key"], s.wrapperWithMock.accessKey) + s.Require().Equal(config["secret_key"], s.wrapperWithMock.secretKey) + s.Require().Equal(config["kms_key_id"], s.wrapperWithMock.keyId) + s.Require().Equal(config["endpoint"], s.wrapperWithMock.endpoint) + }) - config := map[string]string{ - "disallow_env_vars": "true", - "kms_key_id": "a-key-key", - "access_key": "a-access-key", - "secret_key": "a-secret-key", - "endpoint": "my-endpoint", - } + s.Run("Success - endpoint set automatically", func() { + _, err := s.wrapperWithMock.SetConfig(s.T().Context(), WithKeyNotRequired(true)) + s.Require().NoError(err) - _, err := wrapper.SetConfig(context.Background(), wrapping.WithConfigMap(config)) - assert.NoError(t, err) + c, err := s.wrapperWithMock.GetAwsKmsClient(s.T().Context()) + s.Require().NoError(err) + s.Assert().Nil(c.Options().BaseEndpoint) + }) - require.Equal(t, config["access_key"], wrapper.accessKey) - require.Equal(t, config["secret_key"], wrapper.secretKey) - require.Equal(t, config["kms_key_id"], wrapper.keyId) - require.Equal(t, config["endpoint"], wrapper.endpoint) -} + s.Run("Success - custom endpoint set from environment variables", func() { + expectedEndpoint := "https://example.com/0" + oldEndpoint := os.Getenv(EnvAwsKmsEndpoint) + os.Setenv(EnvAwsKmsEndpoint, expectedEndpoint) + defer os.Setenv(EnvAwsKmsEndpoint, oldEndpoint) -func TestAwsKmsWrapper_Lifecycle(t *testing.T) { - if os.Getenv(EnvAwsKmsWrapperKeyId) == "" && os.Getenv(EnvVaultAwsKmsSealKeyId) == "" { - t.SkipNow() - } - s := NewAwsKmsTestWrapper() - oldKeyId := os.Getenv(EnvAwsKmsWrapperKeyId) - os.Setenv(EnvAwsKmsWrapperKeyId, awsTestKeyId) - defer os.Setenv(EnvAwsKmsWrapperKeyId, oldKeyId) - testEncryptionRoundTrip(t, s) -} + _, err := s.wrapperWithMock.SetConfig(s.T().Context(), WithKeyNotRequired(true)) + s.Require().NoError(err) -// This test executes real calls. The calls themselves should be free, -// but the KMS key used is generally not free. AWS charges about $1/month -// per key. -// -// To run this test, the following env variables need to be set: -// - AWSKMS_WRAPPER_KEY_ID or VAULT_AWSKMS_SEAL_KEY_ID -// - AWS_REGION -// - AWS_ACCESS_KEY_ID -// - AWS_SECRET_ACCESS_KEY -func TestAccAwsKmsWrapper_Lifecycle(t *testing.T) { - if os.Getenv(EnvAwsKmsWrapperKeyId) == "" && os.Getenv(EnvVaultAwsKmsSealKeyId) == "" { - t.SkipNow() - } - s := NewWrapper() - testEncryptionRoundTrip(t, s) -} + c, err := s.wrapperWithMock.GetAwsKmsClient(s.T().Context()) + s.Require().NoError(err) + s.Assert().Equal(expectedEndpoint, *(c.Options().BaseEndpoint)) + }) -func testEncryptionRoundTrip(t *testing.T, w *Wrapper) { - w.SetConfig(context.Background()) - input := []byte("foo") - swi, err := w.Encrypt(context.Background(), input, nil) - if err != nil { - t.Fatalf("err: %s", err.Error()) - } + s.Run("Success - custom endpoint set from config", func() { + expectedEndpoint := "https://example.com/1" - pt, err := w.Decrypt(context.Background(), swi, nil) - if err != nil { - t.Fatalf("err: %s", err.Error()) - } + cfg := map[string]string{ + "endpoint": expectedEndpoint, + } - if !reflect.DeepEqual(input, pt) { - t.Fatalf("expected %s, got %s", input, pt) - } -} + _, err := s.wrapperWithMock.SetConfig(s.T().Context(), wrapping.WithConfigMap(cfg), WithKeyNotRequired(true)) + s.Require().NoError(err) + + c, err := s.wrapperWithMock.GetAwsKmsClient(s.T().Context()) + s.Require().NoError(err) + s.Assert().Equal(expectedEndpoint, *(c.Options().BaseEndpoint)) + }) -func TestAwsKmsWrapper_custom_endpoint(t *testing.T) { - customEndpoint := "https://custom.endpoint" - customEndpoint2 := "https://custom.endpoint.2" + s.Run("Success - custom endpoint set from environment variables taking precedence over config", func() { + expectedEndpoint := "https://example.com/2" + oldEndpoint := os.Getenv(EnvAwsKmsEndpoint) + os.Setenv(EnvAwsKmsEndpoint, expectedEndpoint) + defer os.Setenv(EnvAwsKmsEndpoint, oldEndpoint) - // unset at end of test - os.Setenv(EnvAwsKmsWrapperKeyId, awsTestKeyId) - defer func() { - if err := os.Unsetenv(EnvAwsKmsWrapperKeyId); err != nil { - t.Fatal(err) + cfg := map[string]string{ + "endpoint": "https://example.com/3", } - }() - - cfg := make(map[string]string) - cfg["endpoint"] = customEndpoint - - testCases := []struct { - Title string - Env string - Config map[string]string - Expected string - }{ - { - // Default will have nil for the config endpoint, and be looked up - // dynamically by the SDK - Title: "Default", - }, - { - Title: "Environment", - Env: customEndpoint, - Expected: customEndpoint, - }, - { - Title: "Config", - Config: cfg, - Expected: customEndpoint, - }, - { - // Expect environment to take precedence over configuration - Title: "Env-Config", - Env: customEndpoint2, - Config: cfg, - Expected: customEndpoint2, - }, - } - for _, tc := range testCases { - t.Run(tc.Title, func(t *testing.T) { - s := NewAwsKmsTestWrapper() - - if tc.Env != "" { - if err := os.Setenv(EnvAwsKmsEndpoint, tc.Env); err != nil { - t.Fatal(err) - } - } - - // cfg starts as nil, and takes a test case value if given. If not, - // SetConfig is called with nil and creates it's own config - var cfg map[string]string - if tc.Config != nil { - cfg = tc.Config - } - if _, err := s.SetConfig(context.Background(), wrapping.WithConfigMap(cfg)); err != nil { - t.Fatalf("error setting config: %s", err) - } - - // call GetAwsKmsClient() to get the configured client and verify its - // endpoint - k, err := s.GetAwsKmsClient(t.Context()) - if err != nil { - t.Fatal(err) - } - actualEndpoint := k.Options().BaseEndpoint - if tc.Expected == "" && actualEndpoint != nil { - t.Fatalf("Expected nil endpoint, got: (%s)", *actualEndpoint) - } - - if tc.Expected != "" { - if *actualEndpoint == "" { - t.Fatal("expected custom endpoint, but config was nil") - } - if *actualEndpoint != tc.Expected { - t.Fatalf("expected custom endpoint (%s), got: (%s)", tc.Expected, *actualEndpoint) - } - } - - // clear endpoint env after each test - if err := os.Unsetenv(EnvAwsKmsEndpoint); err != nil { - t.Fatal(err) - } - }) - } + _, err := s.wrapperWithMock.SetConfig(s.T().Context(), wrapping.WithConfigMap(cfg), WithKeyNotRequired(true)) + s.Require().NoError(err) + + c, err := s.wrapperWithMock.GetAwsKmsClient(s.T().Context()) + s.Require().NoError(err) + s.Assert().Equal(expectedEndpoint, *(c.Options().BaseEndpoint)) + }) } -func TestSharedProfiles(t *testing.T) { - if os.Getenv(envAwsRegion) == "" { - t.Skip("AWS_REGION required for shared profiles tests") +func (s *AwsKmsSuite) TestEncryptAndDecrypt() { + s.Run("Success - mock client", func() { + // Works around lack of AWS_REGION var in CI + if os.Getenv(envAwsRegion) == "" { + os.Setenv(envAwsRegion, "us-west-2") + defer os.Setenv(envAwsRegion, "") + } + oldKeyId := os.Getenv(EnvAwsKmsWrapperKeyId) + os.Setenv(EnvAwsKmsWrapperKeyId, awsTestKeyId) + defer os.Setenv(EnvAwsKmsWrapperKeyId, oldKeyId) + encryptionRoundTrip(s, s.wrapperWithMock) + }) + // To run the concrete enryption test, the following env variables need to be set: + // - AWSKMS_WRAPPER_KEY_ID or VAULT_AWSKMS_SEAL_KEY_ID + // - This is the ID of a KMS key in AWS that is symmetric with encrypt & decrypt usage. + // - AWS_ACCESS_KEY_ID + // - AWS_SECRET_ACCESS_KEY + // - AWS_SESSION_TOKEN + // - AWS_REGION + // - Works around https://hashicorp.atlassian.net/browse/ICU-17849 + + s.Run("Success - concrete client", func() { + if os.Getenv(EnvAwsKmsWrapperKeyId) == "" && os.Getenv(EnvVaultAwsKmsSealKeyId) == "" { + s.T().Skip("AWSKMS_WRAPPER_KEY_ID or VAULT_AWSKMS_SEAL_KEY_ID required for concrete encryption test") + } + if os.Getenv("AWS_ACCESS_KEY_ID") == "" { + s.T().Skip("AWS_ACCESS_KEY_ID required for concrete encryption test") + } + if os.Getenv("AWS_SECRET_ACCESS_KEY") == "" { + s.T().Skip("AWS_SECRET_ACCESS_KEY required for concrete encryption test") + } + if os.Getenv("AWS_SESSION_TOKEN") == "" { + s.T().Skip("AWS_SESSION_TOKEN required for concrete encryption test") + } + if os.Getenv("AWS_REGION") == "" { + s.T().Skip("AWS_REGION required for concrete encryption test") + } + w := NewWrapper() + + encryptionRoundTrip(s, w) + }) +} + +// Shared profile test setup: +// - Create a role in AWS that whatever role/user you're authenticating as has permission to sts::SetSourceIdentity as +// - Create two profiles in ~/.aws/config +// - A source profile that has credentials or some method of logging in +// - A sink profile that uses `source_profile=$YOUR_SOURCE_PROFILE` and `role_arn=$YOUR_NEW_ROLE` +// +// - Set AWS_PROFILE=$SINK_PROFILE (for shared profile through AWS_PROFILE) +// - Set TEST_PROFILE=$SINK_PROFILE (for shared profile through WithSharedCredsProfile) +// - Set AWS_REGION and AWS_KMS_WRAPPER_KEY_ID as above +func (s *AwsKmsSuite) TestSharedProfiles() { + if os.Getenv("AWS_REGION") == "" { + s.T().Skip("AWS_REGION required for shared profiles tests") } if os.Getenv(EnvAwsKmsWrapperKeyId) == "" && os.Getenv(EnvVaultAwsKmsSealKeyId) == "" { - t.Skip("AWSKMS_WRAPPER_KEY_ID or VAULT_AWSKMS_SEAL_KEY_ID required for shared profiles tests") - } - // Test fail when shared profile doesn't exist - old := "" - if old = os.Getenv(envAwsProfile); old != "" { - os.Setenv(envAwsProfile, "") + s.T().Skip("AWSKMS_WRAPPER_KEY_ID or VAULT_AWSKMS_SEAL_KEY_ID required for shared profiles tests") } - w := NewWrapper() - - _, err := w.SetConfig(t.Context(), WithSharedCredsProfile("this-profile-definitely-doesn't-exist")) - require.Error(t, err) - - // Test shared profile from WithSharedCredsProfile - // Shared profile test setup: - // - Create a role in AWS that whatever role/user you're authenticating as has permission to sts::SetSourceIdentity as - // - Create two profiles in ~/.aws/config - // - A source profile that has credentials or some method of logging in - // - A sink profile that uses `source_profile=$YOUR_SOURCE_PROFILE` and `role_arn=$YOUR_NEW_ROLE` - // - // - Set AWS_PROFILE=$SINK_PROFILE (for shared profile through AWS_PROFILE) - // - Set TEST_PROFILE=$SINK_PROFILE (for shared profile through WithSharedCredsProfile) - // - Set AWS_REGION and AWS_KMS_WRAPPER_KEY_ID as above - prof := os.Getenv("TEST_PROFILE") - if prof == "" { - t.Skip("TEST_PROFILE required for shared profile from WithSharedCredsProfile test") - } + s.Run("Success - shared profile from WithSharedCredsProfile", func() { + prof := os.Getenv("TEST_PROFILE") + if prof == "" { + s.T().Skip("TEST_PROFILE required for shared profile from WithSharedCredsProfile test") + } + // Prevent AWS_PROFILE from clobbering this test + if old := os.Getenv(envAwsProfile); old != "" { + os.Setenv(envAwsProfile, "") + defer os.Setenv(envAwsProfile, old) + } - w = NewWrapper() + w := NewWrapper() - _, err = w.SetConfig(t.Context(), WithSharedCredsProfile(prof)) - require.NoError(t, err) + _, err := w.SetConfig(s.T().Context(), WithSharedCredsProfile(prof)) + s.Require().NoError(err) - testEncryptionRoundTrip(t, w) + encryptionRoundTrip(s, w) + }) - os.Setenv(envAwsProfile, old) + s.Run("Success - shared profile from AWS_PROFILE", func() { + // Default awskms config pulls shared creds from AWS_PROFILE if it's set + if os.Getenv(envAwsProfile) == "" { + s.T().Skip("AWS_PROFILE required for shared profile from AWS_PROFILE test") + } - // Test shared profile from env - // Default awskms config pulls shared creds from AWS_PROFILE if it's set - if os.Getenv(envAwsProfile) == "" { - t.Skip("AWS_PROFILE required for shared profile from AWS_PROFILE test") - } + w := NewWrapper() + _, err := w.SetConfig(s.T().Context()) + s.Require().NoError(err) + encryptionRoundTrip(s, w) + }) + + s.Run("Failure - no shared config", func() { + if old := os.Getenv(envAwsProfile); old != "" { + os.Setenv(envAwsProfile, "") + defer os.Setenv(envAwsProfile, old) + } + + w := NewWrapper() + + _, err := w.SetConfig(s.T().Context(), WithSharedCredsProfile("this-profile-definitely-doesn't-exist")) + s.Require().Error(err) + }) - w = NewWrapper() - _, err = w.SetConfig(t.Context()) - require.NoError(t, err) - testEncryptionRoundTrip(t, w) } -func NewAwsKmsTestWrapper() *Wrapper { - s := NewWrapper() - s.client = &mockClient{ - keyId: awsTestKeyId, - } - return s +func encryptionRoundTrip(s *AwsKmsSuite, w *Wrapper) { + _, err := w.SetConfig(s.T().Context()) + s.Require().NoError(err) + + expected := []byte("foo") + swi, err := w.Encrypt(context.Background(), expected, nil) + s.Require().NoError(err) + + output, err := w.Decrypt(context.Background(), swi, nil) + s.Require().NoError(err) + s.Assert().Equal(expected, output) } From 025170cb3d9ed958881191c5c481fbf4493f93b3 Mon Sep 17 00:00:00 2001 From: Johan Brandhorst-Satzkorn Date: Tue, 21 Oct 2025 13:30:54 -0700 Subject: [PATCH 3/5] wrappers/awskms: replace use of suite (#294) Instead of using a test suite, use vanilla require and assert packages for assertions and standard library testing patterns for tests and sub tests. --- wrappers/awskms/awskms_test.go | 196 +++++++++++++++++---------------- 1 file changed, 104 insertions(+), 92 deletions(-) diff --git a/wrappers/awskms/awskms_test.go b/wrappers/awskms/awskms_test.go index c62043c7..05b2e3cb 100644 --- a/wrappers/awskms/awskms_test.go +++ b/wrappers/awskms/awskms_test.go @@ -9,9 +9,8 @@ import ( "testing" wrapping "github.com/hashicorp/go-kms-wrapping/v2" - "github.com/stretchr/testify/suite" - - "go.uber.org/mock/gomock" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) const ( @@ -20,56 +19,50 @@ const ( envAwsRegion = "AWS_REGION" ) -type AwsKmsSuite struct { - suite.Suite - ctrl *gomock.Controller - wrapperWithMock *Wrapper -} - -func TestSuite(t *testing.T) { - suite.Run(t, new(AwsKmsSuite)) -} - -func (s *AwsKmsSuite) SetupSubTest() { - s.ctrl = gomock.NewController(s.T()) - s.wrapperWithMock = NewWrapper() - s.wrapperWithMock.client = &mockClient{ - keyId: awsTestKeyId, - } -} - -func (s *AwsKmsSuite) TestSetConfig() { +func TestSetConfig(t *testing.T) { // Works around lack of AWS_REGION var in CI if os.Getenv(envAwsRegion) == "" { os.Setenv(envAwsRegion, "us-west-2") defer os.Setenv(envAwsRegion, "") } - s.Run("Failure - No wrapper key ID", func() { + t.Run("Failure - No wrapper key ID", func(t *testing.T) { + wrapperWithMock := NewWrapper() + wrapperWithMock.client = &mockClient{ + keyId: awsTestKeyId, + } oldKeyId := os.Getenv(EnvAwsKmsWrapperKeyId) os.Setenv(EnvAwsKmsWrapperKeyId, "") defer os.Setenv(EnvAwsKmsWrapperKeyId, oldKeyId) - _, err := s.wrapperWithMock.SetConfig(context.Background()) - s.Require().Error(err, "expected error when AwsKms wrapping key ID is not provided") + _, err := wrapperWithMock.SetConfig(context.Background()) + require.Error(t, err, "expected error when AwsKms wrapping key ID is not provided") }) - s.Run("Success - Test key ID pulled from environment variables", func() { + t.Run("Success - Test key ID pulled from environment variables", func(t *testing.T) { + wrapperWithMock := NewWrapper() + wrapperWithMock.client = &mockClient{ + keyId: awsTestKeyId, + } oldKeyId := os.Getenv(EnvAwsKmsWrapperKeyId) os.Setenv(EnvAwsKmsWrapperKeyId, awsTestKeyId) defer os.Setenv(EnvAwsKmsWrapperKeyId, oldKeyId) - _, err := s.wrapperWithMock.SetConfig(context.Background()) - s.Require().NoError(err) + _, err := wrapperWithMock.SetConfig(context.Background()) + require.NoError(t, err) }) - s.Run("Success - Ignore environment variables", func() { + t.Run("Success - Ignore environment variables", func(t *testing.T) { // Setup environment values to ignore for the following values for _, envVar := range []string{EnvAwsKmsWrapperKeyId, EnvVaultAwsKmsSealKeyId, EnvAwsKmsEndpoint, EnvAwsKmsEndpoint} { oldVal := os.Getenv(envVar) os.Setenv(envVar, "") defer os.Setenv(envVar, oldVal) } + wrapperWithMock := NewWrapper() + wrapperWithMock.client = &mockClient{ + keyId: awsTestKeyId, + } config := map[string]string{ "disallow_env_vars": "true", @@ -79,83 +72,103 @@ func (s *AwsKmsSuite) TestSetConfig() { "endpoint": "my-endpoint", } - _, err := s.wrapperWithMock.SetConfig(context.Background(), wrapping.WithConfigMap(config)) - s.Require().NoError(err) + _, err := wrapperWithMock.SetConfig(context.Background(), wrapping.WithConfigMap(config)) + require.NoError(t, err) - s.Require().Equal(config["access_key"], s.wrapperWithMock.accessKey) - s.Require().Equal(config["secret_key"], s.wrapperWithMock.secretKey) - s.Require().Equal(config["kms_key_id"], s.wrapperWithMock.keyId) - s.Require().Equal(config["endpoint"], s.wrapperWithMock.endpoint) + require.Equal(t, config["access_key"], wrapperWithMock.accessKey) + require.Equal(t, config["secret_key"], wrapperWithMock.secretKey) + require.Equal(t, config["kms_key_id"], wrapperWithMock.keyId) + require.Equal(t, config["endpoint"], wrapperWithMock.endpoint) }) - s.Run("Success - endpoint set automatically", func() { - _, err := s.wrapperWithMock.SetConfig(s.T().Context(), WithKeyNotRequired(true)) - s.Require().NoError(err) + t.Run("Success - endpoint set automatically", func(t *testing.T) { + wrapperWithMock := NewWrapper() + wrapperWithMock.client = &mockClient{ + keyId: awsTestKeyId, + } + _, err := wrapperWithMock.SetConfig(t.Context(), WithKeyNotRequired(true)) + require.NoError(t, err) - c, err := s.wrapperWithMock.GetAwsKmsClient(s.T().Context()) - s.Require().NoError(err) - s.Assert().Nil(c.Options().BaseEndpoint) + c, err := wrapperWithMock.GetAwsKmsClient(t.Context()) + require.NoError(t, err) + require.Nil(t, c.Options().BaseEndpoint) }) - s.Run("Success - custom endpoint set from environment variables", func() { + t.Run("Success - custom endpoint set from environment variables", func(t *testing.T) { expectedEndpoint := "https://example.com/0" oldEndpoint := os.Getenv(EnvAwsKmsEndpoint) os.Setenv(EnvAwsKmsEndpoint, expectedEndpoint) defer os.Setenv(EnvAwsKmsEndpoint, oldEndpoint) + wrapperWithMock := NewWrapper() + wrapperWithMock.client = &mockClient{ + keyId: awsTestKeyId, + } - _, err := s.wrapperWithMock.SetConfig(s.T().Context(), WithKeyNotRequired(true)) - s.Require().NoError(err) + _, err := wrapperWithMock.SetConfig(t.Context(), WithKeyNotRequired(true)) + require.NoError(t, err) - c, err := s.wrapperWithMock.GetAwsKmsClient(s.T().Context()) - s.Require().NoError(err) - s.Assert().Equal(expectedEndpoint, *(c.Options().BaseEndpoint)) + c, err := wrapperWithMock.GetAwsKmsClient(t.Context()) + require.NoError(t, err) + assert.Equal(t, expectedEndpoint, *(c.Options().BaseEndpoint)) }) - s.Run("Success - custom endpoint set from config", func() { + t.Run("Success - custom endpoint set from config", func(t *testing.T) { expectedEndpoint := "https://example.com/1" cfg := map[string]string{ "endpoint": expectedEndpoint, } + wrapperWithMock := NewWrapper() + wrapperWithMock.client = &mockClient{ + keyId: awsTestKeyId, + } - _, err := s.wrapperWithMock.SetConfig(s.T().Context(), wrapping.WithConfigMap(cfg), WithKeyNotRequired(true)) - s.Require().NoError(err) + _, err := wrapperWithMock.SetConfig(t.Context(), wrapping.WithConfigMap(cfg), WithKeyNotRequired(true)) + require.NoError(t, err) - c, err := s.wrapperWithMock.GetAwsKmsClient(s.T().Context()) - s.Require().NoError(err) - s.Assert().Equal(expectedEndpoint, *(c.Options().BaseEndpoint)) + c, err := wrapperWithMock.GetAwsKmsClient(t.Context()) + require.NoError(t, err) + assert.Equal(t, expectedEndpoint, *(c.Options().BaseEndpoint)) }) - s.Run("Success - custom endpoint set from environment variables taking precedence over config", func() { + t.Run("Success - custom endpoint set from environment variables taking precedence over config", func(t *testing.T) { expectedEndpoint := "https://example.com/2" oldEndpoint := os.Getenv(EnvAwsKmsEndpoint) os.Setenv(EnvAwsKmsEndpoint, expectedEndpoint) defer os.Setenv(EnvAwsKmsEndpoint, oldEndpoint) + wrapperWithMock := NewWrapper() + wrapperWithMock.client = &mockClient{ + keyId: awsTestKeyId, + } cfg := map[string]string{ "endpoint": "https://example.com/3", } - _, err := s.wrapperWithMock.SetConfig(s.T().Context(), wrapping.WithConfigMap(cfg), WithKeyNotRequired(true)) - s.Require().NoError(err) + _, err := wrapperWithMock.SetConfig(t.Context(), wrapping.WithConfigMap(cfg), WithKeyNotRequired(true)) + require.NoError(t, err) - c, err := s.wrapperWithMock.GetAwsKmsClient(s.T().Context()) - s.Require().NoError(err) - s.Assert().Equal(expectedEndpoint, *(c.Options().BaseEndpoint)) + c, err := wrapperWithMock.GetAwsKmsClient(t.Context()) + require.NoError(t, err) + assert.Equal(t, expectedEndpoint, *(c.Options().BaseEndpoint)) }) } -func (s *AwsKmsSuite) TestEncryptAndDecrypt() { - s.Run("Success - mock client", func() { +func TestEncryptAndDecrypt(t *testing.T) { + t.Run("Success - mock client", func(t *testing.T) { // Works around lack of AWS_REGION var in CI if os.Getenv(envAwsRegion) == "" { os.Setenv(envAwsRegion, "us-west-2") defer os.Setenv(envAwsRegion, "") } + wrapperWithMock := NewWrapper() + wrapperWithMock.client = &mockClient{ + keyId: awsTestKeyId, + } oldKeyId := os.Getenv(EnvAwsKmsWrapperKeyId) os.Setenv(EnvAwsKmsWrapperKeyId, awsTestKeyId) defer os.Setenv(EnvAwsKmsWrapperKeyId, oldKeyId) - encryptionRoundTrip(s, s.wrapperWithMock) + encryptionRoundTrip(t, wrapperWithMock) }) // To run the concrete enryption test, the following env variables need to be set: // - AWSKMS_WRAPPER_KEY_ID or VAULT_AWSKMS_SEAL_KEY_ID @@ -166,25 +179,25 @@ func (s *AwsKmsSuite) TestEncryptAndDecrypt() { // - AWS_REGION // - Works around https://hashicorp.atlassian.net/browse/ICU-17849 - s.Run("Success - concrete client", func() { + t.Run("Success - concrete client", func(t *testing.T) { if os.Getenv(EnvAwsKmsWrapperKeyId) == "" && os.Getenv(EnvVaultAwsKmsSealKeyId) == "" { - s.T().Skip("AWSKMS_WRAPPER_KEY_ID or VAULT_AWSKMS_SEAL_KEY_ID required for concrete encryption test") + t.Skip("AWSKMS_WRAPPER_KEY_ID or VAULT_AWSKMS_SEAL_KEY_ID required for concrete encryption test") } if os.Getenv("AWS_ACCESS_KEY_ID") == "" { - s.T().Skip("AWS_ACCESS_KEY_ID required for concrete encryption test") + t.Skip("AWS_ACCESS_KEY_ID required for concrete encryption test") } if os.Getenv("AWS_SECRET_ACCESS_KEY") == "" { - s.T().Skip("AWS_SECRET_ACCESS_KEY required for concrete encryption test") + t.Skip("AWS_SECRET_ACCESS_KEY required for concrete encryption test") } if os.Getenv("AWS_SESSION_TOKEN") == "" { - s.T().Skip("AWS_SESSION_TOKEN required for concrete encryption test") + t.Skip("AWS_SESSION_TOKEN required for concrete encryption test") } if os.Getenv("AWS_REGION") == "" { - s.T().Skip("AWS_REGION required for concrete encryption test") + t.Skip("AWS_REGION required for concrete encryption test") } w := NewWrapper() - encryptionRoundTrip(s, w) + encryptionRoundTrip(t, w) }) } @@ -197,18 +210,18 @@ func (s *AwsKmsSuite) TestEncryptAndDecrypt() { // - Set AWS_PROFILE=$SINK_PROFILE (for shared profile through AWS_PROFILE) // - Set TEST_PROFILE=$SINK_PROFILE (for shared profile through WithSharedCredsProfile) // - Set AWS_REGION and AWS_KMS_WRAPPER_KEY_ID as above -func (s *AwsKmsSuite) TestSharedProfiles() { +func TestSharedProfiles(t *testing.T) { if os.Getenv("AWS_REGION") == "" { - s.T().Skip("AWS_REGION required for shared profiles tests") + t.Skip("AWS_REGION required for shared profiles tests") } if os.Getenv(EnvAwsKmsWrapperKeyId) == "" && os.Getenv(EnvVaultAwsKmsSealKeyId) == "" { - s.T().Skip("AWSKMS_WRAPPER_KEY_ID or VAULT_AWSKMS_SEAL_KEY_ID required for shared profiles tests") + t.Skip("AWSKMS_WRAPPER_KEY_ID or VAULT_AWSKMS_SEAL_KEY_ID required for shared profiles tests") } - s.Run("Success - shared profile from WithSharedCredsProfile", func() { + t.Run("Success - shared profile from WithSharedCredsProfile", func(t *testing.T) { prof := os.Getenv("TEST_PROFILE") if prof == "" { - s.T().Skip("TEST_PROFILE required for shared profile from WithSharedCredsProfile test") + t.Skip("TEST_PROFILE required for shared profile from WithSharedCredsProfile test") } // Prevent AWS_PROFILE from clobbering this test if old := os.Getenv(envAwsProfile); old != "" { @@ -218,25 +231,25 @@ func (s *AwsKmsSuite) TestSharedProfiles() { w := NewWrapper() - _, err := w.SetConfig(s.T().Context(), WithSharedCredsProfile(prof)) - s.Require().NoError(err) + _, err := w.SetConfig(t.Context(), WithSharedCredsProfile(prof)) + require.NoError(t, err) - encryptionRoundTrip(s, w) + encryptionRoundTrip(t, w) }) - s.Run("Success - shared profile from AWS_PROFILE", func() { + t.Run("Success - shared profile from AWS_PROFILE", func(t *testing.T) { // Default awskms config pulls shared creds from AWS_PROFILE if it's set if os.Getenv(envAwsProfile) == "" { - s.T().Skip("AWS_PROFILE required for shared profile from AWS_PROFILE test") + t.Skip("AWS_PROFILE required for shared profile from AWS_PROFILE test") } w := NewWrapper() - _, err := w.SetConfig(s.T().Context()) - s.Require().NoError(err) - encryptionRoundTrip(s, w) + _, err := w.SetConfig(t.Context()) + require.NoError(t, err) + encryptionRoundTrip(t, w) }) - s.Run("Failure - no shared config", func() { + t.Run("Failure - no shared config", func(t *testing.T) { if old := os.Getenv(envAwsProfile); old != "" { os.Setenv(envAwsProfile, "") defer os.Setenv(envAwsProfile, old) @@ -244,21 +257,20 @@ func (s *AwsKmsSuite) TestSharedProfiles() { w := NewWrapper() - _, err := w.SetConfig(s.T().Context(), WithSharedCredsProfile("this-profile-definitely-doesn't-exist")) - s.Require().Error(err) + _, err := w.SetConfig(t.Context(), WithSharedCredsProfile("this-profile-definitely-doesn't-exist")) + require.Error(t, err) }) - } -func encryptionRoundTrip(s *AwsKmsSuite, w *Wrapper) { - _, err := w.SetConfig(s.T().Context()) - s.Require().NoError(err) +func encryptionRoundTrip(t *testing.T, w *Wrapper) { + _, err := w.SetConfig(t.Context()) + require.NoError(t, err) expected := []byte("foo") swi, err := w.Encrypt(context.Background(), expected, nil) - s.Require().NoError(err) + require.NoError(t, err) output, err := w.Decrypt(context.Background(), swi, nil) - s.Require().NoError(err) - s.Assert().Equal(expected, output) + require.NoError(t, err) + assert.Equal(t, expected, output) } From e45cacbb4f7c9a8ee20da0ebb177b110d668c04d Mon Sep 17 00:00:00 2001 From: Emilia Date: Wed, 22 Oct 2025 11:23:30 -0600 Subject: [PATCH 4/5] update comment on KmsApi Co-authored-by: Johan Brandhorst-Satzkorn --- wrappers/awskms/awskms.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wrappers/awskms/awskms.go b/wrappers/awskms/awskms.go index 8055ebd0..d1b10979 100644 --- a/wrappers/awskms/awskms.go +++ b/wrappers/awskms/awskms.go @@ -57,7 +57,7 @@ type Wrapper struct { logger hclog.Logger } -// Replaces aws-sdk v1's iface package interfaces +// KmsApi defines the functionality expected to be implemented by the AWS SDK v2 kms package. type KmsApi interface { Encrypt(ctx context.Context, input *kms.EncryptInput, opts ...func(*kms.Options)) (*kms.EncryptOutput, error) Decrypt(ctx context.Context, input *kms.DecryptInput, opts ...func(*kms.Options)) (*kms.DecryptOutput, error) From 2e47dfb203b8b9ca62f01b6b35316fc8aa5e1271 Mon Sep 17 00:00:00 2001 From: Emilia Grant Date: Thu, 6 Nov 2025 08:57:22 -0700 Subject: [PATCH 5/5] update go-secure-stdlib --- wrappers/awskms/go.mod | 2 +- wrappers/awskms/go.sum | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/wrappers/awskms/go.mod b/wrappers/awskms/go.mod index 59309880..a4da2259 100644 --- a/wrappers/awskms/go.mod +++ b/wrappers/awskms/go.mod @@ -9,7 +9,7 @@ require ( github.com/hashicorp/go-cleanhttp v0.5.2 github.com/hashicorp/go-hclog v1.6.3 github.com/hashicorp/go-kms-wrapping/v2 v2.0.18 - github.com/hashicorp/go-secure-stdlib/awsutil/v2 v2.1.0 + github.com/hashicorp/go-secure-stdlib/awsutil/v2 v2.1.1 github.com/stretchr/testify v1.11.1 go.uber.org/mock v0.6.0 ) diff --git a/wrappers/awskms/go.sum b/wrappers/awskms/go.sum index aaa17d0d..b586aaff 100644 --- a/wrappers/awskms/go.sum +++ b/wrappers/awskms/go.sum @@ -1,33 +1,63 @@ github.com/aws/aws-sdk-go-v2 v1.39.2 h1:EJLg8IdbzgeD7xgvZ+I8M1e0fL0ptn/M47lianzth0I= github.com/aws/aws-sdk-go-v2 v1.39.2/go.mod h1:sDioUELIUO9Znk23YVmIk86/9DOpkbyyVb1i/gUNFXY= +github.com/aws/aws-sdk-go-v2 v1.39.6 h1:2JrPCVgWJm7bm83BDwY5z8ietmeJUbh3O2ACnn+Xsqk= +github.com/aws/aws-sdk-go-v2 v1.39.6/go.mod h1:c9pm7VwuW0UPxAEYGyTmyurVcNrbF6Rt/wixFqDhcjE= github.com/aws/aws-sdk-go-v2/config v1.31.12 h1:pYM1Qgy0dKZLHX2cXslNacbcEFMkDMl+Bcj5ROuS6p8= github.com/aws/aws-sdk-go-v2/config v1.31.12/go.mod h1:/MM0dyD7KSDPR+39p9ZNVKaHDLb9qnfDurvVS2KAhN8= +github.com/aws/aws-sdk-go-v2/config v1.31.17 h1:QFl8lL6RgakNK86vusim14P2k8BFSxjvUkcWLDjgz9Y= +github.com/aws/aws-sdk-go-v2/config v1.31.17/go.mod h1:V8P7ILjp/Uef/aX8TjGk6OHZN6IKPM5YW6S78QnRD5c= github.com/aws/aws-sdk-go-v2/credentials v1.18.16 h1:4JHirI4zp958zC026Sm+V4pSDwW4pwLefKrc0bF2lwI= github.com/aws/aws-sdk-go-v2/credentials v1.18.16/go.mod h1:qQMtGx9OSw7ty1yLclzLxXCRbrkjWAM7JnObZjmCB7I= +github.com/aws/aws-sdk-go-v2/credentials v1.18.21 h1:56HGpsgnmD+2/KpG0ikvvR8+3v3COCwaF4r+oWwOeNA= +github.com/aws/aws-sdk-go-v2/credentials v1.18.21/go.mod h1:3YELwedmQbw7cXNaII2Wywd+YY58AmLPwX4LzARgmmA= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.9 h1:Mv4Bc0mWmv6oDuSWTKnk+wgeqPL5DRFu5bQL9BGPQ8Y= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.9/go.mod h1:IKlKfRppK2a1y0gy1yH6zD+yX5uplJ6UuPlgd48dJiQ= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.13 h1:T1brd5dR3/fzNFAQch/iBKeX07/ffu/cLu+q+RuzEWk= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.13/go.mod h1:Peg/GBAQ6JDt+RoBf4meB1wylmAipb7Kg2ZFakZTlwk= github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.9 h1:se2vOWGD3dWQUtfn4wEjRQJb1HK1XsNIt825gskZ970= github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.9/go.mod h1:hijCGH2VfbZQxqCDN7bwz/4dzxV+hkyhjawAtdPWKZA= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.13 h1:a+8/MLcWlIxo1lF9xaGt3J/u3yOZx+CdSveSNwjhD40= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.13/go.mod h1:oGnKwIYZ4XttyU2JWxFrwvhF6YKiK/9/wmE3v3Iu9K8= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.9 h1:6RBnKZLkJM4hQ+kN6E7yWFveOTg8NLPHAkqrs4ZPlTU= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.9/go.mod h1:V9rQKRmK7AWuEsOMnHzKj8WyrIir1yUJbZxDuZLFvXI= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.13 h1:HBSI2kDkMdWz4ZM7FjwE7e/pWDEZ+nR95x8Ztet1ooY= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.13/go.mod h1:YE94ZoDArI7awZqJzBAZ3PDD2zSfuP7w6P2knOzIn8M= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo= +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/service/iam v1.47.7 h1:0EDAdmMTzsgXl++8a0JZ+Yx0/dOqT8o/EONknxlQK94= github.com/aws/aws-sdk-go-v2/service/iam v1.47.7/go.mod h1:NkNbn/8/mFrPUq0Kg6EM6c0+GaTLG+aPzXxwB7RF5xo= +github.com/aws/aws-sdk-go-v2/service/iam v1.49.2 h1:XeF6yEMX4/FxoSHCE1VNMOZ0t+mGnf/onqVe9dDVAlQ= +github.com/aws/aws-sdk-go-v2/service/iam v1.49.2/go.mod h1:cuEMbL1mNtO1sUyT+DYDNIA8Y7aJG1oIdgHqUk29Uzk= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.1 h1:oegbebPEMA/1Jny7kvwejowCaHz1FWZAQ94WXFNCyTM= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.1/go.mod h1:kemo5Myr9ac0U9JfSjMo9yHLtw+pECEHsFtJ9tqCEI8= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.3 h1:x2Ibm/Af8Fi+BH+Hsn9TXGdT+hKbDd5XOTZxTMxDk7o= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.3/go.mod h1:IW1jwyrQgMdhisceG8fQLmQIydcT/jWY21rFhzgaKwo= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.9 h1:5r34CgVOD4WZudeEKZ9/iKpiT6cM1JyEROpXjOcdWv8= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.9/go.mod h1:dB12CEbNWPbzO2uC6QSWHteqOg4JfBVJOojbAoAUb5I= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.13 h1:kDqdFvMY4AtKoACfzIGD8A0+hbT41KTKF//gq7jITfM= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.13/go.mod h1:lmKuogqSU3HzQCwZ9ZtcqOc5XGMqtDK7OIc2+DxiUEg= github.com/aws/aws-sdk-go-v2/service/kms v1.45.6 h1:Br3kil4j7RPW+7LoLVkYt8SuhIWlg6ylmbmzXJ7PgXY= github.com/aws/aws-sdk-go-v2/service/kms v1.45.6/go.mod h1:FKXkHzw1fJZtg1P1qoAIiwen5thz/cDRTTDCIu8ljxc= +github.com/aws/aws-sdk-go-v2/service/kms v1.47.1 h1:6+C0RoGF4HJQALrsecOXN7cm/l5rgNHCw2xbcvFgpH4= +github.com/aws/aws-sdk-go-v2/service/kms v1.47.1/go.mod h1:VJcNH6BLr+3VJwinRKdotLOMglHO8mIKlD3ea5c7hbw= github.com/aws/aws-sdk-go-v2/service/sso v1.29.6 h1:A1oRkiSQOWstGh61y4Wc/yQ04sqrQZr1Si/oAXj20/s= github.com/aws/aws-sdk-go-v2/service/sso v1.29.6/go.mod h1:5PfYspyCU5Vw1wNPsxi15LZovOnULudOQuVxphSflQA= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.1 h1:0JPwLz1J+5lEOfy/g0SURC9cxhbQ1lIMHMa+AHZSzz0= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.1/go.mod h1:fKvyjJcz63iL/ftA6RaM8sRCtN4r4zl4tjL3qw5ec7k= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.1 h1:5fm5RTONng73/QA73LhCNR7UT9RpFH3hR6HWL6bIgVY= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.1/go.mod h1:xBEjWD13h+6nq+z4AkqSfSvqRKFgDIQeaMguAJndOWo= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.5 h1:OWs0/j2UYR5LOGi88sD5/lhN6TDLG6SfA7CqsQO9zF0= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.5/go.mod h1:klO+ejMvYsB4QATfEOIXk8WAEwN4N0aBfJpvC+5SZBo= github.com/aws/aws-sdk-go-v2/service/sts v1.38.6 h1:p3jIvqYwUZgu/XYeI48bJxOhvm47hZb5HUQ0tn6Q9kA= github.com/aws/aws-sdk-go-v2/service/sts v1.38.6/go.mod h1:WtKK+ppze5yKPkZ0XwqIVWD4beCwv056ZbPQNoeHqM8= +github.com/aws/aws-sdk-go-v2/service/sts v1.39.1 h1:mLlUgHn02ue8whiR4BmxxGJLR2gwU6s6ZzJ5wDamBUs= +github.com/aws/aws-sdk-go-v2/service/sts v1.39.1/go.mod h1:E19xDjpzPZC7LS2knI9E6BaRFDK43Eul7vd6rSq2HWk= github.com/aws/smithy-go v1.23.0 h1:8n6I3gXzWJB2DxBDnfxgBaSX6oe0d/t10qGz7OKqMCE= github.com/aws/smithy-go v1.23.0/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI= +github.com/aws/smithy-go v1.23.2 h1:Crv0eatJUQhaManss33hS5r40CG3ZFH+21XSkqMrIUM= +github.com/aws/smithy-go v1.23.2/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -46,10 +76,14 @@ github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB1 github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-kms-wrapping/v2 v2.0.18 h1:DLfC677GfKEpSAFpEWvl1vXsGpEcSHmbhBaPLrdDQHc= github.com/hashicorp/go-kms-wrapping/v2 v2.0.18/go.mod h1:t/eaR/mi2mw3klfl1WEAuiLKrlZ/Q8cosmsT+RIPLu0= +github.com/hashicorp/go-kms-wrapping/v2 v2.0.19 h1:FX7HrkfkYomf4SlMrwzOP32FXuFltq34Qy/gXk1Tp5Y= +github.com/hashicorp/go-kms-wrapping/v2 v2.0.19/go.mod h1:wpZygQlPUUGt4Klgg+RlCaq/KRe8XinEzqTf7QmvrNo= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-secure-stdlib/awsutil/v2 v2.1.0 h1:V3TJFolOHYSDqQLbTUBygXtbX4jKXyBcDoU+KNZE1Ak= github.com/hashicorp/go-secure-stdlib/awsutil/v2 v2.1.0/go.mod h1:OeRwM2eWNW62L1Z+8GvoZM5nQJMRWBewHSoo77qmb4Y= +github.com/hashicorp/go-secure-stdlib/awsutil/v2 v2.1.1 h1:rXE5JmHT14VYLVm+hHSqBOojPl0rlBqJx6YLikUuCgM= +github.com/hashicorp/go-secure-stdlib/awsutil/v2 v2.1.1/go.mod h1:6+rVulOPNCQbL3Xv2iLCqM0JmU2WO2wRzP1C6hBKeB8= github.com/hashicorp/go-secure-stdlib/parseutil v0.2.0 h1:U+kC2dOhMFQctRfhK0gRctKAPTloZdMU5ZJxaesJ/VM= github.com/hashicorp/go-secure-stdlib/parseutil v0.2.0/go.mod h1:Ll013mhdmsVDuoIXVfBtvgGJsXDYkTw1kooNcoCXuE0= github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts= @@ -92,6 +126,8 @@ golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= +golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=