mirror of
https://github.com/bpg/terraform-provider-proxmox.git
synced 2025-08-23 20:08:34 +00:00
misc(vm2): add support for vga
(#1328)
* misc(vm2): add support for `vga` * fix: use random VM IDs in parallel acc tests --------- Signed-off-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com>
This commit is contained in:
parent
e0097d9880
commit
d843e46b37
@ -31,6 +31,7 @@ This is an experimental implementation of a Proxmox VM datasource using Plugin F
|
|||||||
- `tags` (Set of String) The tags assigned to the VM.
|
- `tags` (Set of String) The tags assigned to the VM.
|
||||||
- `template` (Boolean) Whether the VM is a template.
|
- `template` (Boolean) Whether the VM is a template.
|
||||||
- `timeouts` (Attributes) (see [below for nested schema](#nestedatt--timeouts))
|
- `timeouts` (Attributes) (see [below for nested schema](#nestedatt--timeouts))
|
||||||
|
- `vga` (Attributes) The VGA configuration. (see [below for nested schema](#nestedatt--vga))
|
||||||
|
|
||||||
<a id="nestedatt--clone"></a>
|
<a id="nestedatt--clone"></a>
|
||||||
### Nested Schema for `clone`
|
### Nested Schema for `clone`
|
||||||
@ -67,3 +68,13 @@ Optional:
|
|||||||
Optional:
|
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.
|
- `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.
|
||||||
|
|
||||||
|
|
||||||
|
<a id="nestedatt--vga"></a>
|
||||||
|
### Nested Schema for `vga`
|
||||||
|
|
||||||
|
Optional:
|
||||||
|
|
||||||
|
- `clipboard` (String) Enable a specific clipboard.
|
||||||
|
- `memory` (Number) The VGA memory in megabytes (4-512 MB). Has no effect with serial display.
|
||||||
|
- `type` (String) The VGA type.
|
||||||
|
@ -541,9 +541,9 @@ output "ubuntu_vm_public_key" {
|
|||||||
- `serial3` - Serial Terminal 3.
|
- `serial3` - Serial Terminal 3.
|
||||||
- `std` - Standard VGA.
|
- `std` - Standard VGA.
|
||||||
- `virtio` - VirtIO-GPU.
|
- `virtio` - VirtIO-GPU.
|
||||||
- `virtio-gl` - VirtIO-GPU with 3D acceleration (VirGL). VirGL support needs some extra libraries that aren’t installed by default. See the [Proxmox documentation](https://pve.proxmox.com/pve-docs/pve-admin-guide.html#qm_virtual_machines_settings) section 10.2.8.for more information.
|
- `virtio-gl` - VirtIO-GPU with 3D acceleration (VirGL). VirGL support needs some extra libraries that aren’t installed by default. See the [Proxmox documentation](https://pve.proxmox.com/pve-docs/pve-admin-guide.html#qm_virtual_machines_settings) section 10.2.8 for more information.
|
||||||
- `vmware` - VMware Compatible.
|
- `vmware` - VMware Compatible.
|
||||||
- `clipboard` - (Optional) Enable VNC clipboard by setting to `vnc`. See the [Proxmox documentation](https://pve.proxmox.com/pve-docs/pve-admin-guide.html#qm_virtual_machines_settings) section 10.2.8.for more information.
|
- `clipboard` - (Optional) Enable VNC clipboard by setting to `vnc`. See the [Proxmox documentation](https://pve.proxmox.com/pve-docs/pve-admin-guide.html#qm_virtual_machines_settings) section 10.2.8 for more information.
|
||||||
- `vm_id` - (Optional) The VM identifier.
|
- `vm_id` - (Optional) The VM identifier.
|
||||||
- `hook_script_file_id` - (Optional) The identifier for a file containing a hook script (needs to be executable).
|
- `hook_script_file_id` - (Optional) The identifier for a file containing a hook script (needs to be executable).
|
||||||
|
|
||||||
|
@ -38,6 +38,7 @@ The attributes are also marked as optional to allow the practitioner to set (or
|
|||||||
- `tags` (Set of String) The tags assigned to the VM.
|
- `tags` (Set of String) The tags assigned to the VM.
|
||||||
- `template` (Boolean) Set to true to create a VM template.
|
- `template` (Boolean) Set to true to create a VM template.
|
||||||
- `timeouts` (Attributes) (see [below for nested schema](#nestedatt--timeouts))
|
- `timeouts` (Attributes) (see [below for nested schema](#nestedatt--timeouts))
|
||||||
|
- `vga` (Attributes) Configure the VGA Hardware. If you want to use high resolution modes (>= 1280x1024x16) you may need to increase the vga memory option. Since QEMU 2.9 the default VGA display type is `std` for all OS types besides some Windows versions (XP and older) which use `cirrus`. The `qxl` option enables the SPICE display server. For win* OS you can select how many independent displays you want, Linux guests can add displays themself. You can also run without any graphic card, using a serial device as terminal. See the [Proxmox documentation](https://pve.proxmox.com/pve-docs/pve-admin-guide.html#qm_virtual_machines_settings) section 10.2.8 for more information and available configuration parameters. (see [below for nested schema](#nestedatt--vga))
|
||||||
|
|
||||||
<a id="nestedatt--clone"></a>
|
<a id="nestedatt--clone"></a>
|
||||||
### Nested Schema for `clone`
|
### Nested Schema for `clone`
|
||||||
@ -77,3 +78,13 @@ Optional:
|
|||||||
- `delete` (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). Setting a timeout for a Delete operation is only applicable if changes are saved into state before the destroy operation occurs.
|
- `delete` (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). Setting a timeout for a Delete operation is only applicable if changes are saved into state before the destroy operation occurs.
|
||||||
- `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.
|
- `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.
|
||||||
- `update` (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).
|
- `update` (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).
|
||||||
|
|
||||||
|
|
||||||
|
<a id="nestedatt--vga"></a>
|
||||||
|
### Nested Schema for `vga`
|
||||||
|
|
||||||
|
Optional:
|
||||||
|
|
||||||
|
- `clipboard` (String) Enable a specific clipboard. If not set, depending on the display type the SPICE one will be added. Currently only `vnc` is available. Migration with VNC clipboard is not supported by Proxmox.
|
||||||
|
- `memory` (Number) The VGA memory in megabytes (4-512 MB). Has no effect with serial display.
|
||||||
|
- `type` (String) The VGA type (defaults to `std`).
|
||||||
|
@ -18,7 +18,7 @@ import (
|
|||||||
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
|
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
|
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
|
||||||
|
|
||||||
"github.com/bpg/terraform-provider-proxmox/fwprovider/structure"
|
"github.com/bpg/terraform-provider-proxmox/fwprovider/attribute"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox/helpers/ptr"
|
"github.com/bpg/terraform-provider-proxmox/proxmox/helpers/ptr"
|
||||||
proxmoxtypes "github.com/bpg/terraform-provider-proxmox/proxmox/types"
|
proxmoxtypes "github.com/bpg/terraform-provider-proxmox/proxmox/types"
|
||||||
@ -54,7 +54,7 @@ func (r *aclResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *
|
|||||||
stringplanmodifier.RequiresReplace(),
|
stringplanmodifier.RequiresReplace(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"id": structure.IDAttribute(),
|
"id": attribute.ID(),
|
||||||
"path": schema.StringAttribute{
|
"path": schema.StringAttribute{
|
||||||
Description: "Access control path",
|
Description: "Access control path",
|
||||||
Required: true,
|
Required: true,
|
||||||
|
@ -16,7 +16,7 @@ import (
|
|||||||
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
|
|
||||||
"github.com/bpg/terraform-provider-proxmox/fwprovider/structure"
|
"github.com/bpg/terraform-provider-proxmox/fwprovider/attribute"
|
||||||
"github.com/bpg/terraform-provider-proxmox/fwprovider/validators"
|
"github.com/bpg/terraform-provider-proxmox/fwprovider/validators"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox/access"
|
"github.com/bpg/terraform-provider-proxmox/proxmox/access"
|
||||||
@ -69,7 +69,7 @@ func (r *userTokenResource) Schema(
|
|||||||
}, "must be a valid RFC3339 date"),
|
}, "must be a valid RFC3339 date"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"id": structure.IDAttribute("Unique token identifier with format `<user_id>!<token_name>`."),
|
"id": attribute.ID("Unique token identifier with format `<user_id>!<token_name>`."),
|
||||||
"privileges_separation": schema.BoolAttribute{
|
"privileges_separation": schema.BoolAttribute{
|
||||||
Description: "Restrict API token privileges with separate ACLs (default)",
|
Description: "Restrict API token privileges with separate ACLs (default)",
|
||||||
MarkdownDescription: "Restrict API token privileges with separate ACLs (default), " +
|
MarkdownDescription: "Restrict API token privileges with separate ACLs (default), " +
|
||||||
|
@ -4,17 +4,18 @@
|
|||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package structure
|
package attribute
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/attr"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
|
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
|
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
|
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
|
||||||
)
|
)
|
||||||
|
|
||||||
// IDAttribute generates an attribute definition suitable for the always-present `id` attribute.
|
// ID generates an attribute definition suitable for the always-present `id` attribute.
|
||||||
func IDAttribute(desc ...string) schema.StringAttribute {
|
func ID(desc ...string) schema.StringAttribute {
|
||||||
attr := schema.StringAttribute{
|
a := schema.StringAttribute{
|
||||||
Computed: true,
|
Computed: true,
|
||||||
Description: "The unique identifier of this resource.",
|
Description: "The unique identifier of this resource.",
|
||||||
PlanModifiers: []planmodifier.String{
|
PlanModifiers: []planmodifier.String{
|
||||||
@ -23,8 +24,18 @@ func IDAttribute(desc ...string) schema.StringAttribute {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(desc) > 0 {
|
if len(desc) > 0 {
|
||||||
attr.Description = desc[0]
|
a.Description = desc[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
return attr
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShouldBeRemoved evaluates if an attribute should be removed from the plan during update.
|
||||||
|
func ShouldBeRemoved(plan attr.Value, state attr.Value, isClone bool) bool {
|
||||||
|
return !IsDefined(plan) && IsDefined(state) && !isClone
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsDefined returns true if attribute is known and not null.
|
||||||
|
func IsDefined(v attr.Value) bool {
|
||||||
|
return !v.IsNull() && !v.IsUnknown()
|
||||||
}
|
}
|
@ -14,7 +14,7 @@ import (
|
|||||||
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
|
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
|
|
||||||
"github.com/bpg/terraform-provider-proxmox/fwprovider/structure"
|
"github.com/bpg/terraform-provider-proxmox/fwprovider/attribute"
|
||||||
|
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
||||||
hagroups "github.com/bpg/terraform-provider-proxmox/proxmox/cluster/ha/groups"
|
hagroups "github.com/bpg/terraform-provider-proxmox/proxmox/cluster/ha/groups"
|
||||||
@ -51,7 +51,7 @@ func (d *haGroupDatasource) Schema(_ context.Context, _ datasource.SchemaRequest
|
|||||||
resp.Schema = schema.Schema{
|
resp.Schema = schema.Schema{
|
||||||
Description: "Retrieves information about a specific High Availability group.",
|
Description: "Retrieves information about a specific High Availability group.",
|
||||||
Attributes: map[string]schema.Attribute{
|
Attributes: map[string]schema.Attribute{
|
||||||
"id": structure.IDAttribute(),
|
"id": attribute.ID(),
|
||||||
"group": schema.StringAttribute{
|
"group": schema.StringAttribute{
|
||||||
Description: "The identifier of the High Availability group to read.",
|
Description: "The identifier of the High Availability group to read.",
|
||||||
Required: true,
|
Required: true,
|
||||||
|
@ -15,7 +15,7 @@ import (
|
|||||||
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
|
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
|
|
||||||
"github.com/bpg/terraform-provider-proxmox/fwprovider/structure"
|
"github.com/bpg/terraform-provider-proxmox/fwprovider/attribute"
|
||||||
|
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
||||||
hagroups "github.com/bpg/terraform-provider-proxmox/proxmox/cluster/ha/groups"
|
hagroups "github.com/bpg/terraform-provider-proxmox/proxmox/cluster/ha/groups"
|
||||||
@ -57,7 +57,7 @@ func (d *haGroupsDatasource) Schema(_ context.Context, _ datasource.SchemaReques
|
|||||||
resp.Schema = schema.Schema{
|
resp.Schema = schema.Schema{
|
||||||
Description: "Retrieves the list of High Availability groups.",
|
Description: "Retrieves the list of High Availability groups.",
|
||||||
Attributes: map[string]schema.Attribute{
|
Attributes: map[string]schema.Attribute{
|
||||||
"id": structure.IDAttribute(),
|
"id": attribute.ID(),
|
||||||
"group_ids": schema.SetAttribute{
|
"group_ids": schema.SetAttribute{
|
||||||
Description: "The identifiers of the High Availability groups.",
|
Description: "The identifiers of the High Availability groups.",
|
||||||
ElementType: types.StringType,
|
ElementType: types.StringType,
|
||||||
|
@ -14,7 +14,7 @@ import (
|
|||||||
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
|
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||||
|
|
||||||
"github.com/bpg/terraform-provider-proxmox/fwprovider/structure"
|
"github.com/bpg/terraform-provider-proxmox/fwprovider/attribute"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
||||||
haresources "github.com/bpg/terraform-provider-proxmox/proxmox/cluster/ha/resources"
|
haresources "github.com/bpg/terraform-provider-proxmox/proxmox/cluster/ha/resources"
|
||||||
proxmoxtypes "github.com/bpg/terraform-provider-proxmox/proxmox/types"
|
proxmoxtypes "github.com/bpg/terraform-provider-proxmox/proxmox/types"
|
||||||
@ -50,7 +50,7 @@ func (d *haResourceDatasource) Schema(_ context.Context, _ datasource.SchemaRequ
|
|||||||
resp.Schema = schema.Schema{
|
resp.Schema = schema.Schema{
|
||||||
Description: "Retrieves the list of High Availability resources.",
|
Description: "Retrieves the list of High Availability resources.",
|
||||||
Attributes: map[string]schema.Attribute{
|
Attributes: map[string]schema.Attribute{
|
||||||
"id": structure.IDAttribute(),
|
"id": attribute.ID(),
|
||||||
"resource_id": schema.StringAttribute{
|
"resource_id": schema.StringAttribute{
|
||||||
Description: "The identifier of the Proxmox HA resource to read.",
|
Description: "The identifier of the Proxmox HA resource to read.",
|
||||||
Required: true,
|
Required: true,
|
||||||
|
@ -17,7 +17,7 @@ import (
|
|||||||
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
|
|
||||||
"github.com/bpg/terraform-provider-proxmox/fwprovider/structure"
|
"github.com/bpg/terraform-provider-proxmox/fwprovider/attribute"
|
||||||
|
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
||||||
haresources "github.com/bpg/terraform-provider-proxmox/proxmox/cluster/ha/resources"
|
haresources "github.com/bpg/terraform-provider-proxmox/proxmox/cluster/ha/resources"
|
||||||
@ -64,7 +64,7 @@ func (d *haResourcesDatasource) Schema(_ context.Context, _ datasource.SchemaReq
|
|||||||
resp.Schema = schema.Schema{
|
resp.Schema = schema.Schema{
|
||||||
Description: "Retrieves the list of High Availability resources.",
|
Description: "Retrieves the list of High Availability resources.",
|
||||||
Attributes: map[string]schema.Attribute{
|
Attributes: map[string]schema.Attribute{
|
||||||
"id": structure.IDAttribute(),
|
"id": attribute.ID(),
|
||||||
"type": schema.StringAttribute{
|
"type": schema.StringAttribute{
|
||||||
Description: "The type of High Availability resources to fetch (`vm` or `ct`). All resources " +
|
Description: "The type of High Availability resources to fetch (`vm` or `ct`). All resources " +
|
||||||
"will be fetched if this option is unset.",
|
"will be fetched if this option is unset.",
|
||||||
|
@ -23,7 +23,7 @@ import (
|
|||||||
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
|
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
|
|
||||||
"github.com/bpg/terraform-provider-proxmox/fwprovider/structure"
|
"github.com/bpg/terraform-provider-proxmox/fwprovider/attribute"
|
||||||
|
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
||||||
hagroups "github.com/bpg/terraform-provider-proxmox/proxmox/cluster/ha/groups"
|
hagroups "github.com/bpg/terraform-provider-proxmox/proxmox/cluster/ha/groups"
|
||||||
@ -64,7 +64,7 @@ func (r *hagroupResource) Schema(
|
|||||||
resp.Schema = schema.Schema{
|
resp.Schema = schema.Schema{
|
||||||
Description: "Manages a High Availability group in a Proxmox VE cluster.",
|
Description: "Manages a High Availability group in a Proxmox VE cluster.",
|
||||||
Attributes: map[string]schema.Attribute{
|
Attributes: map[string]schema.Attribute{
|
||||||
"id": structure.IDAttribute(),
|
"id": attribute.ID(),
|
||||||
"group": schema.StringAttribute{
|
"group": schema.StringAttribute{
|
||||||
Description: "The identifier of the High Availability group to manage.",
|
Description: "The identifier of the High Availability group to manage.",
|
||||||
Required: true,
|
Required: true,
|
||||||
|
@ -12,7 +12,7 @@ import (
|
|||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/bpg/terraform-provider-proxmox/fwprovider/structure"
|
"github.com/bpg/terraform-provider-proxmox/fwprovider/attribute"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
||||||
haresources "github.com/bpg/terraform-provider-proxmox/proxmox/cluster/ha/resources"
|
haresources "github.com/bpg/terraform-provider-proxmox/proxmox/cluster/ha/resources"
|
||||||
proxmoxtypes "github.com/bpg/terraform-provider-proxmox/proxmox/types"
|
proxmoxtypes "github.com/bpg/terraform-provider-proxmox/proxmox/types"
|
||||||
@ -68,7 +68,7 @@ func (r *haResourceResource) Schema(
|
|||||||
resp.Schema = schema.Schema{
|
resp.Schema = schema.Schema{
|
||||||
Description: "Manages Proxmox HA resources.",
|
Description: "Manages Proxmox HA resources.",
|
||||||
Attributes: map[string]schema.Attribute{
|
Attributes: map[string]schema.Attribute{
|
||||||
"id": structure.IDAttribute(),
|
"id": attribute.ID(),
|
||||||
"resource_id": schema.StringAttribute{
|
"resource_id": schema.StringAttribute{
|
||||||
Description: "The Proxmox HA resource identifier",
|
Description: "The Proxmox HA resource identifier",
|
||||||
Required: true,
|
Required: true,
|
||||||
|
@ -19,7 +19,7 @@ import (
|
|||||||
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
|
|
||||||
"github.com/bpg/terraform-provider-proxmox/fwprovider/structure"
|
"github.com/bpg/terraform-provider-proxmox/fwprovider/attribute"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox/cluster/mapping"
|
"github.com/bpg/terraform-provider-proxmox/proxmox/cluster/mapping"
|
||||||
proxmoxtypes "github.com/bpg/terraform-provider-proxmox/proxmox/types/hardwaremapping"
|
proxmoxtypes "github.com/bpg/terraform-provider-proxmox/proxmox/types/hardwaremapping"
|
||||||
@ -179,7 +179,7 @@ func (d *dataSource) Schema(
|
|||||||
Computed: true,
|
Computed: true,
|
||||||
Description: "The identifiers of the hardware mappings.",
|
Description: "The identifiers of the hardware mappings.",
|
||||||
},
|
},
|
||||||
schemaAttrNameTerraformID: structure.IDAttribute(
|
schemaAttrNameTerraformID: attribute.ID(
|
||||||
"The unique identifier of this hardware mappings data source.",
|
"The unique identifier of this hardware mappings data source.",
|
||||||
),
|
),
|
||||||
schemaAttrNameType: schema.StringAttribute{
|
schemaAttrNameType: schema.StringAttribute{
|
||||||
|
@ -15,7 +15,7 @@ import (
|
|||||||
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
|
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||||
|
|
||||||
"github.com/bpg/terraform-provider-proxmox/fwprovider/structure"
|
"github.com/bpg/terraform-provider-proxmox/fwprovider/attribute"
|
||||||
customtypes "github.com/bpg/terraform-provider-proxmox/fwprovider/types/hardwaremapping"
|
customtypes "github.com/bpg/terraform-provider-proxmox/fwprovider/types/hardwaremapping"
|
||||||
"github.com/bpg/terraform-provider-proxmox/fwprovider/validators"
|
"github.com/bpg/terraform-provider-proxmox/fwprovider/validators"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
||||||
@ -155,7 +155,7 @@ func (d *dataSourcePCI) Schema(_ context.Context, _ datasource.SchemaRequest, re
|
|||||||
Description: "The name of this PCI hardware mapping.",
|
Description: "The name of this PCI hardware mapping.",
|
||||||
Required: true,
|
Required: true,
|
||||||
},
|
},
|
||||||
schemaAttrNameTerraformID: structure.IDAttribute(
|
schemaAttrNameTerraformID: attribute.ID(
|
||||||
"The unique identifier of this PCI hardware mapping data source.",
|
"The unique identifier of this PCI hardware mapping data source.",
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
@ -15,7 +15,7 @@ import (
|
|||||||
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
|
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||||
|
|
||||||
"github.com/bpg/terraform-provider-proxmox/fwprovider/structure"
|
"github.com/bpg/terraform-provider-proxmox/fwprovider/attribute"
|
||||||
customtypes "github.com/bpg/terraform-provider-proxmox/fwprovider/types/hardwaremapping"
|
customtypes "github.com/bpg/terraform-provider-proxmox/fwprovider/types/hardwaremapping"
|
||||||
"github.com/bpg/terraform-provider-proxmox/fwprovider/validators"
|
"github.com/bpg/terraform-provider-proxmox/fwprovider/validators"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
||||||
@ -137,7 +137,7 @@ func (d *datasourceUSB) Schema(_ context.Context, _ datasource.SchemaRequest, re
|
|||||||
Description: "The name of this USB hardware mapping.",
|
Description: "The name of this USB hardware mapping.",
|
||||||
Required: true,
|
Required: true,
|
||||||
},
|
},
|
||||||
schemaAttrNameTerraformID: structure.IDAttribute(
|
schemaAttrNameTerraformID: attribute.ID(
|
||||||
"The unique identifier of this USB hardware mapping data source.",
|
"The unique identifier of this USB hardware mapping data source.",
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
@ -22,7 +22,7 @@ import (
|
|||||||
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
|
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
|
|
||||||
"github.com/bpg/terraform-provider-proxmox/fwprovider/structure"
|
"github.com/bpg/terraform-provider-proxmox/fwprovider/attribute"
|
||||||
customtypes "github.com/bpg/terraform-provider-proxmox/fwprovider/types/hardwaremapping"
|
customtypes "github.com/bpg/terraform-provider-proxmox/fwprovider/types/hardwaremapping"
|
||||||
"github.com/bpg/terraform-provider-proxmox/fwprovider/validators"
|
"github.com/bpg/terraform-provider-proxmox/fwprovider/validators"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
||||||
@ -264,7 +264,7 @@ func (r *resourcePCI) Schema(_ context.Context, _ resource.SchemaRequest, resp *
|
|||||||
Description: "The name of this PCI hardware mapping.",
|
Description: "The name of this PCI hardware mapping.",
|
||||||
Required: true,
|
Required: true,
|
||||||
},
|
},
|
||||||
schemaAttrNameTerraformID: structure.IDAttribute(
|
schemaAttrNameTerraformID: attribute.ID(
|
||||||
"The unique identifier of this PCI hardware mapping resource.",
|
"The unique identifier of this PCI hardware mapping resource.",
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
@ -21,7 +21,7 @@ import (
|
|||||||
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
|
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
|
|
||||||
"github.com/bpg/terraform-provider-proxmox/fwprovider/structure"
|
"github.com/bpg/terraform-provider-proxmox/fwprovider/attribute"
|
||||||
customtypes "github.com/bpg/terraform-provider-proxmox/fwprovider/types/hardwaremapping"
|
customtypes "github.com/bpg/terraform-provider-proxmox/fwprovider/types/hardwaremapping"
|
||||||
"github.com/bpg/terraform-provider-proxmox/fwprovider/validators"
|
"github.com/bpg/terraform-provider-proxmox/fwprovider/validators"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
||||||
@ -249,7 +249,7 @@ func (r *resourceUSB) Schema(_ context.Context, _ resource.SchemaRequest, resp *
|
|||||||
Description: "The name of this hardware mapping.",
|
Description: "The name of this hardware mapping.",
|
||||||
Required: true,
|
Required: true,
|
||||||
},
|
},
|
||||||
schemaAttrNameTerraformID: structure.IDAttribute(
|
schemaAttrNameTerraformID: attribute.ID(
|
||||||
"The unique identifier of this USB hardware mapping resource.",
|
"The unique identifier of this USB hardware mapping resource.",
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
@ -24,7 +24,7 @@ import (
|
|||||||
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
|
|
||||||
"github.com/bpg/terraform-provider-proxmox/fwprovider/structure"
|
"github.com/bpg/terraform-provider-proxmox/fwprovider/attribute"
|
||||||
customtypes "github.com/bpg/terraform-provider-proxmox/fwprovider/types"
|
customtypes "github.com/bpg/terraform-provider-proxmox/fwprovider/types"
|
||||||
|
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
||||||
@ -173,7 +173,7 @@ func (r *linuxBridgeResource) Schema(
|
|||||||
Description: "Manages a Linux Bridge network interface in a Proxmox VE node.",
|
Description: "Manages a Linux Bridge network interface in a Proxmox VE node.",
|
||||||
Attributes: map[string]schema.Attribute{
|
Attributes: map[string]schema.Attribute{
|
||||||
// Base attributes
|
// Base attributes
|
||||||
"id": structure.IDAttribute("A unique identifier with format `<node name>:<iface>`"),
|
"id": attribute.ID("A unique identifier with format `<node name>:<iface>`"),
|
||||||
"node_name": schema.StringAttribute{
|
"node_name": schema.StringAttribute{
|
||||||
Description: "The name of the node.",
|
Description: "The name of the node.",
|
||||||
Required: true,
|
Required: true,
|
||||||
|
@ -22,7 +22,7 @@ import (
|
|||||||
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
|
|
||||||
"github.com/bpg/terraform-provider-proxmox/fwprovider/structure"
|
"github.com/bpg/terraform-provider-proxmox/fwprovider/attribute"
|
||||||
customtypes "github.com/bpg/terraform-provider-proxmox/fwprovider/types"
|
customtypes "github.com/bpg/terraform-provider-proxmox/fwprovider/types"
|
||||||
|
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
||||||
@ -146,7 +146,7 @@ func (r *linuxVLANResource) Schema(
|
|||||||
Description: "Manages a Linux VLAN network interface in a Proxmox VE node.",
|
Description: "Manages a Linux VLAN network interface in a Proxmox VE node.",
|
||||||
Attributes: map[string]schema.Attribute{
|
Attributes: map[string]schema.Attribute{
|
||||||
// Base attributes
|
// Base attributes
|
||||||
"id": structure.IDAttribute("A unique identifier with format `<node name>:<iface>`."),
|
"id": attribute.ID("A unique identifier with format `<node name>:<iface>`."),
|
||||||
"node_name": schema.StringAttribute{
|
"node_name": schema.StringAttribute{
|
||||||
Description: "The name of the node.",
|
Description: "The name of the node.",
|
||||||
Required: true,
|
Required: true,
|
||||||
|
@ -27,7 +27,7 @@ import (
|
|||||||
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
|
|
||||||
"github.com/bpg/terraform-provider-proxmox/fwprovider/structure"
|
"github.com/bpg/terraform-provider-proxmox/fwprovider/attribute"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox/api"
|
"github.com/bpg/terraform-provider-proxmox/proxmox/api"
|
||||||
|
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
||||||
@ -193,7 +193,7 @@ func (r *downloadFileResource) Schema(
|
|||||||
"It can be fully compatible and faster replacement for image files created using " +
|
"It can be fully compatible and faster replacement for image files created using " +
|
||||||
"`proxmox_virtual_environment_file`. Supports images for VMs (ISO images) and LXC (CT Templates).",
|
"`proxmox_virtual_environment_file`. Supports images for VMs (ISO images) and LXC (CT Templates).",
|
||||||
Attributes: map[string]schema.Attribute{
|
Attributes: map[string]schema.Attribute{
|
||||||
"id": structure.IDAttribute(),
|
"id": attribute.ID(),
|
||||||
"content_type": schema.StringAttribute{
|
"content_type": schema.StringAttribute{
|
||||||
Description: "The file content type. Must be `iso` for VM images or `vztmpl` for LXC images.",
|
Description: "The file content type. Must be `iso` for VM images or `vztmpl` for LXC images.",
|
||||||
Required: true,
|
Required: true,
|
||||||
|
@ -21,7 +21,7 @@ import (
|
|||||||
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
|
|
||||||
"github.com/bpg/terraform-provider-proxmox/fwprovider/structure"
|
"github.com/bpg/terraform-provider-proxmox/fwprovider/attribute"
|
||||||
"github.com/bpg/terraform-provider-proxmox/fwprovider/validators"
|
"github.com/bpg/terraform-provider-proxmox/fwprovider/validators"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox/cluster"
|
"github.com/bpg/terraform-provider-proxmox/proxmox/cluster"
|
||||||
@ -456,7 +456,7 @@ func (r *clusterOptionsResource) Schema(
|
|||||||
resp.Schema = schema.Schema{
|
resp.Schema = schema.Schema{
|
||||||
Description: "Manages Proxmox VE Cluster Datacenter options.",
|
Description: "Manages Proxmox VE Cluster Datacenter options.",
|
||||||
Attributes: map[string]schema.Attribute{
|
Attributes: map[string]schema.Attribute{
|
||||||
"id": structure.IDAttribute(),
|
"id": attribute.ID(),
|
||||||
"email_from": schema.StringAttribute{
|
"email_from": schema.StringAttribute{
|
||||||
Description: "email address to send notification from (default is root@$hostname).",
|
Description: "email address to send notification from (default is root@$hostname).",
|
||||||
Optional: true,
|
Optional: true,
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
|
"github.com/brianvoe/gofakeit/v7"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/providerserver"
|
"github.com/hashicorp/terraform-plugin-framework/providerserver"
|
||||||
"github.com/hashicorp/terraform-plugin-go/tfprotov5"
|
"github.com/hashicorp/terraform-plugin-go/tfprotov5"
|
||||||
"github.com/hashicorp/terraform-plugin-go/tfprotov6"
|
"github.com/hashicorp/terraform-plugin-go/tfprotov6"
|
||||||
@ -105,6 +106,10 @@ func (e *Environment) RenderConfig(cfg string) string {
|
|||||||
tmpl, err := template.New("config").Parse("{{.ProviderConfig}}" + cfg)
|
tmpl, err := template.New("config").Parse("{{.ProviderConfig}}" + cfg)
|
||||||
require.NoError(e.t, err)
|
require.NoError(e.t, err)
|
||||||
|
|
||||||
|
e.templateVars["RandomVMID"] = gofakeit.IntRange(100_000, 1_000_000)
|
||||||
|
e.templateVars["RandomVMID1"] = gofakeit.IntRange(100_000, 1_000_000)
|
||||||
|
e.templateVars["RandomVMID2"] = gofakeit.IntRange(100_000, 1_000_000)
|
||||||
|
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
err = tmpl.Execute(&buf, e.templateVars)
|
err = tmpl.Execute(&buf, e.templateVars)
|
||||||
require.NoError(e.t, err)
|
require.NoError(e.t, err)
|
||||||
|
@ -4,11 +4,11 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-framework/attr"
|
|
||||||
"github.com/hashicorp/terraform-plugin-framework/diag"
|
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
|
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
|
||||||
|
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/fwprovider/attribute"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox/nodes/vms"
|
"github.com/bpg/terraform-provider-proxmox/proxmox/nodes/vms"
|
||||||
proxmoxtypes "github.com/bpg/terraform-provider-proxmox/proxmox/types"
|
proxmoxtypes "github.com/bpg/terraform-provider-proxmox/proxmox/types"
|
||||||
)
|
)
|
||||||
@ -153,65 +153,65 @@ func FillUpdateBody(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !plan.Affinity.Equal(state.Affinity) {
|
if !plan.Affinity.Equal(state.Affinity) {
|
||||||
if shouldBeRemoved(plan.Affinity, state.Affinity, isClone) {
|
if attribute.ShouldBeRemoved(plan.Affinity, state.Affinity, isClone) {
|
||||||
del("CPUAffinity")
|
del("CPUAffinity")
|
||||||
} else if isDefined(plan.Affinity) {
|
} else if attribute.IsDefined(plan.Affinity) {
|
||||||
updateBody.CPUAffinity = plan.Affinity.ValueStringPointer()
|
updateBody.CPUAffinity = plan.Affinity.ValueStringPointer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !plan.Architecture.Equal(state.Architecture) {
|
if !plan.Architecture.Equal(state.Architecture) {
|
||||||
if shouldBeRemoved(plan.Architecture, state.Architecture, isClone) {
|
if attribute.ShouldBeRemoved(plan.Architecture, state.Architecture, isClone) {
|
||||||
del("CPUArchitecture")
|
del("CPUArchitecture")
|
||||||
} else if isDefined(plan.Architecture) {
|
} else if attribute.IsDefined(plan.Architecture) {
|
||||||
updateBody.CPUArchitecture = plan.Architecture.ValueStringPointer()
|
updateBody.CPUArchitecture = plan.Architecture.ValueStringPointer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !plan.Cores.Equal(state.Cores) {
|
if !plan.Cores.Equal(state.Cores) {
|
||||||
if shouldBeRemoved(plan.Cores, state.Cores, isClone) {
|
if attribute.ShouldBeRemoved(plan.Cores, state.Cores, isClone) {
|
||||||
del("CPUCores")
|
del("CPUCores")
|
||||||
} else if isDefined(plan.Cores) {
|
} else if attribute.IsDefined(plan.Cores) {
|
||||||
updateBody.CPUCores = plan.Cores.ValueInt64Pointer()
|
updateBody.CPUCores = plan.Cores.ValueInt64Pointer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !plan.Limit.Equal(state.Limit) {
|
if !plan.Limit.Equal(state.Limit) {
|
||||||
if shouldBeRemoved(plan.Limit, state.Limit, isClone) {
|
if attribute.ShouldBeRemoved(plan.Limit, state.Limit, isClone) {
|
||||||
del("CPULimit")
|
del("CPULimit")
|
||||||
} else if isDefined(plan.Sockets) {
|
} else if attribute.IsDefined(plan.Sockets) {
|
||||||
updateBody.CPULimit = plan.Limit.ValueInt64Pointer()
|
updateBody.CPULimit = plan.Limit.ValueInt64Pointer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !plan.Sockets.Equal(state.Sockets) {
|
if !plan.Sockets.Equal(state.Sockets) {
|
||||||
if shouldBeRemoved(plan.Sockets, state.Sockets, isClone) {
|
if attribute.ShouldBeRemoved(plan.Sockets, state.Sockets, isClone) {
|
||||||
del("CPUSockets")
|
del("CPUSockets")
|
||||||
} else if isDefined(plan.Sockets) {
|
} else if attribute.IsDefined(plan.Sockets) {
|
||||||
updateBody.CPUSockets = plan.Sockets.ValueInt64Pointer()
|
updateBody.CPUSockets = plan.Sockets.ValueInt64Pointer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !plan.Units.Equal(state.Units) {
|
if !plan.Units.Equal(state.Units) {
|
||||||
if shouldBeRemoved(plan.Units, state.Units, isClone) {
|
if attribute.ShouldBeRemoved(plan.Units, state.Units, isClone) {
|
||||||
del("CPUUnits")
|
del("CPUUnits")
|
||||||
} else if isDefined(plan.Units) {
|
} else if attribute.IsDefined(plan.Units) {
|
||||||
updateBody.CPUUnits = plan.Units.ValueInt64Pointer()
|
updateBody.CPUUnits = plan.Units.ValueInt64Pointer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !plan.Numa.Equal(state.Numa) {
|
if !plan.Numa.Equal(state.Numa) {
|
||||||
if shouldBeRemoved(plan.Numa, state.Numa, isClone) {
|
if attribute.ShouldBeRemoved(plan.Numa, state.Numa, isClone) {
|
||||||
del("NUMAEnabled")
|
del("NUMAEnabled")
|
||||||
} else if isDefined(plan.Numa) {
|
} else if attribute.IsDefined(plan.Numa) {
|
||||||
updateBody.NUMAEnabled = proxmoxtypes.CustomBoolPtr(plan.Numa.ValueBoolPointer())
|
updateBody.NUMAEnabled = proxmoxtypes.CustomBoolPtr(plan.Numa.ValueBoolPointer())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !plan.Hotplugged.Equal(state.Hotplugged) {
|
if !plan.Hotplugged.Equal(state.Hotplugged) {
|
||||||
if shouldBeRemoved(plan.Hotplugged, state.Hotplugged, isClone) {
|
if attribute.ShouldBeRemoved(plan.Hotplugged, state.Hotplugged, isClone) {
|
||||||
del("VirtualCPUCount")
|
del("VirtualCPUCount")
|
||||||
} else if isDefined(plan.Hotplugged) {
|
} else if attribute.IsDefined(plan.Hotplugged) {
|
||||||
updateBody.VirtualCPUCount = plan.Hotplugged.ValueInt64Pointer()
|
updateBody.VirtualCPUCount = plan.Hotplugged.ValueInt64Pointer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -221,17 +221,17 @@ func FillUpdateBody(
|
|||||||
cpuEmulation := &vms.CustomCPUEmulation{}
|
cpuEmulation := &vms.CustomCPUEmulation{}
|
||||||
|
|
||||||
if !plan.Type.Equal(state.Type) {
|
if !plan.Type.Equal(state.Type) {
|
||||||
if shouldBeRemoved(plan.Type, state.Type, isClone) {
|
if attribute.ShouldBeRemoved(plan.Type, state.Type, isClone) {
|
||||||
delType = true
|
delType = true
|
||||||
} else if isDefined(plan.Type) {
|
} else if attribute.IsDefined(plan.Type) {
|
||||||
cpuEmulation.Type = plan.Type.ValueString()
|
cpuEmulation.Type = plan.Type.ValueString()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !plan.Flags.Equal(state.Flags) {
|
if !plan.Flags.Equal(state.Flags) {
|
||||||
if shouldBeRemoved(plan.Flags, state.Flags, isClone) {
|
if attribute.ShouldBeRemoved(plan.Flags, state.Flags, isClone) {
|
||||||
delFlags = true
|
delFlags = true
|
||||||
} else if isDefined(plan.Flags) {
|
} else if attribute.IsDefined(plan.Flags) {
|
||||||
d = plan.Flags.ElementsAs(ctx, &cpuEmulation.Flags, false)
|
d = plan.Flags.ElementsAs(ctx, &cpuEmulation.Flags, false)
|
||||||
diags.Append(d...)
|
diags.Append(d...)
|
||||||
}
|
}
|
||||||
@ -246,11 +246,3 @@ func FillUpdateBody(
|
|||||||
updateBody.CPUEmulation = cpuEmulation
|
updateBody.CPUEmulation = cpuEmulation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func shouldBeRemoved(plan attr.Value, state attr.Value, isClone bool) bool {
|
|
||||||
return !isDefined(plan) && isDefined(state) && !isClone
|
|
||||||
}
|
|
||||||
|
|
||||||
func isDefined(v attr.Value) bool {
|
|
||||||
return !v.IsNull() && !v.IsUnknown()
|
|
||||||
}
|
|
||||||
|
@ -21,6 +21,7 @@ func TestAccResourceVM2CPU(t *testing.T) {
|
|||||||
Config: te.RenderConfig(`
|
Config: te.RenderConfig(`
|
||||||
resource "proxmox_virtual_environment_vm2" "test_vm" {
|
resource "proxmox_virtual_environment_vm2" "test_vm" {
|
||||||
node_name = "{{.NodeName}}"
|
node_name = "{{.NodeName}}"
|
||||||
|
id = {{.RandomVMID}}
|
||||||
name = "test-cpu"
|
name = "test-cpu"
|
||||||
}`),
|
}`),
|
||||||
Check: resource.ComposeTestCheckFunc(
|
Check: resource.ComposeTestCheckFunc(
|
||||||
@ -36,6 +37,7 @@ func TestAccResourceVM2CPU(t *testing.T) {
|
|||||||
Config: te.RenderConfig(`
|
Config: te.RenderConfig(`
|
||||||
resource "proxmox_virtual_environment_vm2" "test_vm" {
|
resource "proxmox_virtual_environment_vm2" "test_vm" {
|
||||||
node_name = "{{.NodeName}}"
|
node_name = "{{.NodeName}}"
|
||||||
|
id = {{.RandomVMID}}
|
||||||
name = "test-cpu"
|
name = "test-cpu"
|
||||||
cpu = {
|
cpu = {
|
||||||
cores = 2
|
cores = 2
|
||||||
@ -59,6 +61,7 @@ func TestAccResourceVM2CPU(t *testing.T) {
|
|||||||
Config: te.RenderConfig(`
|
Config: te.RenderConfig(`
|
||||||
resource "proxmox_virtual_environment_vm2" "test_vm" {
|
resource "proxmox_virtual_environment_vm2" "test_vm" {
|
||||||
node_name = "{{.NodeName}}"
|
node_name = "{{.NodeName}}"
|
||||||
|
id = {{.RandomVMID}}
|
||||||
name = "test-cpu"
|
name = "test-cpu"
|
||||||
cpu = {
|
cpu = {
|
||||||
# affinity = "0-1" only root can set affinity
|
# affinity = "0-1" only root can set affinity
|
||||||
@ -124,6 +127,7 @@ func TestAccResourceVM2CPU(t *testing.T) {
|
|||||||
Config: te.RenderConfig(`
|
Config: te.RenderConfig(`
|
||||||
resource "proxmox_virtual_environment_vm2" "template_vm" {
|
resource "proxmox_virtual_environment_vm2" "template_vm" {
|
||||||
node_name = "{{.NodeName}}"
|
node_name = "{{.NodeName}}"
|
||||||
|
id = {{.RandomVMID1}}
|
||||||
name = "template-cpu"
|
name = "template-cpu"
|
||||||
cpu = {
|
cpu = {
|
||||||
cores = 2
|
cores = 2
|
||||||
@ -132,7 +136,8 @@ func TestAccResourceVM2CPU(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
resource "proxmox_virtual_environment_vm2" "test_vm" {
|
resource "proxmox_virtual_environment_vm2" "test_vm" {
|
||||||
node_name = "{{.NodeName}}"
|
node_name = "{{.NodeName}}"
|
||||||
|
id = {{.RandomVMID2}}
|
||||||
name = "test-cpu"
|
name = "test-cpu"
|
||||||
clone = {
|
clone = {
|
||||||
id = proxmox_virtual_environment_vm2.template_vm.id
|
id = proxmox_virtual_environment_vm2.template_vm.id
|
||||||
@ -150,6 +155,7 @@ func TestAccResourceVM2CPU(t *testing.T) {
|
|||||||
Config: te.RenderConfig(`
|
Config: te.RenderConfig(`
|
||||||
resource "proxmox_virtual_environment_vm2" "template_vm" {
|
resource "proxmox_virtual_environment_vm2" "template_vm" {
|
||||||
node_name = "{{.NodeName}}"
|
node_name = "{{.NodeName}}"
|
||||||
|
id = {{.RandomVMID1}}
|
||||||
name = "template-cpu"
|
name = "template-cpu"
|
||||||
cpu = {
|
cpu = {
|
||||||
cores = 2
|
cores = 2
|
||||||
@ -158,7 +164,8 @@ func TestAccResourceVM2CPU(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
resource "proxmox_virtual_environment_vm2" "test_vm" {
|
resource "proxmox_virtual_environment_vm2" "test_vm" {
|
||||||
node_name = "{{.NodeName}}"
|
node_name = "{{.NodeName}}"
|
||||||
|
id = {{.RandomVMID2}}
|
||||||
name = "test-cpu"
|
name = "test-cpu"
|
||||||
clone = {
|
clone = {
|
||||||
id = proxmox_virtual_environment_vm2.template_vm.id
|
id = proxmox_virtual_environment_vm2.template_vm.id
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
|
|
||||||
"github.com/bpg/terraform-provider-proxmox/fwprovider/types/stringset"
|
"github.com/bpg/terraform-provider-proxmox/fwprovider/types/stringset"
|
||||||
"github.com/bpg/terraform-provider-proxmox/fwprovider/vm/cpu"
|
"github.com/bpg/terraform-provider-proxmox/fwprovider/vm/cpu"
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/fwprovider/vm/vga"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Schema defines the schema for the resource.
|
// Schema defines the schema for the resource.
|
||||||
@ -60,6 +61,7 @@ func (d *Datasource) Schema(
|
|||||||
"timeouts": timeouts.Attributes(ctx, timeouts.Opts{
|
"timeouts": timeouts.Attributes(ctx, timeouts.Opts{
|
||||||
Read: true,
|
Read: true,
|
||||||
}),
|
}),
|
||||||
|
"vga": vga.DataSourceSchema(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ import (
|
|||||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||||
|
|
||||||
"github.com/bpg/terraform-provider-proxmox/fwprovider/vm/cpu"
|
"github.com/bpg/terraform-provider-proxmox/fwprovider/vm/cpu"
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/fwprovider/vm/vga"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox/api"
|
"github.com/bpg/terraform-provider-proxmox/proxmox/api"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox/nodes/vms"
|
"github.com/bpg/terraform-provider-proxmox/proxmox/nodes/vms"
|
||||||
@ -146,6 +147,7 @@ func (r *Resource) create(ctx context.Context, plan Model, diags *diag.Diagnosti
|
|||||||
|
|
||||||
// fill out create body fields with values from other resource blocks
|
// fill out create body fields with values from other resource blocks
|
||||||
cpu.FillCreateBody(ctx, plan.CPU, createBody, diags)
|
cpu.FillCreateBody(ctx, plan.CPU, createBody, diags)
|
||||||
|
vga.FillCreateBody(ctx, plan.VGA, createBody, diags)
|
||||||
|
|
||||||
if diags.HasError() {
|
if diags.HasError() {
|
||||||
return
|
return
|
||||||
@ -321,6 +323,7 @@ func (r *Resource) update(ctx context.Context, plan, state Model, isClone bool,
|
|||||||
}
|
}
|
||||||
|
|
||||||
cpu.FillUpdateBody(ctx, plan.CPU, state.CPU, updateBody, isClone, diags)
|
cpu.FillUpdateBody(ctx, plan.CPU, state.CPU, updateBody, isClone, diags)
|
||||||
|
vga.FillUpdateBody(ctx, plan.VGA, state.VGA, updateBody, isClone, diags)
|
||||||
|
|
||||||
if !updateBody.IsEmpty() {
|
if !updateBody.IsEmpty() {
|
||||||
updateBody.VMID = int(plan.ID.ValueInt64())
|
updateBody.VMID = int(plan.ID.ValueInt64())
|
||||||
|
@ -17,6 +17,7 @@ import (
|
|||||||
|
|
||||||
"github.com/bpg/terraform-provider-proxmox/fwprovider/types/stringset"
|
"github.com/bpg/terraform-provider-proxmox/fwprovider/types/stringset"
|
||||||
"github.com/bpg/terraform-provider-proxmox/fwprovider/vm/cpu"
|
"github.com/bpg/terraform-provider-proxmox/fwprovider/vm/cpu"
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/fwprovider/vm/vga"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Schema defines the schema for the resource.
|
// Schema defines the schema for the resource.
|
||||||
@ -93,6 +94,7 @@ func (r *Resource) Schema(
|
|||||||
Update: true,
|
Update: true,
|
||||||
Delete: true,
|
Delete: true,
|
||||||
}),
|
}),
|
||||||
|
"vga": vga.ResourceSchema(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,9 +62,8 @@ func TestAccResourceVM(t *testing.T) {
|
|||||||
Config: te.RenderConfig(`
|
Config: te.RenderConfig(`
|
||||||
resource "proxmox_virtual_environment_vm2" "test_vm" {
|
resource "proxmox_virtual_environment_vm2" "test_vm" {
|
||||||
node_name = "{{.NodeName}}"
|
node_name = "{{.NodeName}}"
|
||||||
|
id = {{.RandomVMID}}
|
||||||
name = "not a valid DNS name"
|
name = "not a valid DNS name"
|
||||||
|
|
||||||
}`),
|
}`),
|
||||||
ExpectError: regexp.MustCompile(`name must be a valid DNS name`),
|
ExpectError: regexp.MustCompile(`name must be a valid DNS name`),
|
||||||
}}},
|
}}},
|
||||||
@ -73,7 +72,7 @@ func TestAccResourceVM(t *testing.T) {
|
|||||||
Config: te.RenderConfig(`
|
Config: te.RenderConfig(`
|
||||||
resource "proxmox_virtual_environment_vm2" "test_vm" {
|
resource "proxmox_virtual_environment_vm2" "test_vm" {
|
||||||
node_name = "{{.NodeName}}"
|
node_name = "{{.NodeName}}"
|
||||||
|
id = {{.RandomVMID}}
|
||||||
name = "test-vm"
|
name = "test-vm"
|
||||||
description = "test description"
|
description = "test description"
|
||||||
}`),
|
}`),
|
||||||
@ -86,7 +85,6 @@ func TestAccResourceVM(t *testing.T) {
|
|||||||
Config: te.RenderConfig(`
|
Config: te.RenderConfig(`
|
||||||
resource "proxmox_virtual_environment_vm2" "test_vm" {
|
resource "proxmox_virtual_environment_vm2" "test_vm" {
|
||||||
node_name = "{{.NodeName}}"
|
node_name = "{{.NodeName}}"
|
||||||
|
|
||||||
name = "test-vm"
|
name = "test-vm"
|
||||||
}`),
|
}`),
|
||||||
Check: resource.ComposeTestCheckFunc(
|
Check: resource.ComposeTestCheckFunc(
|
||||||
@ -110,7 +108,7 @@ func TestAccResourceVM(t *testing.T) {
|
|||||||
Config: te.RenderConfig(`
|
Config: te.RenderConfig(`
|
||||||
resource "proxmox_virtual_environment_vm2" "test_vm" {
|
resource "proxmox_virtual_environment_vm2" "test_vm" {
|
||||||
node_name = "{{.NodeName}}"
|
node_name = "{{.NodeName}}"
|
||||||
|
id = {{.RandomVMID}}
|
||||||
name = "test-tags"
|
name = "test-tags"
|
||||||
tags = ["tag2", "tag1"]
|
tags = ["tag2", "tag1"]
|
||||||
}`),
|
}`),
|
||||||
@ -159,7 +157,7 @@ func TestAccResourceVM(t *testing.T) {
|
|||||||
Config: te.RenderConfig(`
|
Config: te.RenderConfig(`
|
||||||
resource "proxmox_virtual_environment_vm2" "test_vm" {
|
resource "proxmox_virtual_environment_vm2" "test_vm" {
|
||||||
node_name = "{{.NodeName}}"
|
node_name = "{{.NodeName}}"
|
||||||
|
id = {{.RandomVMID}}
|
||||||
tags = ["", "tag1"]
|
tags = ["", "tag1"]
|
||||||
}`),
|
}`),
|
||||||
ExpectError: regexp.MustCompile(`string length must be at least 1, got: 0`),
|
ExpectError: regexp.MustCompile(`string length must be at least 1, got: 0`),
|
||||||
@ -168,7 +166,7 @@ func TestAccResourceVM(t *testing.T) {
|
|||||||
Config: te.RenderConfig(`
|
Config: te.RenderConfig(`
|
||||||
resource "proxmox_virtual_environment_vm2" "test_vm" {
|
resource "proxmox_virtual_environment_vm2" "test_vm" {
|
||||||
node_name = "{{.NodeName}}"
|
node_name = "{{.NodeName}}"
|
||||||
|
id = {{.RandomVMID}}
|
||||||
tags = [" ", "tag1"]
|
tags = [" ", "tag1"]
|
||||||
}`),
|
}`),
|
||||||
ExpectError: regexp.MustCompile(`must be a non-empty and non-whitespace string`),
|
ExpectError: regexp.MustCompile(`must be a non-empty and non-whitespace string`),
|
||||||
@ -177,7 +175,7 @@ func TestAccResourceVM(t *testing.T) {
|
|||||||
Config: te.RenderConfig(`
|
Config: te.RenderConfig(`
|
||||||
resource "proxmox_virtual_environment_vm2" "test_vm" {
|
resource "proxmox_virtual_environment_vm2" "test_vm" {
|
||||||
node_name = "{{.NodeName}}"
|
node_name = "{{.NodeName}}"
|
||||||
|
id = {{.RandomVMID}}
|
||||||
description = trimspace(<<-EOT
|
description = trimspace(<<-EOT
|
||||||
my
|
my
|
||||||
description
|
description
|
||||||
@ -220,12 +218,14 @@ func TestAccResourceVM2Clone(t *testing.T) {
|
|||||||
Config: te.RenderConfig(`
|
Config: te.RenderConfig(`
|
||||||
resource "proxmox_virtual_environment_vm2" "test_vm" {
|
resource "proxmox_virtual_environment_vm2" "test_vm" {
|
||||||
node_name = "{{.NodeName}}"
|
node_name = "{{.NodeName}}"
|
||||||
|
id = {{.RandomVMID1}}
|
||||||
name = "template"
|
name = "template"
|
||||||
description = "template description"
|
description = "template description"
|
||||||
template = true
|
template = true
|
||||||
}
|
}
|
||||||
resource "proxmox_virtual_environment_vm2" "test_vm_clone" {
|
resource "proxmox_virtual_environment_vm2" "test_vm_clone" {
|
||||||
node_name = "{{.NodeName}}"
|
node_name = "{{.NodeName}}"
|
||||||
|
id = {{.RandomVMID2}}
|
||||||
name = "clone"
|
name = "clone"
|
||||||
clone = {
|
clone = {
|
||||||
id = proxmox_virtual_environment_vm2.test_vm.id
|
id = proxmox_virtual_environment_vm2.test_vm.id
|
||||||
@ -249,11 +249,13 @@ func TestAccResourceVM2Clone(t *testing.T) {
|
|||||||
Config: te.RenderConfig(`
|
Config: te.RenderConfig(`
|
||||||
resource "proxmox_virtual_environment_vm2" "test_vm" {
|
resource "proxmox_virtual_environment_vm2" "test_vm" {
|
||||||
node_name = "{{.NodeName}}"
|
node_name = "{{.NodeName}}"
|
||||||
|
id = {{.RandomVMID1}}
|
||||||
template = true
|
template = true
|
||||||
tags = ["tag1", "tag2"]
|
tags = ["tag1", "tag2"]
|
||||||
}
|
}
|
||||||
resource "proxmox_virtual_environment_vm2" "test_vm_clone" {
|
resource "proxmox_virtual_environment_vm2" "test_vm_clone" {
|
||||||
node_name = "{{.NodeName}}"
|
node_name = "{{.NodeName}}"
|
||||||
|
id = {{.RandomVMID2}}
|
||||||
clone = {
|
clone = {
|
||||||
id = proxmox_virtual_environment_vm2.test_vm.id
|
id = proxmox_virtual_environment_vm2.test_vm.id
|
||||||
}
|
}
|
||||||
|
36
fwprovider/vm/vga/datasource_schema.go
Normal file
36
fwprovider/vm/vga/datasource_schema.go
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
package vga
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DataSourceSchema defines the schema for the VGA resource.
|
||||||
|
func DataSourceSchema() schema.Attribute {
|
||||||
|
return schema.SingleNestedAttribute{
|
||||||
|
CustomType: basetypes.ObjectType{
|
||||||
|
AttrTypes: attributeTypes(),
|
||||||
|
},
|
||||||
|
Description: "The VGA configuration.",
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
Attributes: map[string]schema.Attribute{
|
||||||
|
"clipboard": schema.StringAttribute{
|
||||||
|
Description: "Enable a specific clipboard.",
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"type": schema.StringAttribute{
|
||||||
|
Description: "The VGA type.",
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
"memory": schema.Int64Attribute{
|
||||||
|
Description: "The VGA memory in megabytes (4-512 MB)",
|
||||||
|
MarkdownDescription: "The VGA memory in megabytes (4-512 MB). Has no effect with serial display. ",
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
129
fwprovider/vm/vga/resource.go
Normal file
129
fwprovider/vm/vga/resource.go
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
package vga
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"reflect"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
|
||||||
|
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/fwprovider/attribute"
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/proxmox/nodes/vms"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Value represents the type for VGA settings.
|
||||||
|
type Value = types.Object
|
||||||
|
|
||||||
|
// NewValue returns a new Value with the given VGA settings from the PVE API.
|
||||||
|
func NewValue(ctx context.Context, config *vms.GetResponseData, diags *diag.Diagnostics) Value {
|
||||||
|
vga := Model{}
|
||||||
|
|
||||||
|
if config.VGADevice != nil {
|
||||||
|
vga.Clipboard = types.StringPointerValue(config.VGADevice.Clipboard)
|
||||||
|
vga.Type = types.StringPointerValue(config.VGADevice.Type)
|
||||||
|
vga.Memory = types.Int64PointerValue(config.VGADevice.Memory)
|
||||||
|
}
|
||||||
|
|
||||||
|
obj, d := types.ObjectValueFrom(ctx, attributeTypes(), vga)
|
||||||
|
diags.Append(d...)
|
||||||
|
|
||||||
|
return obj
|
||||||
|
}
|
||||||
|
|
||||||
|
// FillCreateBody fills the CreateRequestBody with the VGA settings from the Value.
|
||||||
|
//
|
||||||
|
// In the 'create' context, v is the plan.
|
||||||
|
func FillCreateBody(ctx context.Context, planValue Value, body *vms.CreateRequestBody, diags *diag.Diagnostics) {
|
||||||
|
var plan Model
|
||||||
|
|
||||||
|
if planValue.IsNull() || planValue.IsUnknown() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
d := planValue.As(ctx, &plan, basetypes.ObjectAsOptions{})
|
||||||
|
diags.Append(d...)
|
||||||
|
|
||||||
|
if d.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
vgaDevice := &vms.CustomVGADevice{}
|
||||||
|
|
||||||
|
// for computed fields, we need to check if they are unknown
|
||||||
|
if !plan.Clipboard.IsUnknown() {
|
||||||
|
vgaDevice.Clipboard = plan.Clipboard.ValueStringPointer()
|
||||||
|
}
|
||||||
|
|
||||||
|
if !plan.Type.IsUnknown() {
|
||||||
|
vgaDevice.Type = plan.Type.ValueStringPointer()
|
||||||
|
}
|
||||||
|
|
||||||
|
if !plan.Memory.IsUnknown() {
|
||||||
|
vgaDevice.Memory = plan.Memory.ValueInt64Pointer()
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(vgaDevice, &vms.CustomVGADevice{}) {
|
||||||
|
body.VGADevice = vgaDevice
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FillUpdateBody fills the UpdateRequestBody with the VGA settings from the Value.
|
||||||
|
//
|
||||||
|
// In the 'update' context, v is the plan and stateValue is the current state.
|
||||||
|
func FillUpdateBody(
|
||||||
|
ctx context.Context,
|
||||||
|
planValue, stateValue Value,
|
||||||
|
updateBody *vms.UpdateRequestBody,
|
||||||
|
isClone bool,
|
||||||
|
diags *diag.Diagnostics,
|
||||||
|
) {
|
||||||
|
var plan, state Model
|
||||||
|
|
||||||
|
if planValue.IsNull() || planValue.IsUnknown() || planValue.Equal(stateValue) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
d := planValue.As(ctx, &plan, basetypes.ObjectAsOptions{})
|
||||||
|
diags.Append(d...)
|
||||||
|
d = stateValue.As(ctx, &state, basetypes.ObjectAsOptions{})
|
||||||
|
diags.Append(d...)
|
||||||
|
|
||||||
|
if diags.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
vgaDevice := &vms.CustomVGADevice{
|
||||||
|
Clipboard: state.Clipboard.ValueStringPointer(),
|
||||||
|
Type: state.Type.ValueStringPointer(),
|
||||||
|
Memory: state.Memory.ValueInt64Pointer(),
|
||||||
|
}
|
||||||
|
|
||||||
|
if !plan.Clipboard.Equal(state.Clipboard) {
|
||||||
|
if attribute.ShouldBeRemoved(plan.Clipboard, state.Clipboard, isClone) {
|
||||||
|
vgaDevice.Clipboard = nil
|
||||||
|
} else if attribute.IsDefined(plan.Clipboard) {
|
||||||
|
vgaDevice.Clipboard = plan.Clipboard.ValueStringPointer()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !plan.Type.Equal(state.Type) {
|
||||||
|
if attribute.ShouldBeRemoved(plan.Type, state.Type, isClone) {
|
||||||
|
vgaDevice.Type = nil
|
||||||
|
} else if attribute.IsDefined(plan.Type) {
|
||||||
|
vgaDevice.Type = plan.Type.ValueStringPointer()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !plan.Memory.Equal(state.Memory) {
|
||||||
|
if attribute.ShouldBeRemoved(plan.Memory, state.Memory, isClone) {
|
||||||
|
vgaDevice.Memory = nil
|
||||||
|
} else if attribute.IsDefined(plan.Memory) {
|
||||||
|
vgaDevice.Memory = plan.Memory.ValueInt64Pointer()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(vgaDevice, &vms.CustomVGADevice{}) {
|
||||||
|
updateBody.VGADevice = vgaDevice
|
||||||
|
}
|
||||||
|
}
|
21
fwprovider/vm/vga/resource_model.go
Normal file
21
fwprovider/vm/vga/resource_model.go
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package vga
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/attr"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Model represents the VGA model.
|
||||||
|
type Model struct {
|
||||||
|
Clipboard types.String `tfsdk:"clipboard"`
|
||||||
|
Type types.String `tfsdk:"type"`
|
||||||
|
Memory types.Int64 `tfsdk:"memory"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func attributeTypes() map[string]attr.Type {
|
||||||
|
return map[string]attr.Type{
|
||||||
|
"clipboard": types.StringType,
|
||||||
|
"type": types.StringType,
|
||||||
|
"memory": types.Int64Type,
|
||||||
|
}
|
||||||
|
}
|
79
fwprovider/vm/vga/resource_schema.go
Normal file
79
fwprovider/vm/vga/resource_schema.go
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
package vga
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework-validators/int64validator"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/resource/schema/objectplanmodifier"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/schema/validator"
|
||||||
|
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ResourceSchema defines the schema for the CPU resource.
|
||||||
|
func ResourceSchema() schema.Attribute {
|
||||||
|
return schema.SingleNestedAttribute{
|
||||||
|
CustomType: basetypes.ObjectType{
|
||||||
|
AttrTypes: attributeTypes(),
|
||||||
|
},
|
||||||
|
Description: "The VGA configuration.",
|
||||||
|
MarkdownDescription: "Configure the VGA Hardware. If you want to use high resolution modes (>= 1280x1024x16) " +
|
||||||
|
"you may need to increase the vga memory option. Since QEMU 2.9 the default VGA display type is `std` " +
|
||||||
|
"for all OS types besides some Windows versions (XP and older) which use `cirrus`. The `qxl` option " +
|
||||||
|
"enables the SPICE display server. For win* OS you can select how many independent displays you want, " +
|
||||||
|
"Linux guests can add displays themself. You can also run without any graphic card, using a serial device " +
|
||||||
|
"as terminal. See the [Proxmox documentation](https://pve.proxmox.com/pve-docs/pve-admin-guide.html#" +
|
||||||
|
"qm_virtual_machines_settings) section 10.2.8 for more information and available configuration parameters.",
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
PlanModifiers: []planmodifier.Object{
|
||||||
|
objectplanmodifier.UseStateForUnknown(),
|
||||||
|
},
|
||||||
|
Attributes: map[string]schema.Attribute{
|
||||||
|
"clipboard": schema.StringAttribute{
|
||||||
|
Description: "Enable a specific clipboard.",
|
||||||
|
MarkdownDescription: "Enable a specific clipboard. If not set, depending on the display type the SPICE " +
|
||||||
|
"one will be added. Currently only `vnc` is available. Migration with VNC clipboard is not " +
|
||||||
|
"supported by Proxmox.",
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
Validators: []validator.String{
|
||||||
|
stringvalidator.OneOf("vnc"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"type": schema.StringAttribute{
|
||||||
|
Description: "The VGA type.",
|
||||||
|
MarkdownDescription: "The VGA type (defaults to `std`).",
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
Validators: []validator.String{
|
||||||
|
stringvalidator.OneOf(
|
||||||
|
"cirrus",
|
||||||
|
"none",
|
||||||
|
"qxl",
|
||||||
|
"qxl2",
|
||||||
|
"qxl3",
|
||||||
|
"qxl4",
|
||||||
|
"serial0",
|
||||||
|
"serial1",
|
||||||
|
"serial2",
|
||||||
|
"serial3",
|
||||||
|
"std",
|
||||||
|
"virtio",
|
||||||
|
"virtio-gl",
|
||||||
|
"vmware",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"memory": schema.Int64Attribute{
|
||||||
|
Description: "The VGA memory in megabytes (4-512 MB)",
|
||||||
|
MarkdownDescription: "The VGA memory in megabytes (4-512 MB). Has no effect with serial display. ",
|
||||||
|
Optional: true,
|
||||||
|
Computed: true,
|
||||||
|
Validators: []validator.Int64{
|
||||||
|
int64validator.Between(4, 512),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
162
fwprovider/vm/vga/resource_test.go
Normal file
162
fwprovider/vm/vga/resource_test.go
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
package vga_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
|
||||||
|
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/fwprovider/test"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestAccResourceVM2VGA(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
te := test.InitEnvironment(t)
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
steps []resource.TestStep
|
||||||
|
}{
|
||||||
|
{"create VM with no vga params", []resource.TestStep{{
|
||||||
|
Config: te.RenderConfig(`
|
||||||
|
resource "proxmox_virtual_environment_vm2" "test_vm" {
|
||||||
|
node_name = "{{.NodeName}}"
|
||||||
|
id = {{.RandomVMID}}
|
||||||
|
name = "test-vga"
|
||||||
|
}`),
|
||||||
|
Check: test.NoResourceAttributesSet("proxmox_virtual_environment_vm2.test_vm", []string{
|
||||||
|
// PVE does not set / return anything by default
|
||||||
|
"vga.type",
|
||||||
|
}),
|
||||||
|
}}},
|
||||||
|
{"create VM with some vga params", []resource.TestStep{{
|
||||||
|
Config: te.RenderConfig(`
|
||||||
|
resource "proxmox_virtual_environment_vm2" "test_vm" {
|
||||||
|
node_name = "{{.NodeName}}"
|
||||||
|
id = {{.RandomVMID}}
|
||||||
|
name = "test-vga"
|
||||||
|
vga = {
|
||||||
|
type = "std"
|
||||||
|
}
|
||||||
|
}`),
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
test.ResourceAttributes("proxmox_virtual_environment_vm2.test_vm", map[string]string{
|
||||||
|
"vga.type": "std",
|
||||||
|
}),
|
||||||
|
test.NoResourceAttributesSet("proxmox_virtual_environment_vm2.test_vm", []string{
|
||||||
|
"vga.clipboard",
|
||||||
|
"vga.memory",
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
}}},
|
||||||
|
{"create VM with VGA params and then update them", []resource.TestStep{
|
||||||
|
{
|
||||||
|
Config: te.RenderConfig(`
|
||||||
|
resource "proxmox_virtual_environment_vm2" "test_vm" {
|
||||||
|
node_name = "{{.NodeName}}"
|
||||||
|
id = {{.RandomVMID}}
|
||||||
|
name = "test-vga"
|
||||||
|
vga = {
|
||||||
|
type = "std"
|
||||||
|
memory = 16
|
||||||
|
}
|
||||||
|
}`),
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
test.ResourceAttributes("proxmox_virtual_environment_vm2.test_vm", map[string]string{
|
||||||
|
"vga.type": "std",
|
||||||
|
"vga.memory": "16",
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{ // now update the vga params and check if they are updated
|
||||||
|
Config: te.RenderConfig(`
|
||||||
|
resource "proxmox_virtual_environment_vm2" "test_vm" {
|
||||||
|
node_name = "{{.NodeName}}"
|
||||||
|
name = "test-cpu"
|
||||||
|
vga = {
|
||||||
|
type = "qxl"
|
||||||
|
clipboard = "vnc"
|
||||||
|
}
|
||||||
|
}`),
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
test.ResourceAttributes("proxmox_virtual_environment_vm2.test_vm", map[string]string{
|
||||||
|
"vga.type": "qxl",
|
||||||
|
"vga.clipboard": "vnc",
|
||||||
|
}),
|
||||||
|
test.NoResourceAttributesSet("proxmox_virtual_environment_vm2.test_vm", []string{
|
||||||
|
"vga.memory",
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
RefreshState: true,
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
{"clone VM with some vga params", []resource.TestStep{{
|
||||||
|
Config: te.RenderConfig(`
|
||||||
|
resource "proxmox_virtual_environment_vm2" "template_vm" {
|
||||||
|
node_name = "{{.NodeName}}"
|
||||||
|
id = {{.RandomVMID1}}
|
||||||
|
name = "template-vga"
|
||||||
|
vga = {
|
||||||
|
type = "qxl"
|
||||||
|
clipboard = "vnc"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resource "proxmox_virtual_environment_vm2" "test_vm" {
|
||||||
|
node_name = "{{.NodeName}}"
|
||||||
|
id = {{.RandomVMID2}}
|
||||||
|
name = "test-vga"
|
||||||
|
clone = {
|
||||||
|
id = proxmox_virtual_environment_vm2.template_vm.id
|
||||||
|
}
|
||||||
|
}`),
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
test.ResourceAttributes("proxmox_virtual_environment_vm2.test_vm", map[string]string{
|
||||||
|
"vga.type": "qxl",
|
||||||
|
"vga.clipboard": "vnc",
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
}}},
|
||||||
|
{"clone VM with some vga params and updating them in the clone", []resource.TestStep{{
|
||||||
|
Config: te.RenderConfig(`
|
||||||
|
resource "proxmox_virtual_environment_vm2" "template_vm" {
|
||||||
|
node_name = "{{.NodeName}}"
|
||||||
|
id = {{.RandomVMID1}}
|
||||||
|
name = "template-vga"
|
||||||
|
vga = {
|
||||||
|
type = "qxl"
|
||||||
|
clipboard = "vnc"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resource "proxmox_virtual_environment_vm2" "test_vm" {
|
||||||
|
node_name = "{{.NodeName}}"
|
||||||
|
name = "test-cpu"
|
||||||
|
id = {{.RandomVMID2}}
|
||||||
|
clone = {
|
||||||
|
id = proxmox_virtual_environment_vm2.template_vm.id
|
||||||
|
}
|
||||||
|
vga = {
|
||||||
|
type = "std"
|
||||||
|
memory = 16
|
||||||
|
}
|
||||||
|
}`),
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
test.ResourceAttributes("proxmox_virtual_environment_vm2.test_vm", map[string]string{
|
||||||
|
"vga.type": "std",
|
||||||
|
"vga.memory": "16",
|
||||||
|
"vga.clipboard": "vnc",
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
}}},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
resource.ParallelTest(t, resource.TestCase{
|
||||||
|
ProtoV6ProviderFactories: te.AccProviders,
|
||||||
|
Steps: tt.steps,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -11,6 +11,7 @@ import (
|
|||||||
|
|
||||||
"github.com/bpg/terraform-provider-proxmox/fwprovider/types/stringset"
|
"github.com/bpg/terraform-provider-proxmox/fwprovider/types/stringset"
|
||||||
"github.com/bpg/terraform-provider-proxmox/fwprovider/vm/cpu"
|
"github.com/bpg/terraform-provider-proxmox/fwprovider/vm/cpu"
|
||||||
|
"github.com/bpg/terraform-provider-proxmox/fwprovider/vm/vga"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
"github.com/bpg/terraform-provider-proxmox/proxmox"
|
||||||
"github.com/bpg/terraform-provider-proxmox/proxmox/api"
|
"github.com/bpg/terraform-provider-proxmox/proxmox/api"
|
||||||
)
|
)
|
||||||
@ -32,6 +33,7 @@ type Model struct {
|
|||||||
Tags stringset.Value `tfsdk:"tags"`
|
Tags stringset.Value `tfsdk:"tags"`
|
||||||
Template types.Bool `tfsdk:"template"`
|
Template types.Bool `tfsdk:"template"`
|
||||||
Timeouts timeouts.Value `tfsdk:"timeouts"`
|
Timeouts timeouts.Value `tfsdk:"timeouts"`
|
||||||
|
VGA vga.Value `tfsdk:"vga"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// read retrieves the current state of the resource from the API and updates the state.
|
// read retrieves the current state of the resource from the API and updates the state.
|
||||||
@ -69,9 +71,12 @@ func read(ctx context.Context, client proxmox.Client, model *Model, diags *diag.
|
|||||||
// Optional fields can be removed from the model, use StringPointerValue to handle removal on nil
|
// Optional fields can be removed from the model, use StringPointerValue to handle removal on nil
|
||||||
model.Description = types.StringPointerValue(config.Description)
|
model.Description = types.StringPointerValue(config.Description)
|
||||||
model.Name = types.StringPointerValue(config.Name)
|
model.Name = types.StringPointerValue(config.Name)
|
||||||
model.CPU = cpu.NewValue(ctx, config, diags)
|
|
||||||
model.Tags = stringset.NewValue(config.Tags, diags)
|
model.Tags = stringset.NewValue(config.Tags, diags)
|
||||||
model.Template = types.BoolPointerValue(config.Template.PointerBool())
|
model.Template = types.BoolPointerValue(config.Template.PointerBool())
|
||||||
|
|
||||||
|
// Blocks
|
||||||
|
model.CPU = cpu.NewValue(ctx, config, diags)
|
||||||
|
model.VGA = vga.NewValue(ctx, config, diags)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -186,7 +186,7 @@ type CustomUSBDevices []CustomUSBDevice
|
|||||||
// CustomVGADevice handles QEMU VGA device parameters.
|
// CustomVGADevice handles QEMU VGA device parameters.
|
||||||
type CustomVGADevice struct {
|
type CustomVGADevice struct {
|
||||||
Clipboard *string `json:"clipboard,omitempty" url:"memory,omitempty"`
|
Clipboard *string `json:"clipboard,omitempty" url:"memory,omitempty"`
|
||||||
Memory *int `json:"memory,omitempty" url:"memory,omitempty"`
|
Memory *int64 `json:"memory,omitempty" url:"memory,omitempty"`
|
||||||
Type *string `json:"type,omitempty" url:"type,omitempty"`
|
Type *string `json:"type,omitempty" url:"type,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2047,7 +2047,7 @@ func (r *CustomVGADevice) UnmarshalJSON(b []byte) error {
|
|||||||
r.Clipboard = &v[1]
|
r.Clipboard = &v[1]
|
||||||
|
|
||||||
case "memory":
|
case "memory":
|
||||||
m, err := strconv.Atoi(v[1])
|
m, err := strconv.ParseInt(v[1], 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to convert memory to int: %w", err)
|
return fmt.Errorf("failed to convert memory to int: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -3357,7 +3357,7 @@ func vmGetVGADeviceObject(d *schema.ResourceData) (*vms.CustomVGADevice, error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if vgaMemory > 0 {
|
if vgaMemory > 0 {
|
||||||
vgaDevice.Memory = &vgaMemory
|
vgaDevice.Memory = ptr.Ptr(int64(vgaMemory))
|
||||||
}
|
}
|
||||||
|
|
||||||
if vgaType != "" {
|
if vgaType != "" {
|
||||||
@ -4429,7 +4429,7 @@ func vmReadCustom(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if vmConfig.VGADevice.Memory != nil {
|
if vmConfig.VGADevice.Memory != nil {
|
||||||
vga[mkVGAMemory] = *vmConfig.VGADevice.Memory
|
vga[mkVGAMemory] = int(*vmConfig.VGADevice.Memory)
|
||||||
} else {
|
} else {
|
||||||
vga[mkVGAMemory] = dvVGAMemory
|
vga[mkVGAMemory] = dvVGAMemory
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user