Skip to content

Commit 6ced45d

Browse files
author
Matthew Peck
committed
initial commit
0 parents  commit 6ced45d

10 files changed

+509
-0
lines changed

Gemfile

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
source 'https://rubygems.org'
2+
3+
gem 'cog-rb', github: "cog-bundles/cog-rb"
4+
gem 'pagerduty'
5+
gem 'pager_duty-connection'

Gemfile.lock

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
GIT
2+
remote: git://github.com/cog-bundles/cog-rb.git
3+
revision: 8213c9fe11d4c0b4274277d7a52018c2f601beb1
4+
specs:
5+
cog-rb (0.1.5)
6+
7+
GEM
8+
remote: https://rubygems.org/
9+
specs:
10+
activesupport (4.2.6)
11+
i18n (~> 0.7)
12+
json (~> 1.7, >= 1.7.7)
13+
minitest (~> 5.1)
14+
thread_safe (~> 0.3, >= 0.3.4)
15+
tzinfo (~> 1.1)
16+
faraday (0.9.2)
17+
multipart-post (>= 1.2, < 3)
18+
faraday_middleware (0.9.2)
19+
faraday (>= 0.7.4, < 0.10)
20+
hashie (2.1.2)
21+
i18n (0.7.0)
22+
json (1.8.3)
23+
minitest (5.9.0)
24+
multipart-post (2.0.0)
25+
pager_duty-connection (0.2.0)
26+
activesupport (>= 3.2, < 5.0)
27+
faraday (~> 0.8, < 0.10)
28+
faraday_middleware (~> 0.9.0)
29+
hashie (>= 1.2, < 2.2)
30+
pagerduty (2.1.0)
31+
json (>= 1.7.7)
32+
thread_safe (0.3.5)
33+
tzinfo (1.2.2)
34+
thread_safe (~> 0.1)
35+
36+
PLATFORMS
37+
ruby
38+
39+
DEPENDENCIES
40+
cog-rb!
41+
pager_duty-connection
42+
pagerduty
43+
44+
BUNDLED WITH
45+
1.12.5

cog-command

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#!/usr/bin/env ruby
2+
3+
# Make sure we're in the top-level directory for the command
4+
# since so many paths are relative.
5+
Dir.chdir(File.dirname(__FILE__))
6+
7+
require 'bundler/setup'
8+
require 'cog'
9+
10+
Cog.bundle('pagerduty')

config.yaml

