route53: adds option to not wait for changes (#2181)

This commit is contained in:
Ludovic Fernandez 2024-05-09 21:05:21 +02:00 committed by GitHub
parent 2ec9e42ee3
commit 11b4beff7e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 37 additions and 22 deletions

View file

@ -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:`)

View file

@ -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" >}}).

View file

@ -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"
@ -53,6 +55,8 @@ type Config struct {
AssumeRoleArn string
ExternalID string
WaitForRecordSetsChanged bool
TTL int
PropagationTimeout time.Duration
PollingInterval time.Duration
@ -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),
@ -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) {

View file

@ -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"

View file

@ -25,7 +25,8 @@ var envTest = tester.NewEnvTest(
EnvMaxRetries,
EnvTTL,
EnvPropagationTimeout,
EnvPollingInterval).
EnvPollingInterval,
EnvWaitForRecordSetsChanged).
WithDomain(envDomain).
WithLiveTestRequirements(EnvAccessKeyID, EnvSecretAccessKey, EnvRegion, envDomain)
@ -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,