diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ecd23c3..dcda4070 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,15 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Changed -* Change the Quick Start Guide to links are pointing to working VMware pages [Issue 726](https://github.com/rubrikinc/rubrik-sdk-for-powershell/issues/726) +### Added + +### Fixed + +## [5.3.0]() - 2021-04-08 + +### Changed + +* Changed the Quick Start Guide to links are pointing to working VMware pages [Issue 726](https://github.com/rubrikinc/rubrik-sdk-for-powershell/issues/726) * Changed, parameter sets, `SLA_Name/SLA_ByID/SLA_Unprotected/SLA_Forever`, added to `Protect-RubrikFileset` & `New-RubrikSnapshot`, fixing [Issue 720](https://github.com/rubrikinc/rubrik-sdk-for-powershell/issues/720) * Added support for `WhatIf` & `Confirm` to the `Invoke-RubrikRESTCall` cmdlet fixing [Issue 713](https://github.com/rubrikinc/rubrik-sdk-for-powershell/issues/713) * Created 3 new parameter sets to `Invoke-RubrikRESTCall` : `BodyAsArray`, `BodyAsJson`, `General` fixing [Issue 711](https://github.com/rubrikinc/rubrik-sdk-for-powershell/issues/711) @@ -29,6 +37,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Added +* Added new cmdlet: `Get-RubrikDebugInfo`, that gathers essential information for troubleshooting [Issue 742](https://github.com/rubrikinc/rubrik-sdk-for-powershell/issues/742) +* Added new cmdlet: `Test-RubrikSnapshotVerification`, that can test if a snapshot, or series of snapshots are recoverable [Issue 733](https://github.com/rubrikinc/rubrik-sdk-for-powershell/issues/733) +* Added example in documentation for: `Invoke-RubrikGraphQLCall` [Issue 736](https://github.com/rubrikinc/rubrik-sdk-for-powershell/issues/736) +* Added better warning message for `New-RubrikMount`, now displays warning when an object ID is specified instead of snapshot ID, [Issue 732](https://github.com/rubrikinc/rubrik-sdk-for-powershell/issues/732) * Added 5.3 endpoint for `Get-RubrikVolumeGroupMount`, resolving issue [Issue 729](https://github.com/rubrikinc/rubrik-sdk-for-powershell/issues/729) * Added support to `Get-RubrikUser` to work around all of the API endpoint changes in CDM 5.3 as per [Issue 723](https://github.com/rubrikinc/rubrik-sdk-for-powershell/issues/723) * Added new parameter, `SLAPrimaryClusterId`, to `Protect-RubrikFileset` & `New-RubrikSnapshot`, fixing [Issue 720](https://github.com/rubrikinc/rubrik-sdk-for-powershell/issues/720) @@ -44,6 +56,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Fixed +* Fixed bug in `Protect-RubrikTag` which could accidentally apply results to all VMs, [Issue 722](https://github.com/rubrikinc/rubrik-sdk-for-powershell/issues/722) * Fixed bug in `New-RubrikSLA` which could prevent correct SLA creation [Issue 706](https://github.com/rubrikinc/rubrik-sdk-for-powershell/issues/706) * Fixed bug in `Get-RubrikEvent` which caused `-Status` not to filter properly [Issue 705](https://github.com/rubrikinc/rubrik-sdk-for-powershell/issues/705) * Fixed documentation for `Invoke-RubrikGraphQLCall` multiline example changed to single line [Issue 685](https://github.com/rubrikinc/rubrik-sdk-for-powershell/issues/685) diff --git a/Rubrik/Private/ConvertTo-UniversalZuluDateTime.ps1 b/Rubrik/Private/ConvertTo-UniversalZuluDateTime.ps1 new file mode 100644 index 00000000..66de71dc --- /dev/null +++ b/Rubrik/Private/ConvertTo-UniversalZuluDateTime.ps1 @@ -0,0 +1,27 @@ +function ConvertTo-UniversalZuluDateTime { + <# + .SYNOPSIS + Converts a datetime value to a epoch millisecond timestamp + + .DESCRIPTION + Some API endpoints require the ISO 8601 notation for datetime stamps for more information about + this notation head over to Wikipedia: https://en.wikipedia.org/wiki/ISO_8601 + + .NOTES + Written by Jaap Brasser for community usage + Twitter: @jaap_brasser + GitHub: JaapBrasser + + .EXAMPLE + ConvertTo-UniversalZuluDateTime -DateTimeValue (Get-Date) + + 2021-02-04T21:03:09.000Z + #> + [CmdletBinding()] + param( + [DateTime]$DateTimeValue + ) + + $return = $DateTimeValue.ToUniversalTime().ToString('o') -replace '\.\d*Z$','.000Z' + return $return +} \ No newline at end of file diff --git a/Rubrik/Private/Get-RubrikAPIData.ps1 b/Rubrik/Private/Get-RubrikAPIData.ps1 index d3a7a890..a41dae94 100644 --- a/Rubrik/Private/Get-RubrikAPIData.ps1 +++ b/Rubrik/Private/Get-RubrikAPIData.ps1 @@ -3392,8 +3392,8 @@ function Get-RubrikAPIData { URI = '/api/internal/config/usersettable_volumeGroup' Method = 'Patch' Body = @{ - migrateFastVirtualDiskBuild = 'migrateFastVirtualDiskBuild' - maxFullMigrationStoragePercentage = 'maxFullMigrationStoragePercentage' + migrateFastVirtualDiskBuild = 'migrateFastVirtualDiskBuild' + maxFullMigrationStoragePercentage = 'maxFullMigrationStoragePercentage' } Query = '' Result = '' @@ -3533,6 +3533,23 @@ function Get-RubrikAPIData { Success = '202' } } + 'Test-RubrikSnapshotVerification' = @{ + '5.3' = @{ + Description = 'Verifies the validity of a snapshot' + URI = '/api/v1/backup/verify' + Method = 'Post' + Body = @{ + "objectId" = '' + "snapshotIdsOpt" = [System.Collections.ArrayList]@() + "locationIdOpt" = "locationIdOpt" + "shouldVerifyAfterOpt" = 'shouldVerifyAfterOpt' + } + Query = '' + Result = '' + Filter = '' + Success = '200' + } + } 'Update-RubrikVCenter' = @{ '1.0' = @{ Description = 'Refresh the metadata for the specified vCenter Server' diff --git a/Rubrik/Public/Get-RubrikDebugInfo.ps1 b/Rubrik/Public/Get-RubrikDebugInfo.ps1 new file mode 100644 index 00000000..d03f831c --- /dev/null +++ b/Rubrik/Public/Get-RubrikDebugInfo.ps1 @@ -0,0 +1,66 @@ +#Requires -Version 3 +function Get-RubrikDebugInfo +{ + <# + .SYNOPSIS + Displays information about the Rubrik module and the PowerShell + + .DESCRIPTION + The Get-RubrikDebugInfo cmdlet will retrieve the version of code that is actively running on the system. It will gather essential information that can be used for quickly troubleshooting issues + + .NOTES + Written by Jaap Brasser for community usage + Twitter: @jaap_brasser + GitHub: JaapBrasser + + .LINK + https://rubrik.gitbook.io/rubrik-sdk-for-powershell/command-documentation/reference/get-rubrikdebuginfo + + .EXAMPLE + Get-RubrikDebugInfo + + This will return information about the PowerShell version, the PowerShell client or console, and both the Rubrik cluster and Rubrik PowerShell module version numbers + #> + + [CmdletBinding()] + Param( + ) + + Process { + # Initiate Hash + $HashProps = [ordered]@{} + + # Add PSVersionTable + $PSVersionTable.Keys | ForEach-Object { + $HashProps.$_ = $PSVersionTable.$_ + } + + # Add Console Host information + $HashProps.HostConsoleName = $host.Name + $HashProps.HostConsoleVersion = $host.Version + $HashProps.HostCulture = $host.CurrentCulture + $HashProps.HostCultureUI = $host.CurrentUICulture + + # Gather Rubrik Cluster information + if ($RubrikConnection) { + $HashProps.RubrikConnection = $true + $HashProps.UserAgentString = $RubrikConnection.header.'User-Agent' + $HashProps.RubrikAuthentication = $RubrikConnection.header.authorization.split(' ')[0].SubString(0, 6) + $HashProps.RubrikClusterVersion = $RubrikConnection.version + } else { + Write-Warning "This cmdlet can gather more information if you're connected to your Rubrik Cluster" + } + + # Add module information + $HashProps.RubrikCurrentModuleVersion = (Get-Module -Name Rubrik) | ForEach-Object {'{0}-{1}' -f $_.Version,$_.PrivateData.PSData.Prerelease} + $HashProps.RubrikInstalledModule = ((Get-Module -Name Rubrik -ListAvailable) | ForEach-Object {if ($_.PrivateData.PSData.Prerelease -ne $null) {'{0}-{1}' -f $_.Version,$_.PrivateData.PSData.Prerelease} else {$_.version}}) -join ', ' + + # Add configured module options and default parameters + $HashProps.RubrikModuleOptions = Get-RubrikModuleOption + $HashProps.RubrikModuleDefaultParameters = Get-RubrikModuleDefaultParameter + + # Output as object + return [pscustomobject]$HashProps + + } # End of process +} # End of function \ No newline at end of file diff --git a/Rubrik/Public/Get-RubrikRequest.ps1 b/Rubrik/Public/Get-RubrikRequest.ps1 index a48c3a8d..6df25425 100644 --- a/Rubrik/Public/Get-RubrikRequest.ps1 +++ b/Rubrik/Public/Get-RubrikRequest.ps1 @@ -55,7 +55,8 @@ function Get-RubrikRequest { 'fileset', 'mssql', 'vmware/vm', 'hyperv/vm', 'hyperv/scvmm', 'managed_volume', 'volume_group', 'nutanix/vm', 'aws/ec2_instance', 'oracle','vcd/vapp', 'vcd/cluster', 'vmware/vcenter', 'cloud_on/azure', - 'report', 'nutanix/cluster', 'vmware/compute_cluster', 'sla_domain' + 'report', 'nutanix/cluster', 'vmware/compute_cluster', 'sla_domain', + 'backup/verify' )] [String]$Type, # Request @@ -111,6 +112,8 @@ function Get-RubrikRequest { $uri = $uri -replace 'v1', 'internal' } elseif ($v2types -contains $Type) { $uri = $uri -replace 'v1', 'v2' + } elseif ($Type -eq 'backup/verify') { + $uri = $uri -replace 'request/' } #endregion @@ -121,8 +124,13 @@ function Get-RubrikRequest { if ($Request) { Write-Verbose "Using uri supplied by pipeline: $($Request.links.href)" $uri = $Request.links.href + + # Fix for 5.3 + if ($uri -match 'backup_verification') { + $uri = $uri -replace 'backup_verification/request', 'backup/verify' + } } - + #We added new code that will now wait for the Rubrik Async Request to complete. Once completion has happened, we return back the request object. #region WaitForCompletion if ($WaitForCompletion) { @@ -138,7 +146,9 @@ function Get-RubrikRequest { else { Write-Progress -Activity "$($result.id)" -status "Job Queued" -percentComplete (0) } - Start-Sleep -Seconds 5 + if ($result.status -notin $ExitList) { + Start-Sleep -Seconds 5 + } } while ($result.status -notin $ExitList) } #endregion diff --git a/Rubrik/Public/Invoke-RubrikGraphQLCall.ps1 b/Rubrik/Public/Invoke-RubrikGraphQLCall.ps1 index a07d7c02..1313aae7 100644 --- a/Rubrik/Public/Invoke-RubrikGraphQLCall.ps1 +++ b/Rubrik/Public/Invoke-RubrikGraphQLCall.ps1 @@ -43,6 +43,11 @@ Returns all VMware VMs on the Rubrik Cluster and displays the individual objects Invoke-RubrikGraphQLCall -ReturnNode -Body '{"query":"query OrganizationSummary(\n $name: String,\n $isGlobal: Boolean,\n $sortBy: String,\n $sortOrder: String,\n $first: Int,\n $after: String,\n) {\n organizationConnection(\n name: $name,\n isGlobal: $isGlobal,\n sortBy: $sortBy,\n sortOrder: $sortOrder,\n first: $first,\n after: $after\n ) {\n nodes {\n id\n name\n isGlobal\n exclusivenessLevel\n admins {\n id\n name\n }\n envoyStatus\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n","variables":{"sortBy":"name","sortOrder":"asc","first":3,"name":"org","isGlobal":false}}' Returns informations on Rubrik Organizations, filtered by name in ascending order and only including organizations with 'org' in their name property. Returns the individual organization objects using the -ReturnNode parameter + +.EXAMPLE +(Invoke-RubrikGraphQLCall -Body '{"query":"query HostsWithSnappables(\n $effectiveSlaDomainId: String,\n $hostname: String,\n $operatingSystemType: String,\n $status: String,\n $primaryClusterId: String,\n $sortBy: String,\n $sortOrder: String,\n $templateId: String,\n $snappableStatus: String,\n $first: Int,\n $after: String,\n) {\n hostConnection(\n effectiveSlaDomainId: $effectiveSlaDomainId,\n hostname: $hostname,\n operatingSystemType: $operatingSystemType,\n status: $status,\n primaryClusterId: $primaryClusterId,\n sortBy: $sortBy,\n sortOrder: $sortOrder,\n templateId: $templateId,\n snappableStatus: $snappableStatus,\n first: $first,\n after: $after,\n )\n {\n nodes {\n id\n hostname\n primaryClusterId\n operatingSystem\n operatingSystemType\n status\n filesets\n {\n hostName\n operatingSystemType\n excludes\n configuredSlaDomainName\n effectiveSlaDomainId\n isEffectiveSlaDomainRetentionLocked\n primaryClusterId\n hostId\n includes\n configuredSlaDomainId\n configuredSlaDomainType\n templateId\n allowBackupNetworkMounts\n exceptions\n effectiveSlaDomainName\n allowBackupHiddenFoldersInNetworkMounts\n templateName\n useWindowsVss\n isRelic\n name\n id\n isPassthrough\n enableSymlinkResolution\n enableHardlinkSupport\n pendingSlaDomain {\n objectId,\n pendingSlaDomainId,\n pendingSlaDomainName,\n isPendingSlaDomainRetentionLocked\n }\n }\n hostVfdDriverState\n volumeGroup\n {\n isPaused\n configuredSlaDomainName\n effectiveSlaDomainId\n isEffectiveSlaDomainRetentionLocked\n primaryClusterId\n slaAssignment\n effectiveSlaSourceObjectId\n volumes {\n mountPoints\n isCurrentlyPresentOnSystem\n id\n size\n includeInSnapshots\n fileSystemType\n }\n effectiveSlaSourceObjectName\n hostId\n configuredSlaDomainId\n configuredSlaDomainType\n effectiveSlaDomainName\n hostname\n isRelic\n name\n volumeIdsIncludedInSnapshots\n id\n }\n storageArrayVolumeGroups\n {\n id\n name\n storageArrayId\n storageArrayName\n storageArrayType\n hostId\n hostname\n proxyHostId\n proxyHostname\n volumes {\n id\n serial\n name\n storageArrayId\n storageArrayType\n }\n configuredSlaDomainId\n configuredSlaDomainType\n configuredSlaDomainName\n effectiveSlaDomainId\n isEffectiveSlaDomainRetentionLocked\n effectiveSlaDomainName\n slaAssignment\n primaryClusterId\n }\n },\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n","variables":{"first":50,"operatingSystemType":"Windows","primaryClusterId":"local","sortBy":"hostname","sortOrder":"asc","snappableStatus":"Protectable"}}').hostconnection.nodes | % {[pscustomobject]@{hostname=$_.Hostname;volumegroup=$_.volumegroup.name;volumegroupsla=$_.volumegroup.effectivesladomainname}} + +Queries all hosts with volumegroups for the SLA set on that specific volumegroup. Returns 3 properties: hostname, volumegroup, volumegroupsla #> [cmdletbinding()] diff --git a/Rubrik/Public/New-RubrikMount.ps1 b/Rubrik/Public/New-RubrikMount.ps1 index e1658403..fa1d51d1 100644 --- a/Rubrik/Public/New-RubrikMount.ps1 +++ b/Rubrik/Public/New-RubrikMount.ps1 @@ -83,6 +83,10 @@ function New-RubrikMount if(-not $PSBoundParameters.ContainsKey('DisableNetwork')) { $Resources.Body.Remove('disableNetwork') } if(-not $PSBoundParameters.ContainsKey('RemoveNetworkDevices')) { $Resources.Body.Remove('removeNetworkDevices') } if(-not $PSBoundParameters.ContainsKey('PowerOn')) { $Resources.Body.Remove('powerOn') } + + if ($id -match ':') { + Write-Warning -Message ('"{0}" specified as ID, the ID should be a snapshot ID not an object ID' -f $Id) + } $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 diff --git a/Rubrik/Public/New-RubrikSnapshot.ps1 b/Rubrik/Public/New-RubrikSnapshot.ps1 index ad496ccb..13b8b9b8 100644 --- a/Rubrik/Public/New-RubrikSnapshot.ps1 +++ b/Rubrik/Public/New-RubrikSnapshot.ps1 @@ -50,7 +50,9 @@ function New-RubrikSnapshot [CmdletBinding(SupportsShouldProcess = $true,ConfirmImpact = 'High')] Param( # Rubrik's id of the object - [Parameter(Mandatory = $true,ValueFromPipelineByPropertyName = $true)] + [Parameter( + Mandatory = $true, + ValueFromPipelineByPropertyName = $true)] [String]$id, # The SLA Domain in Rubrik [Parameter( @@ -73,8 +75,10 @@ function New-RubrikSnapshot # SLA id value [Parameter( ParameterSetName = 'SLA_ByID', + ValueFromPipelineByPropertyName = $true, Mandatory = $true )] + [Alias('effectiveSlaDomainId')] [String]$SLAID, # Rubrik server IP or FQDN [String]$Server = $global:RubrikConnection.server, @@ -86,20 +90,20 @@ function New-RubrikSnapshot # 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 { @@ -134,7 +138,7 @@ function New-RubrikSnapshot $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 diff --git a/Rubrik/Public/Protect-RubrikTag.ps1 b/Rubrik/Public/Protect-RubrikTag.ps1 index 20cb9d1c..9d25c083 100644 --- a/Rubrik/Public/Protect-RubrikTag.ps1 +++ b/Rubrik/Public/Protect-RubrikTag.ps1 @@ -89,7 +89,7 @@ function Protect-RubrikTag Write-Verbose -Message "Gathering a list of VMs associated with Category $Category and Tag $Tag" try { - $vmlist = Get-VM -Tag (Get-Tag -Name $Tag -Category $Category) | Get-View + $vmlist = Get-VM -Tag (Get-Tag -Name $Tag -Category $Category -ErrorAction Stop) | Get-View # This will pull out the vCenter UUID assigned to the parent vCenter Server by Rubrik # Reset switches to prevent Get-RubrikVM from picking them up (must be a better way?) $DoNotProtect = $false diff --git a/Rubrik/Public/Test-RubrikSnapshotVerification.ps1 b/Rubrik/Public/Test-RubrikSnapshotVerification.ps1 new file mode 100644 index 00000000..ba5b32c8 --- /dev/null +++ b/Rubrik/Public/Test-RubrikSnapshotVerification.ps1 @@ -0,0 +1,105 @@ +function Test-RubrikSnapshotVerification +{ + <# + .SYNOPSIS + Tests a snapshot or multiple snapshots for consistency + + .DESCRIPTION + The Test-RubrikSnapshotVerification cmdlet can be used to validate the fingerprint of a snapshot(s) for consistency and reliablity, returning a csv containing the results + + .NOTES + Written by Jaap Brasser for community usage + Twitter: @jaap_brasser + GitHub: JaapBrasser + + .LINK + https://rubrik.gitbook.io/rubrik-sdk-for-powershell/command-documentation/reference/test-rubriksnapshotverification + + .EXAMPLE + Test-RubrikSnapshotVerification -id 'VirtualMachine:::111' + + This will initiate the test for all snapshots on VM with id 111. A callback uri is returned and an ID in order to track the request + + .EXAMPLE + Get-RubrikVM jaapsvm | Test-RubrikSnapshotVerification + + This will initiate the test for all snapshots on VM 'jaapsvm', A callback uri is returned and an ID in order to track the request + + .EXAMPLE + Start-RubrikDownload -uri (Test-RubrikSnapshotVerification -id 'VirtualMachine:::111' | Get-RubrikRequest -WaitForCompletion).links[1].href + + This will initiate the test for all snapshots on VM with id 111. The cmdlet will then wait for the Snapshot verification to be completed, when this happens the file is stored to the current folder + + .EXAMPLE + Invoke-RestMethod -uri (Test-RubrikSnapshotVerification -id 'VirtualMachine:::111' | Get-RubrikRequest -WaitForCompletion).links[1].href | ConvertFrom-Csv + + This will initiate the test for all snapshots on VM with id 111. The cmdlet will then wait for the Snapshot verification to be completed, when this happens the results are converted from csv and displayed in the console + #> + + [CmdletBinding( + SupportsShouldProcess = $true + )] + Param( + # Object id value + [Parameter( + Position = 0, + ValueFromPipelineByPropertyName = $true, + Mandatory = $true )] + [Alias('objectId')] + [ValidateNotNullOrEmpty()] + [String]$id, + # Snapshot id value(s) + [Alias('snapshotIdsOpt')] + [ValidateNotNullOrEmpty()] + [String[]]$SnapshotID, + # Location id value(s) + [Alias('locationIdOpt')] + [ValidateNotNullOrEmpty()] + [String]$LocationID, + # The datetime stamp to verify snapshots after + [Alias('shouldVerifyAfterOpt')] + [ValidateNotNullOrEmpty()] + [datetime]$VerifyAfter, + # Rubrik server IP or FQDN + [String]$Server = $global:RubrikConnection.server, + # API version + [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 { + if ($VerifyAfter) { + $VerifyAfter = ConvertTo-UniversalZuluDateTime -DateTimeValue $VerifyAfter + } + + if ($PSCmdlet.ShouldProcess("snapshot id: '$id'", "Validating backup of '$id'")) { + $uri = New-URIString -server $Server -endpoint ($resources.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 = Set-ObjectTypeName -TypeName $resources.ObjectTName -result $result + return $result + } + } # End of process +} # End of function \ No newline at end of file diff --git a/Rubrik/Rubrik.psd1 b/Rubrik/Rubrik.psd1 index e4cc3e6b..c205a506 100644 --- a/Rubrik/Rubrik.psd1 +++ b/Rubrik/Rubrik.psd1 @@ -130,6 +130,7 @@ 'Get-RubrikDatabaseMount', 'Get-RubrikDatabaseRecoverableRange', 'Get-RubrikDatabaseRecoveryPoint', + 'Get-RubrikDebugInfo', 'Get-RubrikDNSSetting', 'Get-RubrikDownloadLink', 'Get-RubrikEmailSetting', @@ -305,6 +306,7 @@ 'Stop-RubrikManagedVolumeSnapshot', 'Sync-RubrikAnnotation', 'Sync-RubrikTag', + 'Test-RubrikSnapshotVerification', 'Update-RubrikHost', 'Update-RubrikNutanixCluster', 'Update-RubrikVCD', @@ -353,7 +355,7 @@ # ReleaseNotes = '' # Prerelease string of this module - Prerelease = 'RC1' + # Prerelease = 'RC1' # Flag to indicate whether the module requires explicit user acceptance for install/update # RequireLicenseAcceptance = $false diff --git a/Tests/Get-RubrikAPIData.Tests.ps1 b/Tests/Get-RubrikAPIData.Tests.ps1 index 8f519ffc..2868ef33 100644 --- a/Tests/Get-RubrikAPIData.Tests.ps1 +++ b/Tests/Get-RubrikAPIData.Tests.ps1 @@ -19,7 +19,7 @@ Describe -Name 'Private/Get-RubrikAPIData' -Tag 'Private', 'Get-RubrikAPIData' - } #Function List - $ignorelist = @('Invoke-RubrikRESTCall','Invoke-RubrikGraphQLCall','Move-RubrikMountVMDK','Sync-RubrikAnnotation','Sync-RubrikTag','Get-RubrikModuleDefaultParameter','Set-RubrikModuleDefaultParameter','Get-RubrikModuleOption','Set-RubrikModuleOption','Remove-RubrikModuleDefaultParameter','Get-RubrikDownloadLink','Start-RubrikDownload') + $ignorelist = @('Invoke-RubrikRESTCall','Invoke-RubrikGraphQLCall','Move-RubrikMountVMDK','Sync-RubrikAnnotation','Sync-RubrikTag','Get-RubrikModuleDefaultParameter','Set-RubrikModuleDefaultParameter','Get-RubrikModuleOption','Set-RubrikModuleOption','Remove-RubrikModuleDefaultParameter','Get-RubrikDownloadLink','Start-RubrikDownload','Get-RubrikDebugInfo') $functions = ( Get-ChildItem -Path './Rubrik/Public' | Where-Object extension -eq '.ps1').Name.Replace('.ps1','') $functions = $functions | Where-Object {$ignorelist -notcontains $_} @@ -69,7 +69,7 @@ Describe -Name 'Private/Get-RubrikAPIData' -Tag 'Private', 'Get-RubrikAPIData' - It -Name 'Verify property exists' -Test { $functions = ( Get-ChildItem -Path './Rubrik/Public' | Where-Object extension -eq '.ps1').Name.Replace('.ps1','') - $ignorelist = @('Invoke-RubrikRESTCall','Invoke-RubrikGraphQLCall','Move-RubrikMountVMDK','Sync-RubrikAnnotation','Sync-RubrikTag','Get-RubrikObject','Get-RubrikDatabaseRecoveryPoint','Get-RubrikModuleDefaultParameter','Set-RubrikModuleDefaultParameter','Get-RubrikModuleOption','Set-RubrikModuleOption','Remove-RubrikModuleDefaultParameter', 'Get-RubrikDownloadLink','Start-RubrikDownload','Get-RubrikVgfClusterStorage','Get-RubrikVgfReport','Get-RubrikVgfUpgradeReport') + $ignorelist = @('Invoke-RubrikRESTCall','Invoke-RubrikGraphQLCall','Move-RubrikMountVMDK','Sync-RubrikAnnotation','Sync-RubrikTag','Get-RubrikObject','Get-RubrikDatabaseRecoveryPoint','Get-RubrikModuleDefaultParameter','Set-RubrikModuleDefaultParameter','Get-RubrikModuleOption','Set-RubrikModuleOption','Remove-RubrikModuleDefaultParameter', 'Get-RubrikDownloadLink','Start-RubrikDownload','Get-RubrikVgfClusterStorage','Get-RubrikVgfReport','Get-RubrikVgfUpgradeReport', 'Get-RubrikDebugInfo') $functions = $functions | Where-Object {$ignorelist -notcontains $_} $functions | ForEach-Object { (Get-RubrikAPIData -Endpoint $_).Function | diff --git a/Tests/Get-RubrikDebugInfo.Tests.ps1 b/Tests/Get-RubrikDebugInfo.Tests.ps1 new file mode 100644 index 00000000..a14a5632 --- /dev/null +++ b/Tests/Get-RubrikDebugInfo.Tests.ps1 @@ -0,0 +1,33 @@ +Remove-Module -Name 'Rubrik' -ErrorAction 'SilentlyContinue' +Import-Module -Name './Rubrik/Rubrik.psd1' -Force + +Describe -Name 'Public/Get-RubrikDebugInfo' -Tag 'Public', 'Get-RubrikDebugInfo' -Fixture { + #region init + $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 'Validate output of cmdlet' { + It -Name 'Should return correct PSVersion' -Test { + (Get-RubrikDebugInfo).PSVersion | Should -BeExactly $PSVersionTable.PSVersion + } + + It -Name 'Should return correct HostConsoleVersion' -Test { + $WarningPreference = 0 + (Get-RubrikDebugInfo).HostConsoleName | Should -BeExactly $host.Name + } + + It -Name 'Should return correct Culture' -Test { + $WarningPreference = 0 + (Get-RubrikDebugInfo).HostCulture | Should -BeExactly $host.CurrentCulture + } + } +} \ No newline at end of file diff --git a/Tests/Test-RubrikSnapshotVerification.Tests.ps1 b/Tests/Test-RubrikSnapshotVerification.Tests.ps1 new file mode 100644 index 00000000..f5ae2fd5 --- /dev/null +++ b/Tests/Test-RubrikSnapshotVerification.Tests.ps1 @@ -0,0 +1,49 @@ +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/Test-RubrikSnapshotVerification' -Tag 'Public', 'Test-RubrikSnapshotVerification' -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 = '5.3' + } + #endregion + + Context -Name 'Parameter Validation' { + Mock -CommandName Test-RubrikConnection -Verifiable -ModuleName 'Rubrik' -MockWith {} + Mock -CommandName Submit-Request -Verifiable -ModuleName 'Rubrik' -MockWith { + @{ + 'id' = 'BACKUP_INTEGRITY_VERIFICATION_eedf871d-65d6-4595-8e25-50ff79a2cefc_d0376dc4-af94-494a-b4ea-5140812f5eb5:::0' + 'status' = 'RUNNING' + 'progress' = '0' + 'startTime' = '4/8/2021 5:13:17 PM' + 'nodeId' = 'cluster:::22222' + 'links' = 'http:; rel=self}}' + 'snapshotVerificationInfo' = '@{snapshotId=b33a8' + } + } + It -Name 'Request Initiated' -Test { + (Test-RubrikSnapshotVerification -id 'VirtualMachine:::11111' ).snapshotVerificationInfo | + Should -BeExactly '@{snapshotId=b33a8' + } + + It -Name 'Parameter ID must be present' -Test { + { Start-RubrikManagedVolumeSnapshot -Id } | + Should -Throw "Missing an argument for parameter 'id'. Specify a parameter of type 'System.String' and try again." + } + + Assert-VerifiableMock + Assert-MockCalled -CommandName Test-RubrikConnection -ModuleName 'Rubrik' -Exactly 1 + Assert-MockCalled -CommandName Submit-Request -ModuleName 'Rubrik' -Exactly 1 + } +} \ No newline at end of file