Private/AzStackHci.Constants.ps1

# ////////////////////////////////////////////////////////////////////////////
# Module Constants
# Centralized configuration values for the AzStackHci.DiagnosticSettings module.
# All constant numbers and hardcoded values are defined here for easy maintenance.
# ////////////////////////////////////////////////////////////////////////////

# --- Memory Dump Settings ---
# Default dedicated dump file size for systems with less than the large memory threshold
[uint32]$script:DUMP_FILE_SIZE_DEFAULT_MIB = 65536        # 64 GiB

# Dedicated dump file size for large memory systems (>= $LARGE_MEMORY_THRESHOLD_BYTES)
[uint32]$script:DUMP_FILE_SIZE_LARGE_MIB = 131072         # 128 GiB

# RAM threshold (in bytes) above which the large dump file size is used
[uint64]$script:LARGE_MEMORY_THRESHOLD_BYTES = 768GB

# Disk space reserve percentage for dedicated dump file validation
[double]$script:DUMP_DISK_RESERVE_PERCENT = 0.1           # 10%

# --- Page File Settings ---
# Minimum fixed page file size in MiB
[uint32]$script:PAGE_FILE_MINIMUM_SIZE_MIB = 4096          # 4 GiB

# --- Cluster Performance Log Collection ---
# Minimum free disk space (in MiB) required before starting log collection
[uint32]$script:LOG_COLLECTION_MIN_DISK_MIB = 10240        # 10 GiB

# Disk space reserve percentage for log collection
[double]$script:LOG_COLLECTION_DISK_RESERVE_PERCENT = 0.05 # 5%

# --- DNS Settings ---
# Maximum number of DNS resolution retry attempts
[int]$script:DNS_MAX_RETRIES = 3

# Base delay in seconds for exponential backoff between DNS retries
[int]$script:DNS_RETRY_BASE_DELAY_SEC = 1

# --- HTTP / Layer 7 Settings ---
# Maximum number of HTTP redirect hops before giving up
[int]$script:HTTP_MAX_REDIRECTS = 10

# Default timeout in seconds for Invoke-WebRequest calls
[int]$script:HTTP_TIMEOUT_SEC = 60

# HttpClient timeout in ticks (60 seconds = 600,000,000 ticks)
[long]$script:HTTPCLIENT_TIMEOUT_TICKS = 600000000

# --- Network Ports ---
# Well-known ports used for protocol inference
[int]$script:PORT_HTTP = 80
[int]$script:PORT_HTTPS = 443
[int]$script:PORT_HTTPS_ALT1 = 8084
[int]$script:PORT_HTTPS_ALT2 = 8443
[int]$script:PORT_NTP = 123

# --- Animation / UI ---
# Spinner animation frame interval in milliseconds
[int]$script:ANIMATION_FRAME_MS = 125

# Maximum time (in seconds) to wait for a background job before giving up
[int]$script:JOB_ANIMATION_TIMEOUT_SEC = 600  # 10 minutes

# --- SSL Inspection Detection ---
# Known trusted root CA thumbprints for Microsoft services.
# Used by Test-AzStackHciSSLInspection to verify the certificate chain
# is not being intercepted by an SSL inspection appliance.
# These are the root CAs that Microsoft and its CDN partners use.
[string[]]$script:TRUSTED_ROOT_CA_THUMBPRINTS = @(
    # DigiCert Global Root G2
    'DF3C24F9BFD666761B268073FE06D1CC8D4F82A4',
    # DigiCert Global Root CA
    'A8985D3A65E5E5C4B2D7D66D40C6DD2FB19C5436',
    # Baltimore CyberTrust Root
    'D4DE20D05E66FC53FE1A50882C78DB2852CAE474',
    # Microsoft RSA Root Certificate Authority 2017
    '73A5E64A3BFF8316FF0EDCCC618A906E4EAE4D74',
    # Microsoft ECC Root Certificate Authority 2017
    '999A64C37FF47D9FAB95F14769891460EEC4C3C5'
)

# Expected certificate issuer organization strings (for string-based fallback check)
[string[]]$script:EXPECTED_CERT_ISSUERS = @(
    'O=Microsoft Corporation',
    'O=DigiCert Inc'
)

# --- Critical Arc Service Private Link Endpoints ---
# Endpoints that MUST NOT resolve to RFC1918 addresses (Private Link not supported for Arc)
[string[]]$script:PRIVATE_LINK_CRITICAL_ENDPOINTS = @(
    'gbl.his.arc.azure.com',
    '*.guestconfiguration.azure.com'
)

# --- Azure Region Endpoint URLs ---
# GitHub raw URLs for downloading region-specific required endpoint lists.
# Used by Test-AzureLocalConnectivity to fetch the latest endpoint definitions.
[hashtable]$script:REGION_ENDPOINT_URLS = @{
    "EastUS"        = "https://raw.githubusercontent.com/Azure/AzureStack-Tools/master/HCI/EastUSendpoints/eastus-hci-endpoints.md"
    "WestEurope"    = "https://raw.githubusercontent.com/Azure/AzureStack-Tools/master/HCI/WestEuropeendpoints/westeurope-hci-endpoints.md"
    "AustraliaEast" = "https://raw.githubusercontent.com/Azure/AzureStack-Tools/master/HCI/AustraliaEastendpoints/AustraliaEast-hci-endpoints.md"
    "CanadaCentral"  = "https://raw.githubusercontent.com/Azure/AzureStack-Tools/master/HCI/CanadaCentralEndpoints/canadacentral-hci-endpoints.md"
    "CentralIndia"  = "https://raw.githubusercontent.com/Azure/AzureStack-Tools/refs/heads/master/HCI/IndiaCentralEndpoints/IndiaCentral-hci-endpoints.md"
    "JapanEast"     = "https://raw.githubusercontent.com/Azure/AzureStack-Tools/refs/heads/master/HCI/JapanEastEndpoints/japaneast-hci-endpoints.md"
    "SouthCentral"  = "https://raw.githubusercontent.com/Azure/AzureStack-Tools/refs/heads/master/HCI/SouthCentralUSEndpoints/southcentralus-hci-endpoints.md"
    "SouthEastAsia" = "https://raw.githubusercontent.com/Azure/AzureStack-Tools/refs/heads/master/HCI/SouthEastAsiaEndpoints/southeastasia-hci-endpoints.md"
    "USGovVirginia" = "https://raw.githubusercontent.com/Azure/AzureStack-Tools/refs/heads/master/HCI/usgovvirginia-hci-endpoints/usgovvirginia-hci-endpoints.md"
}

