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

Add Authoritative Zone resource #238

Closed
wants to merge 4 commits into from
Closed
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
50 changes: 50 additions & 0 deletions docs/resources/infoblox_zone_auth.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Authoritative Zone Resource

The `infoblox_zone_auth` resource creates a DNS zone with SOA and NS records for the given FQDN.

## Parameter Reference

The following list describes the parameters you can define in the resource block for the zone:

* `fqdn`: required, specifies the fully qualified domain name for the DNS zone. Example: `prod123.example.com`
* `ns_group`: required, name of Nameserver Group in Infoblox; will create NS records
* `restart_if_needed`: optional, restart the member service if necessary for changes to take effect
* `comment`: required, description of this Authoritative Zone; max 256 characters
* `soa_default_ttl`: optional, Time To Live (TTL) of the SOA record, in seconds; default `3600`
* `soa_expire`: optional, time in seconds for secondary servers to stop answering about the zone because the data is stale; default `2419200` (1 week)
* `soa_negative_ttl`: optional, time in seconds for secondary servers to cache data for 'Does Not Respond' responses; default `900`
* `soa_refresh`: optional, interval in seconds for secondary servers to check the primary server for fresh data about the zone; default `10800`
* `soa_retry`: optional, interval in seconds for secondary servers to wait before recontacting primary server about the zone after failure; default `3600`
* `ext_attrs`: optional, a set of NIOS extensible attributes that are attached to the record, using jsonencode().

## Example Usage

```hcl
resource "infoblox_zone_auth" "prod123_zone" {
fqdn = "prod123.example.com"
ns_group = "Prod_NS_Group"
restart_if_needed = true
comment = "Managed by Terraform"
soa_default_ttl = 3600
soa_expire = 2419200
soa_negative_ttl = 900
soa_refresh = 10800
soa_retry = 3600
}
```

## Terraform Import

Authoritative Zone resources can be imported using the Zone Reference from the Infoblox NIOS API.

Example query to see the Zone Refs for an Infoblox instance. Find the Ref for your zone:

```
> curl -k -u $USER:$PASSWORD -X GET "https://infoblox-dns.example.com/wapi/v2.11/zone_auth?_return_as_object=1"
```

Then import into your Terraform state:

