Skip to content

Commit f7ca6ab

Browse files
committed
feat: retrieve aws partition from callerIdentity
1 parent 445c03f commit f7ca6ab

11 files changed

+148
-40
lines changed

apis/core/v1alpha1/common.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ package v1alpha1
1616
// AWSRegion represents an AWS regional identifier
1717
type AWSRegion string
1818

19+
// AWSPartition represents an AWS partition identifier
20+
type AWSPartition string
21+
1922
// AWSAccountID represents an AWS account identifier
2023
type AWSAccountID string
2124

apis/core/v1alpha1/resource_metadata.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,6 @@ type ResourceMetadata struct {
3232
OwnerAccountID *AWSAccountID `json:"ownerAccountID"`
3333
// Region is the AWS region in which the resource exists or will exist.
3434
Region *AWSRegion `json:"region"`
35+
// Partition is the AWS partition in which the resource exists or will exist
36+
Partition *AWSPartition `json:"partition"`
3537
}

mocks/pkg/types/aws_resource_identifiers.go

Lines changed: 20 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

mocks/pkg/types/aws_resource_manager_factory.go

Lines changed: 29 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

mocks/pkg/types/service_controller.go

Lines changed: 19 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/runtime/adoption_reconciler.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,16 +148,19 @@ func (r *adoptionReconciler) reconcile(ctx context.Context, req ctrlrt.Request)
148148
targetDescriptor := rmf.ResourceDescriptor()
149149
endpointURL := r.getEndpointURL(res)
150150
gvk := targetDescriptor.GroupVersionKind()
151+
partition := ""
151152

152-
awsconfig, err := r.sc.NewAWSConfig(ctx, region, &endpointURL, roleARN, gvk)
153+
// The config pivot to the roleARN will happen if it is not empty.
154+
// in the NewResourceManager
155+
awsconfig, partition, err := r.sc.NewAWSConfig(ctx, region, &endpointURL, roleARN, gvk, partition)
153156
if err != nil {
154157
return err
155158
}
156159

157160
ackrtlog.InfoAdoptedResource(r.log, res, "starting adoption reconciliation")
158161

