Private/Deploy-Accelerator-Helpers/New-Bootstrap.ps1
|
function New-Bootstrap { [CmdletBinding(SupportsShouldProcess = $true)] param ( [Parameter(Mandatory = $false)] [string] $iac, [Parameter(Mandatory = $false)] [PSCustomObject] $bootstrapDetails, [Parameter(Mandatory = $false)] [PSCustomObject] $validationConfig, [Parameter(Mandatory = $false)] [PSCustomObject] $inputConfig, [Parameter(Mandatory = $false)] [string] $bootstrapTargetPath, [Parameter(Mandatory = $false)] [switch] $hasStarter, [Parameter(Mandatory = $false)] [string] $starterTargetPath, [Parameter(Mandatory = $false)] [PSCustomObject] $starterConfig = $null, [Parameter(Mandatory = $false)] [string] $bootstrapRelease, [Parameter(Mandatory = $false)] [string] $starterRelease, [Parameter(Mandatory = $false)] [switch] $autoApprove, [Parameter(Mandatory = $false)] [switch] $destroy, [Parameter(Mandatory = $false)] [PSCustomObject] $zonesSupport = $null, [Parameter(Mandatory = $false, HelpMessage = "An extra level of logging that is turned off by default for easier debugging.")] [switch] $writeVerboseLogs, [Parameter(Mandatory = $false)] [string] $hclParserToolPath, [Parameter(Mandatory = $false)] [switch] $convertTfvarsToJson, [Parameter(Mandatory = $false)] [string[]] $inputConfigFilePaths = @(), [Parameter(Mandatory = $false)] [string[]] $starterAdditionalFiles = @() ) if ($PSCmdlet.ShouldProcess("ALZ-Terraform module configuration", "modify")) { $bootstrapPath = Join-Path $bootstrapTargetPath $bootstrapRelease $starterPath = Join-Path $starterTargetPath $starterRelease $bootstrapModulePath = Join-Path -Path $bootstrapPath -ChildPath $bootstrapDetails.Value.location Write-Verbose "Bootstrap Module Path: $bootstrapModulePath" # Run upgrade Invoke-FullUpgrade ` -bootstrapModuleFolder $bootstrapDetails.Value.location ` -bootstrapRelease $bootstrapRelease ` -bootstrapPath $bootstrapTargetPath ` -autoApprove:$autoApprove.IsPresent # Get starter module $starterModulePath = "" $starterRootModuleFolder = "" $starterRootModuleFolderPath = "" $starterFoldersToRetain = @() if($hasStarter) { if($inputConfig.starter_module_name.Value -eq "") { $inputConfig.starter_module_name = @{ Value = Request-SpecialInput -type "starter" -starterConfig $starterConfig Source = "user" } } $chosenStarterConfig = $starterConfig.starter_modules.Value.$($inputConfig.starter_module_name.Value) Write-Verbose "Selected Starter: $($inputConfig.starter_module_name.Value))" $starterModulePath = (Resolve-Path (Join-Path -Path $starterPath -ChildPath $chosenStarterConfig.location)).Path $starterRootModuleFolderPath = $starterModulePath Write-Verbose "Starter Module Path: $starterModulePath" if($chosenStarterConfig.PSObject.Properties.Name -contains "additional_retained_folders") { $starterFoldersToRetain = $chosenStarterConfig.additional_retained_folders Write-Verbose "Starter Additional folders to retain: $($starterFoldersToRetain -join ",")" } if($chosenStarterConfig.PSObject.Properties.Name -contains "root_module_folder") { $starterRootModuleFolder = $chosenStarterConfig.root_module_folder # Retain the root module folder $starterFoldersToRetain += $starterRootModuleFolder # Add the root module folder to bootstrap input config $inputConfig | Add-Member -NotePropertyName "root_module_folder_relative_path" -NotePropertyValue @{ Value = $starterRootModuleFolder Source = "caluated" } # Set the starter root module folder full path $starterRootModuleFolderPath = Join-Path -Path $starterModulePath -ChildPath $starterRootModuleFolder Write-Verbose "Starter root module folder: $starterRootModuleFolder" Write-Verbose "Starter final folders to retain: $($starterFoldersToRetain -join ",")" } } # Getting configuration for the bootstrap module user input $bootstrapParameters = [PSCustomObject]@{} Write-Verbose "Getting the bootstrap configuration..." $terraformFiles = Get-ChildItem -Path $bootstrapModulePath -Filter "*.tf" -File foreach($terraformFile in $terraformFiles) { $bootstrapParameters = Convert-HCLVariablesToInputConfig -targetVariableFile $terraformFile.FullName -hclParserToolPath $hclParserToolPath -validators $validationConfig -appendToObject $bootstrapParameters } # Getting the configuration for the starter module user input $starterParameters = [PSCustomObject]@{} if($hasStarter) { Write-Verbose "Getting the starter configuration..." if($iac -eq "terraform") { $terraformFiles = Get-ChildItem -Path $starterRootModuleFolderPath -Filter "*.tf" -File foreach($terraformFile in $terraformFiles) { $starterParameters = Convert-HCLVariablesToInputConfig -targetVariableFile $terraformFile.FullName -hclParserToolPath $hclParserToolPath -validators $validationConfig -appendToObject $starterParameters } } if($iac -eq "bicep") { $starterParameters = Convert-BicepConfigToInputConfig -bicepConfig $starterConfig.starter_modules.Value.$($inputConfig.starter_module_name.Value) -validators $validationConfig } } # Set computed inputs $inputConfig | Add-Member -NotePropertyName "module_folder_path" -NotePropertyValue @{ Value = $starterModulePath Source = "calculated" } $inputConfig | Add-Member -NotePropertyName "availability_zones_bootstrap" -NotePropertyValue @{ Value = @(Get-AvailabilityZonesSupport -region $inputConfig.bootstrap_location.Value -zonesSupport $zonesSupport) Source = "calculated" } if($inputConfig.PSObject.Properties.Name -contains "starter_location" -and $inputConfig.PSObject.Properties.Name -notcontains "starter_locations") { Write-Verbose "Converting starter_location $($inputConfig.starter_location.Value) to starter_locations..." $inputConfig | Add-Member -NotePropertyName "starter_locations" -NotePropertyValue @{ Value = @($inputConfig.starter_location.Value) Source = "calculated" } } if($inputConfig.PSObject.Properties.Name -contains "starter_locations") { $availabilityZonesStarter = @() foreach($region in $inputConfig.starter_locations.Value) { $availabilityZonesStarter += , @(Get-AvailabilityZonesSupport -region $region -zonesSupport $zonesSupport) } $inputConfig | Add-Member -NotePropertyName "availability_zones_starter" -NotePropertyValue @{ Value = $availabilityZonesStarter Source = "calculated" } } Write-Verbose "Final Input config: $(ConvertTo-Json $inputConfig -Depth 100)" # Getting the input for the bootstrap module Write-Verbose "Setting the configuration for the bootstrap module..." $bootstrapConfiguration = Set-Config ` -configurationParameters $bootstrapParameters ` -inputConfig $inputConfig # Getting the input for the starter module Write-Verbose "Setting the configuration for the starter module..." $starterConfiguration = Set-Config ` -configurationParameters $starterParameters ` -inputConfig $inputConfig ` -copyEnvVarToConfig Write-Verbose "Final Starter Parameters: $(ConvertTo-Json $starterParameters -Depth 100)" # Creating the tfvars files for the bootstrap and starter module $tfVarsFileName = "terraform.tfvars.json" $bootstrapTfvarsPath = Join-Path -Path $bootstrapModulePath -ChildPath $tfVarsFileName $starterTfvarsPath = Join-Path -Path $starterRootModuleFolderPath -ChildPath "terraform.tfvars.json" $starterBicepVarsPath = Join-Path -Path $starterModulePath -ChildPath "parameters.json" # Write the tfvars file for the bootstrap and starter module Write-TfvarsJsonFile -tfvarsFilePath $bootstrapTfvarsPath -configuration $bootstrapConfiguration if($iac -eq "terraform") { if($starterFoldersToRetain.Length -gt 0) { Write-Verbose "Removing unwanted folders from the starter module..." $folders = Get-ChildItem -Path $starterModulePath -Directory foreach($folder in $folders) { if($starterFoldersToRetain -notcontains $folder.Name) { Write-Verbose "Removing folder: $($folder.FullName)" Remove-Item -Path $folder.FullName -Recurse -Force } else { Write-Verbose "Retaining folder: $($folder.FullName)" Remove-TerraformMetaFileSet -path $folder.FullName -writeVerboseLogs:$writeVerboseLogs.IsPresent } } } Remove-TerraformMetaFileSet -path $starterModulePath -writeVerboseLogs:$writeVerboseLogs.IsPresent if($convertTfvarsToJson) { Write-TfvarsJsonFile -tfvarsFilePath $starterTfvarsPath -configuration $starterConfiguration } else { $inputsFromTfvars = $inputConfig.PSObject.Properties | Where-Object { $_.Value.Source -eq ".tfvars" } | Select-Object -ExpandProperty Name Write-TfvarsJsonFile -tfvarsFilePath $starterTfvarsPath -configuration $starterConfiguration -skipItems $inputsFromTfvars foreach($inputConfigFilePath in $inputConfigFilePaths | Where-Object { $_ -like "*.tfvars" }) { $fileName = [System.IO.Path]::GetFileName($inputConfigFilePath) $fileName = $fileName.Replace(".tfvars", ".auto.tfvars") $destination = Join-Path -Path $starterRootModuleFolderPath -ChildPath $fileName Write-Verbose "Copying tfvars file $inputConfigFilePath to $destination" Copy-Item -Path $inputConfigFilePath -Destination $destination -Force } } # Copy additional files foreach($additionalFile in $starterAdditionalFiles) { if(Test-Path $additionalFile -PathType Container) { $folderName = ([System.IO.DirectoryInfo]::new($additionalFile)).Name $destination = Join-Path -Path $starterRootModuleFolderPath -ChildPath $folderName Write-Verbose "Copying folder $additionalFile to $destination" Copy-Item -Path "$additionalFile/*" -Destination $destination -Recurse -Force } else { $fileName = [System.IO.Path]::GetFileName($additionalFile) $destination = Join-Path -Path $starterRootModuleFolderPath -ChildPath $fileName Write-Verbose "Copying file $additionalFile to $destination" Copy-Item -Path $additionalFile -Destination $destination -Force } } } if($iac -eq "bicep") { Copy-ParametersFileCollection -starterPath $starterModulePath -configFiles $starterConfig.starter_modules.Value.$($inputConfig.starter_module_name.Value).deployment_files Set-ComputedConfiguration -configuration $starterConfiguration Edit-ALZConfigurationFilesInPlace -alzEnvironmentDestination $starterModulePath -configuration $starterConfiguration Write-JsonFile -jsonFilePath $starterBicepVarsPath -configuration $starterConfiguration # Remove unrequired files $foldersOrFilesToRetain = $starterConfig.starter_modules.Value.$($inputConfig.starter_module_name.Value).folders_or_files_to_retain $foldersOrFilesToRetain += "parameters.json" $foldersOrFilesToRetain += "config" $foldersOrFilesToRetain += "starter-cache.json" foreach($deployment_file in $starterConfig.starter_modules.Value.$($inputConfig.starter_module_name.Value).deployment_files) { $foldersOrFilesToRetain += $deployment_file.templateParametersSourceFilePath } $subFoldersOrFilesToRemove = $starterConfig.starter_modules.Value.$($inputConfig.starter_module_name.Value).subfolders_or_files_to_remove Remove-UnrequiredFileSet -path $starterModulePath -foldersOrFilesToRetain $foldersOrFilesToRetain -subFoldersOrFilesToRemove $subFoldersOrFilesToRemove -writeVerboseLogs:$writeVerboseLogs.IsPresent } # Running terraform init and apply Write-InformationColored "Thank you for providing those inputs, we are now initializing and applying Terraform to bootstrap your environment..." -ForegroundColor Green -NewLineBefore -InformationAction Continue if($autoApprove) { Invoke-Terraform -moduleFolderPath $bootstrapModulePath -autoApprove -destroy:$destroy.IsPresent } else { Write-InformationColored "Once the plan is complete you will be prompted to confirm the apply." -ForegroundColor Green -NewLineBefore -InformationAction Continue Invoke-Terraform -moduleFolderPath $bootstrapModulePath -destroy:$destroy.IsPresent } Write-InformationColored "Bootstrap has completed successfully! Thanks for using our tool. Head over to Phase 3 in the documentation to continue..." -ForegroundColor Green -NewLineBefore -InformationAction Continue } } # SIG # Begin signature block # MIIoLwYJKoZIhvcNAQcCoIIoIDCCKBwCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCD1fc+JByEEmL7O # 3FWAz7MkFDraL56kxvdgmRe5lGsbgKCCDXYwggX0MIID3KADAgECAhMzAAAEhV6Z # 7A5ZL83XAAAAAASFMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p # bmcgUENBIDIwMTEwHhcNMjUwNjE5MTgyMTM3WhcNMjYwNjE3MTgyMTM3WjB0MQsw # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB # AQDASkh1cpvuUqfbqxele7LCSHEamVNBfFE4uY1FkGsAdUF/vnjpE1dnAD9vMOqy # 5ZO49ILhP4jiP/P2Pn9ao+5TDtKmcQ+pZdzbG7t43yRXJC3nXvTGQroodPi9USQi # 9rI+0gwuXRKBII7L+k3kMkKLmFrsWUjzgXVCLYa6ZH7BCALAcJWZTwWPoiT4HpqQ # hJcYLB7pfetAVCeBEVZD8itKQ6QA5/LQR+9X6dlSj4Vxta4JnpxvgSrkjXCz+tlJ # 67ABZ551lw23RWU1uyfgCfEFhBfiyPR2WSjskPl9ap6qrf8fNQ1sGYun2p4JdXxe # UAKf1hVa/3TQXjvPTiRXCnJPAgMBAAGjggFzMIIBbzAfBgNVHSUEGDAWBgorBgEE # AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUuCZyGiCuLYE0aU7j5TFqY05kko0w # RQYDVR0RBD4wPKQ6MDgxHjAcBgNVBAsTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEW # MBQGA1UEBRMNMjMwMDEyKzUwNTM1OTAfBgNVHSMEGDAWgBRIbmTlUAXTgqoXNzci # tW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8vd3d3Lm1pY3Jvc29mdC5j # b20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3JsMGEG # CCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDovL3d3dy5taWNyb3NvZnQu # Y29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3J0 # MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIBACjmqAp2Ci4sTHZci+qk # tEAKsFk5HNVGKyWR2rFGXsd7cggZ04H5U4SV0fAL6fOE9dLvt4I7HBHLhpGdE5Uj # Ly4NxLTG2bDAkeAVmxmd2uKWVGKym1aarDxXfv3GCN4mRX+Pn4c+py3S/6Kkt5eS # DAIIsrzKw3Kh2SW1hCwXX/k1v4b+NH1Fjl+i/xPJspXCFuZB4aC5FLT5fgbRKqns # WeAdn8DsrYQhT3QXLt6Nv3/dMzv7G/Cdpbdcoul8FYl+t3dmXM+SIClC3l2ae0wO # lNrQ42yQEycuPU5OoqLT85jsZ7+4CaScfFINlO7l7Y7r/xauqHbSPQ1r3oIC+e71 # 5s2G3ClZa3y99aYx2lnXYe1srcrIx8NAXTViiypXVn9ZGmEkfNcfDiqGQwkml5z9 # nm3pWiBZ69adaBBbAFEjyJG4y0a76bel/4sDCVvaZzLM3TFbxVO9BQrjZRtbJZbk # C3XArpLqZSfx53SuYdddxPX8pvcqFuEu8wcUeD05t9xNbJ4TtdAECJlEi0vvBxlm # M5tzFXy2qZeqPMXHSQYqPgZ9jvScZ6NwznFD0+33kbzyhOSz/WuGbAu4cHZG8gKn # lQVT4uA2Diex9DMs2WHiokNknYlLoUeWXW1QrJLpqO82TLyKTbBM/oZHAdIc0kzo # STro9b3+vjn2809D0+SOOCVZMIIHejCCBWKgAwIBAgIKYQ6Q0gAAAAAAAzANBgkq # 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 # /Xmfwb1tbWrJUnMTDXpQzTGCGg8wghoLAgEBMIGVMH4xCzAJBgNVBAYTAlVTMRMw # EQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN # aWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNp # Z25pbmcgUENBIDIwMTECEzMAAASFXpnsDlkvzdcAAAAABIUwDQYJYIZIAWUDBAIB # BQCggbAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEO # MAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIFE7NcsF57ghH5V/Q8+Jx3yY # V0rWgtdhx0rnrHVtdb6MMEQGCisGAQQBgjcCAQwxNjA0oBSAEgBNAGkAYwByAG8A # cwBvAGYAdKEcgBpodHRwczovL3d3dy5taWNyb3NvZnQuY29tIDANBgkqhkiG9w0B # AQEFAASCAQCtQIGA4bfOieBQYppPWj8Y1hdcOee1uoDebwjAxg1t2blR118bEejC # M1FJnBBYF7gcUhoC8UB5xz3V4x4aVoP7BRJVfMkAaOj6/nNhf5rsVUzqyoXcQ2YV # 3OdtC61LkFzyhu6ct56rOPhGX3QVE9Zz/33+kBUwGoo6c7mEy5qLHxXupEIwyWSu # KH411rS77DW5NWAazKC235lcrWHHKZTgWScYjsQNgrF3G+ZmYNPrODdMJIZ/GB39 # +eyQKYp6mLwtexXmvKnhvRe1UVcol+4NJaYUPRvo/XiuXW4JX8+n6aRIrHb6+Jkn # WyW9sKBGY3hihLRfC73sCeuIPyTH6o5ToYIXlzCCF5MGCisGAQQBgjcDAwExgheD # MIIXfwYJKoZIhvcNAQcCoIIXcDCCF2wCAQMxDzANBglghkgBZQMEAgEFADCCAVIG # CyqGSIb3DQEJEAEEoIIBQQSCAT0wggE5AgEBBgorBgEEAYRZCgMBMDEwDQYJYIZI # AWUDBAIBBQAEIKd2I88KOXp9TcW0DDFTGbi6tCdl5FZhvVb6rxGoJwTjAgZpFjII # 85wYEzIwMjUxMTE2MTMyNDQyLjkwMlowBIACAfSggdGkgc4wgcsxCzAJBgNVBAYT # AlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYD # VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJTAjBgNVBAsTHE1pY3Jvc29mdCBB # bWVyaWNhIE9wZXJhdGlvbnMxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVTTjo3RjAw # LTA1RTAtRDk0NzElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vydmlj # ZaCCEe0wggcgMIIFCKADAgECAhMzAAACBte8UTiYI+wsAAEAAAIGMA0GCSqGSIb3 # DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYD # VQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAk # BgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMB4XDTI1MDEzMDE5 # NDI1MFoXDTI2MDQyMjE5NDI1MFowgcsxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpX # YXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQg # Q29ycG9yYXRpb24xJTAjBgNVBAsTHE1pY3Jvc29mdCBBbWVyaWNhIE9wZXJhdGlv # bnMxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVTTjo3RjAwLTA1RTAtRDk0NzElMCMG # A1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZTCCAiIwDQYJKoZIhvcN # AQEBBQADggIPADCCAgoCggIBAOlEhZsgzdGWvf3tyMdpjHzmXsj5lVYYwIEIz3XU # GlTr4gZYKqSyqCp59kUSMrM1UNgL1hyAhMDPbvo0aC8QKbhl82/8U/BxpIPPvFsN # uw6jFvBCgdQ1Guj7Hm5tmFPpYl5T3sXTr68OMDD9i3W9Y6BFOqY/902v2iohsTmg # Ith0ffAj+ehiawlVzv3rqf4HtQAYBZTax7cvP7F3Gc2w1fgJHrMgxUlNJ7M//ZJM # 1zElO72TayXv+/M6HEmEJDfyt1oSiqEYeteuZWQSFK/5LTQMwlzU4hfGp9vA+Myo # RWnsreSZzMKRu6bUE4gnbC4MBsq4l6Wm141mP9Lnw1JDDqSF+4kCW6ocreKCRL86 # 7Hj2pM/6tT49B424P4a2sKikW5xGZqdC/EhIY2jGcGrdR4NOqmGbpojsYwe0UPoM # 6MmWWUfWBVZc9PKK9/7i03xOY7rIiAHi4/TRsf2Of93LLFKPE9Daca9m2C2qe+re # HdNGNGeRz57VcHW5q0NrXNRxLuveKh1OnIBN7aGCRVfebgOFHMjoDhInp9skz2Kw # sfwAYpzKaKwrNi6kB4VJMnXQkQVroyMdBhiiGgIXvtHQILAw2O8Thd8se76oo9jw # ZB+xl2KBD1yVQCLJ0WZW3rWHK2jFk/suZdvOMPRV5zLNmgvgSq7VezMGy6UCvkt3 # YrBzAgMBAAGjggFJMIIBRTAdBgNVHQ4EFgQU7TCwsp0MalP3tzHcjKbKj9IGbhIw # HwYDVR0jBBgwFoAUn6cVXQBeYl2D9OXSZacbUzUZ6XIwXwYDVR0fBFgwVjBUoFKg # UIZOaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jcmwvTWljcm9zb2Z0 # JTIwVGltZS1TdGFtcCUyMFBDQSUyMDIwMTAoMSkuY3JsMGwGCCsGAQUFBwEBBGAw # XjBcBggrBgEFBQcwAoZQaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9j # ZXJ0cy9NaWNyb3NvZnQlMjBUaW1lLVN0YW1wJTIwUENBJTIwMjAxMCgxKS5jcnQw # DAYDVR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDAOBgNVHQ8BAf8E # BAMCB4AwDQYJKoZIhvcNAQELBQADggIBAHbcZk5971OFNS8Pb2Li3qUOnEmGlVEy # Z75RvJmEEUJmGgZO2MN2mEACtTZDrVZiDdhVyXZF0mbk9RtnZsDvvOT6q0vEL7d0 # 3FWxNx23E8NJJaDAEfFOPqkKagM1eiUBixam8dAUIcOoR8CIHFfV2ZpduJM/V3Rd # 9++BHp2yFRypof+YV+MNkDEtTWzodxWAK8FAmUnvEQbmMUp22pqkpZxtQfBNWpdA # ZsiUdUKU0nfKpbpndQkf8IVxiItX97ry6tOYa2JnEZJhvhIFI8CtOtNh4c6VAiP/ # uWhVaZ9ZfbLgAZX8P4zPJkzK8XDhXIvRWCr3oTNArK16JV4FpUSPFAqjcBw9QtEX # hTPP3w/a0IzldsVndCiP08uDeuAVevSgkSF+Ha2pSuFMl3Xf6Lj996T3NaJyiyGX # BeAW7TTZlYFXMBIQW6oQPjyrK6Vn/aMYkFy1r4V2TaWg/YrehKPg9BB7UzPNVk7n # YBc7jYweWGbdIejf9GFD4jUDQ3L724B6GRAfouvGStU29kbh/Q8AoxupRxcbvHOc # onTHQdivlrJYZscplFw5tT7/fhmkv02tc551UNeZJ3bKUpKX+++LVDA0mpcmX/6A # mRAR62qYcBQVCQW16aLwxRdAbbD9EMddfBYCMT6ogNktD+TjPZnbXq1ZpHpEMoca # TB4KgO1C3OQdMIIHcTCCBVmgAwIBAgITMwAAABXF52ueAptJmQAAAAAAFTANBgkq # hkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x # EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv # bjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 # IDIwMTAwHhcNMjEwOTMwMTgyMjI1WhcNMzAwOTMwMTgzMjI1WjB8MQswCQYDVQQG # EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG # A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQg # VGltZS1TdGFtcCBQQ0EgMjAxMDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC # ggIBAOThpkzntHIhC3miy9ckeb0O1YLT/e6cBwfSqWxOdcjKNVf2AX9sSuDivbk+ # F2Az/1xPx2b3lVNxWuJ+Slr+uDZnhUYjDLWNE893MsAQGOhgfWpSg0S3po5GawcU # 88V29YZQ3MFEyHFcUTE3oAo4bo3t1w/YJlN8OWECesSq/XJprx2rrPY2vjUmZNqY # O7oaezOtgFt+jBAcnVL+tuhiJdxqD89d9P6OU8/W7IVWTe/dvI2k45GPsjksUZzp # cGkNyjYtcI4xyDUoveO0hyTD4MmPfrVUj9z6BVWYbWg7mka97aSueik3rMvrg0Xn # Rm7KMtXAhjBcTyziYrLNueKNiOSWrAFKu75xqRdbZ2De+JKRHh09/SDPc31BmkZ1 # zcRfNN0Sidb9pSB9fvzZnkXftnIv231fgLrbqn427DZM9ituqBJR6L8FA6PRc6ZN # N3SUHDSCD/AQ8rdHGO2n6Jl8P0zbr17C89XYcz1DTsEzOUyOArxCaC4Q6oRRRuLR # vWoYWmEBc8pnol7XKHYC4jMYctenIPDC+hIK12NvDMk2ZItboKaDIV1fMHSRlJTY # uVD5C4lh8zYGNRiER9vcG9H9stQcxWv2XFJRXRLbJbqvUAV6bMURHXLvjflSxIUX # k8A8FdsaN8cIFRg/eKtFtvUeh17aj54WcmnGrnu3tz5q4i6tAgMBAAGjggHdMIIB # 2TASBgkrBgEEAYI3FQEEBQIDAQABMCMGCSsGAQQBgjcVAgQWBBQqp1L+ZMSavoKR # PEY1Kc8Q/y8E7jAdBgNVHQ4EFgQUn6cVXQBeYl2D9OXSZacbUzUZ6XIwXAYDVR0g # BFUwUzBRBgwrBgEEAYI3TIN9AQEwQTA/BggrBgEFBQcCARYzaHR0cDovL3d3dy5t # aWNyb3NvZnQuY29tL3BraW9wcy9Eb2NzL1JlcG9zaXRvcnkuaHRtMBMGA1UdJQQM # MAoGCCsGAQUFBwMIMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1UdDwQE # AwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNX2VsuP6KJcYmjRPZSQ # W9fOmhjEMFYGA1UdHwRPME0wS6BJoEeGRWh0dHA6Ly9jcmwubWljcm9zb2Z0LmNv # bS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNybDBa # BggrBgEFBQcBAQROMEwwSgYIKwYBBQUHMAKGPmh0dHA6Ly93d3cubWljcm9zb2Z0 # LmNvbS9wa2kvY2VydHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3J0MA0GCSqG # SIb3DQEBCwUAA4ICAQCdVX38Kq3hLB9nATEkW+Geckv8qW/qXBS2Pk5HZHixBpOX # PTEztTnXwnE2P9pkbHzQdTltuw8x5MKP+2zRoZQYIu7pZmc6U03dmLq2HnjYNi6c # qYJWAAOwBb6J6Gngugnue99qb74py27YP0h1AdkY3m2CDPVtI1TkeFN1JFe53Z/z # jj3G82jfZfakVqr3lbYoVSfQJL1AoL8ZthISEV09J+BAljis9/kpicO8F7BUhUKz # /AyeixmJ5/ALaoHCgRlCGVJ1ijbCHcNhcy4sa3tuPywJeBTpkbKpW99Jo3QMvOyR # gNI95ko+ZjtPu4b6MhrZlvSP9pEB9s7GdP32THJvEKt1MMU0sHrYUP4KWN1APMdU # bZ1jdEgssU5HLcEUBHG/ZPkkvnNtyo4JvbMBV0lUZNlz138eW0QBjloZkWsNn6Qo # 3GcZKCS6OEuabvshVGtqRRFHqfG3rsjoiV5PndLQTHa1V1QJsWkBRH58oWFsc/4K # u+xBZj1p/cvBQUl+fpO+y/g75LcVv7TOPqUxUYS8vwLBgqJ7Fx0ViY1w/ue10Cga # iQuPNtq6TPmb/wrpNPgkNWcr4A245oyZ1uEi6vAnQj0llOZ0dFtq0Z4+7X6gMTN9 # vMvpe784cETRkPHIqzqKOghif9lwY1NNje6CbaUFEMFxBmoQtB1VM1izoXBm8qGC # A1AwggI4AgEBMIH5oYHRpIHOMIHLMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2Fz # aGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENv # cnBvcmF0aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQgQW1lcmljYSBPcGVyYXRpb25z # MScwJQYDVQQLEx5uU2hpZWxkIFRTUyBFU046N0YwMC0wNUUwLUQ5NDcxJTAjBgNV # BAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2WiIwoBATAHBgUrDgMCGgMV # AARrR/XXxccz9U12ooGzhBfE2c33oIGDMIGApH4wfDELMAkGA1UEBhMCVVMxEzAR # BgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1p # Y3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3Rh # bXAgUENBIDIwMTAwDQYJKoZIhvcNAQELBQACBQDsw/v2MCIYDzIwMjUxMTE2MDcy # OTU4WhgPMjAyNTExMTcwNzI5NThaMHcwPQYKKwYBBAGEWQoEATEvMC0wCgIFAOzD # +/YCAQAwCgIBAAICC0ACAf8wBwIBAAICE28wCgIFAOzFTXYCAQAwNgYKKwYBBAGE # WQoEAjEoMCYwDAYKKwYBBAGEWQoDAqAKMAgCAQACAwehIKEKMAgCAQACAwGGoDAN # BgkqhkiG9w0BAQsFAAOCAQEAlzUbyGyOX3cn+GaTugEqoiPTfqngsVZaEAWsojUm # Hl4bDhSYFkhsY7dk61+5KQacjgmuIe1u8rUR9ZGbjthcqarCMNU2SU9fOJ7h/1h4 # x6W6Ih9wBvkqFygrXAsJEhqe++Mi1A3rFUQq+FfCEWMFJT1cU2MG3Ddrk9GeHEZk # QUpTtD5yqmso97Qs6kjwa2PFmNMG4pGZIkuKGBtMqudAsmRTbg8Vzhp30/pAZ6+4 # jWDfXE0lpkvIz6qFDlhuUFR7Ws0k3dNwVh2yp0kCxcxCu8PoRcOxyqPL7vybZpmA # X0SMgve/mbcl4+GyCho22AB5TKQVD0pIaEYPDrJDD4p0fTGCBA0wggQJAgEBMIGT # MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS # ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMT # HU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAACBte8UTiYI+wsAAEA # AAIGMA0GCWCGSAFlAwQCAQUAoIIBSjAaBgkqhkiG9w0BCQMxDQYLKoZIhvcNAQkQ # AQQwLwYJKoZIhvcNAQkEMSIEICuhmU9DelU9G0fqh3rksbuDpAifo9Q3wBVMFYQl # f1F0MIH6BgsqhkiG9w0BCRACLzGB6jCB5zCB5DCBvQQg4Oj1lIiRnp1W0pP4T+5n # HZYDLsqJczlHUkg6E0l/S9IwgZgwgYCkfjB8MQswCQYDVQQGEwJVUzETMBEGA1UE # CBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9z # b2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQ # Q0EgMjAxMAITMwAAAgbXvFE4mCPsLAABAAACBjAiBCAccQaUCm9p/AKr7Eo5d+lL # VUgoXfIMbfh7mdDncs9h/jANBgkqhkiG9w0BAQsFAASCAgBGbwDXJdEjCcTzv6pi # NdQ4ZrKKgKXa0K41F6DT8gCBBvUOFL7ymfK3IQ3wRVEP35r/GVdj4iTg8WXxOUCl # 3Citr4QHOhuD1xu6JbdIkfKsga/7tVMuepxai8xgBNdB7FERxjyfDzY+yVPIsV7U # SoqQfdRL705KKR7jkszZDYX4Y4fFrEXZfWNITbKzB4S4/LGWAi1BZ2b7hPrXGYf9 # Z+t+0mKbN/LtV04mDyllW8PqOqFB7HRc3DO16sa9v+TEz5x2cfGpSvRpWRXg0/8k # ZZKCkvYpyfaJfmhxfBcVXYlkyK/zeMeWe28edsEdyLe21dk8nZWRxOyC9Edpxzvb # oTWiBsI3fyhrg7E38eDmXPxo63VkX+y9rhQaCKovaoC+40BWkRtSFGclnpev892C # qZmwIW/o3jfkvzG8hilsKGarecBp4eXxriGMHJzNBqIUQt0GOabq1kCGkcHLV8Pg # +pFgA/eGXy5xEqPl5G+aBS4m2ibrSBwyOm+1/nETAGQ9qMVMeUrUXVUGr3luB1xq # OWERlatyxq3kX1QpV4p2Az6QbEcG8tQxIv3xs/EMIrikZSV6PD/zhLlS55eSGHg8 # wgaZySvLgLW/ljV1pCxxCODvs0qDbG87PP4gxlH/z3/s3LcPoq5DgXUXtfpptaxK # rC9hf3WpvQ9RXlRMdueqNVDLag== # SIG # End signature block |