Public/Storage/New-VergeNASVolume.ps1
|
function New-VergeNASVolume { <# .SYNOPSIS Creates a new NAS volume in VergeOS. .DESCRIPTION New-VergeNASVolume creates a new NAS volume on a specified NAS service. Volumes are virtual filesystems that can be shared via CIFS/SMB or NFS. .PARAMETER Name The name for the new volume. Must be alphanumeric with underscores/hyphens only. .PARAMETER NASService The NAS service to create the volume on. Can be a service name or key. .PARAMETER SizeGB The maximum size of the volume in gigabytes. .PARAMETER Tier The preferred storage tier (1-5). Defaults to the system default. .PARAMETER Description Optional description for the volume. .PARAMETER ReadOnly If specified, creates the volume as read-only. .PARAMETER Discard If specified, enables automatic discard of deleted files. Defaults to true. .PARAMETER OwnerUser The user that owns the volume directory. .PARAMETER OwnerGroup The group that owns the volume directory. .PARAMETER SnapshotProfile The snapshot profile to apply to this volume. .PARAMETER Server The VergeOS connection to use. Defaults to the current default connection. .EXAMPLE New-VergeNASVolume -Name "FileShare" -NASService "nas01" -SizeGB 500 Creates a 500GB volume named FileShare on the nas01 service. .EXAMPLE New-VergeNASVolume -Name "Archive" -NASService "nas01" -SizeGB 2000 -Tier 3 Creates a 2TB volume on storage tier 3. .EXAMPLE New-VergeNASVolume -Name "ReadOnlyData" -NASService "nas01" -SizeGB 100 -ReadOnly Creates a read-only volume. .OUTPUTS Verge.Volume object representing the created volume. .NOTES Volumes require a NAS service VM to be running. Use Get-VergeVM to find available NAS services in your environment. #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')] [OutputType([PSCustomObject])] param( [Parameter(Mandatory, Position = 0)] [ValidatePattern('^[a-zA-Z0-9_][a-zA-Z0-9_-]*$')] [ValidateLength(1, 128)] [string]$Name, [Parameter(Mandatory)] [Alias('Service')] [object]$NASService, [Parameter(Mandatory)] [Alias('Size', 'MaxSize')] [ValidateRange(1, 524288)] [int]$SizeGB, [Parameter()] [ValidateRange(1, 5)] [int]$Tier, [Parameter()] [ValidateLength(0, 2048)] [string]$Description, [Parameter()] [switch]$ReadOnly, [Parameter()] [bool]$Discard = $true, [Parameter()] [string]$OwnerUser, [Parameter()] [string]$OwnerGroup, [Parameter()] [object]$SnapshotProfile, [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 { try { # Resolve NAS service to key $serviceKey = $null if ($NASService -is [int]) { $serviceKey = $NASService } elseif ($NASService -is [string]) { # Look up service by name - vm_services is the table for NAS services Write-Verbose "Looking up NAS service: $NASService" $serviceResponse = Invoke-VergeAPI -Method GET -Endpoint 'vm_services' -Query @{ filter = "name eq '$NASService'" fields = '$key,name' } -Connection $Server if (-not $serviceResponse -or ($serviceResponse -is [array] -and $serviceResponse.Count -eq 0)) { throw "NAS service '$NASService' not found" } $serviceData = if ($serviceResponse -is [array]) { $serviceResponse[0] } else { $serviceResponse } $serviceKey = $serviceData.'$key' } elseif ($NASService.Key) { $serviceKey = $NASService.Key } else { throw "Invalid NASService parameter. Provide a service name, key, or object." } if (-not $serviceKey) { throw "Could not resolve NAS service key" } # Build request body $body = @{ name = $Name service = $serviceKey maxsize = $SizeGB * 1073741824 # Convert GB to bytes enabled = $true discard = $Discard } if ($Tier) { $body['preferred_tier'] = $Tier.ToString() } if ($Description) { $body['description'] = $Description } if ($ReadOnly) { $body['read_only'] = $true } if ($OwnerUser) { $body['owner_user'] = $OwnerUser } if ($OwnerGroup) { $body['owner_group'] = $OwnerGroup } if ($SnapshotProfile) { if ($SnapshotProfile -is [int]) { $body['snapshot_profile'] = $SnapshotProfile } elseif ($SnapshotProfile.Key) { $body['snapshot_profile'] = $SnapshotProfile.Key } } if ($PSCmdlet.ShouldProcess("Volume '$Name'", 'Create')) { Write-Verbose "Creating volume '$Name' on service $serviceKey" $response = Invoke-VergeAPI -Method POST -Endpoint 'volumes' -Body $body -Connection $Server # Return the created volume if ($response.'$key' -or $response.id) { $volumeKey = $response.'$key' ?? $response.id Get-VergeNASVolume -Key $volumeKey -Server $Server } else { Write-Verbose "Volume created, fetching by name" Get-VergeNASVolume -Name $Name -Server $Server } } } catch { Write-Error -Message "Failed to create volume '$Name': $($_.Exception.Message)" -ErrorId 'NewVolumeFailed' } } } |