Public/Tenant/New-VergeTenantNetworkBlock.ps1
|
function New-VergeTenantNetworkBlock { <# .SYNOPSIS Assigns a network block (CIDR range) to a VergeOS tenant. .DESCRIPTION New-VergeTenantNetworkBlock assigns a CIDR network block to a tenant. This allows the tenant to have an entire subnet routed to them from the parent network. The block must not overlap with existing assignments. .PARAMETER Tenant A tenant object from Get-VergeTenant. Accepts pipeline input. .PARAMETER TenantName The name of the tenant to assign the block to. .PARAMETER TenantKey The unique key (ID) of the tenant to assign the block to. .PARAMETER Network The network name where the block will be assigned from. .PARAMETER NetworkKey The unique key (ID) of the network. .PARAMETER CIDR The network block in CIDR notation (e.g., "192.168.100.0/24"). .PARAMETER Description Optional description for the network block assignment. .PARAMETER PassThru Return the created network block object. .PARAMETER Server The VergeOS connection to use. Defaults to the current default connection. .EXAMPLE New-VergeTenantNetworkBlock -TenantName "Customer01" -Network "External" -CIDR "192.168.100.0/24" Assigns the 192.168.100.0/24 network block from "External" network to the tenant. .EXAMPLE Get-VergeTenant -Name "Customer01" | New-VergeTenantNetworkBlock -NetworkKey 1 -CIDR "10.10.0.0/16" -Description "Customer subnet" Assigns a /16 block with description using pipeline input. .EXAMPLE New-VergeTenantNetworkBlock -TenantName "Customer01" -Network "External" -CIDR "172.16.0.0/24" -PassThru Assigns a block and returns the created object. .OUTPUTS None by default. Verge.TenantNetworkBlock when -PassThru is specified. .NOTES The CIDR block must not overlap with existing network blocks on the network. Use standard CIDR notation: network_address/prefix_length #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium', DefaultParameterSetName = 'ByTenantNameNetwork')] [OutputType([PSCustomObject])] param( [Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'ByTenantNetwork')] [Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'ByTenantNetworkKey')] [PSTypeName('Verge.Tenant')] [PSCustomObject]$Tenant, [Parameter(Mandatory, Position = 0, ParameterSetName = 'ByTenantNameNetwork')] [Parameter(Mandatory, Position = 0, ParameterSetName = 'ByTenantNameNetworkKey')] [string]$TenantName, [Parameter(Mandatory, ParameterSetName = 'ByTenantKeyNetwork')] [Parameter(Mandatory, ParameterSetName = 'ByTenantKeyNetworkKey')] [int]$TenantKey, [Parameter(Mandatory, ParameterSetName = 'ByTenantNameNetwork')] [Parameter(Mandatory, ParameterSetName = 'ByTenantKeyNetwork')] [Parameter(Mandatory, ParameterSetName = 'ByTenantNetwork')] [string]$Network, [Parameter(Mandatory, ParameterSetName = 'ByTenantNameNetworkKey')] [Parameter(Mandatory, ParameterSetName = 'ByTenantKeyNetworkKey')] [Parameter(Mandatory, ParameterSetName = 'ByTenantNetworkKey')] [int]$NetworkKey, [Parameter(Mandatory)] [ValidatePattern('^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/(3[0-2]|[1-2][0-9]|[0-9])$')] [string]$CIDR, [Parameter()] [ValidateLength(0, 2048)] [string]$Description, [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.' ) } } process { # Resolve tenant based on parameter set $targetTenant = switch -Wildcard ($PSCmdlet.ParameterSetName) { 'ByTenantName*' { Get-VergeTenant -Name $TenantName -Server $Server } 'ByTenantKey*' { Get-VergeTenant -Key $TenantKey -Server $Server } 'ByTenant*' { $Tenant } } foreach ($t in $targetTenant) { if (-not $t) { continue } # Check if tenant is a snapshot if ($t.IsSnapshot) { Write-Error -Message "Cannot assign network block to tenant '$($t.Name)': Tenant is a snapshot." -ErrorId 'CannotModifySnapshot' continue } # Resolve network $netKey = if ($PSBoundParameters.ContainsKey('NetworkKey')) { $NetworkKey } else { $net = Get-VergeNetwork -Name $Network -Server $Server if (-not $net) { Write-Error -Message "Network '$Network' not found." -ErrorId 'NetworkNotFound' continue } $net.Key } # Build request body $body = @{ vnet = $netKey cidr = $CIDR owner = "tenants/$($t.Key)" } # Add optional description if ($Description) { $body['description'] = $Description } # Confirm action if ($PSCmdlet.ShouldProcess("$($t.Name)", "Assign Network Block '$CIDR'")) { try { Write-Verbose "Assigning network block '$CIDR' to tenant '$($t.Name)'" $response = Invoke-VergeAPI -Method POST -Endpoint 'vnet_cidrs' -Body $body -Connection $Server Write-Verbose "Network block '$CIDR' assigned to tenant '$($t.Name)'" if ($PassThru) { # Wait briefly then return the new assignment Start-Sleep -Milliseconds 500 Get-VergeTenantNetworkBlock -TenantKey $t.Key -CIDR $CIDR -Server $Server } } catch { $errorMessage = $_.Exception.Message if ($errorMessage -match 'already exists') { Write-Error -Message "Network block '$CIDR' already exists on the network." -ErrorId 'BlockAlreadyExists' } elseif ($errorMessage -match 'overlap') { Write-Error -Message "Network block '$CIDR' overlaps with an existing block." -ErrorId 'BlockOverlap' } else { Write-Error -Message "Failed to assign network block to tenant '$($t.Name)': $errorMessage" -ErrorId 'NetworkBlockAssignFailed' } } } } } } |