Skip to content

Commit aa8965f

Browse files
committed
Fix duplicate entries #1
1 parent 736328b commit aa8965f

File tree

5 files changed

+69
-22
lines changed

5 files changed

+69
-22
lines changed

client.go

+47-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ type Client struct {
2020

2121
// Ovh zone record implementation
2222
type 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.
127127
func (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
136181
func (p *Provider) updateRecord(ctx context.Context, zone string, record libdns.Record) (libdns.Record, error) {
137182
p.client.mutex.Lock()

go.mod

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
module github.com/libdns/ovh
22

3-
go 1.14
3+
go 1.18
44

55
require (
66
github.com/libdns/libdns v0.2.1
7-
github.com/ovh/go-ovh v1.1.0
7+
github.com/ovh/go-ovh v1.3.0
88
)
9+
10+
require gopkg.in/ini.v1 v1.57.0 // indirect

go.sum

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7
44
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
55
github.com/libdns/libdns v0.2.1 h1:Wu59T7wSHRgtA0cfxC+n1c/e+O3upJGWytknkmFEDis=
66
github.com/libdns/libdns v0.2.1/go.mod h1:yQCXzk1lEZmmCPa857bnk4TsOiqYasqpyOEeSObbb40=
7-
github.com/ovh/go-ovh v1.1.0 h1:bHXZmw8nTgZin4Nv7JuaLs0KG5x54EQR7migYTd1zrk=
8-
github.com/ovh/go-ovh v1.1.0/go.mod h1:AxitLZ5HBRPyUd+Zl60Ajaag+rNTdVXWIkzfrVuTXWA=
7+
github.com/ovh/go-ovh v1.3.0 h1:mvZaddk4E4kLcXhzb+cxBsMPYp2pHqiQpWYkInsuZPQ=
8+
github.com/ovh/go-ovh v1.3.0/go.mod h1:AxitLZ5HBRPyUd+Zl60Ajaag+rNTdVXWIkzfrVuTXWA=
99
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
1010
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
1111
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=

provider.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ import (
99
// Provider facilitates DNS record manipulation with OVH.
1010
type Provider struct {
1111
Endpoint string `json:"endpoint,omitempty"`
12-
ApplicationKey string `json:"application_key,omitempty"`
13-
ApplicationSecret string `json:"application_secret,omitempty"`
12+
ApplicationKey string `json:"application_key,omitempty"`
13+
ApplicationSecret string `json:"application_secret,omitempty"`
1414
ConsumerKey string `json:"consumer_key,omitempty"`
1515
client Client
1616
}

provider_test.go

+14-14
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@ import (
1313
)
1414

1515
var (
16-
endPoint = ""
17-
applicationKey = ""
18-
applicationSecret = ""
19-
consumerKey = ""
20-
zone = ""
21-
ttl = time.Duration(120 * time.Second)
16+
endPoint = ""
17+
applicationKey = ""
18+
applicationSecret = ""
19+
consumerKey = ""
20+
zone = ""
21+
ttl = time.Duration(120 * time.Second)
2222
)
2323

2424
func TestMain(m *testing.M) {
@@ -57,7 +57,7 @@ func setupTestRecords(t *testing.T, p *ovh.Provider) ([]libdns.Record, testRecor
5757
},
5858
}
5959

60-
records, err := p.AppendRecords(context.TODO(), zone, testRecords)
60+
records, err := p.SetRecords(context.TODO(), zone, testRecords)
6161
if err != nil {
6262
t.Fatal(err)
6363
return nil, func() {}
@@ -155,20 +155,20 @@ func Test_SetRecords(t *testing.T) {
155155
newTestRecords := []libdns.Record{
156156
{
157157
Type: "TXT",
158-
Name: "new_test1",
159-
Value: "new_test1",
158+
Name: "newtest1",
159+
Value: "newtest1",
160160
TTL: ttl,
161161
},
162162
{
163163
Type: "TXT",
164-
Name: "new_test2",
165-
Value: "new_test2",
164+
Name: "newtest2",
165+
Value: "newtest2",
166166
TTL: ttl,
167167
},
168168
}
169169

170170
allRecords := append(existingRecords, newTestRecords...)
171-
allRecords[0].Value = "new_value"
171+
allRecords[0].Value = "newvalue"
172172

173173
records, err := p.SetRecords(context.TODO(), zone, allRecords)
174174
if err != nil {
@@ -180,8 +180,8 @@ func Test_SetRecords(t *testing.T) {
180180
t.Fatalf("len(records) != len(allRecords) => %d != %d", len(records), len(allRecords))
181181
}
182182

183-
if records[0].Value != "new_value" {
184-
t.Fatalf(`records[0].Value != "new_value" => %s != "new_value"`, records[0].Value)
183+
if records[0].Value != "newvalue" {
184+
t.Fatalf(`records[0].Value != "newvalue" => %s != "newvalue"`, records[0].Value)
185185
}
186186
}
187187

0 commit comments

Comments
 (0)