Private/Checks/VCenter/Test-VcfVcenterVamiCheckStorage.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.
#
# =============================================================================
function Test-VcfVcenterVamiCheckStorage {

    <#
        .SYNOPSIS
        Reports per-partition storage utilization across all vCenter appliances attached to SDDC Manager.

        .DESCRIPTION
        Queries system storage partitions across all vCenter appliances attached to SDDC Manager using
        Get-VcfCheckApplianceSystemStorage, excluding non-disk pseudo-filesystems (such as 'none').

        Retrieves filesystem total size and used metrics for each valid partition via Get-VcfCheckApplianceStorageUsage
        to compute overall usage percentage and available free space in gigabytes.

        Evaluation logic:
        - Pass: Storage utilization metrics successfully retrieved and calculated for all valid partitions.
        - Error: No storage partitions are returned by the appliance system query.

        Populates a structured Rows table detailing Partition, Used %, and Free Space (GB).
        Delegates per-vCenter execution and per-domain outcome packaging 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_vami_check_storage' -Area vCenter -DisplayName $DisplayName -Body {
        param($Context, $VCenterFqdn)
        # The "none" partition is a pseudo-filesystem entry with no backing disk; its usage query always fails.
        $partitions = @(Get-VcfCheckApplianceSystemStorage -Server $VCenterFqdn | Where-Object { $_.Partition -ne 'none' })

        if ($partitions.Count -eq 0) {
            return [PSCustomObject]@{ Status = 'Error'; Detail = 'No storage partitions returned.'; Rows = @() }
        }

        $rows = [System.Collections.Generic.List[PSObject]]::new()
        foreach ($partition in $partitions) {
            $partitionName = $partition.Partition
            $partitionStartedAt = Get-Date
            $usedPercentage = $null
            $freeSpaceGB = $null
            $status = 'Unavailable'

            try {
                $totalMetric = Get-VcfCheckApplianceStorageUsage -Server $VCenterFqdn -ItemName "storage.totalsize.filesystem.$partitionName"
                $usedMetric = Get-VcfCheckApplianceStorageUsage -Server $VCenterFqdn -ItemName "storage.used.filesystem.$partitionName"
                $total = ($totalMetric | Select-Object -First 1 -ExpandProperty Data -ErrorAction SilentlyContinue | Select-Object -Last 1)
                $used = ($usedMetric | Select-Object -First 1 -ExpandProperty Data -ErrorAction SilentlyContinue | Select-Object -Last 1)
                if ($total -and [Double]$total -gt 0) {
                    $usedPercentage = [Math]::Round(([Double]$used / [Double]$total) * 100, 2)
                    # storage.totalsize/used.filesystem.* return KB; divide by 1MB's byte count to get GB.
                    $freeSpaceGB = [Math]::Round(([Double]$total - [Double]$used) / 1MB, 2)
                    $status = 'OK'
                }
            } catch {
                $status = 'Query Failed'
            } finally {
                $partitionMs = ((Get-Date) - $partitionStartedAt).TotalMilliseconds
                Write-LogMessage -Type DEBUG -Message "[$VCenterFqdn] Partition `"$partitionName`" usage query took $(Format-VcfCheckDuration -Milliseconds $partitionMs); status: $status."
            }

            $rows.Add([PSCustomObject]@{
                Partition          = $partitionName
                'Used %'           = $usedPercentage
                'Free Space (GB)'  = $freeSpaceGB
            })
        }
        $rows = @($rows | Sort-Object -Property Partition)

        return [PSCustomObject]@{ Status = 'Pass'; Detail = $null; Rows = $rows }
    }
}