[Bps-public-commit] rt-extension-pagerduty branch master updated. 0ba151c7f1a1ff56256ef7b51398eb617fabe7ec
BPS Git Server
git at git.bestpractical.com
Wed Mar 16 03:49:03 UTC 2022
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "rt-extension-pagerduty".
The branch, master has been updated
discards 2819d95e6c552b3f56fefd1adf7c81f1120d16bd (commit)
discards 1b8a6d251c85c8c3fd9a6359fb36587924e3bf5f (commit)
discards 69d61cbb29a838fdeea0ae4179c182eda6096ce6 (commit)
via 0ba151c7f1a1ff56256ef7b51398eb617fabe7ec (commit)
via b06528b999928a5ff3423b07ffa16978252d3d79 (commit)
via 37baa8afdf48a55e3142639a3bb0913b49ffe57f (commit)
This update added new revisions after undoing existing revisions. That is
to say, the old revision is not a strict subset of the new revision. This
situation occurs when you --force push a change and generate a repository
containing something like this:
* -- * -- B -- O -- O -- O (2819d95e6c552b3f56fefd1adf7c81f1120d16bd)
\
N -- N -- N (0ba151c7f1a1ff56256ef7b51398eb617fabe7ec)
When this happens we assume that you've already had alert emails for all
of the O revisions, and so we here report only the revisions in the N
branch from the common base, B.
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 0ba151c7f1a1ff56256ef7b51398eb617fabe7ec
Author: Brad Embree <brad at bestpractical.com>
Date: Wed Feb 16 11:08:27 2022 -0800
Prep for first release: version 0.01
diff --git a/Changes b/Changes
new file mode 100644
index 0000000..6a334cb
--- /dev/null
+++ b/Changes
@@ -0,0 +1,4 @@
+Revision history for RT-Extension-PagerDuty
+
+0.01 [Release Date]
+ - Initial version
diff --git a/META.yml b/META.yml
new file mode 100644
index 0000000..1a45cc6
--- /dev/null
+++ b/META.yml
@@ -0,0 +1,30 @@
+---
+abstract: 'RT-Extension-PagerDuty Extension'
+author:
+ - 'Best Practical Solutions, LLC <modules at bestpractical.com>'
+build_requires:
+ ExtUtils::MakeMaker: 6.59
+configure_requires:
+ ExtUtils::MakeMaker: 6.59
+distribution_type: module
+dynamic_config: 1
+generated_by: 'Module::Install version 1.19'
+license: gpl_2
+meta-spec:
+ url: http://module-build.sourceforge.net/META-spec-v1.4.html
+ version: 1.4
+name: RT-Extension-PagerDuty
+no_index:
+ directory:
+ - etc
+ - html
+ - inc
+requires:
+ perl: 5.10.1
+resources:
+ license: http://opensource.org/licenses/gpl-license.php
+ repository: https://github.com/bestpractical/rt-extension-pagerduty
+version: '0.01'
+x_module_install_rtx_version: '0.43'
+x_requires_rt: 5.0.0
+x_rt_too_new: 5.2.0
diff --git a/Makefile.PL b/Makefile.PL
new file mode 100644
index 0000000..772fea1
--- /dev/null
+++ b/Makefile.PL
@@ -0,0 +1,12 @@
+use lib '.';
+use inc::Module::Install;
+
+RTx 'RT-Extension-PagerDuty';
+license 'gpl_2';
+repository 'https://github.com/bestpractical/rt-extension-pagerduty';
+
+requires_rt '5.0.0';
+rt_too_new '5.2.0';
+
+sign;
+WriteAll;
diff --git a/README b/README
new file mode 100644
index 0000000..799f9be
--- /dev/null
+++ b/README
@@ -0,0 +1,163 @@
+NAME
+ RT-Extension-PagerDuty - Two way integration with PagerDuty
+
+DESCRIPTION
+ This RT extension allows for two way integration with the PagerDuty
+ incident response platform.
+
+ On ticket creation in RT trigger an incident in PagerDuty. When a ticket
+ is acknowledged or resolved in RT update the incident in PagerDuty.
+
+ Configure a PagerDuty webhook to push noticications to RT from
+ PagerDuty. When a new incident is triggered in PagerDuty have it create
+ a ticket in RT. If an incident is acknowledged or resolved in PagerDuty
+ update the corresponding ticket in RT.
+
+RT VERSION
+ Works with RT 5.
+
+INSTALLATION
+ perl Makefile.PL
+ make
+ make install
+ May need root permissions
+
+ make initdb
+ Only run this the first time you install this module.
+
+ If you run this twice, you may end up with duplicate data in your
+ database.
+
+ If you are upgrading this module, check for upgrading instructions
+ in case changes need to be made to your database.
+
+ Edit your /opt/rt5/etc/RT_SiteConfig.pm
+ Add this line:
+
+ Plugin('RT::Extension::PagerDuty');
+
+ Clear your mason cache
+ rm -rf /opt/rt5/var/mason_data/obj
+
+ Restart your webserver
+
+CONFIGURATION
+ To define the interactions between RT and PagerDuty use the $PagerDuty
+ config option. This option takes the form of:
+
+ Set(
+ $PagerDuty,
+ {
+ services => {
+ 'PagerDuty Service ID' => {
+ api_token => 'PagerDuty API Token',
+ api_user => 'PagerDuty User',
+ create_queue => 'General',
+ }
+ },
+ queues => {
+ 'RT Queue Name' => {
+ service => 'PagerDuty Service ID',
+ acknowledged => 'open',
+ resolved => 'resolved',
+ }
+ }
+ }
+ );
+
+ The services section maps a PagerDuty service id to the token and user
+ to use for API access. The api_token and api_user values are required.
+ The optional create_queue value is the RT queue name where new RT
+ tickets should be created if a PagerDuty incident creates a new RT
+ ticket. create_queue defaults to the General queue if not specified. Use
+ '*' as the PagerDuty service id to apply to multiple PagerDuty services.
+
+ The queues section maps an RT queue name to the PagerDuty service where
+ it should trigger new incidents when an RT ticket is created. The
+ service value is required and must be a PagerDuty service id. The
+ acknowledged and resolved optional values indicate what RT ticket status
+ to use when an incident is acknowledged or resolved on PagerDuty. If not
+ specified they default to acknowledged => 'open' and resolved =>
+ 'resolved'. Use '*' as the RT queue name to apply to multiple RT queues.
+
+ To get the PagerDuty Service ID login to your PagerDuty account and go
+ to Services -> Service Directory. Click on the Service you want the ID
+ for and the the ID will be at the end of the URL. For example:
+
+ pagerduty.com/service-directory/P3AFFQR
+
+ the Service ID is P3AFFQR.
+
+ To create an api_token login to your PagerDuty account and go to
+ Integrations -> API Access Keys. Click the Create New API Key button.
+ Add a description and click Create Key. Copy the key and paste it into
+ the $PagerDuty config as the api_token. You will not be able to view the
+ key again but you can generate a new one if you lose the key.
+
+ The api_user is the email address for a valid PagerDuty user that has
+ access to the PagerDuty Service you are integrating with.
+
+Scrips
+ This extension will install three new Scrips that do not apply to any
+ queues: On Acknowledge PagerDuty Acknowledge, On Create PagerDuty
+ Trigger, and On Resolve PagerDuty Resolve.
+
+ Once you have added the configuration you can apply these Scrips to the
+ queues you want to integrate with PagerDuty.
+
+CUSTOM FIELDS
+ This extension adds two ticket custom fields: PagerDuty ID and PagerDuty
+ URL.
+
+ When an RT ticket creates an incident on PagerDuty or an incident on
+ PagerDuty creates an RT ticket the custom fields are automatically
+ filled in. The PagerDuty URL links directly to the incident on
+ PagerDuty.
+
+ If you would like to group the new custom fields in their own PagerDuty
+ group you can use the CustomFieldGroupings config option:
+
+ Set(
+ %CustomFieldGroupings,
+ 'RT::Ticket' => [
+ 'PagerDuty' => [ 'PagerDuty ID', 'PagerDuty URL' ],
+ ],
+ );
+
+WEBHOOK USAGE
+ To call the webhook from PagerDuty:
+
+ 1. Create an auth token for a user with permissions to create tickets in
+ the PagerDuty create queue. To create an auth token go to Logged in as
+ -> Settings -> Auth Tokens and create a new token.
+ 2. Go to the PagerDuty Service Integrations Webhooks
+ 3. Add a new webhook, using:
+ https://your.rt.example/PagerDuty/WebHook.html as the webhook URL. Add a
+ custom header with the name Authorization and value 'token #-#-abc123'
+ where '#-#-abc123' is the value for the auth token you created in step
+ one. Currently the only event subscriptions supported are
+ incident.acknowledged, incident.resolved, and incident.triggered.
+ 4. WEBHOOK WITH $RestrictReferrer ENABLED - If the RT config setting
+ $RestrictReferrer is enabled then the webhook will not work without
+ allowing it in the config:
+ Set( %ReferrerComponents,
+ '/PagerDuty/WebHook.html' => 1,
+ );
+
+ 5. The PagerDuty Send Test Event button will send a message to the
+ webhook but nothing will happen as a result
+
+AUTHOR
+ Best Practical Solutions, LLC <modules at bestpractical.com>
+
+ All bugs should be reported via email to
+ bug-RT-Extension-PagerDuty at rt.cpan.org
+ or via the web at
+ http://rt.cpan.org/Public/Dist/Display.html?Name=RT-Extension-PagerDuty
+LICENSE AND COPYRIGHT
+ This software is Copyright (c) 2022 by BPS
+
+ This is free software, licensed under:
+
+ The GNU General Public License, Version 2, June 1991
+
commit b06528b999928a5ff3423b07ffa16978252d3d79
Author: Brad Embree <brad at bestpractical.com>
Date: Wed Feb 16 11:07:54 2022 -0800
Add PagerDuty webhook
diff --git a/html/PagerDuty/WebHook.html b/html/PagerDuty/WebHook.html
new file mode 100644
index 0000000..521b55d
--- /dev/null
+++ b/html/PagerDuty/WebHook.html
@@ -0,0 +1,132 @@
+<%init>
+use JSON;
+use Data::Dumper;
+
+if ( !$ARGS{'POSTDATA'} ) {
+ RT->Logger->error('PagerDuty webhook failed no POSTDATA');
+ $m->abort(400);
+}
+
+# payload example: https://developer.pagerduty.com/docs/ZG9jOjExMDI5NTkw-v3-overview#webhook-payload
+my $data;
+eval { $data = decode_json( $ARGS{'POSTDATA'} ); };
+
+if ($@) {
+ RT->Logger->error("PagerDuty webhook failed to decode json data: $@");
+ $m->abort(400);
+}
+
+RT->Logger->debug( 'PagerDuty webhook got data: ' . Dumper($data) );
+
+# this webhook only handles incident events
+if ( $data->{event}{data}{type} ne 'incident' ) {
+ RT->Logger->debug('PagerDuty webhook ignoring non incident event');
+ $m->abort(400);
+}
+
+my $config = RT::Config->Get('PagerDuty') // {};
+my $service = $config->{services}{ $data->{event}{data}{service}{id} }
+ // $config->{services}{'*'};
+
+unless ( defined $service ) {
+ RT->Logger->error( "PagerDuty webhook no service config found for id: "
+ . $data->{event}{data}{service}{id} );
+ $m->abort(400);
+}
+
+my $user_obj = $session{CurrentUser};
+unless ($user_obj) {
+ RT->Logger->error('PagerDuty webhook failed no current user');
+ $m->abort(401);
+}
+
+# need to see if a ticket already exists for this incident
+my $tickets = RT::Tickets->new($user_obj);
+$tickets->LimitCustomField(
+ CUSTOMFIELD => 'PagerDuty ID',
+ OPERATOR => '=',
+ VALUE => $data->{event}{data}{id},
+);
+
+# if there is a ticket already we ignore the triggered event to avoid a loop between RT and PagerDuty
+# XXX - should we log an error if there is more than 1 ticket for this incident?
+my $pd_event = $data->{event}{event_type};
+if ( ( $tickets->Count > 0 ) && ( $pd_event ne 'incident.triggered' ) ) {
+ my $ticket = $tickets->First;
+ my $queue = $config->{queues}{ $ticket->QueueObj->Name }
+ // $config->{queues}{'*'};
+
+ unless ( defined $queue ) {
+ RT->Logger->error( "PagerDuty webhook no queue config found for: "
+ . $ticket->QueueObj->Name );
+ $m->abort(400);
+ }
+
+ if ( $pd_event eq 'incident.acknowledged' ) {
+ if ( $ticket->LifecycleObj->IsInitial( $ticket->Status ) ) {
+ my ( $ret, $msg )
+ = $ticket->SetStatus( $queue->{acknowledged} // 'open' );
+ unless ($ret) {
+ RT->Logger->error(
+ "Pagerduty webhook could not set ticket status: $msg");
+ }
+ ( $ret, $msg )
+ = $ticket->Comment( Content => 'acknowledged on PagerDuty' );
+ unless ($ret) {
+ RT->Logger->error(
+ "Pagerduty webhook could not add comment: $msg");
+ }
+ }
+ } elsif ( $pd_event eq 'incident.resolved' ) {
+ my $resolved_status = $queue->{resolved} // 'resolved';
+ if ( $ticket->Status ne $resolved_status ) {
+ my ( $ret, $msg ) = $ticket->SetStatus($resolved_status);
+ unless ($ret) {
+ RT->Logger->error(
+ "Pagerduty webhook could not set ticket status: $msg");
+ }
+ ( $ret, $msg )
+ = $ticket->Comment( Content => 'resolved on PagerDuty' );
+ unless ($ret) {
+ RT->Logger->error(
+ "Pagerduty webhook could not add comment: $msg");
+ }
+ }
+ }
+}
+
+# if there is not a ticket already we only handle the triggered event
+elsif ( ( $tickets->Count == 0 ) && ( $pd_event eq 'incident.triggered' ) ) {
+ my $queue = $service->{create_queue} // 'General';
+
+ # look up ids for PagerDuty related custom fields
+ my $CF = RT::CustomField->new($user_obj);
+ $CF->LoadByName( Name => 'PagerDuty ID' );
+ my $cf_id = $CF->id;
+ $CF->LoadByName( Name => 'PagerDuty URL' );
+ my $cf_url = $CF->id;
+
+ my $Ticket = RT::Ticket->new($user_obj);
+ my ( $id, $Trans, $ErrMsg ) = $Ticket->Create(
+ Type => 'ticket',
+ Queue => $queue,
+ Subject => 'PagerDuty Incident: '
+ . $data->{event}{data}{service}{summary} . ' - '
+ . $data->{event}{data}{title},
+ "CustomField-$cf_id" => $data->{event}{data}{id} // '',
+ "CustomField-$cf_url" => $data->{event}{data}{html_url} // '',
+ );
+
+ if ($id) {
+ RT::Logger->debug(
+ 'PagerDuty webhook created new ticket with custom field values: '
+ . $data->{event}{data}{id} . ' - '
+ . $data->{event}{data}{html_url} );
+ } else {
+ RT::Logger->error(
+ "PagerDuty webhook failed to create new ticket: $ErrMsg");
+ }
+}
+
+</%init>
+% $m->abort;
commit 37baa8afdf48a55e3142639a3bb0913b49ffe57f
Author: Brad Embree <brad at bestpractical.com>
Date: Wed Feb 16 11:07:04 2022 -0800
Add RT::Extension::PagerDuty POD
diff --git a/lib/RT/Extension/PagerDuty.pm b/lib/RT/Extension/PagerDuty.pm
new file mode 100644
index 0000000..4527180
--- /dev/null
+++ b/lib/RT/Extension/PagerDuty.pm
@@ -0,0 +1,206 @@
+use strict;
+use warnings;
+
+package RT::Extension::PagerDuty;
+
+our $VERSION = '0.01';
+
+=head1 NAME
+
+RT-Extension-PagerDuty - Two way integration with PagerDuty
+
+=head1 DESCRIPTION
+
+This RT extension allows for two way integration with the PagerDuty incident
+response platform.
+
+On ticket creation in RT trigger an incident in PagerDuty. When a ticket is
+acknowledged or resolved in RT update the incident in PagerDuty.
+
+Configure a PagerDuty webhook to push noticications to RT from PagerDuty. When
+a new incident is triggered in PagerDuty have it create a ticket in RT. If an
+incident is acknowledged or resolved in PagerDuty update the corresponding
+ticket in RT.
+
+=head1 RT VERSION
+
+Works with RT 5.
+
+=head1 INSTALLATION
+
+=over
+
+=item C<perl Makefile.PL>
+
+=item C<make>
+
+=item C<make install>
+
+May need root permissions
+
+=item C<make initdb>
+
+Only run this the first time you install this module.
+
+If you run this twice, you may end up with duplicate data
+in your database.
+
+If you are upgrading this module, check for upgrading instructions
+in case changes need to be made to your database.
+
+=item Edit your F</opt/rt5/etc/RT_SiteConfig.pm>
+
+Add this line:
+
+ Plugin('RT::Extension::PagerDuty');
+
+=item Clear your mason cache
+
+ rm -rf /opt/rt5/var/mason_data/obj
+
+=item Restart your webserver
+
+=back
+
+=head1 CONFIGURATION
+
+To define the interactions between RT and PagerDuty use the C<$PagerDuty> config
+option. This option takes the form of:
+
+ Set(
+ $PagerDuty,
+ {
+ services => {
+ 'PagerDuty Service ID' => {
+ api_token => 'PagerDuty API Token',
+ api_user => 'PagerDuty User',
+ create_queue => 'General',
+ }
+ },
+ queues => {
+ 'RT Queue Name' => {
+ service => 'PagerDuty Service ID',
+ acknowledged => 'open',
+ resolved => 'resolved',
+ }
+ }
+ }
+ );
+
+The services section maps a PagerDuty service id to the token and user to use
+for API access. The C<api_token> and C<api_user> values are required. The
+optional C<create_queue> value is the RT queue name where new RT tickets should
+be created if a PagerDuty incident creates a new RT ticket. C<create_queue>
+defaults to the General queue if not specified. Use '*' as the PagerDuty service
+id to apply to multiple PagerDuty services.
+
+The queues section maps an RT queue name to the PagerDuty service where it should
+trigger new incidents when an RT ticket is created. The C<service> value is
+required and must be a PagerDuty service id. The C<acknowledged> and C<resolved>
+optional values indicate what RT ticket status to use when an incident is
+acknowledged or resolved on PagerDuty. If not specified they default to
+acknowledged => 'open' and resolved => 'resolved'. Use '*' as the RT queue name
+to apply to multiple RT queues.
+
+To get the PagerDuty Service ID login to your PagerDuty account and go to
+Services -> Service Directory. Click on the Service you want the ID for and the
+the ID will be at the end of the URL. For example:
+
+ pagerduty.com/service-directory/P3AFFQR
+
+the Service ID is P3AFFQR.
+
+To create an api_token login to your PagerDuty account and go to
+Integrations -> API Access Keys. Click the Create New API Key button. Add a
+description and click Create Key. Copy the key and paste it into the $PagerDuty
+config as the api_token. You will not be able to view the key again but you can generate a new
+one if you lose the key.
+
+The api_user is the email address for a valid PagerDuty user that has access to
+the PagerDuty Service you are integrating with.
+
+=head1 Scrips
+
+This extension will install three new Scrips that do not apply to any queues:
+C<On Acknowledge PagerDuty Acknowledge>, C<On Create PagerDuty Trigger>, and
+C<On Resolve PagerDuty Resolve>.
+
+Once you have added the configuration you can apply these Scrips to the queues
+you want to integrate with PagerDuty.
+
+=head1 CUSTOM FIELDS
+
+This extension adds two ticket custom fields: PagerDuty ID and PagerDuty URL.
+
+When an RT ticket creates an incident on PagerDuty or an incident on PagerDuty
+creates an RT ticket the custom fields are automatically filled in. The PagerDuty
+URL links directly to the incident on PagerDuty.
+
+If you would like to group the new custom fields in their own PagerDuty group
+you can use the CustomFieldGroupings config option:
+
+ Set(
+ %CustomFieldGroupings,
+ 'RT::Ticket' => [
+ 'PagerDuty' => [ 'PagerDuty ID', 'PagerDuty URL' ],
+ ],
+ );
+
+=head1 WEBHOOK USAGE
+
+To call the webhook from PagerDuty:
+
+=over 4
+
+
+=item 1. Create an auth token for a user with permissions to create tickets in
+the PagerDuty create queue. To create an auth token go to
+Logged in as -> Settings -> Auth Tokens and create a new token.
+
+=item 2. Go to the PagerDuty Service Integrations Webhooks
+
+=item 3. Add a new webhook, using: C<https://your.rt.example/PagerDuty/WebHook.html>
+as the webhook URL. Add a custom header with the name Authorization and value
+'token #-#-abc123' where '#-#-abc123' is the value for the auth token you
+created in step one. Currently the only event subscriptions supported are
+incident.acknowledged, incident.resolved, and incident.triggered.
+
+=item 4. WEBHOOK WITH $RestrictReferrer ENABLED - If the RT config setting
+$RestrictReferrer is enabled then the webhook will not work without allowing it
+in the config:
+
+ Set( %ReferrerComponents,
+ '/PagerDuty/WebHook.html' => 1,
+ );
+
+=item 5. The PagerDuty Send Test Event button will send a message to the webhook
+but nothing will happen as a result
+
+=back
+
+=head1 AUTHOR
+
+Best Practical Solutions, LLC E<lt>modules at bestpractical.comE<gt>
+
+=for html <p>All bugs should be reported via email to <a
+href="mailto:bug-RT-Extension-PagerDuty at rt.cpan.org">bug-RT-Extension-PagerDuty at rt.cpan.org</a>
+or via the web at <a
+href="http://rt.cpan.org/Public/Dist/Display.html?Name=RT-Extension-PagerDuty">rt.cpan.org</a>.</p>
+
+=for text
+ All bugs should be reported via email to
+ bug-RT-Extension-PagerDuty at rt.cpan.org
+ or via the web at
+ http://rt.cpan.org/Public/Dist/Display.html?Name=RT-Extension-PagerDuty
+
+=head1 LICENSE AND COPYRIGHT
+
+This software is Copyright (c) 2022 by BPS
+
+This is free software, licensed under:
+
+ The GNU General Public License, Version 2, June 1991
+
+=cut
+
+1;
-----------------------------------------------------------------------
Summary of changes:
README | 17 +++++++++--------
lib/RT/Extension/PagerDuty.pm | 15 +++++++++------
2 files changed, 18 insertions(+), 14 deletions(-)
hooks/post-receive
--
rt-extension-pagerduty
More information about the Bps-public-commit
mailing list