Modules/COM-External-Services.psm1
#------------------- FUNCTIONS FOR COMPUTE OPS MANAGEMENT EXTERNAL-SERVICES ----------------------------------------------------------------------------------------------------------------------------------------------- using module .\Constants.psm1 # Public functions Function Get-HPECOMExternalService { <# .SYNOPSIS Retrieve the list of external services configured. .DESCRIPTION This Cmdlet returns a collection of external services configured that are available in the specified region. .PARAMETER Region Specifies the region code of a Compute Ops Management instance provisioned in the workspace (e.g., 'us-west', 'eu-central', etc.). This mandatory parameter can be retrieved using 'Get-HPEGLService -Name "Compute Ops Management" -ShowProvisioned' or 'Get-HPEGLRegion -ShowProvisioned'. Auto-completion (Tab key) is supported for this parameter, providing a list of region codes provisioned in your workspace. .PARAMETER Name Name of an external services resource. .PARAMETER ServiceType Specifies the type of external service to retrieve. The available options are 'SERVICE_NOW' and 'DSCC'. .PARAMETER WhatIf Shows the raw REST API call that would be made to COM instead of sending the request. This option is useful for understanding the inner workings of the native REST API calls used by COM. .EXAMPLE Get-HPECOMExternalService -Region eu-central Return all external services configured in the central european region. .EXAMPLE Get-HPECOMExternalService -Region eu-central -name MyServiceNow Return the external services 'MyServiceNow' configured in the central european region. #> [CmdletBinding()] Param( [Parameter (Mandatory)] [ValidateScript({ if (($_ -in $Global:HPECOMRegions.region)) { $true } else { Throw "The COM region '$_' is not provisioned in this workspace! Please specify a valid region code (e.g., 'us-west', 'eu-central'). `nYou can retrieve the region code using: Get-HPEGLService -Name 'Compute Ops Management' -ShowProvisioned. `nYou can also use the Tab key for auto-completion to see the list of provisioned region codes." } })] [ArgumentCompleter({ param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters) # Filter region based on $Global:HPECOMRegions global variable and create completions $Global:HPECOMRegions.region | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object { [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) } })] [String]$Region, [String]$Name, [ValidateSet("SERVICE_NOW", "DSCC")] [String]$ServiceType, [Switch]$WhatIf ) Begin { $Caller = (Get-PSCallStack)[1].Command "[{0}] Called from: {1}" -f $MyInvocation.InvocationName.ToString().ToUpper(), $Caller | Write-Verbose } Process { "[{0}] Bound PS Parameters: {1}" -f $MyInvocation.InvocationName.ToString().ToUpper(), ($PSBoundParameters | out-string) | Write-Verbose $Uri = Get-COMExternalServicesUri if ($ServiceType -eq "SERVICE_NOW") { $Uri = (Get-Uri) + "?filter=serviceType eq 'SERVICE_NOW'" } elseif ($ServiceType -eq "DSCC") { $Uri = (Get-Uri) + "?filter=serviceType eq 'DSCC'" } try { [Array]$CollectionList = Invoke-HPECOMWebRequest -Method Get -Uri $Uri -Region $Region -WhatIfBoolean $WhatIf -Verbose:$VerbosePreference } catch { $PSCmdlet.ThrowTerminatingError($_) } $ReturnData = @() if ($Null -ne $CollectionList) { if ($Name) { $CollectionList = $CollectionList | Where-Object name -eq $Name } # Add region to object $CollectionList | Add-Member -type NoteProperty -name region -value $Region $ReturnData = Invoke-RepackageObjectWithType -RawObject $CollectionList -ObjectName "COM.ExternalServices" $ReturnData = $ReturnData #| Sort-Object { $_.updatedAt } return $ReturnData } else { return } } } Function New-HPECOMExternalService { <# .SYNOPSIS Deploy an external service application in a specified region. .DESCRIPTION This cmdlet deploys either a ServiceNow or Data Services Cloud Console (DSCC) external service application in a specified region. - The ServiceNow integration enables COM to automatically create incidents in ServiceNow when iLOs report hardware-related service events. - The Data Services Cloud Console (DSCC) integration allows COM to configure and manage external storage. .PARAMETER Name Name of the external service application to deploy. .PARAMETER Region Specifies the region code of a Compute Ops Management instance provisioned in the workspace (e.g., 'us-west', 'eu-central', etc.) to deploy the external web service. This mandatory parameter can be retrieved using 'Get-HPEGLService -Name "Compute Ops Management" -ShowProvisioned' or 'Get-HPEGLRegion -ShowProvisioned'. Auto-completion (Tab key) is supported for this parameter, providing a list of region codes provisioned in your workspace. .PARAMETER ServiceNow Switch parameter to specify the deployment of a ServiceNow integration. .PARAMETER DSCC Switch parameter to specify the deployment of a Data Services Cloud Console integration .PARAMETER Description Parameter to specify a description. .PARAMETER Credential Parameter to specify the credential (clientID and client secret) of the external service. .PARAMETER RefreshToken Parameter to specify the refresh token of the external web service. .PARAMETER OauthUrl Authentication URL of the external web service to obtain OAuth tokens. .PARAMETER IncidentUrl Incident URL of the external web service that is used to create incidents. .PARAMETER RefreshTokenExpiryInDays Parameter to specify the number of days after which the refresh token will expire. .PARAMETER WhatIf Shows the raw REST API call that would be made to COM instead of sending the request. This option is useful for understanding the inner workings of the native REST API calls used by COM. .EXAMPLE $ExternalServiceCredential = Get-Credential -Message "Enter your clientID and clientSecret" New-HPECOMExternalService -Name MyServiceNow -Region eu-central -Description "This is my ServiceNow integration" -Credential $ExternalServiceCredential -RefreshToken "541646646434684343" -OauthUrl "https://example.service-now.com/oauth_token.do" -IncidentUrl "https://example.service-now.com/api/now/import/u_demo_incident_inbound_api" -refreshTokenExpiryInDays 100 Create a ServiceNow integration in the central EU region. .EXAMPLE $DSCCcredentials = Get-Credential -Message "Enter your clientID and clientSecret" New-HPECOMExternalService -Region eu-central -DSCC -Name "Data Services Cloud Console integration" -Description "This is my DSCC service in US-West" -DSCCRegion us-west -Credential $DSCCcredentials Create in the central EU region a Data Services Cloud Console integration configured in the US-west region. .INPUTS Pipeline input is not supported .OUTPUTS System.Collections.ArrayList A custom status object or array of objects containing the following PsCustomObject keys: * Name - Name of the external service attempted to be deployed * Region - Name of the region where the external service is deployed * Status - Status of the deployment attempt (Failed for http error return; Complete if deployment is successful; Warning if no action is needed) * Details - More information about the status * Exception: Information about any exceptions generated during the operation. #> [CmdletBinding(DefaultParameterSetName = 'ServiceNow')] Param( [Parameter (Mandatory)] [ValidateScript({ if (($_ -in $Global:HPECOMRegions.region)) { $true } else { Throw "The COM region '$_' is not provisioned in this workspace! Please specify a valid region code (e.g., 'us-west', 'eu-central'). `nYou can retrieve the region code using: Get-HPEGLService -Name 'Compute Ops Management' -ShowProvisioned. `nYou can also use the Tab key for auto-completion to see the list of provisioned region codes." } })] [ArgumentCompleter({ param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters) # Filter region based on $Global:HPECOMRegions global variable and create completions $Global:HPECOMRegions.region | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object { [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) } })] [String]$Region, [Parameter (Mandatory)] [ValidateScript({ $_.Length -lt 256 })] [String]$Name, [Parameter(Mandatory, ParameterSetName = 'ServiceNow')] [switch]$ServiceNow, [Parameter(Mandatory, ParameterSetName = 'DSCC')] [switch]$DSCC, [Parameter (Mandatory)] [ValidateScript({ $_.Length -lt 256 })] [String]$Description, [Parameter (Mandatory)] [PSCredential]$Credential, [Parameter (Mandatory, ParameterSetName = 'ServiceNow')] [String]$RefreshToken, [Parameter (Mandatory, ParameterSetName = 'ServiceNow')] [String]$OauthUrl, [Parameter (Mandatory, ParameterSetName = 'ServiceNow')] [String]$IncidentUrl, [Parameter (Mandatory, ParameterSetName = 'ServiceNow')] [ValidateRange(100, 365)] [Int]$RefreshTokenExpiryInDays, [Parameter (Mandatory, ParameterSetName = 'DSCC')] [String]$DSCCRegion, [Switch]$WhatIf ) Begin { $Caller = (Get-PSCallStack)[1].Command "[{0}] Called from: '{1}'" -f $MyInvocation.InvocationName.ToString().ToUpper(), $Caller | Write-Verbose $Uri = Get-COMExternalServicesUri $DeployExternalServiceStatus = [System.Collections.ArrayList]::new() $AuthenticationType = "OAUTH" } Process { "[{0}] Bound PS Parameters: `n{1}" -f $MyInvocation.InvocationName.ToString().ToUpper(), ($PSBoundParameters | out-string) | Write-Verbose # Build object for the output $objStatus = [pscustomobject]@{ Name = $Name ServiceType = $Null Region = $Region Status = $Null Details = $Null Exception = $Null } try { $ExternalServiceResource = Get-HPECOMExternalService -Region $Region -Name $Name } catch { $PSCmdlet.ThrowTerminatingError($_) } if ($ExternalServiceResource) { "[{0}] External service '{1}' already exists in '{2}' region!" -f $MyInvocation.InvocationName.ToString().ToUpper(), $Name, $Region | Write-Verbose if ($WhatIf) { $ErrorMessage = "External service '{0}': Resource already exists in the '{1}' region! No action needed." -f $OneViewID, $Region Write-warning $ErrorMessage return } else { $objStatus.Status = "Warning" $objStatus.Details = "External service already exists in the region! No action needed." } } else { $ClientID = $Credential.UserName $clientSecret = [Runtime.InteropServices.Marshal]::PtrToStringBSTR([Runtime.InteropServices.Marshal]::SecureStringToBSTR($Credential.Password)) if ($ServiceNow) { $ServiceType = "SERVICE_NOW" $Authentication = @{ clientId = $ClientID clientSecret = $clientSecret refreshToken = $RefreshToken } $ServiceData = @{ oauthUrl = $OauthUrl incidentUrl = $IncidentUrl refreshTokenExpiryInDays = $refreshTokenExpiryInDays } } # ServiceType is DSCC else { $ServiceType = "DSCC" $Authentication = @{ clientId = $ClientID clientSecret = $clientSecret } $ServiceData = @{ region = $DSCCRegion } } $objStatus.ServiceType = $ServiceType # Build payload $payload = ConvertTo-Json @{ name = $Name serviceType = $ServiceType authenticationType = $authenticationType description = $Description authentication = $Authentication serviceData = $ServiceData } # Deploy the external service. try { $Response = Invoke-HPECOMWebRequest -Region $Region -Uri $Uri -method POST -body $payload -WhatIfBoolean $WhatIf -Verbose:$VerbosePreference if (-not $WhatIf) { "[{0}] '{1}' external service creation raw response: `n{2}" -f $MyInvocation.InvocationName.ToString().ToUpper(), $ServiceType, $Response | Write-Verbose do { $ExternalService_status = (Get-HPECOMExternalService -Region $Region | Where-Object name -eq $Name ).status Start-Sleep 1 } until ($ExternalService_status -eq "ENABLED") "[{0}] '{1}' external service successfully deployed in '{2}' region" -f $MyInvocation.InvocationName.ToString().ToUpper(), $name, $Region | Write-Verbose $objStatus.Status = "Complete" $objStatus.Details = "External service successfully deployed in $Region region" } } catch { if (-not $WhatIf) { $objStatus.Status = "Failed" $objStatus.Details = "External service cannot be deployed!" $objStatus.Exception = $Global:HPECOMInvokeReturnData } } } [void] $DeployExternalServiceStatus.add($objStatus) } end { if (-not $WhatIf) { $DeployExternalServiceStatus = Invoke-RepackageObjectWithType -RawObject $DeployExternalServiceStatus -ObjectName "COM.ExternalServices.NSDE" Return $DeployExternalServiceStatus } } } Function Remove-HPECOMExternalService { <# .SYNOPSIS Remove a ServiceNow application in a region. .DESCRIPTION This Cmdlet can be used to remove the ServiceNow application in a region. .PARAMETER Name Name of the ServiceNow application to remove. .PARAMETER Region Specifies the region code of a Compute Ops Management instance provisioned in the workspace (e.g., 'us-west', 'eu-central', etc.) where to remove ServiceNow. This mandatory parameter can be retrieved using 'Get-HPEGLService -Name "Compute Ops Management" -ShowProvisioned' or 'Get-HPEGLRegion -ShowProvisioned'. Auto-completion (Tab key) is supported for this parameter, providing a list of region codes provisioned in your workspace. .PARAMETER WhatIf Shows the raw REST API call that would be made to COM instead of sending the request. This option is useful for understanding the inner workings of the native REST API calls used by COM. .EXAMPLE Remove-HPECOMExternalService -Region eu-central -Name 'MyServiceNow_Name' Remove the ServiceNow integration from the central EU region. .EXAMPLE Get-HPECOMExternalService -Region eu-central -Name MyServiceNow_Name | Remove-HPECOMExternalService Remove the ServiceNow integration 'MyServiceNow_Name' from the central EU region. .EXAMPLE Get-HPECOMExternalService -Region eu-central | Remove-HPECOMExternalService Remove from the central EU region all external services returned by the 'Get-HPECOMExternalService' cmdlet. .INPUTS System.Collections.ArrayList List of external service(s) from 'Get-HPECOMExternalService'. .OUTPUTS System.Collections.ArrayList A custom status object or array of objects containing the following PsCustomObject keys: * Name - Name of the external service attempted to be removed * Region - Name of the region where the external service is removed * Status - Status of the removal attempt (Failed for http error return; Complete if removal is successful; Warning if no action is needed) * Details - More information about the status * Exception: Information about any exceptions generated during the operation. #> [CmdletBinding(DefaultParameterSetName = 'Default')] Param( [Parameter (Mandatory, ValueFromPipelineByPropertyName)] [ValidateScript({ if (($_ -in $Global:HPECOMRegions.region)) { $true } else { Throw "The COM region '$_' is not provisioned in this workspace! Please specify a valid region code (e.g., 'us-west', 'eu-central'). `nYou can retrieve the region code using: Get-HPEGLService -Name 'Compute Ops Management' -ShowProvisioned. `nYou can also use the Tab key for auto-completion to see the list of provisioned region codes." } })] [ArgumentCompleter({ param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters) # Filter region based on $Global:HPECOMRegions global variable and create completions $Global:HPECOMRegions.region | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object { [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) } })] [String]$Region, [Parameter (Mandatory, ValueFromPipelineByPropertyName)] [String]$Name, [Switch]$WhatIf ) Begin { $Caller = (Get-PSCallStack)[1].Command "[{0}] Called from: '{1}'" -f $MyInvocation.InvocationName.ToString().ToUpper(), $Caller | Write-Verbose $RemoveExternalServiceStatus = [System.Collections.ArrayList]::new() } Process { "[{0}] Bound PS Parameters: `n{1}" -f $MyInvocation.InvocationName.ToString().ToUpper(), ($PSBoundParameters | out-string) | Write-Verbose try { $ExternalServicesResource = Get-HPECOMExternalService -Region $Region -Name $Name } catch { $PSCmdlet.ThrowTerminatingError($_) } # Build object for the output $objStatus = [pscustomobject]@{ Name = $Name Region = $Region ServiceType = $ExternalServicesResource.ServiceType Status = $Null Details = $Null Exception = $Null } $ExternalServiceID = $ExternalServicesResource.id if (-not $ExternalServiceID) { # Must return a message if not found if ($WhatIf) { $ErrorMessage = "External service '{0}': Resource cannot be found in the '{1}' region!" -f $Name, $Region Write-warning $ErrorMessage return } else { $objStatus.Status = "Failed" $objStatus.Details = "External service cannot be found in the region!" } } else { $Uri = (Get-COMExternalServicesUri) + "/" + $ExternalServiceID # Deploy the external service. try { $Response = Invoke-HPECOMWebRequest -Region $Region -Uri $Uri -method DELETE -WhatIfBoolean $WhatIf -Verbose:$VerbosePreference if (-not $WhatIf) { "[{0}] External service removal raw response: `n{1}" -f $MyInvocation.InvocationName.ToString().ToUpper(), $Response | Write-Verbose "[{0}] External service '{1}' successfully deleted from '{2}' region" -f $MyInvocation.InvocationName.ToString().ToUpper(), $name, $Region | Write-Verbose $objStatus.Status = "Complete" $objStatus.Details = "External service successfully deleted from $Region region" } } catch { if (-not $WhatIf) { $objStatus.Status = "Failed" $objStatus.Details = "External service cannot be deleted!" $objStatus.Exception = $Global:HPECOMInvokeReturnData } } } [void] $RemoveExternalServiceStatus.add($objStatus) } end { if (-not $WhatIf) { $RemoveExternalServiceStatus = Invoke-RepackageObjectWithType -RawObject $RemoveExternalServiceStatus -ObjectName "COM.ExternalServices.NSDE" Return $RemoveExternalServiceStatus } } } Function Set-HPECOMExternalService { <# .SYNOPSIS Updates an external services item in a specified region. .DESCRIPTION This Cmdlet modifies the ServiceNow application settings in a specified region. If a parameter is not provided, the cmdlet retains the current setting and only updates the provided parameters. .PARAMETER Name Specifies the name of the external web service to update. .PARAMETER NewName Specifies the new name for the external web service. .PARAMETER Region Specifies the region code of a Compute Ops Management instance provisioned in the workspace (e.g., 'us-west', 'eu-central', etc.) where the external web service is located. This mandatory parameter can be retrieved using 'Get-HPEGLService -Name "Compute Ops Management" -ShowProvisioned' or 'Get-HPEGLRegion -ShowProvisioned'. Auto-completion (Tab key) is supported for this parameter, providing a list of region codes provisioned in your workspace. .PARAMETER Description Specifies a description for the external web service. .PARAMETER Credential Specifies the credentials (clientID and client secret) of the external web service. .PARAMETER RefreshToken Specifies the refresh token of the external web service. .PARAMETER OauthUrl Specifies the authentication URL of the external web service used to obtain OAuth tokens. .PARAMETER IncidentUrl Specifies the incident URL of the external web service that is used to create incidents. .PARAMETER RefreshTokenExpiryInDays Specifies the number of days after which the refresh token will expire. .PARAMETER WhatIf Shows the raw REST API call that would be made to COM instead of sending the request, useful for understanding the inner workings of the native REST API calls used by COM. .EXAMPLE Set-HPECOMExternalService -Region eu-central -Name MyServiceNow_Name -NewName MyServiceNow_for_COM -Description "This is my new description" -Credential $credentials -RefreshToken "541646646434684343" Updates the external service 'MyServiceNow_Name' in the 'eu-central' region with a new name 'MyServiceNow_for_COM' and a new description. .EXAMPLE Set-HPECOMExternalService -Region eu-central -Name MyServiceNow_Name -Description "This is my new description" -Credential $credential -RefreshToken "541646646434684343" -OauthUrl "https://example.service-now.com/oauth_token.do" -IncidentUrl "https://example.service-now.com/api/now/import/u_demo_incident_inbound_api" -RefreshTokenExpiryInDays 200 Updates the external service 'MyServiceNow_Name' in the central EU region with new parameters. .EXAMPLE Get-HPECOMExternalService -Region eu-central -Name MyServiceNow_Name | Set-HPECOMExternalService -Description "This is my new description" -Credential $credential -RefreshToken "541646646434684343" -OauthUrl "https://example.service-now.com/oauth_token.do" -IncidentUrl "https://example.service-now.com/api/now/import/u_demo_incident_inbound_api" -RefreshTokenExpiryInDays 150 Updates the external service 'MyServiceNow_Name' in the central EU region with new parameters. .INPUTS System.Collections.ArrayList List of external service(s) from 'Get-HPECOMExternalService'. .OUTPUTS System.Collections.ArrayList A custom status object or array of objects containing the following PsCustomObject keys: * Name - Name of the external service attempted to be updated * Region - Name of the region where the external service is updated * Status - Status of the modification attempt (Failed for HTTP error return; Complete if modification is successful; Warning if no action is needed) * Details - More information about the status * Exception - Information about any exceptions generated during the operation. #> [CmdletBinding(DefaultParameterSetName = 'Default')] Param( [Parameter (Mandatory, ValueFromPipelineByPropertyName)] [ValidateScript({ if (($_ -in $Global:HPECOMRegions.region)) { $true } else { Throw "The COM region '$_' is not provisioned in this workspace! Please specify a valid region code (e.g., 'us-west', 'eu-central'). `nYou can retrieve the region code using: Get-HPEGLService -Name 'Compute Ops Management' -ShowProvisioned. `nYou can also use the Tab key for auto-completion to see the list of provisioned region codes." } })] [ArgumentCompleter({ param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters) # Filter region based on $Global:HPECOMRegions global variable and create completions $Global:HPECOMRegions.region | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object { [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) } })] [String]$Region, [Parameter (Mandatory, ValueFromPipelineByPropertyName)] [ValidateScript({ $_.Length -lt 256 })] [String]$Name, [ValidateScript({ $_.Length -le 100 })] [String]$NewName, [ValidateScript({ $_.Length -lt 256 })] [String]$Description, [Parameter (Mandatory)] [PSCredential]$Credential, [Parameter (Mandatory)] [String]$RefreshToken, # [Parameter (Mandatory)] [String]$OauthUrl, # [Parameter (Mandatory)] [String]$IncidentUrl, # [Parameter (Mandatory)] [ValidateRange(100, 365)] [Int]$RefreshTokenExpiryInDays, [Switch]$WhatIf ) Begin { $Caller = (Get-PSCallStack)[1].Command "[{0}] Called from: '{1}'" -f $MyInvocation.InvocationName.ToString().ToUpper(), $Caller | Write-Verbose $SetExternalServiceStatus = [System.Collections.ArrayList]::new() } Process { "[{0}] Bound PS Parameters: `n{1}" -f $MyInvocation.InvocationName.ToString().ToUpper(), ($PSBoundParameters | out-string) | Write-Verbose try { $ExternalServicesResource = Get-HPECOMExternalService -Region $Region -Name $Name } catch { $PSCmdlet.ThrowTerminatingError($_) } # Build object for the output $objStatus = [pscustomobject]@{ Name = $Name ServiceType = $ExternalServicesResource.ServiceType Region = $Region Status = $Null Details = $Null Exception = $Null } $ExternalServiceID = $ExternalServicesResource.id if (-not $ExternalServiceID) { # Must return a message if not found if ($WhatIf) { $ErrorMessage = "External service '{0}': Resource cannot be found in the '{1}' region!" -f $Name, $Region Write-warning $ErrorMessage return } else { $objStatus.Status = "Failed" $objStatus.Details = "External service cannot be found in the region!" } } else { $Uri = (Get-COMExternalServicesUri) + "/" + $ExternalServiceID # Conditionally add properties if ($NewName) { $Name = $NewName } if (-not $PSBoundParameters.ContainsKey('Description')) { if ($ExternalServicesResource.description) { $Description = $ExternalServicesResource.description } else { $Description = $Null } } if (-not $OauthUrl) { $OauthUrl = $ExternalServicesResource.serviceData.oauthUrl } if (-not $IncidentUrl) { $IncidentUrl = $ExternalServicesResource.serviceData.incidentUrl } if (-not $refreshTokenExpiryInDays) { $refreshTokenExpiryInDays = $ExternalServicesResource.serviceData.refreshTokenExpiryInDays } # Deploy the external service. $ClientID = $Credential.UserName $clientSecret = [Runtime.InteropServices.Marshal]::PtrToStringBSTR([Runtime.InteropServices.Marshal]::SecureStringToBSTR($Credential.Password)) $Authentication = @{ clientId = $ClientID clientSecret = $clientSecret refreshToken = $RefreshToken } $ServiceData = @{ oauthUrl = $OauthUrl incidentUrl = $IncidentUrl refreshTokenExpiryInDays = $refreshTokenExpiryInDays } # Build payload $payload = ConvertTo-Json @{ name = $Name state = "ENABLED" description = $Description authentication = $Authentication serviceData = $ServiceData } # Deploy the external service. try { $Response = Invoke-HPECOMWebRequest -Region $Region -Uri $Uri -method PATCH -body $payload -ContentType "application/merge-patch+json" -WhatIfBoolean $WhatIf -Verbose:$VerbosePreference if (-not $WhatIf) { "[{0}] External service update raw response: `n{1}" -f $MyInvocation.InvocationName.ToString().ToUpper(), $Response | Write-Verbose "[{0}] External service '{1}' successfully updated in '{2}' region" -f $MyInvocation.InvocationName.ToString().ToUpper(), $name, $Region | Write-Verbose $objStatus.Status = "Complete" $objStatus.Details = "External service successfully updated in $Region region" } } catch { if (-not $WhatIf) { $objStatus.Status = "Failed" $objStatus.Details = "External service cannot be updated!" $objStatus.Exception = $Global:HPECOMInvokeReturnData } } } [void] $SetExternalServiceStatus.add($objStatus) } end { if (-not $WhatIf) { $SetExternalServiceStatus = Invoke-RepackageObjectWithType -RawObject $SetExternalServiceStatus -ObjectName "COM.ExternalServices.NSDE" Return $SetExternalServiceStatus } } } Function Test-HPECOMExternalService { <# .SYNOPSIS Generate a test incident in a region. .DESCRIPTION This Cmdlet can be used to generate a test incident in a region. For external service with serviceType as SERVICE_NOW, the cmdlet will generate a test incident for ServiceNow. For external service with serviceType as DSCC, the cmdlet will test the integration connection to Data Services Cloud Console. An activity will be generated as a result of this test and indicates the success or failure of creating the test incident. .PARAMETER Name Name of the external web service to test. .PARAMETER Region Specifies the region code of a Compute Ops Management instance provisioned in the workspace (e.g., 'us-west', 'eu-central', etc.) to update the external web service. This mandatory parameter can be retrieved using 'Get-HPEGLService -Name "Compute Ops Management" -ShowProvisioned' or 'Get-HPEGLRegion -ShowProvisioned'. Auto-completion (Tab key) is supported for this parameter, providing a list of region codes provisioned in your workspace. .PARAMETER WhatIf Shows the raw REST API call that would be made to COM instead of sending the request. This option is useful for understanding the inner workings of the native REST API calls used by COM. .EXAMPLE Test-HPECOMExternalServiceServiceNow -Region eu-central -Name MyServiceNow_Name Generate a test incident for ServiceNow. .EXAMPLE Test-HPECOMExternalServiceServiceNow -Region eu-central | Test-HPECOMExternalService Generate a test incident for ServiceNow. .INPUTS System.Collections.ArrayList List of external service(s) from 'Get-HPECOMExternalService'. .OUTPUTS System.Collections.ArrayList A custom status object or array of objects containing the following PsCustomObject keys: * Name - Name of the external service attempted to be tested * Region - Name of the region where the external services is tested * Status - Status of the testing attempt (Failed for http error return; Complete if testing is successful; Warning if no action is needed) * Details - More information about the status * Exception: Information about any exceptions generated during the operation. #> [CmdletBinding(DefaultParameterSetName = 'Default')] Param( [Parameter (Mandatory, ValueFromPipelineByPropertyName)] [ValidateScript({ if (($_ -in $Global:HPECOMRegions.region)) { $true } else { Throw "The COM region '$_' is not provisioned in this workspace! Please specify a valid region code (e.g., 'us-west', 'eu-central'). `nYou can retrieve the region code using: Get-HPEGLService -Name 'Compute Ops Management' -ShowProvisioned. `nYou can also use the Tab key for auto-completion to see the list of provisioned region codes." } })] [ArgumentCompleter({ param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters) # Filter region based on $Global:HPECOMRegions global variable and create completions $Global:HPECOMRegions.region | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object { [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) } })] [String]$Region, [Parameter (Mandatory, ValueFromPipelineByPropertyName)] [ValidateScript({ $_.Length -lt 256 })] [String]$Name, [Switch]$WhatIf ) Begin { $Caller = (Get-PSCallStack)[1].Command "[{0}] Called from: '{1}'" -f $MyInvocation.InvocationName.ToString().ToUpper(), $Caller | Write-Verbose $TestExternalServiceStatus = [System.Collections.ArrayList]::new() $_Date = Get-Date } Process { "[{0}] Bound PS Parameters: `n{1}" -f $MyInvocation.InvocationName.ToString().ToUpper(), ($PSBoundParameters | out-string) | Write-Verbose try { $ExternalServicesResource = Get-HPECOMExternalService -Region $Region -Name $Name } catch { $PSCmdlet.ThrowTerminatingError($_) } # Build object for the output $objStatus = [pscustomobject]@{ Name = $Name ServiceType = $ExternalServicesResource.ServiceType Region = $Region Status = $Null Details = $Null Exception = $Null } if (-not $ExternalServicesResource) { # Must return a message if not found if ($WhatIf) { $ErrorMessage = "External service '{0}': Resource cannot be found in the '{1}' region!" -f $Name, $Region Write-warning $ErrorMessage return } else { $objStatus.Status = "Failed" $objStatus.Details = "External service cannot be found in the region!" } } else { $ExternalServiceID = $ExternalServicesResource.id $ServiceType = $ExternalServicesResource.ServiceType Switch ($ServiceType) { "SERVICE_NOW" { $ServiceTypeName = "ServiceNow" $ServiceTypeCategory = "External service" $ServiceTypeSourceName = "ServiceNow" } "DSCC" { $ServiceTypeName = "Data Services Cloud Console" $ServiceTypeCategory = "External service" $ServiceTypeSourceName = "Data Services Cloud Console integration" } Default { $ErrorMessage = "External service '{0}': Service type '{1}' is not supported for testing in the '{2}' region!" -f $Name, $ServiceType, $Region Write-warning $ErrorMessage return } } $Uri = (Get-COMExternalServicesUri) + "/" + $ExternalServiceID + "/test" # Generate a test incident try { $Response = Invoke-HPECOMWebRequest -Region $Region -Uri $Uri -method POST -ContentType 'application/json' -Body (@{} | ConvertTo-Json) -WhatIfBoolean $WhatIf -Verbose:$VerbosePreference if (-not $WhatIf) { "[{0}] External service test raw response: `n{1}" -f $MyInvocation.InvocationName.ToString().ToUpper(), $Response | Write-Verbose "[{0}] Test incident '{1}' has been successfully generated for '{2}' in '{3}' region" -f $MyInvocation.InvocationName.ToString().ToUpper(), $name, $ServiceTypeName, $Region | Write-Verbose $objStatus.Status = "Complete" $objStatus.Details = "Test incident has been successfully generated for $ServiceTypeName in $Region region" } } catch { if (-not $WhatIf) { $objStatus.Status = "Failed" $objStatus.Details = "Test incident cannot be generated for $ServiceTypeName" $objStatus.Exception = $Global:HPECOMInvokeReturnData } } } [void] $TestExternalServiceStatus.add($objStatus) } end { if (-not $WhatIf) { if ($TestExternalServiceStatus.Status -notcontains "Failed") { do { $_Activity = Get-HPECOMActivity -Region $Region -SourceName $ServiceTypeSourceName -Category $ServiceTypeCategory | Where-Object { ([datetime]$_.createdAt) -gt $_Date } Start-Sleep 1 } until ($_Activity) $TestExternalServiceStatus = Invoke-RepackageObjectWithType -RawObject $TestExternalServiceStatus -ObjectName "COM.ExternalServices.NSDE" Write-Host $TestExternalServiceStatus.details -ForegroundColor Green Return $_Activity } else { $TestExternalServiceStatus = Invoke-RepackageObjectWithType -RawObject $TestExternalServiceStatus -ObjectName "COM.ExternalServices.NSDE" Return $TestExternalServiceStatus } } } } # Private functions (not exported) function Invoke-RepackageObjectWithType { Param ( $RawObject, $ObjectName, [boolean] $WhatIf = $false ) process { if ( $RawObject ) { $OutputObject = @() if ( $WhatIf ) { Return } foreach ( $RawElementObject in $RawObject ) { # "[{0}] Element: `n{1}" -f $MyInvocation.InvocationName.ToString().ToUpper(), ($RawElementObject | out-string) | write-verbose $DataSetType = "HPEGreenLake.$ObjectName" $RawElementObject.PSTypeNames.Insert(0, $DataSetType) # "[{0}] Element PSTypeName set: `n{1}" -f $MyInvocation.InvocationName.ToString().ToUpper(), ($RawElementObject.PSTypeNames[0] | out-string)| write-verbose # "[{0}] Element PSObject TypeNames set: `n{1}" -f $MyInvocation.InvocationName.ToString().ToUpper(), ($RawElementObject.PSObject.TypeNames[0] | out-string)| write-verbose $RawElementObject.PSObject.TypeNames.Insert(0, $DataSetType) # "[{0}] Element PSObject TypeNames set: `n{1}" -f $MyInvocation.InvocationName.ToString().ToUpper(), ($RawElementObject.PSObject.TypeNames[0] | out-string)| write-verbose $OutputObject += $RawElementObject } # "[{0}] Object typenames : `n{1}" -f $MyInvocation.InvocationName.ToString().ToUpper(), ($OutputObject.PSObject.TypeNames | Out-String) | write-verbose if ($OutputObject.PSObject.TypeNames -notcontains $DataSetType) { # "[{0}] Object typenames added using Add-Member as the object is read only" -f $MyInvocation.InvocationName.ToString().ToUpper() | write-verbose foreach ($item in $OutputObject) { [void]($item | Add-Member -MemberType NoteProperty -Name PSObject.TypeNames -Value @( $DataSetType) -Force) } } return $OutputObject } else { # "[{0}] Null value sent to create object type." -f $MyInvocation.InvocationName.ToString().ToUpper() | Write-Verbose return } } } # Export only public functions and aliases Export-ModuleMember -Function 'Get-HPECOMExternalService', 'New-HPECOMExternalService', 'Remove-HPECOMExternalService', 'Set-HPECOMExternalService', 'Test-HPECOMExternalService' -Alias * # SIG # Begin signature block # MIIungYJKoZIhvcNAQcCoIIujzCCLosCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCD4UW66XdboNI5T # 9xjFKLjR7nGavq/dlyQzxHWE5X2WSKCCEfYwggVvMIIEV6ADAgECAhBI/JO0YFWU # jTanyYqJ1pQWMA0GCSqGSIb3DQEBDAUAMHsxCzAJBgNVBAYTAkdCMRswGQYDVQQI # DBJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoM # EUNvbW9kbyBDQSBMaW1pdGVkMSEwHwYDVQQDDBhBQUEgQ2VydGlmaWNhdGUgU2Vy # dmljZXMwHhcNMjEwNTI1MDAwMDAwWhcNMjgxMjMxMjM1OTU5WjBWMQswCQYDVQQG # EwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMS0wKwYDVQQDEyRTZWN0aWdv # IFB1YmxpYyBDb2RlIFNpZ25pbmcgUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEBAQUA # A4ICDwAwggIKAoICAQCN55QSIgQkdC7/FiMCkoq2rjaFrEfUI5ErPtx94jGgUW+s # hJHjUoq14pbe0IdjJImK/+8Skzt9u7aKvb0Ffyeba2XTpQxpsbxJOZrxbW6q5KCD # J9qaDStQ6Utbs7hkNqR+Sj2pcaths3OzPAsM79szV+W+NDfjlxtd/R8SPYIDdub7 # P2bSlDFp+m2zNKzBenjcklDyZMeqLQSrw2rq4C+np9xu1+j/2iGrQL+57g2extme # me/G3h+pDHazJyCh1rr9gOcB0u/rgimVcI3/uxXP/tEPNqIuTzKQdEZrRzUTdwUz # T2MuuC3hv2WnBGsY2HH6zAjybYmZELGt2z4s5KoYsMYHAXVn3m3pY2MeNn9pib6q # RT5uWl+PoVvLnTCGMOgDs0DGDQ84zWeoU4j6uDBl+m/H5x2xg3RpPqzEaDux5mcz # mrYI4IAFSEDu9oJkRqj1c7AGlfJsZZ+/VVscnFcax3hGfHCqlBuCF6yH6bbJDoEc # QNYWFyn8XJwYK+pF9e+91WdPKF4F7pBMeufG9ND8+s0+MkYTIDaKBOq3qgdGnA2T # OglmmVhcKaO5DKYwODzQRjY1fJy67sPV+Qp2+n4FG0DKkjXp1XrRtX8ArqmQqsV/ # AZwQsRb8zG4Y3G9i/qZQp7h7uJ0VP/4gDHXIIloTlRmQAOka1cKG8eOO7F/05QID # AQABo4IBEjCCAQ4wHwYDVR0jBBgwFoAUoBEKIz6W8Qfs4q8p74Klf9AwpLQwHQYD # VR0OBBYEFDLrkpr/NZZILyhAQnAgNpFcF4XmMA4GA1UdDwEB/wQEAwIBhjAPBgNV # HRMBAf8EBTADAQH/MBMGA1UdJQQMMAoGCCsGAQUFBwMDMBsGA1UdIAQUMBIwBgYE # VR0gADAIBgZngQwBBAEwQwYDVR0fBDwwOjA4oDagNIYyaHR0cDovL2NybC5jb21v # ZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNAYIKwYBBQUHAQEE # KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5jb21vZG9jYS5jb20wDQYJKoZI # hvcNAQEMBQADggEBABK/oe+LdJqYRLhpRrWrJAoMpIpnuDqBv0WKfVIHqI0fTiGF # OaNrXi0ghr8QuK55O1PNtPvYRL4G2VxjZ9RAFodEhnIq1jIV9RKDwvnhXRFAZ/ZC # J3LFI+ICOBpMIOLbAffNRk8monxmwFE2tokCVMf8WPtsAO7+mKYulaEMUykfb9gZ # pk+e96wJ6l2CxouvgKe9gUhShDHaMuwV5KZMPWw5c9QLhTkg4IUaaOGnSDip0TYl # d8GNGRbFiExmfS9jzpjoad+sPKhdnckcW67Y8y90z7h+9teDnRGWYpquRRPaf9xH # +9/DUp/mBlXpnYzyOmJRvOwkDynUWICE5EV7WtgwggYaMIIEAqADAgECAhBiHW0M # UgGeO5B5FSCJIRwKMA0GCSqGSIb3DQEBDAUAMFYxCzAJBgNVBAYTAkdCMRgwFgYD # VQQKEw9TZWN0aWdvIExpbWl0ZWQxLTArBgNVBAMTJFNlY3RpZ28gUHVibGljIENv # ZGUgU2lnbmluZyBSb290IFI0NjAeFw0yMTAzMjIwMDAwMDBaFw0zNjAzMjEyMzU5 # NTlaMFQxCzAJBgNVBAYTAkdCMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxKzAp # BgNVBAMTIlNlY3RpZ28gUHVibGljIENvZGUgU2lnbmluZyBDQSBSMzYwggGiMA0G # CSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQCbK51T+jU/jmAGQ2rAz/V/9shTUxjI # ztNsfvxYB5UXeWUzCxEeAEZGbEN4QMgCsJLZUKhWThj/yPqy0iSZhXkZ6Pg2A2NV # DgFigOMYzB2OKhdqfWGVoYW3haT29PSTahYkwmMv0b/83nbeECbiMXhSOtbam+/3 # 6F09fy1tsB8je/RV0mIk8XL/tfCK6cPuYHE215wzrK0h1SWHTxPbPuYkRdkP05Zw # mRmTnAO5/arnY83jeNzhP06ShdnRqtZlV59+8yv+KIhE5ILMqgOZYAENHNX9SJDm # +qxp4VqpB3MV/h53yl41aHU5pledi9lCBbH9JeIkNFICiVHNkRmq4TpxtwfvjsUe # dyz8rNyfQJy/aOs5b4s+ac7IH60B+Ja7TVM+EKv1WuTGwcLmoU3FpOFMbmPj8pz4 # 4MPZ1f9+YEQIQty/NQd/2yGgW+ufflcZ/ZE9o1M7a5Jnqf2i2/uMSWymR8r2oQBM # dlyh2n5HirY4jKnFH/9gRvd+QOfdRrJZb1sCAwEAAaOCAWQwggFgMB8GA1UdIwQY # MBaAFDLrkpr/NZZILyhAQnAgNpFcF4XmMB0GA1UdDgQWBBQPKssghyi47G9IritU # pimqF6TNDDAOBgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADATBgNV # HSUEDDAKBggrBgEFBQcDAzAbBgNVHSAEFDASMAYGBFUdIAAwCAYGZ4EMAQQBMEsG # A1UdHwREMEIwQKA+oDyGOmh0dHA6Ly9jcmwuc2VjdGlnby5jb20vU2VjdGlnb1B1 # YmxpY0NvZGVTaWduaW5nUm9vdFI0Ni5jcmwwewYIKwYBBQUHAQEEbzBtMEYGCCsG # AQUFBzAChjpodHRwOi8vY3J0LnNlY3RpZ28uY29tL1NlY3RpZ29QdWJsaWNDb2Rl # U2lnbmluZ1Jvb3RSNDYucDdjMCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5zZWN0 # aWdvLmNvbTANBgkqhkiG9w0BAQwFAAOCAgEABv+C4XdjNm57oRUgmxP/BP6YdURh # w1aVcdGRP4Wh60BAscjW4HL9hcpkOTz5jUug2oeunbYAowbFC2AKK+cMcXIBD0Zd # OaWTsyNyBBsMLHqafvIhrCymlaS98+QpoBCyKppP0OcxYEdU0hpsaqBBIZOtBajj # cw5+w/KeFvPYfLF/ldYpmlG+vd0xqlqd099iChnyIMvY5HexjO2AmtsbpVn0OhNc # WbWDRF/3sBp6fWXhz7DcML4iTAWS+MVXeNLj1lJziVKEoroGs9Mlizg0bUMbOalO # hOfCipnx8CaLZeVme5yELg09Jlo8BMe80jO37PU8ejfkP9/uPak7VLwELKxAMcJs # zkyeiaerlphwoKx1uHRzNyE6bxuSKcutisqmKL5OTunAvtONEoteSiabkPVSZ2z7 # 6mKnzAfZxCl/3dq3dUNw4rg3sTCggkHSRqTqlLMS7gjrhTqBmzu1L90Y1KWN/Y5J # KdGvspbOrTfOXyXvmPL6E52z1NZJ6ctuMFBQZH3pwWvqURR8AgQdULUvrxjUYbHH # j95Ejza63zdrEcxWLDX6xWls/GDnVNueKjWUH3fTv1Y8Wdho698YADR7TNx8X8z2 # Bev6SivBBOHY+uqiirZtg0y9ShQoPzmCcn63Syatatvx157YK9hlcPmVoa1oDE5/ # L9Uo2bC5a4CH2RwwggZhMIIEyaADAgECAhEAyDHh+zCQwUNyJV9S6gqqvTANBgkq # hkiG9w0BAQwFADBUMQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1p # dGVkMSswKQYDVQQDEyJTZWN0aWdvIFB1YmxpYyBDb2RlIFNpZ25pbmcgQ0EgUjM2 # MB4XDTI1MDUyMDAwMDAwMFoXDTI4MDUxOTIzNTk1OVowdzELMAkGA1UEBhMCVVMx # DjAMBgNVBAgMBVRleGFzMSswKQYDVQQKDCJIZXdsZXR0IFBhY2thcmQgRW50ZXJw # cmlzZSBDb21wYW55MSswKQYDVQQDDCJIZXdsZXR0IFBhY2thcmQgRW50ZXJwcmlz # ZSBDb21wYW55MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA37AD03qw # cmuCQyxRB2VBM7SfUf0SmpQb8iaPvGmxw5uoDBY3gdC/3Xq/rfM3ndCn03hNdGyu # cpC7tD4zmel6yYqxyXDVr45Jd2cz9jFXoYTOMcuDV6I6CvU/EnbFxWhv0VCp+2Ip # z4+uJGI6aVlMpFpLbgPjhp9ogd/89HEyi1FkSFoarnvxxaXm93S81k7FD/4Edtvu # muGI4V8p39GfbCiMuHku8BzSQ2g86gWFnOaVhY6h4XWvEmE8LPYkU/STrej28Flg # kSt9f/Jg6+dvRKm92uN2Z760Eql9+DTWkGmGe4YrIyD25XDa07sS9tIpVWzLrGOy # ecaVpJwVVBqCadXDgkgTYKw/UlS+cEqsviT6wREGl4aX/GbeNO6Y4oDTTYkabW3p # eg1ku0v90oDqzoTaWEE5ly2UajvXIgzpFLLXqpR6GYkv/y3ZJV0chBqRtAObebH7 # XOBa5a2kqMBw0gkIZBJHd8+PCPH/U7eJkeKXtGGj2uTudcGjZgOjVcFYdCRnufJd # isrV7bj0Hzghcv3QyRXL3rRjcNb4ccKNnSgF/8cmiTVpvFHTfUKsYdkbM6wsbjXR # dJNADjGOYRms7tKsii3/oXO+2S1Um7yomBZQ2+wVRCY6MrRX1onDKid5t5AyWFtR # u0aQcdBmHG6JeDiQ3Hrb2g9kZhuFkgABVBkCAwEAAaOCAYkwggGFMB8GA1UdIwQY # MBaAFA8qyyCHKLjsb0iuK1SmKaoXpM0MMB0GA1UdDgQWBBQH4rUE0gsy8LW2G3vm # oYtOnZ8zEjAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH/BAIwADATBgNVHSUEDDAK # BggrBgEFBQcDAzBKBgNVHSAEQzBBMDUGDCsGAQQBsjEBAgEDAjAlMCMGCCsGAQUF # BwIBFhdodHRwczovL3NlY3RpZ28uY29tL0NQUzAIBgZngQwBBAEwSQYDVR0fBEIw # QDA+oDygOoY4aHR0cDovL2NybC5zZWN0aWdvLmNvbS9TZWN0aWdvUHVibGljQ29k # ZVNpZ25pbmdDQVIzNi5jcmwweQYIKwYBBQUHAQEEbTBrMEQGCCsGAQUFBzAChjho # dHRwOi8vY3J0LnNlY3RpZ28uY29tL1NlY3RpZ29QdWJsaWNDb2RlU2lnbmluZ0NB # UjM2LmNydDAjBggrBgEFBQcwAYYXaHR0cDovL29jc3Auc2VjdGlnby5jb20wDQYJ # KoZIhvcNAQEMBQADggGBAIax+Yaj5EciDlztft4iAfD2CtIWEF0cxR+UbbvJEs86 # 5wyoO3ZQoujr0FJ+P5fjDKLbamHrEWmyoD2YC4lzecmnFOnY0y4uJ9zBY8B6X6TU # 9e6+TfZtlXd44YffXYAfoLX+uYjVJcZOaMuXF61+CFpjLJjepsD8m1gdj5QUz2sH # 6GOfU6mEm8SHvKpgPMV/yhEKqgjlenY6Ao49RkxnDuvRlMP8SFPB+8bxiLegEdGa # ei8nSr/j5YeDZFevUJ696T4W45QGrwAhBBpbKDz6CzlImC1b2C8Bp02XBAsOQs/u # CIaQv5XxUmVxmb85tDJkd7QfqHo2z1T2NYMkvXUcSClYRuVxxC/frpqcrxS9O9xE # v65BoUztAJSXsTdfpUjWeNOnhq8lrwa2XAD3fbagNF6ElsBiNDSbwHCG/iY4kAya # VpbAYtaa6TfzdI/I0EaCX5xYRW56ccI2AnbaEVKz9gVjzi8hBLALlRhrs1uMFtPj # nZ+oA+rbZZyGZkz3xbUYKTGCG/4wghv6AgEBMGkwVDELMAkGA1UEBhMCR0IxGDAW # BgNVBAoTD1NlY3RpZ28gTGltaXRlZDErMCkGA1UEAxMiU2VjdGlnbyBQdWJsaWMg # Q29kZSBTaWduaW5nIENBIFIzNgIRAMgx4fswkMFDciVfUuoKqr0wDQYJYIZIAWUD # BAIBBQCgfDAQBgorBgEEAYI3AgEMMQIwADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGC # NwIBBDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQx # IgQgCS05deP6YZtbYE7t6g5ef7E9Pol9zmZzJynIG2evCn8wDQYJKoZIhvcNAQEB # BQAEggIAxCDCXgZIQcxFrjMziotxCnUkitEbcWRnkTcEP1+LqgoZC/VQGLskBDpV # QHmWBKIMJ4u/3PGMwNYMzMXNl3ipNgejckVL3QP0CceAgKFukOvZ6lPAAOvM8DgV # 6U4yVTkdQJfoDrAceC63kLJCx4d0wPqybGwQOqQOcH2H405P1XDEDys040v+yV0X # k/R0ejiO+jiJMAju3/bttb/JoVPsBKNvEtRfrp50fTlCgE/z287ogwVgXFVNvV5L # yA4ccP5U/6ffsHs1HhiICpq6oNZ5LAFmLfYwoj/7EfuQfLCI9ER6PtxqN6Fi05qH # ZVTPRVVfI8Gaq8YTClBPg3EaPLnznt7z6N8Oc1viYmagWs41mY4ir6nPyQ/sFciJ # lzJsioA4Z0tfGI8nW5dHbaP5rwbIYXoFJcxlA8PU19omSGEPC4FhiAXgMPLVt3JB # IXLs3ZVI4Lf9x5FmGeNBIaksphxF4ZbFa5jEZz5UGSkeC2khJFagiYgrGKWm99yy # x/lqAmlQnzDxVTsmPHoWiidTplX75TuykfDYdQAUrxRqfXqgr74j44OoBER5wpQv # nieUV5dr+DloEA8lYd4bWage+1WlkxR0XmPzT7ZuOrk/BXULX+SZ9AMVZIHU3U/7 # f+OrJhm03ZFXMQfc7PzBdmUztoVJfCY3dciumSphqiH2088c4OKhghjoMIIY5AYK # KwYBBAGCNwMDATGCGNQwghjQBgkqhkiG9w0BBwKgghjBMIIYvQIBAzEPMA0GCWCG # SAFlAwQCAgUAMIIBBwYLKoZIhvcNAQkQAQSggfcEgfQwgfECAQEGCisGAQQBsjEC # AQEwQTANBglghkgBZQMEAgIFAAQw20nFR5yYCIOYHduO1SE0ZdGBt1uvmGED998h # bY3/2sgKo5d7VdtG3XEEcAcblYBhAhQwndBr+wPQpzB9wkHuavzW4RSibhgPMjAy # NTEwMDIxNTQ0MjlaoHakdDByMQswCQYDVQQGEwJHQjEXMBUGA1UECBMOV2VzdCBZ # b3Jrc2hpcmUxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDEwMC4GA1UEAxMnU2Vj # dGlnbyBQdWJsaWMgVGltZSBTdGFtcGluZyBTaWduZXIgUjM2oIITBDCCBmIwggTK # oAMCAQICEQCkKTtuHt3XpzQIh616TrckMA0GCSqGSIb3DQEBDAUAMFUxCzAJBgNV # BAYTAkdCMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxLDAqBgNVBAMTI1NlY3Rp # Z28gUHVibGljIFRpbWUgU3RhbXBpbmcgQ0EgUjM2MB4XDTI1MDMyNzAwMDAwMFoX # DTM2MDMyMTIzNTk1OVowcjELMAkGA1UEBhMCR0IxFzAVBgNVBAgTDldlc3QgWW9y # a3NoaXJlMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxMDAuBgNVBAMTJ1NlY3Rp # Z28gUHVibGljIFRpbWUgU3RhbXBpbmcgU2lnbmVyIFIzNjCCAiIwDQYJKoZIhvcN # AQEBBQADggIPADCCAgoCggIBANOElfRupFN48j0QS3gSBzzclIFTZ2Gsn7BjsmBF # 659/kpA2Ey7NXK3MP6JdrMBNU8wdmkf+SSIyjX++UAYWtg3Y/uDRDyg8RxHeHRJ+ # 0U1jHEyH5uPdk1ttiPC3x/gOxIc9P7Gn3OgW7DQc4x07exZ4DX4XyaGDq5LoEmk/ # BdCM1IelVMKB3WA6YpZ/XYdJ9JueOXeQObSQ/dohQCGyh0FhmwkDWKZaqQBWrBwZ # ++zqlt+z/QYTgEnZo6dyIo2IhXXANFkCHutL8765NBxvolXMFWY8/reTnFxk3Maj # gM5NX6wzWdWsPJxYRhLxtJLSUJJ5yWRNw+NBqH1ezvFs4GgJ2ZqFJ+Dwqbx9+rw+ # F2gBdgo4j7CVomP49sS7CbqsdybbiOGpB9DJhs5QVMpYV73TVV3IwLiBHBECrTgU # fZVOMF0KSEq2zk/LsfvehswavE3W4aBXJmGjgWSpcDz+6TqeTM8f1DIcgQPdz0IY # gnT3yFTgiDbFGOFNt6eCidxdR6j9x+kpcN5RwApy4pRhE10YOV/xafBvKpRuWPjO # PWRBlKdm53kS2aMh08spx7xSEqXn4QQldCnUWRz3Lki+TgBlpwYwJUbR77DAayNw # AANE7taBrz2v+MnnogMrvvct0iwvfIA1W8kp155Lo44SIfqGmrbJP6Mn+Udr3MR2 # oWozAgMBAAGjggGOMIIBijAfBgNVHSMEGDAWgBRfWO1MMXqiYUKNUoC6s2GXGaIy # mzAdBgNVHQ4EFgQUiGGMoSo3ZIEoYKGbMdCM/SwCzk8wDgYDVR0PAQH/BAQDAgbA # MAwGA1UdEwEB/wQCMAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwSgYDVR0gBEMw # QTA1BgwrBgEEAbIxAQIBAwgwJTAjBggrBgEFBQcCARYXaHR0cHM6Ly9zZWN0aWdv # LmNvbS9DUFMwCAYGZ4EMAQQCMEoGA1UdHwRDMEEwP6A9oDuGOWh0dHA6Ly9jcmwu # c2VjdGlnby5jb20vU2VjdGlnb1B1YmxpY1RpbWVTdGFtcGluZ0NBUjM2LmNybDB6 # BggrBgEFBQcBAQRuMGwwRQYIKwYBBQUHMAKGOWh0dHA6Ly9jcnQuc2VjdGlnby5j # b20vU2VjdGlnb1B1YmxpY1RpbWVTdGFtcGluZ0NBUjM2LmNydDAjBggrBgEFBQcw # AYYXaHR0cDovL29jc3Auc2VjdGlnby5jb20wDQYJKoZIhvcNAQEMBQADggGBAAKB # PqSGclEh+WWpLj1SiuHlm8xLE0SThI2yLuq+75s11y6SceBchpnKpxWaGtXc8dya # 1Aq3RuW//y3wMThsvT4fSba2AoSWlR67rA4fTYGMIhgzocsids0ct/pHaocLVJSw # nTYxY2pE0hPoZAvRebctbsTqENmZHyOVjOFlwN2R3DRweFeNs4uyZN5LRJ5EnVYl # cTOq3bl1tI5poru9WaQRWQ4eynXp7Pj0Fz4DKr86HYECRJMWiDjeV0QqAcQMFsIj # JtrYTw7mU81qf4FBc4u4swphLeKRNyn9DDrd3HIMJ+CpdhSHEGleeZ5I79YDg3B3 # A/fmVY2GaMik1Vm+FajEMv4/EN2mmHf4zkOuhYZNzVm4NrWJeY4UAriLBOeVYODd # A1GxFr1ycbcUEGlUecc4RCPgYySs4d00NNuicR4a9n7idJlevAJbha/arIYMEuUq # TeRRbWkhJwMKmb9yEvppRudKyu1t6l21sIuIZqcpVH8oLWCxHS0LpDRF9Y4jijCC # BhQwggP8oAMCAQICEHojrtpTaZYPkcg+XPTH4z8wDQYJKoZIhvcNAQEMBQAwVzEL # MAkGA1UEBhMCR0IxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDEuMCwGA1UEAxMl # U2VjdGlnbyBQdWJsaWMgVGltZSBTdGFtcGluZyBSb290IFI0NjAeFw0yMTAzMjIw # MDAwMDBaFw0zNjAzMjEyMzU5NTlaMFUxCzAJBgNVBAYTAkdCMRgwFgYDVQQKEw9T # ZWN0aWdvIExpbWl0ZWQxLDAqBgNVBAMTI1NlY3RpZ28gUHVibGljIFRpbWUgU3Rh # bXBpbmcgQ0EgUjM2MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAzZjY # Q0GrboIr7PYzfiY05ImM0+8iEoBUPu8mr4wOgYPjoiIz5vzf7d5wu8GFK1JWN5hc # iN9rdqOhbdxLcSVwnOTJmUGfAMQm4eXOls3iQwfapEFWuOsYmBKXPNSpwZAFoLGl # 5y1EaGGc5LByM8wjcbSF52/Z42YaJRsPXY545E3QAPN2mxDh0OLozhiGgYT1xtjX # VfEzYBVmfQaI5QL35cTTAjsJAp85R+KAsOfuL9Z7LFnjdcuPkZWjssMETFIueH69 # rxbFOUD64G+rUo7xFIdRAuDNvWBsv0iGDPGaR2nZlY24tz5fISYk1sPY4gir99aX # AGnoo0vX3Okew4MsiyBn5ZnUDMKzUcQrpVavGacrIkmDYu/bcOUR1mVBIZ0X7P4b # Kf38JF7Mp7tY3LFF/h7hvBS2tgTYXlD7TnIMPrxyXCfB5yQq3FFoXRXM3/DvqQ4s # hoVWF/mwwz9xoRku05iphp22fTfjKRIVpm4gFT24JKspEpM8mFa9eTgKWWCvAgMB # AAGjggFcMIIBWDAfBgNVHSMEGDAWgBT2d2rdP/0BE/8WoWyCAi/QCj0UJTAdBgNV # HQ4EFgQUX1jtTDF6omFCjVKAurNhlxmiMpswDgYDVR0PAQH/BAQDAgGGMBIGA1Ud # EwEB/wQIMAYBAf8CAQAwEwYDVR0lBAwwCgYIKwYBBQUHAwgwEQYDVR0gBAowCDAG # BgRVHSAAMEwGA1UdHwRFMEMwQaA/oD2GO2h0dHA6Ly9jcmwuc2VjdGlnby5jb20v # U2VjdGlnb1B1YmxpY1RpbWVTdGFtcGluZ1Jvb3RSNDYuY3JsMHwGCCsGAQUFBwEB # BHAwbjBHBggrBgEFBQcwAoY7aHR0cDovL2NydC5zZWN0aWdvLmNvbS9TZWN0aWdv # UHVibGljVGltZVN0YW1waW5nUm9vdFI0Ni5wN2MwIwYIKwYBBQUHMAGGF2h0dHA6 # Ly9vY3NwLnNlY3RpZ28uY29tMA0GCSqGSIb3DQEBDAUAA4ICAQAS13sgrQ41WAye # gR0lWP1MLWd0r8diJiH2VVRpxqFGhnZbaF+IQ7JATGceTWOS+kgnMAzGYRzpm8jI # cjlSQ8JtcqymKhgx1s6cFZBSfvfeoyigF8iCGlH+SVSo3HHr98NepjSFJTU5KSRK # K+3nVSWYkSVQgJlgGh3MPcz9IWN4I/n1qfDGzqHCPWZ+/Mb5vVyhgaeqxLPbBIqv # 6cM74Nvyo1xNsllECJJrOvsrJQkajVz4xJwZ8blAdX5umzwFfk7K/0K3fpjgiXpq # NOpXaJ+KSRW0HdE0FSDC7+ZKJJSJx78mn+rwEyT+A3z7Ss0gT5CpTrcmhUwIw9jb # vnYuYRKxFVWjKklW3z83epDVzoWJttxFpujdrNmRwh1YZVIB2guAAjEQoF42H0BA # 7WBCueHVMDyV1e4nM9K4As7PVSNvQ8LI1WRaTuGSFUd9y8F8jw22BZC6mJoB40d7 # SlZIYfaildlgpgbgtu6SDsek2L8qomG57Yp5qTqof0DwJ4Q4HsShvRl/59T4IJBo # vRwmqWafH0cIPEX7cEttS5+tXrgRtMjjTOp6A9l0D6xcKZtxnLqiTH9KPCy6xZEi # 0UDcMTww5Fl4VvoGbMG2oonuX3f1tsoHLaO/Fwkj3xVr3lDkmeUqivebQTvGkx5h # GuJaSVQ+x60xJ/Y29RBr8Tm9XJ59AjCCBoIwggRqoAMCAQICEDbCsL18Gzrno7Pd # NsvJdWgwDQYJKoZIhvcNAQEMBQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpO # ZXcgSmVyc2V5MRQwEgYDVQQHEwtKZXJzZXkgQ2l0eTEeMBwGA1UEChMVVGhlIFVT # RVJUUlVTVCBOZXR3b3JrMS4wLAYDVQQDEyVVU0VSVHJ1c3QgUlNBIENlcnRpZmlj # YXRpb24gQXV0aG9yaXR5MB4XDTIxMDMyMjAwMDAwMFoXDTM4MDExODIzNTk1OVow # VzELMAkGA1UEBhMCR0IxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDEuMCwGA1UE # AxMlU2VjdGlnbyBQdWJsaWMgVGltZSBTdGFtcGluZyBSb290IFI0NjCCAiIwDQYJ # KoZIhvcNAQEBBQADggIPADCCAgoCggIBAIid2LlFZ50d3ei5JoGaVFTAfEkFm8xa # FQ/ZlBBEtEFAgXcUmanU5HYsyAhTXiDQkiUvpVdYqZ1uYoZEMgtHES1l1Cc6HaqZ # zEbOOp6YiTx63ywTon434aXVydmhx7Dx4IBrAou7hNGsKioIBPy5GMN7KmgYmuu4 # f92sKKjbxqohUSfjk1mJlAjthgF7Hjx4vvyVDQGsd5KarLW5d73E3ThobSkob2SL # 48LpUR/O627pDchxll+bTSv1gASn/hp6IuHJorEu6EopoB1CNFp/+HpTXeNARXUm # dRMKbnXWflq+/g36NJXB35ZvxQw6zid61qmrlD/IbKJA6COw/8lFSPQwBP1ityZd # wuCysCKZ9ZjczMqbUcLFyq6KdOpuzVDR3ZUwxDKL1wCAxgL2Mpz7eZbrb/JWXiOc # NzDpQsmwGQ6Stw8tTCqPumhLRPb7YkzM8/6NnWH3T9ClmcGSF22LEyJYNWCHrQqY # ubNeKolzqUbCqhSqmr/UdUeb49zYHr7ALL8bAJyPDmubNqMtuaobKASBqP84uhqc # RY/pjnYd+V5/dcu9ieERjiRKKsxCG1t6tG9oj7liwPddXEcYGOUiWLm742st50jG # wTzxbMpepmOP1mLnJskvZaN5e45NuzAHteORlsSuDt5t4BBRCJL+5EZnnw0ezntk # 9R8QJyAkL6/bAgMBAAGjggEWMIIBEjAfBgNVHSMEGDAWgBRTeb9aqitKz1SA4dib # wJ3ysgNmyzAdBgNVHQ4EFgQU9ndq3T/9ARP/FqFsggIv0Ao9FCUwDgYDVR0PAQH/ # BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wEwYDVR0lBAwwCgYIKwYBBQUHAwgwEQYD # VR0gBAowCDAGBgRVHSAAMFAGA1UdHwRJMEcwRaBDoEGGP2h0dHA6Ly9jcmwudXNl # cnRydXN0LmNvbS9VU0VSVHJ1c3RSU0FDZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNy # bDA1BggrBgEFBQcBAQQpMCcwJQYIKwYBBQUHMAGGGWh0dHA6Ly9vY3NwLnVzZXJ0 # cnVzdC5jb20wDQYJKoZIhvcNAQEMBQADggIBAA6+ZUHtaES45aHF1BGH5Lc7JYzr # ftrIF5Ht2PFDxKKFOct/awAEWgHQMVHol9ZLSyd/pYMbaC0IZ+XBW9xhdkkmUV/K # bUOiL7g98M/yzRyqUOZ1/IY7Ay0YbMniIibJrPcgFp73WDnRDKtVutShPSZQZAdt # FwXnuiWl8eFARK3PmLqEm9UsVX+55DbVIz33Mbhba0HUTEYv3yJ1fwKGxPBsP/Mg # TECimh7eXomvMm0/GPxX2uhwCcs/YLxDnBdVVlxvDjHjO1cuwbOpkiJGHmLXXVNb # sdXUC2xBrq9fLrfe8IBsA4hopwsCj8hTuwKXJlSTrZcPRVSccP5i9U28gZ7OMzoJ # GlxZ5384OKm0r568Mo9TYrqzKeKZgFo0fj2/0iHbj55hc20jfxvK3mQi+H7xpbzx # ZOFGm/yVQkpo+ffv5gdhp+hv1GDsvJOtJinJmgGbBFZIThbqI+MHvAmMmkfb3fTx # mSkop2mSJL1Y2x/955S29Gu0gSJIkc3z30vU/iXrMpWx2tS7UVfVP+5tKuzGtgkP # 7d/doqDrLF1u6Ci3TpjAZdeLLlRQZm867eVeXED58LXd1Dk6UvaAhvmWYXoiLz4J # A5gPBcz7J311uahxCweNxE+xxxR3kT0WKzASo5G/PyDez6NHdIUKBeE3jDPs2ACc # 6CkJ1Sji4PKWVT0/MYIEkjCCBI4CAQEwajBVMQswCQYDVQQGEwJHQjEYMBYGA1UE # ChMPU2VjdGlnbyBMaW1pdGVkMSwwKgYDVQQDEyNTZWN0aWdvIFB1YmxpYyBUaW1l # IFN0YW1waW5nIENBIFIzNgIRAKQpO24e3denNAiHrXpOtyQwDQYJYIZIAWUDBAIC # BQCgggH5MBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAcBgkqhkiG9w0BCQUx # DxcNMjUxMDAyMTU0NDI5WjA/BgkqhkiG9w0BCQQxMgQwrHdERCWyIb5xij39Ljkq # SLiWl5TgorfF92oVkPD9KwHLF7732erK/DFHWA4ujasEMIIBegYLKoZIhvcNAQkQ # AgwxggFpMIIBZTCCAWEwFgQUOMkUgRBEtNxmPpPUdEuBQYaptbEwgYcEFMauVOR4 # hvF8PVUSSIxpw0p6+cLdMG8wW6RZMFcxCzAJBgNVBAYTAkdCMRgwFgYDVQQKEw9T # ZWN0aWdvIExpbWl0ZWQxLjAsBgNVBAMTJVNlY3RpZ28gUHVibGljIFRpbWUgU3Rh # bXBpbmcgUm9vdCBSNDYCEHojrtpTaZYPkcg+XPTH4z8wgbwEFIU9Yy2TgoJhfNCQ # NcSR3pLBQtrHMIGjMIGOpIGLMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMKTmV3 # IEplcnNleTEUMBIGA1UEBxMLSmVyc2V5IENpdHkxHjAcBgNVBAoTFVRoZSBVU0VS # VFJVU1QgTmV0d29yazEuMCwGA1UEAxMlVVNFUlRydXN0IFJTQSBDZXJ0aWZpY2F0 # aW9uIEF1dGhvcml0eQIQNsKwvXwbOuejs902y8l1aDANBgkqhkiG9w0BAQEFAASC # AgAnk4p+TV1FwsjnF5uIdhLHESsKMC6EqzjchnXb57Nu/RPIuE+hUOvRSN+pO1A+ # D4Er40cTtojUeNhad3EkOPcV7UJyHKNxqBUyzTKBrR/zgO+a+FRsze+6zn4dceut # id5A/N4/Sq5hdXexzibm0LNWRuGJaAbML5Z7o9EXs5ZcbFREfW80VD4Ic3XsbZ9Z # XB72HPmvMkzAxm1t7X6CS272gxIbDFt3j4YT3rNiO/eKjoew8GNrYOz+nabBgO6c # m7oHriuiAC4LOFk9aFDpQff1KXpx95xTlKK4W2tQ3gvC/iZ2EVlPOIkIrjAqu2Zm # hZ7EwAlDVI6Hn/t5R7FmTwGu5hLjvfLS17geZIUxHX9xwsXp5kje5oyCn/Ng+5hm # XAlPd9s98FcZoKx9GdmJwmbWzpI8bjvtolMNGSQwQYpYi3Npf5H+LpiSGyHDQviB # emzOsjyUVBU1EeIy4cohIuxZPRVhcBN8tzVVAO9VcmdOa6Fvv/KKKsHPWvFBcZPY # AO00xcegkrjSpRrrFVrPtNddaBJIqzbQsvuJCs5xqqq0SZikws8kV05VvPBuv9R2 # SjJxpqMVNrYEwwyt1EHkyKxdcKiyBrpT0xJPKmZ1eglhovqHqM71suKcyqAgs/he # VH4GOUANZHOHOCpkUPjnfeWmivQQYZzmJeFbYxJiQObjpA== # SIG # End signature block |