PagerDutyEventV2.psm1
New-Variable -Name PagerDutyAlertEndpoint -Value ($Env:PD_ALERT_URI ?? "https://events.pagerduty.com/v2/enqueue") -Option ReadOnly New-Variable -Name PagerDutyChangeEndpoint -Value ($Env:PD_CHANGE_URI ?? "https://events.pagerduty.com/v2/change/enqueue") -Option ReadOnly New-Variable -Name ContentType -Value "application/json" -Option ReadOnly New-Variable -Name DummyResult -Value ([PSCustomObject]@{ StatusCode = -1; Status = "RequestNotSend"; Error = "RequestNotSend"; Message = "RequestNotSend"; DeduplicationKey = "RequestNotSend" }) -Option ReadOnly function New-PagerDutyAlert { [CmdletBinding(SupportsShouldProcess)] param ( # This is the 32 character Integration Key for an integration on a service or on a global ruleset. [Parameter(Mandatory = $true, Position = 0)] [ValidateLength(32, 32)] [string] $RoutingKey, # Deduplication key for correlating triggers and resolves. The maximum permitted length of this property is 255 characters. [Parameter()] [string] $DeduplicationKey, # A brief text summary of the event, used to generate the summaries/titles of any associated alerts. The maximum permitted length of this property is 1024 characters. [Parameter(Mandatory = $true, Position = 1)] [ValidateLength(1, 1024)] [string] $Summary, # The unique location of the affected system, preferably a hostname or FQDN. [Parameter(Mandatory = $true, Position = 2)] [string] $Source, # The perceived severity of the status the event is describing with respect to the affected system. This can be Critical, Error, Warning or Info. [Parameter(Mandatory = $true, Position = 3)] [ValidateSet("Critical", "Error", "Warning", "Info")] $Severity, # The time at which the emitting tool detected or generated the event. [Parameter()] [datetime] $Timestamp, # Component of the source machine that is responsible for the event, for example mysql or eth0. [Parameter()] [string] $Component, # Logical grouping of components of a service, for example app-stack. [Parameter()] [string] $Group, # The class/type of the event, for example ping failure or cpu load. [Parameter()] [string] $Class, # Additional details about the event and affected system. [Parameter()] [hashtable] $CustomDetails, # List of images to include. [Parameter()] [hashtable[]] $Images, # List of links to include. [Parameter()] [hashtable[]] $Links ) begin { } process { # Validate image and link objects. if ($Images) { foreach ($image in $Images) { validateImageObject $image } } if ($Links) { foreach ($link in $Links) { validateLinkObject $link } } # Prepare object. [pscustomobject]$object = [PSCustomObject]@{ routing_key = $RoutingKey event_action = "trigger" dedup_key = $DeduplicationKey payload = [PSCustomObject]@{ summary = $Summary source = $Source severity = $Severity.ToLower() timestamp = $Timestamp ?? (Get-Date -Format "o") component = $Component group = $Group class = $Class custom_details = $CustomDetails } } if ($Images) { Add-Member -InputObject $object -NotePropertyName 'images' -NotePropertyValue (prepareImages $Images) } if ($Links) { Add-Member -InputObject $object -NotePropertyName 'links' -NotePropertyValue (prepareLinks $Links) } if ($PSCmdlet.ShouldProcess($Source, "New-PagerDutyAlert")) { # Invoke Event API $result = invokeEventApi -InputObject $object -Uri $PagerDutyAlertEndpoint; } else { $result = $DummyResult.PSObject.Copy() } Write-Output $result } end { } } function Confirm-PagerDutyAlert { [CmdletBinding(SupportsShouldProcess)] param ( # This is the 32 character Integration Key for an integration on a service or on a global ruleset. [Parameter(Mandatory = $true, Position = 0)] [ValidateLength(32, 32)] [string] $RoutingKey, # Deduplication key for correlating triggers and resolves. The maximum permitted length of this property is 255 characters. [Parameter(Mandatory = $true, Position = 1)] [string] $DeduplicationKey ) begin { } process { # Prepare object. [pscustomobject]$object = [PSCustomObject]@{ routing_key = $RoutingKey event_action = "acknowledge" dedup_key = $DeduplicationKey } if ($PSCmdlet.ShouldProcess($DeduplicationKey, "Confirm-PagerDutyAlert")) { # Invoke Event API $result = invokeEventApi -InputObject $object -Uri $PagerDutyAlertEndpoint; } else { $result = $DummyResult.PSObject.Copy() } Write-Output $result } end { } } function Resolve-PagerDutyAlert { [CmdletBinding(SupportsShouldProcess)] param ( # This is the 32 character Integration Key for an integration on a service or on a global ruleset. [Parameter(Mandatory = $true, Position = 0)] [ValidateLength(32, 32)] [string] $RoutingKey, # Deduplication key for correlating triggers and resolves. The maximum permitted length of this property is 255 characters. [Parameter(Mandatory = $true, Position = 1)] [string] $DeduplicationKey ) begin { } process { # Prepare object. [pscustomobject]$object = [PSCustomObject]@{ routing_key = $RoutingKey event_action = "resolve" dedup_key = $DeduplicationKey } if ($PSCmdlet.ShouldProcess($DeduplicationKey, "Resolve-PagerDutyAlert")) { # Invoke Event API $result = invokeEventApi -InputObject $object -Uri $PagerDutyAlertEndpoint; } else { $result = $DummyResult.PSObject.Copy() } Write-Output $result } end { } } function New-PagerDutyChange { [CmdletBinding(SupportsShouldProcess)] param ( # This is the 32 character Integration Key for an integration on a service or on a global ruleset. [Parameter(Mandatory = $true, Position = 0)] [ValidateLength(32, 32)] [string] $RoutingKey, # A brief text summary of the event, used to generate the summaries/titles of any associated alerts. The maximum permitted length of this property is 1024 characters. [Parameter(Mandatory = $true, Position = 1)] [ValidateLength(1, 1024)] [string] $Summary, # The unique location of the affected system, preferably a hostname or FQDN. [Parameter(Mandatory = $true, Position = 2)] [string] $Source, # The time at which the emitting tool detected or generated the event. [Parameter()] [datetime] $Timestamp, [Parameter()] [hashtable] $CustomDetails, # List of links to include. [Parameter()] [hashtable[]] $Links ) begin { } process { # Validate image and link objects. if ($Links) { foreach ($link in $Links) { validateLinkObject $link } } # Prepare object. [pscustomobject]$object = [PSCustomObject]@{ routing_key = $RoutingKey payload = [PSCustomObject]@{ summary = $Summary source = $Source timestamp = $Timestamp ?? (Get-Date -Format "o") custom_details = $CustomDetails } } if ($Links) { Add-Member -InputObject $object -NotePropertyName 'links' -NotePropertyValue (prepareLinks $Links) } if ($PSCmdlet.ShouldProcess($Source, "New-PagerDutyChange")) { # Invoke Event API $result = invokeEventApi -InputObject $object -Uri $PagerDutyChangeEndpoint; } else { $result = $DummyResult.PSObject.Copy() } Write-Output $result } end { } } function validateImageObject { param ( # The image object to validate. [Parameter(Mandatory = $true)] [hashtable] $ImageObject ) if ($ImageObject.Keys -notcontains 'src') { Write-Error -Exception ([System.MissingFieldException]::new("Missing key: src")) -ErrorAction Stop } $srcValue = $ImageObject['src'].ToString(); if ( $false -eq $srcValue.StartsWith("https://") ) { Write-Error -Exception ([System.ArgumentException]::new("Image must be served via https: $srcValue")) -ErrorAction Stop } } function validateLinkObject { param ( # The link object to validate. [Parameter(Mandatory = $true)] [hashtable] $LinkObject ) if ($LinkObject.Keys -notcontains 'href') { Write-Error -Exception ([System.MissingFieldException]::new("Missing key: href")) -ErrorAction Stop } } function prepareImages { param ( [Parameter(Mandatory = $true)] [hashtable[]] $ImageObjects ) [System.Collections.ArrayList]$imageList = New-Object -TypeName "System.Collections.ArrayList" foreach ($obj in $ImageObjects) { $imageObject = [PSCustomObject]@{ src = $obj["src"] href = $obj["href"] alt = $obj["alt"] } [Void]$imageList.Add($imageObject) } Write-Output $imageList } function prepareLinks { param ( [Parameter(Mandatory = $true)] [hashtable[]] $LinkObjects ) [System.Collections.ArrayList]$linkList = New-Object -TypeName "System.Collections.ArrayList" foreach ($obj in $LinkObjects) { $linkObject = [PSCustomObject]@{ href = $obj["href"] text = $obj["text"] } [Void]$linkList.Add($linkObject) } Write-Output $linkList } function invokeEventApi { param ( # Destation URI [Parameter(Mandatory = $true)] [string] $Uri, # Request object [Parameter(Mandatory = $true)] [PSCustomObject] $InputObject ) [int]$statusCode = -1; [string]$json = "" $json = ConvertTo-Json $InputObject -Compress; Write-Verbose "Post Payload: $json" # Send object. $rc = Invoke-RestMethod -Uri $Uri -Method Post -ContentType $ContentType ` -Body $json ` -StatusCodeVariable "statusCode" ` -DisableKeepAlive ` -SkipHttpErrorCheck; Write-Verbose "Raw Response: $rc" $result = [PSCustomObject]@{} Add-Member -InputObject $result -NotePropertyName "StatusCode" -NotePropertyValue $statusCode; if ($result -is [psobject]) { Add-Member -InputObject $result -NotePropertyName "Status" -NotePropertyValue $rc.status Add-Member -InputObject $result -NotePropertyName "Error" -NotePropertyValue $rc.error Add-Member -InputObject $result -NotePropertyName "Message" -NotePropertyValue $rc.message Add-Member -InputObject $result -NotePropertyName "DeduplicationKey" -NotePropertyValue $rc.dedup_key } else { Add-Member -InputObject $result -NotePropertyName "Payload" -NotePropertyValue $rc } Write-Output $result } Export-ModuleMember -Function New-PagerDutyAlert, Confirm-PagerDutyAlert, Resolve-PagerDutyAlert, New-PagerDutyChange |