+156
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
---
2+
cog_bundle_version: 3
3+
4+
name: pagerduty
5+
version: 0.1.0
6+
description: Interact with the pagerduty
7+
permissions:
8+
- pagerduty:read
9+
- pagerduty:write
10+
- pagerduty:alert
11+
commands:
12+
alert:
13+
executable: /Users/mpeck/op/pagerduty/cog-command
14+
documentation: |
15+
pagerduty:alert [-s|--service <service name>] <msg> - Trigger an alert on the specified service
16+
pagerduty:alert <msg> - Trigger an alert on the default service
17+
18+
Returns a confirmation message on success
19+
20+
Requires the following environment variables:
21+
22+
PAGERDUTY_ACCOUNT_SUBDOMAIN
23+
PAGERDUTY_ACCOUNT_TOKEN
24+
25+
Behavior is configured by the following environment variables:
26+
27+
PAGERDUTY_DEFAULT_SERVICE_KEY - If no service is passed, this is the id of the service to use.
28+
29+
Note: If no service is passed and the default service key is not set, the command will fail.
30+
31+
rules:
32+
- must have pagerduty:alert
33+
options:
34+
service:
35+
type: string
36+
required: false
37+
short_flag: s
38+
oncall:
39+
executable: /Users/mpeck/op/pagerduty/cog-command
40+
documentation: |
41+
pagerduty:oncall - Return a list of services and the name and email of the primary oncall
42+
pagerduty:oncall <service> - Return the oncall for the sepcified service
43+
44+
Requires the following environment variables:
45+
46+
PAGERDUTY_ACCOUNT_SUBDOMAIN
47+
PAGERDUTY_ACCOUNT_TOKEN
48+
49+
rules: ["allow"]
50+
ack:
51+
executable: /Users/mpeck/op/pagerduty/cog-command
52+
documentation: |
53+
pagerduty:ack <incident id> - Acknowledge the incident
54+
pagerduty:ack [-a | --as <pagerduty user email>] <incident id> Acknowledge the incident as the account specified by the email
55+
56+
Returns confirmation of acknowledgement
57+
58+
Requires the following environment variables:
59+
60+
PAGERDUTY_ACCOUNT_SUBDOMAIN
61+
PAGERDUTY_ACCOUNT_TOKEN
62+
63+
Behavior is configured by the following environment variables:
64+
65+
PAGERDUTY_DEFAULT_EMAIL - The default pagerduty email to acknowledge incidents as
66+
PAGERDUTY_EMAIL_FOR_<COG USER> - Used to map cog users to pagerduty emails
67+
68+
An email mapping to a pagerduty account is required in order to ack incidents. If the
69+
'--as' option has been specified then that email will be used. If not this command will
70+
first look for an environment variable in the form of 'PAGERDUTY_EMAIL_FOR_<COG USER>',
71+
so if your user name is 'bob', the env var will be 'PAGERDUTY_EMAIL_FOR_BOB', and use
72+
that email to acknowledge the incident. If that fails it will try 'PAGERDUTY_DEFAULT_EMAIL'
73+
If none of those vars are specified and the '--as' option is not passed, the command will
74+
fail.
75+
76+
rules:
77+
- must have pagerduty:write
78+
options:
79+
as:
80+
type: string
81+
required: false
82+
short_flag: a
83+
resolve:
84+
executable: /Users/mpeck/op/pagerduty/cog-command
85+
documentation: |
86+
pagerduty:resolve <incident id> - Resovle the incident
87+
pagerduty:resolve [-a | --as <pagerduty user email>] <incident id> Resolve the incident as the account specified by the email
88+
89+
Returns confirmation of resolution
90+
91+
Requires the following environment variables:
92+
93+
PAGERDUTY_ACCOUNT_SUBDOMAIN
94+
PAGERDUTY_ACCOUNT_TOKEN
95+
96+
Behavior is configured by the following environment variables:
97+
98+
PAGERDUTY_DEFAULT_EMAIL - The default pagerduty email to acknowledge incidents as
99+
PAGERDUTY_EMAIL_FOR_<COG USER> - Used to map cog users to pagerduty emails
100+
101+
An email mapping to a pagerduty account is required in order to resolve incidents. If the
102+
'--as' option has been specified then that email will be used. If not this command will
103+
first look for an environment variable in the form of 'PAGERDUTY_EMAIL_FOR_<COG USER>',
104+
so if your user name is 'bob' the env var will be 'PAGERDUTY_EMAIL_FOR_BOB', and use
105+
that email to acknowledge the incident. If that fails it will try 'PAGERDUTY_DEFAULT_EMAIL'
106+
If none of those vars are specified and the '--as' option is not passed, the command will
107+
fail.
108+
109+
rules:
110+
- must have pagerduty:write
111+
options:
112+
as:
113+
type: string
114+
required: false
115+
short_flag: a
116+
incidents:
117+
executable: /Users/mpeck/op/pagerduty/cog-command
118+
documentation: |
119+
pagerduty:incidents [-a | --acked] [-t | --triggered] [-r | --resolved] [-l | --limit]
120+
121+
Returns incidents matching the specified option. By default, only returns triggered incidents.
122+
123+
Requires the following environment variables:
124+
125+
PAGERDUTY_ACCOUNT_SUBDOMAIN
126+
PAGERDUTY_ACCOUNT_TOKEN
127+
128+
rules:
129+
- must have pagerduty:read
130+
options:
131+
triggered:
132+
type: bool
133+
required: false
134+
short_flag: t
135+
acked:
136+
type: bool
137+
required: false
138+
short_flag: a
139+
resolved:
140+
type: bool
141+
required: false
142+
short_flag: r
143+
limit:
144+
type: int
145+
required: false
146+
short_flag: l
147+
templates:
148+
oncall:
149+
slack: "{{ name }} - {{ oncall.name }}({{ oncall.email }})"
150+
hipchat: "{{ name }} - {{ oncall.name }}({{ oncall.email }})"
151+
incidents:
152+
slack: "Service: {{ service.name }} {{ url }}\nStatus: {{ status }}\n{{ summary.subject }} {{ summary.description }}\n"
153+
hipchat: "Service: {{ service.name }} {{ url }}\nStatus: {{ status }}\n{{ summary.subject }} {{ summary.description }}\n"
154+
noresults:
155+
slack: "Sorry, no results were returned."
156+
hipchat: "Sorry, no results were returned."

