@@ -20,7 +20,7 @@ type Client struct {
2020
2121// Ovh zone record implementation
2222type OvhDomainZoneRecord struct {
23- ID int64 `json:"id,omitempty"`
23+ ID int64 `json:"id,omitempty"`
2424 Zone string `json:"zone,omitempty"`
2525 SubDomain string `json:"subDomain"`
2626 FieldType string `json:"fieldType,omitempty"`
@@ -34,7 +34,7 @@ type OvhDomainZoneSOA struct {
3434 Email string `json:"email"`
3535 Serial int64 `json:"serial"`
3636 Refresh int64 `json:"refresh"`
37- NxDomainTTL int64 `json:"nxDomainTtl"`
37+ NxDomainTTL int64 `json:"nxDomainTtl"`
3838 Expire int64 `json:"expire"`
3939 TTL int64 `json:"ttl"`
4040}
@@ -126,12 +126,57 @@ func (p *Provider) createRecord(ctx context.Context, zone string, record libdns.
126126// createOrUpdateRecord creates or updates a record, either by updating existing record or creating new one.
127127func (p * Provider ) createOrUpdateRecord (ctx context.Context , zone string , record libdns.Record ) (libdns.Record , error ) {
128128 if len (record .ID ) == 0 {
129+ // lookup for existing records
130+ // if we find one, update it
131+ // if we find multiple, delete them and recreate the final one
132+ existingIDs , err := p .lookupRecordIDs (ctx , zone , record .Type , normalizeRecordName (record .Name , zone ))
133+ if err != nil {
134+ return libdns.Record {}, err
135+ }
136+ if len (existingIDs ) == 1 {
137+ record .ID = strconv .FormatInt (existingIDs [0 ], 10 )
138+ return p .updateRecord (ctx , zone , record )
139+ } else if len (existingIDs ) > 1 {
140+ for _ , eid := range existingIDs {
141+ if err := p .deleteRecordID (ctx , zone , strconv .FormatInt (eid , 10 )); err != nil {
142+ return libdns.Record {}, err
143+ }
144+ }
145+ }
146+
129147 return p .createRecord (ctx , zone , record )
130148 }
131149
132150 return p .updateRecord (ctx , zone , record )
133151}
134152
153+ func (p * Provider ) lookupRecordIDs (ctx context.Context , zone string , recordType string , recordName string ) ([]int64 , error ) {
154+ p .client .mutex .Lock ()
155+ defer p .client .mutex .Unlock ()
156+
157+ if err := p .setupClient (); err != nil {
158+ return nil , err
159+ }
160+
161+ var res []int64
162+ if err := p .client .ovhClient .GetWithContext (ctx , fmt .Sprintf ("/domain/zone/%s/record?fieldType=%s&subDomain=%s" , zone , recordType , recordName ), & res ); err != nil {
163+ return nil , err
164+ }
165+
166+ return res , nil
167+ }
168+
169+ func (p * Provider ) deleteRecordID (ctx context.Context , zone string , recordID string ) error {
170+ p .client .mutex .Lock ()
171+ defer p .client .mutex .Unlock ()
172+
173+ if err := p .setupClient (); err != nil {
174+ return err
175+ }
176+
177+ return p .client .ovhClient .DeleteWithContext (ctx , fmt .Sprintf ("/domain/zone/%s/record/%s" , zone , recordID ), nil );
178+ }
179+
135180// updateRecord updates a record
136181func (p * Provider ) updateRecord (ctx context.Context , zone string , record libdns.Record ) (libdns.Record , error ) {
137182 p .client .mutex .Lock ()
0 commit comments