policies/Get-SvtPolicy.ps1
# # (c) Copyright 2020 Hewlett Packard Enterprise Development LP # <# .SYNOPSIS Obtains details for HPE SimpliVity backup policies from the Management Virtual Appliance (MVA). .DESCRIPTION Obtains details for HPE SimpliVity backup policies from the MVA. You can obtain details from: - The entire HPE SimpliVity environment. - A set of HPE SimpliVity clusters (specified with names or IDs). - A set of backup policies (specified with names or IDs). By default, details for a maximum of 500 HPE SimpliVity backup policies are displayed. If necessary, use the Nolimit parameter to display all policies. Use of the Nolimit parameter can take a significant amount of time. Rest URL :- https://<Hostname/IP>/api/policies .PARAMETER HostOAuthToken Specifies the authentication hash table with host name, credentials and accessToken. See Start-SvtSession for more details. .PARAMETER PolicyName Specifies a comma separated list of HPE SimpliVity backup policy names to use for the command output. .PARAMETER PolicyId Specifies a comma separated list of HPE SimpliVity backup policy IDs to use for the command output. .PARAMETER ClusterName Specifies a comma separated list of HPE SimpliVity cluster names to use for the command output. .PARAMETER ClusterId Specifies a comma separated list of HPE SimpliVity cluster IDs to use for the command output. .PARAMETER RuleNumber Specifies the HPE SimpliVity backup policy rule number to use for the command output. This parameter is useful for restricting the output when an HPE SimpliVity backup policy has multiple rules. .PARAMETER Sort Specifies the name of a field to use for sorting command output Supported fields are: PolicyName, PolicyId .PARAMETER Ascending Use with the Sort parameter. Specifies that the results display in ascending order. .PARAMETER Offset Specifies a positive integer that displays results from this offset, up to the available limit. .PARAMETER Limit Limit - A positive integer between 1 to 500 that represents the maximum number of results to display. Default value is 500 .PARAMETER Nolimit Specifies that results for all HPE SimpliVity backup policies should be displayed. .EXAMPLE PS C:\> Get-SvtPolicy -HostOAuthToken $HostOAuthToken Obtains details for a maximum of 500 HPE SimpliVity backup policies. .EXAMPLE PS C:\> Get-SvtPolicy -HostOAuthToken $HostOAuthToken -PolicyName "Policy01" Uses a policy name to obtain details for the specified HPE SimpliVity backup policy. .EXAMPLE PS C:\> Get-SvtPolicy -HostOAuthToken $HostOAuthToken -PolicyName "Policy01","Policy02" Uses policy names to obtain details for the specified HPE SimpliVity backup policies. .EXAMPLE PS C:\> Get-SvtPolicy -HostOAuthToken $HostOAuthToken -PolicyName "Policy01" -RuleNumber 0 Uses a backup policy name and a rule number to obtain details for the specified HPE SimpliVity backup policy. .EXAMPLE PS C:\> Get-SvtPolicy -HostOAuthToken $HostOAuthToken -PolicyId <PolicyId1> Uses a policy ID to obtain details for the specified HPE SimpliVity backup policy. .EXAMPLE PS C:\> Get-SvtPolicy -HostOAuthToken $HostOAuthToken -PolicyId <PolicyId1>,<PolicyId2> -RuleNumber 2 Uses policy IDs and a rule number to obtain details for specified HPE SimpliVity backup policies. .EXAMPLE PS C:\> Get-SvtPolicy -HostOAuthToken $HostOAuthToken -ClusterName "MyCluster", "MyCluster2" Uses cluster names to obtain details for HPE SimpliVity backup policies from specified clusters. .EXAMPLE PS C:\> Get-SvtPolicy -HostOAuthToken $HostOAuthToken -ClusterName "MyCluster" -PolicyName "Policy01" Uses a cluster name and a policy name to obtain details for the specified HPE SimpliVity backup policy from the specified cluster. .EXAMPLE PS C:\> Get-SvtPolicy -HostOAuthToken $HostOAuthToken -ClusterId <ClusterId1>, <ClusterId2> Uses cluster IDs to obtain details for HPE SimpliVity backup policies from specified clusters. .EXAMPLE PS C:\> Get-SvtPolicy -HostOAuthToken $HostOAuthToken -ClusterId <ClusterId1> -PolicyName "Policy01" Uses a cluster ID and a policy name to obtain details for the specified HPE SimpliVity backup policy from the specified cluster. .EXAMPLE PS C:\> Get-SvtPolicy -HostOAuthToken $HostOAuthToken -offset 5 -limit 200 Obtains details for HPE SimpliVity backup policies, starting from the specified offset and with a limit of 200 backup policies. .EXAMPLE PS C:\> Get-SvtPolicy -HostOAuthToken $HostOAuthToken -sort "PolicyName" -Asending Obtains details for HPE SimpliVity backup policies, displayed in ascending order and based on the specified field. .EXAMPLE PS C:\> Get-SvtPolicy -HostOAuthToken $HostOAuthToken -Nolimit Obtains details for HPE SimpliVity backup polices from the entire HPE SimpliVity environment. .INPUTS System.String .OUTPUTS HPE.SimpliVity.Policy .NOTES 1. Limit and Nolimit parameters are mutually exclusive. Specify only one. 2. Get-SvtPolicy displays a maximum of 500 HPE SimpliVity backup policies in the entire environment. Use filter parameters to restrict the output. If necessary, use the Nolimit parameter to display all policies. Use of the Nolimit parameter can take a significant amount of time. 3. If you are using in extended scale mode, duplicate names for HPE SimpliVity backup policies can exist across clusters. If you are using a centrally-managed federation, backup policy names must be unique. 4. Use of filter parameters for cluster name or ID is supported in extended scale mode only. These filter parameters are ignored if you are using a centrally-managed federation. 5. The filtering, sort, offset, and limit parameters apply to policies only. Backup policy rules are part of a policy, therefore these parameters does affect the output especially when more than one policy rule defined per policy. For example, if a policy has three rules, a query for a policy name with a limit of 1 displays three rows because three rules exist. 6. When a backup policy has more than one rule, each additional rule is considered to be another policy object in the output. This action impacts the total policy numbers when the object count is queried. To check the total policy count from a returned object, use ($Object.PolicyID | Select-Object -Unique).count #> function Get-SvtPolicy { [CMDLetBinding(DefaultParameterSetName = 'ByPolicyName')] param ( [ValidateNotNullOrEmpty()] [Parameter(Mandatory=$true, ValueFromPipeline, HelpMessage='Specifies the authentication hash table with host name, credentials and accessToken')] [HashTable]$HostOAuthToken, [ValidateNotNullOrEmpty()] [Parameter(ParameterSetName="ByPolicyName", Mandatory=$false, HelpMessage='Specify an array of HPE SimpliVity backup policy names.')] [Parameter(ParameterSetName="ByClusterName", Mandatory=$false)] [Parameter(ParameterSetName="ByClusterId", Mandatory=$false)] [System.String[]]$PolicyName, #Validate input is in GUID format [ValidateScript({ try { [System.Guid]::ParseExact($_,"D") | Out-Null $True } catch { Throw $_ } })] [Parameter(ParameterSetName="ByPolicyId", Mandatory=$false, HelpMessage='Specifies an array of HPE SimpliVity backup policy IDs.')] [System.String[]]$PolicyId, [ValidateNotNullOrEmpty()] [Parameter(ParameterSetName="ByClusterName", Mandatory=$false, HelpMessage='Specifies an array of HPE SimpliVity cluster names.')] [System.String[]]$ClusterName, #Validate input is in GUID format [ValidateScript({ try { [System.Guid]::ParseExact($_,"D") | Out-Null $True } catch { Throw $_ } })] [Parameter(ParameterSetName="ByClusterId", Mandatory=$false, HelpMessage='Specifies an array of HPE SimpliVity cluster IDs.')] [System.String[]]$ClusterId, [ValidateNotNullOrEmpty()] [Parameter(Mandatory = $false, HelpMessage='Specifies the backup policy rule number.')] [ValidateRange(0, [int]::MaxValue)] [System.Int32]$RuleNumber, [Parameter(Mandatory=$false, HelpMessage='Specifies the name of the field to use for sorting results. Default is to sort by PolicyName. See help for the -sort parameters.')] [ValidateSet('PolicyName', 'PolicyId')] [System.String]$Sort='PolicyName', [Parameter(Mandatory=$false, HelpMessage='Use this parameter with the -sort parameter to display results in ascending order.')] [Switch]$Ascending, [Parameter(Mandatory=$false, HelpMessage='Specifies a positive integer that displays results staring from the specified offset, up to the available limit.')] [ValidateRange(0, [int]::MaxValue)] [System.Int32]$Offset=0, [Parameter(Mandatory=$false, HelpMessage='Specifies a positive integer between 1 to 500 that represents the maximum number of results to display.')] [ValidateRange(1, 500)] [System.Int32]$Limit=500, [Parameter(Mandatory=$false, HelpMessage='Use this parameter to display all the HPE SimpliVity backup policies in HPE SimpliVity environment.')] [Switch]$Nolimit ) #Rest Version check $RestVersion = [double]$HostOAuthToken.RestVersion if ($RestVersion -lt 1.17) { Throw("Current REST version $RestVersion does not support this feature") } if ($PSBoundParameters.ContainsKey('Nolimit') -and $PSBoundParameters.ContainsKey('Limit')) { Throw("Limit and Nolimit parameters are mutually exclusive. Provide only one of them") } if ($PSBoundParameters.ContainsKey('Nolimit')) { $Message = "Nolimit parameter displays all the HPE SimpliVity backup policies in the environment. " + "Using this parameter can take a significant amount of time, depending on the number of policies to display." Write-warning $Message } $NoPolicesMessage = "No HPE SimpliVity backup policies found" $Header = Get-Header $HostOAuthToken.AccessToken $Url = Get-SvtPolicyUrl -hostname $HostOAuthToken.Hostname $Url += "?case=insensitive" if ($PSBoundParameters.ContainsKey('PolicyId')) { $PolicyIds = $PolicyId -join ',' $Url += '&id=' + $PolicyIds $NoPolicesMessage += " with ID: $PolicyIds " } elseif ($PSBoundParameters.ContainsKey('PolicyName')) { $PolicyNames = $PolicyName -join ',' $Url += '&name=' + $PolicyNames $NoPolicesMessage += " with name: $PolicyNames " } #Filter based on cluster name or ID is supported only in 'extended scale mode deployment' $IsExtendedScaleMode = Check-ClusterTopology -HostOAuthToken $HostOAuthToken if ($IsExtendedScaleMode) { if ($PSBoundParameters.ContainsKey('ClusterId')) { $ClusterIds = $ClusterId -join ',' $Url += '&owner_cluster_id=' + $ClusterIds $NoPolicesMessage += " in HPE SimpliVity clusters with ID: $ClusterIds" } elseif ($PSBoundParameters.ContainsKey('ClusterName')) { $ClusterNames = $ClusterName -join ',' $Url += '&owner_cluster_name=' + $ClusterNames $NoPolicesMessage += " in HPE SimpliVity clusters with name: $ClusterNames" } } $SortObjects = @{ "PolicyName" = "name"; "PolicyId" = "id"; } if ($PSBoundParameters.ContainsKey('Sort')) { $Url = $Url + '&sort=' + $SortObjects.$Sort } if ($PSBoundParameters.ContainsKey('Ascending')) { $Url = $Url + '&order=ascending' if ( -not $PSBoundParameters.ContainsKey('Sort')) { $Url = $Url + '&sort=' + $SortObjects.$Sort } } $Url += '&limit=' + $Limit #Pass the limit value to the URL $PolicyDetails = @() $NewOffset = $Offset $WarnMessages = @() # Define empty array for warning messages do { $ThisUrl = $Url + "&offset=$NewOffset" #Pass the newOffset value to URL everytime try { $Response = Invoke-SvtRestMethod -HostOAuthToken $HostOAuthToken -Uri $ThisUrl -Header $Header -Method Get -ErrorAction Stop } catch [System.Management.Automation.RuntimeException] { if ($PSBoundParameters.ContainsKey('PolicyId') -and ($_ -match "id\/(\S+) is an invalid key\/value for the policies object type")) { Throw ("Unable to find the HPE SimpliVity backup policy with ID : "+$Matches[1]) } elseif ($PSBoundParameters.ContainsKey('ClusterId') -and ($_ -match "owner_cluster_id\/(\S+) is an invalid key\/value for the policies object type")) { Throw ("Unable to find the HPE SimpliVity cluster with ID : "+$Matches[1]) } else{ Throw ($_) } } $TotalPolicies = $Response.Count # Total policies count returned by Policy List API #Throw an error if no policies available with provided parameters if ($TotalPolicies -eq 0) { Throw $NoPolicesMessage } #Display error if offset value provided is greater than available policies if ($PSBoundParameters.ContainsKey('Offset') -and ($Offset -ge $TotalPolicies)) { $Message = "The specified offset value ($Offset) is equal to or greater than the number of matching policies ($TotalPolicies)." + " Adjust the offset value." Throw $Message } #Display warning message when user did not provide either 'nolimit' or 'limit' parameter and total policies #more than default limit (500) + provided offset if ((-not $PSBoundParameters.ContainsKey('Nolimit')) -and (-not $PSBoundParameters.ContainsKey('Limit')) ` -and $TotalPolicies -gt ($Limit + $Offset)) { $PolicyOffset = $Offset + $Limit $Message = "More policies ($TotalPolicies) exist than the default limit(500), displaying policies from ($Offset to $PolicyOffset)." + " Specify a different offset and limit value, or use additional filters to restrict the output `n" + "If necessary, use the Nolimit parameter to display all policies." + " Use of the Nolimit parameter can take a significant amount of time." Write-Warning $Message } $PolicyDetails += $Response.policies #Number policies able to fetch based on offset and limit in this rest call $CurrentPolicies = ($PolicyDetails| Measure-Object).count # No of policies in the Array $NewOffset = $Offset + $CurrentPolicies #Update the new offset value } until ((($CurrentPolicies + $Offset) -ge $TotalPolicies ) -or (-not $PSBoundParameters.ContainsKey('Nolimit'))) #Continue the loop until we get all the policies if Nolimit parameter provided, otherwise comeout from the loop #Print warning when a policy or policy in cluster not found when filtering using multiple objects. $AddWarnMessage = "" if ($PSBoundParameters.ContainsKey('Offset') -and ($PSBoundParameters.ContainsKey('Limit'))) { $AddWarnMessage = " with specified Offset value ($Offset) and Limit value ($Limit). Adjust Offset and Limit." } elseif ($PSBoundParameters.ContainsKey('Offset') -and $Offset -ne 0) { $AddWarnMessage = " with specified Offset value ($Offset). Adjust Offset." } elseif ($PSBoundParameters.ContainsKey('Limit') -and $Limit -ne 500) { $AddWarnMessage = " with specified Limit value($Limit). Adjust Limit." } if ($PSBoundParameters.ContainsKey('PolicyName')) { $PoliciesNotFound = $PolicyName | Where-Object {$_ -notin $PolicyDetails.name} #Check not found policies if ($PoliciesNotFound) { $WarnMessages += ("No HPE SimpliVity backup policies found with names: " + ($PoliciesNotFound -join ', ') + $AddWarnMessage) } } elseif ($PSBoundParameters.ContainsKey('PolicyId')) { $PoliciesNotFound = $PolicyId | Where-Object {$_ -notin $PolicyDetails.id} #Check not found policies if ($PoliciesNotFound) { $WarnMessages += ("No HPE SimpliVity backup policies found with IDs : " + ($PoliciesNotFound -join ', ') + $AddWarnMessage) } } #Print warning when policies are not found in one of the cluster name or ID if ($IsExtendedScaleMode) { if ($PSBoundParameters.ContainsKey('ClusterName')) { $NoPoliciesInClusters = $ClusterName | Where-Object {$_ -notin $PolicyDetails.owner_cluster_name} if ($NoPoliciesInClusters) { if ($PolicyName) { $WarnMessages += ("No HPE SimpliVity backup policies found with names: " + ($PolicyName -join ', ') + " and in HPE SimpliVity clusters with names: " + ($NoPoliciesInClusters -join ', ') + $AddWarnMessage) } else { $WarnMessages += ("No HPE SimpliVity backup policies found in HPE SimpliVity clusters with names: " + ($NoPoliciesInClusters -join ', ') + $AddWarnMessage) } } } elseif ($PSBoundParameters.ContainsKey('ClusterId')) { $NoPoliciesInClusters = $ClusterId | Where-Object {$_ -notin $PolicyDetails.owner_cluster_id} if ($NoPoliciesInClusters) { if ($PolicyName) { $WarnMessages += ("No HPE SimpliVity backup policies found with names: " + ($PolicyName -join ', ') + " and in HPE SimpliVity clusters with IDs: " + ($NoPoliciesInClusters -join ', ') + $AddWarnMessage) } else { $WarnMessages += ("No HPE SimpliVity backup policies found in HPE SimpliVity clusters with IDs: " + ($NoPoliciesInClusters -join ', ') + $AddWarnMessage) } } } } $PoliciesList = $PolicyDetails | ForEach-Object { $CurrentPolicyName = $_.name $CurrentPolicyId = $_.id $ClusterGroupIds = $_.cluster_group_ids $OwnerClusterName = $_.owner_cluster_name $OwnerClusterId = $_.owner_cluster_id #If policy has rules display them if ($_.rules) { $_.rules | ForEach-Object { if (-not $PSBoundParameters.ContainsKey('RuleNumber') -or $RuleNumber -eq $_.number) { [PSCustomObject]@{ PSTypeName = 'HPE.SimpliVity.Policy' PolicyName = $CurrentPolicyName PolicyId = $CurrentPolicyId ClusterName = $OwnerClusterName ClusterId = $OwnerClusterId ClusterGroupIds = $ClusterGroupIds DestinationId = $_.destination_id EndTime = $_.end_time DestinationName = $_.destination_name ConsistencyType = $_.consistency_type FrequencyHour = $_.frequency / 60 ApplicationConsistent = $_.application_consistent RuleNumber = $_.number StartTime = $_.start_time MaxBackup = $_.max_backups Day = $_.days RuleId = $_.id RetentionDay = [math]::Round($_.retention / 1440) ExternalStoreName = $_.external_store_name } } # end if } # foreach rule } elseif (-not $PSBoundParameters.ContainsKey('RuleNumber')) { # Don't add policies if user explictly passed RuleNumber and it does not exist [PSCustomObject]@{ PSTypeName = 'HPE.SimpliVity.Policy' PolicyName = $CurrentPolicyName PolicyId = $CurrentPolicyId ClusterName = $OwnerClusterName ClusterId = $OwnerClusterId ClusterGroupIds = $ClusterGroupIds } } } if ($PSBoundParameters.ContainsKey('RuleNumber') -and (($PoliciesList | Measure-Object).count -eq 0)) { Throw("No HPE SimpliVity backup policies found with the specified rule number: $RuleNumber") } if ($WarnMessages) { foreach ($WarnMessage in $WarnMessages) { Write-Warning $WarnMessage } } return $PoliciesList } Export-ModuleMember -function Get-SvtPolicy # SIG # Begin signature block # MIIlSAYJKoZIhvcNAQcCoIIlOTCCJTUCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDD/YCkxIPN0Ub3 # RGydVqLZuEZvJm7mRCJv1OQZNT5UbKCCEKwwggUqMIIEEqADAgECAhEAh0L0QnA4 # GzyXlRYB5/Z3IjANBgkqhkiG9w0BAQsFADB8MQswCQYDVQQGEwJHQjEbMBkGA1UE # CBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRgwFgYDVQQK # Ew9TZWN0aWdvIExpbWl0ZWQxJDAiBgNVBAMTG1NlY3RpZ28gUlNBIENvZGUgU2ln # bmluZyBDQTAeFw0yMTA1MjgwMDAwMDBaFw0yMjA1MjgyMzU5NTlaMIGQMQswCQYD # VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTESMBAGA1UEBwwJUGFsbyBBbHRv # MSswKQYDVQQKDCJIZXdsZXR0IFBhY2thcmQgRW50ZXJwcmlzZSBDb21wYW55MSsw # KQYDVQQDDCJIZXdsZXR0IFBhY2thcmQgRW50ZXJwcmlzZSBDb21wYW55MIIBIjAN # BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuy98a4/YGCzF1KvXZeoHxDtk6qL4 # PSuU32Ob9Fzpxq36JZIs6oezkvBnNVlf4iuaWSk3UyqK/JpKpbdz1dB/cuB2s+PV # aVR9goUC494Qi7HVDeFmomdvH2Xt0r+R6VUDtpxnR/XmZrZjXKP5T2Yk+XDMl78R # XT9ayu3ZZncwTdYauSBk1sJq1Vid3gHnNrrA5DmidVwxmu5Y9XvIjcrEtECPm4hx # sV2ISbMnnuzM0bvisxwAAho74TfswOyBSy182sFGZPbmwkyJvW1RhPV+2POqSaOR # CXvSad2KJUWtxgqfOGOU+hAP+sHvg5MbXDj6I+RSx9dJAu5WKcffyp506QIDAQAB # o4IBkDCCAYwwHwYDVR0jBBgwFoAUDuE6qFM6MdWKvsG7rWcaA4WtNA4wHQYDVR0O # BBYEFE32P36Oqh0//kySCDZQvL8TnjDgMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMB # Af8EAjAAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMBEGCWCGSAGG+EIBAQQEAwIEEDBK # BgNVHSAEQzBBMDUGDCsGAQQBsjEBAgEDAjAlMCMGCCsGAQUFBwIBFhdodHRwczov # L3NlY3RpZ28uY29tL0NQUzAIBgZngQwBBAEwQwYDVR0fBDwwOjA4oDagNIYyaHR0 # cDovL2NybC5zZWN0aWdvLmNvbS9TZWN0aWdvUlNBQ29kZVNpZ25pbmdDQS5jcmww # cwYIKwYBBQUHAQEEZzBlMD4GCCsGAQUFBzAChjJodHRwOi8vY3J0LnNlY3RpZ28u # Y29tL1NlY3RpZ29SU0FDb2RlU2lnbmluZ0NBLmNydDAjBggrBgEFBQcwAYYXaHR0 # cDovL29jc3Auc2VjdGlnby5jb20wDQYJKoZIhvcNAQELBQADggEBABmxgISN4Ehp # rP/zvy+4wqQItJDH30z1qv02yZXsA988VQ8uq3Iof7x1tvTsNo06hcNhqXWx547s # p3DU/FmteG8LTT4iATHZNc6OHdZ+A4IYOAmUNhIPCMT/DLgunRjnLJPHPVYkRiKu # a0Ggzwa2a4CsV2z9DB1erpbX9jsOLS21ENqRIYcgipSVNo1cJYVdtWi7INWwuqcy # juJcy0ZOfKlPMr7Mn4i3L1HPzcoWAkZPBqefO/KrDAhM5qW07+YYZAH7pcBdQcLu # m4+LlAT51Ha9gi1mcr2WcJEOnUtazO/TVcr7T/0RlUMuLRfSkCdQymUDx0TGwSME # elGewxW1JUYwggWBMIIEaaADAgECAhA5ckQ6+SK3UdfTbBDdMTWVMA0GCSqGSIb3 # DQEBDAUAMHsxCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVyIE1hbmNoZXN0 # ZXIxEDAOBgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoMEUNvbW9kbyBDQSBMaW1pdGVk # MSEwHwYDVQQDDBhBQUEgQ2VydGlmaWNhdGUgU2VydmljZXMwHhcNMTkwMzEyMDAw # MDAwWhcNMjgxMjMxMjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5l # dyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNF # UlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNh # dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCA # EmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B3PHTsdZ7 # NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkYtJHUYmTb # f6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/Fp0YvVGO # NaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2VN3I5xI6 # Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT79uq/nRO # acdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6c0Plfg6l # ZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmTYo61Zs8l # iM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97lc6wjOy0A # vzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4eeUB9XVKg+ # /XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeEHg9j1uli # utZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo4HyMIHvMB8GA1Ud # IwQYMBaAFKARCiM+lvEH7OKvKe+CpX/QMKS0MB0GA1UdDgQWBBRTeb9aqitKz1SA # 4dibwJ3ysgNmyzAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zARBgNV # HSAECjAIMAYGBFUdIAAwQwYDVR0fBDwwOjA4oDagNIYyaHR0cDovL2NybC5jb21v # ZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNAYIKwYBBQUHAQEE # KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5jb21vZG9jYS5jb20wDQYJKoZI # hvcNAQEMBQADggEBABiHUdx0IT2ciuAntzPQLszs8ObLXhHeIm+bdY6ecv7k1v6q # H5yWLe8DSn6u9I1vcjxDO8A/67jfXKqpxq7y/Njuo3tD9oY2fBTgzfT3P/7euLSK # 8JGW/v1DZH79zNIBoX19+BkZyUIrE79Yi7qkomYEdoiRTgyJFM6iTckys7roFBq8 # cfFb8EELmAAKIgMQ5Qyx+c2SNxntO/HkOrb5RRMmda+7qu8/e3c70sQCkT0ZANMX # XDnbP3sYDUXNk4WWL13fWRZPP1G91UUYP+1KjugGYXQjFrUNUHMnREd/EF2JKmuF # MRTE6KlqTIC8anjPuH+OdnKZDJ3+15EIFqGjX5UwggX1MIID3aADAgECAhAdokgw # b5smGNCC4JZ9M9NqMA0GCSqGSIb3DQEBDAUAMIGIMQswCQYDVQQGEwJVUzETMBEG # A1UECBMKTmV3IEplcnNleTEUMBIGA1UEBxMLSmVyc2V5IENpdHkxHjAcBgNVBAoT # FVRoZSBVU0VSVFJVU1QgTmV0d29yazEuMCwGA1UEAxMlVVNFUlRydXN0IFJTQSBD # ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xODExMDIwMDAwMDBaFw0zMDEyMzEy # MzU5NTlaMHwxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0 # ZXIxEDAOBgNVBAcTB1NhbGZvcmQxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDEk # MCIGA1UEAxMbU2VjdGlnbyBSU0EgQ29kZSBTaWduaW5nIENBMIIBIjANBgkqhkiG # 9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhiKNMoV6GJ9J8JYvYwgeLdx8nxTP4ya2JWYp # QIZURnQxYsUQ7bKHJ6aZy5UwwFb1pHXGqQ5QYqVRkRBq4Etirv3w+Bisp//uLjMg # +gwZiahse60Aw2Gh3GllbR9uJ5bXl1GGpvQn5Xxqi5UeW2DVftcWkpwAL2j3l+1q # cr44O2Pej79uTEFdEiAIWeg5zY/S1s8GtFcFtk6hPldrH5i8xGLWGwuNx2YbSp+d # gcRyQLXiX+8LRf+jzhemLVWwt7C8VGqdvI1WU8bwunlQSSz3A7n+L2U18iLqLAev # Rtn5RhzcjHxxKPP+p8YU3VWRbooRDd8GJJV9D6ehfDrahjVh0wIDAQABo4IBZDCC # AWAwHwYDVR0jBBgwFoAUU3m/WqorSs9UgOHYm8Cd8rIDZsswHQYDVR0OBBYEFA7h # OqhTOjHVir7Bu61nGgOFrTQOMA4GA1UdDwEB/wQEAwIBhjASBgNVHRMBAf8ECDAG # AQH/AgEAMB0GA1UdJQQWMBQGCCsGAQUFBwMDBggrBgEFBQcDCDARBgNVHSAECjAI # MAYGBFUdIAAwUAYDVR0fBEkwRzBFoEOgQYY/aHR0cDovL2NybC51c2VydHJ1c3Qu # Y29tL1VTRVJUcnVzdFJTQUNlcnRpZmljYXRpb25BdXRob3JpdHkuY3JsMHYGCCsG # AQUFBwEBBGowaDA/BggrBgEFBQcwAoYzaHR0cDovL2NydC51c2VydHJ1c3QuY29t # L1VTRVJUcnVzdFJTQUFkZFRydXN0Q0EuY3J0MCUGCCsGAQUFBzABhhlodHRwOi8v # b2NzcC51c2VydHJ1c3QuY29tMA0GCSqGSIb3DQEBDAUAA4ICAQBNY1DtRzRKYaTb # 3moqjJvxAAAeHWJ7Otcywvaz4GOz+2EAiJobbRAHBE++uOqJeCLrD0bs80ZeQEaJ # EvQLd1qcKkE6/Nb06+f3FZUzw6GDKLfeL+SU94Uzgy1KQEi/msJPSrGPJPSzgTfT # t2SwpiNqWWhSQl//BOvhdGV5CPWpk95rcUCZlrp48bnI4sMIFrGrY1rIFYBtdF5K # dX6luMNstc/fSnmHXMdATWM19jDTz7UKDgsEf6BLrrujpdCEAJM+U100pQA1aWy+ # nyAlEA0Z+1CQYb45j3qOTfafDh7+B1ESZoMmGUiVzkrJwX/zOgWb+W/fiH/AI57S # HkN6RTHBnE2p8FmyWRnoao0pBAJ3fEtLzXC+OrJVWng+vLtvAxAldxU0ivk2zEOS # 5LpP8WKTKCVXKftRGcehJUBqhFfGsp2xvBwK2nxnfn0u6ShMGH7EezFBcZpLKewL # PVdQ0srd/Z4FUeVEeN0B3rF1mA1UJP3wTuPi+IO9crrLPTru8F4XkmhtyGH5pvEq # CgulufSe7pgyBYWe6/mDKdPGLH29OncuizdCoGqC7TtKqpQQpOEN+BfFtlp5MxiS # 47V1+KHpjgolHuQe8Z9ahyP/n6RRnvs5gBHN27XEp6iAb+VT1ODjosLSWxr6MiYt # aldwHDykWC6j81tLB9wyWfOHpxptWDGCE/IwghPuAgEBMIGRMHwxCzAJBgNVBAYT # AkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcTB1NhbGZv # cmQxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDEkMCIGA1UEAxMbU2VjdGlnbyBS # U0EgQ29kZSBTaWduaW5nIENBAhEAh0L0QnA4GzyXlRYB5/Z3IjANBglghkgBZQME # AgEFAKB8MBAGCisGAQQBgjcCAQwxAjAAMBkGCSqGSIb3DQEJAzEMBgorBgEEAYI3 # AgEEMBwGCisGAQQBgjcCAQsxDjAMBgorBgEEAYI3AgEVMC8GCSqGSIb3DQEJBDEi # BCC1Sd7OYBlEj34Van36ZeUMY25kFklq6nxw+fjruWs7cTANBgkqhkiG9w0BAQEF # AASCAQAxLgtfUT76atPqreRCTSvP5lrNTGLgFGiS7dlH7ZPCYaUeQeKv5ku217Ok # UTX646FFSveE3CygnvBDC2ahVVgTjOcvtzvi/j4T2m8XO3ogvwEx4e/uSZryC0Wj # L3oQi2zasz+fCR3W4SK0bEn4bBt6t7hQPDnc9HwShGdc705v/QPX9iSpc9s2lRW7 # OkpLxcGRHWdFI7qA37VR0oTiTIlwZ/TFbElxA/VtIw/UrCWWXNkZDxNNytn/DyzS # MSM3ZniUHyMDoT5/R95wp2TM1MePCpWouE3OG2jbJzuN5BgeYexTJliqggUyqrry # PqqlL9mLmiuR2s9BGpHL4jS8TVxZoYIRszCCEa8GCisGAQQBgjcDAwExghGfMIIR # mwYJKoZIhvcNAQcCoIIRjDCCEYgCAQMxDzANBglghkgBZQMEAgEFADB4BgsqhkiG # 9w0BCRABBKBpBGcwZQIBAQYJYIZIAYb9bAcBMDEwDQYJYIZIAWUDBAIBBQAEIBKi # I8PAVFj7dxrW+WBcVRTjRQz2FXr017xeL3HZNuE9AhEA7OHZPN/yNbXkDqjY2Wxk # /BgPMjAyMjA0MDcwNjE0NTlaoIINfDCCBsYwggSuoAMCAQICEAp6SoieyZlCkAZj # OE2Gl50wDQYJKoZIhvcNAQELBQAwYzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRp # Z2lDZXJ0LCBJbmMuMTswOQYDVQQDEzJEaWdpQ2VydCBUcnVzdGVkIEc0IFJTQTQw # OTYgU0hBMjU2IFRpbWVTdGFtcGluZyBDQTAeFw0yMjAzMjkwMDAwMDBaFw0zMzAz # MTQyMzU5NTlaMEwxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5j # LjEkMCIGA1UEAxMbRGlnaUNlcnQgVGltZXN0YW1wIDIwMjIgLSAyMIICIjANBgkq # hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAuSqWI6ZcvF/WSfAVghj0M+7MXGzj4CUu # 0jHkPECu+6vE43hdflw26vUljUOjges4Y/k8iGnePNIwUQ0xB7pGbumjS0joiUF/ # DbLW+YTxmD4LvwqEEnFsoWImAdPOw2z9rDt+3Cocqb0wxhbY2rzrsvGD0Z/NCcW5 # QWpFQiNBWvhg02UsPn5evZan8Pyx9PQoz0J5HzvHkwdoaOVENFJfD1De1FksRHTA # MkcZW+KYLo/Qyj//xmfPPJOVToTpdhiYmREUxSsMoDPbTSSF6IKU4S8D7n+FAsmG # 4dUYFLcERfPgOL2ivXpxmOwV5/0u7NKbAIqsHY07gGj+0FmYJs7g7a5/KC7CnuAL # S8gI0TK7g/ojPNn/0oy790Mj3+fDWgVifnAs5SuyPWPqyK6BIGtDich+X7Aa3Rm9 # n3RBCq+5jgnTdKEvsFR2wZBPlOyGYf/bES+SAzDOMLeLD11Es0MdI1DNkdcvnfv8 # zbHBp8QOxO9APhk6AtQxqWmgSfl14ZvoaORqDI/r5LEhe4ZnWH5/H+gr5BSyFtaB # ocraMJBr7m91wLA2JrIIO/+9vn9sExjfxm2keUmti39hhwVo99Rw40KV6J67m0uy # 4rZBPeevpxooya1hsKBBGBlO7UebYZXtPgthWuo+epiSUc0/yUTngIspQnL3ebLd # hOon7v59emsCAwEAAaOCAYswggGHMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E # AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMCAGA1UdIAQZMBcwCAYGZ4EMAQQC # MAsGCWCGSAGG/WwHATAfBgNVHSMEGDAWgBS6FtltTYUvcyl2mi91jGogj57IbzAd # BgNVHQ4EFgQUjWS3iSH+VlhEhGGn6m8cNo/drw0wWgYDVR0fBFMwUTBPoE2gS4ZJ # aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0UlNBNDA5 # NlNIQTI1NlRpbWVTdGFtcGluZ0NBLmNybDCBkAYIKwYBBQUHAQEEgYMwgYAwJAYI # KwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBYBggrBgEFBQcwAoZM # aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0UlNB # NDA5NlNIQTI1NlRpbWVTdGFtcGluZ0NBLmNydDANBgkqhkiG9w0BAQsFAAOCAgEA # DS0jdKbR9fjqS5k/AeT2DOSvFp3Zs4yXgimcQ28BLas4tXARv4QZiz9d5YZPvpM6 # 3io5WjlO2IRZpbwbmKrobO/RSGkZOFvPiTkdcHDZTt8jImzV3/ZZy6HC6kx2yqHc # oSuWuJtVqRprfdH1AglPgtalc4jEmIDf7kmVt7PMxafuDuHvHjiKn+8RyTFKWLbf # OHzL+lz35FO/bgp8ftfemNUpZYkPopzAZfQBImXH6l50pls1klB89Bemh2RPPkaJ # FmMga8vye9A140pwSKm25x1gvQQiFSVwBnKpRDtpRxHT7unHoD5PELkwNuTzqmkJ # qIt+ZKJllBH7bjLx9bs4rc3AkxHVMnhKSzcqTPNc3LaFwLtwMFV41pj+VG1/calI # GnjdRncuG3rAM4r4SiiMEqhzzy350yPynhngDZQooOvbGlGglYKOKGukzp123qlz # qkhqWUOuX+r4DwZCnd8GaJb+KqB0W2Nm3mssuHiqTXBt8CzxBxV+NbTmtQyimaXX # FWs1DoXW4CzM4AwkuHxSCx6ZfO/IyMWMWGmvqz3hz8x9Fa4Uv4px38qXsdhH6hyF # 4EVOEhwUKVjMb9N/y77BDkpvIJyu2XMyWQjnLZKhGhH+MpimXSuX4IvTnMxttQ2u # R2M4RxdbbxPaahBuH0m3RFu0CAqHWlkEdhGhp3cCExwwggauMIIElqADAgECAhAH # Nje3JFR82Ees/ShmKl5bMA0GCSqGSIb3DQEBCwUAMGIxCzAJBgNVBAYTAlVTMRUw # EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x # ITAfBgNVBAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBHNDAeFw0yMjAzMjMwMDAw # MDBaFw0zNzAzMjIyMzU5NTlaMGMxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdp # Q2VydCwgSW5jLjE7MDkGA1UEAxMyRGlnaUNlcnQgVHJ1c3RlZCBHNCBSU0E0MDk2 # IFNIQTI1NiBUaW1lU3RhbXBpbmcgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw # ggIKAoICAQDGhjUGSbPBPXJJUVXHJQPE8pE3qZdRodbSg9GeTKJtoLDMg/la9hGh # RBVCX6SI82j6ffOciQt/nR+eDzMfUBMLJnOWbfhXqAJ9/UO0hNoR8XOxs+4rgISK # Ihjf69o9xBd/qxkrPkLcZ47qUT3w1lbU5ygt69OxtXXnHwZljZQp09nsad/ZkIdG # AHvbREGJ3HxqV3rwN3mfXazL6IRktFLydkf3YYMZ3V+0VAshaG43IbtArF+y3kp9 # zvU5EmfvDqVjbOSmxR3NNg1c1eYbqMFkdECnwHLFuk4fsbVYTXn+149zk6wsOeKl # SNbwsDETqVcplicu9Yemj052FVUmcJgmf6AaRyBD40NjgHt1biclkJg6OBGz9vae # 5jtb7IHeIhTZgirHkr+g3uM+onP65x9abJTyUpURK1h0QCirc0PO30qhHGs4xSnz # yqqWc0Jon7ZGs506o9UD4L/wojzKQtwYSH8UNM/STKvvmz3+DrhkKvp1KCRB7UK/ # BZxmSVJQ9FHzNklNiyDSLFc1eSuo80VgvCONWPfcYd6T/jnA+bIwpUzX6ZhKWD7T # A4j+s4/TXkt2ElGTyYwMO1uKIqjBJgj5FBASA31fI7tk42PgpuE+9sJ0sj8eCXbs # q11GdeJgo1gJASgADoRU7s7pXcheMBK9Rp6103a50g5rmQzSM7TNsQIDAQABo4IB # XTCCAVkwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUuhbZbU2FL3Mpdpov # dYxqII+eyG8wHwYDVR0jBBgwFoAU7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYDVR0P # AQH/BAQDAgGGMBMGA1UdJQQMMAoGCCsGAQUFBwMIMHcGCCsGAQUFBwEBBGswaTAk # BggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAC # hjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9v # dEc0LmNydDBDBgNVHR8EPDA6MDigNqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5j # b20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNybDAgBgNVHSAEGTAXMAgGBmeBDAEE # AjALBglghkgBhv1sBwEwDQYJKoZIhvcNAQELBQADggIBAH1ZjsCTtm+YqUQiAX5m # 1tghQuGwGC4QTRPPMFPOvxj7x1Bd4ksp+3CKDaopafxpwc8dB+k+YMjYC+VcW9dt # h/qEICU0MWfNthKWb8RQTGIdDAiCqBa9qVbPFXONASIlzpVpP0d3+3J0FNf/q0+K # LHqrhc1DX+1gtqpPkWaeLJ7giqzl/Yy8ZCaHbJK9nXzQcAp876i8dU+6WvepELJd # 6f8oVInw1YpxdmXazPByoyP6wCeCRK6ZJxurJB4mwbfeKuv2nrF5mYGjVoarCkXJ # 38SNoOeY+/umnXKvxMfBwWpx2cYTgAnEtp/Nh4cku0+jSbl3ZpHxcpzpSwJSpzd+ # k1OsOx0ISQ+UzTl63f8lY5knLD0/a6fxZsNBzU+2QJshIUDQtxMkzdwdeDrknq3l # NHGS1yZr5Dhzq6YBT70/O3itTK37xJV77QpfMzmHQXh6OOmc4d0j/R0o08f56PGY # X/sr2H7yRp11LB4nLCbbbxV7HhmLNriT1ObyF5lZynDwN7+YAN8gFk8n+2BnFqFm # ut1VwDophrCYoCvtlUG3OtUVmDG0YgkPCr2B2RP+v6TR81fZvAT6gt4y3wSJ8ADN # XcL50CN/AAvkdgIm2fBldkKmKYcJRyvmfxqkhQ/8mJb2VVQrH4D6wPIOK+XW+6kv # RBVK5xMOHds3OBqhK/bt1nz8MYIDdjCCA3ICAQEwdzBjMQswCQYDVQQGEwJVUzEX # MBUGA1UEChMORGlnaUNlcnQsIEluYy4xOzA5BgNVBAMTMkRpZ2lDZXJ0IFRydXN0 # ZWQgRzQgUlNBNDA5NiBTSEEyNTYgVGltZVN0YW1waW5nIENBAhAKekqInsmZQpAG # YzhNhpedMA0GCWCGSAFlAwQCAQUAoIHRMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0B # CRABBDAcBgkqhkiG9w0BCQUxDxcNMjIwNDA3MDYxNDU5WjArBgsqhkiG9w0BCRAC # DDEcMBowGDAWBBSFCPOGUVyz0wd9trS3wH8bSl5B3jAvBgkqhkiG9w0BCQQxIgQg # XSdZgqfFpez/vlGh4MOyI2WlDN14QhFXaYF/E0W8jzMwNwYLKoZIhvcNAQkQAi8x # KDAmMCQwIgQgnaaQFcNJxsGJeEW6NYKtcMiPpCk722q+nCvSU5J55jswDQYJKoZI # hvcNAQEBBQAEggIAHPwBmE/k2oSw/W81ASw2R0H6BI9hKVgJoXKrZEieDMLJMN14 # UsbBnHdi8U6hs58cTZfRC9NWxaeKVegR4hN++6XmfP+auhG1h0o26XZZME+fdnyu # EfAIOKEchY0QgQeN3JFa6lYunm5qwU2fMkFh1/jbGGPFwJf8wLvziL35OCeku0QU # ndUadfHfJdiw4t0kK7YbZXeK1lPQWLuXIq5XQlhb765+tc29RCkEFlC/vYcgw5GT # yPfBCQYUs4/vqXs/fYbVQxJy+I9wA9ScdRdg2fheAB+Ijud2vbIF0TG6hsM+JglT # Q+9pw8nFmbbP6nmZeACxQiRlqhNOudahbHa7epnmjAaphmGZcQEPWJbHwtt6U7c4 # baW3LIPNSBvgy69elm/LUcHBq9cob7jhshwY5+bC0YtGTLb8BO/ikMnKiKsG4+Wo # UjMBQmj24NNtrb8LLYRbBiTzoYUPrewGcMUowpkB8pmLdhMY+uyLNEtrQLxqcWZg # w0DeBv4DdYVQlzxFhMh9MlSv1DxvSsOUsRqWBtVO3SZiEQhUysREPJYB9qqvvrVf # wdJSym6HMdXzo1djYA7yJHdCP1NykilJjRuL2OdMZeEc0WGzAwnvrZkVyKmoDMoE # /IlZWF0fs29trdynNlqy/LaNhT3fkbxT75JHFzURwLqjefcn0Z08GaVfoDE= # SIG # End signature block |