Skip to content

Commit 27b345d

Browse files
authored
feat: Add support for extensible attributes (#26)
* feat: Add support for extensible attributes Signed-off-by: Joost Buskermolen <[email protected]> * docs: Extend README with INFOBLOX_EXTENSIBLE_ATTRIBUTES_JSON Signed-off-by: Joost Buskermolen <[email protected]> * fix: Improve deserialization logic for extensible attributes Signed-off-by: Joost Buskermolen <[email protected]> * fix: Remove unnecessary stringified JSON check in deserialization Signed-off-by: Joost Buskermolen <[email protected]> --------- Signed-off-by: Joost Buskermolen <[email protected]>
1 parent 241dcc9 commit 27b345d

File tree

2 files changed

+57
-26
lines changed

2 files changed

+57
-26
lines changed

README.md

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,20 @@ To run the provider, you must provide the following Environment Variables:
1616

1717
**Infoblox Environment Variables**:
1818

19-
| Environment Variable | Default value | Required |
20-
|-----------------------------|---------------|----------|
21-
| INFOBLOX_HOST | localhost | true |
22-
| INFOBLOX_PORT | 443 | true |
23-
| INFOBLOX_WAPI_USER | | true |
24-
| INFOBLOX_WAPI_PASSWORD | | true |
25-
| INFOBLOX_VERSION | | true |
26-
| INFOBLOX_SSL_VERIFY | true | false |
27-
| INFOBLOX_DRY_RUN | false | false |
28-
| INFOBLOX_VIEW | default | false |
29-
| INFOBLOX_MAX_RESULTS | 1500 | false |
30-
| INFOBLOX_CREATE_PTR | false | false |
31-
| INFOBLOX_DEFAULT_TTL | 300 | false |
19+
| Environment Variable | Default value | Required |
20+
|-------------------------------------|---------------|----------|
21+
| INFOBLOX_HOST | localhost | true |
22+
| INFOBLOX_PORT | 443 | true |
23+
| INFOBLOX_WAPI_USER | | true |
24+
| INFOBLOX_WAPI_PASSWORD | | true |
25+
| INFOBLOX_VERSION | | true |
26+
| INFOBLOX_SSL_VERIFY | true | false |
27+
| INFOBLOX_DRY_RUN | false | false |
28+
| INFOBLOX_VIEW | default | false |
29+
| INFOBLOX_MAX_RESULTS | 1500 | false |
30+
| INFOBLOX_CREATE_PTR | false | false |
31+
| INFOBLOX_DEFAULT_TTL | 300 | false |
32+
| INFOBLOX_EXTENSIBLE_ATTRIBUTES_JSON | {} | false |
3233

3334

3435
**external-dns-infoblox-webhook Environment Variables**:

internal/infoblox/infoblox.go

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ Generated by GoLic, for more details see: https://github.com/AbsaOSS/golic
2020

2121
import (
2222
"context"
23+
"encoding/json"
2324
"fmt"
2425
"net"
2526
"net/http"
@@ -59,19 +60,20 @@ type Provider struct {
5960

6061
// StartupConfig clarifies the method signature
6162
type StartupConfig struct {
62-
Host string `env:"INFOBLOX_HOST,required" envDefault:"localhost"`
63-
Port int `env:"INFOBLOX_PORT,required" envDefault:"443"`
64-
Username string `env:"INFOBLOX_WAPI_USER,required"`
65-
Password string `env:"INFOBLOX_WAPI_PASSWORD,required"`
66-
Version string `env:"INFOBLOX_VERSION,required"`
67-
SSLVerify bool `env:"INFOBLOX_SSL_VERIFY" envDefault:"true"`
68-
DryRun bool `env:"INFOBLOX_DRY_RUN" envDefault:"false"`
69-
View string `env:"INFOBLOX_VIEW" envDefault:"default"`
70-
MaxResults int `env:"INFOBLOX_MAX_RESULTS" envDefault:"1500"`
71-
CreatePTR bool `env:"INFOBLOX_CREATE_PTR" envDefault:"false"`
72-
DefaultTTL int `env:"INFOBLOX_DEFAULT_TTL" envDefault:"300"`
73-
FQDNRegEx string
74-
NameRegEx string
63+
Host string `env:"INFOBLOX_HOST,required" envDefault:"localhost"`
64+
Port int `env:"INFOBLOX_PORT,required" envDefault:"443"`
65+
Username string `env:"INFOBLOX_WAPI_USER,required"`
66+
Password string `env:"INFOBLOX_WAPI_PASSWORD,required"`
67+
Version string `env:"INFOBLOX_VERSION,required"`
68+
SSLVerify bool `env:"INFOBLOX_SSL_VERIFY" envDefault:"true"`
69+
DryRun bool `env:"INFOBLOX_DRY_RUN" envDefault:"false"`
70+
View string `env:"INFOBLOX_VIEW" envDefault:"default"`
71+
MaxResults int `env:"INFOBLOX_MAX_RESULTS" envDefault:"1500"`
72+
CreatePTR bool `env:"INFOBLOX_CREATE_PTR" envDefault:"false"`
73+
DefaultTTL int `env:"INFOBLOX_DEFAULT_TTL" envDefault:"300"`
74+
ExtAttrsJSON string `env:"INFOBLOX_EXTENSIBLE_ATTRIBUTES_JSON" envDefault:"{}"`
75+
FQDNRegEx string
76+
NameRegEx string
7577
}
7678

7779
type infobloxRecordSet struct {
@@ -181,13 +183,18 @@ func (p *Provider) Records(_ context.Context) (endpoints []*endpoint.Endpoint, e
181183
if err != nil {
182184
return nil, fmt.Errorf("could not fetch zones: %w", err)
183185
}
186+
extAttrs, err := deserializeEAs(p.config.ExtAttrsJSON)
187+
if err != nil {
188+
return nil, err
189+
}
184190

185191
for _, zone := range zones {
186192
log.Debugf("fetch records from zone '%s'", zone.Fqdn)
187193
searchParams := map[string]string{"zone": zone.Fqdn, "view": p.config.View}
188194
var resA []ibclient.RecordA
189195
objA := ibclient.NewEmptyRecordA()
190196
objA.View = p.config.View
197+
objA.Ea = extAttrs
191198
objA.Zone = zone.Fqdn
192199
err = PagingGetObject(p.client, objA, "", searchParams, &resA)
193200
if err != nil && !isNotFoundError(err) {
@@ -200,6 +207,7 @@ func (p *Provider) Records(_ context.Context) (endpoints []*endpoint.Endpoint, e
200207
var resH []ibclient.HostRecord
201208
objH := ibclient.NewEmptyHostRecord()
202209
objH.View = &p.config.View
210+
objH.Ea = extAttrs
203211
objH.Zone = zone.Fqdn
204212
err = PagingGetObject(p.client, objH, "", searchParams, &resH)
205213
if err != nil && !isNotFoundError(err) {
@@ -211,6 +219,7 @@ func (p *Provider) Records(_ context.Context) (endpoints []*endpoint.Endpoint, e
211219
var resC []ibclient.RecordCNAME
212220
objC := ibclient.NewEmptyRecordCNAME()
213221
objC.View = &p.config.View
222+
objC.Ea = extAttrs
214223
objC.Zone = zone.Fqdn
215224
err = PagingGetObject(p.client, objC, "", searchParams, &resC)
216225
if err != nil && !isNotFoundError(err) {
@@ -222,6 +231,7 @@ func (p *Provider) Records(_ context.Context) (endpoints []*endpoint.Endpoint, e
222231
var resT []ibclient.RecordTXT
223232
objT := ibclient.NewEmptyRecordTXT()
224233
objT.View = &p.config.View
234+
objT.Ea = extAttrs
225235
objT.Zone = zone.Fqdn
226236
err = PagingGetObject(p.client, objT, "", searchParams, &resT)
227237
if err != nil && !isNotFoundError(err) {
@@ -236,6 +246,7 @@ func (p *Provider) Records(_ context.Context) (endpoints []*endpoint.Endpoint, e
236246
var resP []ibclient.RecordPTR
237247
objP := ibclient.NewEmptyRecordPTR()
238248
objP.View = p.config.View
249+
objP.Ea = extAttrs
239250
objP.Zone = arpaZone
240251
err = PagingGetObject(p.client, objP, "", map[string]string{"zone": arpaZone, "view": p.config.View}, &resP)
241252
if err != nil && !isNotFoundError(err) {
@@ -660,6 +671,10 @@ func (p *Provider) recordSet(ep *endpoint.Endpoint, getObject bool) (recordSet i
660671
if ep.RecordTTL.IsConfigured() {
661672
ttl = uint32(ep.RecordTTL)
662673
}
674+
extAttrs, err := deserializeEAs(p.config.ExtAttrsJSON)
675+
if err != nil {
676+
return
677+
}
663678
ptrToBoolTrue := true
664679
switch ep.RecordType {
665680
case endpoint.RecordTypeA:
@@ -668,6 +683,7 @@ func (p *Provider) recordSet(ep *endpoint.Endpoint, getObject bool) (recordSet i
668683
obj.Name = &ep.DNSName
669684
// TODO: get target index
670685
obj.Ipv4Addr = &ep.Targets[0]
686+
obj.Ea = extAttrs
671687
obj.Ttl = &ttl
672688
obj.UseTtl = &ptrToBoolTrue
673689
if getObject {
@@ -692,6 +708,7 @@ func (p *Provider) recordSet(ep *endpoint.Endpoint, getObject bool) (recordSet i
692708
obj.PtrdName = &ep.DNSName
693709
// TODO: get target index
694710
obj.Ipv4Addr = &ep.Targets[0]
711+
obj.Ea = extAttrs
695712
obj.Ttl = &ttl
696713
obj.UseTtl = &ptrToBoolTrue
697714
if getObject {
@@ -714,6 +731,7 @@ func (p *Provider) recordSet(ep *endpoint.Endpoint, getObject bool) (recordSet i
714731
obj := ibclient.NewEmptyRecordCNAME()
715732
obj.Name = &ep.DNSName
716733
obj.Canonical = &ep.Targets[0]
734+
obj.Ea = extAttrs
717735
obj.Ttl = &ttl
718736
obj.UseTtl = &ptrToBoolTrue
719737
if getObject {
@@ -741,6 +759,7 @@ func (p *Provider) recordSet(ep *endpoint.Endpoint, getObject bool) (recordSet i
741759
obj := ibclient.NewEmptyRecordTXT()
742760
obj.Text = &ep.Targets[0]
743761
obj.Name = &ep.DNSName
762+
obj.Ea = extAttrs
744763
obj.Ttl = &ttl
745764
obj.UseTtl = &ptrToBoolTrue
746765
// TODO: Zone?
@@ -784,3 +803,14 @@ func lookupEnvAtoi(key string, fallback int) (i int) {
784803
}
785804
return
786805
}
806+
807+
func deserializeEAs(extAttrJSON string) (map[string]interface{}, error) {
808+
extAttrs := make(map[string]interface{})
809+
if extAttrJSON == "" {
810+
return extAttrs, nil
811+
}
812+
if err := json.Unmarshal([]byte(extAttrJSON), &extAttrs); err != nil {
813+
return nil, fmt.Errorf("cannot process 'ext_attrs' field: %w", err)
814+
}
815+
return extAttrs, nil
816+
}

0 commit comments

Comments
 (0)