Private/Checks/VCenter/Test-VcfVcenterApplianceSizeCheck.ps1
|
# Copyright (c) 2026 Broadcom. All Rights Reserved. # Broadcom Confidential. The term "Broadcom" refers to Broadcom Inc. # and/or its subsidiaries. # # ============================================================================= # # SOFTWARE LICENSE AGREEMENT # # Copyright (c) CA, Inc. All rights reserved. # # You are hereby granted a non-exclusive, worldwide, royalty-free license # under CA, Inc.'s copyrights to use, copy, modify, and distribute this # software in source code or binary form for use in connection with CA, Inc. # products. # # This copyright notice shall be included in all copies or substantial # portions of the software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. # # ============================================================================= #region VCenterApplianceSizeCheck function Get-VcfCheckVCenterApplianceUpgradeApiSteps { <# .SYNOPSIS Returns the fixed-width, numbered SDDC Manager API call sequence for resizing a vCenter appliance's disk tier during an upgrade. .DESCRIPTION VCSA does not support arbitrary disk sizes (Broadcom KB326287) - moving a vCenter appliance to a larger disk preset can only be done as part of an SDDC Manager API driven vCenter upgrade (Reduced Downtime Migration), never in place. This is the same call sequence documented for the Upgrade Resource Estimator in Docs/SIZING_ESTIMATOR_TODO.md. .OUTPUTS [String] the numbered steps, one per line. #> [CmdletBinding()] [OutputType([String])] Param () return @( '1. GET /v1/domains - determine the domain ID for the domain in question.' '2. GET /v1/upgradables/domains/{domainId} - check what''s upgradable for the domain.' '3. GET /v1/upgradables/domains/{domainId}/vcenter-upgrade-mechanisms - determine whether InPlace or ReducedDowntimeMigration (RDU) is eligible for this vCenter. Size selection only matters for the RDU path.' '4. GET /v1/upgradables/domains/{domainId}/vcenter-sizing-infos?targetVersion=<version> - fetch available applianceSize/storageSize combos with isRecommended and resource-requirement fields; select the next larger storageSize than the appliance''s current preset.' '5. POST /v1/upgrades with UpgradeSpec.draftMode = true - stages the upgrade without executing, so it can be precheck''d first.' '6. POST /v1/upgrades/{upgradeId}/prechecks - kicks off precheck validation, returns a Task.' '7. GET /v1/upgrades/{upgradeId}/prechecks/{precheckId} - poll until precheck completes.' '8. PATCH /v1/upgrades/{upgradeId} - commits the DRAFT upgrade to SCHEDULED, actually running it. Alternatively, skip draft mode entirely and call POST /v1/upgrades once with resourceUpgradeSpecs[].upgradeNow: true to run immediately, with no separate precheck/commit step.' '9. GET /v1/upgrades/{upgradeId} or GET /v1/tasks/{id} - poll status.' '' 'The sizing choice is carried in vcenterUpgradeUserInputSpecs[].targetVcenterAppliance (applianceSize, storageSize), alongside upgradeMechanism, switchoverType, and a required temporaryNetwork (a temporary IP is needed during appliance switchover).' ) -join "`n" } function Get-VcfCheckVCenterApplianceSizeEvaluation { <# .SYNOPSIS Evaluates a vCenter appliance sizing snapshot for undersizing and disjoint disk conditions. .DESCRIPTION Reuses Get-VcfCheckSizingSnapshotForVCenter's output (recommendedSizeTier, actualSizeTier, actualStorageSizeKey) to decide the Status/Detail/Rows for Test-VcfVcenterApplianceSizeCheck. Undersized (recommendedSizeTier ranks above actualSizeTier - the appliance is currently running smaller than its live host/VM count now calls for): non-blocking, since Get-VcfCheckSizingSnapshotForVCenter never recommends a tier below the appliance's actual size, this only ever suggests sizing up. Disjoint disk (actualStorageSizeKey is null - the appliance's measured disk, even allowing the existing 5% thin-provisioning tolerance, does not match any of its tier's VCSA disk presets): blocking, since it requires an SDDC Manager API driven vCenter upgrade to move to the next disk preset rather than an in-place resize. .PARAMETER Snapshot Output of Get-VcfCheckSizingSnapshotForVCenter. .PARAMETER ReferenceData Output of Get-VcfCheckSizingReferenceData. .OUTPUTS [PSObject] with Status, Detail, and Rows. #> [CmdletBinding()] [OutputType([PSObject])] Param ( [Parameter(Mandatory = $true)] [Hashtable]$Snapshot, [Parameter(Mandatory = $true)] [Hashtable]$ReferenceData ) $vcenterFqdn = $Snapshot['vcenterFqdn'] if (-not $Snapshot['actualSizeTier']) { return [PSCustomObject]@{ Status = 'Skipped'; Detail = "Could not determine `"$vcenterFqdn`"'s actual VCSA appliance size tier from its measured vCPU/RAM - cannot evaluate its sizing."; SkipReasonTag = 'Appliance size undetermined'; Rows = @() } } $isUndersized = $Snapshot['recommendedSizeTier'] -ne $Snapshot['actualSizeTier'] $isDisjointDisk = -not $Snapshot['actualStorageSizeKey'] if (-not $isUndersized -and -not $isDisjointDisk) { return [PSCustomObject]@{ Status = 'Pass'; Detail = "`"$vcenterFqdn`" is sized `"$($Snapshot['actualSizeTier'])`" ($($Snapshot['actualCpuCores']) vCPU, $($Snapshot['actualMemoryGb']) GB RAM, $($Snapshot['actualStorageGb']) GB disk) with a standard `"$($Snapshot['actualStorageSizeKey'])`" disk preset for its live host/VM inventory ($($Snapshot['hostCount']) hosts / $($Snapshot['virtualMachineCount']) VMs)."; Rows = @() } } $vcenterRef = $ReferenceData['vcenter'] $rows = @() $detailParts = @() if ($isUndersized) { $recommendedTierKey = $Snapshot['recommendedSizeTier'].ToLowerInvariant() $recommendedVCpu = $vcenterRef['cpuCores'][$recommendedTierKey] $recommendedMemoryGb = $vcenterRef['memoryGb'][$recommendedTierKey] $recommendedStorageGb = $vcenterRef['storageGb']["$($recommendedTierKey)Default"] $rows += [PSCustomObject]@{ Condition = 'Undersized' CurrentSizeTier = $Snapshot['actualSizeTier'] CurrentVCpu = $Snapshot['actualCpuCores'] CurrentMemoryGb = $Snapshot['actualMemoryGb'] CurrentStorageGb = $Snapshot['actualStorageGb'] RecommendedSizeTier = $Snapshot['recommendedSizeTier'] RecommendedVCpu = $recommendedVCpu RecommendedMemoryGb = $recommendedMemoryGb RecommendedStorageGb = $recommendedStorageGb } $detailParts += "`"$vcenterFqdn`" is sized `"$($Snapshot['actualSizeTier'])`" ($($Snapshot['actualCpuCores']) vCPU, $($Snapshot['actualMemoryGb']) GB RAM, $($Snapshot['actualStorageGb']) GB disk; $($Snapshot['hostCount']) hosts / $($Snapshot['virtualMachineCount']) VMs under management), which calls for at least `"$($Snapshot['recommendedSizeTier'])`" ($recommendedVCpu vCPU, $recommendedMemoryGb GB RAM, $recommendedStorageGb GB disk with Standard Storage). This is a suggestion only - when it's time for upgrade, we recommend manually resizing the appliance to `"$($Snapshot['recommendedSizeTier'])`" via the SDDC Manager API." } if ($isDisjointDisk) { $rows += [PSCustomObject]@{ Condition = 'Disjoint Disk' ActualSizeTier = $Snapshot['actualSizeTier'] ActualVCpu = $Snapshot['actualCpuCores'] ActualMemoryGb = $Snapshot['actualMemoryGb'] ActualStorageGb = $Snapshot['actualStorageGb'] } $detailParts += "`"$vcenterFqdn`" appliance ($($Snapshot['actualCpuCores']) vCPU, $($Snapshot['actualMemoryGb']) GB RAM, $($Snapshot['actualStorageGb']) GB disk) does not match any `"$($Snapshot['actualSizeTier'])`" VCSA disk preset (Default/Large Storage/X-Large Storage), even allowing the standard 5% thin-provisioning tolerance. VCSA does not support arbitrary disk sizes - this bumps the appliance to the next disk tier and blocks the upgrade until performed via an SDDC Manager API driven vCenter upgrade:`n`n$(Get-VcfCheckVCenterApplianceUpgradeApiSteps)" } $status = if ($isDisjointDisk) { 'Fail' } else { 'Warning' } return [PSCustomObject]@{ Status = $status; Detail = ($detailParts -join "`n`n"); Rows = $rows } } function Test-VcfVcenterApplianceSizeCheck { <# .SYNOPSIS Evaluates whether each vCenter appliance is correctly sized for its live host/VM inventory and its VCSA disk preset. .DESCRIPTION Reuses the Upgrade Resource Estimator's sizing snapshot (Get-VcfCheckSizingSnapshotForVCenter) for every vCenter attached to SDDC Manager: - Undersized appliance: non-blocking Warning suggesting a manual resize to the recommended size tier at upgrade time, with that tier's vCPU/RAM/disk requirements. Never suggests sizing down - the appliance's own actual tier is always the floor. - Disjoint disk (measured disk doesn't match any VCSA disk preset for its size tier): blocking Fail requiring an SDDC Manager API driven vCenter upgrade to the next disk tier. Delegates execution across vCenter domains to Invoke-VcfCheckPerVCenterCheck. .PARAMETER Context The VcfCheck.Context object. Must already be connected to SDDC Manager. .PARAMETER DisplayName Optional friendly display name for the check result. .OUTPUTS [PSObject[]] Per-vCenter check results generated by Invoke-VcfCheckPerVCenterCheck. #> [CmdletBinding()] [OutputType([PSObject])] Param ( [Parameter(Mandatory = $true)] [PSObject]$Context, [Parameter(Mandatory = $false)] [String]$DisplayName = '' ) return Invoke-VcfCheckPerVCenterCheck -Context $Context -CheckId 'vcenter_appliance_size_check' -Area vCenter -DisplayName $DisplayName -Body { param($Context, $VCenterFqdn) $domainName = Get-VcfCheckVCenterDomainName -Context $Context -Fqdn $VCenterFqdn $managementVCenterFqdn = Get-VcfCheckManagementVCenterFqdn -Context $Context $applianceInventoryServers = @($managementVCenterFqdn, $VCenterFqdn) | Select-Object -Unique $treatmentData = Get-VcfCheckBrownfieldTreatmentData $snapshot = Get-VcfCheckSizingSnapshotForVCenter -DomainName $domainName -VCenterFqdn $VCenterFqdn -ApplianceInventoryServers $applianceInventoryServers -TreatmentData $treatmentData return Get-VcfCheckVCenterApplianceSizeEvaluation -Snapshot $snapshot -ReferenceData (Get-VcfCheckSizingReferenceData) } } |