From e096de25e7d548b6bf0067e919ff099f0fcff4b3 Mon Sep 17 00:00:00 2001 From: Grant Spence Date: Tue, 20 Jun 2023 15:59:59 -0400 Subject: [PATCH] OCPBUGS-14998: Only use RoleARN for Route53 API To support Shared VPC, we split the DNS client into public and private providers, the private using the RoleARN (Account A) and the public using the default (Account B). However, the RoleARN only provides API access for Account A's Route53 service, not the ability to describe Account B's ELBs. This fix isolates the RoleARN to only be used with Route53 API services. `pkg/dns/aws/dns.go`: Create a separate Route53 session object that uses the RoleARN when provided. --- pkg/dns/aws/dns.go | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/pkg/dns/aws/dns.go b/pkg/dns/aws/dns.go index 2b6864496..acd4ae172 100644 --- a/pkg/dns/aws/dns.go +++ b/pkg/dns/aws/dns.go @@ -94,7 +94,8 @@ type Config struct { // that is used by SDK to configure the credentials. SharedCredentialFile string - // RoleARN is an optional ARN to use for the AWS client session. + // RoleARN is an optional ARN to use for the AWS client session that is + // intended to only provide access to another account's Route 53 service. RoleARN string // Region is the AWS region ELBs are created in. @@ -144,9 +145,6 @@ func NewProvider(config Config, operatorReleaseVersion string) (*Provider, error Name: "openshift.io/ingress-operator", Fn: request.MakeAddToUserAgentHandler("openshift.io ingress-operator", operatorReleaseVersion), }) - if config.RoleARN != "" { - sess.Config.WithCredentials(stscreds.NewCredentials(sess, config.RoleARN)) - } if len(region) == 0 { if sess.Config.Region != nil { @@ -157,6 +155,31 @@ func NewProvider(config Config, operatorReleaseVersion string) (*Provider, error } } + // When RoleARN is provided, make a copy of the Route 53 session and configure it to use RoleARN. + // RoleARN is intended to only provide access to another account's Route 53 service, not for ELBs. + sessRoute53 := sess + if config.RoleARN != "" { + sessRoute53, err := session.NewSessionWithOptions(sessionOpts) + if err != nil { + return nil, fmt.Errorf("couldn't create AWS client session: %v", err) + } + sessRoute53.Handlers.Build.PushBackNamed(request.NamedHandler{ + Name: "openshift.io/ingress-operator", + Fn: request.MakeAddToUserAgentHandler("openshift.io ingress-operator", operatorReleaseVersion), + }) + + if len(region) == 0 { + if sessRoute53.Config.Region != nil { + region = aws.StringValue(sessRoute53.Config.Region) + log.Info("using region from shared config", "region name", region) + } else { + return nil, fmt.Errorf("region is required") + } + } + + sessRoute53.Config.WithCredentials(stscreds.NewCredentials(sessRoute53, config.RoleARN)) + } + r53Config := aws.NewConfig() // elb requires no special region treatment. elbConfig := aws.NewConfig().WithRegion(region) @@ -238,7 +261,7 @@ func NewProvider(config Config, operatorReleaseVersion string) (*Provider, error // TODO: Add custom endpoint support for elbv2. See the following for details: // https://docs.aws.amazon.com/general/latest/gr/elb.html elbv2: elbv2.New(sess, aws.NewConfig().WithRegion(region)), - route53: route53.New(sess, r53Config), + route53: route53.New(sessRoute53, r53Config), tags: tags, config: config, idsToTags: map[string]map[string]string{},