Skip to content

Commit ca1cbaf

Browse files
authored
feat: Implement support for PTR records (#22)
* feat: Implement PTR records * fix: fix linter errors
1 parent 821c450 commit ca1cbaf

File tree

3 files changed

+66
-66
lines changed

3 files changed

+66
-66
lines changed

internal/infoblox/common.go

Lines changed: 14 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -101,31 +101,20 @@ func ToHostResponseMap(res []ibclient.HostRecord) *ResponseMap {
101101
return rm
102102
}
103103

104-
// TODO: ToPTRResponseMap
105-
//if p.createPTR {
106-
// // infoblox doesn't accept reverse zone's fqdn, and instead expects .in-addr.arpa zone
107-
// // so convert our zone fqdn (if it is a correct cidr block) into in-addr.arpa address and pass that into infoblox
108-
// // example: 10.196.38.0/24 becomes 38.196.10.in-addr.arpa
109-
// arpaZone, err := transform.ReverseDomainName(zone.Fqdn)
110-
// if err == nil {
111-
// var resP []ibclient.RecordPTR
112-
// objP := ibclient.NewEmptyRecordPTR()
113-
// objP.Zone = arpaZone
114-
// objP.View = p.view
115-
// err = p.client.GetObject(objP, "", searchParams, &resP)
116-
// if err != nil && !isNotFoundError(err) {
117-
// return nil, fmt.Errorf("could not fetch PTR records from zone '%s': %w", zone.Fqdn, err)
118-
// }
119-
// for _, res := range resP {
120-
// endpoints = append(endpoints, endpoint.NewEndpointWithTTL(res.PtrdName,
121-
// endpoint.RecordTypePTR,
122-
// endpoint.TTL(int(res.Ttl)),
123-
// res.Ipv4Addr,
124-
// ),
125-
// )
126-
// }
127-
// }
128-
//}
104+
func ToPTRResponseMap(res []ibclient.RecordPTR) *ResponseMap {
105+
rm := &ResponseMap{
106+
Map: make(map[string]ResponseDetails),
107+
RecordType: ibclient.PtrRecord,
108+
}
109+
for _, record := range res {
110+
if _, ok := rm.Map[AsString(record.PtrdName)]; !ok {
111+
rm.Map[AsString(record.PtrdName)] = ResponseDetails{{Target: AsString(record.Ipv4Addr), TTL: AsInt64(record.Ttl)}}
112+
continue
113+
}
114+
rm.Map[AsString(record.PtrdName)] = append(rm.Map[AsString(record.PtrdName)], ResponseDetail{Target: AsString(record.Ipv4Addr), TTL: AsInt64(record.Ttl)})
115+
}
116+
return rm
117+
}
129118

130119
func (rd ResponseDetails) ToEndpointDetail() (targets []string, ttl endpoint.TTL) {
131120
for _, v := range rd {
@@ -136,10 +125,6 @@ func (rd ResponseDetails) ToEndpointDetail() (targets []string, ttl endpoint.TTL
136125
}
137126

138127
func (rm *ResponseMap) ToEndpoints() []*endpoint.Endpoint {
139-
// TODO: PTR provider specific label records
140-
// if p.createPTR {
141-
// newEndpoint.WithProviderSpecific(providerSpecificInfobloxPtrRecord, "true")
142-
// }
143128
var endpoints []*endpoint.Endpoint
144129
for k, v := range rm.Map {
145130
targets, ttl := v.ToEndpointDetail()
@@ -149,34 +134,3 @@ func (rm *ResponseMap) ToEndpoints() []*endpoint.Endpoint {
149134
}
150135
return endpoints
151136
}
152-
153-
// TODO: update A records that have PTR record created for them already
154-
//if p.createPTR {
155-
// // save all ptr records into map for a quick look up
156-
// ptrRecordsMap := make(map[string]bool)
157-
// for _, ptrRecord := range endpoints {
158-
// if ptrRecord.RecordType != endpoint.RecordTypePTR {
159-
// continue
160-
// }
161-
// ptrRecordsMap[ptrRecord.DNSName] = true
162-
// }
163-
//
164-
// for i := range endpoints {
165-
// if endpoints[i].RecordType != endpoint.RecordTypeA {
166-
// continue
167-
// }
168-
// // if PTR record already exists for A record, then mark it as such
169-
// if ptrRecordsMap[endpoints[i].DNSName] {
170-
// found := false
171-
// for j := range endpoints[i].ProviderSpecific {
172-
// if endpoints[i].ProviderSpecific[j].Name == providerSpecificInfobloxPtrRecord {
173-
// endpoints[i].ProviderSpecific[j].Value = "true"
174-
// found = true
175-
// }
176-
// }
177-
// if !found {
178-
// endpoints[i].WithProviderSpecific(providerSpecificInfobloxPtrRecord, "true")
179-
// }
180-
// }
181-
// }
182-
//}

internal/infoblox/infoblox.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import (
3232
log "github.com/sirupsen/logrus"
3333

3434
"sigs.k8s.io/external-dns/endpoint"
35+
"sigs.k8s.io/external-dns/pkg/rfc2317"
3536
"sigs.k8s.io/external-dns/plan"
3637
"sigs.k8s.io/external-dns/provider"
3738
)
@@ -240,6 +241,54 @@ func (p *Provider) Records(_ context.Context) (endpoints []*endpoint.Endpoint, e
240241
}
241242
endpointsTXT := ToTXTResponseMap(resT).ToEndpoints()
242243
endpoints = append(endpoints, endpointsTXT...)
244+
245+
if p.config.CreatePTR {
246+
arpaZone, err := rfc2317.CidrToInAddr(zone.Fqdn)
247+
if err == nil {
248+
var resP []ibclient.RecordPTR
249+
objP := ibclient.NewEmptyRecordPTR()
250+
objP.View = p.config.View
251+
objP.Zone = arpaZone
252+
err = PagingGetObject(p.client, objP, "", map[string]string{"zone": arpaZone, "view": p.config.View}, &resP)
253+
if err != nil && !isNotFoundError(err) {
254+
return nil, fmt.Errorf("could not fetch PTR records from zone '%s': %w", zone.Fqdn, err)
255+
}
256+
endpointsPTR := ToPTRResponseMap(resP).ToEndpoints()
257+
endpoints = append(endpoints, endpointsPTR...)
258+
} else {
259+
log.Debugf("Could not fetch PTR records from zone '%s': %s", zone.Fqdn, err)
260+
}
261+
}
262+
}
263+
264+
if p.config.CreatePTR {
265+
// save all ptr records into map for a quick look up
266+
ptrRecordsMap := make(map[string]bool)
267+
for _, ptrRecord := range endpoints {
268+
if ptrRecord.RecordType != endpoint.RecordTypePTR {
269+
continue
270+
}
271+
ptrRecordsMap[ptrRecord.DNSName] = true
272+
}
273+
274+
for i := range endpoints {
275+
if endpoints[i].RecordType != endpoint.RecordTypeA {
276+
continue
277+
}
278+
// if PTR record already exists for A record, then mark it as such
279+
if ptrRecordsMap[endpoints[i].DNSName] {
280+
found := false
281+
for j := range endpoints[i].ProviderSpecific {
282+
if endpoints[i].ProviderSpecific[j].Name == providerSpecificInfobloxPtrRecord {
283+
endpoints[i].ProviderSpecific[j].Value = "true"
284+
found = true
285+
}
286+
}
287+
if !found {
288+
endpoints[i].WithProviderSpecific(providerSpecificInfobloxPtrRecord, "true")
289+
}
290+
}
291+
}
243292
}
244293

245294
log.Debugf("fetched %d records from infoblox", len(endpoints))

internal/infoblox/infoblox_test.go

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -339,12 +339,11 @@ func (client *mockIBConnector) GetObject(obj ibclient.IBObject, ref string, quer
339339
ref != object.(*ibclient.RecordPTR).Ref {
340340
continue
341341
}
342-
if *obj.(*ibclient.RecordPTR).PtrdName != "" &&
343-
obj.(*ibclient.RecordPTR).PtrdName != object.(*ibclient.RecordPTR).PtrdName {
342+
if AsString(obj.(*ibclient.RecordPTR).PtrdName) != "" &&
343+
AsString(obj.(*ibclient.RecordPTR).PtrdName) != AsString(object.(*ibclient.RecordPTR).PtrdName) {
344344
continue
345345
}
346-
// TODO:
347-
if !strings.Contains(req.queryParams, fmt.Sprintf("ipv4addr:%s name:%s", AsString(object.(*ibclient.RecordPTR).Ipv4Addr), AsString(object.(*ibclient.RecordPTR).Name))) {
346+
if !strings.Contains(req.queryParams, fmt.Sprintf("name:%s", AsString(object.(*ibclient.RecordPTR).Name))) {
348347
if !strings.Contains(req.queryParams, fmt.Sprintf("zone:%s", object.(*ibclient.RecordPTR).Zone)) {
349348
continue
350349
}
@@ -790,7 +789,6 @@ func TestInfobloxAdjustEndpoints(t *testing.T) {
790789
}
791790

792791
func TestInfobloxRecordsReverse(t *testing.T) {
793-
t.Skip()
794792
client := mockIBConnector{
795793
mockInfobloxZones: &[]ibclient.ZoneAuth{
796794
createMockInfobloxZone("10.0.0.0/24"),
@@ -845,7 +843,6 @@ func TestInfobloxApplyChanges(t *testing.T) {
845843
}
846844

847845
func TestInfobloxApplyChangesReverse(t *testing.T) {
848-
t.Skip()
849846
client := mockIBConnector{}
850847

851848
testInfobloxApplyChangesInternal(t, false, true, &client)

0 commit comments

Comments
 (0)