mirror of
https://github.com/bpg/terraform-provider-proxmox.git
synced 2025-06-29 18:21:10 +00:00
chore(vm2): add datasource implementation (#1318)
* chore(vm2): add datasource implementation --------- Signed-off-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com>
This commit is contained in:
parent
98233afabc
commit
e3dd31f55e
69
docs/data-sources/virtual_environment_vm2.md
Normal file
69
docs/data-sources/virtual_environment_vm2.md
Normal file
@ -0,0 +1,69 @@
|
||||
---
|
||||
layout: page
|
||||
title: proxmox_virtual_environment_vm2
|
||||
parent: Data Sources
|
||||
subcategory: Virtual Environment
|
||||
description: |-
|
||||
This is an experimental implementation of a Proxmox VM datasource using Plugin Framework.
|
||||
---
|
||||
|
||||
# Data Source: proxmox_virtual_environment_vm2
|
||||
|
||||
!> **DO NOT USE**
|
||||
This is an experimental implementation of a Proxmox VM datasource using Plugin Framework.
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `id` (Number) The unique identifier of the VM in the Proxmox cluster.
|
||||
- `node_name` (String) The name of the node where the VM is provisioned.
|
||||
|
||||
### Optional
|
||||
|
||||
- `clone` (Attributes) The cloning configuration. (see [below for nested schema](#nestedatt--clone))
|
||||
- `cpu` (Attributes) The CPU configuration. (see [below for nested schema](#nestedatt--cpu))
|
||||
- `description` (String) The description of the VM.
|
||||
- `name` (String) The name of the VM.
|
||||
- `tags` (Set of String) The tags assigned to the VM.
|
||||
- `template` (Boolean) Whether the VM is a template.
|
||||
- `timeouts` (Attributes) (see [below for nested schema](#nestedatt--timeouts))
|
||||
|
||||
<a id="nestedatt--clone"></a>
|
||||
### Nested Schema for `clone`
|
||||
|
||||
Required:
|
||||
|
||||
- `id` (Number) The ID of the VM to clone.
|
||||
|
||||
Optional:
|
||||
|
||||
- `retries` (Number) The number of retries to perform when cloning the VM (default: 3).
|
||||
|
||||
|
||||
<a id="nestedatt--cpu"></a>
|
||||
### Nested Schema for `cpu`
|
||||
|
||||
Optional:
|
||||
|
||||
- `affinity` (String) List of host cores used to execute guest processes, for example: '0,5,8-11'
|
||||
- `architecture` (String) The CPU architecture.
|
||||
- `cores` (Number) The number of CPU cores per socket.
|
||||
- `flags` (Set of String) Set of additional CPU flags.
|
||||
- `hotplugged` (Number) The number of hotplugged vCPUs.
|
||||
- `limit` (Number) Limit of CPU usage.
|
||||
- `numa` (Boolean) Enable NUMA.
|
||||
- `sockets` (Number) The number of CPU sockets.
|
||||
- `type` (String) Emulated CPU type.
|
||||
- `units` (Number) CPU weight for a VM
|
||||
|
||||
|
||||
<a id="nestedatt--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `read` (String) A string that can be [parsed as a duration](https://pkg.go.dev/time#ParseDuration) consisting of numbers and unit suffixes, such as "30s" or "2h45m". Valid time units are "s" (seconds), "m" (minutes), "h" (hours). Read operations occur during any refresh or planning operation when refresh is enabled.
|
@ -35,7 +35,7 @@ The attributes are also marked as optional to allow the practitioner to set (or
|
||||
- `description` (String) The description of the VM.
|
||||
- `id` (Number) The unique identifier of the VM in the Proxmox cluster.
|
||||
- `name` (String) The name of the VM. Doesn't have to be unique.
|
||||
- `tags` (Set of String) The tags assigned to the resource.
|
||||
- `tags` (Set of String) The tags assigned to the VM.
|
||||
- `template` (Boolean) Set to true to create a VM template.
|
||||
- `timeouts` (Attributes) (see [below for nested schema](#nestedatt--timeouts))
|
||||
|
||||
|
@ -441,30 +441,31 @@ func (p *proxmoxProvider) Configure(
|
||||
|
||||
func (p *proxmoxProvider) Resources(_ context.Context) []func() resource.Resource {
|
||||
return []func() resource.Resource{
|
||||
NewClusterOptionsResource,
|
||||
NewDownloadFileResource,
|
||||
access.NewACLResource,
|
||||
access.NewUserTokenResource,
|
||||
ha.NewHAGroupResource,
|
||||
ha.NewHAResourceResource,
|
||||
hardwaremapping.NewResourcePCI,
|
||||
hardwaremapping.NewResourceUSB,
|
||||
network.NewLinuxBridgeResource,
|
||||
network.NewLinuxVLANResource,
|
||||
access.NewUserTokenResource,
|
||||
vm.NewVMResource,
|
||||
NewClusterOptionsResource,
|
||||
NewDownloadFileResource,
|
||||
access.NewACLResource,
|
||||
vm.NewResource,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *proxmoxProvider) DataSources(_ context.Context) []func() datasource.DataSource {
|
||||
return []func() datasource.DataSource{
|
||||
ha.NewHAGroupsDataSource,
|
||||
NewVersionDataSource,
|
||||
ha.NewHAGroupDataSource,
|
||||
ha.NewHAResourcesDataSource,
|
||||
ha.NewHAGroupsDataSource,
|
||||
ha.NewHAResourceDataSource,
|
||||
ha.NewHAResourcesDataSource,
|
||||
hardwaremapping.NewDataSource,
|
||||
hardwaremapping.NewDataSourcePCI,
|
||||
hardwaremapping.NewDataSourceUSB,
|
||||
hardwaremapping.NewDataSource,
|
||||
NewVersionDataSource,
|
||||
vm.NewDataSource,
|
||||
}
|
||||
}
|
||||
|
||||
|
72
fwprovider/vm/cpu/datasource_schema.go
Normal file
72
fwprovider/vm/cpu/datasource_schema.go
Normal file
@ -0,0 +1,72 @@
|
||||
package cpu
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
|
||||
)
|
||||
|
||||
// DataSourceSchema defines the schema for the CPU resource.
|
||||
func DataSourceSchema() schema.Attribute {
|
||||
return schema.SingleNestedAttribute{
|
||||
CustomType: basetypes.ObjectType{
|
||||
AttrTypes: attributeTypes(),
|
||||
},
|
||||
Description: "The CPU configuration.",
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Attributes: map[string]schema.Attribute{
|
||||
"affinity": schema.StringAttribute{
|
||||
Description: "List of host cores used to execute guest processes, for example: '0,5,8-11'",
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
"architecture": schema.StringAttribute{
|
||||
Description: "The CPU architecture.",
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
"cores": schema.Int64Attribute{
|
||||
Description: "The number of CPU cores per socket.",
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
"flags": schema.SetAttribute{
|
||||
Description: "Set of additional CPU flags.",
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
ElementType: types.StringType,
|
||||
},
|
||||
"hotplugged": schema.Int64Attribute{
|
||||
Description: "The number of hotplugged vCPUs.",
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
"limit": schema.Int64Attribute{
|
||||
Description: "Limit of CPU usage.",
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
"numa": schema.BoolAttribute{
|
||||
Description: "Enable NUMA.",
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
"sockets": schema.Int64Attribute{
|
||||
Description: "The number of CPU sockets.",
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
"type": schema.StringAttribute{
|
||||
Description: "Emulated CPU type.",
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
"units": schema.Int64Attribute{
|
||||
Description: "CPU weight for a VM",
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
@ -15,8 +15,8 @@ import (
|
||||
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
|
||||
)
|
||||
|
||||
// Schema defines the schema for the CPU resource.
|
||||
func Schema() schema.Attribute {
|
||||
// ResourceSchema defines the schema for the CPU resource.
|
||||
func ResourceSchema() schema.Attribute {
|
||||
return schema.SingleNestedAttribute{
|
||||
CustomType: basetypes.ObjectType{
|
||||
AttrTypes: attributeTypes(),
|
||||
@ -202,7 +202,8 @@ func Schema() schema.Attribute {
|
||||
},
|
||||
},
|
||||
"units": schema.Int64Attribute{
|
||||
Description: "CPU weight for a VM. Argument is used in the kernel fair scheduler. " +
|
||||
Description: "CPU weight for a VM.",
|
||||
MarkdownDescription: "CPU weight for a VM. Argument is used in the kernel fair scheduler. " +
|
||||
"The larger the number is, the more CPU time this VM gets. " +
|
||||
"Number is relative to weights of all the other running VMs.",
|
||||
Optional: true,
|
94
fwprovider/vm/datasource.go
Normal file
94
fwprovider/vm/datasource.go
Normal file
@ -0,0 +1,94 @@
|
||||
package vm
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/datasource"
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
|
||||
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
||||
)
|
||||
|
||||
// Ensure the implementation satisfies the expected interfaces.
|
||||
var (
|
||||
_ datasource.DataSource = &Datasource{}
|
||||
_ datasource.DataSourceWithConfigure = &Datasource{}
|
||||
)
|
||||
|
||||
// Datasource is the implementation of VM datasource.
|
||||
type Datasource struct {
|
||||
client proxmox.Client
|
||||
}
|
||||
|
||||
// NewDataSource creates a new VM datasource.
|
||||
func NewDataSource() datasource.DataSource {
|
||||
return &Datasource{}
|
||||
}
|
||||
|
||||
// Metadata defines the name of the resource.
|
||||
func (d *Datasource) Metadata(
|
||||
_ context.Context,
|
||||
req datasource.MetadataRequest,
|
||||
resp *datasource.MetadataResponse,
|
||||
) {
|
||||
resp.TypeName = req.ProviderTypeName + "_vm2"
|
||||
}
|
||||
|
||||
// Configure sets the client for the resource.
|
||||
func (d *Datasource) Configure(
|
||||
_ context.Context,
|
||||
req datasource.ConfigureRequest,
|
||||
resp *datasource.ConfigureResponse,
|
||||
) {
|
||||
if req.ProviderData == nil {
|
||||
return
|
||||
}
|
||||
|
||||
client, ok := req.ProviderData.(proxmox.Client)
|
||||
|
||||
if !ok {
|
||||
resp.Diagnostics.AddError(
|
||||
"Unexpected Resource Configure Type",
|
||||
fmt.Sprintf("Expected *proxmox.Client, got: %T", req.ProviderData),
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
d.client = client
|
||||
}
|
||||
|
||||
//nolint:dupl
|
||||
func (d *Datasource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
|
||||
var config Model
|
||||
|
||||
resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
|
||||
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
timeout, diags := config.Timeouts.Read(ctx, defaultReadTimeout)
|
||||
resp.Diagnostics.Append(diags...)
|
||||
|
||||
ctx, cancel := context.WithTimeout(ctx, timeout)
|
||||
defer cancel()
|
||||
|
||||
exists := read(ctx, d.client, &config, &resp.Diagnostics)
|
||||
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
if !exists {
|
||||
tflog.Info(ctx, "VM does not exist, removing from the state", map[string]interface{}{
|
||||
"id": config.ID.ValueInt64(),
|
||||
})
|
||||
resp.State.RemoveResource(ctx)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, config)...)
|
||||
}
|
65
fwprovider/vm/datasource_schema.go
Normal file
65
fwprovider/vm/datasource_schema.go
Normal file
@ -0,0 +1,65 @@
|
||||
package vm
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework-timeouts/resource/timeouts"
|
||||
"github.com/hashicorp/terraform-plugin-framework/datasource"
|
||||
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
|
||||
|
||||
"github.com/bpg/terraform-provider-proxmox/fwprovider/types/stringset"
|
||||
"github.com/bpg/terraform-provider-proxmox/fwprovider/vm/cpu"
|
||||
)
|
||||
|
||||
// Schema defines the schema for the resource.
|
||||
func (d *Datasource) Schema(
|
||||
ctx context.Context,
|
||||
_ datasource.SchemaRequest,
|
||||
resp *datasource.SchemaResponse,
|
||||
) {
|
||||
resp.Schema = schema.Schema{
|
||||
Description: "This is an experimental implementation of a Proxmox VM datasource using Plugin Framework.",
|
||||
Attributes: map[string]schema.Attribute{
|
||||
"clone": schema.SingleNestedAttribute{
|
||||
Description: "The cloning configuration.",
|
||||
Optional: true,
|
||||
Attributes: map[string]schema.Attribute{
|
||||
"id": schema.Int64Attribute{
|
||||
Description: "The ID of the VM to clone.",
|
||||
Required: true,
|
||||
},
|
||||
"retries": schema.Int64Attribute{
|
||||
Description: "The number of retries to perform when cloning the VM (default: 3).",
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
"cpu": cpu.DataSourceSchema(),
|
||||
"description": schema.StringAttribute{
|
||||
Description: "The description of the VM.",
|
||||
Optional: true,
|
||||
},
|
||||
"id": schema.Int64Attribute{
|
||||
Required: true,
|
||||
Description: "The unique identifier of the VM in the Proxmox cluster.",
|
||||
},
|
||||
"name": schema.StringAttribute{
|
||||
Description: "The name of the VM.",
|
||||
Optional: true,
|
||||
},
|
||||
"node_name": schema.StringAttribute{
|
||||
Description: "The name of the node where the VM is provisioned.",
|
||||
Required: true,
|
||||
},
|
||||
"tags": stringset.ResourceAttribute("The tags assigned to the VM.", ""),
|
||||
"template": schema.BoolAttribute{
|
||||
Description: "Whether the VM is a template.",
|
||||
Optional: true,
|
||||
},
|
||||
"timeouts": timeouts.Attributes(ctx, timeouts.Opts{
|
||||
Read: true,
|
||||
}),
|
||||
},
|
||||
}
|
||||
}
|
@ -15,7 +15,6 @@ import (
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
|
||||
"github.com/bpg/terraform-provider-proxmox/fwprovider/types/stringset"
|
||||
"github.com/bpg/terraform-provider-proxmox/fwprovider/vm/cpu"
|
||||
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
||||
"github.com/bpg/terraform-provider-proxmox/proxmox/api"
|
||||
@ -44,8 +43,8 @@ type Resource struct {
|
||||
client proxmox.Client
|
||||
}
|
||||
|
||||
// NewVMResource creates a new resource for managing VMs.
|
||||
func NewVMResource() resource.Resource {
|
||||
// NewResource creates a new resource for managing VMs.
|
||||
func NewResource() resource.Resource {
|
||||
return &Resource{}
|
||||
}
|
||||
|
||||
@ -123,7 +122,7 @@ func (r *Resource) Create(ctx context.Context, req resource.CreateRequest, resp
|
||||
}
|
||||
|
||||
// read back the VM from the PVE API to populate computed fields
|
||||
exists := r.read(ctx, &plan, &resp.Diagnostics)
|
||||
exists := read(ctx, r.client, &plan, &resp.Diagnostics)
|
||||
if !exists {
|
||||
resp.Diagnostics.AddError("VM does not exist after creation", "")
|
||||
}
|
||||
@ -195,7 +194,7 @@ func (r *Resource) clone(ctx context.Context, plan Model, diags *diag.Diagnostic
|
||||
NodeName: plan.NodeName,
|
||||
}
|
||||
|
||||
r.read(ctx, &clone, diags)
|
||||
read(ctx, r.client, &clone, diags)
|
||||
|
||||
if diags.HasError() {
|
||||
return
|
||||
@ -204,6 +203,7 @@ func (r *Resource) clone(ctx context.Context, plan Model, diags *diag.Diagnostic
|
||||
r.update(ctx, plan, clone, true, diags)
|
||||
}
|
||||
|
||||
//nolint:dupl
|
||||
func (r *Resource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
|
||||
var state Model
|
||||
|
||||
@ -219,7 +219,7 @@ func (r *Resource) Read(ctx context.Context, req resource.ReadRequest, resp *res
|
||||
ctx, cancel := context.WithTimeout(ctx, timeout)
|
||||
defer cancel()
|
||||
|
||||
exists := r.read(ctx, &state, &resp.Diagnostics)
|
||||
exists := read(ctx, r.client, &state, &resp.Diagnostics)
|
||||
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
@ -258,7 +258,7 @@ func (r *Resource) Update(ctx context.Context, req resource.UpdateRequest, resp
|
||||
r.update(ctx, plan, state, false, &resp.Diagnostics)
|
||||
|
||||
// read back the VM from the PVE API to populate computed fields
|
||||
exists := r.read(ctx, &plan, &resp.Diagnostics)
|
||||
exists := read(ctx, r.client, &plan, &resp.Diagnostics)
|
||||
if !exists {
|
||||
resp.Diagnostics.AddError("VM does not exist after update", "")
|
||||
}
|
||||
@ -423,7 +423,7 @@ func (r *Resource) ImportState(
|
||||
Timeouts: ts,
|
||||
}
|
||||
|
||||
exists := r.read(ctx, &state, &resp.Diagnostics)
|
||||
exists := read(ctx, r.client, &state, &resp.Diagnostics)
|
||||
if !exists {
|
||||
resp.Diagnostics.AddError(fmt.Sprintf("VM %d does not exist on node %s", id, nodeName), "")
|
||||
}
|
||||
@ -436,48 +436,6 @@ func (r *Resource) ImportState(
|
||||
resp.Diagnostics.Append(diags...)
|
||||
}
|
||||
|
||||
// read retrieves the current state of the resource from the API and updates the state.
|
||||
// Returns false if the resource does not exist, so the caller can remove it from the state if necessary.
|
||||
func (r *Resource) read(ctx context.Context, model *Model, diags *diag.Diagnostics) bool {
|
||||
vmAPI := r.client.Node(model.NodeName.ValueString()).VM(int(model.ID.ValueInt64()))
|
||||
|
||||
// Retrieve the entire configuration in order to compare it to the state.
|
||||
config, err := vmAPI.GetVM(ctx)
|
||||
if err != nil {
|
||||
if errors.Is(err, api.ErrResourceDoesNotExist) {
|
||||
tflog.Info(ctx, "VM does not exist, removing from the state", map[string]interface{}{
|
||||
"vm_id": vmAPI.VMID,
|
||||
})
|
||||
} else {
|
||||
diags.AddError("Failed to get VM", err.Error())
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
status, err := vmAPI.GetVMStatus(ctx)
|
||||
if err != nil {
|
||||
diags.AddError("Failed to get VM status", err.Error())
|
||||
return false
|
||||
}
|
||||
|
||||
if status.VMID == nil {
|
||||
diags.AddError("VM ID is missing in status API response", "")
|
||||
return false
|
||||
}
|
||||
|
||||
model.ID = types.Int64Value(int64(*status.VMID))
|
||||
|
||||
// Optional fields can be removed from the model, use StringPointerValue to handle removal on nil
|
||||
model.Description = types.StringPointerValue(config.Description)
|
||||
model.Name = types.StringPointerValue(config.Name)
|
||||
model.CPU = cpu.NewValue(ctx, config, diags)
|
||||
model.Tags = stringset.NewValue(config.Tags, diags)
|
||||
model.Template = types.BoolPointerValue(config.Template.PointerBool())
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// Shutdown the VM, then wait for it to actually shut down (it may not be shut down immediately if
|
||||
// running in HA mode).
|
||||
func vmShutdown(ctx context.Context, vmAPI *vms.Client) error {
|
@ -50,7 +50,7 @@ func (r *Resource) Schema(
|
||||
},
|
||||
},
|
||||
},
|
||||
"cpu": cpu.Schema(),
|
||||
"cpu": cpu.ResourceSchema(),
|
||||
"description": schema.StringAttribute{
|
||||
Description: "The description of the VM.",
|
||||
Optional: true,
|
||||
@ -79,7 +79,7 @@ func (r *Resource) Schema(
|
||||
Description: "The name of the node where the VM is provisioned.",
|
||||
Required: true,
|
||||
},
|
||||
"tags": stringset.ResourceAttribute("The tags assigned to the resource.", ""),
|
||||
"tags": stringset.ResourceAttribute("The tags assigned to the VM.", ""),
|
||||
"template": schema.BoolAttribute{
|
||||
Description: "Set to true to create a VM template.",
|
||||
Optional: true,
|
@ -1,28 +0,0 @@
|
||||
package vm
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/terraform-plugin-framework-timeouts/resource/timeouts"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
|
||||
"github.com/bpg/terraform-provider-proxmox/fwprovider/types/stringset"
|
||||
"github.com/bpg/terraform-provider-proxmox/fwprovider/vm/cpu"
|
||||
)
|
||||
|
||||
// Model represents the VM model.
|
||||
//
|
||||
// Note: for computed fields / blocks we have to use an Object type (or an alias),
|
||||
// or a custom type in order to hold an unknown value.
|
||||
type Model struct {
|
||||
Description types.String `tfsdk:"description"`
|
||||
CPU cpu.Value `tfsdk:"cpu"`
|
||||
Clone *struct {
|
||||
ID types.Int64 `tfsdk:"id"`
|
||||
Retries types.Int64 `tfsdk:"retries"`
|
||||
} `tfsdk:"clone"`
|
||||
ID types.Int64 `tfsdk:"id"`
|
||||
Name types.String `tfsdk:"name"`
|
||||
NodeName types.String `tfsdk:"node_name"`
|
||||
Tags stringset.Value `tfsdk:"tags"`
|
||||
Template types.Bool `tfsdk:"template"`
|
||||
Timeouts timeouts.Value `tfsdk:"timeouts"`
|
||||
}
|
77
fwprovider/vm/vm_model.go
Normal file
77
fwprovider/vm/vm_model.go
Normal file
@ -0,0 +1,77 @@
|
||||
package vm
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework-timeouts/resource/timeouts"
|
||||
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
|
||||
"github.com/bpg/terraform-provider-proxmox/fwprovider/types/stringset"
|
||||
"github.com/bpg/terraform-provider-proxmox/fwprovider/vm/cpu"
|
||||
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
||||
"github.com/bpg/terraform-provider-proxmox/proxmox/api"
|
||||
)
|
||||
|
||||
// Model represents the VM model.
|
||||
//
|
||||
// Note: for computed fields / blocks we have to use an Object type (or an alias),
|
||||
// or a custom type in order to hold an unknown value.
|
||||
type Model struct {
|
||||
Description types.String `tfsdk:"description"`
|
||||
CPU cpu.Value `tfsdk:"cpu"`
|
||||
Clone *struct {
|
||||
ID types.Int64 `tfsdk:"id"`
|
||||
Retries types.Int64 `tfsdk:"retries"`
|
||||
} `tfsdk:"clone"`
|
||||
ID types.Int64 `tfsdk:"id"`
|
||||
Name types.String `tfsdk:"name"`
|
||||
NodeName types.String `tfsdk:"node_name"`
|
||||
Tags stringset.Value `tfsdk:"tags"`
|
||||
Template types.Bool `tfsdk:"template"`
|
||||
Timeouts timeouts.Value `tfsdk:"timeouts"`
|
||||
}
|
||||
|
||||
// read retrieves the current state of the resource from the API and updates the state.
|
||||
// Returns false if the resource does not exist, so the caller can remove it from the state if necessary.
|
||||
func read(ctx context.Context, client proxmox.Client, model *Model, diags *diag.Diagnostics) bool {
|
||||
vmAPI := client.Node(model.NodeName.ValueString()).VM(int(model.ID.ValueInt64()))
|
||||
|
||||
// Retrieve the entire configuration in order to compare it to the state.
|
||||
config, err := vmAPI.GetVM(ctx)
|
||||
if err != nil {
|
||||
if errors.Is(err, api.ErrResourceDoesNotExist) {
|
||||
tflog.Info(ctx, "VM does not exist, removing from the state", map[string]interface{}{
|
||||
"vm_id": vmAPI.VMID,
|
||||
})
|
||||
} else {
|
||||
diags.AddError("Failed to get VM", err.Error())
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
status, err := vmAPI.GetVMStatus(ctx)
|
||||
if err != nil {
|
||||
diags.AddError("Failed to get VM status", err.Error())
|
||||
return false
|
||||
}
|
||||
|
||||
if status.VMID == nil {
|
||||
diags.AddError("VM ID is missing in status API response", "")
|
||||
return false
|
||||
}
|
||||
|
||||
model.ID = types.Int64Value(int64(*status.VMID))
|
||||
|
||||
// Optional fields can be removed from the model, use StringPointerValue to handle removal on nil
|
||||
model.Description = types.StringPointerValue(config.Description)
|
||||
model.Name = types.StringPointerValue(config.Name)
|
||||
model.CPU = cpu.NewValue(ctx, config, diags)
|
||||
model.Tags = stringset.NewValue(config.Tags, diags)
|
||||
model.Template = types.BoolPointerValue(config.Template.PointerBool())
|
||||
|
||||
return true
|
||||
}
|
21
templates/data-sources/virtual_environment_vm2.md.tmpl
Normal file
21
templates/data-sources/virtual_environment_vm2.md.tmpl
Normal file
@ -0,0 +1,21 @@
|
||||
---
|
||||
layout: page
|
||||
title: {{.Name}}
|
||||
parent: Data Sources
|
||||
subcategory: Virtual Environment
|
||||
description: |-
|
||||
{{ .Description | plainmarkdown | trimspace | prefixlines " " }}
|
||||
---
|
||||
|
||||
# {{.Type}}: {{.Name}}
|
||||
|
||||
!> **DO NOT USE**
|
||||
{{ .Description | trimspace }}
|
||||
|
||||
{{ if .HasExample -}}
|
||||
## Example Usage
|
||||
|
||||
{{ codefile "terraform" .ExampleFile }}
|
||||
{{- end }}
|
||||
|
||||
{{ .SchemaMarkdown | trimspace }}
|
@ -29,7 +29,6 @@ import (
|
||||
// Temporary: while migrating to the TF framework, we need to copy the generated docs to the right place
|
||||
// for the resources / data sources that have been migrated.
|
||||
//go:generate cp -R ../build/docs-gen/guides/ ../docs/guides/
|
||||
//go:generate cp ../build/docs-gen/data-sources/virtual_environment_version.md ../docs/data-sources/
|
||||
//go:generate cp ../build/docs-gen/data-sources/virtual_environment_hagroup.md ../docs/data-sources/
|
||||
//go:generate cp ../build/docs-gen/data-sources/virtual_environment_hagroups.md ../docs/data-sources/
|
||||
//go:generate cp ../build/docs-gen/data-sources/virtual_environment_hardware_mapping_pci.md ../docs/data-sources/
|
||||
@ -37,14 +36,16 @@ import (
|
||||
//go:generate cp ../build/docs-gen/data-sources/virtual_environment_hardware_mappings.md ../docs/data-sources/
|
||||
//go:generate cp ../build/docs-gen/data-sources/virtual_environment_haresource.md ../docs/data-sources/
|
||||
//go:generate cp ../build/docs-gen/data-sources/virtual_environment_haresources.md ../docs/data-sources/
|
||||
//go:generate cp ../build/docs-gen/resources/virtual_environment_network_linux_bridge.md ../docs/resources/
|
||||
//go:generate cp ../build/docs-gen/resources/virtual_environment_network_linux_vlan.md ../docs/resources/
|
||||
//go:generate cp ../build/docs-gen/data-sources/virtual_environment_version.md ../docs/data-sources/
|
||||
//go:generate cp ../build/docs-gen/data-sources/virtual_environment_vm2.md ../docs/data-sources/
|
||||
//go:generate cp ../build/docs-gen/resources/virtual_environment_acl.md ../docs/resources/
|
||||
//go:generate cp ../build/docs-gen/resources/virtual_environment_cluster_options.md ../docs/resources/
|
||||
//go:generate cp ../build/docs-gen/resources/virtual_environment_download_file.md ../docs/resources/
|
||||
//go:generate cp ../build/docs-gen/resources/virtual_environment_hagroup.md ../docs/resources/
|
||||
//go:generate cp ../build/docs-gen/resources/virtual_environment_hardware_mapping_pci.md ../docs/resources/
|
||||
//go:generate cp ../build/docs-gen/resources/virtual_environment_hardware_mapping_usb.md ../docs/resources/
|
||||
//go:generate cp ../build/docs-gen/resources/virtual_environment_haresource.md ../docs/resources/
|
||||
//go:generate cp ../build/docs-gen/resources/virtual_environment_cluster_options.md ../docs/resources/
|
||||
//go:generate cp ../build/docs-gen/resources/virtual_environment_download_file.md ../docs/resources/
|
||||
//go:generate cp ../build/docs-gen/resources/virtual_environment_acl.md ../docs/resources/
|
||||
//go:generate cp ../build/docs-gen/resources/virtual_environment_network_linux_bridge.md ../docs/resources/
|
||||
//go:generate cp ../build/docs-gen/resources/virtual_environment_network_linux_vlan.md ../docs/resources/
|
||||
//go:generate cp ../build/docs-gen/resources/virtual_environment_user_token.md ../docs/resources/
|
||||
//go:generate cp ../build/docs-gen/resources/virtual_environment_vm2.md ../docs/resources/
|
||||
|
Loading…
Reference in New Issue
Block a user