mirror of
https://github.com/bpg/terraform-provider-proxmox.git
synced 2025-07-03 03:52:58 +00:00
feat(vm): Add bare minimum VM datasource (#268)
* feat(vm): Add a bare minimum VM datasource * fix linter errors * fix doc * add lookup across all nodes in the cluster, add filter by tags * stable vm list * fix linter errors * pr feedback: switch to dynamic id for vms * add datasource examples * add unit tests * Update virtual_environment_vms.md
This commit is contained in:
parent
7a0e1db6c4
commit
c2d3f46474
@ -11,6 +11,6 @@ plugins:
|
|||||||
remote_theme: pmarsceill/just-the-docs
|
remote_theme: pmarsceill/just-the-docs
|
||||||
|
|
||||||
# Theme settings.
|
# Theme settings.
|
||||||
footer_content: 'Copyright © 2019-2021 <a href="https://danitso.com/" target="_blank">Danitso</a> - Distributed under the <a href="https://github.com/danitso/terraform-provider-proxmox/blob/master/LICENSE" target="_blank">Mozilla Public License 2.0</a><br>Copyright © 2021-2022 <a href="https://github.com/bpg/" target="_blank">Pavel Boldyrev</a> - Distributed under the <a href="https://github.com/bpg/terraform-provider-proxmox/blob/main/LICENSE" target="_blank">Mozilla Public License 2.0</a>'
|
footer_content: 'Copyright © 2019-2021 <a href="https://danitso.com/" target="_blank">Danitso</a> - Distributed under the <a href="https://github.com/danitso/terraform-provider-proxmox/blob/master/LICENSE" target="_blank">Mozilla Public License 2.0</a><br>Copyright © 2021-2023 <a href="https://github.com/bpg/" target="_blank">Pavel Boldyrev</a> - Distributed under the <a href="https://github.com/bpg/terraform-provider-proxmox/blob/main/LICENSE" target="_blank">Mozilla Public License 2.0</a>'
|
||||||
heading_anchors: true
|
heading_anchors: true
|
||||||
search_enabled: false
|
search_enabled: false
|
||||||
|
31
docs/data-sources/virtual_environment_vm.md
Normal file
31
docs/data-sources/virtual_environment_vm.md
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
---
|
||||||
|
layout: page
|
||||||
|
title: proxmox_virtual_environment_vm
|
||||||
|
permalink: /data-sources/virtual_environment_vm
|
||||||
|
nav_order: 17
|
||||||
|
parent: Data Sources
|
||||||
|
subcategory: Virtual Environment
|
||||||
|
---
|
||||||
|
|
||||||
|
# Data Source: proxmox_virtual_environment_vm
|
||||||
|
|
||||||
|
Retrieves information about a specific VM.
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```terraform
|
||||||
|
data "proxmox_virtual_environment_vm" "test_vm" {
|
||||||
|
node_name = "test"
|
||||||
|
vm_id = 100
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
- `node_name` - (Required) The node name.
|
||||||
|
- `vm_id` - (Required) The VM identifier.
|
||||||
|
|
||||||
|
## Attribute Reference
|
||||||
|
|
||||||
|
- `name` - The virtual machine name.
|
||||||
|
- `tags` - A list of tags of the VM.
|
34
docs/data-sources/virtual_environment_vms.md
Normal file
34
docs/data-sources/virtual_environment_vms.md
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
---
|
||||||
|
layout: page
|
||||||
|
title: proxmox_virtual_environment_vms
|
||||||
|
permalink: /data-sources/virtual_environment_vms
|
||||||
|
nav_order: 18
|
||||||
|
parent: Data Sources
|
||||||
|
subcategory: Virtual Environment
|
||||||
|
---
|
||||||
|
|
||||||
|
# Data Source: proxmox_virtual_environment_vms
|
||||||
|
|
||||||
|
Retrieves information about all VMs in the Proxmox cluster.
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
```terraform
|
||||||
|
data "proxmox_virtual_environment_vms" "ubuntu_vms" {
|
||||||
|
tags = ["ubuntu"]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Argument Reference
|
||||||
|
|
||||||
|
- `node_name` - (Optional) The node name.
|
||||||
|
- `tags` - (Optional) A list of tags to filter the VMs. The VM must have all
|
||||||
|
the tags to be included in the result.
|
||||||
|
|
||||||
|
## Attribute Reference
|
||||||
|
|
||||||
|
- `vms` - The VMs list.
|
||||||
|
- `name` - The virtual machine name.
|
||||||
|
- `node_name` - The node name.
|
||||||
|
- `tags` - A list of tags of the VM.
|
||||||
|
- `vm_id` - The VM identifier.
|
9
example/data_source_virtual_environment_vm.tf
Normal file
9
example/data_source_virtual_environment_vm.tf
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
data "proxmox_virtual_environment_vm" "example" {
|
||||||
|
depends_on = [proxmox_virtual_environment_vm.example]
|
||||||
|
vm_id = proxmox_virtual_environment_vm.example.vm_id
|
||||||
|
node_name = data.proxmox_virtual_environment_nodes.example.names[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
output "proxmox_virtual_environment_vm_example" {
|
||||||
|
value = data.proxmox_virtual_environment_vm.example
|
||||||
|
}
|
15
example/data_source_virtual_environment_vms.tf
Normal file
15
example/data_source_virtual_environment_vms.tf
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
data "proxmox_virtual_environment_vms" "example" {
|
||||||
|
depends_on = [proxmox_virtual_environment_vm.example]
|
||||||
|
tags = ["ubuntu"]
|
||||||
|
|
||||||
|
lifecycle {
|
||||||
|
postcondition {
|
||||||
|
condition = length(self.vms) == 1
|
||||||
|
error_message = "Only 1 vm should have this tag"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
output "proxmox_virtual_environment_vms_example" {
|
||||||
|
value = data.proxmox_virtual_environment_vms.example.vms
|
||||||
|
}
|
2
go.mod
2
go.mod
@ -4,6 +4,7 @@ go 1.18
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/google/go-querystring v1.1.0
|
github.com/google/go-querystring v1.1.0
|
||||||
|
github.com/google/uuid v1.3.0
|
||||||
github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320
|
github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320
|
||||||
github.com/hashicorp/go-multierror v1.1.1
|
github.com/hashicorp/go-multierror v1.1.1
|
||||||
github.com/hashicorp/terraform-plugin-log v0.8.0
|
github.com/hashicorp/terraform-plugin-log v0.8.0
|
||||||
@ -12,6 +13,7 @@ require (
|
|||||||
github.com/skeema/knownhosts v1.1.0
|
github.com/skeema/knownhosts v1.1.0
|
||||||
github.com/stretchr/testify v1.8.2
|
github.com/stretchr/testify v1.8.2
|
||||||
golang.org/x/crypto v0.7.0
|
golang.org/x/crypto v0.7.0
|
||||||
|
golang.org/x/exp v0.0.0-20230315142452-642cacee5cc0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
4
go.sum
4
go.sum
@ -27,6 +27,8 @@ github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
|||||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
||||||
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
||||||
|
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||||
|
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||||
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
|
||||||
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||||
@ -124,6 +126,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
|
|||||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
|
golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
|
||||||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
||||||
|
golang.org/x/exp v0.0.0-20230315142452-642cacee5cc0 h1:pVgRXcIictcr+lBQIFeiwuwtDIs4eL21OuM9nyAADmo=
|
||||||
|
golang.org/x/exp v0.0.0-20230315142452-642cacee5cc0/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
@ -322,8 +322,27 @@ func (c *VirtualEnvironmentClient) MoveVMDiskAsync(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ListVMs retrieves a list of virtual machines.
|
// ListVMs retrieves a list of virtual machines.
|
||||||
func (c *VirtualEnvironmentClient) ListVMs() ([]*VirtualEnvironmentVMListResponseData, error) {
|
func (c *VirtualEnvironmentClient) ListVMs(
|
||||||
return nil, errors.New("not implemented")
|
ctx context.Context,
|
||||||
|
nodeName string,
|
||||||
|
) ([]*VirtualEnvironmentVMListResponseData, error) {
|
||||||
|
resBody := &VirtualEnvironmentVMListResponseBody{}
|
||||||
|
err := c.DoRequest(
|
||||||
|
ctx,
|
||||||
|
hmGET,
|
||||||
|
fmt.Sprintf("nodes/%s/qemu", 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
|
||||||
}
|
}
|
||||||
|
|
||||||
// RebootVM reboots a virtual machine.
|
// RebootVM reboots a virtual machine.
|
||||||
|
@ -504,7 +504,9 @@ type VirtualEnvironmentVMListResponseBody struct {
|
|||||||
|
|
||||||
// VirtualEnvironmentVMListResponseData contains the data from an virtual machine list response.
|
// VirtualEnvironmentVMListResponseData contains the data from an virtual machine list response.
|
||||||
type VirtualEnvironmentVMListResponseData struct {
|
type VirtualEnvironmentVMListResponseData struct {
|
||||||
ACPI *CustomBool `json:"acpi,omitempty" url:"acpi,omitempty,int"`
|
Name *string `json:"name,omitempty"`
|
||||||
|
Tags *string `json:"tags,omitempty"`
|
||||||
|
VMID int `json:"vmid,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// VirtualEnvironmentVMMigrateRequestBody contains the body for a VM migration request.
|
// VirtualEnvironmentVMMigrateRequestBody contains the body for a VM migration request.
|
||||||
|
101
proxmoxtf/data_source_virtual_environment_vm.go
Normal file
101
proxmoxtf/data_source_virtual_environment_vm.go
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
/* 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 (
|
||||||
|
"context"
|
||||||
|
"sort"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
mkDataSourceVirtualEnvironmentVMName = "name"
|
||||||
|
mkDataSourceVirtualEnvironmentVMNodeName = "node_name"
|
||||||
|
mkDataSourceVirtualEnvironmentVMTags = "tags"
|
||||||
|
mkDataSourceVirtualEnvironmentVMVMID = "vm_id"
|
||||||
|
)
|
||||||
|
|
||||||
|
func dataSourceVirtualEnvironmentVM() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
mkDataSourceVirtualEnvironmentVMName: {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Description: "The VM name",
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
mkDataSourceVirtualEnvironmentVMNodeName: {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Description: "The node name",
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
mkDataSourceVirtualEnvironmentVMTags: {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Description: "Tags of the VM",
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||||||
|
},
|
||||||
|
mkDataSourceVirtualEnvironmentVMVMID: {
|
||||||
|
Type: schema.TypeInt,
|
||||||
|
Description: "The VM identifier",
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ReadContext: dataSourceVirtualEnvironmentVMRead,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// dataSourceVirtualEnvironmentVMRead reads the data of a VM by ID.
|
||||||
|
func dataSourceVirtualEnvironmentVMRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
var diags diag.Diagnostics
|
||||||
|
|
||||||
|
config := m.(providerConfiguration)
|
||||||
|
veClient, err := config.GetVEClient()
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeName := d.Get(mkDataSourceVirtualEnvironmentVMNodeName).(string)
|
||||||
|
vmID := d.Get(mkDataSourceVirtualEnvironmentVMVMID).(int)
|
||||||
|
|
||||||
|
vmStatus, err := veClient.GetVMStatus(ctx, nodeName, vmID)
|
||||||
|
if err != nil {
|
||||||
|
if strings.Contains(err.Error(), "HTTP 404") ||
|
||||||
|
(strings.Contains(err.Error(), "HTTP 500") && strings.Contains(err.Error(), "does not exist")) {
|
||||||
|
d.SetId("")
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if vmStatus.Name != nil {
|
||||||
|
err = d.Set(mkDataSourceVirtualEnvironmentVMName, *vmStatus.Name)
|
||||||
|
} else {
|
||||||
|
err = d.Set(mkDataSourceVirtualEnvironmentVMName, "")
|
||||||
|
}
|
||||||
|
diags = append(diags, diag.FromErr(err)...)
|
||||||
|
|
||||||
|
var tags []string
|
||||||
|
if vmStatus.Tags != nil {
|
||||||
|
for _, tag := range strings.Split(*vmStatus.Tags, ";") {
|
||||||
|
t := strings.TrimSpace(tag)
|
||||||
|
if len(t) > 0 {
|
||||||
|
tags = append(tags, t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sort.Strings(tags)
|
||||||
|
}
|
||||||
|
err = d.Set(mkDataSourceVirtualEnvironmentVMTags, tags)
|
||||||
|
diags = append(diags, diag.FromErr(err)...)
|
||||||
|
|
||||||
|
d.SetId(strconv.Itoa(vmID))
|
||||||
|
|
||||||
|
return diags
|
||||||
|
}
|
41
proxmoxtf/data_source_virtual_environment_vm_test.go
Normal file
41
proxmoxtf/data_source_virtual_environment_vm_test.go
Normal file
@ -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-plugin-sdk/v2/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TestDataSourceVirtualEnvironmentVMInstantiation tests whether the dataSourceVirtualEnvironmentVM instance can be instantiated.
|
||||||
|
func TestDataSourceVirtualEnvironmentVMInstantiation(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
s := dataSourceVirtualEnvironmentVM()
|
||||||
|
|
||||||
|
if s == nil {
|
||||||
|
t.Fatalf("Cannot instantiate dataSourceVirtualEnvironmentVM")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestDataSourceVirtualEnvironmentVMSchema tests the dataSourceVirtualEnvironmentVM schema.
|
||||||
|
func TestDataSourceVirtualEnvironmentVMSchema(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
s := dataSourceVirtualEnvironmentVM()
|
||||||
|
|
||||||
|
testComputedAttributes(t, s, []string{
|
||||||
|
mkDataSourceVirtualEnvironmentVMName,
|
||||||
|
mkDataSourceVirtualEnvironmentVMTags,
|
||||||
|
})
|
||||||
|
|
||||||
|
testValueTypes(t, s, map[string]schema.ValueType{
|
||||||
|
mkDataSourceVirtualEnvironmentVMName: schema.TypeString,
|
||||||
|
mkDataSourceVirtualEnvironmentVMNodeName: schema.TypeString,
|
||||||
|
mkDataSourceVirtualEnvironmentVMTags: schema.TypeList,
|
||||||
|
mkDataSourceVirtualEnvironmentVMVMID: schema.TypeInt,
|
||||||
|
})
|
||||||
|
}
|
154
proxmoxtf/data_source_virtual_environment_vms.go
Normal file
154
proxmoxtf/data_source_virtual_environment_vms.go
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
/* 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 (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||||
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
|
"golang.org/x/exp/slices"
|
||||||
|
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
mkDataSourceVirtualEnvironmentVMs = "vms"
|
||||||
|
)
|
||||||
|
|
||||||
|
func dataSourceVirtualEnvironmentVMs() *schema.Resource {
|
||||||
|
return &schema.Resource{
|
||||||
|
Schema: map[string]*schema.Schema{
|
||||||
|
mkDataSourceVirtualEnvironmentVMNodeName: {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
Description: "The node name",
|
||||||
|
},
|
||||||
|
mkDataSourceVirtualEnvironmentVMTags: {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Description: "Tags of the VM to match",
|
||||||
|
Optional: true,
|
||||||
|
Elem: &schema.Schema{Type: schema.TypeString},
|
||||||
|
},
|
||||||
|
mkDataSourceVirtualEnvironmentVMs: {
|
||||||
|
Type: schema.TypeList,
|
||||||
|
Description: "VMs",
|
||||||
|
Computed: true,
|
||||||
|
Elem: &schema.Resource{
|
||||||
|
Schema: dataSourceVirtualEnvironmentVM().Schema,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ReadContext: dataSourceVirtualEnvironmentVMsRead,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// dataSourceVirtualEnvironmentVMRead reads the data of a VM by ID.
|
||||||
|
func dataSourceVirtualEnvironmentVMsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||||
|
var diags diag.Diagnostics
|
||||||
|
|
||||||
|
config := m.(providerConfiguration)
|
||||||
|
veClient, err := config.GetVEClient()
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeNames, err := getNodeNames(ctx, d, veClient)
|
||||||
|
if err != nil {
|
||||||
|
return diag.FromErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tagsData := d.Get(mkResourceVirtualEnvironmentVMTags).([]interface{})
|
||||||
|
var filterTags []string
|
||||||
|
for i := 0; i < len(tagsData); i++ {
|
||||||
|
tag := strings.TrimSpace(tagsData[i].(string))
|
||||||
|
if len(tag) > 0 {
|
||||||
|
filterTags = append(filterTags, tag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sort.Strings(filterTags)
|
||||||
|
|
||||||
|
var vms []interface{}
|
||||||
|
for _, nodeName := range nodeNames {
|
||||||
|
listData, err := veClient.ListVMs(ctx, nodeName)
|
||||||
|
if err != nil {
|
||||||
|
diags = append(diags, diag.FromErr(err)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Slice(listData, func(i, j int) bool {
|
||||||
|
return listData[i].VMID < listData[j].VMID
|
||||||
|
})
|
||||||
|
|
||||||
|
for _, data := range listData {
|
||||||
|
vm := map[string]interface{}{
|
||||||
|
mkDataSourceVirtualEnvironmentVMNodeName: nodeName,
|
||||||
|
mkDataSourceVirtualEnvironmentVMVMID: data.VMID,
|
||||||
|
}
|
||||||
|
|
||||||
|
if data.Name != nil {
|
||||||
|
vm[mkDataSourceVirtualEnvironmentVMName] = *data.Name
|
||||||
|
} else {
|
||||||
|
vm[mkDataSourceVirtualEnvironmentVMName] = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
var tags []string
|
||||||
|
if data.Tags != nil && *data.Tags != "" {
|
||||||
|
tags = strings.Split(*data.Tags, ";")
|
||||||
|
sort.Strings(tags)
|
||||||
|
vm[mkDataSourceVirtualEnvironmentVMTags] = tags
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(filterTags) > 0 {
|
||||||
|
match := true
|
||||||
|
for _, tag := range filterTags {
|
||||||
|
if !slices.Contains(tags, tag) {
|
||||||
|
match = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !match {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vms = append(vms, vm)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = d.Set(mkDataSourceVirtualEnvironmentVMs, vms)
|
||||||
|
diags = append(diags, diag.FromErr(err)...)
|
||||||
|
|
||||||
|
d.SetId(uuid.New().String())
|
||||||
|
|
||||||
|
return diags
|
||||||
|
}
|
||||||
|
|
||||||
|
func getNodeNames(
|
||||||
|
ctx context.Context,
|
||||||
|
d *schema.ResourceData,
|
||||||
|
veClient *proxmox.VirtualEnvironmentClient,
|
||||||
|
) ([]string, error) {
|
||||||
|
var nodeNames []string
|
||||||
|
nodeName := d.Get(mkDataSourceVirtualEnvironmentVMNodeName).(string)
|
||||||
|
if nodeName != "" {
|
||||||
|
nodeNames = append(nodeNames, nodeName)
|
||||||
|
} else {
|
||||||
|
nodes, err := veClient.ListNodes(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error listing nodes: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, node := range nodes {
|
||||||
|
nodeNames = append(nodeNames, node.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Strings(nodeNames)
|
||||||
|
return nodeNames, nil
|
||||||
|
}
|
53
proxmoxtf/data_source_virtual_environment_vms_test.go
Normal file
53
proxmoxtf/data_source_virtual_environment_vms_test.go
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/* 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-plugin-sdk/v2/helper/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TestDataSourceVirtualEnvironmentVMsInstantiation tests whether the dataSourceVirtualEnvironmentVMs instance can be instantiated.
|
||||||
|
func TestDataSourceVirtualEnvironmentVMsInstantiation(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
s := dataSourceVirtualEnvironmentVMs()
|
||||||
|
|
||||||
|
if s == nil {
|
||||||
|
t.Fatalf("Cannot instantiate dataSourceVirtualEnvironmentVMs")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestDataSourceVirtualEnvironmentVMsSchema tests the dataSourceVirtualEnvironmentVMs schema.
|
||||||
|
func TestDataSourceVirtualEnvironmentVMsSchema(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
s := dataSourceVirtualEnvironmentVMs()
|
||||||
|
|
||||||
|
testComputedAttributes(t, s, []string{
|
||||||
|
mkDataSourceVirtualEnvironmentVMs,
|
||||||
|
})
|
||||||
|
|
||||||
|
testValueTypes(t, s, map[string]schema.ValueType{
|
||||||
|
mkDataSourceVirtualEnvironmentVMNodeName: schema.TypeString,
|
||||||
|
mkDataSourceVirtualEnvironmentVMTags: schema.TypeList,
|
||||||
|
mkDataSourceVirtualEnvironmentVMs: schema.TypeList,
|
||||||
|
})
|
||||||
|
|
||||||
|
vmsSchema := testNestedSchemaExistence(t, s, mkDataSourceVirtualEnvironmentVMs)
|
||||||
|
|
||||||
|
testComputedAttributes(t, vmsSchema, []string{
|
||||||
|
mkDataSourceVirtualEnvironmentVMName,
|
||||||
|
mkDataSourceVirtualEnvironmentVMTags,
|
||||||
|
})
|
||||||
|
|
||||||
|
testValueTypes(t, vmsSchema, map[string]schema.ValueType{
|
||||||
|
mkDataSourceVirtualEnvironmentVMName: schema.TypeString,
|
||||||
|
mkDataSourceVirtualEnvironmentVMNodeName: schema.TypeString,
|
||||||
|
mkDataSourceVirtualEnvironmentVMTags: schema.TypeList,
|
||||||
|
mkDataSourceVirtualEnvironmentVMVMID: schema.TypeInt,
|
||||||
|
})
|
||||||
|
}
|
@ -55,6 +55,8 @@ func Provider() *schema.Provider {
|
|||||||
"proxmox_virtual_environment_user": dataSourceVirtualEnvironmentUser(),
|
"proxmox_virtual_environment_user": dataSourceVirtualEnvironmentUser(),
|
||||||
"proxmox_virtual_environment_users": dataSourceVirtualEnvironmentUsers(),
|
"proxmox_virtual_environment_users": dataSourceVirtualEnvironmentUsers(),
|
||||||
"proxmox_virtual_environment_version": dataSourceVirtualEnvironmentVersion(),
|
"proxmox_virtual_environment_version": dataSourceVirtualEnvironmentVersion(),
|
||||||
|
"proxmox_virtual_environment_vm": dataSourceVirtualEnvironmentVM(),
|
||||||
|
"proxmox_virtual_environment_vms": dataSourceVirtualEnvironmentVMs(),
|
||||||
},
|
},
|
||||||
ResourcesMap: map[string]*schema.Resource{
|
ResourcesMap: map[string]*schema.Resource{
|
||||||
"proxmox_virtual_environment_certificate": resourceVirtualEnvironmentCertificate(),
|
"proxmox_virtual_environment_certificate": resourceVirtualEnvironmentCertificate(),
|
||||||
|
Loading…
Reference in New Issue
Block a user