pagerduty_utils 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/pgutils +126 -0
- data/lib/pagerduty/base.rb +133 -0
- data/lib/pagerduty/override.rb +41 -0
- metadata +47 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2734f9242e51882171cf33ec55745551f2ca150d
|
4
|
+
data.tar.gz: 82bc1e579955359c49ef711a768f9920239cd911
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: fb9671f772b4516e211821437a326b46b81d1aa077b5ea5f0ee56493e04294be11d8830854e423103cfde5adfe1e58a8b7af035236b899620f603d72bf685262
|
7
|
+
data.tar.gz: aaa11e2a2934c29f44b3fc07f8a20cece9d43c080057385525f5df382007305883af1f41cb5f1e608f4399d968e0e738fa4cd413dd7e8abb53c3ba4139402957
|
data/bin/pgutils
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
#!/usr/bin/env ruby -w
|
2
|
+
require 'optparse'
|
3
|
+
require 'pagerduty/base'
|
4
|
+
require 'pagerduty/override'
|
5
|
+
|
6
|
+
def load_trigger(trigger_name)
|
7
|
+
config_file = "#{ENV['PAGERDUTY_CONFIG_DIR'] ? ENV['PAGERDUTY_CONFIG_DIR'] + 'triggers.yml' : ENV['HOME'] + '/.pgutils/triggers.yaml'}"
|
8
|
+
if File.readable?(config_file)
|
9
|
+
triggers = YAML.load_file(config_file)
|
10
|
+
else
|
11
|
+
abort("#{config_file} not found")
|
12
|
+
end
|
13
|
+
pg = TapJoy::PagerDuty::Base.new
|
14
|
+
puts pg.post_trigger(**triggers[trigger_name.to_sym])
|
15
|
+
end
|
16
|
+
|
17
|
+
def get_level_one_users(pg)
|
18
|
+
return pg.get_users_on_call['escalation_policies'].flat_map do |policy|
|
19
|
+
policy['on_call'].map do |oncall|
|
20
|
+
oncall['user']['id'] if oncall['start'] and oncall['level'] == 1
|
21
|
+
end.compact
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
options = {}
|
26
|
+
|
27
|
+
subtext = <<HELP
|
28
|
+
Supported commands are:
|
29
|
+
set_override :
|
30
|
+
trigger :
|
31
|
+
get_on_call :
|
32
|
+
|
33
|
+
See '#{File.basename(__FILE__)} COMMAND --help' for more information on a specific command.
|
34
|
+
HELP
|
35
|
+
|
36
|
+
global = OptionParser.new do |opts|
|
37
|
+
opts.banner = "Usage: #{File.basename(__FILE__)} [options] [subcommand [options]]"
|
38
|
+
opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
|
39
|
+
options[:verbose] = v
|
40
|
+
end
|
41
|
+
opts.separator ""
|
42
|
+
opts.separator subtext
|
43
|
+
end
|
44
|
+
|
45
|
+
subcommands = {
|
46
|
+
'set_override' => OptionParser.new do |opts|
|
47
|
+
opts.banner = <<-EOS
|
48
|
+
|
49
|
+
Usage: #{File.basename(__FILE__)} set_override [options]
|
50
|
+
|
51
|
+
This code is used to temporarily override the primary person on-call for a given schedule.
|
52
|
+
|
53
|
+
EOS
|
54
|
+
|
55
|
+
opts.on('-e', '--email EMAIL', 'Specify email address of override user') do |e|
|
56
|
+
options[:email] = e
|
57
|
+
end
|
58
|
+
opts.on('-s', '--schedule-name SCHEDULE', 'Name of schedule to override') do |s|
|
59
|
+
options[:schedule_name] = s
|
60
|
+
end
|
61
|
+
opts.on('-t', '--override-length TIME', 'Number of seconds to maintain override for') do |t|
|
62
|
+
options[:override_length] = t.to_i
|
63
|
+
end
|
64
|
+
end,
|
65
|
+
|
66
|
+
'trigger' => OptionParser.new do |opts|
|
67
|
+
opts.banner = <<-EOS
|
68
|
+
|
69
|
+
Usage: #{File.basename(__FILE__)} trigger [options]
|
70
|
+
|
71
|
+
This script will create a pagerduty alert, based on the name of the trigger
|
72
|
+
hash as specified in 'triggers.yaml'
|
73
|
+
|
74
|
+
EOS
|
75
|
+
|
76
|
+
opts.on("-t", "--trigger TRIGGER", 'Name of trigger to alert on') do |t|
|
77
|
+
options[:trigger] = t
|
78
|
+
end
|
79
|
+
end,
|
80
|
+
|
81
|
+
'get_on_call' => OptionParser.new do |opts|
|
82
|
+
opts.banner = <<-EOS
|
83
|
+
|
84
|
+
Usage: #{File.basename(__FILE__)} get_on_call
|
85
|
+
|
86
|
+
This script will return the list of each person on-call sorted by schedule.
|
87
|
+
There are no options available for this command at this time.
|
88
|
+
|
89
|
+
EOS
|
90
|
+
end
|
91
|
+
}
|
92
|
+
|
93
|
+
global.order!
|
94
|
+
command = ARGV.shift
|
95
|
+
begin
|
96
|
+
subcommands[command].order!
|
97
|
+
rescue NoMethodError
|
98
|
+
abort("Invalid Input.\n\n#{subtext}")
|
99
|
+
end
|
100
|
+
|
101
|
+
case command
|
102
|
+
when 'trigger'
|
103
|
+
raise OptionParser::MissingArgument if options[:trigger].nil?
|
104
|
+
load_trigger(options[:trigger])
|
105
|
+
when 'set_override'
|
106
|
+
raise OptionParser::MissingArgument if options[:email].nil?
|
107
|
+
options[:schedule_name] = 'Default' if options[:schedule_name].nil?
|
108
|
+
options[:override_length] = 3600 if options[:override_length].nil?
|
109
|
+
TapJoy::PagerDuty::Override.new(options[:email], options[:schedule_name], options[:override_length])
|
110
|
+
when 'get_on_call'
|
111
|
+
pg = TapJoy::PagerDuty::Base.new
|
112
|
+
get_level_one_users(pg).each do |u|
|
113
|
+
user = pg.get_user_details(u)['user']
|
114
|
+
on_call = user['on_call']
|
115
|
+
puts "Name: #{user['name']}"
|
116
|
+
on_call.each do |oc|
|
117
|
+
puts "\tGroup: #{oc['escalation_policy']['name']}"
|
118
|
+
puts "\tStart: #{oc['start']}"
|
119
|
+
puts "\tEnd: #{oc['end']}"
|
120
|
+
puts "\n"
|
121
|
+
end
|
122
|
+
puts '---'
|
123
|
+
end
|
124
|
+
else
|
125
|
+
abort("Unknown command: #{command}")
|
126
|
+
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
require 'json'
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
module TapJoy
|
6
|
+
module PagerDuty; end
|
7
|
+
end
|
8
|
+
|
9
|
+
class TapJoy::PagerDuty::Base
|
10
|
+
|
11
|
+
# Initializer services to import values from pg_connect.yaml
|
12
|
+
# to configure organization-specific values (currently, subdomain and api_token)
|
13
|
+
def initialize
|
14
|
+
config_file = "#{ENV['PAGERDUTY_CONFIG_DIR'] ? ENV['PAGERDUTY_CONFIG_DIR'] + 'triggers.yml' : ENV['HOME'] + '/.pgutils/triggers.yaml'}"
|
15
|
+
pg_conn = YAML.load_file(config_file) if File.readable?(config_file)
|
16
|
+
|
17
|
+
@AUTH_HEADER = {
|
18
|
+
:subdomain => ENV['PAGERDUTY_SUBDOMAIN'] || pg_conn[:subdomain],
|
19
|
+
:token_string => "Token token=#{ENV['PAGERDUTY_API_TOKEN'] || pg_conn[:api_token]}"
|
20
|
+
}
|
21
|
+
|
22
|
+
raise 'Missing subdomain value' if @AUTH_HEADER[:subdomain].nil?
|
23
|
+
raise 'Missing API token' if @AUTH_HEADER[:token_string].nil?
|
24
|
+
end
|
25
|
+
|
26
|
+
# Given an email address return the user_id that pagerduty uses for lookups
|
27
|
+
def get_user_id(email)
|
28
|
+
endpoint = return_pagerduty_url(:users)
|
29
|
+
out_array = get_object(endpoint)['users'].select { |i| i['email'].eql?(email) }
|
30
|
+
return Hash[*out_array]['id']
|
31
|
+
end
|
32
|
+
|
33
|
+
# Given the name of a schedule return the schedule_id that pagerduty uses for lookups
|
34
|
+
def get_schedule_id(schedule_name)
|
35
|
+
endpoint = return_pagerduty_url(:schedules)
|
36
|
+
out_array = get_object(endpoint)['schedules'].select { |i| i['name'].eql?(schedule_name)}
|
37
|
+
return Hash[*out_array]['id']
|
38
|
+
end
|
39
|
+
|
40
|
+
# The set_override method takes in several variables and returns
|
41
|
+
# the REST response upon (attempting) completion of an override action
|
42
|
+
def set_override(query_start:, query_end:, override_start:, override_end:,
|
43
|
+
user_id:, schedule_id:)
|
44
|
+
# Ruby 2.x style kw-args is required here to make hash passing easier
|
45
|
+
|
46
|
+
endpoint = "#{return_pagerduty_url(:schedules)}/#{schedule_id}/overrides?since=#{query_start}&until=#{query_end}"
|
47
|
+
|
48
|
+
data = {
|
49
|
+
override: {
|
50
|
+
user_id: user_id,
|
51
|
+
start: override_start,
|
52
|
+
end: override_end,
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
post_object(endpoint, data)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Return all users on call for all schedules, which we can parse through later
|
60
|
+
def get_users_on_call
|
61
|
+
endpoint = return_pagerduty_url(:escalation_on_call)
|
62
|
+
return get_object(endpoint)
|
63
|
+
end
|
64
|
+
|
65
|
+
# Given a specific user, return all details about the
|
66
|
+
# user that we can parse through as needed
|
67
|
+
def get_user_details(user_id)
|
68
|
+
endpoint = return_pagerduty_url(:users) + "/#{user_id}/on_call"
|
69
|
+
return get_object(endpoint)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Create a page to the first person on call for a given service key
|
73
|
+
def post_trigger(service_key:, incident_key:, description:, client:,
|
74
|
+
client_url:, details:)
|
75
|
+
|
76
|
+
# Ruby 2.x style kw-args is required here to make hash passing easier
|
77
|
+
endpoint = return_pagerduty_url(:create_trigger)
|
78
|
+
data = {
|
79
|
+
service_key: service_key,
|
80
|
+
incident_key: incident_key,
|
81
|
+
event_type: 'trigger',
|
82
|
+
description: description,
|
83
|
+
client: client,
|
84
|
+
client_url: client_url,
|
85
|
+
details: details,
|
86
|
+
}
|
87
|
+
|
88
|
+
post_object(endpoint, data)
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
# Helper method for all GETs
|
93
|
+
def get_object(endpoint)
|
94
|
+
response = HTTParty.get(
|
95
|
+
endpoint,
|
96
|
+
headers: {
|
97
|
+
'Content-Type' => 'application/json', 'Authorization' => @AUTH_HEADER[:token_string]
|
98
|
+
}
|
99
|
+
)
|
100
|
+
return JSON.load(response.body)
|
101
|
+
end
|
102
|
+
|
103
|
+
# Helper method for all PUTs
|
104
|
+
def post_object(endpoint, data)
|
105
|
+
response = HTTParty.post(
|
106
|
+
endpoint,
|
107
|
+
body: data.to_json,
|
108
|
+
headers: {
|
109
|
+
'Content-Type' => 'application/json', 'Authorization' => @AUTH_HEADER[:token_string]
|
110
|
+
}
|
111
|
+
)
|
112
|
+
|
113
|
+
return response.body
|
114
|
+
end
|
115
|
+
|
116
|
+
# Helper method for building PagerDuty URLs
|
117
|
+
def return_pagerduty_url(object_type)
|
118
|
+
rest_api_url = "https://#{@AUTH_HEADER[:subdomain]}.pagerduty.com/api/v1"
|
119
|
+
incident_api_url = 'https://events.pagerduty.com/generic/2010-04-15'
|
120
|
+
case object_type
|
121
|
+
when :users
|
122
|
+
return rest_api_url + '/users'
|
123
|
+
when :schedules
|
124
|
+
return rest_api_url + '/schedules'
|
125
|
+
when :escalation_on_call
|
126
|
+
return rest_api_url + '/escalation_policies/on_call'
|
127
|
+
when :create_trigger
|
128
|
+
return incident_api_url + '/create_event.json'
|
129
|
+
else
|
130
|
+
abort("Unknown object type: #{object_type}. Can't build URL.")
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'pagerduty/base'
|
2
|
+
require 'date'
|
3
|
+
|
4
|
+
module TapJoy
|
5
|
+
module PagerDuty; end
|
6
|
+
end
|
7
|
+
|
8
|
+
class TapJoy::PagerDuty::Override
|
9
|
+
|
10
|
+
# Initializer services to import values from pg_connect.yaml
|
11
|
+
# to configure organization-specific values (currently, subdomain and api_token)
|
12
|
+
def initialize(email, schedule_name, override_length)
|
13
|
+
pg = TapJoy::PagerDuty::Base.new
|
14
|
+
override_window_hash = override_window(override_length)
|
15
|
+
puts pg.set_override(**query_dates, **override_window_hash,
|
16
|
+
user_id: pg.get_user_id(email),
|
17
|
+
schedule_id: pg.get_schedule_id(schedule_name) # case-sensitive
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
def time_string(time_object)
|
23
|
+
return time_object.iso8601.to_s
|
24
|
+
end
|
25
|
+
|
26
|
+
def query_dates
|
27
|
+
# This shrinks the query to a one-day window
|
28
|
+
since_date = time_string(Time.now)
|
29
|
+
until_date = time_string((Time.now + (1*86400)))
|
30
|
+
|
31
|
+
return {query_start: since_date, query_end: until_date}
|
32
|
+
end
|
33
|
+
|
34
|
+
def override_window(override_time)
|
35
|
+
from_time = Time.now.iso8601.to_s
|
36
|
+
# 3600 is number of seconds, change this to alter the override window
|
37
|
+
until_time = (Time.now + override_time).iso8601.to_s
|
38
|
+
|
39
|
+
return {override_start: from_time, override_end: until_time}
|
40
|
+
end
|
41
|
+
end
|
metadata
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: pagerduty_utils
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ali Tayarani
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-11-25 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: A set of tools to make leveraging the PagerDuty APIs easier
|
14
|
+
email: ali.tayarani@tapjoy.com
|
15
|
+
executables:
|
16
|
+
- pgutils
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- bin/pgutils
|
21
|
+
- lib/pagerduty/base.rb
|
22
|
+
- lib/pagerduty/override.rb
|
23
|
+
homepage: https://github.com/tapjoy/pagerduty_utils
|
24
|
+
licenses:
|
25
|
+
- MIT
|
26
|
+
metadata: {}
|
27
|
+
post_install_message:
|
28
|
+
rdoc_options: []
|
29
|
+
require_paths:
|
30
|
+
- lib
|
31
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
32
|
+
requirements:
|
33
|
+
- - ">="
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: '0'
|
36
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
requirements: []
|
42
|
+
rubyforge_project:
|
43
|
+
rubygems_version: 2.2.2
|
44
|
+
signing_key:
|
45
|
+
specification_version: 4
|
46
|
+
summary: TapJoy PagerDuty Tools
|
47
|
+
test_files: []
|