Skip to content

Commit

Permalink
feat(vm): pool update support (#505)
Browse files Browse the repository at this point in the history
* 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>
  • Loading branch information
tseeker and bpg authored Aug 19, 2023
1 parent 1896ea0 commit e6c15ec
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 1 deletion.
9 changes: 9 additions & 0 deletions proxmox/pools/pool_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"`
Expand Down Expand Up @@ -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"`
}
51 changes: 50 additions & 1 deletion proxmoxtf/resource/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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"
Expand Down Expand Up @@ -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: {
Expand Down Expand Up @@ -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)

Expand All @@ -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{
Expand Down

0 comments on commit e6c15ec

Please sign in to comment.