From 3834564ea43d1f679e4f281c89ce0a815ddfbd12 Mon Sep 17 00:00:00 2001 From: H3Krn Date: Sat, 15 Feb 2025 02:44:17 +0100 Subject: [PATCH] feat(lxc): add container datasource (#1750) * feat(lxc): add container datasource Signed-off-by: Harm Kroon * chore: ignore duplicated code Signed-off-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com> --------- Signed-off-by: Harm Kroon Signed-off-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com> Co-authored-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com> --- .../virtual_environment_container.md | 31 ++++ ...ta_source_virtual_environment_container.tf | 9 ++ proxmoxtf/datasource/container.go | 141 ++++++++++++++++++ proxmoxtf/datasource/container_test.go | 47 ++++++ proxmoxtf/datasource/vm.go | 1 + proxmoxtf/provider/datasources.go | 1 + 6 files changed, 230 insertions(+) create mode 100644 docs/data-sources/virtual_environment_container.md create mode 100644 example/data_source_virtual_environment_container.tf create mode 100644 proxmoxtf/datasource/container.go create mode 100644 proxmoxtf/datasource/container_test.go diff --git a/docs/data-sources/virtual_environment_container.md b/docs/data-sources/virtual_environment_container.md new file mode 100644 index 00000000..d5dd8acb --- /dev/null +++ b/docs/data-sources/virtual_environment_container.md @@ -0,0 +1,31 @@ +--- +layout: page +title: proxmox_virtual_environment_container +parent: Data Sources +subcategory: Virtual Environment +--- + +# Data Source: proxmox_virtual_environment_container + +Retrieves information about a specific Container. + +## Example Usage + +```hcl +data "proxmox_virtual_environment_container" "test_container" { + node_name = "test" + vm_id = 100 +} +``` + +## Argument Reference + +- `node_name` - (Required) The node name. +- `vm_id` - (Required) The container identifier. + +## Attribute Reference + +- `name` - The container name. +- `tags` - A list of tags of the container. +- `status` - Status of the container +- `template` - Is container a template (true) or a regular container (false) diff --git a/example/data_source_virtual_environment_container.tf b/example/data_source_virtual_environment_container.tf new file mode 100644 index 00000000..fa257186 --- /dev/null +++ b/example/data_source_virtual_environment_container.tf @@ -0,0 +1,9 @@ +data "proxmox_virtual_environment_container" "example" { + depends_on = [proxmox_virtual_environment_container.example] + vm_id = proxmox_virtual_environment_container.example.vm_id + node_name = data.proxmox_virtual_environment_nodes.example.names[0] +} + +output "proxmox_virtual_environment_container_example" { + value = data.proxmox_virtual_environment_container.example +} diff --git a/proxmoxtf/datasource/container.go b/proxmoxtf/datasource/container.go new file mode 100644 index 00000000..f505d5ac --- /dev/null +++ b/proxmoxtf/datasource/container.go @@ -0,0 +1,141 @@ +/* + * 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/. + */ + +//nolint:dupl +package datasource + +import ( + "context" + "errors" + "sort" + "strconv" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmox/api" + "github.com/bpg/terraform-provider-proxmox/proxmoxtf" +) + +const ( + mkDataSourceVirtualEnvironmentContainerName = "name" + mkDataSourceVirtualEnvironmentContainerNodeName = "node_name" + mkDataSourceVirtualEnvironmentContainerTags = "tags" + mkDataSourceVirtualEnvironmentContainerTemplate = "template" + mkDataSourceVirtualEnvironmentContainerStatus = "status" + mkDataSourceVirtualEnvironmentContainerVMID = "vm_id" +) + +// Container returns a resource for a single Proxmox Container. +func Container() *schema.Resource { + return &schema.Resource{ + Schema: map[string]*schema.Schema{ + mkDataSourceVirtualEnvironmentContainerName: { + Type: schema.TypeString, + Description: "The Container name", + Computed: true, + }, + mkDataSourceVirtualEnvironmentContainerNodeName: { + Type: schema.TypeString, + Description: "The node name", + Required: true, + }, + mkDataSourceVirtualEnvironmentContainerTags: { + Type: schema.TypeList, + Description: "Tags of the Container", + Computed: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + mkDataSourceVirtualEnvironmentContainerTemplate: { + Type: schema.TypeBool, + Description: "Is Container a template (true) or a regular Container (false)", + Optional: true, + }, + mkDataSourceVirtualEnvironmentContainerStatus: { + Type: schema.TypeString, + Description: "Status of the Container", + Optional: true, + }, + mkDataSourceVirtualEnvironmentContainerVMID: { + Type: schema.TypeInt, + Description: "The Container identifier", + Required: true, + }, + }, + ReadContext: containerRead, + } +} + +// containerRead reads the data of a Container by ID. +func containerRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + var diags diag.Diagnostics + + config := m.(proxmoxtf.ProviderConfiguration) + + client, err := config.GetClient() + if err != nil { + return diag.FromErr(err) + } + + nodeName := d.Get(mkDataSourceVirtualEnvironmentContainerNodeName).(string) + containerID := d.Get(mkDataSourceVirtualEnvironmentContainerVMID).(int) + + containerStatus, err := client.Node(nodeName).Container(containerID).GetContainerStatus(ctx) + if err != nil { + if errors.Is(err, api.ErrNoDataObjectInResponse) { + d.SetId("") + + return nil + } + + return diag.FromErr(err) + } + + containerConfig, err := client.Node(nodeName).Container(containerID).GetContainer(ctx) + if err != nil { + return diag.FromErr(err) + } + + if containerStatus.Name != nil { + err = d.Set(mkDataSourceVirtualEnvironmentContainerName, *containerStatus.Name) + } else { + err = d.Set(mkDataSourceVirtualEnvironmentContainerName, "") + } + + diags = append(diags, diag.FromErr(err)...) + + var tags []string + + if containerStatus.Tags != nil { + for _, tag := range strings.Split(*containerStatus.Tags, ";") { + t := strings.TrimSpace(tag) + if len(t) > 0 { + tags = append(tags, t) + } + } + + sort.Strings(tags) + } + + err = d.Set(mkDataSourceVirtualEnvironmentContainerStatus, containerStatus.Status) + diags = append(diags, diag.FromErr(err)...) + + if containerConfig.Template == nil { + err = d.Set(mkDataSourceVirtualEnvironmentContainerTemplate, false) + } else { + err = d.Set(mkDataSourceVirtualEnvironmentContainerTemplate, *containerConfig.Template) + } + + diags = append(diags, diag.FromErr(err)...) + + err = d.Set(mkDataSourceVirtualEnvironmentContainerTags, tags) + diags = append(diags, diag.FromErr(err)...) + + d.SetId(strconv.Itoa(containerID)) + + return diags +} diff --git a/proxmoxtf/datasource/container_test.go b/proxmoxtf/datasource/container_test.go new file mode 100644 index 00000000..9c3bcec6 --- /dev/null +++ b/proxmoxtf/datasource/container_test.go @@ -0,0 +1,47 @@ +/* + * 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 datasource + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/bpg/terraform-provider-proxmox/proxmoxtf/test" +) + +// TestContainerInstantiation tests whether the Container instance can be instantiated. +func TestContainerInstantiation(t *testing.T) { + t.Parallel() + + s := Container() + + if s == nil { + t.Fatalf("Cannot instantiate Container") + } +} + +// TestContainerSchema tests the Container schema. +func TestContainerSchema(t *testing.T) { + t.Parallel() + + s := Container().Schema + + test.AssertComputedAttributes(t, s, []string{ + mkDataSourceVirtualEnvironmentContainerName, + mkDataSourceVirtualEnvironmentContainerTags, + }) + + test.AssertValueTypes(t, s, map[string]schema.ValueType{ + mkDataSourceVirtualEnvironmentContainerName: schema.TypeString, + mkDataSourceVirtualEnvironmentContainerNodeName: schema.TypeString, + mkDataSourceVirtualEnvironmentContainerTags: schema.TypeList, + mkDataSourceVirtualEnvironmentContainerTemplate: schema.TypeBool, + mkDataSourceVirtualEnvironmentContainerStatus: schema.TypeString, + mkDataSourceVirtualEnvironmentContainerVMID: schema.TypeInt, + }) +} diff --git a/proxmoxtf/datasource/vm.go b/proxmoxtf/datasource/vm.go index e6e5dd7b..e2381654 100644 --- a/proxmoxtf/datasource/vm.go +++ b/proxmoxtf/datasource/vm.go @@ -4,6 +4,7 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +//nolint:dupl package datasource import ( diff --git a/proxmoxtf/provider/datasources.go b/proxmoxtf/provider/datasources.go index 57bfa2d1..1076198a 100644 --- a/proxmoxtf/provider/datasources.go +++ b/proxmoxtf/provider/datasources.go @@ -30,5 +30,6 @@ func createDatasourceMap() map[string]*schema.Resource { "proxmox_virtual_environment_users": datasource.Users(), "proxmox_virtual_environment_vm": datasource.VM(), "proxmox_virtual_environment_vms": datasource.VMs(), + "proxmox_virtual_environment_container": datasource.Container(), } }