From 20beccc76e694a30778466b73c6c690c6409b78e Mon Sep 17 00:00:00 2001 From: Dan Petersen Date: Wed, 11 Dec 2019 01:32:12 +0100 Subject: [PATCH] Added nodes data source --- CHANGELOG.md | 1 + README.md | 16 ++ data_source_virtual_environment_nodes.go | 176 ++++++++++++++++++ data_source_virtual_environment_nodes_test.go | 45 +++++ .../data_source_virtual_environment_nodes.tf | 37 ++++ example/resource_virtual_environment_pool.tf | 2 +- provider.go | 1 + proxmox/virtual_environment_nodes.go | 48 +++++ 8 files changed, 325 insertions(+), 1 deletion(-) create mode 100644 data_source_virtual_environment_nodes.go create mode 100644 data_source_virtual_environment_nodes_test.go create mode 100644 example/data_source_virtual_environment_nodes.tf create mode 100644 proxmox/virtual_environment_nodes.go diff --git a/CHANGELOG.md b/CHANGELOG.md index e6187831..e3210dd7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ FEATURES: * **New Data Source:** `proxmox_virtual_environment_group` * **New Data Source:** `proxmox_virtual_environment_groups` +* **New Data Source:** `proxmox_virtual_environment_nodes` * **New Data Source:** `proxmox_virtual_environment_pool` * **New Data Source:** `proxmox_virtual_environment_pools` * **New Data Source:** `proxmox_virtual_environment_role` diff --git a/README.md b/README.md index 38217564..da1b508e 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,22 @@ This data source doesn't accept arguments. * `comments` - The group comments * `group_ids` - The group ids +##### Nodes (proxmox_virtual_environment_nodes) + +###### Arguments +This data source doesn't accept arguments. + +###### Attributes +* `cpu_count` - The CPU count for each node +* `cpu_utilization` - The CPU utilization on each node +* `memory_available` - The memory available on each node +* `memory_used` - The memory used on each node +* `names` - The node names +* `online` - Whether a node is online +* `ssl_fingerprints` - The SSL fingerprint for each node +* `support_level` - The support level for each node +* `uptime` - The uptime in seconds for each node + ##### Pool (proxmox_virtual_environment_pool) ###### Arguments diff --git a/data_source_virtual_environment_nodes.go b/data_source_virtual_environment_nodes.go new file mode 100644 index 00000000..d49dcd7a --- /dev/null +++ b/data_source_virtual_environment_nodes.go @@ -0,0 +1,176 @@ +/* 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 main + +import ( + "math" + + "github.com/hashicorp/terraform/helper/schema" +) + +const ( + mkDataSourceVirtualEnvironmentNodesCPUCount = "cpu_count" + mkDataSourceVirtualEnvironmentNodesCPUUtilization = "cpu_utilization" + mkDataSourceVirtualEnvironmentNodesMemoryAvailable = "memory_available" + mkDataSourceVirtualEnvironmentNodesMemoryUsed = "memory_used" + mkDataSourceVirtualEnvironmentNodesNames = "names" + mkDataSourceVirtualEnvironmentNodesOnline = "online" + mkDataSourceVirtualEnvironmentNodesSSLFingerprints = "ssl_fingerprints" + mkDataSourceVirtualEnvironmentNodesSupportLevels = "support_levels" + mkDataSourceVirtualEnvironmentNodesUptime = "uptime" +) + +func dataSourceVirtualEnvironmentNodes() *schema.Resource { + return &schema.Resource{ + Schema: map[string]*schema.Schema{ + mkDataSourceVirtualEnvironmentNodesCPUCount: &schema.Schema{ + Type: schema.TypeList, + Description: "The CPU count for each node", + Computed: true, + Elem: &schema.Schema{Type: schema.TypeInt}, + }, + mkDataSourceVirtualEnvironmentNodesCPUUtilization: &schema.Schema{ + Type: schema.TypeList, + Description: "The CPU utilization on each node", + Computed: true, + Elem: &schema.Schema{Type: schema.TypeFloat}, + }, + mkDataSourceVirtualEnvironmentNodesMemoryAvailable: &schema.Schema{ + Type: schema.TypeList, + Description: "The available memory in bytes on each node", + Computed: true, + Elem: &schema.Schema{Type: schema.TypeInt}, + }, + mkDataSourceVirtualEnvironmentNodesMemoryUsed: &schema.Schema{ + Type: schema.TypeList, + Description: "The used memory in bytes on each node", + Computed: true, + Elem: &schema.Schema{Type: schema.TypeInt}, + }, + mkDataSourceVirtualEnvironmentNodesNames: &schema.Schema{ + Type: schema.TypeList, + Description: "The node names", + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + mkDataSourceVirtualEnvironmentNodesOnline: &schema.Schema{ + Type: schema.TypeList, + Description: "Whether a node is online", + Computed: true, + Elem: &schema.Schema{Type: schema.TypeBool}, + }, + mkDataSourceVirtualEnvironmentNodesSSLFingerprints: &schema.Schema{ + Type: schema.TypeList, + Description: "The SSL fingerprint for each node", + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + mkDataSourceVirtualEnvironmentNodesSupportLevels: &schema.Schema{ + Type: schema.TypeList, + Description: "The support level for each node", + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + mkDataSourceVirtualEnvironmentNodesUptime: &schema.Schema{ + Type: schema.TypeList, + Description: "The uptime in seconds for each node", + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + Read: dataSourceVirtualEnvironmentNodesRead, + } +} + +func dataSourceVirtualEnvironmentNodesRead(d *schema.ResourceData, m interface{}) error { + config := m.(providerConfiguration) + veClient, err := config.GetVEClient() + + if err != nil { + return err + } + + list, err := veClient.ListNodes() + + if err != nil { + return err + } + + cpuCount := make([]interface{}, len(list)) + cpuUtilization := make([]interface{}, len(list)) + memoryAvailable := make([]interface{}, len(list)) + memoryUsed := make([]interface{}, len(list)) + name := make([]interface{}, len(list)) + online := make([]interface{}, len(list)) + sslFingerprints := make([]interface{}, len(list)) + supportLevels := make([]interface{}, len(list)) + uptime := make([]interface{}, len(list)) + + for i, v := range list { + if v.CPUCount != nil { + cpuCount[i] = v.CPUCount + } else { + cpuCount[i] = 0 + } + + if v.CPUUtilization != nil { + cpuUtilization[i] = math.Round(*v.CPUUtilization*100) / 100 + } else { + cpuUtilization[i] = 0 + } + + if v.MemoryAvailable != nil { + memoryAvailable[i] = v.MemoryAvailable + } else { + memoryAvailable[i] = 0 + } + + if v.MemoryUsed != nil { + memoryUsed[i] = v.MemoryUsed + } else { + memoryUsed[i] = 0 + } + + name[i] = v.Name + + if v.Status != nil { + online[i] = *v.Status == "online" + } else { + online[i] = false + } + + if v.SSLFingerprint != nil { + sslFingerprints[i] = v.SSLFingerprint + } else { + sslFingerprints[i] = 0 + } + + if v.SupportLevel != nil { + supportLevels[i] = v.SupportLevel + } else { + supportLevels[i] = "" + } + + if v.Uptime != nil { + uptime[i] = v.Uptime + } else { + uptime[i] = 0 + } + } + + d.SetId("nodes") + + d.Set(mkDataSourceVirtualEnvironmentNodesCPUCount, cpuCount) + d.Set(mkDataSourceVirtualEnvironmentNodesCPUUtilization, cpuUtilization) + d.Set(mkDataSourceVirtualEnvironmentNodesMemoryAvailable, memoryAvailable) + d.Set(mkDataSourceVirtualEnvironmentNodesMemoryUsed, memoryUsed) + d.Set(mkDataSourceVirtualEnvironmentNodesNames, name) + d.Set(mkDataSourceVirtualEnvironmentNodesOnline, online) + d.Set(mkDataSourceVirtualEnvironmentNodesSSLFingerprints, sslFingerprints) + d.Set(mkDataSourceVirtualEnvironmentNodesSupportLevels, supportLevels) + d.Set(mkDataSourceVirtualEnvironmentNodesUptime, uptime) + + return nil +} diff --git a/data_source_virtual_environment_nodes_test.go b/data_source_virtual_environment_nodes_test.go new file mode 100644 index 00000000..30c5b30d --- /dev/null +++ b/data_source_virtual_environment_nodes_test.go @@ -0,0 +1,45 @@ +/* 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 main + +import ( + "testing" +) + +// TestDataSourceVirtualEnvironmentNodesInstantiation tests whether the DataSourceVirtualEnvironmentNodes instance can be instantiated. +func TestDataSourceVirtualEnvironmentNodesInstantiation(t *testing.T) { + s := dataSourceVirtualEnvironmentNodes() + + if s == nil { + t.Fatalf("Cannot instantiate dataSourceVirtualEnvironmentNodes") + } +} + +// TestDataSourceVirtualEnvironmentNodesSchema tests the dataSourceVirtualEnvironmentNodes schema. +func TestDataSourceVirtualEnvironmentNodesSchema(t *testing.T) { + s := dataSourceVirtualEnvironmentNodes() + + attributeKeys := []string{ + mkDataSourceVirtualEnvironmentNodesCPUCount, + mkDataSourceVirtualEnvironmentNodesCPUUtilization, + mkDataSourceVirtualEnvironmentNodesMemoryAvailable, + mkDataSourceVirtualEnvironmentNodesMemoryUsed, + mkDataSourceVirtualEnvironmentNodesNames, + mkDataSourceVirtualEnvironmentNodesOnline, + mkDataSourceVirtualEnvironmentNodesSSLFingerprints, + mkDataSourceVirtualEnvironmentNodesSupportLevels, + mkDataSourceVirtualEnvironmentNodesUptime, + } + + for _, v := range attributeKeys { + if s.Schema[v] == nil { + t.Fatalf("Error in dataSourceVirtualEnvironmentNodes.Schema: Missing attribute \"%s\"", v) + } + + if s.Schema[v].Computed != true { + t.Fatalf("Error in dataSourceVirtualEnvironmentNodes.Schema: Attribute \"%s\" is not computed", v) + } + } +} diff --git a/example/data_source_virtual_environment_nodes.tf b/example/data_source_virtual_environment_nodes.tf new file mode 100644 index 00000000..2a1b5b1a --- /dev/null +++ b/example/data_source_virtual_environment_nodes.tf @@ -0,0 +1,37 @@ +data "proxmox_virtual_environment_nodes" "example" {} + +output "data_proxmox_virtual_environment_nodes_example_cpu_count" { + value = "${data.proxmox_virtual_environment_nodes.example.cpu_count}" +} + +output "data_proxmox_virtual_environment_nodes_example_cpu_utilization" { + value = "${data.proxmox_virtual_environment_nodes.example.cpu_utilization}" +} + +output "data_proxmox_virtual_environment_nodes_example_memory_available" { + value = "${data.proxmox_virtual_environment_nodes.example.memory_available}" +} + +output "data_proxmox_virtual_environment_nodes_example_memory_used" { + value = "${data.proxmox_virtual_environment_nodes.example.memory_used}" +} + +output "data_proxmox_virtual_environment_nodes_example_names" { + value = "${data.proxmox_virtual_environment_nodes.example.names}" +} + +output "data_proxmox_virtual_environment_nodes_example_online" { + value = "${data.proxmox_virtual_environment_nodes.example.online}" +} + +output "data_proxmox_virtual_environment_nodes_example_ssl_fingerprints" { + value = "${data.proxmox_virtual_environment_nodes.example.ssl_fingerprints}" +} + +output "data_proxmox_virtual_environment_nodes_example_support_levels" { + value = "${data.proxmox_virtual_environment_nodes.example.support_levels}" +} + +output "data_proxmox_virtual_environment_nodes_example_uptime" { + value = "${data.proxmox_virtual_environment_nodes.example.uptime}" +} diff --git a/example/resource_virtual_environment_pool.tf b/example/resource_virtual_environment_pool.tf index eb76e4b2..d4d0cc84 100644 --- a/example/resource_virtual_environment_pool.tf +++ b/example/resource_virtual_environment_pool.tf @@ -1,5 +1,5 @@ resource "proxmox_virtual_environment_pool" "example" { - comment = "Managed by Terraform" + comment = "Managed by Terraform" pool_id = "terraform-provider-proxmox-example" } diff --git a/provider.go b/provider.go index 825aa2b0..6443aa7f 100644 --- a/provider.go +++ b/provider.go @@ -30,6 +30,7 @@ func Provider() *schema.Provider { DataSourcesMap: map[string]*schema.Resource{ "proxmox_virtual_environment_group": dataSourceVirtualEnvironmentGroup(), "proxmox_virtual_environment_groups": dataSourceVirtualEnvironmentGroups(), + "proxmox_virtual_environment_nodes": dataSourceVirtualEnvironmentNodes(), "proxmox_virtual_environment_pool": dataSourceVirtualEnvironmentPool(), "proxmox_virtual_environment_pools": dataSourceVirtualEnvironmentPools(), "proxmox_virtual_environment_role": dataSourceVirtualEnvironmentRole(), diff --git a/proxmox/virtual_environment_nodes.go b/proxmox/virtual_environment_nodes.go new file mode 100644 index 00000000..17719bcd --- /dev/null +++ b/proxmox/virtual_environment_nodes.go @@ -0,0 +1,48 @@ +/* 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" + "sort" +) + +// VirtualEnvironmentNodeListResponseBody contains the body from a node list response. +type VirtualEnvironmentNodeListResponseBody struct { + Data []*VirtualEnvironmentNodeListResponseData `json:"data,omitempty"` +} + +// VirtualEnvironmentNodeListResponseData contains the data from a node list response. +type VirtualEnvironmentNodeListResponseData struct { + CPUCount *int `json:"maxcpu,omitempty"` + CPUUtilization *float64 `json:"cpu,omitempty"` + MemoryAvailable *int `json:"maxmem,omitempty"` + MemoryUsed *int `json:"mem,omitempty"` + Name string `json:"node"` + SSLFingerprint *string `json:"ssl_fingerprint,omitempty"` + Status *string `json:"status"` + SupportLevel *string `json:"level,omitempty"` + Uptime *int `json:"uptime"` +} + +// ListNodes retrieves a list of nodes. +func (c *VirtualEnvironmentClient) ListNodes() ([]*VirtualEnvironmentNodeListResponseData, error) { + resBody := &VirtualEnvironmentNodeListResponseBody{} + err := c.DoRequest(hmGET, "nodes", 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") + } + + sort.Slice(resBody.Data, func(i, j int) bool { + return resBody.Data[i].Name < resBody.Data[j].Name + }) + + return resBody.Data, nil +}