From ce7cee738c711062e958a0d1b03d7d0942ed4ba6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20R=C3=A4nnare?= Date: Tue, 31 Jan 2023 14:36:27 +0100 Subject: [PATCH 1/3] Fixed two bugs: * Updating a switch would cause the error "Set-VMSwitch : Cannot convert 'System.Object[]' to the type 'System.String' required by parameter 'NetAdapterName'." * Changing a switch name would not be applied --- api/hyperv-winrm/vm_switch.go | 28 +++++++++++++++---- api/vm_switch.go | 3 +- .../resource_hyperv_network_switch.go | 8 ++++-- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/api/hyperv-winrm/vm_switch.go b/api/hyperv-winrm/vm_switch.go index 69fd979f..ac0388bd 100644 --- a/api/hyperv-winrm/vm_switch.go +++ b/api/hyperv-winrm/vm_switch.go @@ -3,6 +3,7 @@ package hyperv_winrm import ( "context" "encoding/json" + "fmt" "text/template" "github.com/taliesins/terraform-provider-hyperv/api" @@ -177,22 +178,33 @@ func (c *ClientConfig) GetVMSwitch(ctx context.Context, name string) (result api } type updateVMSwitchArgs struct { + VmSwitchId string VmSwitchJson string } var updateVMSwitchTemplate = template.Must(template.New("UpdateVMSwitch").Parse(` $ErrorActionPreference = 'Stop' Import-Module Hyper-V +$vmSwitchId = '{{.VmSwitchId}}' $vmSwitch = '{{.VmSwitchJson}}' | ConvertFrom-Json $minimumBandwidthMode = [Microsoft.HyperV.PowerShell.VMSwitchBandwidthMode]$vmSwitch.BandwidthReservationMode $switchType = [Microsoft.HyperV.PowerShell.VMSwitchType]$vmSwitch.SwitchType -$NetAdapterNames = @($vmSwitch.NetAdapterNames) + +if ($vmSwitch.NetAdapterNames.length -gt 0) { + $NetAdapterNames = [string]$vmSwitch.NetAdapterNames[0] +} + #when EnablePacketDirect=true it seems to throw an exception if EnableIov=true or EnableEmbeddedTeaming=true -$switchObject = Get-VMSwitch -Name "$($vmSwitch.Name)*" | ?{$_.Name -eq $vmSwitch.Name} +$switchObject = Get-VMSwitch -Name "$($vmSwitchId)*" | ?{$_.Name -eq $vmSwitchId} if (!$switchObject){ - throw "Switch does not exist - $($vmSwitch.Name)" + throw "Switch does not exist - $($vmSwitchId)" +} + + +if ($vmSwitchId -ne $vmSwitch.Name) { + Rename-VMSwitch $vmSwitchId -NewName $vmSwitch.Name } $SetVmSwitchArgs = @{} @@ -233,7 +245,8 @@ Set-VMSwitch @SetVmSwitchArgs func (c *ClientConfig) UpdateVMSwitch( ctx context.Context, - name string, + switchId string, + switchName string, notes string, allowManagementOS bool, // embeddedTeamingEnabled bool, @@ -248,8 +261,12 @@ func (c *ClientConfig) UpdateVMSwitch( defaultQueueVmmqQueuePairs int32, defaultQueueVrssEnabled bool, ) (err error) { + if len(netAdapterNames) > 1 { + return fmt.Errorf("[ERROR][hyperv] Can't update a switch with multiple net adapaters names (%v)", netAdapterNames) + } + vmSwitchJson, err := json.Marshal(api.VmSwitch{ - Name: name, + Name: switchName, Notes: notes, AllowManagementOS: allowManagementOS, //EmbeddedTeamingEnabled:embeddedTeamingEnabled, @@ -270,6 +287,7 @@ func (c *ClientConfig) UpdateVMSwitch( } err = c.WinRmClient.RunFireAndForgetScript(ctx, updateVMSwitchTemplate, updateVMSwitchArgs{ + VmSwitchId: switchId, VmSwitchJson: string(vmSwitchJson), }) diff --git a/api/vm_switch.go b/api/vm_switch.go index 6303d866..6307ea04 100644 --- a/api/vm_switch.go +++ b/api/vm_switch.go @@ -166,7 +166,8 @@ type HypervVmSwitchClient interface { GetVMSwitch(ctx context.Context, name string) (result VmSwitch, err error) UpdateVMSwitch( ctx context.Context, - name string, + switchId string, + switchName string, notes string, allowManagementOS bool, // embeddedTeamingEnabled bool, diff --git a/internal/provider/resource_hyperv_network_switch.go b/internal/provider/resource_hyperv_network_switch.go index b197a2f3..ab1a64af 100644 --- a/internal/provider/resource_hyperv_network_switch.go +++ b/internal/provider/resource_hyperv_network_switch.go @@ -369,7 +369,9 @@ func resourceHyperVNetworkSwitchUpdate(ctx context.Context, d *schema.ResourceDa log.Printf("[INFO][hyperv][update] updating hyperv switch: %#v", d) c := meta.(api.Client) - switchName := d.Id() + id := d.Id() + newName := d.Get("name").(string) + notes := (d.Get("notes")).(string) allowManagementOS := (d.Get("allow_management_os")).(bool) // embeddedTeamingEnabled := (d.Get("enable_embedded_teaming")).(bool) @@ -438,12 +440,14 @@ func resourceHyperVNetworkSwitchUpdate(ctx context.Context, d *schema.ResourceDa return diag.Errorf("[ERROR][hyperv][update] defaultQueueVmmqQueuePairs must be greater then 0") } - err := c.UpdateVMSwitch(ctx, switchName, notes, allowManagementOS, switchType, netAdapterNames, defaultFlowMinimumBandwidthAbsolute, defaultFlowMinimumBandwidthWeight, defaultQueueVmmqEnabled, defaultQueueVmmqQueuePairs, defaultQueueVrssEnabled) + err := c.UpdateVMSwitch(ctx, id, newName, notes, allowManagementOS, switchType, netAdapterNames, defaultFlowMinimumBandwidthAbsolute, defaultFlowMinimumBandwidthWeight, defaultQueueVmmqEnabled, defaultQueueVmmqQueuePairs, defaultQueueVrssEnabled) if err != nil { return diag.FromErr(err) } + d.SetId(newName) + log.Printf("[INFO][hyperv][update] updated hyperv switch: %#v", d) return resourceHyperVNetworkSwitchRead(ctx, d, meta) From b863b55d7c5b71c605adffba7b172d877ab778c7 Mon Sep 17 00:00:00 2001 From: Taliesin Sisson Date: Sun, 14 Jan 2024 23:29:18 +0000 Subject: [PATCH 2/3] Make it obvious that we passing in the old name and the new name of switch for renaming it --- api/hyperv-winrm/vm_switch.go | 21 ++++++++++----------- api/vm_switch.go | 4 ++-- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/api/hyperv-winrm/vm_switch.go b/api/hyperv-winrm/vm_switch.go index ac0388bd..ba3e7070 100644 --- a/api/hyperv-winrm/vm_switch.go +++ b/api/hyperv-winrm/vm_switch.go @@ -178,14 +178,14 @@ func (c *ClientConfig) GetVMSwitch(ctx context.Context, name string) (result api } type updateVMSwitchArgs struct { - VmSwitchId string + OldName string VmSwitchJson string } var updateVMSwitchTemplate = template.Must(template.New("UpdateVMSwitch").Parse(` $ErrorActionPreference = 'Stop' Import-Module Hyper-V -$vmSwitchId = '{{.VmSwitchId}}' +$oldName = '{{.OldName}}' $vmSwitch = '{{.VmSwitchJson}}' | ConvertFrom-Json $minimumBandwidthMode = [Microsoft.HyperV.PowerShell.VMSwitchBandwidthMode]$vmSwitch.BandwidthReservationMode $switchType = [Microsoft.HyperV.PowerShell.VMSwitchType]$vmSwitch.SwitchType @@ -196,15 +196,14 @@ if ($vmSwitch.NetAdapterNames.length -gt 0) { #when EnablePacketDirect=true it seems to throw an exception if EnableIov=true or EnableEmbeddedTeaming=true -$switchObject = Get-VMSwitch -Name "$($vmSwitchId)*" | ?{$_.Name -eq $vmSwitchId} +$switchObject = Get-VMSwitch -Name "$($oldName)*" | ?{$_.Name -eq $oldName} if (!$switchObject){ - throw "Switch does not exist - $($vmSwitchId)" + throw "Switch does not exist - $($oldName)" } - -if ($vmSwitchId -ne $vmSwitch.Name) { - Rename-VMSwitch $vmSwitchId -NewName $vmSwitch.Name +if ($oldName -ne $vmSwitch.Name) { + Rename-VMSwitch -Name $oldName -NewName $vmSwitch.Name } $SetVmSwitchArgs = @{} @@ -245,8 +244,8 @@ Set-VMSwitch @SetVmSwitchArgs func (c *ClientConfig) UpdateVMSwitch( ctx context.Context, - switchId string, - switchName string, + oldName string, + name string, notes string, allowManagementOS bool, // embeddedTeamingEnabled bool, @@ -266,7 +265,7 @@ func (c *ClientConfig) UpdateVMSwitch( } vmSwitchJson, err := json.Marshal(api.VmSwitch{ - Name: switchName, + Name: name, Notes: notes, AllowManagementOS: allowManagementOS, //EmbeddedTeamingEnabled:embeddedTeamingEnabled, @@ -287,7 +286,7 @@ func (c *ClientConfig) UpdateVMSwitch( } err = c.WinRmClient.RunFireAndForgetScript(ctx, updateVMSwitchTemplate, updateVMSwitchArgs{ - VmSwitchId: switchId, + OldName: oldName, VmSwitchJson: string(vmSwitchJson), }) diff --git a/api/vm_switch.go b/api/vm_switch.go index 6307ea04..ada356f6 100644 --- a/api/vm_switch.go +++ b/api/vm_switch.go @@ -166,8 +166,8 @@ type HypervVmSwitchClient interface { GetVMSwitch(ctx context.Context, name string) (result VmSwitch, err error) UpdateVMSwitch( ctx context.Context, - switchId string, - switchName string, + oldName string, + name string, notes string, allowManagementOS bool, // embeddedTeamingEnabled bool, From 3d7fd3110008297dcc6e0fad16189499d226d338 Mon Sep 17 00:00:00 2001 From: Taliesin Sisson Date: Mon, 15 Jan 2024 00:32:33 +0000 Subject: [PATCH 3/3] Not sure why the original PR was checking for multiple adaptors (NIC teaming) and failing an update. Perhaps its a particular property. Tested with: New-VMSwitch -Name testeme -NetAdapterName "Ethernet 2", "Ethernet" Rename-VMSwitch -Name testeme -NewName testme2 Set-VMSwitch -Name testme2 -AllowManagementOS:$false --- api/hyperv-winrm/vm_switch.go | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/api/hyperv-winrm/vm_switch.go b/api/hyperv-winrm/vm_switch.go index ba3e7070..40a6dc6b 100644 --- a/api/hyperv-winrm/vm_switch.go +++ b/api/hyperv-winrm/vm_switch.go @@ -3,7 +3,6 @@ package hyperv_winrm import ( "context" "encoding/json" - "fmt" "text/template" "github.com/taliesins/terraform-provider-hyperv/api" @@ -189,10 +188,7 @@ $oldName = '{{.OldName}}' $vmSwitch = '{{.VmSwitchJson}}' | ConvertFrom-Json $minimumBandwidthMode = [Microsoft.HyperV.PowerShell.VMSwitchBandwidthMode]$vmSwitch.BandwidthReservationMode $switchType = [Microsoft.HyperV.PowerShell.VMSwitchType]$vmSwitch.SwitchType - -if ($vmSwitch.NetAdapterNames.length -gt 0) { - $NetAdapterNames = [string]$vmSwitch.NetAdapterNames[0] -} +$NetAdapterNames = @($vmSwitch.NetAdapterNames) #when EnablePacketDirect=true it seems to throw an exception if EnableIov=true or EnableEmbeddedTeaming=true @@ -260,10 +256,6 @@ func (c *ClientConfig) UpdateVMSwitch( defaultQueueVmmqQueuePairs int32, defaultQueueVrssEnabled bool, ) (err error) { - if len(netAdapterNames) > 1 { - return fmt.Errorf("[ERROR][hyperv] Can't update a switch with multiple net adapaters names (%v)", netAdapterNames) - } - vmSwitchJson, err := json.Marshal(api.VmSwitch{ Name: name, Notes: notes,