Public/Backup/New-VergeSiteSyncSchedule.ps1
|
function New-VergeSiteSyncSchedule { <# .SYNOPSIS Creates an auto sync schedule for an outgoing site sync in VergeOS. .DESCRIPTION New-VergeSiteSyncSchedule links a snapshot profile period to an outgoing site sync, enabling automatic syncing of snapshots taken by that profile period to the remote site. .PARAMETER SyncKey The key (ID) of the outgoing sync to add the schedule to. .PARAMETER SyncName The name of the outgoing sync to add the schedule to. .PARAMETER SiteSync A site sync object from Get-VergeSiteSync. .PARAMETER ProfilePeriodKey The key (ID) of the snapshot profile period to sync. .PARAMETER ProfilePeriodName The name of the snapshot profile period to sync. Format: "ProfileName/PeriodName" (e.g., "Default/Daily") .PARAMETER Retention How long to keep synced snapshots on the remote site. Accepts TimeSpan or seconds as integer. .PARAMETER Priority The priority for syncing (lower numbers sync first). Default is auto-assigned. .PARAMETER DoNotExpire If set, the source snapshot will not expire until it has been synced. .PARAMETER DestinationPrefix Prefix to add to the snapshot name on the destination. Default is "remote". .PARAMETER Server The VergeOS connection to use. Defaults to the current default connection. .EXAMPLE New-VergeSiteSyncSchedule -SyncName "DR-Sync" -ProfilePeriodKey 1 -Retention (New-TimeSpan -Days 7) Adds an auto sync schedule for profile period 1 with 7 day retention. .EXAMPLE Get-VergeSiteSync -Name "DR-Sync" | New-VergeSiteSyncSchedule -ProfilePeriodKey 2 -Retention 604800 Adds an auto sync schedule with retention specified in seconds (7 days). .OUTPUTS PSCustomObject with PSTypeName 'Verge.SiteSyncSchedule' .NOTES After creating a schedule, snapshots taken by the linked profile period will automatically be queued for sync to the remote site. Use Get-VergeSnapshotProfile to see available snapshot profiles and their periods. Use Remove-VergeSiteSyncSchedule to remove a schedule. #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium', DefaultParameterSetName = 'ByName')] [OutputType([PSCustomObject])] param( [Parameter(Mandatory, ParameterSetName = 'ByKey')] [Parameter(Mandatory, ParameterSetName = 'ByKeyPeriodName')] [int]$SyncKey, [Parameter(Mandatory, Position = 0, ParameterSetName = 'ByName')] [Parameter(Mandatory, ParameterSetName = 'ByNamePeriodName')] [string]$SyncName, [Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'ByObject')] [Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'ByObjectPeriodName')] [PSTypeName('Verge.SiteSync')] [PSCustomObject]$SiteSync, [Parameter(Mandatory, ParameterSetName = 'ByKey')] [Parameter(Mandatory, ParameterSetName = 'ByName')] [Parameter(Mandatory, ParameterSetName = 'ByObject')] [int]$ProfilePeriodKey, [Parameter(Mandatory, ParameterSetName = 'ByKeyPeriodName')] [Parameter(Mandatory, ParameterSetName = 'ByNamePeriodName')] [Parameter(Mandatory, ParameterSetName = 'ByObjectPeriodName')] [string]$ProfilePeriodName, [Parameter(Mandatory)] [object]$Retention, [Parameter()] [int]$Priority, [Parameter()] [switch]$DoNotExpire, [Parameter()] [ValidatePattern('^[a-zA-Z0-9 :_.,+-]*$')] [string]$DestinationPrefix = 'remote', [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.' ) } # Convert retention to seconds $retentionSeconds = if ($Retention -is [TimeSpan]) { [int]$Retention.TotalSeconds } elseif ($Retention -is [int] -or $Retention -is [long]) { [int]$Retention } else { throw [System.ArgumentException]::new( 'Retention must be a TimeSpan or an integer representing seconds.' ) } } process { # Resolve sync key $targetSyncKey = $null $targetSyncName = $null if ($SiteSync) { $targetSyncKey = $SiteSync.Key $targetSyncName = $SiteSync.Name } elseif ($SyncKey) { $targetSyncKey = $SyncKey $sync = Get-VergeSiteSync -Key $SyncKey -Server $Server if ($sync) { $targetSyncName = $sync.Name } } elseif ($SyncName) { $sync = Get-VergeSiteSync -Name $SyncName -Server $Server if (-not $sync) { Write-Error -Message "Site sync not found: $SyncName" -ErrorId 'SiteSyncNotFound' return } $targetSyncKey = $sync.Key $targetSyncName = $sync.Name } if (-not $targetSyncKey) { Write-Error -Message "Could not resolve site sync" -ErrorId 'SiteSyncNotResolved' return } # Resolve profile period key $targetPeriodKey = $null $targetPeriodName = $null if ($ProfilePeriodKey) { $targetPeriodKey = $ProfilePeriodKey # Try to get period name try { $periodQuery = @{ fields = 'name' filter = "`$key eq $ProfilePeriodKey" } $periodResponse = Invoke-VergeAPI -Method GET -Endpoint 'snapshot_profile_periods' -Query $periodQuery -Connection $Server if ($periodResponse) { $targetPeriodName = $periodResponse.name } } catch { Write-Verbose "Could not retrieve profile period name" } } elseif ($ProfilePeriodName) { # Parse "ProfileName/PeriodName" format or just period name $parts = $ProfilePeriodName -split '/', 2 $periodNameFilter = if ($parts.Count -eq 2) { "name eq '$($parts[1])'" } else { "name eq '$ProfilePeriodName'" } try { $periodQuery = @{ fields = '$key,name' filter = $periodNameFilter } $periodResponse = Invoke-VergeAPI -Method GET -Endpoint 'snapshot_profile_periods' -Query $periodQuery -Connection $Server if ($periodResponse) { $period = if ($periodResponse -is [array]) { $periodResponse[0] } else { $periodResponse } $targetPeriodKey = $period.'$key' $targetPeriodName = $period.name } else { Write-Error -Message "Snapshot profile period not found: $ProfilePeriodName" -ErrorId 'ProfilePeriodNotFound' return } } catch { Write-Error -Message "Failed to find profile period '$ProfilePeriodName': $($_.Exception.Message)" -ErrorId 'ProfilePeriodLookupFailed' return } } if (-not $targetPeriodKey) { Write-Error -Message "Could not resolve profile period" -ErrorId 'ProfilePeriodNotResolved' return } $description = "Sync '$targetSyncName' + Period '$targetPeriodName'" if ($PSCmdlet.ShouldProcess($description, 'Create auto sync schedule')) { # Build request body $body = @{ site_syncs_outgoing = $targetSyncKey profile_period = $targetPeriodKey retention = $retentionSeconds do_not_expire = [bool]$DoNotExpire destination_prefix = $DestinationPrefix } if ($PSBoundParameters.ContainsKey('Priority')) { $body['priority'] = $Priority } try { Write-Verbose "Creating auto sync schedule for sync $targetSyncKey with period $targetPeriodKey" $response = Invoke-VergeAPI -Method POST -Endpoint 'site_syncs_outgoing_profile_periods' -Body $body -Connection $Server if ($response -and $response.'$key') { Write-Verbose "Schedule created with key $($response.'$key')" # Retrieve the full schedule details Get-VergeSiteSyncSchedule -Key $response.'$key' -Server $Server } else { Write-Warning "Schedule creation returned unexpected response" Write-Output $response } } catch { Write-Error -Message "Failed to create auto sync schedule: $($_.Exception.Message)" -ErrorId 'CreateSiteSyncScheduleFailed' } } } } |