Public/cloud-network.ps1
|
function Get-CloudNetwork { <# .SYNOPSIS Gets networks from the Cloud Server. .DESCRIPTION Retrieves a list of networks. Automatically handles token refresh. .PARAMETER Name Optional. Filter by network name. .PARAMETER ID Optional. Filter by network ID .EXAMPLE # Get all networks Get-CloudNetwork .EXAMPLE # Get network by ID Get-CloudNetwork -ID 5 .EXAMPLE # Get network by name Get-CloudNetwork -Name "VPN-net" #> [CmdletBinding()] param( [Parameter(Mandatory = $false)] [string]$Name, [Parameter(Mandatory = $false)] [Nullable[int]]$ID ) $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/network" if ($PSBoundParameters.ContainsKey('ID')) { $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/network/${ID}" $response = Invoke-CloudApiRequest -Uri $uri -Method Get $network = $response.network return $network } else { $response = Invoke-CloudApiRequest -Uri $uri -Method Get $networks = $response.networks if ($Name) { $networks = $networks | Where-Object { $_.name -like "*$Name*" } } return $networks } } function Get-CloudNetworkTemplate { <# .SYNOPSIS Gets network templates from the Cloud Server. .DESCRIPTION Retrieves a list of network templates. Automatically handles token refresh. .PARAMETER Name Optional. Filter by network template name. .PARAMETER ID Optional. Filter by network template ID (can be 0) .EXAMPLE # Get all network templates Get-CloudNetworkTemplate .EXAMPLE # Get network template by ID Get-CloudNetworkTemplate -ID 5 .EXAMPLE # Get network template by name Get-CloudNetworkTemplate -Name "Linux-Net-Template" #> [CmdletBinding()] param( [Parameter(Mandatory = $false)] [string]$Name, [Parameter(Mandatory = $false)] [Nullable[int]]$ID ) $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/network/template" if ($PSBoundParameters.ContainsKey('ID')) { # Query specific template by ID $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/network/template/${ID}" $response = Invoke-CloudApiRequest -Uri $uri -Method Get # If the API returns the template directly, return it # Otherwise filter (adjust based on actual API response structure) return $response.template } else { # Query all templates $response = Invoke-CloudApiRequest -Uri $uri -Method Get $nettemplates = $response.template if ($Name) { $nettemplates = $nettemplates | Where-Object { $_.name -like "*$Name*" } } return $nettemplates } } function New-CloudNetworkTemplate { <# .SYNOPSIS Creates a new virtual network template in the Cloud Server. .DESCRIPTION Creates a virtual network template. Automatically handles token refresh. .PARAMETER Name Name of the network template .PARAMETER VnMad Virtual Network Manager driver (e.g., "bridge", "vxlan", "ovswitch") .PARAMETER Bridge Bridge name for the network .PARAMETER NetworkAddress Network address (e.g., "192.168.1.0") .PARAMETER NetworkMask Network mask (e.g., "255.255.255.0") .PARAMETER Gateway Optional gateway address .PARAMETER DNS Optional DNS server address .PARAMETER Description Optional description of the network template .PARAMETER Template Full network template as a string (alternative to individual parameters) .EXAMPLE # Create a new network template with individual flags New-CloudNetworkTemplate -Name "office-network" -VnMad "bridge" -Bridge "br0" -NetworkAddress "192.168.1.0" -NetworkMask "255.255.255.0" .EXAMPLE # Create a new network template with individual flags New-CloudNetworkTemplate -Name "dmz-network" -VnMad "bridge" -Bridge "br1" -NetworkAddress "10.0.0.0" -NetworkMask "255.255.255.0" -Gateway "10.0.0.1" -DNS "8.8.8.8" .EXAMPLE # Create a new network template with a template variable $template = @" name = "custom-network" vn_mad = "bridge" bridge = "br0" network_address = "172.16.0.0" network_mask = "255.255.0.0" gateway = "172.16.0.1" dns = "8.8.8.8 8.8.4.4" description = "Custom network template" "@ New-CloudNetworkTemplate -Template $template #> [CmdletBinding(DefaultParameterSetName='Individual')] param( [Parameter(Mandatory = $true, ParameterSetName='Individual')] [string]$Name, [Parameter(Mandatory = $true, ParameterSetName='Individual')] [ValidateSet('bridge', 'vxlan', 'ovswitch', 'ebtables', 'fw', '802.1Q', 'vlan')] [string]$VnMad, [Parameter(Mandatory = $true, ParameterSetName='Individual')] [string]$Bridge, [Parameter(Mandatory = $true, ParameterSetName='Individual')] [string]$NetworkAddress, [Parameter(Mandatory = $true, ParameterSetName='Individual')] [string]$NetworkMask, [Parameter(Mandatory = $false, ParameterSetName='Individual')] [string]$Gateway, [Parameter(Mandatory = $false, ParameterSetName='Individual')] [string]$DNS, [Parameter(Mandatory = $false, ParameterSetName='Individual')] [string]$Description, [Parameter(Mandatory = $true, ParameterSetName='Template')] [string]$Template ) # Build template string if using individual parameters if ($PSCmdlet.ParameterSetName -eq 'Individual') { $templateLines = @( "name = `"$Name`"" "vn_mad = `"$VnMad`"" "bridge = `"$Bridge`"" "network_address = `"$NetworkAddress`"" "network_mask = `"$NetworkMask`"" ) # Add optional parameters if provided if ($Gateway) { $templateLines += "gateway = `"$Gateway`"" } if ($DNS) { $templateLines += "dns = `"$DNS`"" } if ($Description) { $templateLines += "description = `"$Description`"" } $Template = $templateLines -join "`n" } # Pass hashtable directly - Invoke-CloudApiRequest will convert to JSON $templateData = @{ template = $Template } $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/network/template" Write-Verbose "Request URI: $uri" Write-Verbose "Network Template:`n$Template" $response = Invoke-CloudApiRequest -Uri $uri -Method Post -Body $templateData Write-Host "Network template created successfully." -ForegroundColor Green return $response } function Update-CloudNetworkOwner { <# .SYNOPSIS Updates the ownership of a network in the Cloud Server. .DESCRIPTION Changes the user and/or group ownership of a network. Prompts for confirmation. .PARAMETER ID Required. ID of the network. .PARAMETER UserID Required. ID of the user to own the network. .PARAMETER GroupID Optional. ID of the group to own the network. .EXAMPLE # Change the owner of a network to a specific user Update-CloudNetworkOwner -ID 5 -UserID 2 .EXAMPLE # Change the owner of a network to a specific user and group Update-CloudNetworkOwner -ID 5 -UserID 2 -GroupID 100 .EXAMPLE # Change the owner of a network to a specific user, bypassing confirmation prompt Update-CloudNetworkOwner -ID 5 -UserID 2 -Confirm:$false #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact='High')] param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [int]$ID, [Parameter(Mandatory = $true)] [Alias('User')] [int]$UserID, [Parameter(Mandatory = $false)] [Alias('Group')] [int]$GroupID ) process { # Build the update body $body = [PSCustomObject]@{ user = $UserID } if ($PSBoundParameters.ContainsKey('GroupID')) { $body | Add-Member -NotePropertyName 'group' -NotePropertyValue $GroupID } $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/network/${ID}/ownership" # Build action description for confirmation $actionParts = @("Change owner to User ID $UserID") if ($PSBoundParameters.ContainsKey('GroupID')) { $actionParts += "Group ID $GroupID" } $actionDescription = $actionParts -join " and " # Use the helper function Invoke-CloudResourceUpdate ` -CallerPSCmdlet $PSCmdlet ` -ResourceType "Network" ` -ID $ID ` -Uri $uri ` -Body $body ` -Action $actionDescription ` -GetResourceScript { Get-CloudNetwork -ID $ID } ` -SuccessMessage "Network $ID ownership updated successfully." } } function Update-CloudNetworkPermissions { <# .SYNOPSIS Updates the permissions of a network in the Cloud Server. .DESCRIPTION Changes the permission of a network. Prompts for confirmation. .PARAMETER ID Required. ID of the network. .PARAMETER OwnerUse Optional. True or false, enable OwnerUse .PARAMETER OwnerManage Optional. True or false, enable OwnerManage .PARAMETER OwnerAdmin Optional. True or false, enable OwnerAdmin .PARAMETER GroupUse Optional. True or false, enable GroupUse .PARAMETER GroupManage Optional. True or false, enable GroupManage .PARAMETER GroupAdmin Optional. True or false, enable GroupAdmin .PARAMETER OtherUse Optional. True or false, enable OtherUse .PARAMETER OtherManage Optional. True or false, enable OtherManage .PARAMETER OtherAdmin Optional. True or false, enable OtherManage .EXAMPLE # Give group users permission to use the network Update-CloudNetworkPermissions -ID 35 -GroupUse $true .EXAMPLE # Deny group admin permission to the network Update-CloudNetworkPermissions -ID 35 -GroupAdmin $false .EXAMPLE # Set multiple permissions at once Update-CloudNetworkPermissions -ID 35 -GroupUse $true -GroupManage $true -OtherUse $true #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact='High')] param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [int]$ID, [Parameter(Mandatory = $false)] [bool]$OwnerUse, [Parameter(Mandatory = $false)] [bool]$OwnerManage, [Parameter(Mandatory = $false)] [bool]$OwnerAdmin, [Parameter(Mandatory = $false)] [bool]$GroupUse, [Parameter(Mandatory = $false)] [bool]$GroupManage, [Parameter(Mandatory = $false)] [bool]$GroupAdmin, [Parameter(Mandatory = $false)] [bool]$OtherUse, [Parameter(Mandatory = $false)] [bool]$OtherManage, [Parameter(Mandatory = $false)] [bool]$OtherAdmin ) process { # Build the permissions object structure as shown in the API spec $permissions = @{} if ($PSBoundParameters.ContainsKey('OwnerUse')) { $permissions['owner_use'] = $OwnerUse } if ($PSBoundParameters.ContainsKey('OwnerManage')) { $permissions['owner_manage'] = $OwnerManage } if ($PSBoundParameters.ContainsKey('OwnerAdmin')) { $permissions['owner_admin'] = $OwnerAdmin } if ($PSBoundParameters.ContainsKey('GroupUse')) { $permissions['group_use'] = $GroupUse } if ($PSBoundParameters.ContainsKey('GroupManage')) { $permissions['group_manage'] = $GroupManage } if ($PSBoundParameters.ContainsKey('GroupAdmin')) { $permissions['group_admin'] = $GroupAdmin } if ($PSBoundParameters.ContainsKey('OtherUse')) { $permissions['other_use'] = $OtherUse } if ($PSBoundParameters.ContainsKey('OtherManage')) { $permissions['other_manage'] = $OtherManage } if ($PSBoundParameters.ContainsKey('OtherAdmin')) { $permissions['other_admin'] = $OtherAdmin } # Create the body with the permissions nested structure $body = @{ permissions = $permissions } $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/network/${ID}/permissions" Invoke-CloudResourceUpdate ` -CallerPSCmdlet $PSCmdlet ` -ResourceType "Network" ` -ID $ID ` -Uri $uri ` -Body $body ` -Action "Update permissions" ` -GetResourceScript { Get-CloudNetwork -ID $ID } } } function New-CloudNetwork { <# .SYNOPSIS Creates a new virtual network on the Cloud Server. .DESCRIPTION Creates a new virtual network using a template string or by specifying a cluster ID and template configuration. .PARAMETER ClusterID Required. The cluster ID where the network will be created. .PARAMETER TemplateText Required. The network template in OpenNebula format. This should be a multi-line string containing the network configuration. .PARAMETER Name Optional. Name of the network. Can be included in the template text instead. .PARAMETER Bridge Optional. Bridge name (e.g., 'br0', 'virbr0'). .PARAMETER BridgeType Optional. Bridge type (e.g., 'linux', 'openvswitch'). .PARAMETER VNMad Optional. Virtual Network Manager driver (e.g., 'fw', 'bridge', 'ovswitch'). .PARAMETER Gateway Optional. Gateway IP address. .PARAMETER NetworkMask Optional. Network mask (e.g., '255.255.255.0'). .PARAMETER DNS Optional. DNS servers (space-separated string, e.g., "8.8.8.8 8.8.4.4"). .PARAMETER NetworkAddress Optional. Network address (e.g., '192.168.1.0'). .PARAMETER PassThru Optional. If specified, returns the created network object. .EXAMPLE # Create a network New-CloudNetwork -ClusterID 0 -TemplateText @" NAME = "Production Network" BRIDGE = br0 BRIDGE_TYPE = linux VN_MAD = fw GATEWAY = 192.168.1.1 NETWORK_MASK = 255.255.255.0 VLAN_ID = 100 VLAN = YES DNS = "8.8.8.8 8.8.4.4" "@ .EXAMPLE # Create a network using individual parameters New-CloudNetwork -ClusterID 0 -Name "Dev Network" -Bridge "virbr0" -BridgeType "linux" -VNMad "fw" -Gateway "10.0.0.1" -NetworkMask "255.255.255.0" .EXAMPLE # Create and return the network object $network = New-CloudNetwork -ClusterID 0 -Name "Test Net" -Bridge "br1" -PassThru #> [CmdletBinding(DefaultParameterSetName='Template', SupportsShouldProcess, ConfirmImpact='Medium')] param( [Parameter(Mandatory = $true, ParameterSetName='Template')] [Parameter(Mandatory = $true, ParameterSetName='Parameters')] [int]$ClusterID, [Parameter(Mandatory = $true, ParameterSetName='Template')] [string]$TemplateText, [Parameter(Mandatory = $true, ParameterSetName='Parameters')] [string]$Name, [Parameter(Mandatory = $false, ParameterSetName='Parameters')] [string]$Bridge, [Parameter(Mandatory = $false, ParameterSetName='Parameters')] [string]$BridgeType, [Parameter(Mandatory = $false, ParameterSetName='Parameters')] [string]$VNMad, [Parameter(Mandatory = $false, ParameterSetName='Parameters')] [string]$Gateway, [Parameter(Mandatory = $false, ParameterSetName='Parameters')] [string]$NetworkMask, [Parameter(Mandatory = $false, ParameterSetName='Parameters')] [string]$DNS, [Parameter(Mandatory = $false, ParameterSetName='Parameters')] [string]$NetworkAddress, [Parameter(Mandatory = $false, ParameterSetName='Parameters')] [string]$Description, [Parameter(Mandatory = $false)] [switch]$PassThru ) process { # Build template string based on parameter set if ($PSCmdlet.ParameterSetName -eq 'Parameters') { $templateComponents = @() $templateComponents += "NAME = `"$Name`"" if ($Bridge) { $templateComponents += "BRIDGE = $Bridge" } if ($BridgeType) { $templateComponents += "BRIDGE_TYPE = $BridgeType" } if ($VNMad) { $templateComponents += "VN_MAD = $VNMad" } if ($Gateway) { $templateComponents += "GATEWAY = $Gateway" } if ($NetworkMask) { $templateComponents += "NETWORK_MASK = $NetworkMask" } if ($DNS) { $templateComponents += "DNS = `"$DNS`"" } if ($NetworkAddress) { $templateComponents += "NETWORK_ADDRESS = $NetworkAddress" } if ($Description) { $templateComponents += "DESCRIPTION = `"$Description`"" } $TemplateText = $templateComponents -join "`n" } Write-Verbose "Network template:`n$TemplateText" # Build the request body - template must be a string $body = @{ cluster = $ClusterID template = $TemplateText } Write-Verbose "Request body: $($body | ConvertTo-Json)" $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/network" $networkName = if ($PSCmdlet.ParameterSetName -eq 'Parameters') { "'$Name'" } else { "in cluster $ClusterID" } if ($PSCmdlet.ShouldProcess($networkName, "Create new network")) { try { $response = Invoke-RestMethod -Uri $uri -Method Post -Body ($body | ConvertTo-Json) -ContentType 'application/json' -Headers $script:CloudConnection.Headers -UseBasicParsing # Extract the network ID from the response $networkId = $response.network Write-Host "Successfully created network with ID: $networkId" -ForegroundColor Green if ($PassThru) { # Return the newly created network object Get-CloudNetwork -ID $networkId } else { return $networkId } } catch { Write-Error "Failed to create network: $_" throw } } } } function Rename-CloudNetwork { <# .SYNOPSIS Rename a virtual network in the Cloud Server. .DESCRIPTION Renames a virtual network. Automatically handles token refresh. .PARAMETER Name New name of the network .PARAMETER ID ID of the network .EXAMPLE # Rename a cloud network Rename-CloudNetwork -Name "new-name" -ID 5 #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string]$Name, [Parameter(Mandatory = $true,ValueFromPipelineByPropertyName = $true)] [int]$ID ) $newname = @{ name = $Name } $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/network/${ID}/name" $response = Invoke-CloudApiRequest -Uri $uri -Method Patch -Body $newname return $response } function Remove-CloudNetwork { <# .SYNOPSIS Removes a network from the Cloud Server. .DESCRIPTION Removes a network. Automatically handles token refresh. .PARAMETER Name Required. Network ID. .EXAMPLE # Remove network with confirmation prompt (default behavior): Remove-CloudNetwork -ID 3 Confirm Are you sure you want to perform this action? Performing the operation "Remove Network" on target "Network ID 3 (MyNetwork)". [Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"): Y .EXAMPLE # Remove network without confirmation prompt: Remove-CloudNetwork -ID 3 -Confirm:$false #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact='High')] param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [int]$ID ) process { $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/network/${ID}" Invoke-CloudResourceRemoval ` -CallerPSCmdlet $PSCmdlet ` -ResourceType "Network" ` -ID $ID ` -Uri $uri ` -GetResourceScript { Get-CloudNetwork -ID $ID } } } function Lock-CloudNetwork { <# .SYNOPSIS Lock a virtual network in the Cloud Server. .DESCRIPTION Lock a virtual network. Automatically handles token refresh. .PARAMETER ID ID of the network .PARAMETER Level Lock level (USE, MANAGE, ADMIN, ALL) .PARAMETER Test When set, performs a test lock instead of a real one. .EXAMPLE # Lock a cloud network to admin operations Lock-CloudNetwork -ID 5 -Level ADMIN .EXAMPLE # Test locking a cloud network to use operations Lock-CloudNetwork -ID 5 -Level USE -Test .EXAMPLE # Lock a cloud network using a pipeline input Get-CloudNetwork -ID 3 | Lock-CloudNetwork -Level MANAGE #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact='High')] param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [int]$ID, [Parameter(Mandatory = $true)] [ValidateSet('USE','MANAGE','ADMIN','ALL')] [string]$Level, [Parameter(Mandatory = $false)] [switch]$Test ) process { $body = @{ level = $Level test = $Test.IsPresent } Write-Verbose "Lock body: $($body | ConvertTo-Json)" # Use the correct lock endpoint $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/network/${ID}/lock" if ($PSCmdlet.ShouldProcess("Network ID $ID", "Lock network at level $Level")) { try { $response = Invoke-RestMethod -Uri $uri -Method PATCH -Body ($body | ConvertTo-Json) -ContentType 'application/json' -Headers $script:CloudConnection.Headers -UseBasicParsing Write-Host "Successfully locked network ID $ID at level $Level" -ForegroundColor Green } catch { Write-Error "Failed to lock network ID ${ID}: $_" throw } } } } function Unlock-CloudNetwork { <# .SYNOPSIS Unlock a virtual network in the Cloud Server. .DESCRIPTION Unlock a virtual network. Automatically handles token refresh. .PARAMETER ID ID of the network .PARAMETER Level Unlock level (USE, MANAGE, ADMIN, ALL) .PARAMETER Test When set, performs a test unlock instead of a real one. .EXAMPLE # Unlock a cloud network Unlock-CloudNetwork -ID 5 .EXAMPLE # Unlock a cloud network using a pipeline input Get-CloudNetwork -ID 3 | Unlock-CloudNetwork #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact='High')] param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [int]$ID, [Parameter(Mandatory = $false)] [switch]$Test ) process { $body = @{ test = $Test.IsPresent } Write-Verbose "Unlock body: $($body | ConvertTo-Json)" # Use the correct unlock endpoint $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/network/${ID}/unlock" if ($PSCmdlet.ShouldProcess("Network ID $ID", "Unlock network")) { try { $response = Invoke-RestMethod -Uri $uri -Method PATCH -Body ($body | ConvertTo-Json) -ContentType 'application/json' -Headers $script:CloudConnection.Headers -UseBasicParsing Write-Host "Successfully unlocked network ID $ID" -ForegroundColor Green } catch { Write-Error "Failed to unlock network ID ${ID}: $_" throw } } } } function Copy-CloudNetwork { <# .SYNOPSIS Clone a network in the Cloud Server. .DESCRIPTION Creates a clone network. Automatically handles token refresh. .PARAMETER Name Required. Name of the new network .PARAMETER ID Required. ID of the the network you wish to clone .EXAMPLE # Clone the network and do not clone the associated image Copy-CloudNetwork -Name "gateway-network" -ID 5 #> [CmdletBinding(DefaultParameterSetName='Individual')] param( [Parameter(Mandatory = $true)] [string]$Name, [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [int]$ID ) $networkData = [PSCustomObject]@{ NAME=$Name } $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/network/${ID}/clone" Write-Verbose "Request URI: $uri" Write-Verbose "Network:`n$NetworkData" $response = Invoke-CloudApiRequest -Uri $uri -Method POST -Body $networkData return $response } function Lock-CloudNetworkTemplate { <# .SYNOPSIS Lock a virtual network template in the Cloud Server. .DESCRIPTION Lock a virtual network template. Automatically handles token refresh. .PARAMETER ID ID of the network .PARAMETER Level Lock level (USE, MANAGE, ADMIN, ALL) .PARAMETER Test When set, performs a test lock instead of a real one. .EXAMPLE # Lock a cloud network template to admin operations Lock-CloudNetworkTemplate -ID 5 -Level ADMIN .EXAMPLE # Test locking a cloud network template to use operations Lock-CloudNetworkTemplate -ID 5 -Level USE -Test .EXAMPLE # Lock a network template using a pipeline input Get-CloudNetworkTemplate -ID 3 | Lock-CloudNetworkTemplate -Level MANAGE #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact='High')] param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [int]$ID, [Parameter(Mandatory = $true)] [ValidateSet('USE','MANAGE','ADMIN','ALL')] [string]$Level, [Parameter(Mandatory = $false)] [switch]$Test ) process { $body = @{ level = $Level test = $Test.IsPresent } Write-Verbose "Lock body: $($body | ConvertTo-Json)" # Use the correct lock endpoint $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/network/template/${ID}/lock" if ($PSCmdlet.ShouldProcess("Network ID $ID", "Lock network at level $Level")) { try { $response = Invoke-RestMethod -Uri $uri -Method PATCH -Body ($body | ConvertTo-Json) -ContentType 'application/json' -Headers $script:CloudConnection.Headers -UseBasicParsing Write-Host "Successfully locked network ID $ID at level $Level" -ForegroundColor Green } catch { Write-Error "Failed to lock network ID ${ID}: $_" throw } } } } function Unlock-CloudNetworkTemplate { <# .SYNOPSIS Unlock a virtual network template in the Cloud Server. .DESCRIPTION Unlock a virtual network template. Automatically handles token refresh. .PARAMETER ID ID of the network .PARAMETER Level Unlock level (USE, MANAGE, ADMIN, ALL) .PARAMETER Test When set, performs a test unlock instead of a real one. .EXAMPLE # Unlock a network template Unlock-CloudNetworkTemplate -ID 5 .EXAMPLE # Unlock a network template using a pipeline input Get-CloudNetworkTemplate -ID 3 | Unlock-CloudNetworkTemplate #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact='High')] param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [int]$ID, [Parameter(Mandatory = $false)] [switch]$Test ) process { $body = @{ test = $Test.IsPresent } Write-Verbose "Unlock body: $($body | ConvertTo-Json)" # Use the correct unlock endpoint $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/network/template/${ID}/unlock" if ($PSCmdlet.ShouldProcess("Network ID $ID", "Unlock network")) { try { $response = Invoke-RestMethod -Uri $uri -Method PATCH -Body ($body | ConvertTo-Json) -ContentType 'application/json' -Headers $script:CloudConnection.Headers -UseBasicParsing Write-Host "Successfully unlocked network ID $ID" -ForegroundColor Green } catch { Write-Error "Failed to unlock network ID ${ID}: $_" throw } } } } function Copy-CloudNetworkTemplate { <# .SYNOPSIS Clone a network in the Cloud Server. .DESCRIPTION Creates a clone network. Automatically handles token refresh. .PARAMETER Name Required. Name of the new network .PARAMETER ID Required. ID of the the network you wish to clone .EXAMPLE # Copy a network template Copy-CloudNetworkTemplate -Name "new-gateway-network" -ID 5 #> [CmdletBinding(DefaultParameterSetName='Individual')] param( [Parameter(Mandatory = $true)] [string]$Name, [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [int]$ID ) $networkData = [PSCustomObject]@{ NAME=$Name } $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/network/template/${ID}/clone" Write-Verbose "Request URI: $uri" Write-Verbose "Network:`n$NetworkData" $response = Invoke-CloudApiRequest -Uri $uri -Method POST -Body $networkData return $response } function Update-CloudNetworkTemplateOwner { <# .SYNOPSIS Updates the ownership of a network in the Cloud Server. .DESCRIPTION Changes the user and/or group ownership of a network. Prompts for confirmation. .PARAMETER ID Required. ID of the network. .PARAMETER UserID Required. ID of the user to own the network. .PARAMETER GroupID Optional. ID of the group to own the network. .EXAMPLE # Set a network template's owner to a user Update-CloudNetworkTemplateOwner -ID 5 -UserID 2 .EXAMPLE # Set a network template's owner to a user and group Update-CloudNetworkTemplateOwner -ID 5 -UserID 2 -GroupID 100 .EXAMPLE # Set a network template's owner to a user, bypassing the confirmation prompt Update-CloudNetworkTemplateOwner -ID 5 -UserID 2 -Confirm:$false #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact='High')] param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [int]$ID, [Parameter(Mandatory = $true)] [Alias('User')] [int]$UserID, [Parameter(Mandatory = $false)] [Alias('Group')] [int]$GroupID ) process { # Build the update body $body = [PSCustomObject]@{ user = $UserID } if ($PSBoundParameters.ContainsKey('GroupID')) { $body | Add-Member -NotePropertyName 'group' -NotePropertyValue $GroupID } $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/network/template/${ID}/ownership" # Build action description for confirmation $actionParts = @("Change owner to User ID $UserID") if ($PSBoundParameters.ContainsKey('GroupID')) { $actionParts += "Group ID $GroupID" } $actionDescription = $actionParts -join " and " # Use the helper function Invoke-CloudResourceUpdate ` -CallerPSCmdlet $PSCmdlet ` -ResourceType "Network" ` -ID $ID ` -Uri $uri ` -Body $body ` -Action $actionDescription ` -GetResourceScript { Get-CloudNetworkTemplate -ID $ID } ` -SuccessMessage "Network $ID ownership updated successfully." } } function Update-CloudNetworkTemplatePermissions { <# .SYNOPSIS Updates the permissions of a network in the Cloud Server. .DESCRIPTION Changes the permission of a network. Prompts for confirmation. .PARAMETER ID Required. ID of the network. .PARAMETER OwnerUse Optional. True or false, enable OwnerUse .PARAMETER OwnerManage Optional. True or false, enable OwnerManage .PARAMETER OwnerAdmin Optional. True or false, enable OwnerAdmin .PARAMETER GroupUse Optional. True or false, enable GroupUse .PARAMETER GroupManage Optional. True or false, enable GroupManage .PARAMETER GroupAdmin Optional. True or false, enable GroupAdmin .PARAMETER OtherUse Optional. True or false, enable OtherUse .PARAMETER OtherManage Optional. True or false, enable OtherManage .PARAMETER OtherAdmin Optional. True or false, enable OtherManage .EXAMPLE # Give group users permission to use the network Update-CloudNetworkTemplatePermissions -ID 35 -GroupUse $true .EXAMPLE # Deny group admin permission to the network Update-CloudNetworkTemplatePermissions -ID 35 -GroupAdmin $false .EXAMPLE # Set multiple permissions at once Update-CloudNetworkTemplatePermissions -ID 35 -GroupUse $true -GroupManage $true -OtherUse $true #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact='High')] param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [int]$ID, [Parameter(Mandatory = $false)] [bool]$OwnerUse, [Parameter(Mandatory = $false)] [bool]$OwnerManage, [Parameter(Mandatory = $false)] [bool]$OwnerAdmin, [Parameter(Mandatory = $false)] [bool]$GroupUse, [Parameter(Mandatory = $false)] [bool]$GroupManage, [Parameter(Mandatory = $false)] [bool]$GroupAdmin, [Parameter(Mandatory = $false)] [bool]$OtherUse, [Parameter(Mandatory = $false)] [bool]$OtherManage, [Parameter(Mandatory = $false)] [bool]$OtherAdmin ) process { # Build the permissions object structure as shown in the API spec $permissions = @{} if ($PSBoundParameters.ContainsKey('OwnerUse')) { $permissions['owner_use'] = $OwnerUse } if ($PSBoundParameters.ContainsKey('OwnerManage')) { $permissions['owner_manage'] = $OwnerManage } if ($PSBoundParameters.ContainsKey('OwnerAdmin')) { $permissions['owner_admin'] = $OwnerAdmin } if ($PSBoundParameters.ContainsKey('GroupUse')) { $permissions['group_use'] = $GroupUse } if ($PSBoundParameters.ContainsKey('GroupManage')) { $permissions['group_manage'] = $GroupManage } if ($PSBoundParameters.ContainsKey('GroupAdmin')) { $permissions['group_admin'] = $GroupAdmin } if ($PSBoundParameters.ContainsKey('OtherUse')) { $permissions['other_use'] = $OtherUse } if ($PSBoundParameters.ContainsKey('OtherManage')) { $permissions['other_manage'] = $OtherManage } if ($PSBoundParameters.ContainsKey('OtherAdmin')) { $permissions['other_admin'] = $OtherAdmin } # Create the body with the permissions nested structure $body = @{ permissions = $permissions } $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/network/template/${ID}/permissions" Invoke-CloudResourceUpdate ` -CallerPSCmdlet $PSCmdlet ` -ResourceType "Network" ` -ID $ID ` -Uri $uri ` -Body $body ` -Action "Update permissions" ` -GetResourceScript { Get-CloudNetworkTemplate -ID $ID } } } function Remove-CloudNetworkTemplate { <# .SYNOPSIS Removes a network template from the Cloud Server. .DESCRIPTION Removes a network template. Automatically handles token refresh. .PARAMETER Name Required. Network template ID. .EXAMPLE # Remove network template with confirmation prompt (default behavior): Remove-CloudNetworkTemplate -ID 3 Confirm Are you sure you want to perform this action? Performing the operation "Remove Network Template" on target "Network Template ID 3 (MyNetworkTemplate)". [Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"): Y .EXAMPLE # Remove network without confirmation prompt: Remove-CloudNetworkTemplate -ID 3 -Confirm:$false #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact='High')] param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [int]$ID ) process { $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/network/template/${ID}" Invoke-CloudResourceRemoval ` -CallerPSCmdlet $PSCmdlet ` -ResourceType "Network Template" ` -ID $ID ` -Uri $uri ` -GetResourceScript { Get-CloudNetwork -ID $ID } } } function Resolve-CloudNetwork { <# .SYNOPSIS Recover a Network from the Cloud Server. .DESCRIPTION Recover the specified Network. Automatically handles token refresh. .PARAMETER ID Required. The ID of the Network to be recovered. .EXAMPLE # Recover a network Resolve-CloudNetwork -ID 561 .EXAMPLE # Recover a network without a confirmation prompt Resolve-CloudNetwork -ID 561 -Confirm:$false .EXAMPLE # Simulate the recovery of a network Resolve-CloudNetwork -ID 561 -WhatIf #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact='High')] param( [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true)] [int]$ID ) process { # Get the Network details for confirmation message try { $Network = Get-CloudNetwork -ID $ID } catch { Write-Warning "Network with ID $ID not found." return } if (-not $Network) { Write-Warning "Network with ID $ID not found." return } $body = @{ recovery = "success" } $NetworkName = if ($Network.name) { $Network.name } else { "Unnamed" } if ($PSCmdlet.ShouldProcess("Network ID $ID ($NetworkName)", "Start Network")) { $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/network/${ID}/recover" Write-Verbose "Starting Network ID ${ID}: $NetworkName" try { $response = Invoke-CloudApiRequest -Uri $uri -Method PATCH -body $body Write-Host "Network $ID recovered successfully." -ForegroundColor Green return $response } catch { # Check for specific error messages if ($_.Exception.Message -match "not found|does not exist") { Write-Warning "Network $ID not found" return } else { # Re-throw other errors throw } } } } } function New-CloudNetworkFromTemplate { <# .SYNOPSIS Creates a new virtual network from a template. .DESCRIPTION Instantiates a virtual network from an existing network template. Automatically handles token refresh. .PARAMETER TemplateID Required. ID of the network template to instantiate. .PARAMETER Name Required. Name for the new virtual network. .PARAMETER Extra Optional. Additional template attributes to override or add. Format as newline-separated "KEY = VALUE" pairs. Values with spaces should be quoted. .EXAMPLE # Create a network from template 3 New-CloudNetworkFromTemplate -TemplateID 3 -Name "my-gateway-network" .EXAMPLE # Create with extra parameters to override template settings $extra = @" VN_MAD = "802.1Q" VLAN_ID = "200" BRIDGE = "onebr.200" "@ New-CloudNetworkFromTemplate -TemplateID 3 -Name "custom-network" -Extra $extra .EXAMPLE # Override just the VLAN_ID to avoid conflicts New-CloudNetworkFromTemplate -TemplateID 3 -Name "new-network" -Extra 'VLAN_ID = "50"' .EXAMPLE # From pipeline Get-CloudNetworkTemplate -ID 3 | New-CloudNetworkFromTemplate -Name "new-network" #> [CmdletBinding()] param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Alias('ID', 'template_id')] [int]$TemplateID, [Parameter(Mandatory = $true)] [string]$Name, [Parameter(Mandatory = $false)] [string]$Extra ) process { # Build the request body $body = @{ name = $Name } # Add extra if provided if ($PSBoundParameters.ContainsKey('Extra')) { $body.extra = $Extra } else { $body.extra = "" } # Convert to PSCustomObject for proper JSON serialization $bodyObject = [PSCustomObject]$body # Build the URI $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/network/template/${TemplateID}/instantiate" Write-Verbose "Instantiating network template ID: $TemplateID" Write-Verbose "Network name: $Name" if ($Extra) { Write-Verbose "Extra parameters:`n$Extra" } Write-Verbose "Request body: $($bodyObject | ConvertTo-Json -Compress)" try { $response = Invoke-CloudApiRequest -Uri $uri -Method Patch -Body $bodyObject Write-Host "Network '$Name' created successfully from template ID $TemplateID." -ForegroundColor Green return $response } catch { Write-Error "Failed to instantiate network template ${TemplateID}: $_" throw } } } function Update-CloudNetwork { <# .SYNOPSIS Updates a virtual network. .DESCRIPTION Updates a virtual network's configuration. .PARAMETER ID Required. ID of the network to update. .PARAMETER Template Required. Network template content in OpenNebula format. .PARAMETER Merge Optional. If true (default), merges with existing configuration. .EXAMPLE # Update cloud network description $template = 'DESCRIPTION = "Updated network description"' Update-CloudNetwork -ID 5 -Template $template .EXAMPLE # Update cloud network 5 without merging Update-CloudNetwork -ID 5 -Template $template -Merge:$false .EXAMPLE # Update a network's MAC address range and description $template = @" DESCRIPTION = "Updated network with custom MAC range" MAC_START = "02:00:c0:a8:00:01" MAC_END = "02:00:c0:a8:00:FF" "@ Update-CloudNetwork -ID 5 -Template $template -Verbose #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact='High')] param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Alias('NetworkID')] [int]$ID, [Parameter(Mandatory = $true)] [string]$Template, [Parameter()] [bool]$Merge = $true ) process { $body = @{ merge = $Merge template = $Template } $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/network/${ID}" Write-Verbose "Updating network ID: $ID" Write-Verbose "Template:`n$Template" try { Invoke-CloudResourceUpdate ` -CallerPSCmdlet $PSCmdlet ` -ResourceType "Network" ` -ID $ID ` -Uri $uri ` -Body $body ` -Action "Update" ` -GetResourceScript { Get-CloudNetwork -ID $ID } Write-Host "Network ID $ID updated successfully." -ForegroundColor Green } catch { Write-Error "Failed to update network ${ID}: $_" throw } } } function New-CloudNetworkAddressRange { <# .SYNOPSIS Adds an address range to a virtual network. .DESCRIPTION Creates a new address range in an existing virtual network. .PARAMETER NetworkID Required. ID of the network. .PARAMETER Template Required. Address range template in OpenNebula format. .EXAMPLE # Add a new address range to the network $template = @" AR = [ TYPE = "IP4", IP = "192.168.1.100", SIZE = "50" ] "@ New-CloudNetworkAddressRange -NetworkID 5 -Template $template #> [CmdletBinding()] param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Alias('ID')] [int]$NetworkID, [Parameter(Mandatory = $true)] [string]$Template ) process { $body = [PSCustomObject]@{ template = $Template } $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/network/${NetworkID}/address-range" Write-Verbose "Adding address range to network ID: $NetworkID" Write-Verbose "Template:`n$Template" try { $response = Invoke-CloudApiRequest -Uri $uri -Method Post -Body $body Write-Host "Address range added successfully to network ID $NetworkID." -ForegroundColor Green return $response } catch { Write-Error "Failed to add address range to network ${NetworkID}: $_" throw } } } function Update-CloudNetworkAddressRange { <# .SYNOPSIS Updates an address range in a virtual network. .DESCRIPTION Modifies an existing address range in a virtual network. .PARAMETER NetworkID Required. ID of the network. .PARAMETER Template Required. Address range template with updates. .EXAMPLE # Update a network range $template = 'AR = [ AR_ID = "0", SIZE = "100" ]' Update-CloudNetworkAddressRange -NetworkID 5 -Template $template #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact='High')] param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Alias('ID')] [int]$NetworkID, [Parameter(Mandatory = $true)] [string]$Template ) process { $body = [PSCustomObject]@{ template = $Template } $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/network/${NetworkID}/address-range" Write-Verbose "Updating address range for network ID: $NetworkID" Write-Verbose "Template:`n$Template" try { Invoke-CloudResourceUpdate ` -CallerPSCmdlet $PSCmdlet ` -ResourceType "Network Address Range" ` -ID $NetworkID ` -Uri $uri ` -Body $body ` -Action "Update" ` -GetResourceScript { Get-CloudNetwork -ID $NetworkID } Write-Host "Address range updated successfully for network ID $NetworkID." -ForegroundColor Green } catch { Write-Error "Failed to update address range for network ${NetworkID}: $_" throw } } } function Remove-CloudNetworkAddressRange { <# .SYNOPSIS Removes an address range from a virtual network. .DESCRIPTION Deletes an address range from a network. .PARAMETER NetworkID Required. ID of the network. .PARAMETER RangeID Required. ID of the address range to remove. .EXAMPLE # Remove range 0 from network 5 Remove-CloudNetworkAddressRange -NetworkID 5 -RangeID 0 #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact='High')] param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Alias('ID')] [int]$NetworkID, [Parameter(Mandatory = $true)] [int]$RangeID ) process { $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/network/${NetworkID}/address-range/${RangeID}" if ($PSCmdlet.ShouldProcess("Network ID $NetworkID", "Delete address range ID $RangeID")) { Write-Verbose "Deleting address range ID $RangeID from network ID: $NetworkID" try { $response = Invoke-CloudApiRequest -Uri $uri -Method Delete Write-Host "Address range ID $RangeID deleted successfully from network ID $NetworkID." -ForegroundColor Green return $response } catch { Write-Error "Failed to delete address range from network ${NetworkID}: $_" throw } } } } function Clear-CloudNetworkAddressRange { <# .SYNOPSIS Frees all addresses in an address range. .DESCRIPTION Releases all IP addresses in a specific address range. .PARAMETER NetworkID Required. ID of the network. .PARAMETER RangeID Required. ID of the address range to free. .EXAMPLE # Release all addresses from network 5 in range 0 Clear-CloudNetworkAddressRange -NetworkID 5 -RangeID 0 #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact='High')] param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Alias('ID')] [int]$NetworkID, [Parameter(Mandatory = $true)] [int]$RangeID ) process { $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/network/${NetworkID}/address-range/${RangeID}/free" if ($PSCmdlet.ShouldProcess("Network ID $NetworkID", "Free address range ID $RangeID")) { Write-Verbose "Freeing address range ID $RangeID in network ID: $NetworkID" try { $response = Invoke-CloudApiRequest -Uri $uri -Method Delete Write-Host "Address range ID $RangeID freed successfully in network ID $NetworkID." -ForegroundColor Green return $response } catch { Write-Error "Failed to free address range in network ${NetworkID}: $_" throw } } } } function Suspend-CloudNetworkLease { <# .SYNOPSIS Holds a virtual network lease as used. .DESCRIPTION Marks specific IP addresses in a network as used/held, preventing them from being automatically assigned to new VMs. .PARAMETER NetworkID Required. ID of the network. .PARAMETER Template Required. Template specifying which addresses to hold. .EXAMPLE # Hold a specific IP address $template = 'LEASES = [ IP = "192.168.1.50" ]' Suspend-CloudNetwork -NetworkID 5 -Template $template .EXAMPLE # Hold a range of IPs $template = @" LEASES = [ IP = "192.168.1.100" ] LEASES = [ IP = "192.168.1.101" ] LEASES = [ IP = "192.168.1.102" ] "@ Suspend-CloudNetworkLease -NetworkID 5 -Template $template .EXAMPLE # Hold by MAC address $template = 'LEASES = [ MAC = "02:00:c0:a8:01:32" ]' Suspend-CloudNetworkLease -NetworkID 5 -Template $template #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact='High')] param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Alias('ID')] [int]$NetworkID, [Parameter(Mandatory = $true)] [string]$Template ) process { $body = [PSCustomObject]@{ template = $Template } $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/network/${NetworkID}/hold" if ($PSCmdlet.ShouldProcess("Network ID $NetworkID", "Hold network addresses")) { Write-Verbose "Holding network addresses for network ID: $NetworkID" Write-Verbose "Template:`n$Template" Write-Verbose "Request body: $($body | ConvertTo-Json -Compress)" try { $response = Invoke-CloudApiRequest -Uri $uri -Method Patch -Body $body Write-Host "Network addresses held successfully for network ID $NetworkID." -ForegroundColor Green return $response } catch { Write-Error "Failed to hold network addresses for network ${NetworkID}: $_" throw } } } } function Restore-CloudNetwork { <# .SYNOPSIS Recovers a virtual network. .DESCRIPTION Recovers a network from an error state. .PARAMETER NetworkID Required. ID of the network to recover. .EXAMPLE # Recover network 5 Restore-CloudNetwork -NetworkID 5 #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact='High')] param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Alias('ID')] [int]$NetworkID ) process { $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/network/${NetworkID}/recover" if ($PSCmdlet.ShouldProcess("Network ID $NetworkID", "Recover network")) { Write-Verbose "Recovering network ID: $NetworkID" try { $response = Invoke-CloudApiRequest -Uri $uri -Method Patch Write-Host "Network ID $NetworkID recovered successfully." -ForegroundColor Green return $response } catch { Write-Error "Failed to recover network ${NetworkID}: $_" throw } } } } function Resume-CloudNetworkLease { <# .SYNOPSIS Releases held leases on a virtual network. .DESCRIPTION Releases reserved leases a network from hold state, making it available for use. .PARAMETER NetworkID Required. ID of the network to release. .EXAMPLE # Release a range of IPs on network 5 $template = @" LEASES = [ IP = "192.168.1.100" ] LEASES = [ IP = "192.168.1.101" ] LEASES = [ IP = "192.168.1.102" ] "@ Resume-CloudNetworkLease -NetworkID 5 -Template $template #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact='High')] param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Alias('ID')] [int]$NetworkID, [Parameter(Mandatory = $true)] [string]$Template ) process { $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/network/${NetworkID}/release" $body = [PSCustomObject]@{ template = $Template } if ($PSCmdlet.ShouldProcess("Network ID $NetworkID", "Release network")) { Write-Verbose "Releasing network ID: $NetworkID" try { write-verbose "Template: $template" $response = Invoke-CloudApiRequest -Uri $uri -Method PATCH -Body $body Write-Host "Network ID $NetworkID released successfully." -ForegroundColor Green return $response } catch { Write-Error "Failed to release network ${NetworkID}: $_" throw } } } } function Save-CloudNetworkAddresses { <# .SYNOPSIS Reserves addresses in a virtual network. .DESCRIPTION Creates a reservation of network addresses. .PARAMETER NetworkID Required. ID of the network. .PARAMETER Template Required. Reservation template specifying addresses to reserve. .EXAMPLE # Reserve a range of IPs on cloud network 5 $template = 'SIZE = "10" NAME = "Reserved-IPs"' Save-CloudNetworkAddresses -NetworkID 5 -Name "SystemReserved" -Template $template #> [CmdletBinding()] param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Alias('ID')] [int]$NetworkID, [Parameter(Mandatory = $true)] [string]$Template ) process { $body = [PSCustomObject]@{ template = $Template } $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/network/${NetworkID}/reserve" Write-Verbose "Reserving addresses in network ID: $NetworkID" Write-Verbose "Template:`n$Template" try { $response = Invoke-CloudApiRequest -Uri $uri -Method PATCH -Body $body Write-Host "Addresses reserved successfully in network ID $NetworkID." -ForegroundColor Green return $response } catch { Write-Error "Failed to reserve addresses in network ${NetworkID}: $_" throw } } } function Update-CloudNetworkTemplate { <# .SYNOPSIS Updates a network template stored in the network. .DESCRIPTION Updates the template configuration for a network. .PARAMETER NetworkID Required. ID of the network. .PARAMETER Template Required. Updated network template. .EXAMPLE # Update a network template using a variable $template = 'DESCRIPTION = "Production Network"' Update-CloudNetworkTemplate -NetworkID 5 -Template $template #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact='High')] param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Alias('ID')] [int]$NetworkID, [Parameter(Mandatory = $true)] [string]$Template ) process { $body = [PSCustomObject]@{ template = $Template } $uri = "$($script:CloudConnection.BaseUri)/manifold-api/v2/cloud/network/${NetworkID}/template/update" Write-Verbose "Updating template for network ID: $NetworkID" Write-Verbose "Template:`n$Template" try { Invoke-CloudResourceUpdate ` -CallerPSCmdlet $PSCmdlet ` -ResourceType "Network Template" ` -ID $NetworkID ` -Uri $uri ` -Body $body ` -Action "Update" ` -GetResourceScript { Get-CloudNetwork -ID $NetworkID } Write-Host "Network template updated successfully for network ID $NetworkID." -ForegroundColor Green } catch { Write-Error "Failed to update network template for network ${NetworkID}: $_" throw } } } |