diff --git a/docs/data-sources/external_dns.md b/docs/data-sources/external_dns.md new file mode 100644 index 0000000..28a035d --- /dev/null +++ b/docs/data-sources/external_dns.md @@ -0,0 +1,49 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "dcloud_external_dns Data Source - terraform-provider-dcloud" +subcategory: "" +description: |- + All the dns records currently in a given topology +--- + +# dcloud_external_dns (Data Source) + +All the dns records currently in a given topology + + + +## Schema + +### Required + +- `topology_uid` (String) + +### Read-Only + +- `id` (String) The ID of this resource. +- `external_dns` (List of Object) (see [below for nested schema](#nestedatt--external_dns)) + + +### Nested Schema for `external_dns` + +Read-Only: + +- `uid` (String) +- `topology_uid` (String) +- `hostname` (String) +- `nat_rule_id` (String) +- `a_record` (String) +- `srv_records` (List of Object) (see [below for nested schema](#nestedobjatt--external_dns--srv_records)) + + + +### Nested Schema for `external_dns.srv_records` + +Read-Only: + +- `protocol` (String) +- `service` (String) +- `port` (Int) +- `uid` (String) + + diff --git a/docs/data-sources/inventory_dns_assets.md b/docs/data-sources/inventory_dns_assets.md new file mode 100644 index 0000000..811db1a --- /dev/null +++ b/docs/data-sources/inventory_dns_assets.md @@ -0,0 +1,35 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "dcloud_inventory_dns_assets Data Source - terraform-provider-dcloud" +subcategory: "" +description: |- + All the inventory dns assets available to be used in a topology +--- + +# dcloud_inventory_dns_assets (Data Source) + +All the inventory dns assets available to be used in a topology + + + + +## Schema + +### Required + +- `topology_uid` (String) + +### Read-Only + +- `id` (String) The ID of this resource. +- `inventory_dns_assets` (List of Object) (see [below for nested schema](#nestedatt--inventory_dns_assets)) + + +### Nested Schema for `inventory_dns_assets` + +Read-Only: + +- `id` (String) +- `name` (String) + + diff --git a/docs/data-sources/inventory_srv_protocols.md b/docs/data-sources/inventory_srv_protocols.md new file mode 100644 index 0000000..eed0acd --- /dev/null +++ b/docs/data-sources/inventory_srv_protocols.md @@ -0,0 +1,32 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "dcloud_inventory_srv_protocols Data Source - terraform-provider-dcloud" +subcategory: "" +description: |- + All the inventory srv protocols available to be used in a topology +--- + +# dcloud_inventory_srv_protocols (Data Source) + +All the inventory srv protocols available to be used in a topology + + + + +## Schema + + +### Read-Only + +- `id` (String) The ID of this resource. +- `inventory_srv_protocols` (List of Object) (see [below for nested schema](#nestedatt--inventory_srv_protocols)) + + +### Nested Schema for `inventory_srv_protocols` + +Read-Only: + +- `id` (String) +- `protocol` (String) + + diff --git a/docs/resources/external_dns.md b/docs/resources/external_dns.md new file mode 100644 index 0000000..43445a3 --- /dev/null +++ b/docs/resources/external_dns.md @@ -0,0 +1,38 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "dcloud_mail_server Resource - terraform-provider-dcloud" +subcategory: "" +description: |- + +--- + +# dcloud_mail_server (Resource) + + + +## Schema + +### Required + +- `nat_rule_id` (String) +- `hostname` (String) +- `topology_uid` (String) + +### Optional + +- `srv_records` (Block List, Min: 1) (see [below for nested schema](#nestedblock--srv_records)) + + +### Nested Schema for `srv_records` + +Required: + +- `protocol` (Boolean) +- `service` (String) +- `port` (Int) + +### Read-Only + +- `id` (String) The ID of this resource. +- `a_record` (String) +- `uid` (String) \ No newline at end of file diff --git a/examples/data-sources/external_dns_data_source/data-source.tf b/examples/data-sources/external_dns_data_source/data-source.tf new file mode 100644 index 0000000..e4a784d --- /dev/null +++ b/examples/data-sources/external_dns_data_source/data-source.tf @@ -0,0 +1,46 @@ +terraform { + required_providers { + dcloud = { + version = "0.1" + source = "cisco-open/dcloud" + } + } +} + +provider "dcloud" { + tb_url = "https://tbv3-production.ciscodcloud.com/api" +} + +resource "dcloud_topology" "test_topology" { + name = "Test Topology For Testing External DNS rules" + description = "Will be used to load External DNS Rules" + notes = "" + datacenter = "LON" +} + +resource "dcloud_ip_nat_rule" "test_topology_ip_nat_rule"{ + topology_uid = dcloud_topology.test_topology.id + target_ip_address = "192.168.1.1" + target_name = "Sample Device" + east_west = false +} + +resource "dcloud_external_dns" "test_topology_external_dns"{ + topology_uid = dcloud_topology.test_topology.id + nat_rule_id = dcloud_ip_nat_rule.test_topology_ip_nat_rule.id + hostname = "localhost" + srv_records{ + service = "_test" + protocol = "TCP" + port = 8081 + } +} + +data "dcloud_external_dns" "external_dns_test"{ + depends_on = [dcloud_external_dns.test_topology_external_dns] + topology_uid = dcloud_topology.test_topology.id +} + +output "external_dns" { + value = data.dcloud_external_dns.external_dns_test +} \ No newline at end of file diff --git a/examples/data-sources/inventory_dns_asset_data_source/data-source.tf b/examples/data-sources/inventory_dns_asset_data_source/data-source.tf new file mode 100644 index 0000000..0e07e2e --- /dev/null +++ b/examples/data-sources/inventory_dns_asset_data_source/data-source.tf @@ -0,0 +1,27 @@ +terraform { + required_providers { + dcloud = { + version = "0.1" + source = "cisco-open/dcloud" + } + } +} + +provider "dcloud" { + tb_url = "https://tbv3-production.ciscodcloud.com/api" +} + +resource "dcloud_topology" "test_topology" { + name = "Test Topology For Testing External DNS Assets" + description = "Will be used to load External DNS assets" + notes = "" + datacenter = "LON" +} + +data "dcloud_inventory_dns_assets" "test_dns_assets" { + topology_uid = dcloud_topology.test_topology.id +} + +output "dns_assets" { + value = data.dcloud_inventory_dns_assets.test_dns_assets +} \ No newline at end of file diff --git a/examples/data-sources/inventory_srv_protocol_data_source/data-source.tf b/examples/data-sources/inventory_srv_protocol_data_source/data-source.tf new file mode 100644 index 0000000..8ec62e7 --- /dev/null +++ b/examples/data-sources/inventory_srv_protocol_data_source/data-source.tf @@ -0,0 +1,19 @@ +terraform { + required_providers { + dcloud = { + version = "0.1" + source = "cisco-open/dcloud" + } + } +} + +provider "dcloud" { + tb_url = "https://tbv3-production.ciscodcloud.com/api" +} + +data "dcloud_inventory_srv_protocols" "test_srv_protocols" { +} + +output "srv_protocols" { + value = data.dcloud_inventory_srv_protocols.test_srv_protocols +} \ No newline at end of file diff --git a/examples/provider/provider.tf b/examples/provider/provider.tf index 48d4d8a..d87bc58 100644 --- a/examples/provider/provider.tf +++ b/examples/provider/provider.tf @@ -159,42 +159,6 @@ resource "dcloud_vm" "vm3" { } } -resource "dcloud_vm" "vm4" { - inventory_vm_id = "7668085" - topology_uid = dcloud_topology.test_topology.id - name = "Ubuntu Desktop 4" - description = "A standard Ubuntu Desktop VM" - cpu_qty = 1 - memory_mb = 1024 - - network_interfaces{ - network_uid = dcloud_network.unrouted_network.id - name = "Network adapter 1" - mac_address = "00:50:56:00:04:AA" - type = "VIRTUAL_E1000" - ip_address = "127.0.0.5" - ssh_enabled = true - rdp_enabled = true - rdp_auto_login = true - } - - advanced_settings { - all_disks_non_persistent = false - bios_uuid = "42 3a 5f 9d f1 a8 7c 0e-7d c2 44 27 2e d6 67 aa" - name_in_hypervisor = "ubuntu" - not_started = false - } - - remote_access { - vm_console_enabled = true - display_credentials { - username = "displayuser" - password = "displaypassword" - } - } -} - - resource "dcloud_hw" "hw1" { topology_uid = dcloud_topology.test_topology.id inventory_hw_id = "76" @@ -327,8 +291,19 @@ resource "dcloud_inbound_proxy_rule" "inbound_proxy_rule"{ show_hyperlink = true } +resource "dcloud_external_dns" "external_dns"{ + topology_uid = dcloud_topology.test_topology.id + nat_rule_id = dcloud_ip_nat_rule.ip_nat_rule.id + hostname = "localhost" + srv_records{ + service = "_test" + protocol = "TCP" + port = 8081 + } +} + resource "dcloud_mail_server" "mail_server"{ topology_uid = dcloud_topology.test_topology.id - nic_uid = dcloud_vm.vm4.network_interfaces[0].uid + nic_uid = dcloud_vm.vm3.network_interfaces[0].uid dns_asset_id = "3" -} \ No newline at end of file +} diff --git a/examples/resources/external_dns_resource/resource.tf b/examples/resources/external_dns_resource/resource.tf new file mode 100644 index 0000000..ce33141 --- /dev/null +++ b/examples/resources/external_dns_resource/resource.tf @@ -0,0 +1,79 @@ +terraform { + required_providers { + dcloud = { + version = "0.1" + source = "cisco-open/dcloud" + } + } +} + +provider "dcloud" { + tb_url = "https://tbv3-production.ciscodcloud.com/api" +} + +resource "dcloud_topology" "test_topology" { + name = "External DNS Resource Test" + description = "Testing Topology External DNS Resource Management" + notes = "Created via Terraform Test" + datacenter = "LON" +} + +resource "dcloud_network" "unrouted_network" { + name = "An unrouted network" + description = "Demonstrating a network not routed through VPOD Gateway" + inventory_network_id = "L2-VLAN-16" + topology_uid = dcloud_topology.test_topology.id +} + +resource "dcloud_vm" "vm1" { + inventory_vm_id = "7668085" + topology_uid = dcloud_topology.test_topology.id + name = "Ubuntu Desktop 1" + description = "A standard Ubuntu Desktop VM" + cpu_qty = 1 + memory_mb = 1024 + + network_interfaces{ + network_uid = dcloud_network.unrouted_network.id + name = "Network adapter 1" + mac_address = "00:50:56:00:03:AA" + type = "VIRTUAL_E1000" + ip_address = "127.0.0.2" + ssh_enabled = true + rdp_enabled = true + rdp_auto_login = true + } + + advanced_settings { + all_disks_non_persistent = false + bios_uuid = "42 3a 5f 9d f1 a8 7c 0e-7d c2 44 27 2e d6 67 aa" + name_in_hypervisor = "ubuntu" + not_started = false + } + + remote_access { + vm_console_enabled = true + display_credentials { + username = "displayuser" + password = "displaypassword" + } + } + +} + +resource "dcloud_vm_nat_rule" "test_vm_nat"{ + topology_uid = dcloud_topology.test_topology.id + nic_uid = dcloud_vm.vm1.network_interfaces[0].uid + east_west = true +} + +resource "dcloud_external_dns" "test_external_dns"{ + topology_uid = dcloud_topology.test_topology.id + nat_rule_id = dcloud_vm_nat_rule.test_vm_nat.id + hostname = "localhost" + srv_records{ + service = "_test" + protocol = "TCP" + port = 8081 + } +} \ No newline at end of file diff --git a/internal/dcloud/data_source_external_dns.go b/internal/dcloud/data_source_external_dns.go new file mode 100644 index 0000000..d8fc25a --- /dev/null +++ b/internal/dcloud/data_source_external_dns.go @@ -0,0 +1,130 @@ +package dcloud + +import ( + "context" + "github.com/cisco-open/dcloud-tb-go-client/tbclient" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "strconv" + "time" +) + +func dataSourceExternalDns() *schema.Resource { + return &schema.Resource{ + Description: "All the External DNS rules in a given topology", + + ReadContext: dataSourceExternalDnsRead, + + Schema: map[string]*schema.Schema{ + "topology_uid": { + Type: schema.TypeString, + Required: true, + }, + "external_dns": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "uid": { + Type: schema.TypeString, + Computed: true, + }, + "topology_uid": { + Type: schema.TypeString, + Computed: true, + }, + "hostname": { + Type: schema.TypeString, + Computed: true, + }, + "nat_rule_id": { + Type: schema.TypeString, + Computed: true, + }, + "a_record": { + Type: schema.TypeString, + Computed: true, + }, + "srv_records": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "uid": { + Type: schema.TypeString, + Computed: true, + }, + "service": { + Type: schema.TypeString, + Computed: true, + }, + "protocol": { + Type: schema.TypeString, + Computed: true, + }, + "port": { + Type: schema.TypeInt, + Computed: true, + }, + }, + }, + }, + }, + }, + }, + }, + } +} + +func dataSourceExternalDnsRead(ctx context.Context, d *schema.ResourceData, i interface{}) diag.Diagnostics { + tb := i.(*tbclient.Client) + + topologyUid := d.Get("topology_uid").(string) + externalDnsRecords, err := tb.GetAllExternalDnsRecords(topologyUid) + + if err != nil { + return diag.FromErr(err) + } + + externalDnsResources := make([]map[string]interface{}, len(externalDnsRecords)) + + for i, externalDnsRecord := range externalDnsRecords { + externalDnsResources[i] = convertExternalDnsDataResource(externalDnsRecord) + } + if err := d.Set("external_dns", externalDnsResources); err != nil { + return diag.FromErr(err) + } + d.SetId(strconv.FormatInt(time.Now().Unix(), 10)) + + return diag.Diagnostics{} + +} + +func convertExternalDnsDataResource(externalDns tbclient.ExternalDnsRecord) map[string]interface{} { + resource := make(map[string]interface{}) + resource["uid"] = externalDns.Uid + resource["topology_uid"] = externalDns.Topology.Uid + resource["hostname"] = externalDns.Hostname + resource["nat_rule_id"] = externalDns.NatRule.Uid + resource["a_record"] = externalDns.ARecord + if srvRecords := externalDns.SrvRecords; len(srvRecords) > 0 { + resource["srv_records"] = convertSrvRecords(externalDns) + } + + return resource +} + +func convertSrvRecords(externalDnsRecord tbclient.ExternalDnsRecord) []map[string]interface{} { + srvs := make([]map[string]interface{}, len(externalDnsRecord.SrvRecords)) + for i, srv := range externalDnsRecord.SrvRecords { + s := make(map[string]interface{}) + + s["uid"] = srv.Uid + s["service"] = srv.Service + s["protocol"] = srv.Protocol + s["port"] = srv.Port + + srvs[i] = s + } + return srvs +} diff --git a/internal/dcloud/data_source_inventory_dns_assets.go b/internal/dcloud/data_source_inventory_dns_assets.go new file mode 100644 index 0000000..befe613 --- /dev/null +++ b/internal/dcloud/data_source_inventory_dns_assets.go @@ -0,0 +1,73 @@ +package dcloud + +import ( + "context" + "github.com/cisco-open/dcloud-tb-go-client/tbclient" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "strconv" + "time" +) + +func dataSourceInventoryDnsAssets() *schema.Resource { + return &schema.Resource{ + Description: "All the Inventory DNS assets in a given topology", + + ReadContext: dataSourceInventoryDnsAssetsRead, + + Schema: map[string]*schema.Schema{ + "topology_uid": { + Type: schema.TypeString, + Required: true, + }, + "inventory_dns_assets": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + }, + } +} + +func dataSourceInventoryDnsAssetsRead(ctx context.Context, d *schema.ResourceData, i interface{}) diag.Diagnostics { + tb := i.(*tbclient.Client) + + topologyUid := d.Get("topology_uid").(string) + inventoryDnsAssets, err := tb.GetAllInventoryDnsAssets(topologyUid) + + if err != nil { + return diag.FromErr(err) + } + + inventoryDnsAssetsResources := make([]map[string]interface{}, len(inventoryDnsAssets)) + + for i, inventoryDnsAsset := range inventoryDnsAssets { + inventoryDnsAssetsResources[i] = convertInventoryDnsAssetResource(inventoryDnsAsset) + } + if err := d.Set("inventory_dns_assets", inventoryDnsAssetsResources); err != nil { + return diag.FromErr(err) + } + d.SetId(strconv.FormatInt(time.Now().Unix(), 10)) + + return diag.Diagnostics{} + +} + +func convertInventoryDnsAssetResource(inventoryDnsAsset tbclient.InventoryDnsAsset) map[string]interface{} { + resource := make(map[string]interface{}) + resource["id"] = inventoryDnsAsset.Id + resource["name"] = inventoryDnsAsset.Name + + return resource +} diff --git a/internal/dcloud/data_source_inventory_srv_protocols.go b/internal/dcloud/data_source_inventory_srv_protocols.go new file mode 100644 index 0000000..31b9a9b --- /dev/null +++ b/internal/dcloud/data_source_inventory_srv_protocols.go @@ -0,0 +1,68 @@ +package dcloud + +import ( + "context" + "github.com/cisco-open/dcloud-tb-go-client/tbclient" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "strconv" + "time" +) + +func dataSourceInventorySrvProtocols() *schema.Resource { + return &schema.Resource{ + Description: "All the Inventory SRV protocols in a given topology", + + ReadContext: dataSourceInventorySrvProtocolsRead, + + Schema: map[string]*schema.Schema{ + "inventory_srv_protocols": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + }, + "protocol": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + }, + } +} + +func dataSourceInventorySrvProtocolsRead(ctx context.Context, d *schema.ResourceData, i interface{}) diag.Diagnostics { + tb := i.(*tbclient.Client) + + inventorySrvProtocols, err := tb.GetAllInventorySrvProtocols() + + if err != nil { + return diag.FromErr(err) + } + + inventorySrvProtocolsResources := make([]map[string]interface{}, len(inventorySrvProtocols)) + + for i, inventorySrvProtocol := range inventorySrvProtocols { + inventorySrvProtocolsResources[i] = convertInventorySrvProtocolResource(inventorySrvProtocol) + } + if err := d.Set("inventory_srv_protocols", inventorySrvProtocolsResources); err != nil { + return diag.FromErr(err) + } + d.SetId(strconv.FormatInt(time.Now().Unix(), 10)) + + return diag.Diagnostics{} + +} + +func convertInventorySrvProtocolResource(inventorySrvProtocol tbclient.InventorySrvProtocol) map[string]interface{} { + resource := make(map[string]interface{}) + resource["id"] = inventorySrvProtocol.Id + resource["protocol"] = inventorySrvProtocol.Protocol + + return resource +} diff --git a/internal/dcloud/provider.go b/internal/dcloud/provider.go index 1736032..ed350fc 100644 --- a/internal/dcloud/provider.go +++ b/internal/dcloud/provider.go @@ -69,6 +69,9 @@ func Provider() *schema.Provider { "dcloud_vm_nat_rules": dataSourceVmNatRules(), "dcloud_inbound_proxy_rules": dataSourceInboundProxyRules(), "dcloud_mail_servers": dataSourceMailServers(), + "dcloud_external_dns": dataSourceExternalDns(), + "dcloud_inventory_dns_assets": dataSourceInventoryDnsAssets(), + "dcloud_inventory_srv_protocols": dataSourceInventorySrvProtocols(), }, ResourcesMap: map[string]*schema.Resource{ "dcloud_topology": resourceTopology(), @@ -87,6 +90,7 @@ func Provider() *schema.Provider { "dcloud_vm_nat_rule": resourceVmNat(), "dcloud_inbound_proxy_rule": resourceInboundProxy(), "dcloud_mail_server": resourceMailServer(), + "dcloud_external_dns": resourceExternalDns(), }, ConfigureContextFunc: providerConfigure, } diff --git a/internal/dcloud/resource_external_dns.go b/internal/dcloud/resource_external_dns.go new file mode 100644 index 0000000..7a690d1 --- /dev/null +++ b/internal/dcloud/resource_external_dns.go @@ -0,0 +1,148 @@ +package dcloud + +import ( + "context" + "github.com/cisco-open/dcloud-tb-go-client/tbclient" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func resourceExternalDns() *schema.Resource { + return &schema.Resource{ + CreateContext: resourceExternalDnsCreate, + ReadContext: resourceExternalDnsRead, + DeleteContext: resourceExternalDnsDelete, + Schema: map[string]*schema.Schema{ + "uid": { + Type: schema.TypeString, + Computed: true, + }, + "topology_uid": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "hostname": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "nat_rule_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "a_record": { + Type: schema.TypeString, + Computed: true, + }, + "srv_records": { + Type: schema.TypeList, + Optional: true, + ForceNew: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "uid": { + Type: schema.TypeString, + Computed: true, + }, + "service": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "protocol": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + "port": { + Type: schema.TypeInt, + Required: true, + ForceNew: true, + }, + }, + }, + }, + }, + } +} + +func resourceExternalDnsCreate(ctx context.Context, data *schema.ResourceData, i interface{}) diag.Diagnostics { + c := i.(*tbclient.Client) + + var diags diag.Diagnostics + + //TODO: Add dnsAsset info in the resource + + d, err := c.CreateExternalDnsRecord(extractExternalDns(data, ctx)) + if err != nil { + return diag.FromErr(err) + } + + data.SetId(d.Uid) + + resourceExternalDnsRead(ctx, data, i) + + return diags +} + +func resourceExternalDnsRead(ctx context.Context, data *schema.ResourceData, i interface{}) diag.Diagnostics { + c := i.(*tbclient.Client) + + var diags diag.Diagnostics + + externalDnsRecord, err := c.GetExternalDnsRecord(data.Id()) + if err != nil { + return handleClientError(err, data, diags) + } + + data.Set("uid", externalDnsRecord.Uid) + data.Set("topology_uid", externalDnsRecord.Topology.Uid) + data.Set("hostname", externalDnsRecord.Hostname) + data.Set("nat_rule_id", externalDnsRecord.NatRule.Uid) + data.Set("a_record", externalDnsRecord.ARecord) + if srvRecords := externalDnsRecord.SrvRecords; len(srvRecords) > 0 { + data.Set("srv_records", convertSrvRecords(*externalDnsRecord)) + } + + return diags +} + +func resourceExternalDnsDelete(ctx context.Context, data *schema.ResourceData, i interface{}) diag.Diagnostics { + c := i.(*tbclient.Client) + + if err := c.DeleteExternalDnsRecord(data.Id()); err != nil { + return diag.FromErr(err) + } + + return diag.Diagnostics{} +} + +func extractExternalDns(data *schema.ResourceData, ctx context.Context) tbclient.ExternalDnsRecord { + externalDnsRecord := tbclient.ExternalDnsRecord{ + Topology: &tbclient.Topology{ + Uid: data.Get("topology_uid").(string), + }, + NatRule: &tbclient.ExternalDnsNatRule{ + Uid: data.Get("nat_rule_id").(string), + }, + Hostname: data.Get("hostname").(string), + } + + if srvRecords := data.Get("srv_records").([]interface{}); srvRecords != nil && len(srvRecords) > 0 { + srvs := make([]tbclient.ExternalDnsSrvRecord, len(srvRecords)) + for i, srvRecord := range srvRecords { + srv := srvRecord.(map[string]interface{}) + s := tbclient.ExternalDnsSrvRecord{ + Service: srv["service"].(string), + Protocol: srv["protocol"].(string), + Port: srv["port"].(int), + } + srvs[i] = s + } + externalDnsRecord.SrvRecords = srvs + } + + return externalDnsRecord +}