Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding ability to query Infoblox API using regex for fqdn (#2102) #2110

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions docs/tutorials/infoblox.md
Original file line number Diff line number Diff line change
Expand Up @@ -260,3 +260,11 @@ $ curl -kl \
-u ${WAPI_USERNAME}:${WAPI_PASSWORD} \
https://${GRID_HOST}:${WAPI_PORT}/wapi/v${WAPI_VERSION}/zone_auth?fqdn=example.com
```

## Ability to filter results from the zone auth API using a regular expression

There is also the ability to filter results from the Infoblox zone_auth service based upon a regular expression. See the [Infoblox API document](https://www.infoblox.com/wp-content/uploads/infoblox-deployment-infoblox-rest-api.pdf) for examples. To use this feature for the zone_auth service, set the parameter infoblox-fqdn-regex for external-dns to a regular expression that makes sense for you. For instance, to only return hosted zones that start with staging in the test.com domain (like staging.beta.test.com, or staging.test.com), use the following command line option when starting external-dns

```
--infoblox-fqdn-regex=^staging.*test.com$
```
1 change: 1 addition & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ func main() {
View: cfg.InfobloxView,
MaxResults: cfg.InfobloxMaxResults,
DryRun: cfg.DryRun,
FQDNRexEx: cfg.InfobloxFQDNRegEx,
},
)
case "dyn":
Expand Down
3 changes: 3 additions & 0 deletions pkg/apis/externaldns/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ type Config struct {
InfobloxSSLVerify bool
InfobloxView string
InfobloxMaxResults int
InfobloxFQDNRegEx string
DynCustomerName string
DynUsername string
DynPassword string `secure:"yes"`
Expand Down Expand Up @@ -228,6 +229,7 @@ var defaultConfig = &Config{
InfobloxSSLVerify: true,
InfobloxView: "",
InfobloxMaxResults: 0,
InfobloxFQDNRegEx: "",
OCIConfigFile: "/etc/kubernetes/oci.yaml",
InMemoryZones: []string{},
OVHEndpoint: "ovh-eu",
Expand Down Expand Up @@ -410,6 +412,7 @@ func (cfg *Config) ParseFlags(args []string) error {
app.Flag("infoblox-ssl-verify", "When using the Infoblox provider, specify whether to verify the SSL certificate (default: true, disable with --no-infoblox-ssl-verify)").Default(strconv.FormatBool(defaultConfig.InfobloxSSLVerify)).BoolVar(&cfg.InfobloxSSLVerify)
app.Flag("infoblox-view", "DNS view (default: \"\")").Default(defaultConfig.InfobloxView).StringVar(&cfg.InfobloxView)
app.Flag("infoblox-max-results", "Add _max_results as query parameter to the URL on all API requests. The default is 0 which means _max_results is not set and the default of the server is used.").Default(strconv.Itoa(defaultConfig.InfobloxMaxResults)).IntVar(&cfg.InfobloxMaxResults)
app.Flag("infoblox-fqdn-regex", "Apply this regular expression as a filter for obtaining zone_auth objects. This is disabled by default.").Default(defaultConfig.InfobloxFQDNRegEx).StringVar(&cfg.InfobloxFQDNRegEx)
app.Flag("dyn-customer-name", "When using the Dyn provider, specify the Customer Name").Default("").StringVar(&cfg.DynCustomerName)
app.Flag("dyn-username", "When using the Dyn provider, specify the Username").Default("").StringVar(&cfg.DynUsername)
app.Flag("dyn-password", "When using the Dyn provider, specify the password").Default("").StringVar(&cfg.DynPassword)
Expand Down
31 changes: 21 additions & 10 deletions provider/infoblox/infoblox.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ type InfobloxConfig struct {
DryRun bool
View string
MaxResults int
FQDNRexEx string
}

// InfobloxProvider implements the DNS provider for Infoblox.
Expand All @@ -56,35 +57,44 @@ type InfobloxProvider struct {
zoneIDFilter provider.ZoneIDFilter
view string
dryRun bool
fqdnRegEx string
}

type infobloxRecordSet struct {
obj ibclient.IBObject
res interface{}
}

// MaxResultsRequestBuilder implements a HttpRequestBuilder which sets the
// _max_results query parameter on all get requests
type MaxResultsRequestBuilder struct {
// ExtendedRequestBuilder implements a HttpRequestBuilder which sets
// additional query parameter on all get requests
type ExtendedRequestBuilder struct {
fqdnRegEx string
maxResults int
ibclient.WapiRequestBuilder
}

// NewMaxResultsRequestBuilder returns a MaxResultsRequestBuilder which adds
// NewExtendedRequestBuilder returns a ExtendedRequestBuilder which adds
// _max_results query parameter to all GET requests
func NewMaxResultsRequestBuilder(maxResults int) *MaxResultsRequestBuilder {
return &MaxResultsRequestBuilder{
func NewExtendedRequestBuilder(maxResults int, fqdnRegEx string) *ExtendedRequestBuilder {
return &ExtendedRequestBuilder{
fqdnRegEx: fqdnRegEx,
maxResults: maxResults,
}
}

// BuildRequest prepares the api request. it uses BuildRequest of
// WapiRequestBuilder and then add the _max_requests parameter
func (mrb *MaxResultsRequestBuilder) BuildRequest(t ibclient.RequestType, obj ibclient.IBObject, ref string, queryParams ibclient.QueryParams) (req *http.Request, err error) {
func (mrb *ExtendedRequestBuilder) BuildRequest(t ibclient.RequestType, obj ibclient.IBObject, ref string, queryParams ibclient.QueryParams) (req *http.Request, err error) {
req, err = mrb.WapiRequestBuilder.BuildRequest(t, obj, ref, queryParams)
if req.Method == "GET" {
query := req.URL.Query()
query.Set("_max_results", strconv.Itoa(mrb.maxResults))
if mrb.maxResults > 0 {
query.Set("_max_results", strconv.Itoa(mrb.maxResults))
}
_, ok := obj.(*ibclient.ZoneAuth)
if ok && t == ibclient.GET && mrb.fqdnRegEx != "" {
query.Set("fqdn~", mrb.fqdnRegEx)
}
req.URL.RawQuery = query.Encode()
}
return
Expand All @@ -110,9 +120,9 @@ func NewInfobloxProvider(infobloxConfig InfobloxConfig) (*InfobloxProvider, erro
)

var requestBuilder ibclient.HttpRequestBuilder
if infobloxConfig.MaxResults != 0 {
if infobloxConfig.MaxResults != 0 || infobloxConfig.FQDNRexEx != "" {
// use our own HttpRequestBuilder which sets _max_results parameter on GET requests
requestBuilder = NewMaxResultsRequestBuilder(infobloxConfig.MaxResults)
requestBuilder = NewExtendedRequestBuilder(infobloxConfig.MaxResults, infobloxConfig.FQDNRexEx)
} else {
// use the default HttpRequestBuilder of the infoblox client
requestBuilder = &ibclient.WapiRequestBuilder{}
Expand All @@ -132,6 +142,7 @@ func NewInfobloxProvider(infobloxConfig InfobloxConfig) (*InfobloxProvider, erro
zoneIDFilter: infobloxConfig.ZoneIDFilter,
dryRun: infobloxConfig.DryRun,
view: infobloxConfig.View,
fqdnRegEx: infobloxConfig.FQDNRexEx,
}

return provider, nil
Expand Down
26 changes: 24 additions & 2 deletions provider/infoblox/infoblox_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,7 @@ func TestInfobloxZones(t *testing.T) {
assert.Equal(t, provider.findZone(zones, "lvl2-2.lvl1-2.example.com").Fqdn, "example.com")
}

func TestMaxResultsRequestBuilder(t *testing.T) {
func TestExtendedRequestFDQDRegExBuilder(t *testing.T) {
hostConfig := ibclient.HostConfig{
Host: "localhost",
Port: "8080",
Expand All @@ -542,7 +542,29 @@ func TestMaxResultsRequestBuilder(t *testing.T) {
Version: "2.3.1",
}

requestBuilder := NewMaxResultsRequestBuilder(54321)
requestBuilder := NewExtendedRequestBuilder(0, "^staging.*test.com$")
requestBuilder.Init(hostConfig)

obj := ibclient.NewZoneAuth(ibclient.ZoneAuth{})

req, _ := requestBuilder.BuildRequest(ibclient.GET, obj, "", ibclient.QueryParams{})

assert.True(t, req.URL.Query().Get("fqdn~") == "^staging.*test.com$")

req, _ = requestBuilder.BuildRequest(ibclient.CREATE, obj, "", ibclient.QueryParams{})

assert.True(t, req.URL.Query().Get("fqdn~") == "")
}
func TestExtendedRequestMaxResultsBuilder(t *testing.T) {
hostConfig := ibclient.HostConfig{
Host: "localhost",
Port: "8080",
Username: "user",
Password: "abcd",
Version: "2.3.1",
}

requestBuilder := NewExtendedRequestBuilder(54321, "")
requestBuilder.Init(hostConfig)

obj := ibclient.NewRecordCNAME(ibclient.RecordCNAME{Zone: "foo.bar.com"})
Expand Down