Public/Tenant/New-VergeTenantStorage.ps1
|
function New-VergeTenantStorage { <# .SYNOPSIS Adds a storage tier allocation to a VergeOS tenant. .DESCRIPTION New-VergeTenantStorage allocates storage from a specified tier to a tenant. Each tenant can have allocations from multiple storage tiers. The provisioned amount is the maximum storage the tenant can use from that tier. .PARAMETER Tenant A tenant object from Get-VergeTenant. Accepts pipeline input. .PARAMETER TenantName The name of the tenant to add storage to. .PARAMETER TenantKey The unique key (ID) of the tenant to add storage to. .PARAMETER Tier The storage tier number (0-5) to allocate from. .PARAMETER ProvisionedGB The amount of storage to provision in gigabytes. .PARAMETER ProvisionedBytes The amount of storage to provision in bytes. Use for precise control. .PARAMETER PassThru Return the created storage allocation object. .PARAMETER Server The VergeOS connection to use. Defaults to the current default connection. .EXAMPLE New-VergeTenantStorage -TenantName "Customer01" -Tier 1 -ProvisionedGB 100 Allocates 100 GB from Tier 1 to the tenant. .EXAMPLE Get-VergeTenant -Name "Customer01" | New-VergeTenantStorage -Tier 2 -ProvisionedGB 500 -PassThru Allocates 500 GB from Tier 2 and returns the allocation object. .EXAMPLE New-VergeTenantStorage -TenantName "Customer01" -Tier 0 -ProvisionedBytes 107374182400 Allocates exactly 100 GB (in bytes) from Tier 0. .OUTPUTS None by default. Verge.TenantStorage when -PassThru is specified. .NOTES A tenant can only have one allocation per tier. Use Set-VergeTenantStorage to modify an existing allocation. #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium', DefaultParameterSetName = 'ByTenantNameGB')] [OutputType([PSCustomObject])] param( [Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'ByTenantGB')] [Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'ByTenantBytes')] [PSTypeName('Verge.Tenant')] [PSCustomObject]$Tenant, [Parameter(Mandatory, Position = 0, ParameterSetName = 'ByTenantNameGB')] [Parameter(Mandatory, Position = 0, ParameterSetName = 'ByTenantNameBytes')] [string]$TenantName, [Parameter(Mandatory, ParameterSetName = 'ByTenantKeyGB')] [Parameter(Mandatory, ParameterSetName = 'ByTenantKeyBytes')] [int]$TenantKey, [Parameter(Mandatory, Position = 1)] [ValidateRange(1, 5)] [ValidateScript({ if ($_ -eq 0) { throw "Tier 0 is reserved for system metadata and cannot be used for tenant storage allocations." } $true })] [int]$Tier, [Parameter(Mandatory, ParameterSetName = 'ByTenantNameGB')] [Parameter(Mandatory, ParameterSetName = 'ByTenantKeyGB')] [Parameter(Mandatory, ParameterSetName = 'ByTenantGB')] [ValidateRange(1, [int]::MaxValue)] [int]$ProvisionedGB, [Parameter(Mandatory, ParameterSetName = 'ByTenantNameBytes')] [Parameter(Mandatory, ParameterSetName = 'ByTenantKeyBytes')] [Parameter(Mandatory, ParameterSetName = 'ByTenantBytes')] [ValidateRange(1073741824, [long]::MaxValue)] [long]$ProvisionedBytes, [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 add storage to tenant '$($t.Name)': Tenant is a snapshot." -ErrorId 'CannotModifySnapshot' continue } # Get storage tier key $tierQueryParams = @{ filter = "tier eq $Tier" fields = '$key,tier,description' } $tierResponse = Invoke-VergeAPI -Method GET -Endpoint 'storage_tiers' -Query $tierQueryParams -Connection $Server if (-not $tierResponse) { Write-Error -Message "Storage tier $Tier not found." -ErrorId 'TierNotFound' continue } $tierKey = $tierResponse.'$key' # Calculate provisioned bytes $provBytes = if ($PSBoundParameters.ContainsKey('ProvisionedBytes')) { $ProvisionedBytes } else { [long]$ProvisionedGB * 1GB } # Build request body $body = @{ tenant = $t.Key tier = $tierKey provisioned = $provBytes } # Format size for display $sizeDisplay = if ($provBytes -ge 1TB) { "{0:N2} TB" -f ($provBytes / 1TB) } else { "{0:N0} GB" -f ($provBytes / 1GB) } # Confirm action if ($PSCmdlet.ShouldProcess("$($t.Name)", "Add Tier $Tier storage allocation ($sizeDisplay)")) { try { Write-Verbose "Adding Tier $Tier storage allocation ($sizeDisplay) to tenant '$($t.Name)'" $response = Invoke-VergeAPI -Method POST -Endpoint 'tenant_storage' -Body $body -Connection $Server Write-Verbose "Storage allocation added to tenant '$($t.Name)'" if ($PassThru) { # Wait briefly then return the new allocation Start-Sleep -Milliseconds 500 Get-VergeTenantStorage -TenantKey $t.Key -Tier "Tier $Tier" -Server $Server } } catch { $errorMessage = $_.Exception.Message if ($errorMessage -match 'already exists' -or $errorMessage -match 'unique') { Write-Error -Message "Tenant '$($t.Name)' already has a Tier $Tier storage allocation. Use Set-VergeTenantStorage to modify it." -ErrorId 'AllocationExists' } else { Write-Error -Message "Failed to add storage allocation to tenant '$($t.Name)': $errorMessage" -ErrorId 'StorageAllocationFailed' } } } } } } |