Skip to content

Commit

Permalink
Merge pull request #308 from rubrikinc/melliott-devel-148
Browse files Browse the repository at this point in the history
Add Remove-RubrikVMSnapshot cmdlet and additional logging
  • Loading branch information
jaapbrasser authored Jun 21, 2019
2 parents f191bb8 + b6da2ad commit c57ec0f
Show file tree
Hide file tree
Showing 7 changed files with 190 additions and 5 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,24 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

## 2019-06-20

### Added [New Remove-RubrikVMSnapshot cmdlet]

* Added Remove-RubrikVMSnapshot cmdlet to address [148](https://github.com/rubrikinc/rubrik-sdk-for-powershell/issues/148) and associated unit test

### Changed [Additional logging and info]

* Updated Invoke-RubrikWebRequest so the HTTP status code returned from the API call is displayed when verbose logging is enabled
* Updated Submit-Request to handle `Delete` API calls differently than other calls. Previously `Delete` operations did not surface any status to the user. With this change, the HTTP response code is checked to verify it matches the expected response. If so, it returns a PSObject with the HTTP code and Status = 'Success'.

## 2019-06-18

### Added [Update-RubrikVMwareVM]

* Added new `Update-RubrikVMwareVM` cmdlet to refresh a single VMware VM's metadata. This addresses issue [305](https://github.com/rubrikinc/rubrik-sdk-for-powershell/issues/305)


## 2019-06-04

### Added [Resolving Issues]
Expand Down
13 changes: 13 additions & 0 deletions Rubrik/Private/Get-RubrikAPIData.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -1292,6 +1292,19 @@ function Get-RubrikAPIData($endpoint) {
Success = '204'
}
}
'Remove-RubrikVMSnapshot' = @{
'1.0' = @{
Description = 'Removes an expired VM snapshot available for garbage collection'
URI = '/api/v1/vmware/vm/snapshot/{id}'
Method = 'Delete'
Body = ''
Query = @{
location = 'location'
}
Result = ''
Success = '204'
}
}
'Remove-RubrikUnmanagedObject' = @{
'1.0' = @{
Description = 'Bulk delete all unmanaged snapshots for the objects specified by objectId/objectType pairings.'
Expand Down
8 changes: 6 additions & 2 deletions Rubrik/Private/Invoke-RubrikWebRequest.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,12 @@ Custom wrapper for Invoke-WebRequest, implemented to provide different parameter
)

if (Test-PowerShellSix) {
Invoke-WebRequest -UseBasicParsing -SkipCertificateCheck @PSBoundParameters
$result = Invoke-WebRequest -UseBasicParsing -SkipCertificateCheck @PSBoundParameters
} else {
Invoke-WebRequest -UseBasicParsing @PSBoundParameters
$result = Invoke-WebRequest -UseBasicParsing @PSBoundParameters
}

Write-Verbose -Message "Received HTTP Status $($result.StatusCode)"

return $result
}
31 changes: 29 additions & 2 deletions Rubrik/Private/Submit-Request.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,35 @@
if ($PSCmdlet.ShouldProcess($id, $resources.Description)) {
try {
Write-Verbose -Message 'Submitting the request'
# Because some calls require more than the default payload limit of 2MB, ExpandPayload dynamically adjusts the payload limit
$result = ExpandPayload -response (Invoke-RubrikWebRequest -Uri $uri -Headers $header -Method $method -Body $body)
if ($resources.method -eq 'Delete') {
# Delete operations generally have no response body, skip JSON formatting and store the response from Invoke-WebRequest
$response = Invoke-RubrikWebRequest -Uri $uri -Headers $header -Method $method -Body $body
# Parse response to verify there is nothing in the body
$result = ExpandPayload -response $response
# If $result is null, build a $result object to return to the user. Otherwise, $result will be returned.
if($null -eq $result) {
# If if HTTP status code matches our expected result, build a PSObject reflecting success
if($response.StatusCode -eq [int]$resources.Success) {
$result = @{
Status = 'Success'
HTTPStatusCode = $response.StatusCode
}
}
# If a different HTTP status is returned, surface that information to the user
# This code may never run due to non-200 HTTP codes throwing an HttpResponseException
else {
$result = @{
Status = 'Error'
HTTPStatusCode = $response.StatusCode
HTTPStatusDescription = $response.StatusCode
}
}
}
}
else {
# Because some calls require more than the default payload limit of 2MB, ExpandPayload dynamically adjusts the payload limit
$result = ExpandPayload -response (Invoke-RubrikWebRequest -Uri $uri -Headers $header -Method $method -Body $body)
}
}
catch {
switch -Wildcard ($_) {
Expand Down
79 changes: 79 additions & 0 deletions Rubrik/Public/Remove-RubrikVMSnapshot.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#requires -Version 3
function Remove-RubrikVMSnapshot
{
<#
.SYNOPSIS
Connects to Rubrik and removes an expired VMware VM snapshot available for garbage collection.
.DESCRIPTION
The Remove-RubrikVMSnapshot cmdlet will request that the Rubrik API delete an an expired VMware VM snapshot.
The snapshot must be an on-demand snapshot or a snapshot from a virtual machine that is not assigned to an SLA Domain.
.NOTES
Written by Matt Elliott for community usage
Twitter: @NetworkBrouhaha
GitHub: shamsway
.LINK
http://rubrikinc.github.io/rubrik-sdk-for-powershell/reference/Remove-RubrikVMSnapshot.html
.EXAMPLE
Remove-RubrikVMSnapshot -id '01234567-8910-1abc-d435-0abc1234d567'
This will attempt to remove VM snapshot (backup) data with the snapshot id `01234567-8910-1abc-d435-0abc1234d567`
.EXAMPLE
Remove-RubrikVMSnapshot -id '01234567-8910-1abc-d435-0abc1234d567' -location local
This will attempt to remove the local copy of the VM snapshot (backup) data with the snapshot id `01234567-8910-1abc-d435-0abc1234d567`
.EXAMPLE
Get-RubrikVM OldVM1 | Get-RubrikSnapshot -Date '03/21/2017' | Remove-RubrikVMSnapshot
This will attempt to remove any snapshot from `03/21/2017` for VM `OldVM1`.
#>

[CmdletBinding(SupportsShouldProcess = $true,ConfirmImpact = 'High')]
Param(
# ID of the snapshot to delete
[Parameter(Mandatory = $true,ValueFromPipelineByPropertyName = $true)]
[String]$id,
# Snapshot location to delete, either "local" or "all". Defaults to "all"
[String]$location = "all",
# Rubrik server IP or FQDN
[String]$Server = $global:RubrikConnection.server,
# API version
[ValidateNotNullorEmpty()]
[String]$api = $global:RubrikConnection.api
)

Begin {

# The Begin section is used to perform one-time loads of data necessary to carry out the function's purpose
# If a command needs to be run with each iteration or pipeline input, place it in the Process section

# Check to ensure that a session to the Rubrik cluster exists and load the needed header data for authentication
Test-RubrikConnection

# API data references the name of the function
# For convenience, that name is saved here to $function
$function = $MyInvocation.MyCommand.Name

# Retrieve all of the URI, method, body, query, result, filter, and success details for the API endpoint
Write-Verbose -Message "Gather API Data for $function"
$resources = Get-RubrikAPIData -endpoint $function
Write-Verbose -Message "Load API data for $($resources.Function)"
Write-Verbose -Message "Description: $($resources.Description)"

}

Process {

$uri = New-URIString -server $Server -endpoint ($resources.URI) -id $id
$uri = Test-QueryParam -querykeys ($resources.Query.Keys) -parameters ((Get-Command $function).Parameters.Values) -uri $uri
$body = New-BodyString -bodykeys ($resources.Body.Keys) -parameters ((Get-Command $function).Parameters.Values)
$result = Submit-Request -uri $uri -header $Header -method $($resources.Method) -body $body
$result = Test-ReturnFormat -api $api -result $result -location $resources.Result
$result = Test-FilterObject -filter ($resources.Filter) -result $result

return $result

} # End of process
} # End of function
2 changes: 1 addition & 1 deletion Rubrik/Rubrik.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ FunctionsToExport = @('Connect-Rubrik', 'Disconnect-Rubrik', 'Export-RubrikDatab
'Remove-RubrikLogShipping', 'Remove-RubrikManagedVolume',
'Remove-RubrikManagedVolumeExport', 'Remove-RubrikMount',
'Remove-RubrikNASShare', 'Remove-RubrikReport', 'Remove-RubrikSLA',
'Remove-RubrikUnmanagedObject', 'Remove-RubrikVCenter',
'Remove-RubrikUnmanagedObject', 'Remove-RubrikVCenter', 'Remove-RubrikVMSnapshot'
'Remove-RubrikVolumeGroupMount', 'Reset-RubrikLogShipping',
'Restore-RubrikDatabase', 'Set-RubrikAvailabilityGroup',
'Set-RubrikBlackout', 'Set-RubrikDatabase', 'Set-RubrikHyperVVM',
Expand Down
50 changes: 50 additions & 0 deletions Tests/Remove-RubrikVMSnapshot.Tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
Remove-Module -Name 'Rubrik' -ErrorAction 'SilentlyContinue'
Import-Module -Name './Rubrik/Rubrik.psd1' -Force

foreach ( $privateFunctionFilePath in ( Get-ChildItem -Path './Rubrik/Private' | Where-Object extension -eq '.ps1').FullName ) {
. $privateFunctionFilePath
}

Describe -Name 'Public/Remove-RubrikVMSnapshot' -Tag 'Public', 'Remove-RubrikVMSnapshot' -Fixture {
#region init
$global:rubrikConnection = @{
id = 'test-id'
userId = 'test-userId'
token = 'test-token'
server = 'test-server'
header = @{ 'Authorization' = 'Bearer test-authorization' }
time = (Get-Date)
api = 'v1'
version = '4.0.5'
}
#endregion

Context -Name 'Parameters' {
Mock -CommandName Test-RubrikConnection -Verifiable -ModuleName 'Rubrik' -MockWith {}
Mock -CommandName Submit-Request -Verifiable -ModuleName 'Rubrik' -MockWith {
@{
Status = 'Success'
HTTPStatusCode = 204
}
}
It -Name 'Should Return status of Success' -Test {
( Remove-RubrikVMSnapshot -id '01234567-8910-1abc-d435-0abc1234d567').Status |
Should -BeExactly 'Success'
}

It -Name 'Should Return HTTP status code 204' -Test {
( Remove-RubrikVMSnapshot -id '01234567-8910-1abc-d435-0abc1234d567').HTTPStatusCode |
Should -BeExactly 204
}

Context -Name 'Parameter Validation' {
It -Name 'Parameter id cannot be $null or empty' -Test {
{ Remove-RubrikVMSnapshot -id $null } |
Should -Throw "Cannot bind argument to parameter 'id' because it is an empty string."
}
}
Assert-VerifiableMock
Assert-MockCalled -CommandName Test-RubrikConnection -ModuleName 'Rubrik' -Times 1
Assert-MockCalled -CommandName Submit-Request -ModuleName 'Rubrik' -Times 1
}
}

0 comments on commit c57ec0f

Please sign in to comment.