From f1f1a84b7201ccc8c7ce799f5f617b08078526c3 Mon Sep 17 00:00:00 2001 From: Dan Petersen Date: Wed, 1 Jan 2020 04:42:34 +0100 Subject: [PATCH] Add dns data source and resource --- CHANGELOG.md | 5 + README.md | 20 +++ .../data_source_virtual_environment_dns.tf | 11 ++ example/resource_virtual_environment_dns.tf | 5 + proxmox/virtual_environment_dns.go | 32 ++++ proxmox/virtual_environment_dns_types.go | 26 +++ .../data_source_virtual_environment_dns.go | 83 +++++++++ ...ata_source_virtual_environment_dns_test.go | 43 +++++ proxmoxtf/provider.go | 2 + proxmoxtf/resource_virtual_environment_dns.go | 160 ++++++++++++++++++ .../resource_virtual_environment_dns_test.go | 41 +++++ .../resource_virtual_environment_group.go | 2 - .../resource_virtual_environment_pool.go | 2 - .../resource_virtual_environment_role.go | 2 - 14 files changed, 428 insertions(+), 6 deletions(-) create mode 100644 example/data_source_virtual_environment_dns.tf create mode 100644 example/resource_virtual_environment_dns.tf create mode 100644 proxmox/virtual_environment_dns.go create mode 100644 proxmox/virtual_environment_dns_types.go create mode 100644 proxmoxtf/data_source_virtual_environment_dns.go create mode 100644 proxmoxtf/data_source_virtual_environment_dns_test.go create mode 100644 proxmoxtf/resource_virtual_environment_dns.go create mode 100644 proxmoxtf/resource_virtual_environment_dns_test.go diff --git a/CHANGELOG.md b/CHANGELOG.md index f512214b..37f0ad1b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ ## 0.2.0 (UNRELEASED) +FEATURES: + +* **New Data Source:** `proxmox_virtual_environment_dns` +* **New Resource:** `proxmox_virtual_environment_dns` + ENHANCEMENTS: * resource/virtual_environment_vm: Add `acpi` argument diff --git a/README.md b/README.md index 2878933a..70f28bc6 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ A Terraform Provider which adds support for Proxmox solutions. - [Data Sources](#data-sources) - [Virtual Environment](#virtual-environment) - [Datastores](#datastores-proxmox_virtual_environment_datastores) + - [DNS](#group-proxmox_virtual_environment_dns) - [Group](#group-proxmox_virtual_environment_group) - [Groups](#groups-proxmox_virtual_environment_groups) - [Nodes](#nodes-proxmox_virtual_environment_nodes) @@ -112,6 +113,15 @@ You can omit `PROXMOX_VE_INSECURE`, if the Proxmox Virtual Environment API is ex * `space_used` - The used space in bytes * `types` - The storage types +##### DNS (proxmox_virtual_environment_dns) + +###### Arguments +* `node_name` - (Required) A node name + +###### Attributes +* `domain` - The DNS search domain +* `servers` - The DNS servers + ##### Group (proxmox_virtual_environment_group) ###### Arguments @@ -240,6 +250,16 @@ This data source doesn't accept arguments. #### Virtual Environment +##### DNS (proxmox_virtual_environment_dns) + +###### Arguments +* `domain` - (Required) The DNS search domain +* `node_name` - (Required) A node name +* `servers` - (Optional) The DNS servers + +###### Attributes +This resource doesn't expose any additional attributes. + ##### File (proxmox_virtual_environment_file) ###### Arguments diff --git a/example/data_source_virtual_environment_dns.tf b/example/data_source_virtual_environment_dns.tf new file mode 100644 index 00000000..120d47ca --- /dev/null +++ b/example/data_source_virtual_environment_dns.tf @@ -0,0 +1,11 @@ +data "proxmox_virtual_environment_dns" "example" { + node_name = "${data.proxmox_virtual_environment_nodes.example.names[0]}" +} + +output "data_proxmox_virtual_environment_dns_example_domain" { + value = "${data.proxmox_virtual_environment_dns.example.domain}" +} + +output "data_proxmox_virtual_environment_dns_example_servers" { + value = "${data.proxmox_virtual_environment_dns.example.servers}" +} diff --git a/example/resource_virtual_environment_dns.tf b/example/resource_virtual_environment_dns.tf new file mode 100644 index 00000000..83b3f4d5 --- /dev/null +++ b/example/resource_virtual_environment_dns.tf @@ -0,0 +1,5 @@ +resource "proxmox_virtual_environment_dns" "example" { + domain = "${data.proxmox_virtual_environment_dns.example.domain}" + node_name = "${data.proxmox_virtual_environment_nodes.example.names[0]}" + servers = "${data.proxmox_virtual_environment_dns.example.servers}" +} diff --git a/proxmox/virtual_environment_dns.go b/proxmox/virtual_environment_dns.go new file mode 100644 index 00000000..17e65b91 --- /dev/null +++ b/proxmox/virtual_environment_dns.go @@ -0,0 +1,32 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +package proxmox + +import ( + "errors" + "fmt" + "net/url" +) + +// GetDNS retrieves the DNS configuration for a node. +func (c *VirtualEnvironmentClient) GetDNS(nodeName string) (*VirtualEnvironmentDNSGetResponseData, error) { + resBody := &VirtualEnvironmentDNSGetResponseBody{} + err := c.DoRequest(hmGET, fmt.Sprintf("nodes/%s/dns", url.PathEscape(nodeName)), nil, resBody) + + if err != nil { + return nil, err + } + + if resBody.Data == nil { + return nil, errors.New("The server did not include a data object in the response") + } + + return resBody.Data, nil +} + +// UpdateDNS updates the DNS configuration for a node. +func (c *VirtualEnvironmentClient) UpdateDNS(nodeName string, d *VirtualEnvironmentDNSUpdateRequestBody) error { + return c.DoRequest(hmPUT, fmt.Sprintf("nodes/%s/dns", url.PathEscape(nodeName)), d, nil) +} diff --git a/proxmox/virtual_environment_dns_types.go b/proxmox/virtual_environment_dns_types.go new file mode 100644 index 00000000..9523f746 --- /dev/null +++ b/proxmox/virtual_environment_dns_types.go @@ -0,0 +1,26 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +package proxmox + +// VirtualEnvironmentDNSGetResponseBody contains the body from an pool get response. +type VirtualEnvironmentDNSGetResponseBody struct { + Data *VirtualEnvironmentDNSGetResponseData `json:"data,omitempty"` +} + +// VirtualEnvironmentDNSGetResponseData contains the data from an pool get response. +type VirtualEnvironmentDNSGetResponseData struct { + Server1 *string `json:"dns1,omitempty" url:"dns1,omitempty"` + Server2 *string `json:"dns2,omitempty" url:"dns2,omitempty"` + Server3 *string `json:"dns3,omitempty" url:"dns3,omitempty"` + SearchDomain *string `json:"search,omitempty" url:"search,omitempty"` +} + +// VirtualEnvironmentDNSUpdateRequestBody contains the data for an pool create request. +type VirtualEnvironmentDNSUpdateRequestBody struct { + Server1 *string `json:"dns1,omitempty" url:"dns1,omitempty"` + Server2 *string `json:"dns2,omitempty" url:"dns2,omitempty"` + Server3 *string `json:"dns3,omitempty" url:"dns3,omitempty"` + SearchDomain *string `json:"search,omitempty" url:"search,omitempty"` +} diff --git a/proxmoxtf/data_source_virtual_environment_dns.go b/proxmoxtf/data_source_virtual_environment_dns.go new file mode 100644 index 00000000..383a7830 --- /dev/null +++ b/proxmoxtf/data_source_virtual_environment_dns.go @@ -0,0 +1,83 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +package proxmoxtf + +import ( + "fmt" + + "github.com/hashicorp/terraform/helper/schema" +) + +const ( + mkDataSourceVirtualEnvironmentDNSDomain = "domain" + mkDataSourceVirtualEnvironmentDNSNodeName = "node_name" + mkDataSourceVirtualEnvironmentDNSServers = "servers" +) + +func dataSourceVirtualEnvironmentDNS() *schema.Resource { + return &schema.Resource{ + Schema: map[string]*schema.Schema{ + mkDataSourceVirtualEnvironmentDNSDomain: &schema.Schema{ + Type: schema.TypeString, + Description: "The DNS search domain", + Computed: true, + }, + mkDataSourceVirtualEnvironmentDNSNodeName: &schema.Schema{ + Type: schema.TypeString, + Description: "The node name", + Required: true, + }, + mkDataSourceVirtualEnvironmentDNSServers: &schema.Schema{ + Type: schema.TypeList, + Description: "The DNS servers", + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + Read: dataSourceVirtualEnvironmentDNSRead, + } +} + +func dataSourceVirtualEnvironmentDNSRead(d *schema.ResourceData, m interface{}) error { + config := m.(providerConfiguration) + veClient, err := config.GetVEClient() + + if err != nil { + return err + } + + nodeName := d.Get(mkDataSourceVirtualEnvironmentDNSNodeName).(string) + dns, err := veClient.GetDNS(nodeName) + + if err != nil { + return err + } + + d.SetId(fmt.Sprintf("%s_dns", nodeName)) + + if dns.SearchDomain != nil { + d.Set(mkDataSourceVirtualEnvironmentDNSDomain, *dns.SearchDomain) + } else { + d.Set(mkDataSourceVirtualEnvironmentDNSDomain, "") + } + + servers := []interface{}{} + + if dns.Server1 != nil { + servers = append(servers, *dns.Server1) + } + + if dns.Server2 != nil { + servers = append(servers, *dns.Server2) + } + + if dns.Server3 != nil { + servers = append(servers, *dns.Server3) + } + + d.Set(mkDataSourceVirtualEnvironmentDNSServers, servers) + + return nil +} diff --git a/proxmoxtf/data_source_virtual_environment_dns_test.go b/proxmoxtf/data_source_virtual_environment_dns_test.go new file mode 100644 index 00000000..9b6ea8ba --- /dev/null +++ b/proxmoxtf/data_source_virtual_environment_dns_test.go @@ -0,0 +1,43 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +package proxmoxtf + +import ( + "github.com/hashicorp/terraform/helper/schema" + "testing" +) + +// TestDataSourceVirtualEnvironmentDNSInstantiation tests whether the DataSourceVirtualEnvironmentDNS instance can be instantiated. +func TestDataSourceVirtualEnvironmentDNSInstantiation(t *testing.T) { + s := dataSourceVirtualEnvironmentDNS() + + if s == nil { + t.Fatalf("Cannot instantiate dataSourceVirtualEnvironmentDNS") + } +} + +// TestDataSourceVirtualEnvironmentDNSSchema tests the dataSourceVirtualEnvironmentDNS schema. +func TestDataSourceVirtualEnvironmentDNSSchema(t *testing.T) { + s := dataSourceVirtualEnvironmentDNS() + + testRequiredArguments(t, s, []string{ + mkDataSourceVirtualEnvironmentDNSNodeName, + }) + + testComputedAttributes(t, s, []string{ + mkDataSourceVirtualEnvironmentDNSDomain, + mkDataSourceVirtualEnvironmentDNSServers, + }) + + testSchemaValueTypes(t, s, []string{ + mkDataSourceVirtualEnvironmentDNSDomain, + mkDataSourceVirtualEnvironmentDNSNodeName, + mkDataSourceVirtualEnvironmentDNSServers, + }, []schema.ValueType{ + schema.TypeString, + schema.TypeString, + schema.TypeList, + }) +} diff --git a/proxmoxtf/provider.go b/proxmoxtf/provider.go index 85b657d8..35b397cf 100644 --- a/proxmoxtf/provider.go +++ b/proxmoxtf/provider.go @@ -31,6 +31,7 @@ func Provider() *schema.Provider { ConfigureFunc: providerConfigure, DataSourcesMap: map[string]*schema.Resource{ "proxmox_virtual_environment_datastores": dataSourceVirtualEnvironmentDatastores(), + "proxmox_virtual_environment_dns": dataSourceVirtualEnvironmentDNS(), "proxmox_virtual_environment_group": dataSourceVirtualEnvironmentGroup(), "proxmox_virtual_environment_groups": dataSourceVirtualEnvironmentGroups(), "proxmox_virtual_environment_nodes": dataSourceVirtualEnvironmentNodes(), @@ -43,6 +44,7 @@ func Provider() *schema.Provider { "proxmox_virtual_environment_version": dataSourceVirtualEnvironmentVersion(), }, ResourcesMap: map[string]*schema.Resource{ + "proxmox_virtual_environment_dns": resourceVirtualEnvironmentDNS(), "proxmox_virtual_environment_file": resourceVirtualEnvironmentFile(), "proxmox_virtual_environment_group": resourceVirtualEnvironmentGroup(), "proxmox_virtual_environment_pool": resourceVirtualEnvironmentPool(), diff --git a/proxmoxtf/resource_virtual_environment_dns.go b/proxmoxtf/resource_virtual_environment_dns.go new file mode 100644 index 00000000..0cacc136 --- /dev/null +++ b/proxmoxtf/resource_virtual_environment_dns.go @@ -0,0 +1,160 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +package proxmoxtf + +import ( + "fmt" + + "github.com/danitso/terraform-provider-proxmox/proxmox" + "github.com/hashicorp/terraform/helper/schema" +) + +const ( + mkResourceVirtualEnvironmentDNSDomain = "domain" + mkResourceVirtualEnvironmentDNSNodeName = "node_name" + mkResourceVirtualEnvironmentDNSServers = "servers" +) + +func resourceVirtualEnvironmentDNS() *schema.Resource { + return &schema.Resource{ + Schema: map[string]*schema.Schema{ + mkResourceVirtualEnvironmentDNSDomain: &schema.Schema{ + Type: schema.TypeString, + Description: "The DNS search domain", + Required: true, + }, + mkResourceVirtualEnvironmentDNSNodeName: &schema.Schema{ + Type: schema.TypeString, + Description: "The node name", + Required: true, + ForceNew: true, + }, + mkResourceVirtualEnvironmentDNSServers: &schema.Schema{ + Type: schema.TypeList, + Description: "The DNS servers", + Optional: true, + DefaultFunc: func() (interface{}, error) { + return []interface{}{}, nil + }, + Elem: &schema.Schema{Type: schema.TypeString}, + MinItems: 0, + MaxItems: 3, + }, + }, + Create: resourceVirtualEnvironmentDNSCreate, + Read: resourceVirtualEnvironmentDNSRead, + Update: resourceVirtualEnvironmentDNSUpdate, + Delete: resourceVirtualEnvironmentDNSDelete, + } +} + +func resourceVirtualEnvironmentDNSCreate(d *schema.ResourceData, m interface{}) error { + err := resourceVirtualEnvironmentDNSUpdate(d, m) + + if err != nil { + return err + } + + nodeName := d.Get(mkResourceVirtualEnvironmentDNSNodeName).(string) + + d.SetId(fmt.Sprintf("%s_dns", nodeName)) + + return nil +} + +func resourceVirtualEnvironmentDNSGetUpdateBody(d *schema.ResourceData, m interface{}) (*proxmox.VirtualEnvironmentDNSUpdateRequestBody, error) { + domain := d.Get(mkResourceVirtualEnvironmentDNSDomain).(string) + servers := d.Get(mkResourceVirtualEnvironmentDNSServers).([]interface{}) + + body := &proxmox.VirtualEnvironmentDNSUpdateRequestBody{ + SearchDomain: &domain, + } + + for i, server := range servers { + s := server.(string) + + switch i { + case 0: + body.Server1 = &s + case 1: + body.Server2 = &s + case 2: + body.Server3 = &s + } + } + + return body, nil +} + +func resourceVirtualEnvironmentDNSRead(d *schema.ResourceData, m interface{}) error { + config := m.(providerConfiguration) + veClient, err := config.GetVEClient() + + if err != nil { + return err + } + + nodeName := d.Get(mkResourceVirtualEnvironmentDNSNodeName).(string) + dns, err := veClient.GetDNS(nodeName) + + if err != nil { + return err + } + + if dns.SearchDomain != nil { + d.Set(mkResourceVirtualEnvironmentDNSDomain, *dns.SearchDomain) + } else { + d.Set(mkResourceVirtualEnvironmentDNSDomain, "") + } + + servers := []interface{}{} + + if dns.Server1 != nil { + servers = append(servers, *dns.Server1) + } + + if dns.Server2 != nil { + servers = append(servers, *dns.Server2) + } + + if dns.Server3 != nil { + servers = append(servers, *dns.Server3) + } + + d.Set(mkResourceVirtualEnvironmentDNSServers, servers) + + return nil +} + +func resourceVirtualEnvironmentDNSUpdate(d *schema.ResourceData, m interface{}) error { + config := m.(providerConfiguration) + veClient, err := config.GetVEClient() + + if err != nil { + return err + } + + nodeName := d.Get(mkResourceVirtualEnvironmentDNSNodeName).(string) + + body, err := resourceVirtualEnvironmentDNSGetUpdateBody(d, m) + + if err != nil { + return err + } + + err = veClient.UpdateDNS(nodeName, body) + + if err != nil { + return err + } + + return resourceVirtualEnvironmentDNSRead(d, m) +} + +func resourceVirtualEnvironmentDNSDelete(d *schema.ResourceData, m interface{}) error { + d.SetId("") + + return nil +} diff --git a/proxmoxtf/resource_virtual_environment_dns_test.go b/proxmoxtf/resource_virtual_environment_dns_test.go new file mode 100644 index 00000000..9b84bd1b --- /dev/null +++ b/proxmoxtf/resource_virtual_environment_dns_test.go @@ -0,0 +1,41 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +package proxmoxtf + +import ( + "testing" + + "github.com/hashicorp/terraform/helper/schema" +) + +// TestResourceVirtualEnvironmentDNSInstantiation tests whether the ResourceVirtualEnvironmentDNS instance can be instantiated. +func TestResourceVirtualEnvironmentDNSInstantiation(t *testing.T) { + s := resourceVirtualEnvironmentDNS() + + if s == nil { + t.Fatalf("Cannot instantiate resourceVirtualEnvironmentDNS") + } +} + +// TestResourceVirtualEnvironmentDNSSchema tests the resourceVirtualEnvironmentDNS schema. +func TestResourceVirtualEnvironmentDNSSchema(t *testing.T) { + s := resourceVirtualEnvironmentDNS() + + testRequiredArguments(t, s, []string{ + mkResourceVirtualEnvironmentDNSDomain, + mkResourceVirtualEnvironmentDNSNodeName, + mkResourceVirtualEnvironmentDNSServers, + }) + + testSchemaValueTypes(t, s, []string{ + mkResourceVirtualEnvironmentDNSDomain, + mkResourceVirtualEnvironmentDNSNodeName, + mkResourceVirtualEnvironmentDNSServers, + }, []schema.ValueType{ + schema.TypeString, + schema.TypeString, + schema.TypeList, + }) +} diff --git a/proxmoxtf/resource_virtual_environment_group.go b/proxmoxtf/resource_virtual_environment_group.go index 1e66e0af..4866cf45 100644 --- a/proxmoxtf/resource_virtual_environment_group.go +++ b/proxmoxtf/resource_virtual_environment_group.go @@ -156,8 +156,6 @@ func resourceVirtualEnvironmentGroupRead(d *schema.ResourceData, m interface{}) return err } - d.SetId(groupID) - aclParsed := []interface{}{} for _, v := range acl { diff --git a/proxmoxtf/resource_virtual_environment_pool.go b/proxmoxtf/resource_virtual_environment_pool.go index decb1512..133b4708 100644 --- a/proxmoxtf/resource_virtual_environment_pool.go +++ b/proxmoxtf/resource_virtual_environment_pool.go @@ -129,8 +129,6 @@ func resourceVirtualEnvironmentPoolRead(d *schema.ResourceData, m interface{}) e return err } - d.SetId(poolID) - if pool.Comment != nil { d.Set(mkResourceVirtualEnvironmentPoolComment, pool.Comment) } else { diff --git a/proxmoxtf/resource_virtual_environment_role.go b/proxmoxtf/resource_virtual_environment_role.go index e9b6eb24..308954a3 100644 --- a/proxmoxtf/resource_virtual_environment_role.go +++ b/proxmoxtf/resource_virtual_environment_role.go @@ -100,8 +100,6 @@ func resourceVirtualEnvironmentRoleRead(d *schema.ResourceData, m interface{}) e } } - d.SetId(roleID) - d.Set(mkResourceVirtualEnvironmentRolePrivileges, privileges) return nil