Private/FileTransfer/Assert-VmFileSingleEntry.ps1
|
<#
.SYNOPSIS Validates a single-form file entry inside a VM 'files' array. .DESCRIPTION Extracted from Assert-VmFilesField so the public dispatcher stays small and the two entry forms (single vs bulk) can evolve independently. Rules: - All entry sub-fields must be in -AllowedSubFields. Unknown sub-fields throw - catches typos like 'src' or 'dest'. - 'source' is required, non-empty string, and must exist on the host. Existence is checked at validation time so an operator typo fails fast before any VM work begins. - 'target' is required, non-empty string, absolute Linux path. .PARAMETER EntryCtx Error-message prefix identifying this entry (e.g. "VM 'node-01': files[2]"). Built by the caller. .PARAMETER Entry The PSCustomObject parsed from the JSON entry. .PARAMETER AllowedSubFields Allow-list for entry sub-fields. Caller-controlled so consumers can extend the single-form schema (e.g. add 'owner'). #> function Assert-VmFileSingleEntry { [CmdletBinding()] param( [Parameter(Mandatory)] [string] $EntryCtx, [Parameter(Mandatory)] [object] $Entry, [Parameter(Mandatory)] [string[]] $AllowedSubFields ) foreach ($prop in $Entry.PSObject.Properties) { if ($prop.Name -notin $AllowedSubFields) { throw "$EntryCtx has unknown sub-field '$($prop.Name)'. Allowed sub-fields: $($AllowedSubFields -join ', ')." } } if (-not $Entry.PSObject.Properties['source']) { throw "$EntryCtx is missing required sub-field 'source'." } if ($Entry.source -isnot [string] -or [string]::IsNullOrWhiteSpace($Entry.source)) { throw "$EntryCtx.source must be a non-empty string (host path)." } if (-not (Test-Path -LiteralPath $Entry.source)) { throw "$EntryCtx.source path does not exist on the host: '$($Entry.source)'." } if (-not $Entry.PSObject.Properties['target']) { throw "$EntryCtx is missing required sub-field 'target'." } if ($Entry.target -isnot [string] -or [string]::IsNullOrWhiteSpace($Entry.target)) { throw "$EntryCtx.target must be a non-empty string (absolute Linux path)." } if ($Entry.target -notmatch '^/') { throw "$EntryCtx.target must be an absolute Linux path starting with '/' (got '$($Entry.target)')." } } |