From 5680f13cff333d7d0dbf38b7c25b05f1f036ccf5 Mon Sep 17 00:00:00 2001 From: michaelhtm <98621731+michaelhtm@users.noreply.github.com> Date: Tue, 29 Jul 2025 15:49:22 -0700 Subject: [PATCH] feat: Store resource partition in Status --- templates/pkg/resource/identifiers.go.tpl | 9 +++++ templates/pkg/resource/manager.go.tpl | 8 +++- templates/pkg/resource/manager_factory.go.tpl | 40 +++++++++++++------ templates/pkg/resource/sdk.go.tpl | 3 ++ 4 files changed, 45 insertions(+), 15 deletions(-) diff --git a/templates/pkg/resource/identifiers.go.tpl b/templates/pkg/resource/identifiers.go.tpl index 9b728e78..9cced915 100644 --- a/templates/pkg/resource/identifiers.go.tpl +++ b/templates/pkg/resource/identifiers.go.tpl @@ -40,3 +40,12 @@ func (ri *resourceIdentifiers) Region() *ackv1alpha1.AWSRegion { } return nil } + +// Partition returns the AWS partition in which the reosurce exists, or +// nil if this information is not known. +func (ri *resourceIdentifiers) Partition() *ackv1alpha1.AWSPartition { + if ri.meta != nil { + return ri.meta.Partition + } + return nil +} diff --git a/templates/pkg/resource/manager.go.tpl b/templates/pkg/resource/manager.go.tpl index 01188517..ffb5a9bc 100644 --- a/templates/pkg/resource/manager.go.tpl +++ b/templates/pkg/resource/manager.go.tpl @@ -62,6 +62,8 @@ type resourceManager struct { awsAccountID ackv1alpha1.AWSAccountID // The AWS Region that this resource manager targets awsRegion ackv1alpha1.AWSRegion + // The AWS Partition that this resource manager targets + awsPartition ackv1alpha1.AWSPartition // sdk is a pointer to the AWS service API client exposed by the // aws-sdk-go-v2/services/{alias} package. sdkapi *svcsdk.Client @@ -180,13 +182,13 @@ func (rm *resourceManager) Delete( // name for the resource func (rm *resourceManager) ARNFromName(name string) string { return fmt.Sprintf( - "arn:aws:{{ .ControllerName }}:%s:%s:%s", + "arn:%s:{{ .ControllerName }}:%s:%s:%s", + rm.awsPartition, rm.awsRegion, rm.awsAccountID, name, ) } - // LateInitialize returns an acktypes.AWSResource after setting the late initialized // fields from the readOne call. This method will initialize the optional fields // which were not provided by the k8s user but were defaulted by the AWS service. @@ -413,6 +415,7 @@ func newResourceManager( rr acktypes.Reconciler, id ackv1alpha1.AWSAccountID, region ackv1alpha1.AWSRegion, + partition ackv1alpha1.AWSPartition, ) (*resourceManager, error) { return &resourceManager{ cfg: cfg, @@ -422,6 +425,7 @@ func newResourceManager( rr: rr, awsAccountID: id, awsRegion: region, + awsPartition: partition, sdkapi: svcsdk.NewFromConfig(clientcfg), }, nil } diff --git a/templates/pkg/resource/manager_factory.go.tpl b/templates/pkg/resource/manager_factory.go.tpl index f62f0670..5050ec9c 100644 --- a/templates/pkg/resource/manager_factory.go.tpl +++ b/templates/pkg/resource/manager_factory.go.tpl @@ -30,18 +30,13 @@ func (f *resourceManagerFactory) ResourceDescriptor() acktypes.AWSResourceDescri return &resourceDescriptor{} } -// ManagerFor returns a resource manager object that can manage resources for a -// supplied AWS account -func (f *resourceManagerFactory) ManagerFor( - cfg ackcfg.Config, - clientcfg aws.Config, - log logr.Logger, - metrics *ackmetrics.Metrics, - rr acktypes.Reconciler, +// GetCachedManager returns a manager object that can manage resources for a +// supplied AWS account if it was already created and cached, or nil if not +func (f *resourceManagerFactory) GetCachedManager( id ackv1alpha1.AWSAccountID, region ackv1alpha1.AWSRegion, roleARN ackv1alpha1.AWSResourceName, -) (acktypes.AWSResourceManager, error) { +) acktypes.AWSResourceManager { // We use the account ID, region, and role ARN to uniquely identify a // resource manager. This helps us to avoid creating multiple resource // managers for the same account/region/roleARN combination. @@ -49,15 +44,34 @@ func (f *resourceManagerFactory) ManagerFor( f.RLock() rm, found := f.rmCache[rmId] f.RUnlock() - - if found { - return rm, nil + if !found { + return nil } + return rm +} + +// ManagerFor returns a resource manager object that can manage resources for a +// supplied AWS account +func (f *resourceManagerFactory) ManagerFor( + cfg ackcfg.Config, + clientcfg aws.Config, + log logr.Logger, + metrics *ackmetrics.Metrics, + rr acktypes.Reconciler, + id ackv1alpha1.AWSAccountID, + region ackv1alpha1.AWSRegion, + partition ackv1alpha1.AWSPartition, + roleARN ackv1alpha1.AWSResourceName, +) (acktypes.AWSResourceManager, error) { f.Lock() defer f.Unlock() - rm, err := newResourceManager(cfg, clientcfg, log, metrics, rr, id, region) + // We use the account ID, region, partition, and role ARN to uniquely identify a + // resource manager. This helps us to avoid creating multiple resource + // managers for the same account/region/roleARN combination. + rmId := fmt.Sprintf("%s/%s/%s", id, region, roleARN) + rm, err := newResourceManager(cfg, clientcfg, log, metrics, rr, id, region, partition) if err != nil { return nil, err } diff --git a/templates/pkg/resource/sdk.go.tpl b/templates/pkg/resource/sdk.go.tpl index 25bf7e2e..91a7ace9 100644 --- a/templates/pkg/resource/sdk.go.tpl +++ b/templates/pkg/resource/sdk.go.tpl @@ -201,6 +201,9 @@ func (rm *resourceManager) setStatusDefaults ( if ko.Status.ACKResourceMetadata.Region == nil { ko.Status.ACKResourceMetadata.Region = &rm.awsRegion } + if ko.Status.ACKResourceMetadata.Partition == nil { + ko.Status.ACKResourceMetadata.Partition = &rm.awsPartition + } if ko.Status.ACKResourceMetadata.OwnerAccountID == nil { ko.Status.ACKResourceMetadata.OwnerAccountID = &rm.awsAccountID }