mirror of
https://github.com/kubernetes-sigs/external-dns.git
synced 2025-08-07 01:56:57 +02:00
Add aws max change count flag (#596)
* Create `NewAWSProvider` with `AWSConfig` struct Rather than calling `NewAWSProvider` with a list of objects, you will now call it using a new `AWSConfig` struct. This allows for clearer declarations of variables which becomes even more important as more variables are added. * Add `aws-max-change-count` flag Adding a new `aws-max-change-count` flag to override the default max change count on the aws provider. Included updated tests with a new `defaultMaxChangeCount` constant and tests for setting the value as a flag and as an environment variable. * Update CHANGELOG.md Updating CHANGELOG.md with 'Add aws max change count flag' PR.
This commit is contained in:
parent
f53589f76b
commit
e34bf552d6
@ -1,3 +1,5 @@
|
|||||||
|
- AWS: Add a flag to override the default max change count (#596) @peterbale
|
||||||
|
|
||||||
## v0.5.3 - 2018-06-15
|
## v0.5.3 - 2018-06-15
|
||||||
|
|
||||||
- Print a message if no hosted zones match (aws provider) (#592) @svend
|
- Print a message if no hosted zones match (aws provider) (#592) @svend
|
||||||
|
11
main.go
11
main.go
@ -95,7 +95,16 @@ func main() {
|
|||||||
var p provider.Provider
|
var p provider.Provider
|
||||||
switch cfg.Provider {
|
switch cfg.Provider {
|
||||||
case "aws":
|
case "aws":
|
||||||
p, err = provider.NewAWSProvider(domainFilter, zoneIDFilter, zoneTypeFilter, cfg.AWSAssumeRole, cfg.DryRun)
|
p, err = provider.NewAWSProvider(
|
||||||
|
provider.AWSConfig{
|
||||||
|
DomainFilter: domainFilter,
|
||||||
|
ZoneIDFilter: zoneIDFilter,
|
||||||
|
ZoneTypeFilter: zoneTypeFilter,
|
||||||
|
MaxChangeCount: cfg.AWSMaxChangeCount,
|
||||||
|
AssumeRole: cfg.AWSAssumeRole,
|
||||||
|
DryRun: cfg.DryRun,
|
||||||
|
},
|
||||||
|
)
|
||||||
case "aws-sd":
|
case "aws-sd":
|
||||||
// Check that only compatible Registry is used with AWS-SD
|
// Check that only compatible Registry is used with AWS-SD
|
||||||
if cfg.Registry != "noop" && cfg.Registry != "aws-sd" {
|
if cfg.Registry != "noop" && cfg.Registry != "aws-sd" {
|
||||||
|
@ -52,6 +52,7 @@ type Config struct {
|
|||||||
ZoneIDFilter []string
|
ZoneIDFilter []string
|
||||||
AWSZoneType string
|
AWSZoneType string
|
||||||
AWSAssumeRole string
|
AWSAssumeRole string
|
||||||
|
AWSMaxChangeCount int
|
||||||
AzureConfigFile string
|
AzureConfigFile string
|
||||||
AzureResourceGroup string
|
AzureResourceGroup string
|
||||||
CloudflareProxied bool
|
CloudflareProxied bool
|
||||||
@ -97,6 +98,7 @@ var defaultConfig = &Config{
|
|||||||
DomainFilter: []string{},
|
DomainFilter: []string{},
|
||||||
AWSZoneType: "",
|
AWSZoneType: "",
|
||||||
AWSAssumeRole: "",
|
AWSAssumeRole: "",
|
||||||
|
AWSMaxChangeCount: 4000,
|
||||||
AzureConfigFile: "/etc/kubernetes/azure.json",
|
AzureConfigFile: "/etc/kubernetes/azure.json",
|
||||||
AzureResourceGroup: "",
|
AzureResourceGroup: "",
|
||||||
CloudflareProxied: false,
|
CloudflareProxied: false,
|
||||||
@ -176,6 +178,7 @@ func (cfg *Config) ParseFlags(args []string) error {
|
|||||||
app.Flag("google-project", "When using the Google provider, current project is auto-detected, when running on GCP. Specify other project with this. Must be specified when running outside GCP.").Default(defaultConfig.GoogleProject).StringVar(&cfg.GoogleProject)
|
app.Flag("google-project", "When using the Google provider, current project is auto-detected, when running on GCP. Specify other project with this. Must be specified when running outside GCP.").Default(defaultConfig.GoogleProject).StringVar(&cfg.GoogleProject)
|
||||||
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-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-max-change-count", "When using the AWS provider, set the maximum number of changes that will be applied.").Default(strconv.Itoa(defaultConfig.AWSMaxChangeCount)).IntVar(&cfg.AWSMaxChangeCount)
|
||||||
app.Flag("azure-config-file", "When using the Azure provider, specify the Azure configuration file (required when --provider=azure").Default(defaultConfig.AzureConfigFile).StringVar(&cfg.AzureConfigFile)
|
app.Flag("azure-config-file", "When using the Azure provider, specify the Azure configuration file (required when --provider=azure").Default(defaultConfig.AzureConfigFile).StringVar(&cfg.AzureConfigFile)
|
||||||
app.Flag("azure-resource-group", "When using the Azure provider, override the Azure resource group to use (optional)").Default(defaultConfig.AzureResourceGroup).StringVar(&cfg.AzureResourceGroup)
|
app.Flag("azure-resource-group", "When using the Azure provider, override the Azure resource group to use (optional)").Default(defaultConfig.AzureResourceGroup).StringVar(&cfg.AzureResourceGroup)
|
||||||
app.Flag("cloudflare-proxied", "When using the Cloudflare provider, specify if the proxy mode must be enabled (default: disabled)").BoolVar(&cfg.CloudflareProxied)
|
app.Flag("cloudflare-proxied", "When using the Cloudflare provider, specify if the proxy mode must be enabled (default: disabled)").BoolVar(&cfg.CloudflareProxied)
|
||||||
|
@ -41,6 +41,7 @@ var (
|
|||||||
ZoneIDFilter: []string{""},
|
ZoneIDFilter: []string{""},
|
||||||
AWSZoneType: "",
|
AWSZoneType: "",
|
||||||
AWSAssumeRole: "",
|
AWSAssumeRole: "",
|
||||||
|
AWSMaxChangeCount: 4000,
|
||||||
AzureConfigFile: "/etc/kubernetes/azure.json",
|
AzureConfigFile: "/etc/kubernetes/azure.json",
|
||||||
AzureResourceGroup: "",
|
AzureResourceGroup: "",
|
||||||
CloudflareProxied: false,
|
CloudflareProxied: false,
|
||||||
@ -80,6 +81,7 @@ var (
|
|||||||
ZoneIDFilter: []string{"/hostedzone/ZTST1", "/hostedzone/ZTST2"},
|
ZoneIDFilter: []string{"/hostedzone/ZTST1", "/hostedzone/ZTST2"},
|
||||||
AWSZoneType: "private",
|
AWSZoneType: "private",
|
||||||
AWSAssumeRole: "some-other-role",
|
AWSAssumeRole: "some-other-role",
|
||||||
|
AWSMaxChangeCount: 100,
|
||||||
AzureConfigFile: "azure.json",
|
AzureConfigFile: "azure.json",
|
||||||
AzureResourceGroup: "arg",
|
AzureResourceGroup: "arg",
|
||||||
CloudflareProxied: true,
|
CloudflareProxied: true,
|
||||||
@ -155,6 +157,7 @@ func TestParseFlags(t *testing.T) {
|
|||||||
"--zone-id-filter=/hostedzone/ZTST2",
|
"--zone-id-filter=/hostedzone/ZTST2",
|
||||||
"--aws-zone-type=private",
|
"--aws-zone-type=private",
|
||||||
"--aws-assume-role=some-other-role",
|
"--aws-assume-role=some-other-role",
|
||||||
|
"--aws-max-change-count=100",
|
||||||
"--policy=upsert-only",
|
"--policy=upsert-only",
|
||||||
"--registry=noop",
|
"--registry=noop",
|
||||||
"--txt-owner-id=owner-1",
|
"--txt-owner-id=owner-1",
|
||||||
@ -199,6 +202,7 @@ func TestParseFlags(t *testing.T) {
|
|||||||
"EXTERNAL_DNS_ZONE_ID_FILTER": "/hostedzone/ZTST1\n/hostedzone/ZTST2",
|
"EXTERNAL_DNS_ZONE_ID_FILTER": "/hostedzone/ZTST1\n/hostedzone/ZTST2",
|
||||||
"EXTERNAL_DNS_AWS_ZONE_TYPE": "private",
|
"EXTERNAL_DNS_AWS_ZONE_TYPE": "private",
|
||||||
"EXTERNAL_DNS_AWS_ASSUME_ROLE": "some-other-role",
|
"EXTERNAL_DNS_AWS_ASSUME_ROLE": "some-other-role",
|
||||||
|
"EXTERNAL_DNS_AWS_MAX_CHANGE_COUNT": "100",
|
||||||
"EXTERNAL_DNS_POLICY": "upsert-only",
|
"EXTERNAL_DNS_POLICY": "upsert-only",
|
||||||
"EXTERNAL_DNS_REGISTRY": "noop",
|
"EXTERNAL_DNS_REGISTRY": "noop",
|
||||||
"EXTERNAL_DNS_TXT_OWNER_ID": "owner-1",
|
"EXTERNAL_DNS_TXT_OWNER_ID": "owner-1",
|
||||||
|
@ -33,7 +33,6 @@ import (
|
|||||||
const (
|
const (
|
||||||
evaluateTargetHealth = true
|
evaluateTargetHealth = true
|
||||||
recordTTL = 300
|
recordTTL = 300
|
||||||
maxChangeCount = 4000
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -88,6 +87,7 @@ type Route53API interface {
|
|||||||
type AWSProvider struct {
|
type AWSProvider struct {
|
||||||
client Route53API
|
client Route53API
|
||||||
dryRun bool
|
dryRun bool
|
||||||
|
maxChangeCount int
|
||||||
// only consider hosted zones managing domains ending in this suffix
|
// only consider hosted zones managing domains ending in this suffix
|
||||||
domainFilter DomainFilter
|
domainFilter DomainFilter
|
||||||
// filter hosted zones by id
|
// filter hosted zones by id
|
||||||
@ -96,8 +96,18 @@ type AWSProvider struct {
|
|||||||
zoneTypeFilter ZoneTypeFilter
|
zoneTypeFilter ZoneTypeFilter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AWSConfig contains configuration to create a new AWS provider.
|
||||||
|
type AWSConfig struct {
|
||||||
|
DomainFilter DomainFilter
|
||||||
|
ZoneIDFilter ZoneIDFilter
|
||||||
|
ZoneTypeFilter ZoneTypeFilter
|
||||||
|
MaxChangeCount int
|
||||||
|
AssumeRole string
|
||||||
|
DryRun bool
|
||||||
|
}
|
||||||
|
|
||||||
// NewAWSProvider initializes a new AWS Route53 based Provider.
|
// NewAWSProvider initializes a new AWS Route53 based Provider.
|
||||||
func NewAWSProvider(domainFilter DomainFilter, zoneIDFilter ZoneIDFilter, zoneTypeFilter ZoneTypeFilter, assumeRole string, dryRun bool) (*AWSProvider, error) {
|
func NewAWSProvider(awsConfig AWSConfig) (*AWSProvider, error) {
|
||||||
config := aws.NewConfig()
|
config := aws.NewConfig()
|
||||||
|
|
||||||
config.WithHTTPClient(
|
config.WithHTTPClient(
|
||||||
@ -117,17 +127,18 @@ func NewAWSProvider(domainFilter DomainFilter, zoneIDFilter ZoneIDFilter, zoneTy
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if assumeRole != "" {
|
if awsConfig.AssumeRole != "" {
|
||||||
log.Infof("Assuming role: %s", assumeRole)
|
log.Infof("Assuming role: %s", awsConfig.AssumeRole)
|
||||||
session.Config.WithCredentials(stscreds.NewCredentials(session, assumeRole))
|
session.Config.WithCredentials(stscreds.NewCredentials(session, awsConfig.AssumeRole))
|
||||||
}
|
}
|
||||||
|
|
||||||
provider := &AWSProvider{
|
provider := &AWSProvider{
|
||||||
client: route53.New(session),
|
client: route53.New(session),
|
||||||
domainFilter: domainFilter,
|
domainFilter: awsConfig.DomainFilter,
|
||||||
zoneIDFilter: zoneIDFilter,
|
zoneIDFilter: awsConfig.ZoneIDFilter,
|
||||||
zoneTypeFilter: zoneTypeFilter,
|
zoneTypeFilter: awsConfig.ZoneTypeFilter,
|
||||||
dryRun: dryRun,
|
maxChangeCount: awsConfig.MaxChangeCount,
|
||||||
|
dryRun: awsConfig.DryRun,
|
||||||
}
|
}
|
||||||
|
|
||||||
return provider, nil
|
return provider, nil
|
||||||
@ -275,7 +286,7 @@ func (p *AWSProvider) submitChanges(changes []*route53.Change) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for z, cs := range changesByZone {
|
for z, cs := range changesByZone {
|
||||||
limCs := limitChangeSet(cs, maxChangeCount)
|
limCs := limitChangeSet(cs, p.maxChangeCount)
|
||||||
|
|
||||||
for _, c := range limCs {
|
for _, c := range limCs {
|
||||||
log.Infof("Desired change: %s %s %s", *c.Action, *c.ResourceRecordSet.Name, *c.ResourceRecordSet.Type)
|
log.Infof("Desired change: %s %s %s", *c.Action, *c.ResourceRecordSet.Name, *c.ResourceRecordSet.Type)
|
||||||
|
@ -32,6 +32,8 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const defaultMaxChangeCount = 4000
|
||||||
|
|
||||||
// Compile time check for interface conformance
|
// Compile time check for interface conformance
|
||||||
var _ Route53API = &Route53APIStub{}
|
var _ Route53API = &Route53APIStub{}
|
||||||
|
|
||||||
@ -540,7 +542,7 @@ func TestAWSChangesByZones(t *testing.T) {
|
|||||||
func TestAWSsubmitChanges(t *testing.T) {
|
func TestAWSsubmitChanges(t *testing.T) {
|
||||||
provider := newAWSProvider(t, NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), NewZoneIDFilter([]string{}), NewZoneTypeFilter(""), false, []*endpoint.Endpoint{})
|
provider := newAWSProvider(t, NewDomainFilter([]string{"ext-dns-test-2.teapot.zalan.do."}), NewZoneIDFilter([]string{}), NewZoneTypeFilter(""), false, []*endpoint.Endpoint{})
|
||||||
const subnets = 16
|
const subnets = 16
|
||||||
const hosts = maxChangeCount / subnets
|
const hosts = defaultMaxChangeCount / subnets
|
||||||
|
|
||||||
endpoints := make([]*endpoint.Endpoint, 0)
|
endpoints := make([]*endpoint.Endpoint, 0)
|
||||||
for i := 0; i < subnets; i++ {
|
for i := 0; i < subnets; i++ {
|
||||||
@ -566,7 +568,7 @@ func TestAWSsubmitChanges(t *testing.T) {
|
|||||||
func TestAWSLimitChangeSet(t *testing.T) {
|
func TestAWSLimitChangeSet(t *testing.T) {
|
||||||
var cs []*route53.Change
|
var cs []*route53.Change
|
||||||
|
|
||||||
for i := 1; i <= maxChangeCount; i += 2 {
|
for i := 1; i <= defaultMaxChangeCount; i += 2 {
|
||||||
cs = append(cs, &route53.Change{
|
cs = append(cs, &route53.Change{
|
||||||
Action: aws.String(route53.ChangeActionCreate),
|
Action: aws.String(route53.ChangeActionCreate),
|
||||||
ResourceRecordSet: &route53.ResourceRecordSet{
|
ResourceRecordSet: &route53.ResourceRecordSet{
|
||||||
@ -583,7 +585,7 @@ func TestAWSLimitChangeSet(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
limCs := limitChangeSet(cs, maxChangeCount)
|
limCs := limitChangeSet(cs, defaultMaxChangeCount)
|
||||||
|
|
||||||
// sorting cs not needed as it should be returned as is
|
// sorting cs not needed as it should be returned as is
|
||||||
validateAWSChangeRecords(t, limCs, cs)
|
validateAWSChangeRecords(t, limCs, cs)
|
||||||
@ -864,6 +866,7 @@ func newAWSProvider(t *testing.T, domainFilter DomainFilter, zoneIDFilter ZoneID
|
|||||||
|
|
||||||
provider := &AWSProvider{
|
provider := &AWSProvider{
|
||||||
client: client,
|
client: client,
|
||||||
|
maxChangeCount: defaultMaxChangeCount,
|
||||||
domainFilter: domainFilter,
|
domainFilter: domainFilter,
|
||||||
zoneIDFilter: zoneIDFilter,
|
zoneIDFilter: zoneIDFilter,
|
||||||
zoneTypeFilter: zoneTypeFilter,
|
zoneTypeFilter: zoneTypeFilter,
|
||||||
|
Loading…
Reference in New Issue
Block a user