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 support for alias object resource and data source and testscases #475

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
99 changes: 99 additions & 0 deletions docs/data-sources/infoblox_alias_record.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Alias-record Data Source

Use the `infoblox_alias_record` data resource for the Alias record to retrieve the following information for a Alias record:

* `name`: the alias name of the record in the FQDN format. Example: `foo1.test.com`
* `view`: the DNS view which the record's zone belongs to. Example: `nondefault_dnsview`
* `target_name`: the name of the target in FQDN format. Example: `aa.test.com`
* `target_type`: the type of the target object. Valid values are: `A`, `AAAA`, `MX`, `NAPTR`, `PTR`, `SPF`, `SRV` and `TXT`.
* `zone`: the name of the zone in which the record exists. Example: `test.com`.
* `ttl`: the "time to live" value of the record, in seconds. Example: `3600`.
* `dns_name`: the name for an Alias record in punycode format. Example: `foo1.test.com`.
* `dns_target_name`: the DNS target name of the Alias Record in punycode format. Example: `aa.test.com`.
* `disable`: the flag to disable the record. Valid values are `true` and `false`.
* `comment`: the text describing the record. This is a regular comment. Example: `Temporary Alias-record`.
* `creator`: the creator of the record. Valid value is `STATIC`.
* `ext_attrs`: the set of extensible attributes of the record, if any. The content is formatted as string of JSON map. Example: `"{\"Site\":\"Greece\"}"`

For usage of filters, add the fields as keys and appropriate values to be passed to the keys like `name`, `view`, `zone`, `comment`, `target_name`, and `target_type` corresponding to object.
From the below list of supported arguments for filters, use only the searchable fields for retrieving the matching records.

### Supported Arguments for filters

-----
| Field | Alias | Type | Searchable |
|-------------|-------------|--------|------------|
| name | name | string | yes |
| view | dns_view | string | yes |
| target_name | target_name | string | yes |
| target_type | target_type | uint | yes |
| comment | comment | string | yes |
| zone | zone | string | yes |

!> Any of the combination from searchable fields in supported arguments list for fields are allowed.

!> Please consider using only fields as the keys in terraform datasource filters, kindly don't use alias names as keys from the above table.

### Example for using the filters:
```hcl
data "infoblox_alias_record" "alias_read" {
filters = {
name = "foo1.test.com"
comment = "Temporary Alias-record"
}
}
```

!> From the above example, if the 'view' alias 'dns_view' value is not specified, if same record exists in one or more different DNS views, those
all records will be fetched in results.

!> If `null` or empty filters are passed, then all the records or objects associated with datasource like here `infoblox_alias_record`, will be fetched in results.

### Example of the Alias-record Data Source Block

This example defines a data source of type `infoblox_alias_record` and the name "alias_read", which is configured in a Terraform file.
You can reference this resource and retrieve information about it.

```hcl
resource "infoblox_alias_record" "alias_record" {
name = "alias-record.test.com"
target_name = "hh.ll.com"
target_type = "NAPTR"
comment = "example alias record"
view = "default"
disable = true
ttl = 1200
ext_attrs = jsonencode({
"Site" = "Ireland"
})
}

data "infoblox_alias_record" "alias_read"{
filters = {
name = infoblox_alias_record.alias_record.name
target_name = infoblox_alias_record.alias_record.target_name
view = infoblox_alias_record.alias_record.view
}
}

output "alias_record_out" {
value = data.infoblox_alias_record.alias_read
}

// accessing individual field in results
output "alias_target_type_out" {
value = data.infoblox_alias_record.alias_read.results.0.target_type //zero represents index of json object from results list
}

// accessing Alias-Record through EA's
data "infoblox_alias_record" "alias_read_ea" {
filters = {
"*Site" = "Ireland"
}
}

// throws matching Alias records with EA, if any
output "alias_read_ea_out" {
value = data.infoblox_alias_record.alias_read_ea
}
```
40 changes: 40 additions & 0 deletions docs/resources/infoblox_alias_record.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Alias-record Resource

The `infoblox_dtc_alias` resource enables you to perform `create`, `update` and `delete` operations on Alias Record in a NIOS appliance.
The resource represents the ‘record:alias’ WAPI object in NIOS.

The following list describes the parameters you can define in the `infoblox_alias_record` resource block:

