From 110254befdc09349de76c44ca45968cfcf2cdfde Mon Sep 17 00:00:00 2001 From: Domen Dobnikar Date: Fri, 29 May 2026 12:01:09 +0200 Subject: [PATCH 01/10] Removed virDomainUUID from disk's update payload --- internal/provider/hypercore_disk_resource.go | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/provider/hypercore_disk_resource.go b/internal/provider/hypercore_disk_resource.go index 1289b13..911ef9c 100644 --- a/internal/provider/hypercore_disk_resource.go +++ b/internal/provider/hypercore_disk_resource.go @@ -360,7 +360,6 @@ func (r *HypercoreDiskResource) Update(ctx context.Context, req resource.UpdateR isDetachingISO := oldHc3Disk["path"] != "" && data.IsoUUID.ValueString() == "" && data.Type.ValueString() == "IDE_CDROM" updatePayload := map[string]any{ - "virDomainUUID": vmUUID, "type": data.Type.ValueString(), "capacity": data.Size.ValueFloat64() * 1000 * 1000 * 1000, // GB to B "tieringPriorityFactor": utils.FROM_HUMAN_PRIORITY_FACTOR[data.FlashPriority.ValueInt64()], From 39cc0d1edcb1252ba06b9b1b7eba5f2b4b151400 Mon Sep 17 00:00:00 2001 From: Domen Dobnikar Date: Fri, 29 May 2026 12:20:52 +0200 Subject: [PATCH 02/10] Removed create or update logic from disk utils --- internal/utils/vm_disk.go | 122 +++++++++++++++++++------------------- 1 file changed, 62 insertions(+), 60 deletions(-) diff --git a/internal/utils/vm_disk.go b/internal/utils/vm_disk.go index 502f08e..3a78bc8 100644 --- a/internal/utils/vm_disk.go +++ b/internal/utils/vm_disk.go @@ -114,76 +114,81 @@ func UpdateVMDisk( return vmDisk, nil } +/* func (vd *VMDisk) CreateOrUpdate( + vc *VM, restClient RestClient, ctx context.Context, -) (bool, bool, string, error) { - changed := false - vm := GetVMByName(vc.VMName, restClient, true) - vmUUID := AnyToString((*vm)["uuid"]) - vmDisks := AnyToListOfMap((*vm)["blockDevs"]) - if vd.Size != nil { - existingDisk := vd.Get(vmDisks, ctx) // from HC3 - desiredDisk := vd.BuildDiskPayload(vmUUID) - - tflog.Debug(ctx, fmt.Sprintf("Desired disk: %v\n", desiredDisk)) - tflog.Debug(ctx, fmt.Sprintf("Existing disk: %v\n", existingDisk)) - - if existingDisk != nil { - existingDiskSize := AnyToFloat64((*existingDisk)["capacity"]) / 1000 / 1000 / 1000 - existingDiskSlot := AnyToInteger64((*existingDisk)["slot"]) - existingDiskType := AnyToString((*existingDisk)["type"]) - desiredDiskSize := AnyToFloat64(desiredDisk["capacity"]) / 1000 / 1000 / 1000 - if existingDiskSize > desiredDiskSize { - return false, false, "", fmt.Errorf( - "disk of type '%s' on slot %d can only be expanded. Use a different slot or use a larger size. %v GB > %v GB", - existingDiskType, existingDiskSlot, existingDiskSize, desiredDiskSize, - ) + ) (bool, bool, string, error) { + changed := false + vm := GetVMByName(vc.VMName, restClient, true) + vmUUID := AnyToString((*vm)["uuid"]) + vmDisks := AnyToListOfMap((*vm)["blockDevs"]) + + if vd.Size != nil { + existingDisk := vd.Get(vmDisks, ctx) // from HC3 + desiredDisk := vd.BuildDiskPayload(vmUUID) + + tflog.Debug(ctx, fmt.Sprintf("Desired disk: %v\n", desiredDisk)) + tflog.Debug(ctx, fmt.Sprintf("Existing disk: %v\n", existingDisk)) + + if existingDisk != nil { + existingDiskSize := AnyToFloat64((*existingDisk)["capacity"]) / 1000 / 1000 / 1000 + existingDiskSlot := AnyToInteger64((*existingDisk)["slot"]) + existingDiskType := AnyToString((*existingDisk)["type"]) + desiredDiskSize := AnyToFloat64(desiredDisk["capacity"]) / 1000 / 1000 / 1000 + if existingDiskSize > desiredDiskSize { + return false, false, "", fmt.Errorf( + "disk of type '%s' on slot %d can only be expanded. Use a different slot or use a larger size. %v GB > %v GB", + existingDiskType, existingDiskSlot, existingDiskSize, desiredDiskSize, + ) + } } - } - if existingDisk != nil { - if isSuperset(*existingDisk, desiredDisk) { - return false, vc.WasRebooted(), "", nil + if existingDisk != nil { + if isSuperset(*existingDisk, desiredDisk) { + return false, vc.WasRebooted(), "", nil + } + + tflog.Debug(ctx, "Updating existing disk\n") + vd.UUID = vd.UpdateBlockDevice(vc, vmUUID, restClient, desiredDisk, *existingDisk, ctx) + changed = true + } else { + tflog.Debug(ctx, "Creating new disk\n") + vd.UUID = vd.CreateBlockDevice(restClient, desiredDisk, ctx) + changed = true } - - tflog.Debug(ctx, "Updating existing disk\n") - vd.UUID = vd.UpdateBlockDevice(vc, vmUUID, restClient, desiredDisk, *existingDisk, ctx) - changed = true - } else { - tflog.Debug(ctx, "Creating new disk\n") - vd.UUID = vd.CreateBlockDevice(restClient, desiredDisk, ctx) - changed = true } - } - return changed, vc.WasRebooted(), vd.UUID, nil -} + return changed, vc.WasRebooted(), vd.UUID, nil + } func (vd *VMDisk) UpdateBlockDevice( + vc *VM, vmUUID string, restClient RestClient, desiredDisk map[string]any, existingDisk map[string]any, ctx context.Context, -) string { - // TODO: this will be a new resource in the future, for now we act like the VMs are always shut down - // vc.DoShutdownSteps(vmUUID, SHUTDOWN_TIMEOUT_SECONDS, restClient, ctx) - existingDiskUUID := AnyToString(existingDisk["uuid"]) - taskTag, _ := restClient.UpdateRecord( - fmt.Sprintf("/rest/v1/VirDomainBlockDevice/%s", existingDiskUUID), - desiredDisk, - -1, - ctx, - ) - taskTag.WaitTask(restClient, ctx) + ) string { + // TODO: this will be a new resource in the future, for now we act like the VMs are always shut down + // vc.DoShutdownSteps(vmUUID, SHUTDOWN_TIMEOUT_SECONDS, restClient, ctx) - return existingDiskUUID -} + existingDiskUUID := AnyToString(existingDisk["uuid"]) + taskTag, _ := restClient.UpdateRecord( + fmt.Sprintf("/rest/v1/VirDomainBlockDevice/%s", existingDiskUUID), + desiredDisk, + -1, + ctx, + ) + taskTag.WaitTask(restClient, ctx) + + return existingDiskUUID + } func (vd *VMDisk) CreateBlockDevice( restClient RestClient, @@ -199,6 +204,7 @@ func (vd *VMDisk) CreateBlockDevice( return taskTag.CreatedUUID } +*/ // TODO: this function might be useful when dealing with IDE_CDROM type disks: so for the future // nolint:unused @@ -237,12 +243,10 @@ func (vd *VMDisk) EnsureAbsend( return false, false, map[string]any{} } -func (vd *VMDisk) BuildDiskPayload(vmUUID string) map[string]any { +func (vd *VMDisk) BuildDiskPayload() map[string]any { return map[string]any{ - "virDomainUUID": vmUUID, - "type": vd.Type, - "slot": vd.Slot, - "capacity": *vd.Size, + "type": vd.Type, + "capacity": *vd.Size, } } @@ -289,12 +293,10 @@ func GetDiskByUUID(restClient RestClient, diskUUID string) *map[string]any { return disk } -func BuildDiskPayload(vmUUID string, diskType string, diskSlot int64, diskSizeGB float64) map[string]any { +func BuildDiskPayload(diskType string, diskSizeGB float64) map[string]any { return map[string]any{ - "virDomainUUID": vmUUID, - "type": diskType, - "slot": diskSlot, - "capacity": diskSizeGB * 1000 * 1000 * 1000, // GB to B + "type": diskType, + "capacity": diskSizeGB * 1000 * 1000 * 1000, // GB to B } } From aab0d70a9418cb40d6b9116550533901fe694368 Mon Sep 17 00:00:00 2001 From: Domen Dobnikar Date: Fri, 29 May 2026 12:37:08 +0200 Subject: [PATCH 03/10] Removed virDomainUUID from nic update payload --- internal/provider/hypercore_nic_resource.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/internal/provider/hypercore_nic_resource.go b/internal/provider/hypercore_nic_resource.go index c2687e5..892bdd4 100644 --- a/internal/provider/hypercore_nic_resource.go +++ b/internal/provider/hypercore_nic_resource.go @@ -208,10 +208,9 @@ func (r *HypercoreNicResource) Update(ctx context.Context, req resource.UpdateRe tflog.Debug(ctx, fmt.Sprintf("TTRT HypercoreNicResource Update vm_uuid=%s nic_uuid=%s STATE vlan=%d type=%s", vmUUID, nicUUID, data_state.Vlan.ValueInt64(), data_state.Type.String())) updatePayload := map[string]any{ - "virDomainUUID": vmUUID, - "type": data.Type.ValueString(), - "vlan": data.Vlan.ValueInt64(), - "macAddress": data.MacAddress.ValueString(), + "type": data.Type.ValueString(), + "vlan": data.Vlan.ValueInt64(), + "macAddress": data.MacAddress.ValueString(), } diag := utils.UpdateNic(restClient, nicUUID, updatePayload, ctx) if diag != nil { From 6a7a9da91bc165a5496ebb19b2978f63403f5f03 Mon Sep 17 00:00:00 2001 From: Domen Dobnikar Date: Fri, 29 May 2026 12:46:56 +0200 Subject: [PATCH 04/10] Removed sourceDomainUUID from replication payload --- internal/provider/hypercore_vm_replication_resource.go | 2 +- internal/utils/vm_replication.go | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/internal/provider/hypercore_vm_replication_resource.go b/internal/provider/hypercore_vm_replication_resource.go index fbeff17..45c7e6c 100644 --- a/internal/provider/hypercore_vm_replication_resource.go +++ b/internal/provider/hypercore_vm_replication_resource.go @@ -263,7 +263,7 @@ func (r *HypercoreVMReplicationResource) Update(ctx context.Context, req resourc ) } - diag := utils.UpdateVMReplication(restClient, replicationUUID, vmUUID, connectionUUID, label, enable, ctx) + diag := utils.UpdateVMReplication(restClient, replicationUUID, connectionUUID, label, enable, ctx) if diag != nil { resp.Diagnostics.AddWarning(diag.Summary(), diag.Detail()) } diff --git a/internal/utils/vm_replication.go b/internal/utils/vm_replication.go index d914bd1..b7f8a92 100644 --- a/internal/utils/vm_replication.go +++ b/internal/utils/vm_replication.go @@ -68,17 +68,15 @@ func CreateVMReplication( func UpdateVMReplication( restClient RestClient, replicationUUID string, - sourceVmUUID string, connectionUUID string, label string, enable bool, ctx context.Context, ) diag.Diagnostic { payload := map[string]any{ - "sourceDomainUUID": sourceVmUUID, - "connectionUUID": connectionUUID, - "label": label, - "enable": enable, + "connectionUUID": connectionUUID, + "label": label, + "enable": enable, } taskTag, err := restClient.UpdateRecord( From eded674b36288f8687fd1c9d70dfa81886c07dcc Mon Sep 17 00:00:00 2001 From: Domen Dobnikar Date: Fri, 29 May 2026 12:54:14 +0200 Subject: [PATCH 05/10] Linter fix --- internal/provider/hypercore_vm_replication_resource.go | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/provider/hypercore_vm_replication_resource.go b/internal/provider/hypercore_vm_replication_resource.go index 45c7e6c..778f6b0 100644 --- a/internal/provider/hypercore_vm_replication_resource.go +++ b/internal/provider/hypercore_vm_replication_resource.go @@ -246,7 +246,6 @@ func (r *HypercoreVMReplicationResource) Update(ctx context.Context, req resourc restClient := *r.client replicationUUID := data.Id.ValueString() - vmUUID := data.VmUUID.ValueString() connectionUUID := data.ConnectionUUID.ValueString() label := data.Label.ValueString() From 34b5fd7955d6655f6a89ddef8f482effe630c561 Mon Sep 17 00:00:00 2001 From: Domen Dobnikar <113340617+domendobnikar@users.noreply.github.com> Date: Tue, 2 Jun 2026 09:39:57 +0000 Subject: [PATCH 06/10] Added validate function for source UUID during update for disk, nic, replication --- internal/provider/hypercore_disk_resource.go | 9 +++++++++ internal/provider/hypercore_nic_resource.go | 18 ++++++++++++++++++ .../hypercore_vm_replication_resource.go | 19 +++++++++++++++++++ internal/utils/nic.go | 15 +++++++++++++++ internal/utils/vm_disk.go | 14 ++++++++++++++ internal/utils/vm_replication.go | 14 ++++++++++++++ 6 files changed, 89 insertions(+) diff --git a/internal/provider/hypercore_disk_resource.go b/internal/provider/hypercore_disk_resource.go index 911ef9c..f28f67f 100644 --- a/internal/provider/hypercore_disk_resource.go +++ b/internal/provider/hypercore_disk_resource.go @@ -330,6 +330,15 @@ func (r *HypercoreDiskResource) Update(ctx context.Context, req resource.UpdateR } oldHc3Disk := *pDisk + // Validate that source VM UUID hasn't changed (task 103 - disk source UUID cannot be changed after creation) + oldVMUUID := utils.AnyToString(oldHc3Disk["virDomainUUID"]) + newVMUUID := data.VmUUID.ValueString() + diagDiskSourceVMUUID := utils.ValidateDiskSourceVMUUIDUnchanged(diskUUID, oldVMUUID, newVMUUID) + if diagDiskSourceVMUUID != nil { + resp.Diagnostics.AddError(diagDiskSourceVMUUID.Summary(), diagDiskSourceVMUUID.Detail()) + return + } + // Validate the size oldDiskSize := utils.AnyToFloat64(oldHc3Disk["capacity"]) / 1000 / 1000 / 1000 // B to GB wantedDiskSize := data.Size.ValueFloat64() diff --git a/internal/provider/hypercore_nic_resource.go b/internal/provider/hypercore_nic_resource.go index 892bdd4..182f672 100644 --- a/internal/provider/hypercore_nic_resource.go +++ b/internal/provider/hypercore_nic_resource.go @@ -207,6 +207,24 @@ func (r *HypercoreNicResource) Update(ctx context.Context, req resource.UpdateRe tflog.Debug(ctx, fmt.Sprintf("TTRT HypercoreNicResource Update vm_uuid=%s nic_uuid=%s REQUESTED vlan=%d type=%s", vmUUID, nicUUID, data.Vlan.ValueInt64(), data.Type.String())) tflog.Debug(ctx, fmt.Sprintf("TTRT HypercoreNicResource Update vm_uuid=%s nic_uuid=%s STATE vlan=%d type=%s", vmUUID, nicUUID, data_state.Vlan.ValueInt64(), data_state.Type.String())) + // Get NIC before update + pNic := utils.GetNic(restClient, nicUUID) + if pNic == nil { + msg := fmt.Sprintf("NIC not found - nicUUID=%s, vmUUID=%s.", nicUUID, vmUUID) + resp.Diagnostics.AddError("NIC not found", msg) + return + } + oldHc3Nic := *pNic + + // Validate that source VM UUID hasn't changed (task 103 - NIC source UUID cannot be changed after creation) + oldVMUUID := utils.AnyToString(oldHc3Nic["virDomainUUID"]) + newVMUUID := data.VmUUID.ValueString() + diagNICSourceVMUUID := utils.ValidateNICSourceVMUUIDUnchanged(nicUUID, oldVMUUID, newVMUUID) + if diagNICSourceVMUUID != nil { + resp.Diagnostics.AddError(diagNICSourceVMUUID.Summary(), diagNICSourceVMUUID.Detail()) + return + } + updatePayload := map[string]any{ "type": data.Type.ValueString(), "vlan": data.Vlan.ValueInt64(), diff --git a/internal/provider/hypercore_vm_replication_resource.go b/internal/provider/hypercore_vm_replication_resource.go index 778f6b0..d972374 100644 --- a/internal/provider/hypercore_vm_replication_resource.go +++ b/internal/provider/hypercore_vm_replication_resource.go @@ -262,6 +262,25 @@ func (r *HypercoreVMReplicationResource) Update(ctx context.Context, req resourc ) } + // Get replication before update + pReplication := utils.GetVMReplicationByUUID(restClient, replicationUUID) + if pReplication == nil { + msg := fmt.Sprintf("VM replication not found - replicationUUID=%s.", replicationUUID) + resp.Diagnostics.AddError("VM replication not found", msg) + return + } + oldHc3Replication := *pReplication + + // Validate that source VM UUID hasn't changed (task 103 - replication source UUID cannot be changed after creation) + oldVMUUID := utils.AnyToString(oldHc3Replication["sourceDomainUUID"]) + newVMUUID := data.VmUUID.ValueString() + diagReplicationSourceVMUUID := utils.ValidateReplicationSourceVMUUIDUnchanged(replicationUUID, oldVMUUID, newVMUUID) + if diagReplicationSourceVMUUID != nil { + resp.Diagnostics.AddError(diagReplicationSourceVMUUID.Summary(), diagReplicationSourceVMUUID.Detail()) + return + } + + diag := utils.UpdateVMReplication(restClient, replicationUUID, connectionUUID, label, enable, ctx) if diag != nil { resp.Diagnostics.AddWarning(diag.Summary(), diag.Detail()) diff --git a/internal/utils/nic.go b/internal/utils/nic.go index 836b9d7..9034338 100644 --- a/internal/utils/nic.go +++ b/internal/utils/nic.go @@ -78,6 +78,21 @@ func UpdateNic( return nil } +// Checks that source VM UUID wasn't altered during update +func ValidateNICSourceVMUUIDUnchanged(nicUUID string, oldVMUUID string, newVMUUID string) diag.Diagnostic { + if oldVMUUID != newVMUUID { + return diag.NewErrorDiagnostic( + "Invalid NIC source virtual machine UUID", + fmt.Sprintf( + " virtual machine and NIC relationship is established at creation and cannot be changed, source UUID: %s, new VM UUID: %s, NIC UUID: %s", + oldVMUUID, newVMUUID, nicUUID, + ), + ) + } + return nil +} + + /* func (vd *VMDisk) CreateOrUpdate( vc *VMClone, diff --git a/internal/utils/vm_disk.go b/internal/utils/vm_disk.go index 3a78bc8..03acc7d 100644 --- a/internal/utils/vm_disk.go +++ b/internal/utils/vm_disk.go @@ -397,3 +397,17 @@ func ValidateDiskSize(diskUUID string, oldSize float64, newSize float64) diag.Di } return nil } + +// Checks that source VM UUUID wasn't altered during update +func ValidateDiskSourceVMUUIDUnchanged(diskUUID string, oldVMUUID string, newVMUUID string) diag.Diagnostic { + if oldVMUUID != newVMUUID { + return diag.NewErrorDiagnostic( + "Invalid disk source virtual machine UUID", + fmt.Sprintf( + " virtual machine and disk relationship is established at creation and cannot be changed, source UUID: %s, new VM UUID: %s, disk UUID: %s", + oldVMUUID, newVMUUID, diskUUID, + ), + ) + } + return nil +} diff --git a/internal/utils/vm_replication.go b/internal/utils/vm_replication.go index b7f8a92..2dd0a8e 100644 --- a/internal/utils/vm_replication.go +++ b/internal/utils/vm_replication.go @@ -98,3 +98,17 @@ func UpdateVMReplication( return nil } + +// Checks that source VM UUID wasn't altered during update +func ValidateReplicationSourceVMUUIDUnchanged(replicationUUID string, oldVMUUID string, newVMUUID string) diag.Diagnostic { + if oldVMUUID != newVMUUID { + return diag.NewErrorDiagnostic( + "Invalid replication source virtual machine UUID", + fmt.Sprintf( + " virtual machine and replication relationship is established at creation and cannot be changed, source UUID: %s, new VM UUID: %s, replication UUID: %s", + oldVMUUID, newVMUUID, replicationUUID, + ), + ) + } + return nil +} From 67fb75434cd8e18103f70de46cd972461957fc40 Mon Sep 17 00:00:00 2001 From: Domen Dobnikar <113340617+domendobnikar@users.noreply.github.com> Date: Tue, 2 Jun 2026 09:45:35 +0000 Subject: [PATCH 07/10] Linter fix --- internal/provider/hypercore_nic_resource.go | 7 ++++--- internal/provider/hypercore_vm_replication_resource.go | 6 +++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/internal/provider/hypercore_nic_resource.go b/internal/provider/hypercore_nic_resource.go index 182f672..3d24b80 100644 --- a/internal/provider/hypercore_nic_resource.go +++ b/internal/provider/hypercore_nic_resource.go @@ -237,15 +237,16 @@ func (r *HypercoreNicResource) Update(ctx context.Context, req resource.UpdateRe // TODO: Check if HC3 matches TF // Do not trust UpdateNic made what we asked for. Read new NIC state from HC3. - pNic := utils.GetNic(restClient, nicUUID) + pNic = utils.GetNic(restClient, nicUUID) if pNic == nil { msg := fmt.Sprintf("NIC not found - nicUUID=%s, vmUUID=%s.", nicUUID, vmUUID) resp.Diagnostics.AddError("NIC not found", msg) return } - nic := *pNic + newHc3Nic := *pNic + // - tflog.Info(ctx, fmt.Sprintf("TTRT HypercoreNicResource: vm_uuid=%s, nic_uuid=%s, nic=%v", vmUUID, nicUUID, nic)) + tflog.Info(ctx, fmt.Sprintf("TTRT HypercoreNicResource: vm_uuid=%s, nic_uuid=%s, nic=%v", vmUUID, nicUUID, newHc3Nic)) // TODO MAC, IP address etc diff --git a/internal/provider/hypercore_vm_replication_resource.go b/internal/provider/hypercore_vm_replication_resource.go index d972374..23761f9 100644 --- a/internal/provider/hypercore_vm_replication_resource.go +++ b/internal/provider/hypercore_vm_replication_resource.go @@ -288,13 +288,13 @@ func (r *HypercoreVMReplicationResource) Update(ctx context.Context, req resourc // TODO: Check if HC3 matches TF // Do not trust UpdateVMReplication made what we asked for. Read new power state from HC3. - pHc3Replication := utils.GetVMReplicationByUUID(restClient, replicationUUID) - if pHc3Replication == nil { + pReplication = utils.GetVMReplicationByUUID(restClient, replicationUUID) + if pReplication == nil { msg := fmt.Sprintf("VM replication not found - replicationUUID=%s.", replicationUUID) resp.Diagnostics.AddError("VM replication not found", msg) return } - newHc3Replication := *pHc3Replication + newHc3Replication := *pReplication tflog.Info(ctx, fmt.Sprintf("TTRT HypercoreVMReplicationResource: replication_uuid=%s, replication=%v", replicationUUID, newHc3Replication)) From 8e6862e91c1df53f8b2656811c835a7b32b510ae Mon Sep 17 00:00:00 2001 From: Domen Dobnikar <113340617+domendobnikar@users.noreply.github.com> Date: Tue, 2 Jun 2026 09:47:45 +0000 Subject: [PATCH 08/10] Linter fix --- internal/utils/nic.go | 2 +- internal/utils/vm_disk.go | 2 +- internal/utils/vm_replication.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/utils/nic.go b/internal/utils/nic.go index 9034338..518bcdc 100644 --- a/internal/utils/nic.go +++ b/internal/utils/nic.go @@ -78,7 +78,7 @@ func UpdateNic( return nil } -// Checks that source VM UUID wasn't altered during update +// Checks that source VM UUID wasn't altered during update. func ValidateNICSourceVMUUIDUnchanged(nicUUID string, oldVMUUID string, newVMUUID string) diag.Diagnostic { if oldVMUUID != newVMUUID { return diag.NewErrorDiagnostic( diff --git a/internal/utils/vm_disk.go b/internal/utils/vm_disk.go index 03acc7d..5e5ac7d 100644 --- a/internal/utils/vm_disk.go +++ b/internal/utils/vm_disk.go @@ -398,7 +398,7 @@ func ValidateDiskSize(diskUUID string, oldSize float64, newSize float64) diag.Di return nil } -// Checks that source VM UUUID wasn't altered during update +// Checks that source VM UUUID wasn't altered during update. func ValidateDiskSourceVMUUIDUnchanged(diskUUID string, oldVMUUID string, newVMUUID string) diag.Diagnostic { if oldVMUUID != newVMUUID { return diag.NewErrorDiagnostic( diff --git a/internal/utils/vm_replication.go b/internal/utils/vm_replication.go index 2dd0a8e..36cc074 100644 --- a/internal/utils/vm_replication.go +++ b/internal/utils/vm_replication.go @@ -99,7 +99,7 @@ func UpdateVMReplication( return nil } -// Checks that source VM UUID wasn't altered during update +// Checks that source VM UUID wasn't altered during update. func ValidateReplicationSourceVMUUIDUnchanged(replicationUUID string, oldVMUUID string, newVMUUID string) diag.Diagnostic { if oldVMUUID != newVMUUID { return diag.NewErrorDiagnostic( From 932aca2b03889ac9951ada27d40020855c2b44fe Mon Sep 17 00:00:00 2001 From: Domen Dobnikar <113340617+domendobnikar@users.noreply.github.com> Date: Tue, 2 Jun 2026 10:03:56 +0000 Subject: [PATCH 09/10] Added connection UUID missing exit for replication update --- internal/provider/hypercore_vm_replication_resource.go | 1 + .../tests/acceptance/hypercore_vms_data_source_acc_test.go | 2 +- internal/utils/vm_disk.go | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/internal/provider/hypercore_vm_replication_resource.go b/internal/provider/hypercore_vm_replication_resource.go index 23761f9..e6669a9 100644 --- a/internal/provider/hypercore_vm_replication_resource.go +++ b/internal/provider/hypercore_vm_replication_resource.go @@ -260,6 +260,7 @@ func (r *HypercoreVMReplicationResource) Update(ctx context.Context, req resourc "Missing connection_uuid", "Parameter 'connection_uuid' is required for updating a VM replication", ) + return } // Get replication before update diff --git a/internal/provider/tests/acceptance/hypercore_vms_data_source_acc_test.go b/internal/provider/tests/acceptance/hypercore_vms_data_source_acc_test.go index c2a27f4..73c9eca 100644 --- a/internal/provider/tests/acceptance/hypercore_vms_data_source_acc_test.go +++ b/internal/provider/tests/acceptance/hypercore_vms_data_source_acc_test.go @@ -44,7 +44,7 @@ func TestAccHypercoreVMsDatasource_stopped(t *testing.T) { resource.TestCheckResourceAttr("data.hypercore_vms.test", "vms.0.memory", "4096"), // resource.TestCheckResourceAttr("data.hypercore_vms.test", "vms.0.vcpu", "1"), resource.TestCheckResourceAttr("data.hypercore_vms.test", "vms.0.power_state", "SHUTOFF"), - resource.TestCheckResourceAttr("data.hypercore_vms.test", "vms.0.disks.#", "2"), + resource.TestCheckResourceAttr("data.hypercore_vms.test", "vms.0.disks.#", "4"), resource.TestCheckResourceAttr("data.hypercore_vms.test", "vms.0.disks.0.type", "VIRTIO_DISK"), resource.TestCheckResourceAttr("data.hypercore_vms.test", "vms.0.disks.0.slot", "0"), resource.TestCheckResourceAttr("data.hypercore_vms.test", "vms.0.disks.0.size", "1.2"), diff --git a/internal/utils/vm_disk.go b/internal/utils/vm_disk.go index 5e5ac7d..f728ff0 100644 --- a/internal/utils/vm_disk.go +++ b/internal/utils/vm_disk.go @@ -398,7 +398,7 @@ func ValidateDiskSize(diskUUID string, oldSize float64, newSize float64) diag.Di return nil } -// Checks that source VM UUUID wasn't altered during update. +// Checks that source VM UUID wasn't altered during update. func ValidateDiskSourceVMUUIDUnchanged(diskUUID string, oldVMUUID string, newVMUUID string) diag.Diagnostic { if oldVMUUID != newVMUUID { return diag.NewErrorDiagnostic( From 88db5969abd6189b7dad5591e4c8dc1579d1edeb Mon Sep 17 00:00:00 2001 From: Domen Dobnikar <113340617+domendobnikar@users.noreply.github.com> Date: Fri, 5 Jun 2026 12:02:35 +0000 Subject: [PATCH 10/10] Removed deprecated code --- internal/utils/nic.go | 152 -------------------------------------- internal/utils/vm_disk.go | 92 ----------------------- 2 files changed, 244 deletions(-) diff --git a/internal/utils/nic.go b/internal/utils/nic.go index 518bcdc..8dba9cc 100644 --- a/internal/utils/nic.go +++ b/internal/utils/nic.go @@ -91,155 +91,3 @@ func ValidateNICSourceVMUUIDUnchanged(nicUUID string, oldVMUUID string, newVMUUI } return nil } - - -/* -func (vd *VMDisk) CreateOrUpdate( - vc *VMClone, - restClient RestClient, - ctx context.Context, -) (bool, bool, string, error) { - changed := false - vm := GetByName(vc.VMName, restClient, true) - vmUUID := AnyToString((*vm)["uuid"]) - vmDisks := AnyToListOfMap((*vm)["blockDevs"]) - - if vd.Size != nil { - existingDisk := vd.GetSpecificDisk(vmDisks, ctx) // from HC3 - desiredDisk := vd.BuildDiskPayload(vmUUID) - - tflog.Debug(ctx, fmt.Sprintf("Desired disk: %v\n", desiredDisk)) - tflog.Debug(ctx, fmt.Sprintf("Existing disk: %v\n", existingDisk)) - - if existingDisk != nil { - existingDiskSize := AnyToFloat64((*existingDisk)["capacity"]) / 1000 / 1000 / 1000 - existingDiskSlot := AnyToInteger64((*existingDisk)["slot"]) - existingDiskType := AnyToString((*existingDisk)["type"]) - desiredDiskSize := AnyToFloat64(desiredDisk["capacity"]) / 1000 / 1000 / 1000 - if existingDiskSize > desiredDiskSize { - return false, false, "", fmt.Errorf( - "Disk of type '%s' on slot %d can only be expanded. Use a different slot or use a larger size. %v GB > %v GB\n", - existingDiskType, existingDiskSlot, existingDiskSize, desiredDiskSize, - ) - } - } - - if existingDisk != nil { - if isSuperset(*existingDisk, desiredDisk) { - return false, vc.WasRebooted(), "", nil - } - - tflog.Debug(ctx, "Updating existing disk\n") - vd.UUID = vd.UpdateBlockDevice(vc, vmUUID, restClient, desiredDisk, *existingDisk, ctx) - changed = true - } else { - tflog.Debug(ctx, "Creating new disk\n") - vd.UUID = vd.CreateBlockDevice(restClient, desiredDisk, ctx) - changed = true - } - } - - return changed, vc.WasRebooted(), vd.UUID, nil -} - -func (vd *VMDisk) UpdateBlockDevice( - vc *VMClone, - vmUUID string, - restClient RestClient, - desiredDisk map[string]any, - existingDisk map[string]any, - ctx context.Context, -) string { - vc.DoShutdownSteps(vmUUID, SHUTDOWN_TIMEOUT_SECONDS, restClient, ctx) - - existingDiskUUID := AnyToString(existingDisk["uuid"]) - taskTag := restClient.UpdateRecord( - fmt.Sprintf("/rest/v1/VirDomainBlockDevice/%s", existingDiskUUID), - desiredDisk, - -1, - ctx, - ) - taskTag.WaitTask(restClient, ctx) - - return existingDiskUUID -} - -func (vd *VMDisk) CreateBlockDevice( - restClient RestClient, - desiredDisk map[string]any, - ctx context.Context, -) string { - taskTag, _, _ := restClient.CreateRecord( - "/rest/v1/VirDomainBlockDevice", - desiredDisk, - -1, - ) - taskTag.WaitTask(restClient, ctx) - - return taskTag.CreatedUUID -} - -// This function will be useful when dealing with IDE_CDROM type disks: so for the future -// nolint:unused -func (vd *VMDisk) EnsureAbsend( - vc *VMClone, - changedParams map[string]bool, - restClient RestClient, - ctx context.Context, -) (bool, bool, map[string]any) { - vm := GetByName(vc.VMName, restClient, true) - vmDisks := AnyToListOfMap((*vm)["blockDevs"]) - - if vd.Size != nil { - existingDisk := vd.GetSpecificDisk(vmDisks, ctx) - if existingDisk == nil { - return true, false, map[string]any{} // no disk - absent is already ensured - } - - diskUUID := AnyToString((*existingDisk)["uuid"]) - - // Remove the disk to ensure it's absence - vmUUID := AnyToString((*vm)["uuid"]) - vc.DoShutdownSteps(vmUUID, SHUTDOWN_TIMEOUT_SECONDS, restClient, ctx) - - taskTag := restClient.DeleteRecord( - fmt.Sprintf("/rest/v1/VirDomainBlockDevice/%s", diskUUID), - -1, - ctx, - ) - taskTag.WaitTask(restClient, ctx) - - vc.PowerUp(*vm, restClient, ctx) - return true, true, map[string]any{} - } - - return false, false, map[string]any{} -} - -func (vd *VMDisk) BuildDiskPayload(vmUUID string) map[string]any { - return map[string]any{ - "virDomainUUID": vmUUID, - "type": vd.Type, - "slot": vd.Slot, - "capacity": *vd.Size, - } -} - -func (vd *VMDisk) GetSpecificDisk(vmDisks []map[string]any, ctx context.Context) *map[string]any { - for _, vmDisk := range vmDisks { - vmDiskUUID := AnyToString(vmDisk["uuid"]) - vmDiskSlot := AnyToInteger64(vmDisk["slot"]) - vmDiskType := AnyToString(vmDisk["type"]) - if vmDiskUUID == vd.UUID { - tflog.Debug(ctx, fmt.Sprintf("Got disk by UUID: %v", vmDisk)) - return &vmDisk - } - - if vmDiskSlot == vd.Slot && vmDiskType == vd.Type { - tflog.Debug(ctx, fmt.Sprintf("Got disk by slot and type: %v", vmDisk)) - return &vmDisk - } - } - return nil -} -*/ diff --git a/internal/utils/vm_disk.go b/internal/utils/vm_disk.go index f728ff0..77a21b4 100644 --- a/internal/utils/vm_disk.go +++ b/internal/utils/vm_disk.go @@ -114,98 +114,6 @@ func UpdateVMDisk( return vmDisk, nil } -/* -func (vd *VMDisk) CreateOrUpdate( - - vc *VM, - restClient RestClient, - ctx context.Context, - - ) (bool, bool, string, error) { - changed := false - vm := GetVMByName(vc.VMName, restClient, true) - vmUUID := AnyToString((*vm)["uuid"]) - vmDisks := AnyToListOfMap((*vm)["blockDevs"]) - - if vd.Size != nil { - existingDisk := vd.Get(vmDisks, ctx) // from HC3 - desiredDisk := vd.BuildDiskPayload(vmUUID) - - tflog.Debug(ctx, fmt.Sprintf("Desired disk: %v\n", desiredDisk)) - tflog.Debug(ctx, fmt.Sprintf("Existing disk: %v\n", existingDisk)) - - if existingDisk != nil { - existingDiskSize := AnyToFloat64((*existingDisk)["capacity"]) / 1000 / 1000 / 1000 - existingDiskSlot := AnyToInteger64((*existingDisk)["slot"]) - existingDiskType := AnyToString((*existingDisk)["type"]) - desiredDiskSize := AnyToFloat64(desiredDisk["capacity"]) / 1000 / 1000 / 1000 - if existingDiskSize > desiredDiskSize { - return false, false, "", fmt.Errorf( - "disk of type '%s' on slot %d can only be expanded. Use a different slot or use a larger size. %v GB > %v GB", - existingDiskType, existingDiskSlot, existingDiskSize, desiredDiskSize, - ) - } - } - - if existingDisk != nil { - if isSuperset(*existingDisk, desiredDisk) { - return false, vc.WasRebooted(), "", nil - } - - tflog.Debug(ctx, "Updating existing disk\n") - vd.UUID = vd.UpdateBlockDevice(vc, vmUUID, restClient, desiredDisk, *existingDisk, ctx) - changed = true - } else { - tflog.Debug(ctx, "Creating new disk\n") - vd.UUID = vd.CreateBlockDevice(restClient, desiredDisk, ctx) - changed = true - } - } - - return changed, vc.WasRebooted(), vd.UUID, nil - } - -func (vd *VMDisk) UpdateBlockDevice( - - vc *VM, - vmUUID string, - restClient RestClient, - desiredDisk map[string]any, - existingDisk map[string]any, - ctx context.Context, - - ) string { - // TODO: this will be a new resource in the future, for now we act like the VMs are always shut down - // vc.DoShutdownSteps(vmUUID, SHUTDOWN_TIMEOUT_SECONDS, restClient, ctx) - - existingDiskUUID := AnyToString(existingDisk["uuid"]) - taskTag, _ := restClient.UpdateRecord( - fmt.Sprintf("/rest/v1/VirDomainBlockDevice/%s", existingDiskUUID), - desiredDisk, - -1, - ctx, - ) - taskTag.WaitTask(restClient, ctx) - - return existingDiskUUID - } - -func (vd *VMDisk) CreateBlockDevice( - restClient RestClient, - desiredDisk map[string]any, - ctx context.Context, -) string { - taskTag, _, _ := restClient.CreateRecord( - "/rest/v1/VirDomainBlockDevice", - desiredDisk, - -1, - ) - taskTag.WaitTask(restClient, ctx) - - return taskTag.CreatedUUID -} -*/ - // TODO: this function might be useful when dealing with IDE_CDROM type disks: so for the future // nolint:unused func (vd *VMDisk) EnsureAbsend(