Public/Storage/New-VergeNASNFSShare.ps1
|
function New-VergeNASNFSShare { <# .SYNOPSIS Creates a new NFS share on a VergeOS volume. .DESCRIPTION New-VergeNASNFSShare creates an NFS file share on a NAS volume. The share can be accessed from Unix/Linux and other NFS clients. .PARAMETER Volume The name or object of the volume to create the share on. .PARAMETER Name The name for the new share. .PARAMETER SharePath The path within the volume to share. Leave empty to share the entire volume. .PARAMETER Description Optional description for the share. .PARAMETER AllowedHosts Comma-delimited list of allowed hosts: FQDNs (wildcards allowed), IP addresses, IP networks (CIDR), NIS netgroups (@group). Required unless -AllowAll is specified. .PARAMETER AllowAll Allow connections from any host. Use with caution. .PARAMETER DataAccess Data access mode: ReadOnly or ReadWrite. Default is ReadOnly. .PARAMETER Squash User/group ID mapping: SquashRoot (default), SquashAll, or NoSquash. .PARAMETER AnonymousUID User ID for anonymous/squashed users. Default is 65534. .PARAMETER AnonymousGID Group ID for anonymous/squashed users. Default is 65534. .PARAMETER Async Enable asynchronous mode for better performance (risk of data loss on crash). .PARAMETER Insecure Allow connections from ports above 1024. .PARAMETER NoACL Disable access control lists. .PARAMETER FilesystemID Filesystem ID for the export. Must be unique per volume. .PARAMETER Server The VergeOS connection to use. Defaults to the current default connection. .EXAMPLE New-VergeNASNFSShare -Volume "FileShare" -Name "exports" -AllowedHosts "192.168.1.0/24" Creates an NFS share accessible from the 192.168.1.0/24 subnet. .EXAMPLE New-VergeNASNFSShare -Volume "FileShare" -Name "public" -AllowAll -DataAccess ReadOnly Creates a read-only NFS share accessible from any host. .EXAMPLE New-VergeNASNFSShare -Volume "FileShare" -Name "secure" -AllowedHosts "10.0.0.5,10.0.0.6" -DataAccess ReadWrite -Squash NoSquash Creates a read-write share with no user squashing for specific hosts. .OUTPUTS Verge.NASNFSShare object representing the created share. .NOTES Mount the share from Linux: mount -t nfs server:/sharename /mnt/point #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')] [OutputType([PSCustomObject])] param( [Parameter(Mandatory, Position = 0, ValueFromPipeline)] [Alias('VolumeName')] [object]$Volume, [Parameter(Mandatory, Position = 1)] [ValidateLength(1, 128)] [string]$Name, [Parameter()] [string]$SharePath, [Parameter()] [ValidateLength(0, 2048)] [string]$Description, [Parameter()] [string]$AllowedHosts, [Parameter()] [switch]$AllowAll, [Parameter()] [ValidateSet('ReadOnly', 'ReadWrite')] [string]$DataAccess = 'ReadOnly', [Parameter()] [ValidateSet('SquashRoot', 'SquashAll', 'NoSquash')] [string]$Squash = 'SquashRoot', [Parameter()] [string]$AnonymousUID, [Parameter()] [string]$AnonymousGID, [Parameter()] [switch]$Async, [Parameter()] [switch]$Insecure, [Parameter()] [switch]$NoACL, [Parameter()] [string]$FilesystemID, [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.' ) } # Map friendly names to API values $dataAccessMap = @{ 'ReadOnly' = 'ro' 'ReadWrite' = 'rw' } $squashMap = @{ 'SquashRoot' = 'root_squash' 'SquashAll' = 'all_squash' 'NoSquash' = 'no_root_squash' } } process { try { # Validate hosts requirement if (-not $AllowAll -and -not $AllowedHosts) { throw "Either -AllowedHosts or -AllowAll must be specified" } # Resolve volume to key $volumeKey = $null $volumeName = $null if ($Volume -is [string]) { $volumeName = $Volume $volumeData = Get-VergeNASVolume -Name $Volume -Server $Server if (-not $volumeData) { throw "Volume '$Volume' not found" } $volumeKey = $volumeData.Key $volumeName = $volumeData.Name } elseif ($Volume.Key) { $volumeKey = $Volume.Key $volumeName = $Volume.Name } elseif ($Volume -is [int]) { $volumeKey = $Volume } if (-not $volumeKey) { throw "Could not resolve volume key" } # Build request body $body = @{ volume = $volumeKey name = $Name enabled = $true data_access = $dataAccessMap[$DataAccess] squash = $squashMap[$Squash] } if ($SharePath) { $body['share_path'] = $SharePath } if ($Description) { $body['description'] = $Description } if ($AllowAll) { $body['allow_all'] = $true } if ($AllowedHosts) { $body['allowed_hosts'] = $AllowedHosts } if ($AnonymousUID) { $body['anonuid'] = $AnonymousUID } if ($AnonymousGID) { $body['anongid'] = $AnonymousGID } if ($Async) { $body['async'] = $true } if ($Insecure) { $body['insecure'] = $true } if ($NoACL) { $body['no_acl'] = $true } if ($FilesystemID) { $body['fsid'] = $FilesystemID } $displayName = $volumeName ?? $volumeKey if ($PSCmdlet.ShouldProcess("Volume '$displayName'", "Create NFS share '$Name'")) { Write-Verbose "Creating NFS share '$Name' on volume '$displayName'" $response = Invoke-VergeAPI -Method POST -Endpoint 'volume_nfs_shares' -Body $body -Connection $Server # Return the created share if ($response.'$key' -or $response.id) { $shareKey = $response.'$key' ?? $response.id Get-VergeNASNFSShare -Key $shareKey -Server $Server } else { Get-VergeNASNFSShare -Volume $volumeKey -Name $Name -Server $Server } } } catch { $displayName = $volumeName ?? $volumeKey ?? 'unknown' Write-Error -Message "Failed to create NFS share on volume '$displayName': $($_.Exception.Message)" -ErrorId 'NewNFSShareFailed' } } } |