0
0
mirror of https://github.com/bpg/terraform-provider-proxmox.git synced 2025-07-01 19:12:59 +00:00

feat(vm): pool update support (#505)

* feat(vm): pool update support

This commit removed the ForceNew flag from the VM resource's `pool_id`
argument and implements pool update:

  * if the VM was part of a pool, it is removed from it,
  * if the new `pool_id` value is non-empty, the VM is added to that new
    pool.

* fix: use `types.CustomCommaSeparatedList` in `PoolUpdateRequestBody` datatype, minor error fix

---------

Co-authored-by: Pavel Boldyrev <627562+bpg@users.noreply.github.com>
This commit is contained in:
Emmanuel Benoît 2023-08-19 03:48:37 +02:00 committed by GitHub
parent 1896ea08f0
commit e6c15eccc6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 59 additions and 1 deletions

View File

@ -6,6 +6,8 @@
package pools
import "github.com/bpg/terraform-provider-proxmox/internal/types"
// PoolCreateRequestBody contains the data for a pool create request.
type PoolCreateRequestBody struct {
Comment *string `json:"comment,omitempty" url:"comment,omitempty"`
@ -45,5 +47,12 @@ type PoolListResponseData struct {
// PoolUpdateRequestBody contains the data for an pool update request.
type PoolUpdateRequestBody struct {
// The pool's comment
Comment *string `json:"comment,omitempty" url:"comment,omitempty"`
// If this is set to 1, VMs and datastores will be removed from the pool instead of added.
Delete *types.CustomBool `json:"delete,omitempty" url:"delete,omitempty,int"`
// The list of virtual machines to add or delete.
VMs *types.CustomCommaSeparatedList `json:"vms,omitempty" url:"vms,omitempty,comma"`
// The list of datastores to add or delete.
Storage *types.CustomCommaSeparatedList `json:"storage,omitempty" url:"storage,omitempty,comma"`
}

View File

@ -17,6 +17,7 @@ import (
"time"
"unicode"
"github.com/google/go-cmp/cmp"
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
@ -27,6 +28,7 @@ import (
"github.com/bpg/terraform-provider-proxmox/internal/types"
"github.com/bpg/terraform-provider-proxmox/proxmox/cluster"
"github.com/bpg/terraform-provider-proxmox/proxmox/nodes/vms"
"github.com/bpg/terraform-provider-proxmox/proxmox/pools"
"github.com/bpg/terraform-provider-proxmox/proxmoxtf"
"github.com/bpg/terraform-provider-proxmox/proxmoxtf/resource/validator"
"github.com/bpg/terraform-provider-proxmox/proxmoxtf/structure"
@ -1212,7 +1214,6 @@ func VM() *schema.Resource {
Type: schema.TypeString,
Description: "The ID of the pool to assign the virtual machine to",
Optional: true,
ForceNew: true,
Default: dvResourceVirtualEnvironmentVMPoolID,
},
mkResourceVirtualEnvironmentVMSerialDevice: {
@ -4782,6 +4783,49 @@ func vmReadPrimitiveValues(
return diags
}
// vmUpdatePool moves the VM to the pool it is supposed to be in if the pool ID changed.
func vmUpdatePool(
ctx context.Context,
d *schema.ResourceData,
api *pools.Client,
vmID int,
) error {
oldPoolValue, newPoolValue := d.GetChange(mkResourceVirtualEnvironmentVMPoolID)
if cmp.Equal(newPoolValue, oldPoolValue) {
return nil
}
oldPool := oldPoolValue.(string)
newPool := newPoolValue.(string)
vmList := (types.CustomCommaSeparatedList)([]string{strconv.Itoa(vmID)})
tflog.Debug(ctx, fmt.Sprintf("Moving VM %d from pool '%s' to pool '%s'", vmID, oldPool, newPool))
if oldPool != "" {
trueValue := types.CustomBool(true)
poolUpdate := &pools.PoolUpdateRequestBody{
VMs: &vmList,
Delete: &trueValue,
}
err := api.UpdatePool(ctx, oldPool, poolUpdate)
if err != nil {
return fmt.Errorf("while removing VM %d from pool %s: %w", vmID, oldPool, err)
}
}
if newPool != "" {
poolUpdate := &pools.PoolUpdateRequestBody{VMs: &vmList}
err := api.UpdatePool(ctx, newPool, poolUpdate)
if err != nil {
return fmt.Errorf("while adding VM %d to pool %s: %w", vmID, newPool, err)
}
}
return nil
}
func vmUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
config := m.(proxmoxtf.ProviderConfiguration)
@ -4798,6 +4842,11 @@ func vmUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.D
return diag.FromErr(e)
}
e = vmUpdatePool(ctx, d, api.Pool(), vmID)
if e != nil {
return diag.FromErr(e)
}
vmAPI := api.Node(nodeName).VM(vmID)
updateBody := &vms.UpdateRequestBody{