159162
rm, err := rmf.ManagerFor(
160-
r.cfg, awsconfig, r.log, r.metrics, r, acctID, region, roleARN,
163+
r.cfg, awsconfig, r.log, r.metrics, r, acctID, region, ackv1alpha1.AWSPartition(partition), roleARN,
161164
)
162165
if err != nil {
163166
return err

pkg/runtime/config.go

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"strings"
2121

2222
"github.com/aws/aws-sdk-go-v2/aws"
23+
"github.com/aws/aws-sdk-go-v2/aws/arn"
2324
"github.com/aws/aws-sdk-go-v2/config"
2425
"github.com/aws/aws-sdk-go-v2/credentials/stscreds"
2526
"github.com/aws/aws-sdk-go-v2/service/sts"
@@ -47,7 +48,8 @@ func (c *serviceController) NewAWSConfig(
4748
endpointURL *string,
4849
roleARN ackv1alpha1.AWSResourceName,
4950
groupVersionKind schema.GroupVersionKind,
50-
) (aws.Config, error) {
51+
partition string,
52+
) (aws.Config, string, error) {
5153

5254
val := formatUserAgent(
5355
appName,
@@ -69,19 +71,25 @@ func (c *serviceController) NewAWSConfig(
6971
config.WithHTTPClient(client),
7072
)
7173
if err != nil {
72-
return awsCfg, err
74+
return awsCfg, partition, err
7375
}
7476

7577
if endpointURL != nil && *endpointURL != "" {
7678
awsCfg.BaseEndpoint = endpointURL
7779
}
7880

81+
stsclient := sts.NewFromConfig(awsCfg)
7982
if roleARN != "" {
80-
client := sts.NewFromConfig(awsCfg)
81-
creds := stscreds.NewAssumeRoleProvider(client, string(roleARN))
83+
creds := stscreds.NewAssumeRoleProvider(stsclient, string(roleARN))
8284
awsCfg.Credentials = aws.NewCredentialsCache(creds)
8385
}
84-
return awsCfg, nil
86+
if partition == "" {
87+
partition, err = c.getPartition(ctx, stsclient)
88+
if err != nil {
89+
return awsCfg, partition, nil
90+
}
91+
}
92+
return awsCfg, partition, nil
8593
}
8694

8795
func formatUserAgent(name, version string, extra ...string) string {
@@ -91,3 +99,18 @@ func formatUserAgent(name, version string, extra ...string) string {
9199
}
92100
return ua
93101
}
102+
103+
// getPartition gets the partition of the caller identity
104+
func (c *serviceController) getPartition(ctx context.Context, client *sts.Client) (string, error) {
105+
identity, err := client.GetCallerIdentity(ctx, &sts.GetCallerIdentityInput{})
106+
// what od we do if ARN is nil?
107+
if err != nil || identity.Arn == nil {
108+
return "", err
109+
}
110+
clientArn, err := arn.Parse(*identity.Arn)
111+
if err != nil {
112+
return "", err
113+
}
114+
115+
return clientArn.Partition, nil
116+
}

pkg/runtime/reconciler.go

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -262,25 +262,30 @@ func (r *resourceReconciler) Reconcile(ctx context.Context, req ctrlrt.Request)
262262
region := r.getRegion(desired)
263263
endpointURL := r.getEndpointURL(desired)
264264
gvk := r.rd.GroupVersionKind()
265-
// The config pivot to the roleARN will happen if it is not empty.
266-
// in the NewResourceManager
267-
clientConfig, err := r.sc.NewAWSConfig(ctx, region, &endpointURL, roleARN, gvk)
268-
if err != nil {
269-
return ctrlrt.Result{}, err
270-
}
265+
partition := r.getPartition(desired)
271266

272267
rlog.WithValues(
273268
"account", acctID,
274269
"role", roleARN,
275270
"region", region,
276271
)
277272

278-
rm, err := r.rmf.ManagerFor(
279-
r.cfg, clientConfig, r.log, r.metrics, r, acctID, region, roleARN,
280-
)
281-
if err != nil {
282-
return ctrlrt.Result{}, err
273+
rm := r.rmf.GetCachedManager(acctID, region, roleARN)
274+
if rm == nil {
275+
// The config pivot to the roleARN will happen if it is not empty.
276+
// in the NewResourceManager
277+
clientConfig, partition, err := r.sc.NewAWSConfig(ctx, region, &endpointURL, roleARN, gvk, partition)
278+
if err != nil {
279+
return ctrlrt.Result{}, err
280+
}
281+
rm, err = r.rmf.ManagerFor(
282+
r.cfg, clientConfig, r.log, r.metrics, r, acctID, region, ackv1alpha1.AWSPartition(partition), roleARN,
283+
)
284+
if err != nil {
285+
return ctrlrt.Result{}, err
286+
}
283287
}
288+
284289
latest, err := r.reconcile(ctx, rm, desired)
285290
return r.HandleReconcileError(ctx, desired, latest, err)
286291
}
@@ -1313,6 +1318,20 @@ func (r *resourceReconciler) getRegion(
13131318
return ackv1alpha1.AWSRegion(r.cfg.Region)
13141319
}
13151320

1321+
// getPartition attempts getting the partition from the resource status
1322+
// if it exists
1323+
func (r *resourceReconciler) getPartition(
1324+
res acktypes.AWSResource,
1325+
) string {
1326+
// first try to get the region from the status.resourceMetadata
1327+
metadataRegion := res.Identifiers().Partition()
1328+
if metadataRegion != nil {
1329+
return string(*metadataRegion)
1330+
}
1331+
1332+
return ""
1333+
}
1334+
13161335
// getDeletionPolicy returns the resource's deletion policy based on the default
13171336
// behaviour or any other overriding annotations.
13181337
//

pkg/types/aws_resource_identifiers.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,6 @@ type AWSResourceIdentifiers interface {
2929
ARN() *ackv1alpha1.AWSResourceName
3030
// Region is the AWS region in which the resource exists or will exist.
3131
Region() *ackv1alpha1.AWSRegion
32+
// Partition is the AWS partition in which the resource exists or will exist.
33+
Partition() *ackv1alpha1.AWSPartition
3234
}

pkg/types/aws_resource_manager.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,16 @@ type AWSResourceManagerFactory interface {
112112
Reconciler,
113113
ackv1alpha1.AWSAccountID,
114114
ackv1alpha1.AWSRegion,
115+
ackv1alpha1.AWSPartition,
115116
ackv1alpha1.AWSResourceName,
116117
) (AWSResourceManager, error)
118+
// GetCachedManager returns an AWSResourceManager if it has previously been created
119+
// and cahced, or returns nil if not
120+
GetCachedManager(
121+
ackv1alpha1.AWSAccountID,
122+
ackv1alpha1.AWSRegion,
123+
ackv1alpha1.AWSResourceName,
124+
) AWSResourceManager
117125
// IsAdoptable returns true if the resource is able to be adopted
118126
IsAdoptable() bool
119127
// RequeueOnSuccessSeconds returns true if the resource should be requeued after specified seconds

0 commit comments

Comments
 (0)