AzStackHci.EnvironmentChecker.Operations.psm1
<#############################################################
# # # Copyright (C) Microsoft Corporation. All rights reserved. # # # #############################################################> function Invoke-EnvironmentValidator { <# .SYNOPSIS Wrapper command to Test Environment Readiness .DESCRIPTION Wrapper command to test environment readiness, run locally on HCI system. .PARAMETER OperationType Type of Operation. .PARAMETER WaitForResult Wait for action plan to complete. #> [CmdletBinding()] Param( [Parameter(Mandatory = $true, ParameterSetName = "AddNode")] [Parameter(Mandatory = $true, ParameterSetName = 'All')] [Parameter(Mandatory = $true, ParameterSetName = "Update")] [ValidateSet('Deploy', 'Upgrade', 'AddNode', 'Update')] [String] $OperationType, [Parameter(Mandatory = $true, ParameterSetName = "AddNode")] [ValidateNotNullOrEmpty()] [String] $Name, [Parameter(Mandatory = $true, ParameterSetName = "AddNode")] [ValidateNotNullOrEmpty()] [String] $HostIpv4, [Parameter(Mandatory = $false, ParameterSetName = "Update")] [ValidateNotNullOrEmpty()] [String] $EnvironmentCheckerResultPath = "$($env:LocalRootFolderPath)\MasLogs\EnvironmentCheckerUpdateResult.json", [Parameter(Mandatory = $false, ParameterSetName = 'All', HelpMessage = 'Wait for action plan to conclude. Shows progress if running on the ECE owning node.')] [switch]$Wait ) $ErrorActionPreference = 'Stop' # Check if we are running Orchestrator as a service or lite $Script:OrchestratorSvc = IsOrchestratorSvc # Check if action plan is running $RunningActionPlans = Get-AzStackHciEnvironmentCheckerActionPlan | Where-Object Status -In 'Running', 'Queued' if ($RunningActionPlans) { throw "Environment Validator action plan in progress" } # Archive Log file ArchiveLogFiles $ActionType = switch ($OperationType) { 'Deploy' { 'EnvironmentValidatorFull' } 'Upgrade' { 'EnvironmentValidatorUpgrade' } 'AddNode' { 'EnvironmentValidatorAddNode' } 'Update' { 'EnvironmentValidatorPreUpdate' } Default {} } Write-Verbose "Starting Environment Validator for $OperationType" # TODO check if Deploy, Upgrade or AddNode ops are running here? $params = @{ RolePath = 'Cloud\Infrastructure\EnvironmentValidator' ActionType = $ActionType } # Add needs a node name and IP, take these from the user if ($ActionType -eq 'EnvironmentValidatorAddNode') { if ([string]::IsNullOrEmpty($Name) -or [string]::IsNullOrEmpty($HostIpv4)) { throw "Parameters missing: Name and HostIpv4 must be supplied when OperationType is AddNode." } $params += @{ runtimeParameters = @{ NodeName = $Name IpAddress = $HostIpv4 } } } # Update needs a path to the result file, take this from the user if ($ActionType -eq 'EnvironmentValidatorPreUpdate') { if ([string]::IsNullOrEmpty($EnvironmentCheckerResultPath)) { throw "Parameters missing: EnvironmentCheckerResultPath must be supplied when OperationType is Update." } $params += @{ runtimeParameters = @{ EnvironmentCheckerResultPath = $EnvironmentCheckerResultPath } } } if ($Script:OrchestratorSvc) { $ActionPlanInstanceId = Invoke-ActionPlanInstance @params 4>$null if (-not $wait) { Write-Verbose "To check progress, open a powershell session to $(GetOrchestratorOwner) and call: 'Get-AzStackHciEnvironmentCheckerProgress -Path $($env:LocalRootFolderPath)\MasLogs\AzStackHciEnvironmentProgress.json'" } } else { Invoke-EceAction @params if (-not $wait) { Write-Verbose "To check progress, call: 'Get-AzStackHciEnvironmentCheckerProgress -Path $($env:LocalRootFolderPath)\MasLogs\AzStackHciEnvironmentProgress.json'" } } Start-Sleep -Seconds 5 for ($i = 0; $i -lt 30; $i++) { $ActionPlan = Get-AzStackHciEnvironmentCheckerActionPlan | Sort-Object LastModifiedDateTime -Descending | Select-Object -First 1 switch ($ActionPlan.Status) { { $_ -in "Failed", "Cancelled" } { throw "$ActionType is $($actionPlan.Status). Please resume please review: `n $($actionPlan.ProgressAsXml)" } { $_ -in "Waiting", "Pending" } { Write-Verbose "$ActionType is currently $($actionPlan.Status)" } { $_ -eq "Running" } { Write-Verbose "$ActionType is currently $($actionPlan.Status)" if ($Wait) { if ($ENV:COMPUTERNAME -eq (GetOrchestratorOwner)) { Get-AzStackHciEnvironmentCheckerProgress | Format-Table Result, StartTime, EndTime, DurationSeconds, Name, Description -AutoSize } } else { break outer } } { $_ -eq 'Completed' } { if ($ENV:COMPUTERNAME -eq (GetOrchestratorOwner)) { Get-AzStackHciEnvironmentCheckerProgress | Format-Table Result, StartTime, EndTime, DurationSeconds, Name, Description -AutoSize } break outer } default { Write-Warning "$ActionType cannot be started due to unknown status of last run" return } } Start-Sleep -Seconds 30 } Write-Verbose "$ActionType $($ActionPlanResult.Status) Action Plan ID: $($ActionPlanInstanceId.Guid)" } function Get-AzStackHciEnvironmentCheckerActionPlan { <# .SYNOPSIS Get all Environment Validator action plan instances #> [CmdletBinding()] param () $validatorLookup = 'EnvironmentValidator*' if (IsOrchestratorSvc) { Get-ActionPlanInstances | Where-Object { $_.ActionTypeName -like $validatorLookup } } else { Get-ActionProgress -ActionType $validatorLookup } } function Get-AzStackHciEnvironmentCheckerProgress { <# .SYNOPSIS Intended for internal-use to retrieve multi-validator invocation progress using action plan #> [CmdletBinding()] param ( [Parameter()] [string] $Path = "$($env:LocalRootFolderPath)\MasLogs\AzStackHciEnvironmentProgress.json" ) Get-Content $Path -ErrorAction SilentlyContinue | ConvertFrom-Json } function ArchiveLogFiles { <# .SYNOPSIS INTERNAL USE ONLY - Archives any supporting files for environment checker. #> [CmdletBinding()] param ( [Parameter()] [string] $Path = "$($env:LocalRootFolderPath)\MASLogs" ) # Archive any logs 'AzStackHciEnvironmentChecker.log', 'AzStackHciEnvironmentProgress.json', 'AzStackHciEnvironmentReport.json', 'AzStackHciEnvironmentReport.xml' | ForEach-Object { Get-ChildItem -Path $Path -Filter $PSITEM -ErrorAction SilentlyContinue | ForEach-Object { Rename-Item -Path $PSITEM.FullName -NewName ($PSITEM.fullname -replace '(\.)', ('_{0}.' -f (Get-Date -Format yyyyMMdd-HHmmss))) } } } function IsOrchestratorSvc { [CmdletBinding()] param () $orchestratorSvc = Get-Service | Where-Object {$_.Name -eq 'ECE Windows Service' -or $_.Name -eq 'Azure Stack HCI Orchestrator Service'} if ($orchestratorSvc) { return $true } else { Import-Module C:\CloudDeployment\ECEngine\EnterpriseCloudEngine.psd1 -Force return $false } } function GetOrchestratorOwner { [CmdletBinding()] param () try { Get-ClusterGroup | Where-Object {$_.Name -eq 'ECE Windows Service Cluster Group' -or $_.Name -eq 'Azure Stack HCI Orchestrator Service Cluster Group'} | Select-Object -expandProperty OwnerNode | Select-Object -ExpandProperty Name } catch { return $null } } # SIG # Begin signature block # MIInzgYJKoZIhvcNAQcCoIInvzCCJ7sCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBk2oxvuCmn6Gws # tgkq3ELgsBX3FvXKva+UIFbOAaz5KKCCDYUwggYDMIID66ADAgECAhMzAAADri01 # UchTj1UdAAAAAAOuMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p # bmcgUENBIDIwMTEwHhcNMjMxMTE2MTkwODU5WhcNMjQxMTE0MTkwODU5WjB0MQsw # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB # AQD0IPymNjfDEKg+YyE6SjDvJwKW1+pieqTjAY0CnOHZ1Nj5irGjNZPMlQ4HfxXG # yAVCZcEWE4x2sZgam872R1s0+TAelOtbqFmoW4suJHAYoTHhkznNVKpscm5fZ899 # QnReZv5WtWwbD8HAFXbPPStW2JKCqPcZ54Y6wbuWV9bKtKPImqbkMcTejTgEAj82 # 6GQc6/Th66Koka8cUIvz59e/IP04DGrh9wkq2jIFvQ8EDegw1B4KyJTIs76+hmpV # M5SwBZjRs3liOQrierkNVo11WuujB3kBf2CbPoP9MlOyyezqkMIbTRj4OHeKlamd # WaSFhwHLJRIQpfc8sLwOSIBBAgMBAAGjggGCMIIBfjAfBgNVHSUEGDAWBgorBgEE # AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUhx/vdKmXhwc4WiWXbsf0I53h8T8w # VAYDVR0RBE0wS6RJMEcxLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJh # dGlvbnMgTGltaXRlZDEWMBQGA1UEBRMNMjMwMDEyKzUwMTgzNjAfBgNVHSMEGDAW # gBRIbmTlUAXTgqoXNzcitW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8v # d3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIw # MTEtMDctMDguY3JsMGEGCCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDov # L3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDEx # XzIwMTEtMDctMDguY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIB # AGrJYDUS7s8o0yNprGXRXuAnRcHKxSjFmW4wclcUTYsQZkhnbMwthWM6cAYb/h2W # 5GNKtlmj/y/CThe3y/o0EH2h+jwfU/9eJ0fK1ZO/2WD0xi777qU+a7l8KjMPdwjY # 0tk9bYEGEZfYPRHy1AGPQVuZlG4i5ymJDsMrcIcqV8pxzsw/yk/O4y/nlOjHz4oV # APU0br5t9tgD8E08GSDi3I6H57Ftod9w26h0MlQiOr10Xqhr5iPLS7SlQwj8HW37 # ybqsmjQpKhmWul6xiXSNGGm36GarHy4Q1egYlxhlUnk3ZKSr3QtWIo1GGL03hT57 # xzjL25fKiZQX/q+II8nuG5M0Qmjvl6Egltr4hZ3e3FQRzRHfLoNPq3ELpxbWdH8t # Nuj0j/x9Crnfwbki8n57mJKI5JVWRWTSLmbTcDDLkTZlJLg9V1BIJwXGY3i2kR9i # 5HsADL8YlW0gMWVSlKB1eiSlK6LmFi0rVH16dde+j5T/EaQtFz6qngN7d1lvO7uk # 6rtX+MLKG4LDRsQgBTi6sIYiKntMjoYFHMPvI/OMUip5ljtLitVbkFGfagSqmbxK # 7rJMhC8wiTzHanBg1Rrbff1niBbnFbbV4UDmYumjs1FIpFCazk6AADXxoKCo5TsO # zSHqr9gHgGYQC2hMyX9MGLIpowYCURx3L7kUiGbOiMwaMIIHejCCBWKgAwIBAgIK # YQ6Q0gAAAAAAAzANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNV # BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv # c29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlm # aWNhdGUgQXV0aG9yaXR5IDIwMTEwHhcNMTEwNzA4MjA1OTA5WhcNMjYwNzA4MjEw # OTA5WjB+MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE # BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSgwJgYD # VQQDEx9NaWNyb3NvZnQgQ29kZSBTaWduaW5nIFBDQSAyMDExMIICIjANBgkqhkiG # 9w0BAQEFAAOCAg8AMIICCgKCAgEAq/D6chAcLq3YbqqCEE00uvK2WCGfQhsqa+la # UKq4BjgaBEm6f8MMHt03a8YS2AvwOMKZBrDIOdUBFDFC04kNeWSHfpRgJGyvnkmc # 6Whe0t+bU7IKLMOv2akrrnoJr9eWWcpgGgXpZnboMlImEi/nqwhQz7NEt13YxC4D # dato88tt8zpcoRb0RrrgOGSsbmQ1eKagYw8t00CT+OPeBw3VXHmlSSnnDb6gE3e+ # lD3v++MrWhAfTVYoonpy4BI6t0le2O3tQ5GD2Xuye4Yb2T6xjF3oiU+EGvKhL1nk # kDstrjNYxbc+/jLTswM9sbKvkjh+0p2ALPVOVpEhNSXDOW5kf1O6nA+tGSOEy/S6 # A4aN91/w0FK/jJSHvMAhdCVfGCi2zCcoOCWYOUo2z3yxkq4cI6epZuxhH2rhKEmd # X4jiJV3TIUs+UsS1Vz8kA/DRelsv1SPjcF0PUUZ3s/gA4bysAoJf28AVs70b1FVL # 5zmhD+kjSbwYuER8ReTBw3J64HLnJN+/RpnF78IcV9uDjexNSTCnq47f7Fufr/zd # sGbiwZeBe+3W7UvnSSmnEyimp31ngOaKYnhfsi+E11ecXL93KCjx7W3DKI8sj0A3 # T8HhhUSJxAlMxdSlQy90lfdu+HggWCwTXWCVmj5PM4TasIgX3p5O9JawvEagbJjS # 4NaIjAsCAwEAAaOCAe0wggHpMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBRI # bmTlUAXTgqoXNzcitW2oynUClTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTAL # BgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRyLToCMZBD # uRQFTuHqp8cx0SOJNDBaBgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsLm1pY3Jv # c29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFf # MDNfMjIuY3JsMF4GCCsGAQUFBwEBBFIwUDBOBggrBgEFBQcwAoZCaHR0cDovL3d3 # dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFf # MDNfMjIuY3J0MIGfBgNVHSAEgZcwgZQwgZEGCSsGAQQBgjcuAzCBgzA/BggrBgEF # BQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9kb2NzL3ByaW1h # cnljcHMuaHRtMEAGCCsGAQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAHAAbwBsAGkA # YwB5AF8AcwB0AGEAdABlAG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUAA4ICAQBn # 8oalmOBUeRou09h0ZyKbC5YR4WOSmUKWfdJ5DJDBZV8uLD74w3LRbYP+vj/oCso7 # v0epo/Np22O/IjWll11lhJB9i0ZQVdgMknzSGksc8zxCi1LQsP1r4z4HLimb5j0b # pdS1HXeUOeLpZMlEPXh6I/MTfaaQdION9MsmAkYqwooQu6SpBQyb7Wj6aC6VoCo/ # KmtYSWMfCWluWpiW5IP0wI/zRive/DvQvTXvbiWu5a8n7dDd8w6vmSiXmE0OPQvy # CInWH8MyGOLwxS3OW560STkKxgrCxq2u5bLZ2xWIUUVYODJxJxp/sfQn+N4sOiBp # mLJZiWhub6e3dMNABQamASooPoI/E01mC8CzTfXhj38cbxV9Rad25UAqZaPDXVJi # hsMdYzaXht/a8/jyFqGaJ+HNpZfQ7l1jQeNbB5yHPgZ3BtEGsXUfFL5hYbXw3MYb # BL7fQccOKO7eZS/sl/ahXJbYANahRr1Z85elCUtIEJmAH9AAKcWxm6U/RXceNcbS # oqKfenoi+kiVH6v7RyOA9Z74v2u3S5fi63V4GuzqN5l5GEv/1rMjaHXmr/r8i+sL # gOppO6/8MO0ETI7f33VtY5E90Z1WTk+/gFcioXgRMiF670EKsT/7qMykXcGhiJtX # cVZOSEXAQsmbdlsKgEhr/Xmfwb1tbWrJUnMTDXpQzTGCGZ8wghmbAgEBMIGVMH4x # CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt # b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01p # Y3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTECEzMAAAOuLTVRyFOPVR0AAAAA # A64wDQYJYIZIAWUDBAIBBQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQw # HAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIAoM # CHoeSxpGnPcWOdsAyn8NmEmikIKLjknCUIEAQDkUMEIGCisGAQQBgjcCAQwxNDAy # oBSAEgBNAGkAYwByAG8AcwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5j # b20wDQYJKoZIhvcNAQEBBQAEggEAe4qL9O/RdB9+F14TpI0RSSZ2lCaYA1XZDRYh # glfh5XZU2FZn46lrb9dt7vWgEjHgzkX/SnGxeyglnTzrEfjjlCcyomIkbjUblEZa # Ibx0cJlUTQurPl4MrBlnpgyZAiGxeSDfbxk4qHQ18DrTW36rJCKoXFB4m+C2SDKO # w7e32OyHjNZ50p36V51TErdtrQur5I7zNIEnDJekfJD0zVwMr9oR8sUlI4rAPkXs # 8dKNfNnR0zw5Fm5JKpwnwjBcjQC8IjuouxC1tQ7f8OnOME65QL1S6KC95aTVWihv # w5x2Mu0q0l8zQeMfThW1+OewsUwBhPV/opIFNweIp4dCNeARo6GCFykwghclBgor # BgEEAYI3AwMBMYIXFTCCFxEGCSqGSIb3DQEHAqCCFwIwghb+AgEDMQ8wDQYJYIZI # AWUDBAIBBQAwggFZBgsqhkiG9w0BCRABBKCCAUgEggFEMIIBQAIBAQYKKwYBBAGE # WQoDATAxMA0GCWCGSAFlAwQCAQUABCAZw0jHMvpy/VEm6aufmjfXgu3A1vFXwQa2 # sf0eg6P2swIGZdZD5kbKGBMyMDI0MDMxMTE4MTgzMi4zMzJaMASAAgH0oIHYpIHV # MIHSMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH # UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQL # EyRNaWNyb3NvZnQgSXJlbGFuZCBPcGVyYXRpb25zIExpbWl0ZWQxJjAkBgNVBAsT # HVRoYWxlcyBUU1MgRVNOOkQwODItNEJGRC1FRUJBMSUwIwYDVQQDExxNaWNyb3Nv # ZnQgVGltZS1TdGFtcCBTZXJ2aWNloIIReDCCBycwggUPoAMCAQICEzMAAAHcweCM # wl9YXo4AAQAAAdwwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UEBhMCVVMxEzARBgNV # BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv # c29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAg # UENBIDIwMTAwHhcNMjMxMDEyMTkwNzA2WhcNMjUwMTEwMTkwNzA2WjCB0jELMAkG # A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx # HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEtMCsGA1UECxMkTWljcm9z # b2Z0IElyZWxhbmQgT3BlcmF0aW9ucyBMaW1pdGVkMSYwJAYDVQQLEx1UaGFsZXMg # VFNTIEVTTjpEMDgyLTRCRkQtRUVCQTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUt # U3RhbXAgU2VydmljZTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAIvI # syA1sjg9kSKJzelrUWF5ShqYWL83amn3SE5JyIVPUC7F6qTcLphhHZ9idf21f0Ra # GrU8EHydF8NxPMR2KVNiAtCGPJa8kV1CGvn3beGB2m2ltmqJanG71mAywrkKATYn # iwKLPQLJ00EkXw5TSwfmJXbdgQLFlHyfA5Kg+pUsJXzqumkIvEr0DXPvptAGqkdF # LKwo4BTlEgnvzeTfXukzX8vQtTALfVJuTUgRU7zoP/RFWt3WagahZ6UloI0FC8Xl # BQDVDX5JeMEsx7jgJDdEnK44Y8gHuEWRDq+SG9Xo0GIOjiuTWD5uv3vlEmIAyR/7 # rSFvcLnwAqMdqcy/iqQPMlDOcd0AbniP8ia1BQEUnfZT3UxyK9rLB/SRiKPyHDlg # 8oWwXyiv3+bGB6dmdM61ur6nUtfDf51lPcKhK4Vo83pOE1/niWlVnEHQV9NJ5/Db # USqW2RqTUa2O2KuvsyRGMEgjGJA12/SqrRqlvE2fiN5ZmZVtqSPWaIasx7a0GB+f # dTw+geRn6Mo2S6+/bZEwS/0IJ5gcKGinNbfyQ1xrvWXPtXzKOfjkh75iRuXourGV # PRqkmz5UYz+R5ybMJWj+mfcGqz2hXV8iZnCZDBrrnZivnErCMh5Flfg8496pT0ph # jUTH2GChHIvE4SDSk2hwWP/uHB9gEs8p/9Pe/mt9AgMBAAGjggFJMIIBRTAdBgNV # HQ4EFgQU6HPSBd0OfEX3uNWsdkSraUGe3dswHwYDVR0jBBgwFoAUn6cVXQBeYl2D # 9OXSZacbUzUZ6XIwXwYDVR0fBFgwVjBUoFKgUIZOaHR0cDovL3d3dy5taWNyb3Nv # ZnQuY29tL3BraW9wcy9jcmwvTWljcm9zb2Z0JTIwVGltZS1TdGFtcCUyMFBDQSUy # MDIwMTAoMSkuY3JsMGwGCCsGAQUFBwEBBGAwXjBcBggrBgEFBQcwAoZQaHR0cDov # L3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNyb3NvZnQlMjBUaW1l # LVN0YW1wJTIwUENBJTIwMjAxMCgxKS5jcnQwDAYDVR0TAQH/BAIwADAWBgNVHSUB # Af8EDDAKBggrBgEFBQcDCDAOBgNVHQ8BAf8EBAMCB4AwDQYJKoZIhvcNAQELBQAD # ggIBANnrb8Ewr8eX/H1sKt3rnwTDx4AqgHbkMNQo+kUGwCINXS3y1GUcdqsK/R1g # 6Tf7tNx1q0NpKk1JTupUJfHdExKtkuhHA+82lT7yISp/Y74dqJ03RCT4Q+8ooQXT # MzxiewfErVLt8WefebncST0i6ypKv87pCYkxM24bbqbM/V+M5VBppCUs7R+cETiz # /zEA1AbZL/viXtHmryA0CGd+Pt9c+adsYfm7qe5UMnS0f/YJmEEMkEqGXCzyLK+d # h+UsFi0d4lkdcE+Zq5JNjIHesX1wztGVAtvX0DYDZdN2WZ1kk+hOMblUV/L8n1YW # zhP/5XQnYl03AfXErn+1Eatylifzd3ChJ1xuGG76YbWgiRXnDvCiwDqvUJevVRY1 # qy4y4vlVKaShtbdfgPyGeeJ/YcSBONOc0DNTWbjMbL50qeIEC0lHSpL2rRYNVu3h # sHzG8n5u5CQajPwx9PzpsZIeFTNHyVF6kujI4Vo9NvO/zF8Ot44IMj4M7UX9Za4Q # wGf5B71x57OjaX53gxT4vzoHvEBXF9qCmHRgXBLbRomJfDn60alzv7dpCVQIuQ06 # 2nyIZKnsXxzuKFb0TjXWw6OFpG1bsjXpOo5DMHkysribxHor4Yz5dZjVyHANyKo0 # bSrAlVeihcaG5F74SZT8FtyHAW6IgLc5w/3D+R1obDhKZ21WMIIHcTCCBVmgAwIB # AgITMwAAABXF52ueAptJmQAAAAAAFTANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UE # BhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAc # BgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0 # IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTAwHhcNMjEwOTMwMTgyMjI1 # WhcNMzAwOTMwMTgzMjI1WjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGlu # Z3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBv # cmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDCC # AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAOThpkzntHIhC3miy9ckeb0O # 1YLT/e6cBwfSqWxOdcjKNVf2AX9sSuDivbk+F2Az/1xPx2b3lVNxWuJ+Slr+uDZn # hUYjDLWNE893MsAQGOhgfWpSg0S3po5GawcU88V29YZQ3MFEyHFcUTE3oAo4bo3t # 1w/YJlN8OWECesSq/XJprx2rrPY2vjUmZNqYO7oaezOtgFt+jBAcnVL+tuhiJdxq # D89d9P6OU8/W7IVWTe/dvI2k45GPsjksUZzpcGkNyjYtcI4xyDUoveO0hyTD4MmP # frVUj9z6BVWYbWg7mka97aSueik3rMvrg0XnRm7KMtXAhjBcTyziYrLNueKNiOSW # rAFKu75xqRdbZ2De+JKRHh09/SDPc31BmkZ1zcRfNN0Sidb9pSB9fvzZnkXftnIv # 231fgLrbqn427DZM9ituqBJR6L8FA6PRc6ZNN3SUHDSCD/AQ8rdHGO2n6Jl8P0zb # r17C89XYcz1DTsEzOUyOArxCaC4Q6oRRRuLRvWoYWmEBc8pnol7XKHYC4jMYcten # IPDC+hIK12NvDMk2ZItboKaDIV1fMHSRlJTYuVD5C4lh8zYGNRiER9vcG9H9stQc # xWv2XFJRXRLbJbqvUAV6bMURHXLvjflSxIUXk8A8FdsaN8cIFRg/eKtFtvUeh17a # j54WcmnGrnu3tz5q4i6tAgMBAAGjggHdMIIB2TASBgkrBgEEAYI3FQEEBQIDAQAB # MCMGCSsGAQQBgjcVAgQWBBQqp1L+ZMSavoKRPEY1Kc8Q/y8E7jAdBgNVHQ4EFgQU # n6cVXQBeYl2D9OXSZacbUzUZ6XIwXAYDVR0gBFUwUzBRBgwrBgEEAYI3TIN9AQEw # QTA/BggrBgEFBQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9E # b2NzL1JlcG9zaXRvcnkuaHRtMBMGA1UdJQQMMAoGCCsGAQUFBwMIMBkGCSsGAQQB # gjcUAgQMHgoAUwB1AGIAQwBBMAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/ # MB8GA1UdIwQYMBaAFNX2VsuP6KJcYmjRPZSQW9fOmhjEMFYGA1UdHwRPME0wS6BJ # oEeGRWh0dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01p # Y1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNybDBaBggrBgEFBQcBAQROMEwwSgYIKwYB # BQUHMAKGPmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMvTWljUm9v # Q2VyQXV0XzIwMTAtMDYtMjMuY3J0MA0GCSqGSIb3DQEBCwUAA4ICAQCdVX38Kq3h # LB9nATEkW+Geckv8qW/qXBS2Pk5HZHixBpOXPTEztTnXwnE2P9pkbHzQdTltuw8x # 5MKP+2zRoZQYIu7pZmc6U03dmLq2HnjYNi6cqYJWAAOwBb6J6Gngugnue99qb74p # y27YP0h1AdkY3m2CDPVtI1TkeFN1JFe53Z/zjj3G82jfZfakVqr3lbYoVSfQJL1A # oL8ZthISEV09J+BAljis9/kpicO8F7BUhUKz/AyeixmJ5/ALaoHCgRlCGVJ1ijbC # HcNhcy4sa3tuPywJeBTpkbKpW99Jo3QMvOyRgNI95ko+ZjtPu4b6MhrZlvSP9pEB # 9s7GdP32THJvEKt1MMU0sHrYUP4KWN1APMdUbZ1jdEgssU5HLcEUBHG/ZPkkvnNt # yo4JvbMBV0lUZNlz138eW0QBjloZkWsNn6Qo3GcZKCS6OEuabvshVGtqRRFHqfG3 # rsjoiV5PndLQTHa1V1QJsWkBRH58oWFsc/4Ku+xBZj1p/cvBQUl+fpO+y/g75LcV # v7TOPqUxUYS8vwLBgqJ7Fx0ViY1w/ue10CgaiQuPNtq6TPmb/wrpNPgkNWcr4A24 # 5oyZ1uEi6vAnQj0llOZ0dFtq0Z4+7X6gMTN9vMvpe784cETRkPHIqzqKOghif9lw # Y1NNje6CbaUFEMFxBmoQtB1VM1izoXBm8qGCAtQwggI9AgEBMIIBAKGB2KSB1TCB # 0jELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1Jl # ZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEtMCsGA1UECxMk # TWljcm9zb2Z0IElyZWxhbmQgT3BlcmF0aW9ucyBMaW1pdGVkMSYwJAYDVQQLEx1U # aGFsZXMgVFNTIEVTTjpEMDgyLTRCRkQtRUVCQTElMCMGA1UEAxMcTWljcm9zb2Z0 # IFRpbWUtU3RhbXAgU2VydmljZaIjCgEBMAcGBSsOAwIaAxUAHDn/cz+3yRkIUCJf # SbL3djnQEqaggYMwgYCkfjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGlu # Z3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBv # cmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDAN # BgkqhkiG9w0BAQUFAAIFAOmZJPIwIhgPMjAyNDAzMTExNDM2MzRaGA8yMDI0MDMx # MjE0MzYzNFowdDA6BgorBgEEAYRZCgQBMSwwKjAKAgUA6Zkk8gIBADAHAgEAAgIP # 5jAHAgEAAgISBTAKAgUA6Zp2cgIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEE # AYRZCgMCoAowCAIBAAIDB6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBBQUAA4GB # AEnp5IEb3Yf3GB5/uVjS4xo4JZEx2KfJ6LX11vwW4T9ViD7bWIN8NsqHuJX96IBA # D/2YNah18Midhe38BMtmYPtQNoEd+FdYxfcZN97swDTFR14W1qGOCWdftv3MsK8+ # QkthEeNbLfNnrXPsXmvCqpb2f9UCsXRvK3M1y+cAiH4GMYIEDTCCBAkCAQEwgZMw # fDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1Jl # ZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMd # TWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTACEzMAAAHcweCMwl9YXo4AAQAA # AdwwDQYJYIZIAWUDBAIBBQCgggFKMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRAB # BDAvBgkqhkiG9w0BCQQxIgQgy2kLBEXmXexuUCgX7gFKVLel/bKxpW3jswpJR4VY # nzQwgfoGCyqGSIb3DQEJEAIvMYHqMIHnMIHkMIG9BCBTpxeKatlEP4y8qZzjuWL0 # Ou0IqxELDhX2TLylxIINNzCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQI # EwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3Nv # ZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBD # QSAyMDEwAhMzAAAB3MHgjMJfWF6OAAEAAAHcMCIEIIryvC4+0V7RzAR/kEzt6v8L # CncFnPLA8Eyd0hpkqbWjMA0GCSqGSIb3DQEBCwUABIICAEl/u9tHmIM8fO6No3dD # U1580S6jmGyGpFzHQFWijt2kJyHSpnqMGirjVCZ4QjOyFpnBz8eCrSnrMD9M9qoB # EsN/Q4thJkLb/c/+HHaOKfgOpCXrgHOi475tre4HeOHcuHKPipef8ozCJfatvTi/ # Mq+iB3AiEapw0rEsVzXRxyaooYmqzy9vtSCGPpxpwWGna83sAARyz5RRLwn56s9r # g+MuYkvwNrVvh5LoO9V467SEu0RQ2ZPLMLsNFKGllIlNacMLuMaAXNTl1I5rxNDn # SUU17x4yj1SJniZ9IqL1AYJ1sSBn4XMJJstog7fT+ChAvJLIwkYstXjETeZqxUmr # iCoEZHl+k3BbLTE5/thFgQgd8kuCmYjsBppZqZsifz9NyNEVDr7jL6oxEOTRFIMj # yvOPgNZEJj9qCjpdQr3/BpN2u7n645G7zw8JRD0Z+jP5BR8O+4gWNLxE5tMzDqSl # YMk541T8uSJ5yBKG2vEfokXKsBpU83pL1t3TIFfm7E0hpKP//LgTIEffcOqRKw9j # wIXST0CsMNY5KpvyBCocBOh6IMgujtry8oRO4TkWU8wcGb144GwyEsZ5lrj8gruK # e7whDSjCqS0j6Iy1PzlYvgEBlR9oYXsM5FCOKqY0KS+K+rLdRn2AqaT8+gSj7Bxb # k05sEXhCJReP/vdTjZGEm0Rx # SIG # End signature block |