AzStackHciNetwork/AzStackHci.Network.psm1
<#############################################################
# # # Copyright (C) Microsoft Corporation. All rights reserved. # # # #############################################################> Import-Module $PSScriptRoot\AzStackHci.Network.Helpers.psm1 -Force -DisableNameChecking -Global Import-Module $PSScriptRoot\..\AzStackHci.EnvironmentChecker.Utilities.psm1 -Force -DisableNameChecking -Global Import-Module $PSScriptRoot\..\AzStackHci.EnvironmentChecker.Reporting.psm1 -Force -DisableNameChecking -Global Import-LocalizedData -BindingVariable lnTxt -FileName AzStackHci.Network.Strings.psd1 function Invoke-AzStackHciNetworkValidation { <# .SYNOPSIS Perform AzStackHci Network Validation .DESCRIPTION Perform AzStackHci Network Validation by attempting to ICMP and TCP ports 22 and 5896. No response from any test consistutes a healthy result. The range is also validated for size and subnet. .EXAMPLE PS C:\> Invoke-AzStackHciNetworkValidation -StartingAddress 192.168.50.2 -EndingAddress 192.168.50.4 Perform Network validation against 192.168.50.2-192.168.50.4 from localhost. .EXAMPLE PS C:\> Invoke-AzStackHciNetworkValidation -AnswerFile C:\DeploymentData\AnswerFile.json Perform Network validation against against the startingAddress and EndingAddress read from C:\DeploymentData\AnswerFile.json. .INPUTS Inputs (if any) .OUTPUTS Output (if any) .LINK https://docs.microsoft.com/en-us/azure-stack/hci/manage/use-environment-checker?tabs=network #> [CmdletBinding()] param ( [Parameter(Mandatory = $true, ParameterSetName = 'Manual', HelpMessage = "Specify starting Management IP Range")] [Parameter(Mandatory = $true, ParameterSetName = 'AddNode', HelpMessage = "Specify starting infra IP Range")] [System.Net.IPAddress] $StartingAddress, [Parameter(Mandatory = $true, ParameterSetName = 'Manual', HelpMessage = "Specify end Management IP Range")] [Parameter(Mandatory = $true, ParameterSetName = 'AddNode', HelpMessage = "Specify end infra IP Range")] [System.Net.IPAddress] $EndingAddress, [Parameter(Mandatory = $true, ParameterSetName = 'AddNode', HelpMessage = "Specify the PsSession(s) used to validation from.")] [System.Management.Automation.Runspaces.PSSession] $PsSession, [Parameter(Mandatory = $true, ParameterSetName = 'AddNode', HelpMessage = "Run tests only for Add Node")] [switch] $AddNodeScenario, [Parameter(Mandatory = $true, ParameterSetName = 'AddNode', HelpMessage = "Specify Host and Mgmt IP Mapping for Nodes")] [Hashtable] $NodeToManagementIPMap, [Parameter(Mandatory = $true, ParameterSetName = 'AddNode', HelpMessage = "Specify First Adapter of Management Intent")] [String] $FirstAdapterName, [Parameter(Mandatory = $true, ParameterSetName = 'AddNode', HelpMessage = "Specify Intent Name of Management Intent")] [String] $IntentName, [Parameter(Mandatory = $true, ParameterSetName = 'AnswerFile', HelpMessage = "Specify full path to Deployment Answer File.")] [ValidateScript({ Test-Path -Path $PSITEM <# should be full path to answer file #> })] [string] $AnswerFile, [Parameter(Mandatory = $false, HelpMessage = "Return PSObject result.")] [switch] $PassThru, [Parameter(Mandatory = $false, HelpMessage = "Tests to include.")] [ArgumentCompleter({ Get-TestListByFunction -ModuleName AzStackHci.Network.Helpers })] [ValidateScript({ $_ -in (Get-TestListByFunction -ModuleName AzStackHci.Network.Helpers) })] [string[]] $Include, [Parameter(Mandatory = $false, HelpMessage = "Tests to exclude.")] [ArgumentCompleter({ Get-TestListByFunction -ModuleName AzStackHci.Network.Helpers })] [ValidateScript({ $_ -in (Get-TestListByFunction -ModuleName AzStackHci.Network.Helpers) })] [string[]] $Exclude, [Parameter(Mandatory = $false, HelpMessage = "Directory path for log and report output")] [string]$OutputPath, [Parameter(Mandatory = $false, HelpMessage = "Remove all previous progress and create a clean report")] [switch]$CleanReport = $false, [Parameter(Mandatory = $false, HelpMessage = "Show only failed results on screen.")] [switch]$ShowFailedOnly ) try { $script:ErrorActionPreference = 'Stop' Set-AzStackHciOutputPath -Path $OutputPath Write-AzStackHciHeader -invocation $MyInvocation -params $PSBoundParameters -PassThru:$PassThru #Test-ModuleUpdate -PassThru:$PassThru # Call/Initialise reporting $envcheckerReport = Get-AzStackHciEnvProgress -clean:$CleanReport $envcheckerReport = Add-AzStackHciEnvJob -report $envcheckerReport Import-Module $PSScriptRoot\AzStackHci.Network.Helpers.psm1 -Force -DisableNameChecking -Global if ($AnswerFile) { $DeploymentData = Get-DeploymentData -Path $AnswerFile $StartingAddress = $DeploymentData.InfrastructureNetwork.IpPools.StartingAddress $EndingAddress = $DeploymentData.InfrastructureNetwork.IpPools.EndingAddress if ([string]::IsNullOrEmpty($StartingAddress) -or [string]::IsNullOrEmpty($EndingAddress) -and $PassThru) { Log-Info $lnTxt.InvalidDeploymentData return (New-Object PsObject -Property @{ Name = 'AzStackHci_Network_Test_AnswerFile' Title = 'Test Answer File' Severity = 'Information' Description = 'Test Answer File' Remediation = 'https://learn.microsoft.com/en-us/azure-stack/hci/deploy/deployment-tool-checklist' TargetResourceID = 'AnswerFile' TargetResourceName = 'AnswerFile' TargetResourceType = 'AnswerFile' Timestamp = [datetime]::UtcNow HealthCheckSource = $ENV:EnvChkrId Status = 'Skipped' AdditionalData = New-Object -TypeName PSObject -Property @{ Source = $ENV:COMPUTERNAME Resource = 'AnswerFile' Detail = 'Cannot find Management IP Range StartingAddress or EndingAddress' Status = 'Skipped' TimeStamp = [datetime]::UtcNow } }) } } Write-Progress -Id 1 -Activity "Checking AzStackHci Dependancies" -Status "Network Configuration" -PercentComplete 0 -ErrorAction SilentlyContinue $TestList = Get-TestListByFunction -ModuleName AzStackHci.Network.Helpers $script:envchktestList = Select-TestList -Include $Include -Exclude $Exclude -TestList $TestList $TotalTestCount = ($script:envchktestList).Count # Run validation $i = 0 $Result = @() $ProgressActivity = "Checking AzStackHci Network Compatibility" $i = 0 $ProgressStatus = "Testing $ENV:ComputerName" $progressParams = @{ Id = 1 Activity = $ProgressActivity Status = $ProgressStatus ErrorAction = 'SilentlyContinue' } Write-Progress @progressParams if ($AddNodeScenario) { $script:envchktestList = Select-TestList -TestList TestMgmtIPForNewNode $TotalTestCount = ($script:envchktestList).Count :noTestsBreak foreach ($test in $script:envchktestList) { $OpMsg = "Checking {0} on {1}" -f $test, $ENV:ComputerName Log-Info -Message $OpMsg Write-Progress @progressParams -CurrentOperation $OpMsg -PercentComplete (($i++ / $TotalTestCount) * 100) $splat = @{ StartingAddress = $StartingAddress EndingAddress = $EndingAddress PSSession = $PsSession NodeToManagementIPMap = $NodeToManagementIPMap FirstAdapterName = $FirstAdapterName IntentName = $IntentName } $Result += Invoke-Expression "$test @splat" } # The way the $AddNodeScenario tests are invoked are currently being refactored and this is temporary to invoke the tests. $script:envchktestList = Select-TestList -TestList TestNetworkIntentStatus $TotalTestCount = ($script:envchktestList).Count :noTestsBreak foreach ($test in $script:envchktestList) { $OpMsg = "Checking {0} on {1}" -f $test, $ENV:ComputerName Log-Info -Message $OpMsg Write-Progress @progressParams -CurrentOperation $OpMsg -PercentComplete (($i++ / $TotalTestCount) * 100) $splat = @{ PSSession = $PsSession } $Result += Invoke-Expression "$test @splat" } } else { :noTestsBreak foreach ($test in $script:envchktestList) { $OpMsg = "Checking {0} on {1}" -f $test, $ENV:ComputerName Log-Info -Message $OpMsg Write-Progress @progressParams -CurrentOperation $OpMsg -PercentComplete (($i++ / $TotalTestCount) * 100) $splat = @{ StartingAddress = $StartingAddress EndingAddress = $EndingAddress } $Result += Invoke-Expression "$test @splat" } } # Feedback results - user scenario Log-Info "Network Validation" -ConsoleOut:(-not $PassThru) if (-not $PassThru) { $progressParams = @{ Id = 3 Activity = "Formating Results" Status = "Writing Results for $($ENV:ComputerName)" PercentComplete = 1 ErrorAction = 'SilentlyContinue' } Write-Progress @progressParams Write-AzStackHciResult -Title "$($ENV:COMPUTERNAME):" -Result $result -ShowFailedOnly:$ShowFailedOnly -Seperator ': ' Write-Summary -Result $Result -Property1 Detail } else { return $result } } catch { Log-Info -Message "" -ConsoleOut Log-Info -Message "$($_.Exception.Message)" -ConsoleOut -Type Error Log-Info -Message "$($_.ScriptStackTrace)" -ConsoleOut -Type Error $cmdletFailed = $true throw $_ } finally { $Script:ErrorActionPreference = 'SilentlyContinue' # Write result to telemetry channel foreach ($r in $result) { Write-ETWResult -Result $r } # Write validation result to report object and close out report $envcheckerReport | Add-Member -MemberType NoteProperty -Name 'Network' -Value $Result -Force $envcheckerReport = Close-AzStackHciEnvJob -report $envcheckerReport Write-AzStackHciEnvReport -report $envcheckerReport Write-AzStackHciFooter -invocation $MyInvocation -Failed:$cmdletFailed -PassThru:$PassThru } } # SIG # Begin signature block # MIInkgYJKoZIhvcNAQcCoIIngzCCJ38CAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBvfcUhrYsir4ND # Ja8InCmewQlCXoWSb7mx5A+kjIYtnKCCDXYwggX0MIID3KADAgECAhMzAAADTrU8 # esGEb+srAAAAAANOMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p # bmcgUENBIDIwMTEwHhcNMjMwMzE2MTg0MzI5WhcNMjQwMzE0MTg0MzI5WjB0MQsw # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB # AQDdCKiNI6IBFWuvJUmf6WdOJqZmIwYs5G7AJD5UbcL6tsC+EBPDbr36pFGo1bsU # p53nRyFYnncoMg8FK0d8jLlw0lgexDDr7gicf2zOBFWqfv/nSLwzJFNP5W03DF/1 # 1oZ12rSFqGlm+O46cRjTDFBpMRCZZGddZlRBjivby0eI1VgTD1TvAdfBYQe82fhm # WQkYR/lWmAK+vW/1+bO7jHaxXTNCxLIBW07F8PBjUcwFxxyfbe2mHB4h1L4U0Ofa # +HX/aREQ7SqYZz59sXM2ySOfvYyIjnqSO80NGBaz5DvzIG88J0+BNhOu2jl6Dfcq # jYQs1H/PMSQIK6E7lXDXSpXzAgMBAAGjggFzMIIBbzAfBgNVHSUEGDAWBgorBgEE # AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUnMc7Zn/ukKBsBiWkwdNfsN5pdwAw # RQYDVR0RBD4wPKQ6MDgxHjAcBgNVBAsTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEW # MBQGA1UEBRMNMjMwMDEyKzUwMDUxNjAfBgNVHSMEGDAWgBRIbmTlUAXTgqoXNzci # tW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8vd3d3Lm1pY3Jvc29mdC5j # b20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3JsMGEG # CCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDovL3d3dy5taWNyb3NvZnQu # Y29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3J0 # MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIBAD21v9pHoLdBSNlFAjmk # mx4XxOZAPsVxxXbDyQv1+kGDe9XpgBnT1lXnx7JDpFMKBwAyIwdInmvhK9pGBa31 # TyeL3p7R2s0L8SABPPRJHAEk4NHpBXxHjm4TKjezAbSqqbgsy10Y7KApy+9UrKa2 # kGmsuASsk95PVm5vem7OmTs42vm0BJUU+JPQLg8Y/sdj3TtSfLYYZAaJwTAIgi7d # hzn5hatLo7Dhz+4T+MrFd+6LUa2U3zr97QwzDthx+RP9/RZnur4inzSQsG5DCVIM # pA1l2NWEA3KAca0tI2l6hQNYsaKL1kefdfHCrPxEry8onJjyGGv9YKoLv6AOO7Oh # JEmbQlz/xksYG2N/JSOJ+QqYpGTEuYFYVWain7He6jgb41JbpOGKDdE/b+V2q/gX # UgFe2gdwTpCDsvh8SMRoq1/BNXcr7iTAU38Vgr83iVtPYmFhZOVM0ULp/kKTVoir # IpP2KCxT4OekOctt8grYnhJ16QMjmMv5o53hjNFXOxigkQWYzUO+6w50g0FAeFa8 # 5ugCCB6lXEk21FFB1FdIHpjSQf+LP/W2OV/HfhC3uTPgKbRtXo83TZYEudooyZ/A # Vu08sibZ3MkGOJORLERNwKm2G7oqdOv4Qj8Z0JrGgMzj46NFKAxkLSpE5oHQYP1H # tPx1lPfD7iNSbJsP6LiUHXH1MIIHejCCBWKgAwIBAgIKYQ6Q0gAAAAAAAzANBgkq # hkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x # EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv # bjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 # IDIwMTEwHhcNMTEwNzA4MjA1OTA5WhcNMjYwNzA4MjEwOTA5WjB+MQswCQYDVQQG # EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG # A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSgwJgYDVQQDEx9NaWNyb3NvZnQg # Q29kZSBTaWduaW5nIFBDQSAyMDExMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC # CgKCAgEAq/D6chAcLq3YbqqCEE00uvK2WCGfQhsqa+laUKq4BjgaBEm6f8MMHt03 # a8YS2AvwOMKZBrDIOdUBFDFC04kNeWSHfpRgJGyvnkmc6Whe0t+bU7IKLMOv2akr # rnoJr9eWWcpgGgXpZnboMlImEi/nqwhQz7NEt13YxC4Ddato88tt8zpcoRb0Rrrg # OGSsbmQ1eKagYw8t00CT+OPeBw3VXHmlSSnnDb6gE3e+lD3v++MrWhAfTVYoonpy # 4BI6t0le2O3tQ5GD2Xuye4Yb2T6xjF3oiU+EGvKhL1nkkDstrjNYxbc+/jLTswM9 # sbKvkjh+0p2ALPVOVpEhNSXDOW5kf1O6nA+tGSOEy/S6A4aN91/w0FK/jJSHvMAh # dCVfGCi2zCcoOCWYOUo2z3yxkq4cI6epZuxhH2rhKEmdX4jiJV3TIUs+UsS1Vz8k # A/DRelsv1SPjcF0PUUZ3s/gA4bysAoJf28AVs70b1FVL5zmhD+kjSbwYuER8ReTB # w3J64HLnJN+/RpnF78IcV9uDjexNSTCnq47f7Fufr/zdsGbiwZeBe+3W7UvnSSmn # Eyimp31ngOaKYnhfsi+E11ecXL93KCjx7W3DKI8sj0A3T8HhhUSJxAlMxdSlQy90 # lfdu+HggWCwTXWCVmj5PM4TasIgX3p5O9JawvEagbJjS4NaIjAsCAwEAAaOCAe0w # ggHpMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBRIbmTlUAXTgqoXNzcitW2o # ynUClTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMCAYYwDwYD # VR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRyLToCMZBDuRQFTuHqp8cx0SOJNDBa # BgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2Ny # bC9wcm9kdWN0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFfMDNfMjIuY3JsMF4GCCsG # AQUFBwEBBFIwUDBOBggrBgEFBQcwAoZCaHR0cDovL3d3dy5taWNyb3NvZnQuY29t # L3BraS9jZXJ0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFfMDNfMjIuY3J0MIGfBgNV # HSAEgZcwgZQwgZEGCSsGAQQBgjcuAzCBgzA/BggrBgEFBQcCARYzaHR0cDovL3d3 # dy5taWNyb3NvZnQuY29tL3BraW9wcy9kb2NzL3ByaW1hcnljcHMuaHRtMEAGCCsG # AQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAHAAbwBsAGkAYwB5AF8AcwB0AGEAdABl # AG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUAA4ICAQBn8oalmOBUeRou09h0ZyKb # C5YR4WOSmUKWfdJ5DJDBZV8uLD74w3LRbYP+vj/oCso7v0epo/Np22O/IjWll11l # hJB9i0ZQVdgMknzSGksc8zxCi1LQsP1r4z4HLimb5j0bpdS1HXeUOeLpZMlEPXh6 # I/MTfaaQdION9MsmAkYqwooQu6SpBQyb7Wj6aC6VoCo/KmtYSWMfCWluWpiW5IP0 # wI/zRive/DvQvTXvbiWu5a8n7dDd8w6vmSiXmE0OPQvyCInWH8MyGOLwxS3OW560 # STkKxgrCxq2u5bLZ2xWIUUVYODJxJxp/sfQn+N4sOiBpmLJZiWhub6e3dMNABQam # ASooPoI/E01mC8CzTfXhj38cbxV9Rad25UAqZaPDXVJihsMdYzaXht/a8/jyFqGa # J+HNpZfQ7l1jQeNbB5yHPgZ3BtEGsXUfFL5hYbXw3MYbBL7fQccOKO7eZS/sl/ah # XJbYANahRr1Z85elCUtIEJmAH9AAKcWxm6U/RXceNcbSoqKfenoi+kiVH6v7RyOA # 9Z74v2u3S5fi63V4GuzqN5l5GEv/1rMjaHXmr/r8i+sLgOppO6/8MO0ETI7f33Vt # Y5E90Z1WTk+/gFcioXgRMiF670EKsT/7qMykXcGhiJtXcVZOSEXAQsmbdlsKgEhr # /Xmfwb1tbWrJUnMTDXpQzTGCGXIwghluAgEBMIGVMH4xCzAJBgNVBAYTAlVTMRMw # EQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN # aWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNp # Z25pbmcgUENBIDIwMTECEzMAAANOtTx6wYRv6ysAAAAAA04wDQYJYIZIAWUDBAIB # BQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEO # MAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEICFKXxrOldTxRLoSK7/KYSjg # ntq2sB97TAO+roCeqaVeMEIGCisGAQQBgjcCAQwxNDAyoBSAEgBNAGkAYwByAG8A # cwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20wDQYJKoZIhvcNAQEB # BQAEggEAhPXKzRVzjPM1tif8HLm/BjSr+zukekMnoA939vnPGY1hLaOg2DNY52Vi # DgVPM+Uz1fERYoUxgtnhOFzCcVsxgGkdjRuDNPxzDBDZgvr94zRScx7XFRsnPyO9 # whMbPco5Jci//pG5Tmw3qvQaCyzQ3alQj38/WRUc1XYDRG1F4937QerADzo43w2V # HxTaKlNoft/edvj5qGaYpU8yqMUULILw0rtJv+gNmqge/3eJydUW/pnftxTzEyaH # XselmaPNwuj2bJWt7VsWu2rgspMA21JYrql91Cl3taumlRDF/caKZz8xzGq9AXvn # CTs0WcnrQo9Awx+0D/R4VpGcxsLkaaGCFvwwghb4BgorBgEEAYI3AwMBMYIW6DCC # FuQGCSqGSIb3DQEHAqCCFtUwghbRAgEDMQ8wDQYJYIZIAWUDBAIBBQAwggFQBgsq # hkiG9w0BCRABBKCCAT8EggE7MIIBNwIBAQYKKwYBBAGEWQoDATAxMA0GCWCGSAFl # AwQCAQUABCC9AVyQP7UkXNoJnK9lHZz1er1u8kCQBq7r6Q28QO7lCQIGZDfqPGrs # GBIyMDIzMDUwNDE1NTkyOS45NlowBIACAfSggdCkgc0wgcoxCzAJBgNVBAYTAlVT # MRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQK # ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJTAjBgNVBAsTHE1pY3Jvc29mdCBBbWVy # aWNhIE9wZXJhdGlvbnMxJjAkBgNVBAsTHVRoYWxlcyBUU1MgRVNOOjEyQkMtRTNB # RS03NEVCMSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNloIIR # VDCCBwwwggT0oAMCAQICEzMAAAHKT8Kz7QMNGGwAAQAAAcowDQYJKoZIhvcNAQEL # BQAwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcT # B1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UE # AxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAwHhcNMjIxMTA0MTkwMTQw # WhcNMjQwMjAyMTkwMTQwWjCByjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hp # bmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jw # b3JhdGlvbjElMCMGA1UECxMcTWljcm9zb2Z0IEFtZXJpY2EgT3BlcmF0aW9uczEm # MCQGA1UECxMdVGhhbGVzIFRTUyBFU046MTJCQy1FM0FFLTc0RUIxJTAjBgNVBAMT # HE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2UwggIiMA0GCSqGSIb3DQEBAQUA # A4ICDwAwggIKAoICAQDDAZyr2PnStYSRwtKUZkvB5RV/FdFpSOI+zJo1XE90xGzc # JV7nyyK78SRpW3u3s81M+Sj+zyU226wB4sSfOSLjjLGTZz16SbwTVJDZhX1vz8s7 # F8pqlny1WU/LHDoOYXM0VCOJ9WbwSJnuUVGhjjjy+lxsEPXyqNg0X/ZndJByFyx1 # XU31jpXZYaXnlWYuoVFfn52m12Ot4FfOLdZb1OygIRZxgIErnBiBL21PZJJJPNp7 # eOZ3DjSD4s4jKtU8XYOjORK2/okEM+/BqFdakoak7usesoX6jsQI39WJAUxnKn+/ # F4+JQAEM2rMRQjyzuSViZ4de+N5A6r8IzcL9jxuPd8k5udkft4Be9EOfFPxHpb+4 # PWYZQm+/0z0Ey7eeEqkqZLHPM7ku1wwSHa0xfGEwYY0xQ/cM4Qrdf7b8sPVnTe6w # lOTmkc2gf+AMi9unvzsLDjS2wCmIC+2sdjC5vROoi/xnLraXyfyz8y/8/vrgJOqv # FxfNqUEeH5fLhc+OZp2c+RknJyncpzNuSD1Bu8mnQf/QWzAdL558Wh+kM0nAuHWG # z9oyLUr+jMS/v9Ysg+wOArXp9T9rHJuowqTQ07GB6VSMBgqXjBTRjpDir03/0/AB # LRyyJ9CFjWihB8AjSIMIJIQBOyUPxtM7S1G2p1wh1q85F6rOg928C/cOvVddDwID # AQABo4IBNjCCATIwHQYDVR0OBBYEFPrH/qVLgRJDwpmF3RGBTtFhczx/MB8GA1Ud # IwQYMBaAFJ+nFV0AXmJdg/Tl0mWnG1M1GelyMF8GA1UdHwRYMFYwVKBSoFCGTmh0 # dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY3Jvc29mdCUyMFRp # bWUtU3RhbXAlMjBQQ0ElMjAyMDEwKDEpLmNybDBsBggrBgEFBQcBAQRgMF4wXAYI # KwYBBQUHMAKGUGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY2VydHMv # TWljcm9zb2Z0JTIwVGltZS1TdGFtcCUyMFBDQSUyMDIwMTAoMSkuY3J0MAwGA1Ud # EwEB/wQCMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwgwDQYJKoZIhvcNAQELBQADggIB # ANjQeSoJLcq4p58Vfz+ub920P3Trp0oSV42quLBmqwzhibwTDhCKo6o7uZahhhjg # rnLx5dI4co1c5+k7pFtpiPyMI5wkAHm2ouXmGIyBoxsBUuuXWGWLH2yWg7jks43Q # mmEq9rcPoBUoDs/vyYD2JEdlhRWtGLJ+9CNbGZSfGGKzx+ib3b79EdwRnUOHn6ni # DN54vzhiXTRbKr0RyAEop+CrSUKNY1KrUBQbWwQuWBc5K8pnj+Vdcf4x+Fwd73VY # shpmRL8e73B1NPojXgEL3vKEOxlZcCXQgnzTUjpS0QWkKxN47JkEnsIXSt/mXEny # 0T2iM2zKpckq7BWfR7AIyRmrP9wTC/0UTHxCaxnRk2h1O2yX5X11mb55SswpmTo8 # qwoCu1D6MeR9WweAo4OWh6Wk6YeqBftRs7Q1WciWk/nmBBOpXvq9TvBFelR/PsqE # TcFlc2DAbTl1GcJcPCuGFjP4i1vOzUrVHwjhgwMmNb3QBIKD0l/7HKBEpkYoeOjY # GzZfJoq43U/oUUIhVc3sqAeX9tmJqQaruTlNDg5crnGSEIeGN2Ae7GPeErkBo7L4 # ZfE7+NvKoZGp5LF/5NM+5aENa6sijfdEwMZ7kNsiaNxtyPp1WFB6+ocKVHU4dJ+v # 7ybWFZEkaULVq1w5YpqMCvA5RGolJWVOHBWAjLMY2aPOMIIHcTCCBVmgAwIBAgIT # MwAAABXF52ueAptJmQAAAAAAFTANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMC # VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV # BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJv # b3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTAwHhcNMjEwOTMwMTgyMjI1WhcN # MzAwOTMwMTgzMjI1WjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv # bjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0 # aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDCCAiIw # DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAOThpkzntHIhC3miy9ckeb0O1YLT # /e6cBwfSqWxOdcjKNVf2AX9sSuDivbk+F2Az/1xPx2b3lVNxWuJ+Slr+uDZnhUYj # DLWNE893MsAQGOhgfWpSg0S3po5GawcU88V29YZQ3MFEyHFcUTE3oAo4bo3t1w/Y # JlN8OWECesSq/XJprx2rrPY2vjUmZNqYO7oaezOtgFt+jBAcnVL+tuhiJdxqD89d # 9P6OU8/W7IVWTe/dvI2k45GPsjksUZzpcGkNyjYtcI4xyDUoveO0hyTD4MmPfrVU # j9z6BVWYbWg7mka97aSueik3rMvrg0XnRm7KMtXAhjBcTyziYrLNueKNiOSWrAFK # u75xqRdbZ2De+JKRHh09/SDPc31BmkZ1zcRfNN0Sidb9pSB9fvzZnkXftnIv231f # gLrbqn427DZM9ituqBJR6L8FA6PRc6ZNN3SUHDSCD/AQ8rdHGO2n6Jl8P0zbr17C # 89XYcz1DTsEzOUyOArxCaC4Q6oRRRuLRvWoYWmEBc8pnol7XKHYC4jMYctenIPDC # +hIK12NvDMk2ZItboKaDIV1fMHSRlJTYuVD5C4lh8zYGNRiER9vcG9H9stQcxWv2 # XFJRXRLbJbqvUAV6bMURHXLvjflSxIUXk8A8FdsaN8cIFRg/eKtFtvUeh17aj54W # cmnGrnu3tz5q4i6tAgMBAAGjggHdMIIB2TASBgkrBgEEAYI3FQEEBQIDAQABMCMG # CSsGAQQBgjcVAgQWBBQqp1L+ZMSavoKRPEY1Kc8Q/y8E7jAdBgNVHQ4EFgQUn6cV # XQBeYl2D9OXSZacbUzUZ6XIwXAYDVR0gBFUwUzBRBgwrBgEEAYI3TIN9AQEwQTA/ # BggrBgEFBQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9Eb2Nz # L1JlcG9zaXRvcnkuaHRtMBMGA1UdJQQMMAoGCCsGAQUFBwMIMBkGCSsGAQQBgjcU # AgQMHgoAUwB1AGIAQwBBMAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8G # A1UdIwQYMBaAFNX2VsuP6KJcYmjRPZSQW9fOmhjEMFYGA1UdHwRPME0wS6BJoEeG # RWh0dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jv # b0NlckF1dF8yMDEwLTA2LTIzLmNybDBaBggrBgEFBQcBAQROMEwwSgYIKwYBBQUH # MAKGPmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMvTWljUm9vQ2Vy # QXV0XzIwMTAtMDYtMjMuY3J0MA0GCSqGSIb3DQEBCwUAA4ICAQCdVX38Kq3hLB9n # ATEkW+Geckv8qW/qXBS2Pk5HZHixBpOXPTEztTnXwnE2P9pkbHzQdTltuw8x5MKP # +2zRoZQYIu7pZmc6U03dmLq2HnjYNi6cqYJWAAOwBb6J6Gngugnue99qb74py27Y # P0h1AdkY3m2CDPVtI1TkeFN1JFe53Z/zjj3G82jfZfakVqr3lbYoVSfQJL1AoL8Z # thISEV09J+BAljis9/kpicO8F7BUhUKz/AyeixmJ5/ALaoHCgRlCGVJ1ijbCHcNh # cy4sa3tuPywJeBTpkbKpW99Jo3QMvOyRgNI95ko+ZjtPu4b6MhrZlvSP9pEB9s7G # dP32THJvEKt1MMU0sHrYUP4KWN1APMdUbZ1jdEgssU5HLcEUBHG/ZPkkvnNtyo4J # vbMBV0lUZNlz138eW0QBjloZkWsNn6Qo3GcZKCS6OEuabvshVGtqRRFHqfG3rsjo # iV5PndLQTHa1V1QJsWkBRH58oWFsc/4Ku+xBZj1p/cvBQUl+fpO+y/g75LcVv7TO # PqUxUYS8vwLBgqJ7Fx0ViY1w/ue10CgaiQuPNtq6TPmb/wrpNPgkNWcr4A245oyZ # 1uEi6vAnQj0llOZ0dFtq0Z4+7X6gMTN9vMvpe784cETRkPHIqzqKOghif9lwY1NN # je6CbaUFEMFxBmoQtB1VM1izoXBm8qGCAsswggI0AgEBMIH4oYHQpIHNMIHKMQsw # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSUwIwYDVQQLExxNaWNy # b3NvZnQgQW1lcmljYSBPcGVyYXRpb25zMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVT # TjoxMkJDLUUzQUUtNzRFQjElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAg # U2VydmljZaIjCgEBMAcGBSsOAwIaAxUAo47nlwxPizI8/qcKWDYhZ9qMyqSggYMw # gYCkfjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE # BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYD # VQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQUF # AAIFAOf+FqYwIhgPMjAyMzA1MDQxOTMzNThaGA8yMDIzMDUwNTE5MzM1OFowdDA6 # BgorBgEEAYRZCgQBMSwwKjAKAgUA5/4WpgIBADAHAgEAAgIFMjAHAgEAAgIRxjAK # AgUA5/9oJgIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAowCAIB # AAIDB6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBBQUAA4GBABv6UUa0ko4X315+ # af8TT+CGhMBEaBC2LY1I0p+2i1JiqzH2jPozWYgSOf8pOI474Edw+qf4wVqqvmDg # 8PjDIralqK8NbWT2Vu70xiR0vkCgRcaqd7OvRILvg/fTFkoIvCfAY9S2gC1scau9 # cWPy3x/RbDaZapwaZ9CPUJKELUSYMYIEDTCCBAkCAQEwgZMwfDELMAkGA1UEBhMC # VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV # BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRp # bWUtU3RhbXAgUENBIDIwMTACEzMAAAHKT8Kz7QMNGGwAAQAAAcowDQYJYIZIAWUD # BAIBBQCgggFKMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0B # CQQxIgQg6/eePxDQWtNWugRMrlpSRYbTJgAelpaCNQV2CEDsqEUwgfoGCyqGSIb3 # DQEJEAIvMYHqMIHnMIHkMIG9BCATPRvzm+tVTayVkCTiO3VIMSTojNkDBUKhbAXc # rNwa4DCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9u # MRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRp # b24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAAB # yk/Cs+0DDRhsAAEAAAHKMCIEIIqWFtfF8MWr1s0juNi8WcVbpB+3xCqNwVSZH8GS # ctvGMA0GCSqGSIb3DQEBCwUABIICALK0wmhrXq0gub5cNnoBJMllCLVgb9eDvI94 # AR1VNxeWWfXoHRqYiPqhePvYCrySeEgTTh5Q6LFMJO+yygvBsuwxVnRt+KcJrvZX # EqhBbzhS/WYVX8g9eQECx9UmgIxSitV0QxJvsIbkWqIJXgDXgPHb4IO8lmnzj0Z3 # 0ahQHv+/mUhNIR7HOVGzUMvg0kPMxVlpzsXRBo6oY/GLY9gxGuZ9Vjd0+EpHSX/4 # d1aujjSR5FgsSmz95jlojDIzW1j9ggF3wS0GwrqGRt/5w8DaDtfO+7rZpFV3Z/aY # 2eq80GecSiuRZ75hC9/hW43j0Z0cfEKx62L6+gSUuqx2JdAJ6IDj2Zmu31vYhU1N # rwXbYhK1elPvdLDhNy1xOHTc8tPpVmQIKTGOKLpAhyULr3oVUh0SiHfNSQewFlX/ # NDso50SZZCS28N4h0k2hlWzSknn/8FeZNp06LlOVvq7ENlztqmxS/XJljBk/0cHt # 6SIe7sPSD42dQ/l0fslDIQewAPKCODqzVZboNLu1/2ZD34hdOWZlbxywyFkdPtF9 # K+jite6N3/sshW4ixPcXmWDYfv0TYUzV+gP5BFDe7g/kHPImDKle4KwZ6z2ebVfZ # BzBDoxCzFhqwMb4RCy7/BSiPCILqiw9OiScHhxKL4WWHP6L6WBrcrqM0Cfvbhz09 # ro/9swQ+ # SIG # End signature block |