Obs/bin/GMA/GetTelemetryStatusAndEditConfigs.ps1
##------------------------------------------------------------------ ## <copyright file="GetTelemetryStatusAndEditConfigs.ps1" company="Microsoft"> ## Copyright (C) Microsoft. All rights reserved. ## </copyright> ##------------------------------------------------------------------ Param ( [Parameter(Mandatory=$true)] [System.String] $TaskName, [Parameter(Mandatory = $true)] [System.String] $GMACacheFolderPath, [Parameter(Mandatory = $true)] [System.String] $GmaPackageContentPath, [Parameter(Mandatory=$false)] [System.String] $TranscriptFolderPath = "$env:SystemDrive\Observability\ObsScheduledTaskTranscripts" ) $functionName = $MyInvocation.MyCommand.Name $transcriptFileName = "{0}.{1:yyyy-MM-dd}.log" -f $TaskName, $(Get-Date) $transcriptFilePath = Join-Path -Path $TranscriptFolderPath -ChildPath $transcriptFileName Start-Transcript -Path $transcriptFilePath -Append Import-Module (Join-Path -Path $GmaPackageContentPath -ChildPath 'GMATenantJsonHelper.psm1') ` -DisableNameChecking ` -Verbose:$false function Set-RegistryKeyLocal { Param ( [Parameter(Mandatory=$True)] [System.Collections.Hashtable] $IdParamsToUpdate ) $functionName = $MyInvocation.MyCommand.Name Write-ObservabilityGMAEventSource "[$functionName] Entering. Params: {IdParamsToUpdate = $($IdParamsToUpdate | ConvertTo-Json) }." $regPath = [Microsoft.AzureStack.Observability.ObservabilityCommon.TenantConfigGenerator.Constants]::CommonConfigRegistryPath Write-ObservabilityGMAEventSource "[$functionName] RegPath value is $regPath." foreach ($regKey in $IdParamsToUpdate.Keys) { $regValue = $IdParamsToUpdate[$regKey] if (Confirm-IsStringNotEmpty $regValue) { [Microsoft.AzureStack.Observability.ObservabilityCommon.TenantConfigGenerator.RegistryUtility]::SetRegistryKey($regPath, $regKey, $regValue) Write-ObservabilityGMAEventSource -Message "[$functionName] Successfully updated $regKey value ($regValue) in registry." } else { Write-ObservabilityGMAEventSource -Message "[$functionName] $regKey value is either null or empty. Registry value won't be updated." } } Write-ObservabilityGMAEventSource "[$functionName] Exiting." } function Set-LastWriteTimeOfFile { Param ( [Parameter(Mandatory=$True)] [System.IO.FileInfo] $FileObj ) $functionName = $MyInvocation.MyCommand.Name Write-ObservabilityGMAEventSource "[$functionName] Entering. Params: {FileObj = $($FileObj.Name)}." $FileObj.LastWriteTime = (Get-Date) Write-ObservabilityGMAEventSource -Message "[$functionName] Modified the LastWriteTime of $($FileObj.FullName) to $($FileObj.LastWriteTime)." Write-ObservabilityGMAEventSource "[$functionName] Exiting." } try { Write-ObservabilityGMAEventSource -Message "[$functionName] Entering." $jsonDropLocation = Join-Path $GMACacheFolderPath -ChildPath "JsonDropLocation" $configTypesToNotUpdateAsTheyAreStatic = @( $MiscConstants.ConfigTypes.Diagnostics, $MiscConstants.ConfigTypes.Health ) ## Set telemetry to always be enabled. $telemetryEnabled = $true try { ## Set the Proactive Log collection status to always be enabled. $diagnosticLevel = $MiscConstants.HciDiagnosticLevel.Enhanced Set-ProactiveLogCollectionStatus -DiagnosticLevel $diagnosticLevel } catch { Write-ObservabilityGMAEventSource -Message "[$functionName] Enabling Proactive log collection failed. Continuing." } $maRestarted = $false ## Keep track of which configs need to be updated $configsToBeUpdated = @{} $configFilePaths = @{} $MiscConstants.ConfigTypes.Values | ForEach-Object { $configType = $_ $jsonConfigFileName = "AEO" + $configType + ".json" $configsToBeUpdated[$configType] = $true $configFilePaths[$configType] = Join-Path $jsonDropLocation -ChildPath $jsonConfigFileName } if (Confirm-ClusterCmdletsAreAvailable) { Write-ObservabilityGMAEventSource -Message "[$functionName] As cluster cmdlets are available, evaluate whether the values are changed, if yes then update the reg keys as well as Tenant jsons." ## Fetch respective values from cluster cmdlets. $azureStackHciDetails = Get-AzureStackHCI $deviceArmResourceUri = $azureStackHciDetails.AzureResourceUri $stampId = $azureStackHciDetails.AzureResourceName $clusterName = (Get-Cluster).Name $osBuildVersion = Get-OSBuildVersion $assemblyBuild = Get-AssemblyVersion $nodeId = $StampId + "-" + (Get-ClusterNode(hostname)).Id $arcAgentResourceInfo = Get-ArcAgentResourceInfo $arcAgentVmId = Get-ArcAgentVmId -ArcAgentInfo $arcAgentResourceInfo $valuesFromClusterCmdlets = [ordered] @{ $MiscConstants.TenantJsonPropertyNames.MONITORING_AEO_DEVICE_ARM_RESOURCE_URI = $deviceArmResourceUri $MiscConstants.TenantJsonPropertyNames.MONITORING_AEO_STAMPID = $stampId $MiscConstants.TenantJsonPropertyNames.MONITORING_AEO_CLUSTER_NAME = $clusterName $MiscConstants.TenantJsonPropertyNames.MONITORING_AEO_OSBUILD = $osBuildVersion $MiscConstants.TenantJsonPropertyNames.MONITORING_AEO_ASSEMBLYBUILD = $assemblyBuild $MiscConstants.TenantJsonPropertyNames.MONITORING_AEO_NODEID = $nodeId $MiscConstants.TenantJsonPropertyNames.MONITORING_AEO_NODE_ARC_VMID = $arcAgentVmId } Write-ObservabilityGMAEventSource "[$functionName] Values from cluster cmdlets are as follows: $($valuesFromClusterCmdlets | ConvertTo-Json)" ## Check Diagnostics tenant json and evaluate whether any of the ID params have changed, if yes, then update the registry keys and all the json files. $diagTenantJsonFilePath = $configFilePaths[$MiscConstants.ConfigTypes.Diagnostics] if (-not (Test-Path -Path $diagTenantJsonFilePath)) { Set-TenantConfigJsonFile -ConfigType $MiscConstants.ConfigTypes.Diagnostics -FilePath $diagTenantJsonFilePath } $jsonFiles = Get-ChildItem $jsonDropLocation $diagTenantJsonContent = Get-ContentAsJson $diagTenantJsonFilePath $currentJsonIdParams = $diagTenantJsonContent.ConstantVariables ## Track the idParams that are to be updated. $idParamsToBeUpdated = @{} foreach ($idParam in $valuesFromClusterCmdlets.Keys) { if ($valuesFromClusterCmdlets.$idParam -ne $currentJsonIdParams.$idParam) { $idParamsToBeUpdated.Add($idParam, $valuesFromClusterCmdlets.$idParam) Write-ObservabilityGMAEventSource "[$functionName] Value for $idParam is updated, registry will be updated. Current json value = $($currentJsonIdParams.$idParam), New value = $($valuesFromClusterCmdlets.$idParam)." } else { Write-ObservabilityGMAEventSource "[$functionName] Value for $idParam hasn't changed, registry won't be updated." } } ## Update the registry keys with latest values. if ($idParamsToBeUpdated.Count -gt 0) { Set-RegistryKeyLocal -IdParamsToUpdate $idParamsToBeUpdated } else { Write-ObservabilityGMAEventSource "[$functionName] All the Id params are latest, nothing to update." } $configTypesToRemoveJsonIfTelemetryIsDisabled = @( $MiscConstants.ConfigTypes.Telemetry, $MiscConstants.ConfigTypes.Metrics ) foreach ($configType in $MiscConstants.ConfigTypes.Values) { Write-ObservabilityGMAEventSource "[$functionName] ConfigType to evaluate is $configType" $tenantJsonFilePath = $configFilePaths[$configType] ## If configType is the one whose json is to be removed based on Telemetry status and Telemetry is actually disabled, then delete the json if it exists. if ($configType -in $configTypesToRemoveJsonIfTelemetryIsDisabled -and (-not $telemetryEnabled)) { if ((Confirm-IsStringNotEmpty $tenantJsonFilePath) -and (Test-Path $tenantJsonFilePath)) { Write-ObservabilityGMAEventSource "[$functionName] Telemetry is disabled, however $configType tenant json file exists. Thus, removing the file." Remove-Item $tenantJsonFilePath -Verbose } else { Write-ObservabilityGMAEventSource "[$functionName] Tenant json for $configType does not exists already, nothing to remove." } $configsToBeUpdated[$configType] = $false } else { if (Confirm-IsStringEmpty $tenantJsonFilePath) { ## If the json for either telemetry or metrics is not present and telemetry is enabled, then generate the config. Write-ObservabilityGMAEventSource "[$functionName] Tenant json for $configType does not exists, creating config file." $tenantJsonFilePath = "$jsonDropLocation\AEO$configType.json" & "$GmaPackageContentPath\NewMultiTenantJsonForObservabilityGMA.ps1" ` -ConfigType $configType ` -TelemetryEnabled $telemetryEnabled ` -TenantJsonFilePath $tenantJsonFilePath $maRestarted = $true } else { ## Update the json, only if Id param values are changed. Don't update security as that is done on-demand. if ($idParamsToBeUpdated.Count -gt 0 -and $configType -ne $MiscConstants.ConfigTypes.Security) { Write-ObservabilityGMAEventSource "[$functionName] Updating tenant json for $configType with latest id param values at location $tenantJsonFilePath." Set-TenantConfigJsonFile -ConfigType $ConfigType -FilePath $tenantJsonFilePath $maRestarted = $true } elseif ($configType -notin $configTypesToNotUpdateAsTheyAreStatic -and (Test-Path -Path $tenantJsonFilePath)) { ## If no id params are changed, then just update the LastWriteTime so GMA downloads the latest config. Write-ObservabilityGMAEventSource "[$functionName] Tenant json for $configType already has latest id params. So just updating the LastWriteTime of the file, so GMA downloads latest config." Set-LastWriteTimeOfFile -FileObj $(Get-Item $tenantJsonFilePath) $maRestarted = $true } else { ## Do nothing Write-ObservabilityGMAEventSource "[$functionName] Tenant json for $configType already has latest id param values, so it won't be updated." } } } } } else { Write-ObservabilityGMAEventSource "[$functionName] As cluster cmdlets are not available, we will just modify the LastWriteTime of Tenant json files." ## Modify the LastWriteTime of Json files (except some), so that the latest MA configs are pulled down. foreach ($tenantJsonFile in $jsonFiles) { $isTenantJsonToBeUpdated = $True foreach ($configType in $configTypesToNotUpdateAsTheyAreStatic) { if ($tenantJsonFile.Name -match $configType) { Write-ObservabilityGMAEventSource "[$functionName] Not updating LastWriteTime of $($tenantJsonFile.FullName) as config is static." $isTenantJsonToBeUpdated = $False } } if ($isTenantJsonToBeUpdated) { Set-LastWriteTimeOfFile -FileObj $tenantJsonFile $maRestarted = $true } } } foreach ($configType in $MiscConstants.ConfigTypes.Values) { if($configsToBeUpdated[$configType]) { Sync-TenantRegKeysAndConfigFile -ConfigType $configType -FilePath $configFilePaths[$configType] } } if ($maRestarted) { Write-ObservabilityGMAEventSource "[$functionName] MA has restarted: restarting $($MiscConstants.ObsServiceDetails.DiagTrack.Name) service." try { $diagTrackService = Get-Service -Name $MiscConstants.ObsServiceDetails.DiagTrack.Name -ErrorAction SilentlyContinue if ($diagTrackService) { $diagTrackService | Restart-Service Write-ObservabilityGMAEventSource "[$functionName] Restarted $($MiscConstants.ObsServiceDetails.DiagTrack.Name) service." } else { Write-ObservabilityGMAEventSource "[$functionName] $($MiscConstants.ObsServiceDetails.DiagTrack.Name) service not found." } } catch { Write-ObservabilityGMAEventSource "[$functionName] Failed to restart $($MiscConstants.ObsServiceDetails.DiagTrack.Name) service with error $_." } } Write-ObservabilityGMAEventSource -Message "[$functionName] Exiting." } catch { $exceptionDetails = Get-ExceptionDetails -ErrorObject $_ Write-ObservabilityGMAEventSource -Message "[$functionName] $exceptionDetails" -Level "ERROR" } Stop-Transcript # SIG # Begin signature block # MIIoKQYJKoZIhvcNAQcCoIIoGjCCKBYCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCA/ZyAbvYo2ZzGI # kGHuEw37o0hO8lf+XTUwlHbiebHo/qCCDXYwggX0MIID3KADAgECAhMzAAADrzBA # DkyjTQVBAAAAAAOvMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p # bmcgUENBIDIwMTEwHhcNMjMxMTE2MTkwOTAwWhcNMjQxMTE0MTkwOTAwWjB0MQsw # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB # AQDOS8s1ra6f0YGtg0OhEaQa/t3Q+q1MEHhWJhqQVuO5amYXQpy8MDPNoJYk+FWA # hePP5LxwcSge5aen+f5Q6WNPd6EDxGzotvVpNi5ve0H97S3F7C/axDfKxyNh21MG # 0W8Sb0vxi/vorcLHOL9i+t2D6yvvDzLlEefUCbQV/zGCBjXGlYJcUj6RAzXyeNAN # xSpKXAGd7Fh+ocGHPPphcD9LQTOJgG7Y7aYztHqBLJiQQ4eAgZNU4ac6+8LnEGAL # go1ydC5BJEuJQjYKbNTy959HrKSu7LO3Ws0w8jw6pYdC1IMpdTkk2puTgY2PDNzB # tLM4evG7FYer3WX+8t1UMYNTAgMBAAGjggFzMIIBbzAfBgNVHSUEGDAWBgorBgEE # AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQURxxxNPIEPGSO8kqz+bgCAQWGXsEw # RQYDVR0RBD4wPKQ6MDgxHjAcBgNVBAsTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEW # MBQGA1UEBRMNMjMwMDEyKzUwMTgyNjAfBgNVHSMEGDAWgBRIbmTlUAXTgqoXNzci # tW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8vd3d3Lm1pY3Jvc29mdC5j # b20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3JsMGEG # CCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDovL3d3dy5taWNyb3NvZnQu # Y29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3J0 # MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIBAISxFt/zR2frTFPB45Yd # mhZpB2nNJoOoi+qlgcTlnO4QwlYN1w/vYwbDy/oFJolD5r6FMJd0RGcgEM8q9TgQ # 2OC7gQEmhweVJ7yuKJlQBH7P7Pg5RiqgV3cSonJ+OM4kFHbP3gPLiyzssSQdRuPY # 1mIWoGg9i7Y4ZC8ST7WhpSyc0pns2XsUe1XsIjaUcGu7zd7gg97eCUiLRdVklPmp # XobH9CEAWakRUGNICYN2AgjhRTC4j3KJfqMkU04R6Toyh4/Toswm1uoDcGr5laYn # TfcX3u5WnJqJLhuPe8Uj9kGAOcyo0O1mNwDa+LhFEzB6CB32+wfJMumfr6degvLT # e8x55urQLeTjimBQgS49BSUkhFN7ois3cZyNpnrMca5AZaC7pLI72vuqSsSlLalG # OcZmPHZGYJqZ0BacN274OZ80Q8B11iNokns9Od348bMb5Z4fihxaBWebl8kWEi2O # PvQImOAeq3nt7UWJBzJYLAGEpfasaA3ZQgIcEXdD+uwo6ymMzDY6UamFOfYqYWXk # ntxDGu7ngD2ugKUuccYKJJRiiz+LAUcj90BVcSHRLQop9N8zoALr/1sJuwPrVAtx # HNEgSW+AKBqIxYWM4Ev32l6agSUAezLMbq5f3d8x9qzT031jMDT+sUAoCw0M5wVt # CUQcqINPuYjbS1WgJyZIiEkBMIIHejCCBWKgAwIBAgIKYQ6Q0gAAAAAAAzANBgkq # 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 # /Xmfwb1tbWrJUnMTDXpQzTGCGgkwghoFAgEBMIGVMH4xCzAJBgNVBAYTAlVTMRMw # EQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN # aWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNp # Z25pbmcgUENBIDIwMTECEzMAAAOvMEAOTKNNBUEAAAAAA68wDQYJYIZIAWUDBAIB # BQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEO # MAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIHz9+4ag/ErAebi3ZNh7LxEU # q8nJEmdsHlciJyn8LjxnMEIGCisGAQQBgjcCAQwxNDAyoBSAEgBNAGkAYwByAG8A # cwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20wDQYJKoZIhvcNAQEB # BQAEggEAN1rVAYk0VNqBUB0GbZNMxUMXa7C9b4Clu8QGWJxKz/vRb9FSJDJF8w3n # FwlsnGOmKnbUcJFCrZFRraDkGii1U7W8EZzQvHjlHku42rXYu2lsLL8RKkEvxXtF # bPeE9sh3OhECBCEZdpVxQUGPZ0uCmYjidpIr8VMaQ1y9Un2xQeUXVYiylh7wHaqR # Cm91pCgQW2Nm/6yFJd3ZayPhW7htgXBZjpJPQzNW4tjUoMNAKMEkWPPrrwAI/GMy # Vimcdhc17ZZV8qYEPiZQN/lv41Snx+QZZ+KkrDCeRT8Dga/4XyoBcR4HGoYisIEO # 6VUKMsL8wU59zmy4x04T4X7TCw3Tb6GCF5MwghePBgorBgEEAYI3AwMBMYIXfzCC # F3sGCSqGSIb3DQEHAqCCF2wwghdoAgEDMQ8wDQYJYIZIAWUDBAIBBQAwggFRBgsq # hkiG9w0BCRABBKCCAUAEggE8MIIBOAIBAQYKKwYBBAGEWQoDATAxMA0GCWCGSAFl # AwQCAQUABCBR9WWe2K1b0dv0Wq1im/tWaOM5YK5xlAr1OKlevF9paAIGZr40Xq// # GBIyMDI0MDgyMjE5MDYzOS43NlowBIACAfSggdGkgc4wgcsxCzAJBgNVBAYTAlVT # MRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQK # ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJTAjBgNVBAsTHE1pY3Jvc29mdCBBbWVy # aWNhIE9wZXJhdGlvbnMxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVTTjpGMDAyLTA1 # RTAtRDk0NzElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZaCC # EeowggcgMIIFCKADAgECAhMzAAAB8j4y12SscJGUAAEAAAHyMA0GCSqGSIb3DQEB # CwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQH # EwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNV # BAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMB4XDTIzMTIwNjE4NDU1 # OFoXDTI1MDMwNTE4NDU1OFowgcsxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo # aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y # cG9yYXRpb24xJTAjBgNVBAsTHE1pY3Jvc29mdCBBbWVyaWNhIE9wZXJhdGlvbnMx # JzAlBgNVBAsTHm5TaGllbGQgVFNTIEVTTjpGMDAyLTA1RTAtRDk0NzElMCMGA1UE # AxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZTCCAiIwDQYJKoZIhvcNAQEB # BQADggIPADCCAgoCggIBALzl88sXCmliDHBjGRIR5i9AG2dglO0oqPYUrHMfHR+B # XpeAgiuYJaakqX0g7O858n+TqI/RGehGjkXz0B3b153MZ2VZsKPVDLHkdQc1jzK7 # 0SUk6Z2B6429MrhFbjC72IHn/PZJ4K5irJf+/zPo+m/b2HW201axJz8o8566HNIB # eqQDbrkFIVPmTKTG/MHQvGjFLqhahdYrrDHXvY1ElFhwg19cOFRG9R8PvSOKgT3a # tb86CNw4rFmR9DEuXBoVKtKcazteEyun1OxSCbCzJxMQ4F0ZWZ/UcIPtY5rPkQRx # DIhLYGlFhjCw8xsHre4eInXnyo2HVIle6gvnAYO79tlTM34HNwuP3qLELvAkZAwG # LFYf1375XxuXXRFh1cNmWWNEC9LqIXA3OtqG7gOthvtvwzu+/CEQvTEI69vtYUyy # y2xxd+R0TmD41JpymGAV9yh+1Dmo8PY81WasbfwOYcOhiGCP26o8s/u+ehd/uPr4 # tbxWifXnwPRauaTsK6a5xBOIdHJ6kRpUOecDYaSImh6H+vd9KEvoIeA+hMHuhhT9 # 3ok6dxGKgNiqpF9XbCWkpU7xv5VgcvyGfXUlEXHqnr2YvwFG1Jnp0b8YURUT59Wa # DFh8gJSumCHJCURMk8hMQFLXkixpS5bQa9eUtKh8Z/a3kMCgOS4oJsL7dV0+aVhV # AgMBAAGjggFJMIIBRTAdBgNVHQ4EFgQUlVuHACbq0DEEzlwfwGDT5jrihnkwHwYD # VR0jBBgwFoAUn6cVXQBeYl2D9OXSZacbUzUZ6XIwXwYDVR0fBFgwVjBUoFKgUIZO # aHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jcmwvTWljcm9zb2Z0JTIw # VGltZS1TdGFtcCUyMFBDQSUyMDIwMTAoMSkuY3JsMGwGCCsGAQUFBwEBBGAwXjBc # BggrBgEFBQcwAoZQaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0 # cy9NaWNyb3NvZnQlMjBUaW1lLVN0YW1wJTIwUENBJTIwMjAxMCgxKS5jcnQwDAYD # VR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDAOBgNVHQ8BAf8EBAMC # B4AwDQYJKoZIhvcNAQELBQADggIBAD1Lp47gex8HTRek6A9ptw3dBl7KKmCKVxBI # NnyDpUK/0VUfN1Kr1ekCyWNlIo1ZIKWEkTPk6jdSb+1o+ehsX7wKQB2RwtCEt2RK # F+v3WTPL28M+s6aUIDYVD2NWEVpq3ZAzffPWn4YI/m26+KsVpRbNRZUMU6mj87nM # OnOg9i1OvRwWDe5dpEtPnhRDdji49heqfrC6dm1RBEyIkzPGlSW919YZS0K+dbd4 # MGKQOSLHVcT3xVxgjPb7l91y+sdV5RqsZfLgtG3DObCmwK1SHu1HrCEKtViRvoW5 # 0F1YztNW+OLukaB+N6yCcBJoP8KEu7Hro8bBohoX7EvOTRs3GwCPS6F3pB1avpNP # f2b9I1nX9RdTuTMSh3S8BjeYifxfkDgj7397WcE2lREnpiIMpB3lhWDGy5kJa/hD # BvSZeEch70K5t9KpmO8NrB/Yjbb03cuy0MlRKvW8YUHyJDlbxkszk/BPy+2woQHA # cRibCy5aazGSKYgXkFBtLOD3DPU7qN1ZPEYbQ5S3VxdY4wlQnPIQfhZIpkc7Hnep # wC8P2HRTqMQXZ+4GO0n9AOtZtvi6u8B+u+o2f2UfuBU+mWo08Mi9DwORneW9tCxi # qXPrXt7vqBrtJjTDvX5A/XrkI93NRjfp63ZKbim+ykQryGWWrchhzJfS/z3v5f1h # 55wzU9vWMIIHcTCCBVmgAwIBAgITMwAAABXF52ueAptJmQAAAAAAFTANBgkqhkiG # 9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAO # BgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEy # MDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIw # MTAwHhcNMjEwOTMwMTgyMjI1WhcNMzAwOTMwMTgzMjI1WjB8MQswCQYDVQQGEwJV # UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UE # ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGlt # ZS1TdGFtcCBQQ0EgMjAxMDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB # AOThpkzntHIhC3miy9ckeb0O1YLT/e6cBwfSqWxOdcjKNVf2AX9sSuDivbk+F2Az # /1xPx2b3lVNxWuJ+Slr+uDZnhUYjDLWNE893MsAQGOhgfWpSg0S3po5GawcU88V2 # 9YZQ3MFEyHFcUTE3oAo4bo3t1w/YJlN8OWECesSq/XJprx2rrPY2vjUmZNqYO7oa # ezOtgFt+jBAcnVL+tuhiJdxqD89d9P6OU8/W7IVWTe/dvI2k45GPsjksUZzpcGkN # yjYtcI4xyDUoveO0hyTD4MmPfrVUj9z6BVWYbWg7mka97aSueik3rMvrg0XnRm7K # MtXAhjBcTyziYrLNueKNiOSWrAFKu75xqRdbZ2De+JKRHh09/SDPc31BmkZ1zcRf # NN0Sidb9pSB9fvzZnkXftnIv231fgLrbqn427DZM9ituqBJR6L8FA6PRc6ZNN3SU # HDSCD/AQ8rdHGO2n6Jl8P0zbr17C89XYcz1DTsEzOUyOArxCaC4Q6oRRRuLRvWoY # WmEBc8pnol7XKHYC4jMYctenIPDC+hIK12NvDMk2ZItboKaDIV1fMHSRlJTYuVD5 # C4lh8zYGNRiER9vcG9H9stQcxWv2XFJRXRLbJbqvUAV6bMURHXLvjflSxIUXk8A8 # FdsaN8cIFRg/eKtFtvUeh17aj54WcmnGrnu3tz5q4i6tAgMBAAGjggHdMIIB2TAS # BgkrBgEEAYI3FQEEBQIDAQABMCMGCSsGAQQBgjcVAgQWBBQqp1L+ZMSavoKRPEY1 # Kc8Q/y8E7jAdBgNVHQ4EFgQUn6cVXQBeYl2D9OXSZacbUzUZ6XIwXAYDVR0gBFUw # UzBRBgwrBgEEAYI3TIN9AQEwQTA/BggrBgEFBQcCARYzaHR0cDovL3d3dy5taWNy # b3NvZnQuY29tL3BraW9wcy9Eb2NzL1JlcG9zaXRvcnkuaHRtMBMGA1UdJQQMMAoG # CCsGAQUFBwMIMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1UdDwQEAwIB # hjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNX2VsuP6KJcYmjRPZSQW9fO # mhjEMFYGA1UdHwRPME0wS6BJoEeGRWh0dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9w # a2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNybDBaBggr # BgEFBQcBAQROMEwwSgYIKwYBBQUHMAKGPmh0dHA6Ly93d3cubWljcm9zb2Z0LmNv # bS9wa2kvY2VydHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3J0MA0GCSqGSIb3 # DQEBCwUAA4ICAQCdVX38Kq3hLB9nATEkW+Geckv8qW/qXBS2Pk5HZHixBpOXPTEz # tTnXwnE2P9pkbHzQdTltuw8x5MKP+2zRoZQYIu7pZmc6U03dmLq2HnjYNi6cqYJW # AAOwBb6J6Gngugnue99qb74py27YP0h1AdkY3m2CDPVtI1TkeFN1JFe53Z/zjj3G # 82jfZfakVqr3lbYoVSfQJL1AoL8ZthISEV09J+BAljis9/kpicO8F7BUhUKz/Aye # ixmJ5/ALaoHCgRlCGVJ1ijbCHcNhcy4sa3tuPywJeBTpkbKpW99Jo3QMvOyRgNI9 # 5ko+ZjtPu4b6MhrZlvSP9pEB9s7GdP32THJvEKt1MMU0sHrYUP4KWN1APMdUbZ1j # dEgssU5HLcEUBHG/ZPkkvnNtyo4JvbMBV0lUZNlz138eW0QBjloZkWsNn6Qo3GcZ # KCS6OEuabvshVGtqRRFHqfG3rsjoiV5PndLQTHa1V1QJsWkBRH58oWFsc/4Ku+xB # Zj1p/cvBQUl+fpO+y/g75LcVv7TOPqUxUYS8vwLBgqJ7Fx0ViY1w/ue10CgaiQuP # Ntq6TPmb/wrpNPgkNWcr4A245oyZ1uEi6vAnQj0llOZ0dFtq0Z4+7X6gMTN9vMvp # e784cETRkPHIqzqKOghif9lwY1NNje6CbaUFEMFxBmoQtB1VM1izoXBm8qGCA00w # ggI1AgEBMIH5oYHRpIHOMIHLMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGlu # Z3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBv # cmF0aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQgQW1lcmljYSBPcGVyYXRpb25zMScw # JQYDVQQLEx5uU2hpZWxkIFRTUyBFU046RjAwMi0wNUUwLUQ5NDcxJTAjBgNVBAMT # HE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2WiIwoBATAHBgUrDgMCGgMVAGuL # 3jdwUsfZN9AR8HTlIsgKDvgIoIGDMIGApH4wfDELMAkGA1UEBhMCVVMxEzARBgNV # BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv # c29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAg # UENBIDIwMTAwDQYJKoZIhvcNAQELBQACBQDqcey0MCIYDzIwMjQwODIyMTY1ODI4 # WhgPMjAyNDA4MjMxNjU4MjhaMHQwOgYKKwYBBAGEWQoEATEsMCowCgIFAOpx7LQC # AQAwBwIBAAICBEEwBwIBAAICE48wCgIFAOpzPjQCAQAwNgYKKwYBBAGEWQoEAjEo # MCYwDAYKKwYBBAGEWQoDAqAKMAgCAQACAwehIKEKMAgCAQACAwGGoDANBgkqhkiG # 9w0BAQsFAAOCAQEAlEnfMYaDCfOO5IbOCggt8sGE3cQHAGFgISo36xDmk5tEOLRL # 0oUqMs/yHbCIEC6C3ouT4fb1zAn8giM/AfbjI5/Wv2UwqJspz3F7MKrBcz4d8e+d # y/qLLb5NvnQj/8/WB4Cv6Jo0F4RAVUE+Rar2KDPO9UDLc7BDscDwLK61o+7i+l7i # lEn9LAYKYWpUTjOudxg7FwJtr7cWJPTQj69gJV3RYm7lghaa8Pr/2lrL9NUQyNWv # sYeX6pey/CLSpqCSY7i0ypVByecO5NelFZYBL3PrUXenAfehWI9wEMtKSJv40dqj # FUFsyMw60jdOOhNqDvEZu5WVBEdvW5JbRTdPlDGCBA0wggQJAgEBMIGTMHwxCzAJ # BgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25k # MR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jv # c29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAAB8j4y12SscJGUAAEAAAHyMA0G # CWCGSAFlAwQCAQUAoIIBSjAaBgkqhkiG9w0BCQMxDQYLKoZIhvcNAQkQAQQwLwYJ # KoZIhvcNAQkEMSIEIMwRPsk7A01q93JoAh2zRsK1dQM6AxBwGJjopVHcwu+RMIH6 # BgsqhkiG9w0BCRACLzGB6jCB5zCB5DCBvQQg+No+HS4xUlzTj5jhG7kFRRscTiy5 # nqdEdJS7RddKQ0QwgZgwgYCkfjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2Fz # aGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENv # cnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAx # MAITMwAAAfI+MtdkrHCRlAABAAAB8jAiBCAuZpEawe4a7aWAPMhUJmStvOnjJPac # 7AXTZYRyC80oFjANBgkqhkiG9w0BAQsFAASCAgBLaoJfeOZNVhauhMaXFLRKkRQ7 # DuBqSCAXgQc29BCs71991JM7KP4h+FdoXd2sisSEK/cQ/EjwglE+BdTF/CSoI6+s # brvFqIiVXPQ7kv96ualELW3XP6rQfbhuFIqf75P3Y9s6vplcQQEakpnbwD+NqtT6 # UMcEzA+ov5B0eU8L4XDeyFZkaAjTlVA+UX93/WUeZq8zJ0c67KRsMnvMhOFTrkgn # l7PeEcDoHHIe7MMGQGYpoj0nkCRJxlnSDg9SrtTyDphJ6DmNkcP4Pnp8VlwctvKw # BaaNe8fclzbk1ZviB+VAzXjgvzYx2/BAy1wnGFMqFgfDZahIxTi7hRX1LirXzEbR # K9A4jTbIx0g8s9O46/CLNpOUduLgtLBA3C1sDEZXzhMoXjE25fs2E+uU54hlj8yu # Sb+k5KyhLo9dyJT65taa+6wP0Z0pe3B3+Ovezv5l5UnEUVzRN6dTKa7IOhnRnzpG # mAAU8IhCKLst/hQfyCTyed3BASNKB2rFYN1WIO44gVujAGKRbofk3L2niSrDvwzK # v8hQc9YzbiIBVfNMKz19pbnchMobnlldgG3zPRieV/GDE2xG6N2JprvPs+FmY42C # TsH3/pXmVNLrYrWPv4h711AgPM3krzifsOo24LlN5j9xE/V8cwhOk9LaQOv3P9im # tjQkj3eFnS7IlberRA== # SIG # End signature block |