From 36807ef79dcb38c259e871d6cba537b225663e7d Mon Sep 17 00:00:00 2001 From: ian-flores Date: Mon, 26 Jan 2026 09:59:46 -0800 Subject: [PATCH 1/2] feat: migrate from aws-sdk-go v1 to v2 Migrate AWS SDK usage from the deprecated aws-sdk-go (v1) to aws-sdk-go-v2. This addresses issue #12. Changes: - Replace session-based auth with config-based auth pattern - Update Secrets Manager client to v2 API - Replace endpoints.UsEast2RegionID with local constant - Remove v1 dependency entirely Closes #12 --- api/product/secret.go | 66 +++++++++++++++++++--------------------- api/product/util.go | 6 ++-- api/product/util_test.go | 3 +- go.mod | 16 ++++++++-- go.sum | 37 ++++++++++++++++------ 5 files changed, 78 insertions(+), 50 deletions(-) diff --git a/api/product/secret.go b/api/product/secret.go index 5ea86fdf..c3dbe96b 100644 --- a/api/product/secret.go +++ b/api/product/secret.go @@ -5,9 +5,9 @@ import ( "encoding/json" "fmt" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/session" - "github.com/aws/aws-sdk-go/service/secretsmanager" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go-v2/service/secretsmanager" "github.com/pkg/errors" v12 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -139,40 +139,36 @@ func FetchSecret(ctx context.Context, r SomeReconciler, req ctrl.Request, secret l := r.GetLogger(ctx) switch secretType { case SiteSecretAws: - if sess, err := session.NewSession(&aws.Config{ - Region: aws.String(GetAWSRegion()), - }); err != nil { + cfg, err := config.LoadDefaultConfig(ctx, config.WithRegion(GetAWSRegion())) + if err != nil { + return "", err + } + sm := secretsmanager.NewFromConfig(cfg) + query := &secretsmanager.GetSecretValueInput{ + SecretId: aws.String(vaultName), + VersionStage: aws.String("AWSCURRENT"), + } + valueOutput, err := sm.GetSecretValue(ctx, query) + if err != nil { + return "", err + } + secretValue := map[string]json.RawMessage{} + if err := json.Unmarshal([]byte(*valueOutput.SecretString), &secretValue); err != nil { + return "", err + } + + rawSecretEntry, ok := secretValue[key] + if !ok { + // failed to find the configured key + return "", errors.New(fmt.Sprintf("could not find the configured key '%s' in secret '%s' with type '%s'", key, vaultName, secretType)) + } + var secretEntry string + if err := json.Unmarshal(rawSecretEntry, &secretEntry); err != nil { + // error unmarshalling secret return "", err - } else { - sm := secretsmanager.New(sess) - query := &secretsmanager.GetSecretValueInput{ - SecretId: aws.String(vaultName), - VersionId: nil, - VersionStage: aws.String("AWSCURRENT"), - } - if valueOutput, err := sm.GetSecretValue(query); err != nil { - return "", err - } else { - secretValue := map[string]json.RawMessage{} - if err := json.Unmarshal([]byte(*valueOutput.SecretString), &secretValue); err != nil { - return "", err - } - - if rawSecretEntry, ok := secretValue[key]; !ok { - // failed to find the configured key - return "", errors.New(fmt.Sprintf("could not find the configured key '%s' in secret '%s' with type '%s'", key, vaultName, secretType)) - } else { - var secretEntry string - if err := json.Unmarshal(rawSecretEntry, &secretEntry); err != nil { - // error unmarshalling secret - return "", err - } else { - // SUCCESS!! we got the secret! - return secretEntry, nil - } - } - } } + // SUCCESS!! we got the secret! + return secretEntry, nil case SiteSecretKubernetes: kubernetesSecretName := client.ObjectKey{Name: vaultName, Namespace: req.Namespace} diff --git a/api/product/util.go b/api/product/util.go index 8b5ff216..c8bc02ca 100644 --- a/api/product/util.go +++ b/api/product/util.go @@ -6,11 +6,13 @@ import ( "os" "sort" - "github.com/aws/aws-sdk-go/aws/endpoints" "golang.org/x/exp/maps" corev1 "k8s.io/api/core/v1" ) +// defaultAWSRegion is the fallback region for backwards compatibility +const defaultAWSRegion = "us-east-2" + func ConcatLists[T any](slices ...[]T) []T { out := []T{} for _, s := range slices { @@ -103,5 +105,5 @@ func GetAWSRegion() string { return region } // Fallback to the original hardcoded region for backwards compatibility - return endpoints.UsEast2RegionID + return defaultAWSRegion } diff --git a/api/product/util_test.go b/api/product/util_test.go index 867a70b4..0bc88511 100644 --- a/api/product/util_test.go +++ b/api/product/util_test.go @@ -4,7 +4,6 @@ import ( "os" "testing" - "github.com/aws/aws-sdk-go/aws/endpoints" "github.com/posit-dev/team-operator/api/product" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -93,7 +92,7 @@ func TestGetAWSRegion(t *testing.T) { {"AWS_REGION set", "us-west-2", "", "us-west-2"}, {"AWS_DEFAULT_REGION set", "", "eu-west-1", "eu-west-1"}, {"Both set, AWS_REGION wins", "us-west-2", "eu-west-1", "us-west-2"}, - {"Neither set, defaults", "", "", endpoints.UsEast2RegionID}, + {"Neither set, defaults", "", "", "us-east-2"}, } for _, tt := range tests { diff --git a/go.mod b/go.mod index 8afe19fe..a369ad87 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,9 @@ go 1.25.3 require ( github.com/BurntSushi/toml v1.5.0 github.com/Masterminds/sprig/v3 v3.3.0 - github.com/aws/aws-sdk-go v1.55.8 + github.com/aws/aws-sdk-go-v2 v1.41.1 + github.com/aws/aws-sdk-go-v2/config v1.32.7 + github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.41.1 github.com/go-logr/logr v1.4.3 github.com/jackc/pgconn v1.14.3 github.com/jackc/pgx/v4 v4.18.3 @@ -40,6 +42,17 @@ require ( dario.cat/mergo v1.0.2 // indirect github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver/v3 v3.4.0 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.19.7 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.17 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.17 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.17 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.17 // indirect + github.com/aws/aws-sdk-go-v2/service/signin v1.0.5 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.30.9 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.13 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.41.6 // indirect github.com/aws/smithy-go v1.24.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect @@ -91,7 +104,6 @@ require ( github.com/jackc/pgproto3/v2 v2.3.3 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect github.com/jackc/pgtype v1.14.4 // indirect - github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/json-iterator/go v1.1.13-0.20220915233716-71ac16282d12 // indirect github.com/maragudk/gomponents v0.22.0 // indirect github.com/mattn/go-colorable v0.1.14 // indirect diff --git a/go.sum b/go.sum index 8370cc47..b4db1ef5 100644 --- a/go.sum +++ b/go.sum @@ -10,8 +10,34 @@ github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1 github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs= github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0= -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.1 h1:ABlyEARCDLN034NhxlRUSZr4l71mh+T5KAeGh6cerhU= +github.com/aws/aws-sdk-go-v2 v1.41.1/go.mod h1:MayyLB8y+buD9hZqkCW3kX1AKq07Y5pXxtgB+rRFhz0= +github.com/aws/aws-sdk-go-v2/config v1.32.7 h1:vxUyWGUwmkQ2g19n7JY/9YL8MfAIl7bTesIUykECXmY= +github.com/aws/aws-sdk-go-v2/config v1.32.7/go.mod h1:2/Qm5vKUU/r7Y+zUk/Ptt2MDAEKAfUtKc1+3U1Mo3oY= +github.com/aws/aws-sdk-go-v2/credentials v1.19.7 h1:tHK47VqqtJxOymRrNtUXN5SP/zUTvZKeLx4tH6PGQc8= +github.com/aws/aws-sdk-go-v2/credentials v1.19.7/go.mod h1:qOZk8sPDrxhf+4Wf4oT2urYJrYt3RejHSzgAquYeppw= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.17 h1:I0GyV8wiYrP8XpA70g1HBcQO1JlQxCMTW9npl5UbDHY= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.17/go.mod h1:tyw7BOl5bBe/oqvoIeECFJjMdzXoa/dfVz3QQ5lgHGA= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.17 h1:xOLELNKGp2vsiteLsvLPwxC+mYmO6OZ8PYgiuPJzF8U= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.17/go.mod h1:5M5CI3D12dNOtH3/mk6minaRwI2/37ifCURZISxA/IQ= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.17 h1:WWLqlh79iO48yLkj1v3ISRNiv+3KdQoZ6JWyfcsyQik= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.17/go.mod h1:EhG22vHRrvF8oXSTYStZhJc1aUgKtnJe+aOiFEV90cM= +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/internal/accept-encoding v1.13.4 h1:0ryTNEdJbzUCEWkVXEXoqlXV72J5keC1GvILMOuD00E= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4/go.mod h1:HQ4qwNZh32C3CBeO6iJLQlgtMzqeG17ziAA/3KDJFow= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.17 h1:RuNSMoozM8oXlgLG/n6WLaFGoea7/CddrCfIiSA+xdY= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.17/go.mod h1:F2xxQ9TZz5gDWsclCtPQscGpP0VUOc8RqgFM3vDENmU= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.41.1 h1:72DBkm/CCuWx2LMHAXvLDkZfzopT3psfAeyZDIt1/yE= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.41.1/go.mod h1:A+oSJxFvzgjZWkpM0mXs3RxB5O1SD6473w3qafOC9eU= +github.com/aws/aws-sdk-go-v2/service/signin v1.0.5 h1:VrhDvQib/i0lxvr3zqlUwLwJP4fpmpyD9wYG1vfSu+Y= +github.com/aws/aws-sdk-go-v2/service/signin v1.0.5/go.mod h1:k029+U8SY30/3/ras4G/Fnv/b88N4mAfliNn08Dem4M= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.9 h1:v6EiMvhEYBoHABfbGB4alOYmCIrcgyPPiBE1wZAEbqk= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.9/go.mod h1:yifAsgBxgJWn3ggx70A3urX2AN49Y5sJTD1UQFlfqBw= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.13 h1:gd84Omyu9JLriJVCbGApcLzVR3XtmC4ZDPcAI6Ftvds= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.13/go.mod h1:sTGThjphYE4Ohw8vJiRStAcu3rbjtXRsdNB0TvZ5wwo= +github.com/aws/aws-sdk-go-v2/service/sts v1.41.6 h1:5fFjR/ToSOzB2OQ/XqWpZBmNvmP/pJ1jOWYlFDJTjRQ= +github.com/aws/aws-sdk-go-v2/service/sts v1.41.6/go.mod h1:qgFDZQSD/Kys7nJnVqYlWKnh0SSdMjAi0uSwON4wgYQ= github.com/aws/smithy-go v1.24.0 h1:LpilSUItNPFr1eY85RYgTIg5eIEPtvFbskaFcmmIUnk= github.com/aws/smithy-go v1.24.0/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -195,10 +221,6 @@ github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0f github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -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/joshdk/go-junit v1.0.0 h1:S86cUKIdwBHWwA6xCmFlf3RTLfVXYQfvanM5Uh+K6GE= github.com/joshdk/go-junit v1.0.0/go.mod h1:TiiV0PqkaNfFXjEiyjWM3XXrhVyCa1K4Zfga6W52ung= github.com/json-iterator/go v1.1.13-0.20220915233716-71ac16282d12 h1:9Nu54bhS/H/Kgo2/7xNSUuC5G28VR8ljfrLKU2G4IjU= @@ -534,9 +556,6 @@ gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:a gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From 4a48b6712c3ff017f206c36608237240ef841f7c Mon Sep 17 00:00:00 2001 From: ian-flores Date: Mon, 26 Jan 2026 10:47:07 -0800 Subject: [PATCH 2/2] fix: add nil check for SecretString in AWS secrets fetch --- api/product/secret.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/api/product/secret.go b/api/product/secret.go index c3dbe96b..c18f707d 100644 --- a/api/product/secret.go +++ b/api/product/secret.go @@ -152,6 +152,9 @@ func FetchSecret(ctx context.Context, r SomeReconciler, req ctrl.Request, secret if err != nil { return "", err } + if valueOutput.SecretString == nil { + return "", errors.New("secret value is nil or stored as binary, expected string") + } secretValue := map[string]json.RawMessage{} if err := json.Unmarshal([]byte(*valueOutput.SecretString), &secretValue); err != nil { return "", err