pagerduty_utils 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|