mirror of
https://github.com/bpg/terraform-provider-proxmox.git
synced 2025-07-03 12:02:57 +00:00
Add hosts resource
This commit is contained in:
parent
9ac2a3eba9
commit
0e4647f0ee
@ -6,6 +6,7 @@ FEATURES:
|
|||||||
* **New Data Source:** `proxmox_virtual_environment_hosts`
|
* **New Data Source:** `proxmox_virtual_environment_hosts`
|
||||||
* **New Resource:** `proxmox_virtual_environment_certificate`
|
* **New Resource:** `proxmox_virtual_environment_certificate`
|
||||||
* **New Resource:** `proxmox_virtual_environment_dns`
|
* **New Resource:** `proxmox_virtual_environment_dns`
|
||||||
|
* **New Resource:** `proxmox_virtual_environment_hosts`
|
||||||
|
|
||||||
ENHANCEMENTS:
|
ENHANCEMENTS:
|
||||||
|
|
||||||
|
17
README.md
17
README.md
@ -34,6 +34,7 @@ A Terraform Provider which adds support for Proxmox solutions.
|
|||||||
- [DNS](#dns-proxmox_virtual_environment_dns-1)
|
- [DNS](#dns-proxmox_virtual_environment_dns-1)
|
||||||
- [File](#file-proxmox_virtual_environment_file)
|
- [File](#file-proxmox_virtual_environment_file)
|
||||||
- [Group](#group-proxmox_virtual_environment_group-1)
|
- [Group](#group-proxmox_virtual_environment_group-1)
|
||||||
|
- [Hosts](#hosts-proxmox_virtual_environment_hosts-1)
|
||||||
- [Pool](#pool-proxmox_virtual_environment_pool-1)
|
- [Pool](#pool-proxmox_virtual_environment_pool-1)
|
||||||
- [Role](#role-proxmox_virtual_environment_role-1)
|
- [Role](#role-proxmox_virtual_environment_role-1)
|
||||||
- [User](#user-proxmox_virtual_environment_user-1)
|
- [User](#user-proxmox_virtual_environment_user-1)
|
||||||
@ -155,7 +156,7 @@ This data source doesn't accept arguments.
|
|||||||
###### Attributes
|
###### Attributes
|
||||||
* `addresses` - The IP addresses
|
* `addresses` - The IP addresses
|
||||||
* `digest` - The SHA1 digest
|
* `digest` - The SHA1 digest
|
||||||
* `entries` - The entries (conversion of `addresses` and `hostnames` into objects)
|
* `entries` - The host entries (conversion of `addresses` and `hostnames` into objects)
|
||||||
* `hostnames` - The hostnames associated with each of the IP addresses
|
* `hostnames` - The hostnames associated with each of the IP addresses
|
||||||
|
|
||||||
##### Nodes (proxmox_virtual_environment_nodes)
|
##### Nodes (proxmox_virtual_environment_nodes)
|
||||||
@ -341,6 +342,20 @@ You must ensure that you have at least `Size-in-MB * 2 + 1` MB of storage space
|
|||||||
###### Attributes
|
###### Attributes
|
||||||
* `members` - The group members as a list with `username@realm` entries
|
* `members` - The group members as a list with `username@realm` entries
|
||||||
|
|
||||||
|
##### Hosts (proxmox_virtual_environment_hosts)
|
||||||
|
|
||||||
|
###### Arguments
|
||||||
|
* `node_name` - (Required) A node name
|
||||||
|
* `entry` - (Required) A host entry (multiple blocks supported)
|
||||||
|
* `address` - (Required) The IP address
|
||||||
|
* `hostnames` - (Required) The hostnames
|
||||||
|
|
||||||
|
###### Attributes
|
||||||
|
* `addresses` - The IP addresses
|
||||||
|
* `digest` - The SHA1 digest
|
||||||
|
* `entries` - The host entries (conversion of `addresses` and `hostnames` into objects)
|
||||||
|
* `hostnames` - The hostnames associated with each of the IP addresses
|
||||||
|
|
||||||
##### Pool (proxmox_virtual_environment_pool)
|
##### Pool (proxmox_virtual_environment_pool)
|
||||||
|
|
||||||
###### Arguments
|
###### Arguments
|
||||||
|
28
example/resource_virtual_environment_hosts.tf
Normal file
28
example/resource_virtual_environment_hosts.tf
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
resource "proxmox_virtual_environment_hosts" "example" {
|
||||||
|
node_name = "${data.proxmox_virtual_environment_nodes.example.names[0]}"
|
||||||
|
|
||||||
|
dynamic "entry" {
|
||||||
|
for_each = "${data.proxmox_virtual_environment_hosts.example.entries}"
|
||||||
|
|
||||||
|
content {
|
||||||
|
address = "${entry.value.address}"
|
||||||
|
hostnames = "${entry.value.hostnames}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
output "resource_proxmox_virtual_environment_hosts_example_addresses" {
|
||||||
|
value = "${proxmox_virtual_environment_hosts.example.addresses}"
|
||||||
|
}
|
||||||
|
|
||||||
|
output "resource_proxmox_virtual_environment_hosts_example_digest" {
|
||||||
|
value = "${proxmox_virtual_environment_hosts.example.digest}"
|
||||||
|
}
|
||||||
|
|
||||||
|
output "resource_proxmox_virtual_environment_hosts_example_entries" {
|
||||||
|
value = "${proxmox_virtual_environment_hosts.example.entries}"
|
||||||
|
}
|
||||||
|
|
||||||
|
output "resource_proxmox_virtual_environment_hosts_example_hostnames" {
|
||||||
|
value = "${proxmox_virtual_environment_hosts.example.hostnames}"
|
||||||
|
}
|
@ -37,7 +37,7 @@ func dataSourceVirtualEnvironmentHosts() *schema.Resource {
|
|||||||
},
|
},
|
||||||
mkDataSourceVirtualEnvironmentHostsEntries: &schema.Schema{
|
mkDataSourceVirtualEnvironmentHostsEntries: &schema.Schema{
|
||||||
Type: schema.TypeList,
|
Type: schema.TypeList,
|
||||||
Description: "The entries",
|
Description: "The host entries",
|
||||||
Computed: true,
|
Computed: true,
|
||||||
Elem: &schema.Resource{
|
Elem: &schema.Resource{
|
||||||
Schema: map[string]*schema.Schema{
|
Schema: map[string]*schema.Schema{
|
||||||
|
@ -49,6 +49,7 @@ func Provider() *schema.Provider {
|
|||||||
"proxmox_virtual_environment_dns": resourceVirtualEnvironmentDNS(),
|
"proxmox_virtual_environment_dns": resourceVirtualEnvironmentDNS(),
|
||||||
"proxmox_virtual_environment_file": resourceVirtualEnvironmentFile(),
|
"proxmox_virtual_environment_file": resourceVirtualEnvironmentFile(),
|
||||||
"proxmox_virtual_environment_group": resourceVirtualEnvironmentGroup(),
|
"proxmox_virtual_environment_group": resourceVirtualEnvironmentGroup(),
|
||||||
|
"proxmox_virtual_environment_hosts": resourceVirtualEnvironmentHosts(),
|
||||||
"proxmox_virtual_environment_pool": resourceVirtualEnvironmentPool(),
|
"proxmox_virtual_environment_pool": resourceVirtualEnvironmentPool(),
|
||||||
"proxmox_virtual_environment_role": resourceVirtualEnvironmentRole(),
|
"proxmox_virtual_environment_role": resourceVirtualEnvironmentRole(),
|
||||||
"proxmox_virtual_environment_user": resourceVirtualEnvironmentUser(),
|
"proxmox_virtual_environment_user": resourceVirtualEnvironmentUser(),
|
||||||
|
229
proxmoxtf/resource_virtual_environment_hosts.go
Normal file
229
proxmoxtf/resource_virtual_environment_hosts.go
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
/* 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"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/danitso/terraform-provider-proxmox/proxmox"
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
mkResourceVirtualEnvironmentHostsAddresses = "addresses"
|
||||||
|
mkResourceVirtualEnvironmentHostsDigest = "digest"
|
||||||
|
mkResourceVirtualEnvironmentHostsEntries = "entries"
|
||||||
|
mkResourceVirtualEnvironmentHostsEntriesAddress = "address"
|
||||||
|
mkResourceVirtualEnvironmentHostsEntriesHostnames = "hostnames"
|
||||||
|
mkResourceVirtualEnvironmentHostsEntry = "entry"
|
||||||
|
mkResourceVirtualEnvironmentHostsEntryAddress = "address"
|
||||||
|
mkResourceVirtualEnvironmentHostsEntryHostnames = "hostnames"
|
||||||
|
mkResourceVirtualEnvironmentHostsHostnames = "hostnames"
|
||||||
|
mkResourceVirtualEnvironmentHostsNodeName = "node_name"
|
||||||
|
)
|
||||||
|
|
||||||
|
func resourceVirtualEnvironmentHosts() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
mkResourceVirtualEnvironmentHostsAddresses: &schema.Schema{
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Description: "The addresses",
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||||||
|
},
|
||||||
|
mkResourceVirtualEnvironmentHostsDigest: &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Description: "The SHA1 digest",
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
mkResourceVirtualEnvironmentHostsEntries: &schema.Schema{
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Description: "The host entries",
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
mkResourceVirtualEnvironmentHostsEntriesAddress: {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Description: "The address",
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
mkResourceVirtualEnvironmentHostsEntriesHostnames: &schema.Schema{
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Description: "The hostnames",
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mkResourceVirtualEnvironmentHostsEntry: &schema.Schema{
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Description: "The host entries",
|
||||||
|
Required: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
mkResourceVirtualEnvironmentHostsEntryAddress: {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Description: "The address",
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
mkResourceVirtualEnvironmentHostsEntryHostnames: &schema.Schema{
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Description: "The hostnames",
|
||||||
|
Required: true,
|
||||||
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||||||
|
MinItems: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mkResourceVirtualEnvironmentHostsHostnames: &schema.Schema{
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Description: "The hostnames",
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Schema{
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mkResourceVirtualEnvironmentHostsNodeName: &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Description: "The node name",
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Create: resourceVirtualEnvironmentHostsCreate,
|
||||||
|
Read: resourceVirtualEnvironmentHostsRead,
|
||||||
|
Update: resourceVirtualEnvironmentHostsUpdate,
|
||||||
|
Delete: resourceVirtualEnvironmentHostsDelete,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceVirtualEnvironmentHostsCreate(d *schema.ResourceData, m interface{}) error {
|
||||||
|
err := resourceVirtualEnvironmentHostsUpdate(d, m)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeName := d.Get(mkResourceVirtualEnvironmentHostsNodeName).(string)
|
||||||
|
|
||||||
|
d.SetId(fmt.Sprintf("%s_hosts", nodeName))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceVirtualEnvironmentHostsRead(d *schema.ResourceData, m interface{}) error {
|
||||||
|
config := m.(providerConfiguration)
|
||||||
|
veClient, err := config.GetVEClient()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeName := d.Get(mkResourceVirtualEnvironmentHostsNodeName).(string)
|
||||||
|
hosts, err := veClient.GetHosts(nodeName)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the entries in the hosts file.
|
||||||
|
addresses := []interface{}{}
|
||||||
|
entries := []interface{}{}
|
||||||
|
hostnames := []interface{}{}
|
||||||
|
lines := strings.Split(hosts.Data, "\n")
|
||||||
|
|
||||||
|
for _, line := range lines {
|
||||||
|
if strings.HasPrefix(line, "#") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
line = strings.ReplaceAll(line, "\t", " ")
|
||||||
|
values := strings.Split(line, " ")
|
||||||
|
|
||||||
|
if values[0] == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
addresses = append(addresses, values[0])
|
||||||
|
entry := map[string]interface{}{}
|
||||||
|
hostnamesForAddress := []interface{}{}
|
||||||
|
|
||||||
|
for _, hostname := range values[1:] {
|
||||||
|
if hostname != "" {
|
||||||
|
hostnamesForAddress = append(hostnamesForAddress, hostname)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
entry[mkResourceVirtualEnvironmentHostsEntriesAddress] = values[0]
|
||||||
|
entry[mkResourceVirtualEnvironmentHostsEntriesHostnames] = hostnamesForAddress
|
||||||
|
|
||||||
|
entries = append(entries, entry)
|
||||||
|
hostnames = append(hostnames, hostnamesForAddress)
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Set(mkResourceVirtualEnvironmentHostsAddresses, addresses)
|
||||||
|
|
||||||
|
if hosts.Digest != nil {
|
||||||
|
d.Set(mkResourceVirtualEnvironmentHostsDigest, *hosts.Digest)
|
||||||
|
} else {
|
||||||
|
d.Set(mkResourceVirtualEnvironmentHostsDigest, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
d.Set(mkResourceVirtualEnvironmentHostsEntries, entries)
|
||||||
|
d.Set(mkResourceVirtualEnvironmentHostsEntry, entries)
|
||||||
|
d.Set(mkResourceVirtualEnvironmentHostsHostnames, hostnames)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceVirtualEnvironmentHostsUpdate(d *schema.ResourceData, m interface{}) error {
|
||||||
|
config := m.(providerConfiguration)
|
||||||
|
veClient, err := config.GetVEClient()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
entry := d.Get(mkResourceVirtualEnvironmentHostsEntry).([]interface{})
|
||||||
|
nodeName := d.Get(mkResourceVirtualEnvironmentHostsNodeName).(string)
|
||||||
|
|
||||||
|
// Generate the data for the hosts file based on the specified entries.
|
||||||
|
body := proxmox.VirtualEnvironmentHostsUpdateRequestBody{
|
||||||
|
Data: "",
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, e := range entry {
|
||||||
|
eMap := e.(map[string]interface{})
|
||||||
|
|
||||||
|
address := eMap[mkResourceVirtualEnvironmentHostsEntryAddress].(string)
|
||||||
|
hostnames := eMap[mkResourceVirtualEnvironmentHostsEntryHostnames].([]interface{})
|
||||||
|
|
||||||
|
body.Data += address
|
||||||
|
|
||||||
|
for _, h := range hostnames {
|
||||||
|
hostname := h.(string)
|
||||||
|
body.Data += " " + hostname
|
||||||
|
}
|
||||||
|
|
||||||
|
body.Data += "\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
err = veClient.UpdateHosts(nodeName, &body)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return resourceVirtualEnvironmentHostsRead(d, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
func resourceVirtualEnvironmentHostsDelete(d *schema.ResourceData, m interface{}) error {
|
||||||
|
d.SetId("")
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
83
proxmoxtf/resource_virtual_environment_hosts_test.go
Normal file
83
proxmoxtf/resource_virtual_environment_hosts_test.go
Normal file
@ -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 (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TestResourceVirtualEnvironmentHostsInstantiation tests whether the ResourceVirtualEnvironmentHosts instance can be instantiated.
|
||||||
|
func TestResourceVirtualEnvironmentHostsInstantiation(t *testing.T) {
|
||||||
|
s := resourceVirtualEnvironmentHosts()
|
||||||
|
|
||||||
|
if s == nil {
|
||||||
|
t.Fatalf("Cannot instantiate resourceVirtualEnvironmentHosts")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestResourceVirtualEnvironmentHostsSchema tests the resourceVirtualEnvironmentHosts schema.
|
||||||
|
func TestResourceVirtualEnvironmentHostsSchema(t *testing.T) {
|
||||||
|
s := resourceVirtualEnvironmentHosts()
|
||||||
|
|
||||||
|
testRequiredArguments(t, s, []string{
|
||||||
|
mkResourceVirtualEnvironmentHostsEntry,
|
||||||
|
mkResourceVirtualEnvironmentHostsNodeName,
|
||||||
|
})
|
||||||
|
|
||||||
|
testComputedAttributes(t, s, []string{
|
||||||
|
mkResourceVirtualEnvironmentHostsAddresses,
|
||||||
|
mkResourceVirtualEnvironmentHostsDigest,
|
||||||
|
mkResourceVirtualEnvironmentHostsEntries,
|
||||||
|
mkResourceVirtualEnvironmentHostsHostnames,
|
||||||
|
})
|
||||||
|
|
||||||
|
testSchemaValueTypes(t, s, []string{
|
||||||
|
mkResourceVirtualEnvironmentHostsAddresses,
|
||||||
|
mkResourceVirtualEnvironmentHostsDigest,
|
||||||
|
mkResourceVirtualEnvironmentHostsEntries,
|
||||||
|
mkResourceVirtualEnvironmentHostsEntry,
|
||||||
|
mkResourceVirtualEnvironmentHostsHostnames,
|
||||||
|
mkResourceVirtualEnvironmentHostsNodeName,
|
||||||
|
}, []schema.ValueType{
|
||||||
|
schema.TypeList,
|
||||||
|
schema.TypeString,
|
||||||
|
schema.TypeList,
|
||||||
|
schema.TypeList,
|
||||||
|
schema.TypeList,
|
||||||
|
schema.TypeString,
|
||||||
|
})
|
||||||
|
|
||||||
|
entriesSchema := testNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentHostsEntries)
|
||||||
|
|
||||||
|
testComputedAttributes(t, entriesSchema, []string{
|
||||||
|
mkResourceVirtualEnvironmentHostsEntriesAddress,
|
||||||
|
mkResourceVirtualEnvironmentHostsEntriesHostnames,
|
||||||
|
})
|
||||||
|
|
||||||
|
testSchemaValueTypes(t, entriesSchema, []string{
|
||||||
|
mkResourceVirtualEnvironmentHostsEntriesAddress,
|
||||||
|
mkResourceVirtualEnvironmentHostsEntriesHostnames,
|
||||||
|
}, []schema.ValueType{
|
||||||
|
schema.TypeString,
|
||||||
|
schema.TypeList,
|
||||||
|
})
|
||||||
|
|
||||||
|
entrySchema := testNestedSchemaExistence(t, s, mkResourceVirtualEnvironmentHostsEntry)
|
||||||
|
|
||||||
|
testRequiredArguments(t, entrySchema, []string{
|
||||||
|
mkResourceVirtualEnvironmentHostsEntryAddress,
|
||||||
|
mkResourceVirtualEnvironmentHostsEntryHostnames,
|
||||||
|
})
|
||||||
|
|
||||||
|
testSchemaValueTypes(t, entrySchema, []string{
|
||||||
|
mkResourceVirtualEnvironmentHostsEntryAddress,
|
||||||
|
mkResourceVirtualEnvironmentHostsEntryHostnames,
|
||||||
|
}, []schema.ValueType{
|
||||||
|
schema.TypeString,
|
||||||
|
schema.TypeList,
|
||||||
|
})
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user