lib/cog_cmd/pagerduty/ack.rb

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#!/usr/bin/env ruby
2+
3+
require_relative 'pagerduty'
4+
require 'cog/command'
5+
require 'pager_duty/connection'
6+
7+
class CogCmd::Pagerduty::Ack < Cog::Command
8+
9+
include CogCmd::Pagerduty
10+
11+
def initialize
12+
@client = PagerDuty::Connection.new(account, token)
13+
end
14+
15+
def run_command
16+
incident_ids = request.args
17+
18+
if incident_ids.length == 0
19+
response['body'] = 'You must pass at least one incident to acknowledge.'
20+
return response
21+
end
22+
23+
if user
24+
acks = []
25+
incident_ids.each do |id|
26+
begin
27+
@client.put("incidents/#{id}/acknowledge", requester_id: user.id)
28+
acks.push("Acknowledged #{id}")
29+
rescue PagerDuty::Connection::ApiError => error
30+
fail(error.inspect)
31+
end
32+
end
33+
response['body'] = acks
34+
else
35+
fail("Couldn't find a user to make the request as.")
36+
end
37+
end
38+
39+
private
40+
41+
def user
42+
user_name =
43+
request.options["as"] ||
44+
env_var("PAGERDUTY_EMAIL_FOR",
45+
suffix: env_var("USER"),
46+
required: false) ||
47+
env_var("PAGERDUTY_DEFAULT_EMAIL")
48+
49+
@client.get('users', query: user_name)['users'].first if user_name
50+
end
51+
52+
end

lib/cog_cmd/pagerduty/alert.rb

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#!/usr/bin/env ruby
2+
3+
require_relative 'pagerduty'
4+
require 'cog/command'
5+
require 'pager_duty/connection'
6+
require 'pagerduty'
7+
8+
class CogCmd::Pagerduty::Alert < Cog::Command
9+
10+
include CogCmd::Pagerduty
11+
12+
def initialize
13+
@client = PagerDuty::Connection.new(account, token)
14+
@event = Pagerduty.new(service_key)
15+
end
16+
17+
def run_command
18+
msg = request.args.join(" ")
19+
20+
begin
21+
@event.trigger(msg)
22+
response['body'] = "Alert sent"
23+
rescue Net::HTTPServerException => error
24+
error = <<-END.gsub(/^ {7}/, '')
25+
\nError triggering incident:
26+
#{error.response.code}:#{error.response.message}
27+
#{error.response.body}
28+
END
29+
fail(error)
30+
end
31+
end
32+
33+
def service_key
34+
service_name = request.options['service']
35+
if service_name
36+
@client.get('services', query: service_name)['services'].first['service_key']
37+
else
38+
env_var("PAGERDUTY_DEFAULT_SERVICE_KEY", required: true)
39+
end
40+
end
41+
42+
end

lib/cog_cmd/pagerduty/incidents.rb

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#!/usr/bin/env ruby
2+
3+
require_relative 'pagerduty'
4+
require 'cog/command'
5+
require 'pager_duty/connection'
6+
7+
class CogCmd::Pagerduty::Incidents < Cog::Command
8+
9+
include CogCmd::Pagerduty
10+
11+
def initialize
12+
@default_limit = 100
13+
@client = PagerDuty::Connection.new(account, token)
14+
end
15+
16+
def run_command
17+
incidents = incidents(request)
18+
19+
response.template = 'incidents'
20+
21+
if incidents.length > 0
22+
response.content = incidents.map {|incident|
23+
{id: incident.id,
24+
urgency: incident.urgency,
25+
summary: incident.trigger_summary_data,
26+
incident_key: incident.incident_key,
27+
created_on: incident.created_on,
28+
service: incident.service,
29+
url: incident.html_url,
30+
status: incident.status}
31+
}
32+
else
33+
response['body'] = "No incidents found."
34+
end
35+
end
36+
37+
private
38+
39+
def statuses(options)
40+
status_list = []
41+
status_list.push('triggered') if options["triggered"]
42+
status_list.push('resolved') if options["resolved"]
43+
status_list.push('acknowledged') if options["acked"]
44+
45+
if status_list.length == 0
46+
status_list.push('triggered')
47+
end
48+
49+
status_list.join(",")
50+
end
51+
52+
def limit(limit)
53+
if limit
54+
limit
55+
else
56+
env_var("PAGERDUTY_DEFAULT_LIMIT", required: false) || @default_limit
57+
end
58+
end
59+
60+
def services(service)
61+
resp = @client.get('services', query: service.join(" "))
62+
resp.services.map { |ser|
63+
ser.id
64+
}.join(",")
65+
end
66+
67+
def incidents(request)
68+
opts = {
69+
status: statuses(request.options)
70+
}
71+
opts[:limit] = limit(request.options['limit']) if request.options['limit']
72+
opts[:service] = services(request.args) if request.args.length > 0
73+
74+
resp = @client.get('incidents', opts)
75+
resp['incidents']
76+
end
77+
78+
end

0 commit comments

Comments
 (0)