Skip to content

Commit

Permalink
route53: adds option to not wait for changes (#2181)
Browse files Browse the repository at this point in the history
  • Loading branch information
ldez authored May 9, 2024
1 parent 2ec9e42 commit 11b4bef
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 22 deletions.
1 change: 1 addition & 0 deletions cmd/zz_gen_cmd_dnshelp.go
Original file line number Diff line number Diff line change
Expand Up @@ -2306,6 +2306,7 @@ func displayDNSHelp(w io.Writer, name string) error {
ew.writeln(` - "AWS_REGION": Managed by the AWS client ('AWS_REGION_FILE' is not supported)`)
ew.writeln(` - "AWS_SDK_LOAD_CONFIG": Managed by the AWS client. Retrieve the region from the CLI config file ('AWS_SDK_LOAD_CONFIG_FILE' is not supported)`)
ew.writeln(` - "AWS_SECRET_ACCESS_KEY": Managed by the AWS client. Secret access key ('AWS_SECRET_ACCESS_KEY_FILE' is not supported, use 'AWS_SHARED_CREDENTIALS_FILE' instead)`)
ew.writeln(` - "AWS_WAIT_FOR_RECORD_SETS_CHANGED": Wait for changes to be INSYNC (it can be unstable)`)
ew.writeln()

ew.writeln(`Additional Configuration:`)
Expand Down
1 change: 1 addition & 0 deletions docs/content/dns/zz_gen_route53.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ lego --domains example.com --email your_example@email.com --dns route53 --accept
| `AWS_REGION` | Managed by the AWS client (`AWS_REGION_FILE` is not supported) |
| `AWS_SDK_LOAD_CONFIG` | Managed by the AWS client. Retrieve the region from the CLI config file (`AWS_SDK_LOAD_CONFIG_FILE` is not supported) |
| `AWS_SECRET_ACCESS_KEY` | Managed by the AWS client. Secret access key (`AWS_SECRET_ACCESS_KEY_FILE` is not supported, use `AWS_SHARED_CREDENTIALS_FILE` instead) |
| `AWS_WAIT_FOR_RECORD_SETS_CHANGED` | Wait for changes to be INSYNC (it can be unstable) |

The environment variable names can be suffixed by `_FILE` to reference a file instead of a value.
More information [here]({{< ref "dns#configuration-and-credentials" >}}).
Expand Down
31 changes: 20 additions & 11 deletions providers/dns/route53/route53.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ const (
EnvAssumeRoleArn = envNamespace + "ASSUME_ROLE_ARN"
EnvExternalID = envNamespace + "EXTERNAL_ID"

EnvWaitForRecordSetsChanged = envNamespace + "WAIT_FOR_RECORD_SETS_CHANGED"

EnvTTL = envNamespace + "TTL"
EnvPropagationTimeout = envNamespace + "PROPAGATION_TIMEOUT"
EnvPollingInterval = envNamespace + "POLLING_INTERVAL"
Expand All @@ -53,6 +55,8 @@ type Config struct {
AssumeRoleArn string
ExternalID string

WaitForRecordSetsChanged bool

TTL int
PropagationTimeout time.Duration
PollingInterval time.Duration
Expand All @@ -68,6 +72,8 @@ func NewDefaultConfig() *Config {
AssumeRoleArn: env.GetOrDefaultString(EnvAssumeRoleArn, ""),
ExternalID: env.GetOrDefaultString(EnvExternalID, ""),

WaitForRecordSetsChanged: env.GetOrDefaultBool(EnvWaitForRecordSetsChanged, true),

TTL: env.GetOrDefaultInt(EnvTTL, 10),
PropagationTimeout: env.GetOrDefaultSecond(EnvPropagationTimeout, 2*time.Minute),
PollingInterval: env.GetOrDefaultSecond(EnvPollingInterval, 4*time.Second),
Expand Down Expand Up @@ -235,19 +241,22 @@ func (d *DNSProvider) changeRecord(ctx context.Context, action awstypes.ChangeAc

changeID := resp.ChangeInfo.Id

return wait.For("route53", d.config.PropagationTimeout, d.config.PollingInterval, func() (bool, error) {
reqParams := &route53.GetChangeInput{Id: changeID}
if d.config.WaitForRecordSetsChanged {
return wait.For("route53", d.config.PropagationTimeout, d.config.PollingInterval, func() (bool, error) {
resp, err := d.client.GetChange(ctx, &route53.GetChangeInput{Id: changeID})
if err != nil {
return false, fmt.Errorf("failed to query change status: %w", err)
}

resp, err := d.client.GetChange(ctx, reqParams)
if err != nil {
return false, fmt.Errorf("failed to query change status: %w", err)
}
if resp.ChangeInfo.Status == awstypes.ChangeStatusInsync {
return true, nil
}

if resp.ChangeInfo.Status == awstypes.ChangeStatusInsync {
return true, nil
}
return false, fmt.Errorf("unable to retrieve change: ID=%s", deref(changeID))
})
return false, fmt.Errorf("unable to retrieve change: ID=%s", deref(changeID))
})
}

return nil
}

func (d *DNSProvider) getExistingRecordSets(ctx context.Context, hostedZoneID, fqdn string) ([]awstypes.ResourceRecord, error) {
Expand Down
1 change: 1 addition & 0 deletions providers/dns/route53/route53.toml
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ Replace `Z11111112222222333333` with your hosted zone ID and `example.com` with
AWS_SDK_LOAD_CONFIG = "Managed by the AWS client. Retrieve the region from the CLI config file (`AWS_SDK_LOAD_CONFIG_FILE` is not supported)"
AWS_ASSUME_ROLE_ARN = "Managed by the AWS Role ARN (`AWS_ASSUME_ROLE_ARN_FILE` is not supported)"
AWS_EXTERNAL_ID = "Managed by STS AssumeRole API operation (`AWS_EXTERNAL_ID_FILE` is not supported)"
AWS_WAIT_FOR_RECORD_SETS_CHANGED = "Wait for changes to be INSYNC (it can be unstable)"
[Configuration.Additional]
AWS_SHARED_CREDENTIALS_FILE = "Managed by the AWS client. Shared credentials file."
AWS_MAX_RETRIES = "The number of maximum returns the service will use to make an individual API request"
Expand Down
25 changes: 14 additions & 11 deletions providers/dns/route53/route53_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ var envTest = tester.NewEnvTest(
EnvMaxRetries,
EnvTTL,
EnvPropagationTimeout,
EnvPollingInterval).
EnvPollingInterval,
EnvWaitForRecordSetsChanged).
WithDomain(envDomain).
WithLiveTestRequirements(EnvAccessKeyID, EnvSecretAccessKey, EnvRegion, envDomain)

Expand Down Expand Up @@ -119,20 +120,22 @@ func TestNewDefaultConfig(t *testing.T) {
{
desc: "default configuration",
expected: &Config{
MaxRetries: 5,
TTL: 10,
PropagationTimeout: 2 * time.Minute,
PollingInterval: 4 * time.Second,
MaxRetries: 5,
TTL: 10,
PropagationTimeout: 2 * time.Minute,
PollingInterval: 4 * time.Second,
WaitForRecordSetsChanged: true,
},
},
{
desc: "",
desc: "set values",
envVars: map[string]string{
EnvMaxRetries: "10",
EnvTTL: "99",
EnvPropagationTimeout: "60",
EnvPollingInterval: "60",
EnvHostedZoneID: "abc123",
EnvMaxRetries: "10",
EnvTTL: "99",
EnvPropagationTimeout: "60",
EnvPollingInterval: "60",
EnvHostedZoneID: "abc123",
EnvWaitForRecordSetsChanged: "false",
},
expected: &Config{
MaxRetries: 10,
Expand Down

0 comments on commit 11b4bef

Please sign in to comment.