diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 9267c2c..891d95c 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -8,3 +8,4 @@ * Refactored the `Checkpoint-ZertoVpg` command to allow pipeline input (ByValue and ByProperty) for the VpgName parameter. * Corrected a parameter typo in the `Get-ZertoVpgSetting` function. The misspelt parameter was added as an alias to ensure any existing scripts using the parameter continue to function. * Refactored the `Get-ZertoVpg` command to remove repetitive commands and variables that are no longer required. +* Moved `Invoke-ZertoRestRequest` and `Invoke-ZARestRequest` to be public functions. As there become more and more scenarios where there are not prebuilt functions to accomplish complex specialized tasks, it became apparent that these functions could be leveraged to make the experience and workflow easier. diff --git a/Tests/Private/Invoke-ZARestRequest.Tests.ps1 b/Tests/Public/Invoke-ZARestRequest.Tests.ps1 similarity index 91% rename from Tests/Private/Invoke-ZARestRequest.Tests.ps1 rename to Tests/Public/Invoke-ZARestRequest.Tests.ps1 index 78bb6f3..c545e56 100644 --- a/Tests/Private/Invoke-ZARestRequest.Tests.ps1 +++ b/Tests/Public/Invoke-ZARestRequest.Tests.ps1 @@ -12,7 +12,6 @@ Describe $global:function -Tag 'Unit', 'Source', 'Built' { @{ParameterName = 'uri'; Type = 'String'; Mandatory = $true; TestName = 'URI' } @{ParameterName = 'method'; Type = 'String'; Mandatory = $false; TestName = 'Method' } @{ParameterName = 'body'; Type = 'String'; Mandatory = $false; TestName = 'Body' } - @{ParameterName = 'contentType'; Type = 'String'; Mandatory = $false; TestName = 'contentType' } ) It "Parameter present and Type test for: " -TestCases $testCases { @@ -29,14 +28,9 @@ Describe $global:function -Tag 'Unit', 'Source', 'Built' { Get-Command $global:function | Should -HaveParameter Method -DefaultValue "GET" } - It "ContentType parameter default is 'application/json'" { - Get-Command $global:function | Should -HaveParameter contentType -DefaultValue "application/json" - } - $NotNullOrEmptyTests = @( @{ParameterName = 'uri'; TestName = 'Uri' } @{ParameterName = 'body'; TestName = 'Body' } - @{ParameterName = 'contentType'; TestName = 'ContentType' } ) It " parameter does not accecpt a null or empty value" -TestCases $NotNullOrEmptyTests { diff --git a/Tests/Private/Invoke-ZertoRestRequest.Tests.ps1 b/Tests/Public/Invoke-ZertoRestRequest.Tests.ps1 similarity index 91% rename from Tests/Private/Invoke-ZertoRestRequest.Tests.ps1 rename to Tests/Public/Invoke-ZertoRestRequest.Tests.ps1 index df40da6..f7a23d5 100644 --- a/Tests/Private/Invoke-ZertoRestRequest.Tests.ps1 +++ b/Tests/Public/Invoke-ZertoRestRequest.Tests.ps1 @@ -14,9 +14,7 @@ Describe $global:function -Tag 'Unit', 'Source', 'Built' { $ParameterNameTestCases = @( @{ParameterName = "uri"; Type = "String"; Mandatory = $true; DefaultValue = $null; TestName = "URI" } @{ParameterName = "method"; Type = "String"; Mandatory = $false; DefaultValue = 'GET'; TestName = "Method" } - @{ParameterName = "apiVersion"; Type = "String"; Mandatory = $false; DefaultValue = 'v1'; TestName = "API Version" } @{ParameterName = "body"; Type = "String"; Mandatory = $false; DefaultValue = $null; TestName = "Body" } - @{ParameterName = "contentType"; Type = "String"; Mandatory = $false; DefaultValue = 'application/json'; TestName = "Content Type" } @{ParameterName = "credential"; Type = "PSCredential"; Mandatory = $false; DefaultValue = $null; TestName = "Credential" } @{ParameterName = "returnHeaders"; Type = "Switch"; Mandatory = $false; DefaultValue = $null; TestName = "Return Headers" } ) @@ -36,9 +34,7 @@ Describe $global:function -Tag 'Unit', 'Source', 'Built' { $ParameterValidationTestCases = @( @{ParameterName = "URI"; TestName = "URI" } - @{ParameterName = "apiVersion"; TestName = "Api Version" } @{ParameterName = "body"; TestName = "Body" } - @{ParameterName = "contentType"; TestName = "Content Type" } ) It " parameter cannot be null or empty" -TestCases $ParameterValidationTestCases { diff --git a/ZertoApiWrapper/Private/Invoke-ZARestRequest.ps1 b/ZertoApiWrapper/Public/Invoke-ZARestRequest.ps1 similarity index 64% rename from ZertoApiWrapper/Private/Invoke-ZARestRequest.ps1 rename to ZertoApiWrapper/Public/Invoke-ZARestRequest.ps1 index 0304c88..52aab99 100644 --- a/ZertoApiWrapper/Private/Invoke-ZARestRequest.ps1 +++ b/ZertoApiWrapper/Public/Invoke-ZARestRequest.ps1 @@ -1,26 +1,38 @@ +<# .ExternalHelp ./en-us/ZertoApiWrapper-help.xml #> function Invoke-ZARestRequest { [cmdletbinding()] param( # Parameter help description - [Parameter(Mandatory)] + [Parameter( + Mandatory, + Helpmessage = "URI endpoint to be utilized. When submitting the URI, only the endpoint needs to be submitted. Please review the help documentation for examples." + )] [ValidateNotNullOrEmpty()] [string]$uri, + [Parameter( + Helpmessage = "API method to be used. GET, PUT, POST, or DELETE. Refer to documentation for the API endpoint to ensure the correct method is being used. If unspecified, defaults to GET" + )] [ValidateSet("GET", "PUT", "POST", "DELETE")] [string]$method = "GET", + [Parameter( + Helpmessage = "Body to be submitted to the REST API endpoint. This needs to be submitted in JSON format" + )] [ValidateNotNullOrEmpty()] - [string]$body, - [ValidateNotNullOrEmpty()] - [string]$contentType = "application/json" + [string]$body + ) + # While the API can use XML or JSON, this module is built on JSON functionality. Currently forcing all + # content types and language to JSON. + [string]$contentType = "application/json" # Check to see if the required variables are present and currently valid if ( -not ((Test-Path variable:script:zaLastActionTime) -and (Test-Path variable:script:zaHeaders)) ) { Throw "Zerto Analytics Connection does not Exist. Please run Connect-ZertoAnalytics first to establish a connection" - } elseif ( (Test-Path variable:script:zaHeaders) -and $([datetime]$script:zaLastActionTime).addMinutes(60) -lt $(get-date) ) { + } elseif ( (Test-Path variable:script:zaHeaders) -and $([datetime]$script:zaLastActionTime).addMinutes(60) -lt $(Get-Date) ) { Throw "Authorization Token has Expired. Please re-authorize to the Zerto Analytics Portal" } else { # Update the last action time and submit the request based on PS Version. - Set-Variable -Name zaLastActionTime -Scope Script -Value $(Get-date).Ticks + Set-Variable -Name zaLastActionTime -Scope Script -Value $(Get-Date).Ticks $submittedUri = "https://analytics.api.zerto.com/v2/{0}" -f $uri if ($PSVersionTable.PSVersion.Major -ge 6) { Invoke-RestMethod -Uri $submittedUri -Method $method -Body $body -Headers $Script:zaHeaders -ContentType $contentType -TimeoutSec 100 diff --git a/ZertoApiWrapper/Private/Invoke-ZertoRestRequest.ps1 b/ZertoApiWrapper/Public/Invoke-ZertoRestRequest.ps1 similarity index 75% rename from ZertoApiWrapper/Private/Invoke-ZertoRestRequest.ps1 rename to ZertoApiWrapper/Public/Invoke-ZertoRestRequest.ps1 index 4a3f642..97430ab 100644 --- a/ZertoApiWrapper/Private/Invoke-ZertoRestRequest.ps1 +++ b/ZertoApiWrapper/Public/Invoke-ZertoRestRequest.ps1 @@ -1,20 +1,39 @@ +<# .ExternalHelp ./en-us/ZertoApiWrapper-help.xml #> function Invoke-ZertoRestRequest { [cmdletbinding()] param( + # Parameter help description + [Parameter( + Helpmessage = "API method to be used. GET, PUT, POST, or DELETE. Refer to documentation for the API endpoint to ensure the correct method is being used. If unspecified, defaults to GET" + )] [ValidateSet("GET", "PUT", "POST", "DELETE")] [string]$method = "GET", - [Parameter(Mandatory)] + [Parameter( + Mandatory, + Helpmessage = "URI endpoint to be utilized. When submitting the URI, only the endpoint needs to be submitted. Please review the help documentation for examples." + )] [ValidateNotNullOrEmpty()] [string]$uri, - [ValidateNotNullOrEmpty()] - [string]$apiVersion = "v1", + [Parameter( + Helpmessage = "Body to be submitted to the REST API endpoint. This needs to be submitted in JSON format" + )] [ValidateNotNullOrEmpty()] [string]$body, - [ValidateNotNullOrEmpty()] - [string]$contentType = "application/json", + [Parameter( + Helpmessage = "PSCredential object. This is ONLY used when authenticating with the ZVM. No other endpoints require this and generally is not used." + )] [PSCredential]$credential, + [Parameter( + Helpmessage = "Use this switch if you would like the request headers returned along with the body. Useful for troubleshooting to get HTTP error codes." + )] [switch]$returnHeaders ) + # API version. Currently this is locked at v1 in all versions of Zerto. Should this change, will look + # at making this as parameter to be selected during function call. + $apiVersion = "v1" + # While the API can use XML or JSON, this module is built on JSON functionality. Currently forcing all + # content types and language to JSON. + $contentType = "application/json" $callerErrorActionPreference = $ErrorActionPreference # If the ZVM server and Port not defined, Stop Call if ( -not ((Test-Path variable:script:zvmServer) -and (Test-Path variable:script:zvmPort)) ) { @@ -22,7 +41,7 @@ function Invoke-ZertoRestRequest { } # If the Headers exist and the Last action was more than 30 minutes ago, Session is Expired - if ( (Test-Path variable:script:zvmHeaders) -and $([datetime]$script:zvmLastAction).addMinutes(30) -lt $(get-date) ) { + if ( (Test-Path variable:script:zvmHeaders) -and $([datetime]$script:zvmLastAction).addMinutes(30) -lt $(Get-Date) ) { Throw "Authorization Token has Expired. Please re-authorize to the Zerto Virtual Manager" } else { @@ -30,7 +49,7 @@ function Invoke-ZertoRestRequest { $submittedURI = "https://{0}:{1}/{2}/{3}" -f $script:zvmServer, $script:zvmPort, $apiVersion, $uri try { # Set the zvmLastAction time and try to submit the REST Request - $script:zvmLastAction = (get-date).Ticks + $script:zvmLastAction = (Get-Date).Ticks # If running PwSh - Use this Invoke-RestMethod with passed Variables if ($PSVersionTable.PSVersion.Major -ge 6) { $apiRequestResults = Invoke-RestMethod -Uri $submittedURI -Headers $script:zvmHeaders -Method $method -Body $body -ContentType $contentType -Credential $credential -SkipCertificateCheck -ResponseHeadersVariable responseHeaders -TimeoutSec 100 diff --git a/docs/Invoke-ZARestRequest.md b/docs/Invoke-ZARestRequest.md new file mode 100644 index 0000000..187e60d --- /dev/null +++ b/docs/Invoke-ZARestRequest.md @@ -0,0 +1,100 @@ +--- +external help file: ZertoApiWrapper-help.xml +Module Name: ZertoApiWrapper +online version: https://github.com/ZertoPublic/ZertoApiWrapper/blob/master/docs/Invoke-ZARestRequest.md +schema: 2.0.0 +--- + +# Invoke-ZARestRequest + +## SYNOPSIS +Function used to submit a REST request to the Zerto Analytics Portal. Should be used when attempting to submit a request inside a ZertoApiWrapper function or if attempting to perform an operation not currently covered in a ZertoApiWrapper function. + +## SYNTAX + +``` +Invoke-ZARestRequest [-uri] [[-method] ] [[-body] ] [] +``` + +## DESCRIPTION +Function used to submit a REST request to the Zerto Analytics Portal. Should be used when attempting to submit a request inside a ZertoApiWrapper function or if attempting to perform an operation not currently covered in a ZertoApiWrapper function. To function properly, you will have to have completed a connection to a Zerto Virtual Manager with the `Connect-ZertoAnalytics` function. + +## EXAMPLES + +### Example 1 +```powershell +PS C:\> Invoke-ZertoRestRequest -uri 'apiEndpoint/subApiEndpoint' -Method GET +``` + +Submits a GET request to the connected Zerto Virtual Manager api endpoint 'apiEndpoint/subApiEndpoint'. Check the API documentation for the endpoint to ensure the URI is formatted correctly. Typically a GET request does not require a BODY parameter. + +### Example 1 +```powershell +PS C:\> Invoke-ZertoRestRequest -uri 'apiEndpoint/subApiEndpoint' -Method POST -Body $Body +``` + +Submits a PUT request to the connected Zerto Virtual Manager api endpoint 'apiEndpoint/subApiEndpoint' with a Body parameter. Check the API documentation for the endpoint to ensure the URI is formatted correctly and the format of the Body variable. The command above assumes that the $Body variable is an object that can be formatted into JSON. + +## PARAMETERS + +### -body +Body to be submitted to the REST API endpoint. +This needs to be submitted in JSON format + +```yaml +Type: String +Parameter Sets: (All) +Aliases: + +Required: False +Position: 3 +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -method +API method to be used. +GET, PUT, POST, or DELETE. +Refer to documentation for the API endpoint to ensure the correct method is being used. +If unspecified, defaults to GET + +```yaml +Type: String +Parameter Sets: (All) +Aliases: + +Required: False +Position: 2 +Default value: GET +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -uri +Parameter help description + +```yaml +Type: String +Parameter Sets: (All) +Aliases: + +Required: True +Position: 1 +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 Analytics API Endpoint Documentation](https://docs.api.zerto.com/) diff --git a/docs/Invoke-ZertoRestRequest.md b/docs/Invoke-ZertoRestRequest.md new file mode 100644 index 0000000..b2ad214 --- /dev/null +++ b/docs/Invoke-ZertoRestRequest.md @@ -0,0 +1,154 @@ +--- +external help file: ZertoApiWrapper-help.xml +Module Name: ZertoApiWrapper +online version: https://github.com/ZertoPublic/ZertoApiWrapper/blob/master/docs/Invoke-ZertoRestRequest.md +schema: 2.0.0 +--- + +# Invoke-ZertoRestRequest + +## SYNOPSIS +Function used to submit a REST request to the Zerto Virtual Manager. Should be used when attempting to submit a request inside a ZertoApiWrapper function or if attempting to perform an operation not currently covered in a ZertoApiWrapper function. + +## SYNTAX + +``` +Invoke-ZertoRestRequest [[-method] ] [-uri] [[-body] ] [[-credential] ] + [-returnHeaders] [] +``` + +## DESCRIPTION +Function used to submit a REST request to the Zerto Virtual Manager. Should be used when attempting to submit a request inside a ZertoApiWrapper function or if attempting to perform an operation not currently covered in a ZertoApiWrapper function. To function properly, you will have to have completed a connection to a Zerto Virtual Manager with the `Connect-ZertoServer` function. + +## EXAMPLES + +### Example 1 +```powershell +PS C:\> Invoke-ZertoRestRequest -uri 'apiEndpoint/subApiEndpoint' -Method POST -Body $Body +``` + +Submits a POST request to the connected Zerto Virtual Manager api endpoint 'apiEndpoint/subApiEndpoint' with a Body parameter. Check the API documentation for the endpoint to ensure the URI is formatted correctly and the format of the Body variable. The command above assumes that the $Body variable is a string properly formatted for JSON + +### Example 2 +```powershell +PS C:\> Invoke-ZertoRestRequest -uri 'apiEndpoint/subApiEndpoint' -Method POST -Body ($Body | ConvertTo-Json) +``` + +Submits a POST request to the connected Zerto Virtual Manager api endpoint 'apiEndpoint/subApiEndpoint' with a Body parameter. Check the API documentation for the endpoint to ensure the URI is formatted correctly and the format of the Body variable. The command above assumes that the $Body variable is an object that can be formatted into JSON. + +### Example 3 +```powershell +PS C:\> Invoke-ZertoRestRequest -uri 'apiEndpoint/subApiEndpoint' -Method PUT -Body $Body +``` + +Submits a PUT request to the connected Zerto Virtual Manager api endpoint 'apiEndpoint/subApiEndpoint' with a Body parameter. Check the API documentation for the endpoint to ensure the URI is formatted correctly and the format of the Body variable. The command above assumes that the $Body variable is a string properly formatted for JSON + +### Example 4 +```powershell +PS C:\> Invoke-ZertoRestRequest -uri 'apiEndpoint/subApiEndpoint' -Method DELETE +``` + +Submits a DELETE request to the connected Zerto Virtual Manager api endpoint 'apiEndpoint/subApiEndpoint'. Check the API documentation for the endpoint to ensure the URI is formatted correctly. Typically a DELETE request does not require a BODY parameter. + +### Example 5 +```powershell +PS C:\> Invoke-ZertoRestRequest -uri 'apiEndpoint/subApiEndpoint' -Method GET +``` + +Submits a GET request to the connected Zerto Virtual Manager api endpoint 'apiEndpoint/subApiEndpoint'. Check the API documentation for the endpoint to ensure the URI is formatted correctly. Typically a GET request does not require a BODY parameter. + +## PARAMETERS + +### -body +Body to be submitted to the REST API endpoint. +This needs to be submitted in JSON format + +```yaml +Type: String +Parameter Sets: (All) +Aliases: + +Required: False +Position: 3 +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -credential +PSCredential object. +This is ONLY used when authenticating with the ZVM. +No other endpoints require this and generally is not used. + +```yaml +Type: PSCredential +Parameter Sets: (All) +Aliases: + +Required: False +Position: 4 +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -method +Parameter help description + +```yaml +Type: String +Parameter Sets: (All) +Aliases: + +Required: False +Position: 1 +Default value: GET +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -returnHeaders +Use this switch if you would like the request headers returned along with the body. +Useful for troubleshooting to get HTTP error codes. + +```yaml +Type: SwitchParameter +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: False +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -uri +URI endpoint to be utilized. +When submitting the URI, only the endpoint needs to be submitted. +Please review the help documentation for examples. + +```yaml +Type: String +Parameter Sets: (All) +Aliases: + +Required: True +Position: 2 +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 Virtual Replication API Endpoint Documentation](https://s3.amazonaws.com/zertodownload_docs/Latest/Zerto%20Virtual%20Replication%20Zerto%20Virtual%20Manager%20(ZVM)%20-%20vSphere%20Online%20Help/content/intro/book_in_portal_-_zvr_restful_apis.htm)