From 01e3242006ffcbaa48e61cb82a4a883c4a0fae63 Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 23 Jan 2026 10:08:32 -0500 Subject: [PATCH 1/3] fix: set region for package manager and chronicle storage configs --- api/product/secret.go | 20 +------ api/product/util.go | 16 ++++++ api/product/util_test.go | 53 +++++++++++++++++++ .../core/site_controller_chronicle.go | 7 ++- .../core/site_controller_package_manager.go | 1 + 5 files changed, 75 insertions(+), 22 deletions(-) diff --git a/api/product/secret.go b/api/product/secret.go index 2732ae7a..5ea86fdf 100644 --- a/api/product/secret.go +++ b/api/product/secret.go @@ -4,10 +4,8 @@ import ( "context" "encoding/json" "fmt" - "os" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/endpoints" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/secretsmanager" "github.com/pkg/errors" @@ -121,7 +119,7 @@ func GetSecretProviderClassForAllSecrets(p KubernetesOwnerProvider, name, namesp SecretObjects: generateSecretObjects(p, kubernetesSecrets), Parameters: map[string]string{ "objects": secretObjectYaml, - "region": getAWSRegion(), + "region": GetAWSRegion(), }, }, }, nil @@ -137,26 +135,12 @@ const ( SiteSecretNone SiteSecretType = "" ) -// getAWSRegion returns the AWS region to use for secret operations. -// It checks the AWS_REGION environment variable first, then falls back to AWS_DEFAULT_REGION, -// and finally defaults to us-east-2 for backwards compatibility. -func getAWSRegion() string { - if region := os.Getenv("AWS_REGION"); region != "" { - return region - } - if region := os.Getenv("AWS_DEFAULT_REGION"); region != "" { - return region - } - // Fallback to the original hardcoded region for backwards compatibility - return endpoints.UsEast2RegionID -} - func FetchSecret(ctx context.Context, r SomeReconciler, req ctrl.Request, secretType SiteSecretType, vaultName, key string) (string, error) { l := r.GetLogger(ctx) switch secretType { case SiteSecretAws: if sess, err := session.NewSession(&aws.Config{ - Region: aws.String(getAWSRegion()), + Region: aws.String(GetAWSRegion()), }); err != nil { return "", err } else { diff --git a/api/product/util.go b/api/product/util.go index 3b316925..d4774d7b 100644 --- a/api/product/util.go +++ b/api/product/util.go @@ -3,8 +3,10 @@ package product import ( "crypto/sha256" "fmt" + "os" "sort" + "github.com/aws/aws-sdk-go/aws/endpoints" "golang.org/x/exp/maps" corev1 "k8s.io/api/core/v1" ) @@ -89,3 +91,17 @@ func ComputeSha256(in map[string]string) (string, error) { return fmt.Sprintf("%x", h.Sum(nil)), nil } } + +// GetAWSRegion returns the AWS region to use for secret operations. +// It checks the AWS_REGION environment variable first, then falls back to AWS_DEFAULT_REGION, +// and finally defaults to us-east-2 for backwards compatibility. +func GetAWSRegion() string { + if region := os.Getenv("AWS_REGION"); region != "" { + return region + } + if region := os.Getenv("AWS_DEFAULT_REGION"); region != "" { + return region + } + // Fallback to the original hardcoded region for backwards compatibility + return endpoints.UsEast2RegionID +} diff --git a/api/product/util_test.go b/api/product/util_test.go index ad2ee9f9..867a70b4 100644 --- a/api/product/util_test.go +++ b/api/product/util_test.go @@ -1,8 +1,10 @@ package product_test 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" @@ -80,3 +82,54 @@ func TestLabelMerge(t *testing.T) { expected = map[string]string{"vorpal": "sword"} assert.Equal(t, expected, result) } + +func TestGetAWSRegion(t *testing.T) { + tests := []struct { + name string + awsRegion string + awsDefault string + want string + }{ + {"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}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Save original values + origRegion := os.Getenv("AWS_REGION") + origDefault := os.Getenv("AWS_DEFAULT_REGION") + defer func() { + // Restore original values + if origRegion != "" { + os.Setenv("AWS_REGION", origRegion) + } else { + os.Unsetenv("AWS_REGION") + } + if origDefault != "" { + os.Setenv("AWS_DEFAULT_REGION", origDefault) + } else { + os.Unsetenv("AWS_DEFAULT_REGION") + } + }() + + // Set test values + if tt.awsRegion != "" { + os.Setenv("AWS_REGION", tt.awsRegion) + } else { + os.Unsetenv("AWS_REGION") + } + if tt.awsDefault != "" { + os.Setenv("AWS_DEFAULT_REGION", tt.awsDefault) + } else { + os.Unsetenv("AWS_DEFAULT_REGION") + } + + if got := product.GetAWSRegion(); got != tt.want { + t.Errorf("GetAWSRegion() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/internal/controller/core/site_controller_chronicle.go b/internal/controller/core/site_controller_chronicle.go index 6bfd068e..c9017899 100644 --- a/internal/controller/core/site_controller_chronicle.go +++ b/internal/controller/core/site_controller_chronicle.go @@ -6,8 +6,8 @@ import ( "github.com/posit-dev/team-operator/api/core/v1beta1" "github.com/posit-dev/team-operator/api/product" "github.com/posit-dev/team-operator/internal" - "k8s.io/apimachinery/pkg/apis/meta/v1" - "sigs.k8s.io/controller-runtime" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + controllerruntime "sigs.k8s.io/controller-runtime" ) func (r *SiteReconciler) reconcileChronicle(ctx context.Context, req controllerruntime.Request, site *v1beta1.Site) error { @@ -83,8 +83,7 @@ func (r *SiteReconciler) reconcileChronicle(ctx context.Context, req controllerr Enabled: true, Bucket: site.Spec.Chronicle.S3Bucket, Prefix: site.Name + "/chr-v0", - // TODO: should not be hard-coded - Region: "us-east-2", + Region: product.GetAWSRegion(), } } return nil diff --git a/internal/controller/core/site_controller_package_manager.go b/internal/controller/core/site_controller_package_manager.go index a1ff0188..af0026b2 100644 --- a/internal/controller/core/site_controller_package_manager.go +++ b/internal/controller/core/site_controller_package_manager.go @@ -111,6 +111,7 @@ func (r *SiteReconciler) reconcilePackageManager( } pm.Spec.Config.S3Storage.Bucket = site.Spec.PackageManager.S3Bucket pm.Spec.Config.S3Storage.Prefix = site.Name + "/ppm-v0" + pm.Spec.Config.S3Storage.Region = product.GetAWSRegion() } return nil }); err != nil { From 505bd5ce5c10b0b6cfcffac224903264448a312e Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 23 Jan 2026 10:09:16 -0500 Subject: [PATCH 2/3] chore: gitignore build artifacts and use recommended claude setting --- .claude/settings.json | 2 +- .gitignore | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.claude/settings.json b/.claude/settings.json index 4268e198..16676f7d 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -3,7 +3,7 @@ "allow": [ "Bash(just test)", "Bash(just build)", - "Bash(make *)" + "Bash(make :*)" ] }, "hooks": { diff --git a/.gitignore b/.gitignore index aaadf736..acea8a96 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,9 @@ coverage.* *.coverprofile profile.cov +# Build artifacts +bin/ + # Dependency directories (remove the comment below to include it) # vendor/ From 25a522dacbfabe113025d2df66f5256bfcc86324 Mon Sep 17 00:00:00 2001 From: Tim Date: Fri, 23 Jan 2026 10:53:45 -0500 Subject: [PATCH 3/3] fix: correct comment for moved function --- api/product/util.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/product/util.go b/api/product/util.go index d4774d7b..8b5ff216 100644 --- a/api/product/util.go +++ b/api/product/util.go @@ -92,7 +92,7 @@ func ComputeSha256(in map[string]string) (string, error) { } } -// GetAWSRegion returns the AWS region to use for secret operations. +// GetAWSRegion returns the AWS region. // It checks the AWS_REGION environment variable first, then falls back to AWS_DEFAULT_REGION, // and finally defaults to us-east-2 for backwards compatibility. func GetAWSRegion() string {