Public/VM/New-VergeNIC.ps1
|
function New-VergeNIC { <# .SYNOPSIS Adds a new network interface to a VergeOS virtual machine. .DESCRIPTION New-VergeNIC creates a new virtual network interface and attaches it to a VM. The NIC can be connected to a virtual network (vnet) and configured with various interface types. .PARAMETER VM A VM object from Get-VergeVM. Accepts pipeline input. .PARAMETER VMName The name of the VM to add the NIC to. .PARAMETER VMKey The key (ID) of the VM to add the NIC to. .PARAMETER Name The name for the new NIC. If not specified, uses auto-generated name. .PARAMETER NetworkKey The key (ID) of the virtual network to connect to. .PARAMETER NetworkName The name of the virtual network to connect to. .PARAMETER Interface The NIC interface type. Default is 'virtio'. Valid values: virtio, e1000, e1000e, rtl8139, pcnet, igb, vmxnet3 .PARAMETER MACAddress A specific MAC address to assign. If not specified, one is auto-generated. Format: xx:xx:xx:xx:xx:xx .PARAMETER IPAddress A static IP address to assign to the NIC (requires DHCP reservation). .PARAMETER Description An optional description for the NIC. .PARAMETER Disabled Create the NIC in disabled state. .PARAMETER PassThru Return the created NIC object. .PARAMETER Server The VergeOS connection to use. Defaults to the current default connection. .EXAMPLE New-VergeNIC -VMName "WebServer01" -NetworkName "Internal" Adds a NIC connected to the "Internal" network. .EXAMPLE New-VergeNIC -VMName "WebServer01" -NetworkKey 5 -Interface e1000e Adds an Intel e1000e NIC connected to network with key 5. .EXAMPLE Get-VergeVM -Name "Web*" | New-VergeNIC -NetworkName "DMZ" -PassThru Adds a NIC to all web servers and returns the created NICs. .EXAMPLE New-VergeNIC -VMName "LegacyApp" -NetworkName "Internal" -Interface vmxnet3 Adds a VMware-compatible NIC for migrated workloads. .OUTPUTS None by default. Verge.NIC when -PassThru is specified. .NOTES The VM should be powered off when adding NICs for best results, though hot-add may be supported depending on configuration. #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium', DefaultParameterSetName = 'ByVMName')] [OutputType([PSCustomObject])] param( [Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'ByVMObject')] [Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'ByVMObjectNetKey')] [PSTypeName('Verge.VM')] [PSCustomObject]$VM, [Parameter(Mandatory, Position = 0, ParameterSetName = 'ByVMName')] [Parameter(Mandatory, Position = 0, ParameterSetName = 'ByVMNameNetKey')] [string]$VMName, [Parameter(Mandatory, ParameterSetName = 'ByVMKey')] [Parameter(Mandatory, ParameterSetName = 'ByVMKeyNetKey')] [int]$VMKey, [Parameter()] [ValidateLength(1, 128)] [string]$Name, [Parameter(Mandatory, ParameterSetName = 'ByVMNameNetKey')] [Parameter(Mandatory, ParameterSetName = 'ByVMKeyNetKey')] [Parameter(Mandatory, ParameterSetName = 'ByVMObjectNetKey')] [int]$NetworkKey, [Parameter(ParameterSetName = 'ByVMName')] [Parameter(ParameterSetName = 'ByVMKey')] [Parameter(ParameterSetName = 'ByVMObject')] [string]$NetworkName, [Parameter()] [ValidateSet('virtio', 'e1000', 'e1000e', 'rtl8139', 'pcnet', 'igb', 'vmxnet3')] [string]$Interface = 'virtio', [Parameter()] [ValidatePattern('^([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$')] [string]$MACAddress, [Parameter()] [string]$IPAddress, [Parameter()] [ValidateLength(0, 2048)] [string]$Description, [Parameter()] [switch]$Disabled, [Parameter()] [switch]$PassThru, [Parameter()] [object]$Server ) begin { # Resolve connection if (-not $Server) { $Server = $script:DefaultConnection } if (-not $Server) { throw [System.InvalidOperationException]::new( 'Not connected to VergeOS. Use Connect-VergeOS to establish a connection.' ) } # Resolve network by name if provided $resolvedNetworkKey = $null if ($NetworkKey) { $resolvedNetworkKey = $NetworkKey } elseif ($NetworkName) { try { $networks = Invoke-VergeAPI -Method GET -Endpoint 'vnets' -Query @{ filter = "name eq '$NetworkName'" fields = '$key,name' } -Connection $Server if ($networks -and $networks.Count -gt 0) { $net = $networks | Select-Object -First 1 $resolvedNetworkKey = $net.'$key' ?? $net.key Write-Verbose "Resolved network '$NetworkName' to key $resolvedNetworkKey" } elseif ($networks -and $networks.'$key') { # Single object response $resolvedNetworkKey = $networks.'$key' Write-Verbose "Resolved network '$NetworkName' to key $resolvedNetworkKey" } else { throw "Network '$NetworkName' not found" } } catch { throw "Failed to resolve network '$NetworkName': $($_.Exception.Message)" } } } process { # Resolve VM based on parameter set $targetVMs = switch -Wildcard ($PSCmdlet.ParameterSetName) { 'ByVMName*' { Get-VergeVM -Name $VMName -Server $Server } 'ByVMKey*' { Get-VergeVM -Key $VMKey -Server $Server } 'ByVMObject*' { $VM } } foreach ($targetVM in $targetVMs) { if (-not $targetVM) { continue } # Check if VM is a snapshot if ($targetVM.IsSnapshot) { Write-Error -Message "Cannot add NIC to '$($targetVM.Name)': VM is a snapshot" -ErrorId 'CannotModifySnapshot' continue } # Build request body $body = @{ machine = $targetVM.MachineKey interface = $Interface enabled = -not $Disabled.IsPresent } if ($Name) { $body['name'] = $Name } if ($resolvedNetworkKey) { $body['vnet'] = $resolvedNetworkKey } if ($MACAddress) { $body['macaddress'] = $MACAddress.ToLower() } if ($IPAddress) { $body['ipaddress'] = $IPAddress } if ($Description) { $body['description'] = $Description } $nicDesc = if ($Name) { $Name } else { 'NIC' } $netDesc = if ($NetworkName) { " on '$NetworkName'" } elseif ($resolvedNetworkKey) { " on network $resolvedNetworkKey" } else { '' } if ($PSCmdlet.ShouldProcess($targetVM.Name, "Add $nicDesc ($Interface)$netDesc")) { try { Write-Verbose "Adding NIC to VM '$($targetVM.Name)'" $response = Invoke-VergeAPI -Method POST -Endpoint 'machine_nics' -Body $body -Connection $Server if ($response) { Write-Verbose "NIC added successfully with key: $($response.'$key' ?? $response.key ?? 'unknown')" if ($PassThru) { # Return the NIC using Get-VergeNIC $nicKey = $response.'$key' ?? $response.key if ($nicKey) { Get-VergeNIC -VM $targetVM -Server $Server | Where-Object { $_.Key -eq $nicKey } } } } } catch { Write-Error -Message "Failed to add NIC to VM '$($targetVM.Name)': $($_.Exception.Message)" -ErrorId 'NICAddFailed' } } } } } |