mirror of
https://github.com/kubernetes-sigs/external-dns.git
synced 2025-08-06 01:26:59 +02:00
Validate AWS record values size during batch set generation
This commit is contained in:
parent
b9da66a524
commit
c391f5588a
22
main.go
22
main.go
@ -227,16 +227,18 @@ func main() {
|
||||
case "aws":
|
||||
p, err = aws.NewAWSProvider(
|
||||
aws.AWSConfig{
|
||||
DomainFilter: domainFilter,
|
||||
ZoneIDFilter: zoneIDFilter,
|
||||
ZoneTypeFilter: zoneTypeFilter,
|
||||
ZoneTagFilter: zoneTagFilter,
|
||||
BatchChangeSize: cfg.AWSBatchChangeSize,
|
||||
BatchChangeInterval: cfg.AWSBatchChangeInterval,
|
||||
EvaluateTargetHealth: cfg.AWSEvaluateTargetHealth,
|
||||
PreferCNAME: cfg.AWSPreferCNAME,
|
||||
DryRun: cfg.DryRun,
|
||||
ZoneCacheDuration: cfg.AWSZoneCacheDuration,
|
||||
DomainFilter: domainFilter,
|
||||
ZoneIDFilter: zoneIDFilter,
|
||||
ZoneTypeFilter: zoneTypeFilter,
|
||||
ZoneTagFilter: zoneTagFilter,
|
||||
BatchChangeSize: cfg.AWSBatchChangeSize,
|
||||
BatchChangeSizeBytes: cfg.AWSBatchChangeSizeBytes,
|
||||
BatchChangeSizeValues: cfg.AWSBatchChangeSizeValues,
|
||||
BatchChangeInterval: cfg.AWSBatchChangeInterval,
|
||||
EvaluateTargetHealth: cfg.AWSEvaluateTargetHealth,
|
||||
PreferCNAME: cfg.AWSPreferCNAME,
|
||||
DryRun: cfg.DryRun,
|
||||
ZoneCacheDuration: cfg.AWSZoneCacheDuration,
|
||||
},
|
||||
route53.New(awsSession),
|
||||
)
|
||||
|
@ -86,6 +86,8 @@ type Config struct {
|
||||
AWSAssumeRole string
|
||||
AWSAssumeRoleExternalID string
|
||||
AWSBatchChangeSize int
|
||||
AWSBatchChangeSizeBytes int
|
||||
AWSBatchChangeSizeValues int
|
||||
AWSBatchChangeInterval time.Duration
|
||||
AWSEvaluateTargetHealth bool
|
||||
AWSAPIRetries int
|
||||
@ -258,6 +260,8 @@ var defaultConfig = &Config{
|
||||
AWSAssumeRole: "",
|
||||
AWSAssumeRoleExternalID: "",
|
||||
AWSBatchChangeSize: 1000,
|
||||
AWSBatchChangeSizeBytes: 32000,
|
||||
AWSBatchChangeSizeValues: 1000,
|
||||
AWSBatchChangeInterval: time.Second,
|
||||
AWSEvaluateTargetHealth: true,
|
||||
AWSAPIRetries: 3,
|
||||
@ -477,6 +481,8 @@ func (cfg *Config) ParseFlags(args []string) error {
|
||||
app.Flag("aws-assume-role", "When using the AWS API, 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 API 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-bytes", "When using the AWS provider, set the maximum byte size that will be applied in each batch.").Default(strconv.Itoa(defaultConfig.AWSBatchChangeSizeBytes)).IntVar(&cfg.AWSBatchChangeSizeBytes)
|
||||
app.Flag("aws-batch-change-size-values", "When using the AWS provider, set the maximum total record values that will be applied in each batch.").Default(strconv.Itoa(defaultConfig.AWSBatchChangeSizeValues)).IntVar(&cfg.AWSBatchChangeSizeValues)
|
||||
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-api-retries", "When using the AWS API, set the maximum number of retries before giving up.").Default(strconv.Itoa(defaultConfig.AWSAPIRetries)).IntVar(&cfg.AWSAPIRetries)
|
||||
|
@ -58,6 +58,8 @@ var (
|
||||
AWSAssumeRole: "",
|
||||
AWSAssumeRoleExternalID: "",
|
||||
AWSBatchChangeSize: 1000,
|
||||
AWSBatchChangeSizeBytes: 32000,
|
||||
AWSBatchChangeSizeValues: 1000,
|
||||
AWSBatchChangeInterval: time.Second,
|
||||
AWSEvaluateTargetHealth: true,
|
||||
AWSAPIRetries: 3,
|
||||
@ -169,6 +171,8 @@ var (
|
||||
AWSAssumeRole: "some-other-role",
|
||||
AWSAssumeRoleExternalID: "pg2000",
|
||||
AWSBatchChangeSize: 100,
|
||||
AWSBatchChangeSizeBytes: 16000,
|
||||
AWSBatchChangeSizeValues: 100,
|
||||
AWSBatchChangeInterval: time.Second * 2,
|
||||
AWSEvaluateTargetHealth: false,
|
||||
AWSAPIRetries: 13,
|
||||
@ -354,6 +358,8 @@ func TestParseFlags(t *testing.T) {
|
||||
"--aws-assume-role=some-other-role",
|
||||
"--aws-assume-role-external-id=pg2000",
|
||||
"--aws-batch-change-size=100",
|
||||
"--aws-batch-change-size-bytes=16000",
|
||||
"--aws-batch-change-size-values=100",
|
||||
"--aws-batch-change-interval=2s",
|
||||
"--aws-api-retries=13",
|
||||
"--aws-prefer-cname",
|
||||
@ -476,6 +482,8 @@ func TestParseFlags(t *testing.T) {
|
||||
"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_BYTES": "16000",
|
||||
"EXTERNAL_DNS_AWS_BATCH_CHANGE_SIZE_VALUES": "100",
|
||||
"EXTERNAL_DNS_AWS_BATCH_CHANGE_INTERVAL": "2s",
|
||||
"EXTERNAL_DNS_AWS_EVALUATE_TARGET_HEALTH": "0",
|
||||
"EXTERNAL_DNS_AWS_API_RETRIES": "13",
|
||||
|
@ -206,6 +206,8 @@ type Route53API interface {
|
||||
type Route53Change struct {
|
||||
route53.Change
|
||||
OwnedRecord string
|
||||
sizeBytes int
|
||||
sizeValues int
|
||||
}
|
||||
|
||||
type Route53Changes []*Route53Change
|
||||
@ -227,11 +229,13 @@ type zonesListCache struct {
|
||||
// AWSProvider is an implementation of Provider for AWS Route53.
|
||||
type AWSProvider struct {
|
||||
provider.BaseProvider
|
||||
client Route53API
|
||||
dryRun bool
|
||||
batchChangeSize int
|
||||
batchChangeInterval time.Duration
|
||||
evaluateTargetHealth bool
|
||||
client Route53API
|
||||
dryRun bool
|
||||
batchChangeSize int
|
||||
batchChangeSizeBytes int
|
||||
batchChangeSizeValues int
|
||||
batchChangeInterval time.Duration
|
||||
evaluateTargetHealth bool
|
||||
// only consider hosted zones managing domains ending in this suffix
|
||||
domainFilter endpoint.DomainFilter
|
||||
// filter hosted zones by id
|
||||
@ -248,33 +252,37 @@ type AWSProvider struct {
|
||||
|
||||
// AWSConfig contains configuration to create a new AWS provider.
|
||||
type AWSConfig struct {
|
||||
DomainFilter endpoint.DomainFilter
|
||||
ZoneIDFilter provider.ZoneIDFilter
|
||||
ZoneTypeFilter provider.ZoneTypeFilter
|
||||
ZoneTagFilter provider.ZoneTagFilter
|
||||
BatchChangeSize int
|
||||
BatchChangeInterval time.Duration
|
||||
EvaluateTargetHealth bool
|
||||
PreferCNAME bool
|
||||
DryRun bool
|
||||
ZoneCacheDuration time.Duration
|
||||
DomainFilter endpoint.DomainFilter
|
||||
ZoneIDFilter provider.ZoneIDFilter
|
||||
ZoneTypeFilter provider.ZoneTypeFilter
|
||||
ZoneTagFilter provider.ZoneTagFilter
|
||||
BatchChangeSize int
|
||||
BatchChangeSizeBytes int
|
||||
BatchChangeSizeValues int
|
||||
BatchChangeInterval time.Duration
|
||||
EvaluateTargetHealth bool
|
||||
PreferCNAME bool
|
||||
DryRun bool
|
||||
ZoneCacheDuration time.Duration
|
||||
}
|
||||
|
||||
// NewAWSProvider initializes a new AWS Route53 based Provider.
|
||||
func NewAWSProvider(awsConfig AWSConfig, client Route53API) (*AWSProvider, error) {
|
||||
provider := &AWSProvider{
|
||||
client: client,
|
||||
domainFilter: awsConfig.DomainFilter,
|
||||
zoneIDFilter: awsConfig.ZoneIDFilter,
|
||||
zoneTypeFilter: awsConfig.ZoneTypeFilter,
|
||||
zoneTagFilter: awsConfig.ZoneTagFilter,
|
||||
batchChangeSize: awsConfig.BatchChangeSize,
|
||||
batchChangeInterval: awsConfig.BatchChangeInterval,
|
||||
evaluateTargetHealth: awsConfig.EvaluateTargetHealth,
|
||||
preferCNAME: awsConfig.PreferCNAME,
|
||||
dryRun: awsConfig.DryRun,
|
||||
zonesCache: &zonesListCache{duration: awsConfig.ZoneCacheDuration},
|
||||
failedChangesQueue: make(map[string]Route53Changes),
|
||||
client: client,
|
||||
domainFilter: awsConfig.DomainFilter,
|
||||
zoneIDFilter: awsConfig.ZoneIDFilter,
|
||||
zoneTypeFilter: awsConfig.ZoneTypeFilter,
|
||||
zoneTagFilter: awsConfig.ZoneTagFilter,
|
||||
batchChangeSize: awsConfig.BatchChangeSize,
|
||||
batchChangeSizeBytes: awsConfig.BatchChangeSizeBytes,
|
||||
batchChangeSizeValues: awsConfig.BatchChangeSizeValues,
|
||||
batchChangeInterval: awsConfig.BatchChangeInterval,
|
||||
evaluateTargetHealth: awsConfig.EvaluateTargetHealth,
|
||||
preferCNAME: awsConfig.PreferCNAME,
|
||||
dryRun: awsConfig.DryRun,
|
||||
zonesCache: &zonesListCache{duration: awsConfig.ZoneCacheDuration},
|
||||
failedChangesQueue: make(map[string]Route53Changes),
|
||||
}
|
||||
|
||||
return provider, nil
|
||||
@ -565,7 +573,8 @@ func (p *AWSProvider) submitChanges(ctx context.Context, changes Route53Changes,
|
||||
retriedChanges, newChanges := findChangesInQueue(cs, p.failedChangesQueue[z])
|
||||
p.failedChangesQueue[z] = nil
|
||||
|
||||
batchCs := append(batchChangeSet(newChanges, p.batchChangeSize), batchChangeSet(retriedChanges, p.batchChangeSize)...)
|
||||
batchCs := append(batchChangeSet(newChanges, p.batchChangeSize, p.batchChangeSizeBytes, p.batchChangeSizeValues),
|
||||
batchChangeSet(retriedChanges, p.batchChangeSize, p.batchChangeSizeBytes, p.batchChangeSizeValues)...)
|
||||
for i, b := range batchCs {
|
||||
if len(b) == 0 {
|
||||
continue
|
||||
@ -719,6 +728,8 @@ func (p *AWSProvider) newChange(action string, ep *endpoint.Endpoint) (*Route53C
|
||||
Name: aws.String(ep.DNSName),
|
||||
},
|
||||
},
|
||||
sizeBytes: 0,
|
||||
sizeValues: 0,
|
||||
}
|
||||
dualstack := false
|
||||
if targetHostedZone := isAWSAlias(ep); targetHostedZone != "" {
|
||||
@ -736,6 +747,8 @@ func (p *AWSProvider) newChange(action string, ep *endpoint.Endpoint) (*Route53C
|
||||
HostedZoneId: aws.String(cleanZoneID(targetHostedZone)),
|
||||
EvaluateTargetHealth: aws.Bool(evalTargetHealth),
|
||||
}
|
||||
change.sizeBytes += len([]byte(ep.Targets[0]))
|
||||
change.sizeValues += 1
|
||||
} else {
|
||||
change.ResourceRecordSet.Type = aws.String(ep.RecordType)
|
||||
if !ep.RecordTTL.IsConfigured() {
|
||||
@ -748,9 +761,18 @@ func (p *AWSProvider) newChange(action string, ep *endpoint.Endpoint) (*Route53C
|
||||
change.ResourceRecordSet.ResourceRecords[idx] = &route53.ResourceRecord{
|
||||
Value: aws.String(val),
|
||||
}
|
||||
change.sizeBytes += len([]byte(val))
|
||||
change.sizeValues += 1
|
||||
}
|
||||
}
|
||||
|
||||
if action == route53.ChangeActionUpsert {
|
||||
// When the value of the Action element is UPSERT, each ResourceRecord element and each character in a Value
|
||||
// element is counted twice
|
||||
change.sizeBytes *= 2
|
||||
change.sizeValues *= 2
|
||||
}
|
||||
|
||||
setIdentifier := ep.SetIdentifier
|
||||
if setIdentifier != "" {
|
||||
change.ResourceRecordSet.SetIdentifier = aws.String(setIdentifier)
|
||||
@ -856,8 +878,26 @@ func (p *AWSProvider) tagsForZone(ctx context.Context, zoneID string) (map[strin
|
||||
return tagMap, nil
|
||||
}
|
||||
|
||||
func batchChangeSet(cs Route53Changes, batchSize int) []Route53Changes {
|
||||
if len(cs) <= batchSize {
|
||||
// count bytes for all changes values
|
||||
func countChangeBytes(cs Route53Changes) int {
|
||||
count := 0
|
||||
for _, c := range cs {
|
||||
count += c.sizeBytes
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
// count total value count for all changes
|
||||
func countChangeValues(cs Route53Changes) int {
|
||||
count := 0
|
||||
for _, c := range cs {
|
||||
count += c.sizeValues
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
func batchChangeSet(cs Route53Changes, batchSize int, batchSizeBytes int, batchSizeValues int) []Route53Changes {
|
||||
if len(cs) <= batchSize && countChangeBytes(cs) <= batchSizeBytes && countChangeValues(cs) <= batchSizeValues {
|
||||
res := sortChangesByActionNameType(cs)
|
||||
return []Route53Changes{res}
|
||||
}
|
||||
@ -880,7 +920,10 @@ func batchChangeSet(cs Route53Changes, batchSize int) []Route53Changes {
|
||||
continue
|
||||
}
|
||||
|
||||
if len(currentBatch)+len(v) > batchSize {
|
||||
bytes := countChangeBytes(currentBatch) + countChangeBytes(v)
|
||||
values := countChangeValues(currentBatch) + countChangeValues(v)
|
||||
|
||||
if len(currentBatch)+len(v) > batchSize || bytes > batchSizeBytes || values > batchSizeValues {
|
||||
// currentBatch would be too large if we add this changeset;
|
||||
// add currentBatch to batchChanges and start a new currentBatch
|
||||
batchChanges = append(batchChanges, sortChangesByActionNameType(currentBatch))
|
||||
|
@ -19,6 +19,7 @@ package aws
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math"
|
||||
"net"
|
||||
"sort"
|
||||
"strings"
|
||||
@ -39,9 +40,11 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
defaultBatchChangeSize = 4000
|
||||
defaultBatchChangeInterval = time.Second
|
||||
defaultEvaluateTargetHealth = true
|
||||
defaultBatchChangeSize = 4000
|
||||
defaultBatchChangeSizeBytes = 32000
|
||||
defaultBatchChangeSizeValues = 1000
|
||||
defaultBatchChangeInterval = time.Second
|
||||
defaultEvaluateTargetHealth = true
|
||||
)
|
||||
|
||||
// Compile time check for interface conformance
|
||||
@ -1527,7 +1530,7 @@ func TestAWSBatchChangeSet(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
batchCs := batchChangeSet(cs, defaultBatchChangeSize)
|
||||
batchCs := batchChangeSet(cs, defaultBatchChangeSize, defaultBatchChangeSizeBytes, defaultBatchChangeSizeValues)
|
||||
|
||||
require.Equal(t, 1, len(batchCs))
|
||||
|
||||
@ -1565,7 +1568,7 @@ func TestAWSBatchChangeSetExceeding(t *testing.T) {
|
||||
)
|
||||
}
|
||||
|
||||
batchCs := batchChangeSet(cs, testLimit)
|
||||
batchCs := batchChangeSet(cs, testLimit, defaultBatchChangeSizeBytes, defaultBatchChangeSizeValues)
|
||||
|
||||
require.Equal(t, expectedBatchCount, len(batchCs))
|
||||
|
||||
@ -1603,11 +1606,227 @@ func TestAWSBatchChangeSetExceedingNameChange(t *testing.T) {
|
||||
)
|
||||
}
|
||||
|
||||
batchCs := batchChangeSet(cs, testLimit)
|
||||
batchCs := batchChangeSet(cs, testLimit, defaultBatchChangeSizeBytes, defaultBatchChangeSizeValues)
|
||||
|
||||
require.Equal(t, 0, len(batchCs))
|
||||
}
|
||||
|
||||
func TestAWSBatchChangeSetExceedingBytesLimit(t *testing.T) {
|
||||
var cs Route53Changes
|
||||
const testCount = 50
|
||||
const testLimit = 100
|
||||
const groupSize = 2
|
||||
// Bytes for each name
|
||||
var testBytes = len([]byte("1.2.3.4")) + len([]byte("test-record"))
|
||||
// testCount / groupSize / (testLimit // bytes)
|
||||
var expectedBatchCountFloat = float64(testCount) / float64(groupSize) / float64(testLimit/testBytes)
|
||||
// Round up
|
||||
var expectedBatchCount = int(math.Floor(expectedBatchCountFloat + 0.5))
|
||||
|
||||
for i := 1; i <= testCount; i += groupSize {
|
||||
cs = append(cs,
|
||||
&Route53Change{
|
||||
Change: route53.Change{
|
||||
Action: aws.String(route53.ChangeActionCreate),
|
||||
ResourceRecordSet: &route53.ResourceRecordSet{
|
||||
Name: aws.String(fmt.Sprintf("host-%d", i)),
|
||||
Type: aws.String("A"),
|
||||
ResourceRecords: []*route53.ResourceRecord{
|
||||
{
|
||||
Value: aws.String("1.2.3.4"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
sizeBytes: len([]byte("1.2.3.4")),
|
||||
sizeValues: 1,
|
||||
},
|
||||
&Route53Change{
|
||||
Change: route53.Change{
|
||||
Action: aws.String(route53.ChangeActionCreate),
|
||||
ResourceRecordSet: &route53.ResourceRecordSet{
|
||||
Name: aws.String(fmt.Sprintf("host-%d", i)),
|
||||
Type: aws.String("TXT"),
|
||||
ResourceRecords: []*route53.ResourceRecord{
|
||||
{
|
||||
Value: aws.String("txt-record"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
sizeBytes: len([]byte("txt-record")),
|
||||
sizeValues: 1,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
batchCs := batchChangeSet(cs, defaultBatchChangeSize, testLimit, defaultBatchChangeSizeValues)
|
||||
|
||||
require.Equal(t, expectedBatchCount, len(batchCs))
|
||||
}
|
||||
|
||||
func TestAWSBatchChangeSetExceedingBytesLimitUpsert(t *testing.T) {
|
||||
var cs Route53Changes
|
||||
const testCount = 50
|
||||
const testLimit = 100
|
||||
const groupSize = 2
|
||||
// Bytes for each name multiplied by 2 for Upsert records
|
||||
var testBytes = (len([]byte("1.2.3.4")) + len([]byte("test-record"))) * 2
|
||||
// testCount / groupSize / (testLimit // bytes)
|
||||
var expectedBatchCountFloat = float64(testCount) / float64(groupSize) / float64(testLimit/testBytes)
|
||||
// Round up
|
||||
var expectedBatchCount = int(math.Floor(expectedBatchCountFloat + 0.5))
|
||||
|
||||
for i := 1; i <= testCount; i += groupSize {
|
||||
cs = append(cs,
|
||||
&Route53Change{
|
||||
Change: route53.Change{
|
||||
Action: aws.String(route53.ChangeActionUpsert),
|
||||
ResourceRecordSet: &route53.ResourceRecordSet{
|
||||
Name: aws.String(fmt.Sprintf("host-%d", i)),
|
||||
Type: aws.String("A"),
|
||||
ResourceRecords: []*route53.ResourceRecord{
|
||||
{
|
||||
Value: aws.String("1.2.3.4"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
sizeBytes: len([]byte("1.2.3.4")) * 2,
|
||||
sizeValues: 1,
|
||||
},
|
||||
&Route53Change{
|
||||
Change: route53.Change{
|
||||
Action: aws.String(route53.ChangeActionUpsert),
|
||||
ResourceRecordSet: &route53.ResourceRecordSet{
|
||||
Name: aws.String(fmt.Sprintf("host-%d", i)),
|
||||
Type: aws.String("TXT"),
|
||||
ResourceRecords: []*route53.ResourceRecord{
|
||||
{
|
||||
Value: aws.String("txt-record"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
sizeBytes: len([]byte("txt-record")) * 2,
|
||||
sizeValues: 1,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
batchCs := batchChangeSet(cs, defaultBatchChangeSize, testLimit, defaultBatchChangeSizeValues)
|
||||
|
||||
require.Equal(t, expectedBatchCount, len(batchCs))
|
||||
}
|
||||
|
||||
func TestAWSBatchChangeSetExceedingValuesLimit(t *testing.T) {
|
||||
var cs Route53Changes
|
||||
const testCount = 50
|
||||
const testLimit = 100
|
||||
const groupSize = 2
|
||||
// Values for each group
|
||||
const testValues = 2
|
||||
// testCount / groupSize / (testLimit // bytes)
|
||||
var expectedBatchCountFloat = float64(testCount) / float64(groupSize) / float64(testLimit/testValues)
|
||||
// Round up
|
||||
var expectedBatchCount = int(math.Floor(expectedBatchCountFloat + 0.5))
|
||||
|
||||
for i := 1; i <= testCount; i += groupSize {
|
||||
cs = append(cs,
|
||||
&Route53Change{
|
||||
Change: route53.Change{
|
||||
Action: aws.String(route53.ChangeActionCreate),
|
||||
ResourceRecordSet: &route53.ResourceRecordSet{
|
||||
Name: aws.String(fmt.Sprintf("host-%d", i)),
|
||||
Type: aws.String("A"),
|
||||
ResourceRecords: []*route53.ResourceRecord{
|
||||
{
|
||||
Value: aws.String("1.2.3.4"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
sizeBytes: len([]byte("1.2.3.4")),
|
||||
sizeValues: 1,
|
||||
},
|
||||
&Route53Change{
|
||||
Change: route53.Change{
|
||||
Action: aws.String(route53.ChangeActionCreate),
|
||||
ResourceRecordSet: &route53.ResourceRecordSet{
|
||||
Name: aws.String(fmt.Sprintf("host-%d", i)),
|
||||
Type: aws.String("TXT"),
|
||||
ResourceRecords: []*route53.ResourceRecord{
|
||||
{
|
||||
Value: aws.String("txt-record"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
sizeBytes: len([]byte("txt-record")),
|
||||
sizeValues: 1,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
batchCs := batchChangeSet(cs, defaultBatchChangeSize, defaultBatchChangeSizeBytes, testLimit)
|
||||
|
||||
require.Equal(t, expectedBatchCount, len(batchCs))
|
||||
}
|
||||
|
||||
func TestAWSBatchChangeSetExceedingValuesLimitUpsert(t *testing.T) {
|
||||
var cs Route53Changes
|
||||
const testCount = 50
|
||||
const testLimit = 100
|
||||
const groupSize = 2
|
||||
// Values for each group multiplied by 2 for Upsert records
|
||||
const testValues = 2 * 2
|
||||
// testCount / groupSize / (testLimit // bytes)
|
||||
var expectedBatchCountFloat = float64(testCount) / float64(groupSize) / float64(testLimit/testValues)
|
||||
// Round up
|
||||
var expectedBatchCount = int(math.Floor(expectedBatchCountFloat + 0.5))
|
||||
|
||||
for i := 1; i <= testCount; i += groupSize {
|
||||
cs = append(cs,
|
||||
&Route53Change{
|
||||
Change: route53.Change{
|
||||
Action: aws.String(route53.ChangeActionUpsert),
|
||||
ResourceRecordSet: &route53.ResourceRecordSet{
|
||||
Name: aws.String(fmt.Sprintf("host-%d", i)),
|
||||
Type: aws.String("A"),
|
||||
ResourceRecords: []*route53.ResourceRecord{
|
||||
{
|
||||
Value: aws.String("1.2.3.4"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
sizeBytes: len([]byte("1.2.3.4")) * 2,
|
||||
sizeValues: 1,
|
||||
},
|
||||
&Route53Change{
|
||||
Change: route53.Change{
|
||||
Action: aws.String(route53.ChangeActionUpsert),
|
||||
ResourceRecordSet: &route53.ResourceRecordSet{
|
||||
Name: aws.String(fmt.Sprintf("host-%d", i)),
|
||||
Type: aws.String("TXT"),
|
||||
ResourceRecords: []*route53.ResourceRecord{
|
||||
{
|
||||
Value: aws.String("txt-record"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
sizeBytes: len([]byte("txt-record")) * 2,
|
||||
sizeValues: 1,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
batchCs := batchChangeSet(cs, defaultBatchChangeSize, defaultBatchChangeSizeBytes, testLimit)
|
||||
|
||||
require.Equal(t, expectedBatchCount, len(batchCs))
|
||||
}
|
||||
|
||||
func validateEndpoints(t *testing.T, provider *AWSProvider, endpoints []*endpoint.Endpoint, expected []*endpoint.Endpoint) {
|
||||
assert.True(t, testutils.SameEndpoints(endpoints, expected), "actual and expected endpoints don't match. %+v:%+v", endpoints, expected)
|
||||
|
||||
@ -1933,17 +2152,19 @@ func newAWSProviderWithTagFilter(t *testing.T, domainFilter endpoint.DomainFilte
|
||||
client := NewRoute53APIStub(t)
|
||||
|
||||
provider := &AWSProvider{
|
||||
client: client,
|
||||
batchChangeSize: defaultBatchChangeSize,
|
||||
batchChangeInterval: defaultBatchChangeInterval,
|
||||
evaluateTargetHealth: evaluateTargetHealth,
|
||||
domainFilter: domainFilter,
|
||||
zoneIDFilter: zoneIDFilter,
|
||||
zoneTypeFilter: zoneTypeFilter,
|
||||
zoneTagFilter: zoneTagFilter,
|
||||
dryRun: false,
|
||||
zonesCache: &zonesListCache{duration: 1 * time.Minute},
|
||||
failedChangesQueue: make(map[string]Route53Changes),
|
||||
client: client,
|
||||
batchChangeSize: defaultBatchChangeSize,
|
||||
batchChangeSizeBytes: defaultBatchChangeSizeBytes,
|
||||
batchChangeSizeValues: defaultBatchChangeSizeValues,
|
||||
batchChangeInterval: defaultBatchChangeInterval,
|
||||
evaluateTargetHealth: evaluateTargetHealth,
|
||||
domainFilter: domainFilter,
|
||||
zoneIDFilter: zoneIDFilter,
|
||||
zoneTypeFilter: zoneTypeFilter,
|
||||
zoneTagFilter: zoneTagFilter,
|
||||
dryRun: false,
|
||||
zonesCache: &zonesListCache{duration: 1 * time.Minute},
|
||||
failedChangesQueue: make(map[string]Route53Changes),
|
||||
}
|
||||
|
||||
createAWSZone(t, provider, &route53.HostedZone{
|
||||
|
Loading…
Reference in New Issue
Block a user