# --- OEM SBE Endpoint URLs ---
# GitHub raw URLs for hardware OEM Solution Builder Extension (SBE) endpoint lists.
# Used by Get-HardwareOEMUrlContent to fetch OEM-specific required endpoints.
[hashtable]$script:OEM_ENDPOINT_URLS = @{
    "DataOn"  = "https://raw.githubusercontent.com/Azure/AzureStack-Tools/refs/heads/master/HCI/OEMEndpoints/DataOn/DataOnAzureLocalEndpoints.md"
    "Dell"    = "https://raw.githubusercontent.com/Azure/AzureStack-Tools/refs/heads/master/HCI/OEMEndpoints/Dell/DellAzureLocalEndpoints.md"
    "HPE"     = "https://raw.githubusercontent.com/Azure/AzureStack-Tools/refs/heads/master/HCI/OEMEndpoints/HPE/HPEAzureLocalEndpoints.md"
    "Hitachi" = "https://raw.githubusercontent.com/Azure/AzureStack-Tools/refs/heads/master/HCI/OEMEndpoints/Hitachi/HitachiAzureLocalEndpoints.md"
    "Lenovo"  = "https://raw.githubusercontent.com/Azure/AzureStack-Tools/refs/heads/master/HCI/OEMEndpoints/Lenovo/LenovoAzureLocalEndpoints.md"
}

# --- Manually Defined Wildcard Subdomains ---
# Static list of known subdomains used to validate connectivity for wildcard endpoints.
# Defined here so the total count is available before the main testing loop for unified progress tracking.
$script:MANUAL_SUBDOMAINS = @(
    @{ Wildcard = "*.blob.core.windows.net"; Subdomains = @("mystorageaccount.blob.core.windows.net","eus2azreplstore214.blob.core.windows.net") },
    @{ Wildcard = "*.download.windowsupdate.com"; Subdomains = @("1a.au.download.windowsupdate.com") },
    @{ Wildcard = "*.update.microsoft.com"; Subdomains = @("fe2.update.microsoft.com") },
    @{ Wildcard = "*.windowsupdate.com"; Subdomains = @("ctldl.windowsupdate.com") },
    @{ Wildcard = "*.endpoint.security.microsoft.com"; Subdomains = @("edr-neu3.eu.endpoint.security.microsoft.com") },
    @{ Wildcard = "*.prod.hot.ingest.monitor.core.windows.net"; Subdomains = @("prod5.prod.hot.ingest.monitor.core.windows.net") },
    @{ Wildcard = "*.servicebus.windows.net"; Subdomains = @("azgn-southcentralus-public-1p-sn-vazr0002.servicebus.windows.net") }
)
# Pre-calculated total subdomain count for progress tracking
[int]$script:MANUAL_SUBDOMAIN_COUNT = ($script:MANUAL_SUBDOMAINS | ForEach-Object { $_.Subdomains.Count } | Measure-Object -Sum).Sum

# --- Module State Initialization ---
# Central initialization of all module-scoped state variables.
# This makes the shared surface explicit and enables clean reset between runs.
function Initialize-ModuleState {
    <#
    .SYNOPSIS
        Resets all module-scoped state variables to their default values.
    .DESCRIPTION
        Called during module load and can be called between test runs to ensure
        clean state. All $script: variables used for cross-function communication
        are initialized here.
    #>

    $script:SilentMode = $false
    $script:Proxy = $null
    [System.Collections.ArrayList]$script:Results = @()
    [System.Collections.ArrayList]$script:RedirectedResults = @()
    $script:SSLInspectionDetected = $false
    [System.Collections.ArrayList]$script:SSLInspectedURLs = @()
    $script:PrivateLinkDetected = $false
    $script:PrivateLinkDetectedArray = @()
    $script:PrivateLinkCriticalEndpoints = $script:PRIVATE_LINK_CRITICAL_ENDPOINTS
    $script:DedicatedDumpFileSize = 0
    $script:MinimumRequiredDiskSpace = 0
    $script:PageFileAutoManaged = $false
    $script:PageFileConfiguration = $null
    $script:PageFileAllocatedBaseSize = 0
    $script:PageFileCurrentUsage = 0
    $script:PageFilePeakUsage = 0
    $script:CurrentDumpFile = $null
    $script:CurrentSettings = $null
    $script:DateFormatted = $null
    $script:OutputFolderPath = $null
    $script:OutputFile = $null
    $script:OutputFileExtension = $null
    $script:CsvFile = $null
    $script:TranscriptFile = $null
    $script:UpdatedKeyVaultURL = $null
    $script:UpdatedArcGatewayURL = $null
    $script:HardwareOEM = $null
    $script:PreArcGatewayRemoval = $null
    $script:job = $null
}

# Initialize state on module load
Initialize-ModuleState