88 "net/http"
99 "os"
1010 "os/signal"
11+ "strings"
1112 "syscall"
1213 "time"
1314
@@ -29,14 +30,19 @@ var (
2930
3031 register , unRegister bool
3132
32- r53 * route53. Client
33+ r53 Route53Client
3334)
3435
36+ type Route53Client interface {
37+ ChangeResourceRecordSets (ctx context.Context , params * route53.ChangeResourceRecordSetsInput , optFns ... func (* route53.Options )) (* route53.ChangeResourceRecordSetsOutput , error )
38+ GetChange (ctx context.Context , params * route53.GetChangeInput , optFns ... func (* route53.Options )) (* route53.GetChangeOutput , error )
39+ }
40+
3541func configureFromFlags (ctx context.Context ) {
3642 flag .StringVar (& dns , "dns" , "my.example.com" , "DNS name to register in Route53" )
3743 flag .StringVar (& hostedZone , "hostedzone" , "Z2AAAABCDEFGT4" , "Hosted zone ID in route53" )
3844 flag .IntVar (& dnsTTL , "dnsttl" , 10 , "Timeout for DNS entry" )
39- flag .StringVar (& ipAddress , "ipaddress" , "public-ipv4 " , "IP Address for A Record" )
45+ flag .StringVar (& ipAddress , "ipaddress" , "1.2.4.5 " , "IP Address for A Record" )
4046 flag .BoolVar (& register , "register" , false , "Register DNS and exit" )
4147 flag .BoolVar (& unRegister , "unregister" , false , "Unregister DNS and exit" )
4248 flag .Parse ()
@@ -122,7 +128,7 @@ func tearDownDNS(ctx context.Context) {
122128 log .Print ("DNS Timeout expiry finished" )
123129}
124130
125- func setupDNS (ctx context.Context ) {
131+ func setupDNS (ctx context.Context ) error {
126132 log .Printf ("Setting up Route 53 DNS Name A %s => %s" , dns , ipAddress )
127133
128134 input := & route53.ChangeResourceRecordSetsInput {
@@ -149,22 +155,34 @@ func setupDNS(ctx context.Context) {
149155 HostedZoneId : aws .String (hostedZone ),
150156 }
151157
152- changeSet , err := r53 .ChangeResourceRecordSets (ctx , input )
153- if err != nil {
154- log .Printf ("Failed to create DNS: %v" , err .Error ())
155- return
158+ var changeSet * route53.ChangeResourceRecordSetsOutput
159+ for {
160+ var err error
161+ changeSet , err = r53 .ChangeResourceRecordSets (ctx , input )
162+ if err != nil {
163+ if ! strings .Contains (err .Error (), "conflicting RRSet of type CNAME" ) {
164+ log .Printf ("Failed to create DNS: %v" , err .Error ())
165+ return err
166+ }
167+ // If the error is due to a conflicting CNAME, wait and try again
168+ if err := SleepWithContext (ctx , 5 * time .Second ); err != nil {
169+ return err
170+ }
171+ continue
172+ }
173+ break
156174 }
157175
158176 log .Print ("Request sent to Route 53..." )
159- waitForSync (ctx , changeSet )
177+ return waitForSync (ctx , changeSet )
160178}
161179
162- func waitForSync (ctx context.Context , changeSet * route53.ChangeResourceRecordSetsOutput ) {
180+ func waitForSync (ctx context.Context , changeSet * route53.ChangeResourceRecordSetsOutput ) error {
163181 failures := 0
164182 for {
165183 if err := SleepWithContext (ctx , 5 * time .Second ); err != nil {
166184 log .Print ("Context cancelled, stop waiting for Route53 ChangeSet to propogate" )
167- return
185+ return err
168186 }
169187
170188 changeOutput , err := r53 .GetChange (ctx , & route53.GetChangeInput {
@@ -181,7 +199,7 @@ func waitForSync(ctx context.Context, changeSet *route53.ChangeResourceRecordSet
181199
182200 if changeOutput .ChangeInfo .Status == "INSYNC" {
183201 log .Print ("Route53 Change Completed" )
184- break
202+ return nil
185203 }
186204
187205 log .Printf ("Route53 Change not yet propogated (ChangeInfo.Status = %s)..." , changeOutput .ChangeInfo .Status )
0 commit comments