pagerduty_utils 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/pgutils +36 -87
- data/lib/pagerduty/base.rb +131 -127
- data/lib/pagerduty/override.rb +36 -39
- data/lib/pagerduty/version.rb +11 -0
- metadata +61 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b78ef3120e4fcfc5c4579c60e349ff7ccca904ab
|
4
|
+
data.tar.gz: 5a1df5a97c35c826f4c41767ac81488195a21f5d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0f0e66729f30f8ac6c05a9574d9214bab47a8380068cb0435d96b819b01df5a761a197072e4863e5a8538f71cd45affb6f1e84e7787c567b14f2c3d423de7fe3
|
7
|
+
data.tar.gz: 51beffa82f6a8f690c2f172bb5bcf893da676a7d4f7e5fc523129f57505a5e336e9ab59199257e47c6db83f222f80a657a093cb0fce60ecfd9acccd514a29051
|
data/bin/pgutils
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
#!/usr/bin/env ruby -w
|
2
|
-
|
2
|
+
|
3
3
|
require 'pagerduty/base'
|
4
|
-
require 'pagerduty/override'
|
5
4
|
|
6
|
-
def load_trigger(trigger_name)
|
5
|
+
def load_trigger(trigger_name, message)
|
7
6
|
config_file = "#{ENV['PAGERDUTY_CONFIG_DIR'] ? ENV['PAGERDUTY_CONFIG_DIR'] + 'triggers.yml' : ENV['HOME'] + '/.pgutils/triggers.yaml'}"
|
8
|
-
|
7
|
+
if File.readable?(config_file)
|
9
8
|
triggers = YAML.load_file(config_file)
|
10
9
|
else
|
11
10
|
abort("#{config_file} not found")
|
12
11
|
end
|
13
|
-
pg =
|
12
|
+
pg = Tapjoy::PagerDuty::Base.new
|
13
|
+
triggers[trigger_name.to_sym][:description] = message if message
|
14
14
|
puts pg.post_trigger(**triggers[trigger_name.to_sym])
|
15
15
|
end
|
16
16
|
|
@@ -22,93 +22,42 @@ def get_level_one_users(pg)
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
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
|
25
|
+
SUB_COMMANDS = %w(set_override trigger get_on_call)
|
26
|
+
Trollop::options do
|
27
|
+
usage '[SUB_COMMAND] [options]'
|
28
|
+
synopsis "\nTool to integrate with PagerDuty API.\nAvailable subcommands are: #{SUB_COMMANDS}"
|
29
|
+
version "#{File.basename($0)} #{Tapjoy::PagerDuty::VERSION} \u00A9 2014-2015 Tapjoy, Inc."
|
30
|
+
stop_on SUB_COMMANDS
|
43
31
|
end
|
44
32
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
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
|
33
|
+
cmd = ARGV.shift
|
34
|
+
case cmd
|
35
|
+
when 'set_override'
|
36
|
+
opts = Trollop::options do
|
37
|
+
usage 'set_override [options]'
|
38
|
+
synopsis "\nTemporarily override the primary person on-call for a given schedule."
|
39
|
+
opt(:email, 'Specify email address of override user', required: true, :type => :string)
|
40
|
+
opt(:schedule_name, 'Name of schedule to override', default: 'Default', :type => :string)
|
41
|
+
opt(:override_length, 'Number of seconds to maintain override for', default: 3600, :type => :int)
|
90
42
|
end
|
91
|
-
}
|
92
43
|
|
93
|
-
|
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
|
44
|
+
Tapjoy::PagerDuty::Override.new(opts[:email], opts[:schedule_name], opts[:override_length])
|
102
45
|
when 'trigger'
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
46
|
+
opts = Trollop::options do
|
47
|
+
usage 'trigger [options]'
|
48
|
+
synopsis "\nThis script will create a pagerduty alert, based on the name of the trigger hash as specified in 'triggers.yaml'"
|
49
|
+
opt :trigger, 'Name of trigger to alert on', required: true, type: :string
|
50
|
+
opt :message, 'Message to include in trigger', type: :string
|
51
|
+
end
|
52
|
+
|
53
|
+
load_trigger(opts[:trigger], opts[:message])
|
110
54
|
when 'get_on_call'
|
111
|
-
|
55
|
+
Trollop::options do
|
56
|
+
usage 'get_on_call'
|
57
|
+
synopsis "\nThis script will return the list of each person on-call sorted by schedule.\nThere are no options available for this command at this time."
|
58
|
+
end
|
59
|
+
|
60
|
+
pg = Tapjoy::PagerDuty::Base.new
|
112
61
|
get_level_one_users(pg).each do |u|
|
113
62
|
user = pg.get_user_details(u)['user']
|
114
63
|
on_call = user['on_call']
|
@@ -122,5 +71,5 @@ when 'get_on_call'
|
|
122
71
|
puts '---'
|
123
72
|
end
|
124
73
|
else
|
125
|
-
|
74
|
+
Trollop::educate
|
126
75
|
end
|
data/lib/pagerduty/base.rb
CHANGED
@@ -1,133 +1,137 @@
|
|
1
1
|
require 'httparty'
|
2
2
|
require 'json'
|
3
3
|
require 'yaml'
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
endpoint
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
endpoint,
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
4
|
+
require 'date'
|
5
|
+
require 'trollop'
|
6
|
+
require 'pagerduty/override'
|
7
|
+
require_relative 'version'
|
8
|
+
|
9
|
+
module Tapjoy
|
10
|
+
module PagerDuty
|
11
|
+
class Base
|
12
|
+
|
13
|
+
# Initializer services to import values from pg_connect.yaml
|
14
|
+
# to configure organization-specific values (currently, subdomain and api_token)
|
15
|
+
def initialize
|
16
|
+
config_file = "#{ENV['PAGERDUTY_CONFIG_DIR'] ? ENV['PAGERDUTY_CONFIG_DIR'] + 'pgconnect.yml' : ENV['HOME'] + '/.pgutils/pgconnect.yaml'}"
|
17
|
+
pg_conn = YAML.load_file(config_file) if File.readable?(config_file)
|
18
|
+
|
19
|
+
@AUTH_HEADER = {
|
20
|
+
:subdomain => ENV['PAGERDUTY_SUBDOMAIN'] || pg_conn[:subdomain],
|
21
|
+
:token_string => "Token token=#{ENV['PAGERDUTY_API_TOKEN'] || pg_conn[:api_token]}"
|
22
|
+
}
|
23
|
+
|
24
|
+
raise 'Missing subdomain value' if @AUTH_HEADER[:subdomain].nil?
|
25
|
+
raise 'Missing API token' if @AUTH_HEADER[:token_string].nil?
|
26
|
+
end
|
27
|
+
|
28
|
+
# Given an email address return the user_id that pagerduty uses for lookups
|
29
|
+
def get_user_id(email)
|
30
|
+
endpoint = return_pagerduty_url(:users)
|
31
|
+
out_array = get_object(endpoint)['users'].select { |i| i['email'].eql?(email) }
|
32
|
+
return Hash[*out_array]['id']
|
33
|
+
end
|
34
|
+
|
35
|
+
# Given the name of a schedule return the schedule_id that pagerduty uses for lookups
|
36
|
+
def get_schedule_id(schedule_name)
|
37
|
+
endpoint = return_pagerduty_url(:schedules)
|
38
|
+
out_array = get_object(endpoint)['schedules'].select { |i| i['name'].eql?(schedule_name)}
|
39
|
+
return Hash[*out_array]['id']
|
40
|
+
end
|
41
|
+
|
42
|
+
# The set_override method takes in several variables and returns
|
43
|
+
# the REST response upon (attempting) completion of an override action
|
44
|
+
def set_override(query_start:, query_end:, override_start:, override_end:,
|
45
|
+
user_id:, schedule_id:)
|
46
|
+
# Ruby 2.x style kw-args is required here to make hash passing easier
|
47
|
+
|
48
|
+
endpoint = "#{return_pagerduty_url(:schedules)}/#{schedule_id}/overrides?since=#{query_start}&until=#{query_end}"
|
49
|
+
|
50
|
+
data = {
|
51
|
+
override: {
|
52
|
+
user_id: user_id,
|
53
|
+
start: override_start,
|
54
|
+
end: override_end,
|
55
|
+
}
|
56
|
+
}
|
57
|
+
|
58
|
+
post_object(endpoint, data)
|
59
|
+
end
|
60
|
+
|
61
|
+
# Return all users on call for all schedules, which we can parse through later
|
62
|
+
def get_users_on_call
|
63
|
+
endpoint = return_pagerduty_url(:escalation_on_call)
|
64
|
+
return get_object(endpoint)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Given a specific user, return all details about the
|
68
|
+
# user that we can parse through as needed
|
69
|
+
def get_user_details(user_id)
|
70
|
+
endpoint = return_pagerduty_url(:users) + "/#{user_id}/on_call"
|
71
|
+
return get_object(endpoint)
|
72
|
+
end
|
73
|
+
|
74
|
+
# Create a page to the first person on call for a given service key
|
75
|
+
def post_trigger(service_key:, incident_key:, description:, client:,
|
76
|
+
client_url:, details:)
|
77
|
+
|
78
|
+
# Ruby 2.x style kw-args is required here to make hash passing easier
|
79
|
+
endpoint = return_pagerduty_url(:create_trigger)
|
80
|
+
data = {
|
81
|
+
service_key: service_key,
|
82
|
+
incident_key: incident_key,
|
83
|
+
event_type: 'trigger',
|
84
|
+
description: description,
|
85
|
+
client: client,
|
86
|
+
client_url: client_url,
|
87
|
+
details: details,
|
88
|
+
}
|
89
|
+
|
90
|
+
post_object(endpoint, data)
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
# Helper method for all GETs
|
95
|
+
def get_object(endpoint)
|
96
|
+
response = HTTParty.get(
|
97
|
+
endpoint,
|
98
|
+
headers: {
|
99
|
+
'Content-Type' => 'application/json', 'Authorization' => @AUTH_HEADER[:token_string]
|
100
|
+
}
|
101
|
+
)
|
102
|
+
return JSON.load(response.body)
|
103
|
+
end
|
104
|
+
|
105
|
+
# Helper method for all PUTs
|
106
|
+
def post_object(endpoint, data)
|
107
|
+
response = HTTParty.post(
|
108
|
+
endpoint,
|
109
|
+
body: data.to_json,
|
110
|
+
headers: {
|
111
|
+
'Content-Type' => 'application/json', 'Authorization' => @AUTH_HEADER[:token_string]
|
112
|
+
}
|
113
|
+
)
|
114
|
+
|
115
|
+
return response.body
|
116
|
+
end
|
117
|
+
|
118
|
+
# Helper method for building PagerDuty URLs
|
119
|
+
def return_pagerduty_url(object_type)
|
120
|
+
rest_api_url = "https://#{@AUTH_HEADER[:subdomain]}.pagerduty.com/api/v1"
|
121
|
+
incident_api_url = 'https://events.pagerduty.com/generic/2010-04-15'
|
122
|
+
case object_type
|
123
|
+
when :users
|
124
|
+
return rest_api_url + '/users'
|
125
|
+
when :schedules
|
126
|
+
return rest_api_url + '/schedules'
|
127
|
+
when :escalation_on_call
|
128
|
+
return rest_api_url + '/escalation_policies/on_call'
|
129
|
+
when :create_trigger
|
130
|
+
return incident_api_url + '/create_event.json'
|
131
|
+
else
|
132
|
+
abort("Unknown object type: #{object_type}. Can't build URL.")
|
133
|
+
end
|
134
|
+
end
|
131
135
|
end
|
132
136
|
end
|
133
137
|
end
|
data/lib/pagerduty/override.rb
CHANGED
@@ -1,41 +1,38 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
until_time = (Time.now + override_time).iso8601.to_s
|
38
|
-
|
39
|
-
return {override_start: from_time, override_end: until_time}
|
1
|
+
module Tapjoy
|
2
|
+
module PagerDuty
|
3
|
+
class Override
|
4
|
+
|
5
|
+
# Initializer services to import values from pg_connect.yaml
|
6
|
+
# to configure organization-specific values (currently, subdomain and api_token)
|
7
|
+
def initialize(email, schedule_name, override_length)
|
8
|
+
pg = Tapjoy::PagerDuty::Base.new
|
9
|
+
override_window_hash = override_window(override_length)
|
10
|
+
puts pg.set_override(**query_dates, **override_window_hash,
|
11
|
+
user_id: pg.get_user_id(email),
|
12
|
+
schedule_id: pg.get_schedule_id(schedule_name) # case-sensitive
|
13
|
+
)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
def time_string(time_object)
|
18
|
+
return time_object.iso8601.to_s
|
19
|
+
end
|
20
|
+
|
21
|
+
def query_dates
|
22
|
+
# This shrinks the query to a one-day window
|
23
|
+
since_date = time_string(Time.now)
|
24
|
+
until_date = time_string((Time.now + (1*86400)))
|
25
|
+
|
26
|
+
return {query_start: since_date, query_end: until_date}
|
27
|
+
end
|
28
|
+
|
29
|
+
def override_window(override_time)
|
30
|
+
from_time = Time.now.iso8601.to_s
|
31
|
+
# 3600 is number of seconds, change this to alter the override window
|
32
|
+
until_time = (Time.now + override_time).iso8601.to_s
|
33
|
+
|
34
|
+
return {override_start: from_time, override_end: until_time}
|
35
|
+
end
|
36
|
+
end
|
40
37
|
end
|
41
38
|
end
|
metadata
CHANGED
@@ -1,15 +1,71 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pagerduty_utils
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ali Tayarani
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
12
|
-
dependencies:
|
11
|
+
date: 2015-04-02 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: trollop
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.1'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.1'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: httparty
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.2'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.2'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: activesupport
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '4.2'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '4.2'
|
13
69
|
description: A set of tools to make leveraging the PagerDuty APIs easier
|
14
70
|
email: ali.tayarani@tapjoy.com
|
15
71
|
executables:
|
@@ -20,6 +76,7 @@ files:
|
|
20
76
|
- bin/pgutils
|
21
77
|
- lib/pagerduty/base.rb
|
22
78
|
- lib/pagerduty/override.rb
|
79
|
+
- lib/pagerduty/version.rb
|
23
80
|
homepage: https://github.com/tapjoy/pagerduty_utils
|
24
81
|
licenses:
|
25
82
|
- MIT
|
@@ -43,5 +100,5 @@ rubyforge_project:
|
|
43
100
|
rubygems_version: 2.2.2
|
44
101
|
signing_key:
|
45
102
|
specification_version: 4
|
46
|
-
summary:
|
103
|
+
summary: Tapjoy PagerDuty Tools
|
47
104
|
test_files: []
|