Merge pull request #2818 from PG2000/master

support ExternalID in AWS Provider when assuming a role
This commit is contained in:
Kubernetes Prow Robot 2022-08-19 08:41:52 -07:00 committed by GitHub
commit 1f0f004d33
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 29 additions and 6 deletions

View File

@ -200,6 +200,7 @@ func main() {
BatchChangeInterval: cfg.AWSBatchChangeInterval, BatchChangeInterval: cfg.AWSBatchChangeInterval,
EvaluateTargetHealth: cfg.AWSEvaluateTargetHealth, EvaluateTargetHealth: cfg.AWSEvaluateTargetHealth,
AssumeRole: cfg.AWSAssumeRole, AssumeRole: cfg.AWSAssumeRole,
AssumeRoleExternalID: cfg.AWSAssumeRoleExternalID,
APIRetries: cfg.AWSAPIRetries, APIRetries: cfg.AWSAPIRetries,
PreferCNAME: cfg.AWSPreferCNAME, PreferCNAME: cfg.AWSPreferCNAME,
DryRun: cfg.DryRun, DryRun: cfg.DryRun,
@ -212,7 +213,7 @@ func main() {
log.Infof("Registry \"%s\" cannot be used with AWS Cloud Map. Switching to \"aws-sd\".", cfg.Registry) log.Infof("Registry \"%s\" cannot be used with AWS Cloud Map. Switching to \"aws-sd\".", cfg.Registry)
cfg.Registry = "aws-sd" cfg.Registry = "aws-sd"
} }
p, err = awssd.NewAWSSDProvider(domainFilter, cfg.AWSZoneType, cfg.AWSAssumeRole, cfg.DryRun, cfg.AWSSDServiceCleanup, cfg.TXTOwnerID) p, err = awssd.NewAWSSDProvider(domainFilter, cfg.AWSZoneType, cfg.AWSAssumeRole, cfg.AWSAssumeRoleExternalID, cfg.DryRun, cfg.AWSSDServiceCleanup, cfg.TXTOwnerID)
case "azure-dns", "azure": case "azure-dns", "azure":
p, err = azure.NewAzureProvider(cfg.AzureConfigFile, domainFilter, zoneNameFilter, zoneIDFilter, cfg.AzureResourceGroup, cfg.AzureUserAssignedIdentityClientID, cfg.DryRun) p, err = azure.NewAzureProvider(cfg.AzureConfigFile, domainFilter, zoneNameFilter, zoneIDFilter, cfg.AzureResourceGroup, cfg.AzureUserAssignedIdentityClientID, cfg.DryRun)
case "azure-private-dns": case "azure-private-dns":

View File