* `name`: required, specifies the alias name in the FQDN format. Example: `alias1.example.com`.
* `target_name`: required, specifies the target name in the FQDN format. Example: `main.example.com`.
* `target_type`: required, specifies the type of the target object. Valid values are: `A`, `AAAA`, `MX`, `NAPTR`, `PTR`, `SPF`, `SRV` and `TXT`.
* `ttl`: optional, specifies the "time to live" value for the alias-record. There is no default value for this parameter. If a value is not specified, then in NIOS, the value is inherited from the parent zone of the DNS record for this resource. A TTL value of 0 (zero) means caching should be disabled for this record. Example: `3600`.
* `disable`: optional, specifies whether the alias record is disabled or not. Default value is `false`.
* `view`: required, specifies the DNS view in which the zone exists. If a value is not specified, the name `default` is set as the DNS view. Example: `dns_view_1`.
* `comment`: optional, describes the alias-record. Example: `an example alias-record`.
* `ext_attrs`: optional, specifies the set of NIOS extensible attributes that are attached to the alias-record. Example: `jsonencode({})`.

### Example of an Alias-record Resource

```hcl
// Alias-record, minimal set of parameters
resource "infoblox_alias_record" "alias_record_minimum_params" {
name = "alias-record1.test.com"
target_name = "aa.bb.com"
target_type = "PTR"
}

// Alias-record, full set of parameters
resource "infoblox_alias_record" "alias_record_full_params" {
name = "alias-record2.test.com"
target_name = "kk.ll.com"
target_type = "AAAA"
comment = "example alias record"
view = "default.view2"
disable = false
ttl = 120
ext_attrs = jsonencode({
"Site" = "MOROCCO"
})
}
```
41 changes: 41 additions & 0 deletions examples/datasources/infoblox_alias_record.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// creating an alias record resource
resource "infoblox_alias_record" "alias_record" {
name = "alias-record.test.com"
target_name = "hh.ll.com"
target_type = "NAPTR"
comment = "example alias record"
view = "default"
disable = true
ttl = 1200
ext_attrs = jsonencode({
"Site" = "Ireland"
})
}

// accessing alias record by specifying name and comment
data "infoblox_alias_record" "alias_read" {
filters = {
name = infoblox_alias_record.alias_record.name
comment = infoblox_alias_record.alias_record.comment
}
}

// returns matching alias record with name and comment, if any
output "alias_record_res" {
value = data.infoblox_alias_record.alias_read
}

// accessing alias record by specifying view, zone, target_name and target_type
data "infoblox_alias_record" "alias_read1" {
filters = {
view = "default"
zone = "test.com"
target_name = "hh.ll.com"
target_type = "NAPTR"
}
}

// returns matching alias record with view, zone, target_name and target_type, if any
output "alias_record_res1" {
value = data.infoblox_alias_record.alias_read1
}
21 changes: 21 additions & 0 deletions examples/resources/infoblox_alias_record.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// creating an alias record with minimum set of parameters
resource "infoblox_alias_record" "alias_record_minimum_params" {
name = "alias-record1.test.com"
target_name = "aa.bb.com"
target_type = "PTR"
}

// creating an alias record with full set of parameters
resource "infoblox_alias_record" "alias_record_full_params" {
name = "alias-record2.test.com"
target_name = "kk.ll.com"
target_type = "AAAA"
comment = "example alias record"
view = "default.view2"
disable = false
ttl = 120
ext_attrs = jsonencode({
"Site" = "MOROCCO"
})
}

182 changes: 182 additions & 0 deletions infoblox/datasource_infoblox_alias_record.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
package infoblox

import (
"context"
"encoding/json"
"fmt"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
ibclient "github.com/infobloxopen/infoblox-go-client/v2"
"strconv"
"time"
)