```
> terraform import infoblox_zone_auth.prod123_zone zone_auth/kZWZhdWx0LmlvLnZG5zLnpvbmUkLl9RrdG0udXxLnNhbmRib3gxMQ:prod123.example.com/default
```
1 change: 1 addition & 0 deletions infoblox/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ func Provider() *schema.Provider {
"infoblox_aaaa_record": resourceAAAARecord(),
"infoblox_cname_record": resourceCNAMERecord(),
"infoblox_ptr_record": resourcePTRRecord(),
"infoblox_zone_auth": resourceZoneAuth(),
},
DataSourcesMap: map[string]*schema.Resource{
"infoblox_ipv4_network": dataSourceIPv4Network(),
Expand Down
232 changes: 232 additions & 0 deletions infoblox/resource_infoblox_zone_auth.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
package infoblox

import (
"encoding/json"
"fmt"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
ibclient "github.com/infobloxopen/infoblox-go-client/v2"
)

func resourceZoneAuth() *schema.Resource {
return &schema.Resource{
Create: resourceZoneAuthCreate,
Read: resourceZoneAuthGet,
Update: resourceZoneAuthUpdate,
Delete: resourceZoneAuthDelete,
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
Schema: map[string]*schema.Schema{
"dns_view": {
Type: schema.TypeString,
Optional: true,
Default: "default",
Description: "Dns View under which the zone has been created",
},
"fqdn": {
Type: schema.TypeString,
Required: true,
Description: "The FQDN of the Authoritative zone",
},
"ns_group": {
Type: schema.TypeString,
Required: true,
Description: "Name of Nameserver Group in Infoblox; will create NS records",
},
"restart_if_needed": {
Type: schema.TypeBool,
Optional: true,
Computed: true,
Description: "Restart the member service if necessary for changes to take effect",
},
"comment": {
Type: schema.TypeString,
Required: true,
Description: "Description of this Authoritative Zone; max 256 characters",
},
"soa_default_ttl": {
Type: schema.TypeInt,
Default: 3600,
Optional: true,
Description: "Time To Live (TTL) of the SOA record, in seconds",
},
"soa_expire": {
Type: schema.TypeInt,
Default: 2419200,
Optional: true,
Description: "Time in seconds for secondary servers to stop answering about the zone because the data is stale (default 1 week)",
},
"soa_negative_ttl": {
Type: schema.TypeInt,
Default: 900,
Optional: true,
Description: "Time in seconds for secondary servers to cache data for 'Does Not Respond' responses",
},
"soa_refresh": {
Type: schema.TypeInt,
Default: 10800,
Optional: true,
Description: "Interval in seconds for secondary servers to check the primary server for fresh data about the zone",
},
"soa_retry": {
Type: schema.TypeInt,
Default: 3600,
Optional: true,
Description: "Interval in seconds for secondary servers to wait before recontacting primary server about the zone after failure",
},
"zone_format": {
Type: schema.TypeString,
Optional: true,
Default: "FORWARD",
Description: "Format of the zone: FORWARD, IPV4, IPV6",
},
"ext_attrs": {
Type: schema.TypeString,
Default: "",
Optional: true,
Description: "Extensible attributes, as a map in JSON format",
},
},
bsmithtm marked this conversation as resolved.
Show resolved Hide resolved
}
}

// CRUD FUNCTIONS

func resourceZoneAuthCreate(d *schema.ResourceData, m interface{}) error {
dnsview := d.Get("dns_view").(string)
fqdn := d.Get("fqdn").(string)
nsGroup := d.Get("ns_group").(string)
restartIfNeeded := d.Get("restart_if_needed").(bool)
comment := d.Get("comment").(string)
soaDefaultTtl := d.Get("soa_default_ttl").(int)
soaExpire := d.Get("soa_expire").(int)
soaNegativeTtl := d.Get("soa_negative_ttl").(int)
soaRefresh := d.Get("soa_refresh").(int)
soaRetry := d.Get("soa_retry").(int)
zoneFormat := d.Get("zone_format").(string)

extAttrJSON := d.Get("ext_attrs").(string)
extAttrs := make(map[string]interface{})
if extAttrJSON != "" {
if err := json.Unmarshal([]byte(extAttrJSON), &extAttrs); err != nil {
return fmt.Errorf("cannot process 'ext_attrs' field: %s", err.Error())
}
}

var tenantID string
tempVal, found := extAttrs["Tenant ID"]
if found {
tenantID = tempVal.(string)
}
connector := m.(ibclient.IBConnector)
objMgr := ibclient.NewObjectManager(connector, "Terraform", tenantID)

newZone, err := objMgr.CreateZoneAuth(
dnsview, fqdn, nsGroup, restartIfNeeded, comment,
soaDefaultTtl, soaExpire, soaNegativeTtl, soaRefresh, soaRetry, zoneFormat, extAttrs)
if err != nil {
return fmt.Errorf("error creating Zone Auth: %s", err.Error())
}

d.SetId(newZone.Ref)

return nil
}

func resourceZoneAuthGet(d *schema.ResourceData, m interface{}) error {
extAttrJSON := d.Get("ext_attrs").(string)
extAttrs := make(map[string]interface{})
if extAttrJSON != "" {
if err := json.Unmarshal([]byte(extAttrJSON), &extAttrs); err != nil {
return fmt.Errorf("cannot process 'ext_attrs' field: %s", err.Error())
}
}

var tenantID string
tempVal, found := extAttrs["Tenant ID"]
if found {
tenantID = tempVal.(string)
}
connector := m.(ibclient.IBConnector)
objMgr := ibclient.NewObjectManager(connector, "Terraform", tenantID)

obj, err := objMgr.GetZoneAuthByRef(d.Id())
if err != nil {
return fmt.Errorf("getting Zone Auth failed: %s", err.Error())
}

d.Set("fqdn", obj.Fqdn)
d.Set("comment", obj.Comment)
d.SetId(obj.Ref)

return nil
}

func resourceZoneAuthUpdate(d *schema.ResourceData, m interface{}) error {
dnsview := d.Get("dns_view").(string)
// fqdn := d.Get("fqdn").(string) CANNOT BE UPDATED IN WAPI
nsGroup := d.Get("ns_group").(string)
restartIfNeeded := d.Get("restart_if_needed").(bool)
comment := d.Get("comment").(string)
soaDefaultTtl := d.Get("soa_default_ttl").(int)
soaExpire := d.Get("soa_expire").(int)
soaNegativeTtl := d.Get("soa_negative_ttl").(int)
soaRefresh := d.Get("soa_refresh").(int)
soaRetry := d.Get("soa_retry").(int)
// zoneFormat := d.Get("zone_format").(string) CANNOT BE UPDATED IN WAPI

extAttrJSON := d.Get("ext_attrs").(string)
extAttrs := make(map[string]interface{})
if extAttrJSON != "" {
if err := json.Unmarshal([]byte(extAttrJSON), &extAttrs); err != nil {
return fmt.Errorf("cannot process 'ext_attrs' field: %s", err.Error())
}
}

var tenantID string
tempVal, found := extAttrs["Tenant ID"]
if found {
tenantID = tempVal.(string)
}
connector := m.(ibclient.IBConnector)
objMgr := ibclient.NewObjectManager(connector, "Terraform", tenantID)

updatedZone, err := objMgr.UpdateZoneAuth(
d.Id(), dnsview, nsGroup, restartIfNeeded, comment,
soaDefaultTtl, soaExpire, soaNegativeTtl, soaRefresh, soaRetry, extAttrs)
if err != nil {
return fmt.Errorf("error creating Zone Auth: %s", err.Error())
}

d.SetId(updatedZone.Ref)

return nil
bsmithtm marked this conversation as resolved.
Show resolved Hide resolved
}

func resourceZoneAuthDelete(d *schema.ResourceData, m interface{}) error {
dnsview := d.Get("dns_view").(string)
extAttrJSON := d.Get("ext_attrs").(string)
extAttrs := make(map[string]interface{})
if extAttrJSON != "" {
if err := json.Unmarshal([]byte(extAttrJSON), &extAttrs); err != nil {
return fmt.Errorf("cannot process 'ext_attrs' field: %s", err.Error())
}
}

var tenantID string
tempVal, found := extAttrs["Tenant ID"]
if found {
tenantID = tempVal.(string)
}
connector := m.(ibclient.IBConnector)
objMgr := ibclient.NewObjectManager(connector, "Terraform", tenantID)

_, err := objMgr.DeleteZoneAuth(d.Id())
if err != nil {
return fmt.Errorf("deletion of Zone Auth from dns view %s failed: %s", dnsview, err.Error())
}
d.SetId("")

return nil
}