@ -85,6 +85,7 @@ type Config struct {
AWSZoneType string AWSZoneType string
AWSZoneTagFilter []string AWSZoneTagFilter []string
AWSAssumeRole string AWSAssumeRole string
AWSAssumeRoleExternalID string
AWSBatchChangeSize int AWSBatchChangeSize int
AWSBatchChangeInterval time.Duration AWSBatchChangeInterval time.Duration
AWSEvaluateTargetHealth bool AWSEvaluateTargetHealth bool
@ -231,6 +232,7 @@ var defaultConfig = &Config{
AWSZoneType: "", AWSZoneType: "",
AWSZoneTagFilter: []string{}, AWSZoneTagFilter: []string{},
AWSAssumeRole: "", AWSAssumeRole: "",
AWSAssumeRoleExternalID: "",
AWSBatchChangeSize: 1000, AWSBatchChangeSize: 1000,
AWSBatchChangeInterval: time.Second, AWSBatchChangeInterval: time.Second,
AWSEvaluateTargetHealth: true, AWSEvaluateTargetHealth: true,
@ -429,6 +431,7 @@ func (cfg *Config) ParseFlags(args []string) error {
app.Flag("aws-zone-type", "When using the AWS provider, filter for zones of this type (optional, options: public, private)").Default(defaultConfig.AWSZoneType).EnumVar(&cfg.AWSZoneType, "", "public", "private") app.Flag("aws-zone-type", "When using the AWS provider, filter for zones of this type (optional, options: public, private)").Default(defaultConfig.AWSZoneType).EnumVar(&cfg.AWSZoneType, "", "public", "private")
app.Flag("aws-zone-tags", "When using the AWS provider, filter for zones with these tags").Default("").StringsVar(&cfg.AWSZoneTagFilter) app.Flag("aws-zone-tags", "When using the AWS provider, filter for zones with these tags").Default("").StringsVar(&cfg.AWSZoneTagFilter)
app.Flag("aws-assume-role", "When using the AWS provider, assume this IAM role. Useful for hosted zones in another AWS account. Specify the full ARN, e.g. `arn:aws:iam::123455567:role/external-dns` (optional)").Default(defaultConfig.AWSAssumeRole).StringVar(&cfg.AWSAssumeRole) app.Flag("aws-assume-role", "When using the AWS provider, assume this IAM role. Useful for hosted zones in another AWS account. Specify the full ARN, e.g. `arn:aws:iam::123455567:role/external-dns` (optional)").Default(defaultConfig.AWSAssumeRole).StringVar(&cfg.AWSAssumeRole)
app.Flag("aws-assume-role-external-id", "When using the AWS provider and assuming a role then specify this external ID` (optional)").Default(defaultConfig.AWSAssumeRoleExternalID).StringVar(&cfg.AWSAssumeRoleExternalID)
app.Flag("aws-batch-change-size", "When using the AWS provider, set the maximum number of changes that will be applied in each batch.").Default(strconv.Itoa(defaultConfig.AWSBatchChangeSize)).IntVar(&cfg.AWSBatchChangeSize) app.Flag("aws-batch-change-size", "When using the AWS provider, set the maximum number of changes that will be applied in each batch.").Default(strconv.Itoa(defaultConfig.AWSBatchChangeSize)).IntVar(&cfg.AWSBatchChangeSize)
app.Flag("aws-batch-change-interval", "When using the AWS provider, set the interval between batch changes.").Default(defaultConfig.AWSBatchChangeInterval.String()).DurationVar(&cfg.AWSBatchChangeInterval) app.Flag("aws-batch-change-interval", "When using the AWS provider, set the interval between batch changes.").Default(defaultConfig.AWSBatchChangeInterval.String()).DurationVar(&cfg.AWSBatchChangeInterval)
app.Flag("aws-evaluate-target-health", "When using the AWS provider, set whether to evaluate the health of a DNS target (default: enabled, disable with --no-aws-evaluate-target-health)").Default(strconv.FormatBool(defaultConfig.AWSEvaluateTargetHealth)).BoolVar(&cfg.AWSEvaluateTargetHealth) app.Flag("aws-evaluate-target-health", "When using the AWS provider, set whether to evaluate the health of a DNS target (default: enabled, disable with --no-aws-evaluate-target-health)").Default(strconv.FormatBool(defaultConfig.AWSEvaluateTargetHealth)).BoolVar(&cfg.AWSEvaluateTargetHealth)

View File

@ -57,6 +57,7 @@ var (
AWSZoneType: "", AWSZoneType: "",
AWSZoneTagFilter: []string{""}, AWSZoneTagFilter: []string{""},
AWSAssumeRole: "", AWSAssumeRole: "",
AWSAssumeRoleExternalID: "",
AWSBatchChangeSize: 1000, AWSBatchChangeSize: 1000,
AWSBatchChangeInterval: time.Second, AWSBatchChangeInterval: time.Second,
AWSEvaluateTargetHealth: true, AWSEvaluateTargetHealth: true,
@ -159,6 +160,7 @@ var (
AWSZoneType: "private", AWSZoneType: "private",
AWSZoneTagFilter: []string{"tag=foo"}, AWSZoneTagFilter: []string{"tag=foo"},
AWSAssumeRole: "some-other-role", AWSAssumeRole: "some-other-role",
AWSAssumeRoleExternalID: "pg2000",
AWSBatchChangeSize: 100, AWSBatchChangeSize: 100,
AWSBatchChangeInterval: time.Second * 2, AWSBatchChangeInterval: time.Second * 2,
AWSEvaluateTargetHealth: false, AWSEvaluateTargetHealth: false,
@ -332,6 +334,7 @@ func TestParseFlags(t *testing.T) {
"--aws-zone-type=private", "--aws-zone-type=private",
"--aws-zone-tags=tag=foo", "--aws-zone-tags=tag=foo",
"--aws-assume-role=some-other-role", "--aws-assume-role=some-other-role",
"--aws-assume-role-external-id=pg2000",
"--aws-batch-change-size=100", "--aws-batch-change-size=100",
"--aws-batch-change-interval=2s", "--aws-batch-change-interval=2s",
"--aws-api-retries=13", "--aws-api-retries=13",
@ -446,6 +449,7 @@ func TestParseFlags(t *testing.T) {
"EXTERNAL_DNS_AWS_ZONE_TYPE": "private", "EXTERNAL_DNS_AWS_ZONE_TYPE": "private",
"EXTERNAL_DNS_AWS_ZONE_TAGS": "tag=foo", "EXTERNAL_DNS_AWS_ZONE_TAGS": "tag=foo",
"EXTERNAL_DNS_AWS_ASSUME_ROLE": "some-other-role", "EXTERNAL_DNS_AWS_ASSUME_ROLE": "some-other-role",
"EXTERNAL_DNS_AWS_ASSUME_ROLE_EXTERNAL_ID": "pg2000",
"EXTERNAL_DNS_AWS_BATCH_CHANGE_SIZE": "100", "EXTERNAL_DNS_AWS_BATCH_CHANGE_SIZE": "100",
"EXTERNAL_DNS_AWS_BATCH_CHANGE_INTERVAL": "2s", "EXTERNAL_DNS_AWS_BATCH_CHANGE_INTERVAL": "2s",
"EXTERNAL_DNS_AWS_EVALUATE_TARGET_HEALTH": "0", "EXTERNAL_DNS_AWS_EVALUATE_TARGET_HEALTH": "0",

View File

@ -170,6 +170,7 @@ type AWSConfig struct {
BatchChangeInterval time.Duration BatchChangeInterval time.Duration
EvaluateTargetHealth bool EvaluateTargetHealth bool
AssumeRole string AssumeRole string
AssumeRoleExternalID string
APIRetries int APIRetries int
PreferCNAME bool PreferCNAME bool
DryRun bool DryRun bool
@ -198,9 +199,16 @@ func NewAWSProvider(awsConfig AWSConfig) (*AWSProvider, error) {
} }
if awsConfig.AssumeRole != "" { if awsConfig.AssumeRole != "" {
if awsConfig.AssumeRoleExternalID != "" {
log.Infof("Assuming role: %s with external id %s", awsConfig.AssumeRole, awsConfig.AssumeRoleExternalID)
session.Config.WithCredentials(stscreds.NewCredentials(session, awsConfig.AssumeRole, func(p *stscreds.AssumeRoleProvider) {
p.ExternalID = &awsConfig.AssumeRoleExternalID
}))
} else {
log.Infof("Assuming role: %s", awsConfig.AssumeRole) log.Infof("Assuming role: %s", awsConfig.AssumeRole)
session.Config.WithCredentials(stscreds.NewCredentials(session, awsConfig.AssumeRole)) session.Config.WithCredentials(stscreds.NewCredentials(session, awsConfig.AssumeRole))
} }
}
provider := &AWSProvider{ provider := &AWSProvider{
client: route53.New(session), client: route53.New(session),

View File

@ -88,7 +88,7 @@ type AWSSDProvider struct {
} }
// NewAWSSDProvider initializes a new AWS Cloud Map based Provider. // NewAWSSDProvider initializes a new AWS Cloud Map based Provider.
func NewAWSSDProvider(domainFilter endpoint.DomainFilter, namespaceType string, assumeRole string, dryRun, cleanEmptyService bool, ownerID string) (*AWSSDProvider, error) { func NewAWSSDProvider(domainFilter endpoint.DomainFilter, namespaceType string, assumeRole string, assumeRoleExternalID string, dryRun, cleanEmptyService bool, ownerID string) (*AWSSDProvider, error) {
config := aws.NewConfig() config := aws.NewConfig()
config = config.WithHTTPClient( config = config.WithHTTPClient(
@ -109,9 +109,16 @@ func NewAWSSDProvider(domainFilter endpoint.DomainFilter, namespaceType string,
} }
if assumeRole != "" { if assumeRole != "" {
if assumeRoleExternalID != "" {
log.Infof("Assuming role %q with external ID %q", assumeRole, assumeRoleExternalID)
sess.Config.WithCredentials(stscreds.NewCredentials(sess, assumeRole, func(p *stscreds.AssumeRoleProvider) {
p.ExternalID = &assumeRoleExternalID
}))
} else {
log.Infof("Assuming role: %s", assumeRole) log.Infof("Assuming role: %s", assumeRole)
sess.Config.WithCredentials(stscreds.NewCredentials(sess, assumeRole)) sess.Config.WithCredentials(stscreds.NewCredentials(sess, assumeRole))
} }
}
sess.Handlers.Build.PushBack(request.MakeAddToUserAgentHandler("ExternalDNS", externaldns.Version)) sess.Handlers.Build.PushBack(request.MakeAddToUserAgentHandler("ExternalDNS", externaldns.Version))