func dataSourceAliasRecord() *schema.Resource {
return &schema.Resource{
ReadContext: datasourceAliasRecordRead,
Schema: map[string]*schema.Schema{
"filters": {
Type: schema.TypeMap,
Required: true,
},
"results": {
Type: schema.TypeList,
Computed: true,
Description: "List of Alias records matching filters",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeString,
Computed: true,
},
"name": {
Type: schema.TypeString,
Computed: true,
Description: "Name of the alias record.",
},
"comment": {
Type: schema.TypeString,
Computed: true,
Description: "Comment for the alias record.",
},
"disable": {
Type: schema.TypeBool,
Computed: true,
Description: "A boolean flag which indicates if the alias record is disabled.",
},
"target_name": {
Type: schema.TypeString,
Computed: true,
Description: "Target name in FQDN format.",
},
"target_type": {
Type: schema.TypeString,
Computed: true,
Description: "Type of the target object.",
},
"view": {
Type: schema.TypeString,
Computed: true,
Description: "Name of the DNS view in which the alias record is created.",
},
"ttl": {
Type: schema.TypeInt,
Computed: true,
Description: "The Time To Live (TTL) value for record. A 32-bit unsigned integer that represents the duration, " +
"in seconds, for which the record is valid (cached). Zero indicates that the record should not be cached.",
},
"ext_attrs": {
Type: schema.TypeString,
Computed: true,
Description: "Extensible attributes of the Alias Record to be added/updated, as a map in JSON format",
},
"creator": {
Type: schema.TypeString,
Computed: true,
Description: "Creator of the Alias Record. Valid value is STATIC",
},
"dns_name": {
Type: schema.TypeString,
Computed: true,
Description: "The name for an Alias record in punycode format.",
},
"dns_target_name": {
Type: schema.TypeString,
Computed: true,
Description: "DNS target name of the Alias Record in punycode format.",
},
"zone": {
Type: schema.TypeString,
Computed: true,
Description: "The name of the zone in which the record resides. Example: “zone.com”.",
},
},
},
},
},
}
}

func datasourceAliasRecordRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
connector := m.(ibclient.IBConnector)

var diags diag.Diagnostics

filters := filterFromMap(d.Get("filters").(map[string]interface{}))

objMgr := ibclient.NewObjectManager(connector, "Terraform", "")

qp := ibclient.NewQueryParams(false, filters)
res, err := objMgr.GetAllAliasRecord(qp)

Check failure on line 110 in infoblox/datasource_infoblox_alias_record.go

View workflow job for this annotation

GitHub Actions / Test (ubuntu-latest, 1.21)

objMgr.GetAllAliasRecord undefined (type ibclient.IBObjectManager has no field or method GetAllAliasRecord)

Check failure on line 110 in infoblox/datasource_infoblox_alias_record.go

View workflow job for this annotation

GitHub Actions / Test (macOS-latest, 1.21)

objMgr.GetAllAliasRecord undefined (type ibclient.IBObjectManager has no field or method GetAllAliasRecord)
if err != nil {
return diag.FromErr(fmt.Errorf("failed to get alias records: %w", err))
}

if res == nil {
return diag.FromErr(fmt.Errorf("API returns a nil/empty ID for alias record"))
}
// TODO: temporary scaffold, need to rework marshalling/unmarshalling of EAs
// (avoiding additional layer of keys ("value" key)
results := make([]interface{}, 0, len(res))
for _, r := range res {
aliasRecord, err := flattenAliasRecord(r)
if err != nil {
return diag.FromErr(fmt.Errorf("failed to flatten alias record : %w", err))
}
results = append(results, aliasRecord)
}

err = d.Set("results", results)
if err != nil {
return diag.FromErr(err)
}

// always run
d.SetId(strconv.FormatInt(time.Now().Unix(), 10))
return diags
}

func flattenAliasRecord(aliasRecord ibclient.RecordAlias) (interface{}, error) {
var eaMap map[string]interface{}
if aliasRecord.Ea != nil && len(aliasRecord.Ea) > 0 {
eaMap = aliasRecord.Ea
} else {
eaMap = make(map[string]interface{})
}

ea, err := json.Marshal(eaMap)
if err != nil {
return nil, err
}

res := map[string]interface{}{
"id": aliasRecord.Ref,
"name": aliasRecord.Name,
"ext_attrs": string(ea),
"target_name": aliasRecord.TargetName,
"target_type": aliasRecord.TargetType,
"view": *aliasRecord.View,
"dns_name": aliasRecord.DnsName,
"dns_target_name": aliasRecord.DnsTargetName,
"creator": aliasRecord.Creator,
"zone": aliasRecord.Zone,
}
if aliasRecord.Comment != nil {
res["comment"] = *aliasRecord.Comment
}
if aliasRecord.Disable != nil {
res["disable"] = *aliasRecord.Disable
}
if aliasRecord.UseTtl != nil {
if !*aliasRecord.UseTtl {
res["ttl"] = ttlUndef
}
}
if aliasRecord.Ttl != nil && *aliasRecord.Ttl > 0 {
res["ttl"] = *aliasRecord.Ttl
} else {
res["ttl"] = ttlUndef
}

return res, nil
}
Loading
Loading