Merge pull request #55 from ZertoPublic/CloneVPG
Implement Clone VPG Function
This commit is contained in:
@@ -6,6 +6,7 @@
|
|||||||
* A token is now required to pair two sites together. The need is discussed in [Issue 46](https://github.com/ZertoPublic/ZertoApiWrapper/issues/46). To implement this change a `-token` parameter has been added to the `Add-ZertoPeerSite` function.
|
* A token is now required to pair two sites together. The need is discussed in [Issue 46](https://github.com/ZertoPublic/ZertoApiWrapper/issues/46). To implement this change a `-token` parameter has been added to the `Add-ZertoPeerSite` function.
|
||||||
* A new function has been added; `New-ZertoPairingToken`. This function will allow users to generate a pairing authentication token from the target ZVM to be used in the pairing process. [Issue 47](https://github.com/ZertoPublic/ZertoApiWrapper/issues/47) covers additional details.
|
* A new function has been added; `New-ZertoPairingToken`. This function will allow users to generate a pairing authentication token from the target ZVM to be used in the pairing process. [Issue 47](https://github.com/ZertoPublic/ZertoApiWrapper/issues/47) covers additional details.
|
||||||
* A new function has been added; `Invoke-ZertoEvacuateVra`. This function will allow users to evacuate a target VRA by specifying a Host Name, VRA Name, or VRA Identifier. All VMs currently replicating to the specified location will be migrated to different targets. [Issue 51](https://github.com/ZertoPublic/ZertoApiWrapper/issues/51)
|
* A new function has been added; `Invoke-ZertoEvacuateVra`. This function will allow users to evacuate a target VRA by specifying a Host Name, VRA Name, or VRA Identifier. All VMs currently replicating to the specified location will be migrated to different targets. [Issue 51](https://github.com/ZertoPublic/ZertoApiWrapper/issues/51)
|
||||||
|
* A function has been added; `Copy-ZertoVpg`. This function will allow users to copy the settings of a single VPG and add new VMs to it. There is currently no customization beyond specifying the VMs to be placed in the newly created VPG. Should additional edits \ updates be required, they should be done post creation. [Issue 54](https://github.com/ZertoPublic/ZertoApiWrapper/issues/54)
|
||||||
|
|
||||||
### Zerto Analytics
|
### Zerto Analytics
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
#Requires -Modules Pester
|
||||||
|
$global:here = (Split-Path -Parent $MyInvocation.MyCommand.Path)
|
||||||
|
$global:function = ((Split-Path -leaf $MyInvocation.MyCommand.Path).Split('.'))[0]
|
||||||
|
|
||||||
|
Describe $global:function -Tag 'Unit', 'Source', 'Built' {
|
||||||
|
BeforeAll {
|
||||||
|
$script:ScriptBlock = (Get-Command $global:function).ScriptBlock
|
||||||
|
}
|
||||||
|
|
||||||
|
Context "$($global:function)::Parameter Unit Tests" {
|
||||||
|
|
||||||
|
It "$global:function should have exactly 16 parameters defined" {
|
||||||
|
(Get-Command $global:function).Parameters.Count | Should -Be 16
|
||||||
|
}
|
||||||
|
|
||||||
|
$ParameterTestCases = @(
|
||||||
|
@{ParameterName = 'SourceVpgName'; Type = 'String'; Mandatory = $true; Validation = 'NotNullOrEmpty' }
|
||||||
|
@{ParameterName = 'NewVpgName'; Type = 'String'; Mandatory = $true; Validation = 'NotNullOrEmpty' }
|
||||||
|
@{ParameterName = 'VMs'; Type = 'String[]'; Mandatory = $true; Validation = 'NotNullOrEmpty' }
|
||||||
|
)
|
||||||
|
|
||||||
|
It "<ParameterName> parameter is of <Type> type" -TestCases $ParameterTestCases {
|
||||||
|
param($ParameterName, $Type, $Mandatory)
|
||||||
|
Get-Command $global:function | Should -HaveParameter $ParameterName -Mandatory:$Mandatory -Type $Type
|
||||||
|
}
|
||||||
|
|
||||||
|
It "<ParameterName> parameter has correct validation setting" -TestCases $ParameterTestCases {
|
||||||
|
param($ParameterName, $Validation)
|
||||||
|
Switch ($Validation) {
|
||||||
|
'NotNullOrEmpty' {
|
||||||
|
$attrs = (Get-Command $global:function).Parameters[$ParameterName].Attributes
|
||||||
|
$attrs.Where{ $_ -is [ValidateNotNullOrEmpty] }.Count | Should -Be 1
|
||||||
|
}
|
||||||
|
|
||||||
|
$null {
|
||||||
|
$attrs = (Get-Command $global:function).Parameters[$ParameterName].Attributes
|
||||||
|
$attrs.TypeId.Count | Should -Be 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
It "Supports 'SupportsShouldProcess'" {
|
||||||
|
Get-Command $global:function | Should -HaveParameter WhatIf
|
||||||
|
Get-Command $global:function | Should -HaveParameter Confirm
|
||||||
|
$script:ScriptBlock | Should -match 'SupportsShouldProcess'
|
||||||
|
$script:ScriptBlock | Should -match '\$PSCmdlet\.ShouldProcess\(.+\)'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Context "$($global:function)::Function Unit Tests" {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Remove-Variable -Name function -Scope Global
|
||||||
|
Remove-Variable -Name here -Scope Global
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
<# .ExternalHelp ./en-us/ZertoApiWrapper-help.xml #>
|
||||||
|
function Copy-ZertoVpg {
|
||||||
|
[CmdletBinding(SupportsShouldProcess)]
|
||||||
|
param (
|
||||||
|
# VPG Name to Clone
|
||||||
|
[Parameter(Mandatory,
|
||||||
|
HelpMessage = "Name of the VPG to clone")]
|
||||||
|
[ValidateNotNullOrEmpty()]
|
||||||
|
[String]$SourceVpgName,
|
||||||
|
# New VPG Name
|
||||||
|
[Parameter(Mandatory,
|
||||||
|
HelpMessage = "Name to assign the newly created VPG")]
|
||||||
|
[ValidateNotNullOrEmpty()]
|
||||||
|
[String]$NewVpgName, # Name of VMs to add to the VPG
|
||||||
|
[Parameter(Mandatory,
|
||||||
|
HelpMessage = "Name(s) of the Virtual Machine(s) to add to the VPG")]
|
||||||
|
[ValidateNotNullOrEmpty()]
|
||||||
|
[String[]]$VMs
|
||||||
|
)
|
||||||
|
|
||||||
|
begin {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
process {
|
||||||
|
$VpgIdToCopy = @{ VpgIdentifier = (Get-ZertoVpg -vpgName $SourceVpgName).vpgIdentifier }
|
||||||
|
if ( $null -eq $VpgIdToCopy.VpgIdentifier ) {
|
||||||
|
Write-Error -Message "Unable to find a VPG with the name: $SourceVpgName. Please check the name and try again."
|
||||||
|
Break
|
||||||
|
} elseif ($VpgIdToCopy.VpgIdentifier.Count -gt 1) {
|
||||||
|
Write-Error -Message "More than one VPG was returned when searching for the VPG name: $SourceVpgName. Please try again."
|
||||||
|
Break
|
||||||
|
}
|
||||||
|
$BaseUri = "vpgSettings/copyVpgSettings"
|
||||||
|
$UnprotectedVms = Get-ZertoUnprotectedVm
|
||||||
|
$ProtectedVms = Get-ZertoProtectedVm
|
||||||
|
$VMsToAdd = foreach ($VM in $VMs) {
|
||||||
|
if ($UnprotectedVms.VmName -contains $VM) {
|
||||||
|
$VmId = $UnprotectedVms | Where-Object { $_.VmName -like $VM } | Select-Object -ExpandProperty VmIdentifier
|
||||||
|
} elseif ($ProtectedVms.VmName -contains $VM) {
|
||||||
|
$VmId = $ProtectedVms | Where-Object { $_.VmName -like $VM } | Select-Object -ExpandProperty VmIdentifier
|
||||||
|
} else {
|
||||||
|
Write-Warning -Message "Unable to find VM with Name $VM. Skipping."
|
||||||
|
}
|
||||||
|
$returnObject = New-Object PSObject
|
||||||
|
$returnObject | Add-Member -MemberType NoteProperty -Name "VmIdentifier" -Value $VmId
|
||||||
|
$returnObject
|
||||||
|
}
|
||||||
|
if ($PSCmdlet.ShouldProcess("$VMsToAdd", "Copying $SourceVpgName to $NewVpgName with Settings")) {
|
||||||
|
$NewVpgId = Invoke-ZertoRestRequest -Uri $BaseUri -Body ($VpgIdToCopy | ConvertTo-Json) -Method "POST"
|
||||||
|
$Uri = "{0}/{1}/vms" -f "vpgSettings", $NewVpgId
|
||||||
|
$null = Invoke-ZertoRestRequest -Uri $Uri -Body ($VMsToAdd | ConvertTo-Json) -Method "POST"
|
||||||
|
$Uri = "vpgSettings/{0}" -f $NewVpgId
|
||||||
|
$CurrentSettings = Invoke-ZertoRestRequest -Uri $Uri
|
||||||
|
$CurrentSettings.Basic.Name = $NewVpgName
|
||||||
|
$Null = Invoke-ZertoRestRequest -Uri $Uri -Method "Put" -Body $($CurrentSettings | ConvertTo-Json -Depth 20)
|
||||||
|
Save-ZertoVpgSetting -vpgSettingsIdentifier $NewVpgId
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
end {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,127 @@
|
|||||||
|
---
|
||||||
|
external help file: ZertoApiWrapper-help.xml
|
||||||
|
Module Name: ZertoApiWrapper
|
||||||
|
online version: https://github.com/ZertoPublic/ZertoApiWrapper/blob/master/docs/Copy-ZertoVpg.md
|
||||||
|
schema: 2.0.0
|
||||||
|
---
|
||||||
|
|
||||||
|
# Copy-ZertoVpg
|
||||||
|
|
||||||
|
## SYNOPSIS
|
||||||
|
Copy an existing VPG settings object to create a new VPG with the same settings. New VMs must be added to the copied VPG.
|
||||||
|
|
||||||
|
## SYNTAX
|
||||||
|
|
||||||
|
```
|
||||||
|
Copy-ZertoVpg -SourceVpgName <String> -NewVpgName <String> [-VMs] <String[]> [-WhatIf] [-Confirm]
|
||||||
|
[<CommonParameters>]
|
||||||
|
```
|
||||||
|
|
||||||
|
## DESCRIPTION
|
||||||
|
Copy an existing VPG settings object to create a new VPG with the same settings. New VMs must be added to the copied VPG.
|
||||||
|
|
||||||
|
## EXAMPLES
|
||||||
|
|
||||||
|
### Example 1
|
||||||
|
```powershell
|
||||||
|
PS C:\> Copy-ZertoVpg -SourceVpgName 'MyVpg' -NewVpgName 'MyNewVpg' -VMs 'VmToAdd01'
|
||||||
|
```
|
||||||
|
|
||||||
|
Copies the settings of 'MyVpg' into a new VPG 'MyNewVpg' adding one VM, 'VmToAdd01'
|
||||||
|
|
||||||
|
### Example 2
|
||||||
|
```powershell
|
||||||
|
PS C:\> Copy-ZertoVpg -SourceVpgName 'MyVpg' -NewVpgName 'MyNewVpg' -VMs 'VmToAdd01', 'VmToAdd02'
|
||||||
|
```
|
||||||
|
|
||||||
|
Copies the settings of 'MyVpg' into a new VPG 'MyNewVpg' adding two VMs, 'VmToAdd01' and 'VmToAdd02'
|
||||||
|
|
||||||
|
## PARAMETERS
|
||||||
|
|
||||||
|
### -NewVpgName
|
||||||
|
Name to assign the newly created VPG
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
Type: String
|
||||||
|
Parameter Sets: (All)
|
||||||
|
Aliases:
|
||||||
|
|
||||||
|
Required: True
|
||||||
|
Position: Named
|
||||||
|
Default value: None
|
||||||
|
Accept pipeline input: False
|
||||||
|
Accept wildcard characters: False
|
||||||
|
```
|
||||||
|
|
||||||
|
### -SourceVpgName
|
||||||
|
Name of the VPG to clone
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
Type: String
|
||||||
|
Parameter Sets: (All)
|
||||||
|
Aliases:
|
||||||
|
|
||||||
|
Required: True
|
||||||
|
Position: Named
|
||||||
|
Default value: None
|
||||||
|
Accept pipeline input: False
|
||||||
|
Accept wildcard characters: False
|
||||||
|
```
|
||||||
|
|
||||||
|
### -VMs
|
||||||
|
Name of VMs to add to the VPG
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
Type: String[]
|
||||||
|
Parameter Sets: (All)
|
||||||
|
Aliases:
|
||||||
|
|
||||||
|
Required: True
|
||||||
|
Position: 2
|
||||||
|
Default value: None
|
||||||
|
Accept pipeline input: False
|
||||||
|
Accept wildcard characters: False
|
||||||
|
```
|
||||||
|
|
||||||
|
### -Confirm
|
||||||
|
Prompts you for confirmation before running the cmdlet.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
Type: SwitchParameter
|
||||||
|
Parameter Sets: (All)
|
||||||
|
Aliases: cf
|
||||||
|
|
||||||
|
Required: False
|
||||||
|
Position: Named
|
||||||
|
Default value: None
|
||||||
|
Accept pipeline input: False
|
||||||
|
Accept wildcard characters: False
|
||||||
|
```
|
||||||
|
|
||||||
|
### -WhatIf
|
||||||
|
Shows what would happen if the cmdlet runs. The cmdlet is not run.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
Type: SwitchParameter
|
||||||
|
Parameter Sets: (All)
|
||||||
|
Aliases: wi
|
||||||
|
|
||||||
|
Required: False
|
||||||
|
Position: Named
|
||||||
|
Default value: None
|
||||||
|
Accept pipeline input: False
|
||||||
|
Accept wildcard characters: False
|
||||||
|
```
|
||||||
|
|
||||||
|
### CommonParameters
|
||||||
|
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
|
||||||
|
|
||||||
|
## INPUTS
|
||||||
|
|
||||||
|
## OUTPUTS
|
||||||
|
|
||||||
|
## NOTES
|
||||||
|
|
||||||
|
## RELATED LINKS
|
||||||
|
|
||||||
|
[Zerto Clone VPG API Endpoint Documentation](http://s3.amazonaws.com/zertodownload_docs/Latest/Zerto%20Virtual%20Replication%20Zerto%20Virtual%20Manager%20%28ZVM%29%20-%20vSphere%20Online%20Help/index.html#page/RestfulAPIs%2FStatusAPIs.5.119.html%23)
|
||||||
@@ -143,5 +143,6 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
|
|||||||
## NOTES
|
## NOTES
|
||||||
|
|
||||||
## RELATED LINKS
|
## RELATED LINKS
|
||||||
|
|
||||||
[Zerto REST API Evacuate VRA End Point Documentation](http://s3.amazonaws.com/zertodownload_docs/Latest/Zerto%20Virtual%20Replication%20Zerto%20Virtual%20Manager%20%28ZVM%29%20-%20vSphere%20Online%20Help/index.html#page/RestfulAPIs%2FStatusAPIs.5.129.html%23)
|
[Zerto REST API Evacuate VRA End Point Documentation](http://s3.amazonaws.com/zertodownload_docs/Latest/Zerto%20Virtual%20Replication%20Zerto%20Virtual%20Manager%20%28ZVM%29%20-%20vSphere%20Online%20Help/index.html#page/RestfulAPIs%2FStatusAPIs.5.129.html%23)
|
||||||
|
|
||||||
|
|||||||
@@ -74,4 +74,5 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable
|
|||||||
## NOTES
|
## NOTES
|
||||||
|
|
||||||
## RELATED LINKS
|
## RELATED LINKS
|
||||||
|
|
||||||
[Zerto REST API Peer Sites End Point Documentation](http://s3.amazonaws.com/zertodownload_docs/Latest/Zerto%20Virtual%20Replication%20Zerto%20Virtual%20Manager%20%28ZVM%29%20-%20vSphere%20Online%20Help/index.html#page/RestfulAPIs%2FStatusAPIs.5.046.html%23)
|
[Zerto REST API Peer Sites End Point Documentation](http://s3.amazonaws.com/zertodownload_docs/Latest/Zerto%20Virtual%20Replication%20Zerto%20Virtual%20Manager%20%28ZVM%29%20-%20vSphere%20Online%20Help/index.html#page/RestfulAPIs%2FStatusAPIs.5.046.html%23)
|
||||||
|
|||||||
Reference in New Issue
Block a user