@@ -103,6 +103,9 @@ func (p *Provider) Delete(record *iov1.DNSRecord, zone configv1.DNSZone) error {
103103
104104 for _ , resourceRecord := range result .ResourceRecords {
105105 var resourceRecordTarget string
106+ if resourceRecord .ID == nil {
107+ return fmt .Errorf ("delete: record id is nil" )
108+ }
106109 rData , ok := resourceRecord .Rdata .(map [string ]interface {})
107110 if ! ok {
108111 return fmt .Errorf ("delete: failed to get resource data: %v" , resourceRecord .Rdata )
@@ -126,7 +129,8 @@ func (p *Provider) Delete(record *iov1.DNSRecord, zone configv1.DNSZone) error {
126129 default :
127130 return fmt .Errorf ("delete: resource data has record with unknown type: %v" , * resourceRecord .Type )
128131 }
129-
132+ // While creating DNS records with multiple targets is unsupported, we still
133+ // iterate through all targets during deletion to be extra cautious.
130134 for _ , target := range record .Spec .Targets {
131135 if * resourceRecord .Name == dnsName {
132136 if resourceRecordTarget != target {
@@ -190,9 +194,14 @@ func (p *Provider) createOrUpdateDNSRecord(record *iov1.DNSRecord, zone configv1
190194 log .Info ("Warning: TTL must be one of [1 60 120 300 600 900 1800 3600 7200 18000 43200]. RecordTTL set to default" , "default DSNSVCS record TTL" , defaultDNSSVCSRecordTTL )
191195 record .Spec .RecordTTL = defaultDNSSVCSRecordTTL
192196 }
197+ if len (record .Spec .Targets ) > 1 {
198+ return fmt .Errorf ("createOrUpdateDNSRecord: only one target is supported, but found %d: targets=%v" , len (record .Spec .Targets ), record .Spec .Targets )
199+ }
193200
194201 listResult , response , err := p .dnsService .ListResourceRecords (listOpt )
195202 if err != nil {
203+ // Avoid continuing with an invalid list response, as we can't determine
204+ // whether to create or update the DNS record, which may lead to further issues.
196205 if response == nil || response .StatusCode != http .StatusNotFound {
197206 return fmt .Errorf ("createOrUpdateDNSRecord: failed to list the dns record: %w" , err )
198207 }
@@ -201,72 +210,74 @@ func (p *Provider) createOrUpdateDNSRecord(record *iov1.DNSRecord, zone configv1
201210 return fmt .Errorf ("createOrUpdateDNSRecord: ListResourceRecords returned nil as result" )
202211 }
203212
204- for _ , target := range record .Spec .Targets {
205- updated := false
206- for _ , resourceRecord := range listResult .ResourceRecords {
207- if * resourceRecord .Name == dnsName {
208- updateOpt := p .dnsService .NewUpdateResourceRecordOptions (p .config .InstanceID , zone .ID , * resourceRecord .ID )
209- updateOpt .SetName (dnsName )
210-
211- if resourceRecord .Type == nil {
212- return fmt .Errorf ("createOrUpdateDNSRecord: failed to get resource type, resourceRecord.Type is nil" )
213- }
213+ target := record .Spec .Targets [0 ]
214+ updated := false
215+ for _ , resourceRecord := range listResult .ResourceRecords {
216+ if * resourceRecord .Name == dnsName {
217+ if resourceRecord .ID == nil {
218+ return fmt .Errorf ("createOrUpdateDNSRecord: record id is nil" )
219+ }
220+ updateOpt := p .dnsService .NewUpdateResourceRecordOptions (p .config .InstanceID , zone .ID , * resourceRecord .ID )
221+ updateOpt .SetName (dnsName )
214222
215- // TODO DNS record update should handle the case where we have an A record and want a CNAME record or vice versa
216- switch * resourceRecord .Type {
217- case string (iov1 .CNAMERecordType ):
218- inputRData , err := p .dnsService .NewResourceRecordUpdateInputRdataRdataCnameRecord (target )
219- if err != nil {
220- return fmt .Errorf ("createOrUpdateDNSRecord: failed to create CNAME inputRData for the dns record: %w" , err )
221- }
222- updateOpt .SetRdata (inputRData )
223- case string (iov1 .ARecordType ):
224- inputRData , err := p .dnsService .NewResourceRecordUpdateInputRdataRdataARecord (target )
225- if err != nil {
226- return fmt .Errorf ("createOrUpdateDNSRecord: failed to create A inputRData for the dns record: %w" , err )
227- }
228- updateOpt .SetRdata (inputRData )
229- default :
230- return fmt .Errorf ("createOrUpdateDNSRecord: resource data has record with unknown type: %v" , * resourceRecord .Type )
231- }
232- updateOpt .SetTTL (record .Spec .RecordTTL )
233- _ , _ , err := p .dnsService .UpdateResourceRecord (updateOpt )
234- if err != nil {
235- return fmt .Errorf ("createOrUpdateDNSRecord: failed to update the dns record: %w" , err )
236- }
237- updated = true
238- log .Info ("updated DNS record" , "record" , record .Spec , "zone" , zone , "target" , target )
223+ if resourceRecord .Type == nil {
224+ return fmt .Errorf ("createOrUpdateDNSRecord: failed to get resource type, resourceRecord.Type is nil" )
239225 }
240- }
241- if ! updated {
242- createOpt := p .dnsService .NewCreateResourceRecordOptions (p .config .InstanceID , zone .ID )
243- createOpt .SetName (dnsName )
244- createOpt .SetType (string (record .Spec .RecordType ))
245-
246- switch record .Spec .RecordType {
247- case iov1 .CNAMERecordType :
248- inputRData , err := p .dnsService .NewResourceRecordInputRdataRdataCnameRecord (target )
226+
227+ // TODO DNS record update should handle the case where we have an A record and want a CNAME record or vice versa
228+ switch * resourceRecord .Type {
229+ case string (iov1 .CNAMERecordType ):
230+ inputRData , err := p .dnsService .NewResourceRecordUpdateInputRdataRdataCnameRecord (target )
249231 if err != nil {
250232 return fmt .Errorf ("createOrUpdateDNSRecord: failed to create CNAME inputRData for the dns record: %w" , err )
251233 }
252- createOpt .SetRdata (inputRData )
253- case iov1 .ARecordType :
254- inputRData , err := p .dnsService .NewResourceRecordInputRdataRdataARecord (target )
234+ updateOpt .SetRdata (inputRData )
235+ case string ( iov1 .ARecordType ) :
236+ inputRData , err := p .dnsService .NewResourceRecordUpdateInputRdataRdataARecord (target )
255237 if err != nil {
256238 return fmt .Errorf ("createOrUpdateDNSRecord: failed to create A inputRData for the dns record: %w" , err )
257239 }
258- createOpt .SetRdata (inputRData )
240+ updateOpt .SetRdata (inputRData )
259241 default :
260- return fmt .Errorf ("createOrUpdateDNSRecord: resource data has record with unknown type: %v" , record .Spec .RecordType )
261-
242+ return fmt .Errorf ("createOrUpdateDNSRecord: resource data has record with unknown type: %v" , * resourceRecord .Type )
243+ }
244+ updateOpt .SetTTL (record .Spec .RecordTTL )
245+ _ , _ , err := p .dnsService .UpdateResourceRecord (updateOpt )
246+ if err != nil {
247+ return fmt .Errorf ("createOrUpdateDNSRecord: failed to update the dns record: %w" , err )
248+ }
249+ updated = true
250+ log .Info ("updated DNS record" , "record" , record .Spec , "zone" , zone , "target" , target )
251+ }
252+ }
253+ if ! updated {
254+ createOpt := p .dnsService .NewCreateResourceRecordOptions (p .config .InstanceID , zone .ID )
255+ createOpt .SetName (dnsName )
256+ createOpt .SetType (string (record .Spec .RecordType ))
257+
258+ switch record .Spec .RecordType {
259+ case iov1 .CNAMERecordType :
260+ inputRData , err := p .dnsService .NewResourceRecordInputRdataRdataCnameRecord (target )
261+ if err != nil {
262+ return fmt .Errorf ("createOrUpdateDNSRecord: failed to create CNAME inputRData for the dns record: %w" , err )
262263 }
263- createOpt .SetTTL (record .Spec .RecordTTL )
264- _ , _ , err := p .dnsService .CreateResourceRecord (createOpt )
264+ createOpt .SetRdata (inputRData )
265+ case iov1 .ARecordType :
266+ inputRData , err := p .dnsService .NewResourceRecordInputRdataRdataARecord (target )
265267 if err != nil {
266- return fmt .Errorf ("createOrUpdateDNSRecord: failed to create the dns record: %w" , err )
268+ return fmt .Errorf ("createOrUpdateDNSRecord: failed to create A inputRData for the dns record: %w" , err )
267269 }
268- log .Info ("created DNS record" , "record" , record .Spec , "zone" , zone , "target" , target )
270+ createOpt .SetRdata (inputRData )
271+ default :
272+ return fmt .Errorf ("createOrUpdateDNSRecord: resource data has record with unknown type: %v" , record .Spec .RecordType )
273+
274+ }
275+ createOpt .SetTTL (record .Spec .RecordTTL )
276+ _ , _ , err := p .dnsService .CreateResourceRecord (createOpt )
277+ if err != nil {
278+ return fmt .Errorf ("createOrUpdateDNSRecord: failed to create the dns record: %w" , err )
269279 }
280+ log .Info ("created DNS record" , "record" , record .Spec , "zone" , zone , "target" , target )
270281 }
271282 return nil
272283}
0 commit comments