lita-pagerduty 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/README.md +10 -3
- data/lib/lita-pagerduty.rb +6 -4
- data/lib/lita/commands/base.rb +6 -1
- data/lib/lita/handlers/pagerduty.rb +9 -3
- data/lib/pagerduty.rb +53 -29
- data/lita-pagerduty.gemspec +1 -1
- data/spec/pagerduty_spec.rb +96 -54
- data/spec/spec_helper.rb +3 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4a28972f5fc4c637f95ea379c642402c8857feca
|
4
|
+
data.tar.gz: 2e2622aacc42cdaa1140447a83ad253c6423e2e3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0730876673981ee24e02c9a1c00f45bd0689de3bb4ffb06fb4506cb730f1f04c77c55b5fc0c70ba36b998ff10992a14ea54bbe0bf76683ca1741c7cf46adb8c7
|
7
|
+
data.tar.gz: 44bfee93a0e97ac22c1d1700cd5f4be54f0e1be66e9d22c1be155212bcf40fbe0c5b39d1e876caad6f84065840d85aa9a75a5f7273ba79dbcc2e37dea06c5083
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -13,21 +13,28 @@ A [PagerDuty](http://pagerduty.com) plugin for [Lita](https://github.com/jimmycu
|
|
13
13
|
|
14
14
|
Add lita-pagerduty to your Lita instance's Gemfile:
|
15
15
|
|
16
|
-
```
|
16
|
+
```ruby
|
17
17
|
gem "lita-pagerduty"
|
18
18
|
```
|
19
19
|
|
20
20
|
## Configuration
|
21
21
|
|
22
|
-
Create a PagerDuty
|
22
|
+
Create a PagerDuty API key (v2). You will need to give it FullAccess to update incidents.
|
23
23
|
|
24
24
|
Add the following variables to your Lita config file:
|
25
25
|
|
26
|
-
```
|
26
|
+
```ruby
|
27
27
|
config.handlers.pagerduty.api_key = ''
|
28
28
|
config.handlers.pagerduty.email = ''
|
29
29
|
```
|
30
30
|
|
31
|
+
If your account has the teams capability and you want to scope Lita's access to a specific set of
|
32
|
+
teams, you can set the list of teams by adding the following to your config file:
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
config..handlers.pagerduty.teams = [ "team-a", "team-b" ]
|
36
|
+
```
|
37
|
+
|
31
38
|
## Usage
|
32
39
|
|
33
40
|
### Misc
|
data/lib/lita-pagerduty.rb
CHANGED
@@ -1,14 +1,16 @@
|
|
1
1
|
require 'lita'
|
2
|
+
|
3
|
+
Lita.load_locales Dir[File.expand_path(
|
4
|
+
File.join('..', '..', 'locales', '*.yml'), __FILE__
|
5
|
+
)]
|
6
|
+
|
2
7
|
require 'exceptions'
|
3
8
|
require 'pagerduty'
|
4
9
|
require 'store'
|
5
10
|
require 'lita/handlers/pagerduty'
|
6
11
|
require 'lita/commands/base'
|
7
|
-
Dir[File.join(__dir__, 'lita', 'commands', '*.rb')].each { |file| require file }
|
8
12
|
|
9
|
-
|
10
|
-
File.join('..', '..', 'locales', '*.yml'), __FILE__
|
11
|
-
)]
|
13
|
+
Dir[File.join(__dir__, 'lita', 'commands', '*.rb')].each { |file| require file }
|
12
14
|
|
13
15
|
Lita::Handlers::Pagerduty.template_root File.expand_path(
|
14
16
|
File.join('..', '..', 'templates'), __FILE__
|
data/lib/lita/commands/base.rb
CHANGED
@@ -4,6 +4,7 @@ module Lita
|
|
4
4
|
namespace 'Pagerduty'
|
5
5
|
config :api_key, required: true
|
6
6
|
config :email, required: true
|
7
|
+
config :teams, required: false
|
7
8
|
|
8
9
|
COMMANDS_PATH = File.read("#{File.dirname(__FILE__)}/commands.yml")
|
9
10
|
COMMANDS = YAML.safe_load(COMMANDS_PATH)
|
@@ -13,8 +14,8 @@ module Lita
|
|
13
14
|
command['method'].to_sym,
|
14
15
|
command: true,
|
15
16
|
help: {
|
16
|
-
"help.#{command['method']}.syntax" =>
|
17
|
-
"help.#{command['method']}.desc"
|
17
|
+
t("help.#{command['method']}.syntax") =>
|
18
|
+
t("help.#{command['method']}.desc")
|
18
19
|
}
|
19
20
|
)
|
20
21
|
end
|
@@ -32,7 +33,12 @@ module Lita
|
|
32
33
|
end
|
33
34
|
|
34
35
|
def pagerduty
|
35
|
-
@pagerduty ||= ::Pagerduty.new(
|
36
|
+
@pagerduty ||= ::Pagerduty.new(
|
37
|
+
http,
|
38
|
+
config.api_key,
|
39
|
+
config.email,
|
40
|
+
config.teams
|
41
|
+
)
|
36
42
|
end
|
37
43
|
|
38
44
|
def store
|
data/lib/pagerduty.rb
CHANGED
@@ -1,57 +1,54 @@
|
|
1
1
|
class Pagerduty
|
2
|
-
|
3
|
-
|
2
|
+
attr_reader :http, :teams
|
3
|
+
|
4
|
+
def initialize(http, token, email, teams = [])
|
4
5
|
@http = http
|
6
|
+
@teams = teams || []
|
7
|
+
|
5
8
|
http.url_prefix = 'https://api.pagerduty.com/'
|
6
|
-
http.headers =
|
9
|
+
http.headers = auth_headers(email, token)
|
7
10
|
end
|
8
11
|
|
9
12
|
def get_incidents(params = {})
|
10
|
-
|
11
|
-
data = JSON.parse(response.body, symbolize_names: true)
|
12
|
-
.fetch(:incidents, [])
|
13
|
+
data = get_resources(:incidents, params)
|
13
14
|
raise Exceptions::IncidentsEmptyList if data.empty?
|
14
15
|
|
15
16
|
data
|
16
17
|
end
|
17
18
|
|
18
19
|
def get_users(params = {})
|
19
|
-
|
20
|
-
data = JSON.parse(response.body, symbolize_names: true).fetch(:users, [])
|
20
|
+
data = get_resources(:users, params)
|
21
21
|
raise Exceptions::UsersEmptyList if data.empty?
|
22
22
|
|
23
23
|
data
|
24
24
|
end
|
25
25
|
|
26
26
|
def get_schedules(params = {})
|
27
|
-
|
28
|
-
data = JSON.parse(response.body, symbolize_names: true)
|
29
|
-
.fetch(:schedules, [])
|
27
|
+
data = get_resources(:schedules, params)
|
30
28
|
raise Exceptions::SchedulesEmptyList if data.empty?
|
31
29
|
|
32
30
|
data
|
33
31
|
end
|
34
32
|
|
35
33
|
def get_oncall_user(params = {})
|
36
|
-
|
37
|
-
data = JSON.parse(response.body, symbolize_names: true).fetch(:oncalls, [])
|
34
|
+
data = get_resources(:oncalls, params)
|
38
35
|
raise Exceptions::NoOncallUser if data.empty?
|
39
36
|
|
40
37
|
data.first.fetch(:user)
|
41
38
|
end
|
42
39
|
|
43
40
|
def get_incident(id = '404stub')
|
44
|
-
response =
|
41
|
+
response = http.get "/incidents/#{id}"
|
45
42
|
raise Exceptions::IncidentNotFound if response.status == 404
|
46
43
|
|
47
|
-
|
44
|
+
parse_json_response(response, :incident)
|
48
45
|
end
|
49
46
|
|
50
47
|
def get_notes_by_incident_id(incident_id)
|
51
|
-
response =
|
48
|
+
response = http.get "/incidents/#{incident_id}/notes"
|
52
49
|
raise Exceptions::IncidentNotFound if response.status == 404
|
53
50
|
|
54
|
-
data =
|
51
|
+
data = parse_json_response(response, :notes, [])
|
55
52
|
raise Exceptions::NotesEmptyList if data.empty?
|
56
53
|
|
57
54
|
data
|
@@ -62,33 +59,60 @@ class Pagerduty
|
|
62
59
|
{ id: id, type: 'incident_reference', status: "#{action}d" }
|
63
60
|
end
|
64
61
|
payload = { incidents: incidents }
|
65
|
-
response =
|
62
|
+
response = http.put '/incidents', payload
|
66
63
|
raise Exceptions::IncidentManageUnsuccess if response.status != 200
|
67
64
|
|
68
65
|
response
|
69
66
|
end
|
70
67
|
|
71
68
|
def override(schedule_id, user_id, minutes)
|
72
|
-
|
73
|
-
|
74
|
-
payload = { override: {
|
75
|
-
start: from.iso8601,
|
76
|
-
end: to.iso8601,
|
77
|
-
user: { id: user_id, type: 'user_reference' }
|
78
|
-
} }
|
79
|
-
response = @http.post "/schedules/#{schedule_id}/overrides", payload
|
69
|
+
payload = override_payload(user_id, minutes)
|
70
|
+
response = http.post("/schedules/#{schedule_id}/overrides", payload)
|
80
71
|
raise Exceptions::OverrideUnsuccess if response.status != 201
|
81
72
|
|
82
|
-
|
73
|
+
parse_json_response(response, :override)
|
83
74
|
end
|
84
75
|
|
85
76
|
private
|
86
77
|
|
87
|
-
def
|
78
|
+
def auth_headers(email, token)
|
88
79
|
{
|
89
80
|
'Accept' => 'application/vnd.pagerduty+json;version=2',
|
90
|
-
'Authorization' => "Token token=#{
|
81
|
+
'Authorization' => "Token token=#{token}",
|
91
82
|
'From' => email
|
92
83
|
}
|
93
84
|
end
|
85
|
+
|
86
|
+
# Fetches a list of resources from a given collection using Pagerduty REST API
|
87
|
+
def get_resources(collection_name, params = {})
|
88
|
+
# Scope down to a single team
|
89
|
+
params[:team_ids] = teams if teams.any?
|
90
|
+
|
91
|
+
# Get the resources
|
92
|
+
response = http.get("/#{collection_name}", params)
|
93
|
+
|
94
|
+
# Parse the reponse and get the objects from the collection
|
95
|
+
parse_json_response(response, collection_name, [])
|
96
|
+
end
|
97
|
+
|
98
|
+
# Parses a JSON response and fetches a specific key from it
|
99
|
+
def parse_json_response(response, response_key, default_value = nil)
|
100
|
+
data = JSON.parse(response.body, symbolize_names: true)
|
101
|
+
data.fetch(response_key, default_value)
|
102
|
+
end
|
103
|
+
|
104
|
+
# Returns a payload for overriding a schedule and putting the user
|
105
|
+
# identified by +user_id+ on-call for the period defined by +minutes+
|
106
|
+
def override_payload(user_id, minutes)
|
107
|
+
# start 10 sec from now
|
108
|
+
from = ::Time.now.utc + 10
|
109
|
+
to = from + (60 * minutes)
|
110
|
+
|
111
|
+
{
|
112
|
+
override: {
|
113
|
+
start: from.iso8601, end: to.iso8601,
|
114
|
+
user: { id: user_id, type: 'user_reference' }
|
115
|
+
}
|
116
|
+
}
|
117
|
+
end
|
94
118
|
end
|
data/lita-pagerduty.gemspec
CHANGED
data/spec/pagerduty_spec.rb
CHANGED
@@ -2,9 +2,10 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Pagerduty do
|
4
4
|
let(:http) { double }
|
5
|
-
let(:
|
5
|
+
let(:teams) { nil }
|
6
|
+
let(:pagerduty) { Pagerduty.new(http, 'token', 'email', teams) }
|
6
7
|
|
7
|
-
before
|
8
|
+
before do
|
8
9
|
expect(http).to receive(:url_prefix=).with('https://api.pagerduty.com/')
|
9
10
|
expect(http).to receive(:headers=).with({
|
10
11
|
'Accept' => 'application/vnd.pagerduty+json;version=2',
|
@@ -13,86 +14,127 @@ describe Pagerduty do
|
|
13
14
|
})
|
14
15
|
end
|
15
16
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
)
|
20
|
-
expect(pagerduty.get_incidents).to eq([{ id: 1 }])
|
17
|
+
def stub_response(response_hash)
|
18
|
+
OpenStruct.new(body: response_hash.to_json)
|
19
|
+
end
|
21
20
|
|
22
|
-
|
23
|
-
|
24
|
-
)
|
25
|
-
expect
|
21
|
+
def stub_collection_response(collection, params, response)
|
22
|
+
uri = "/#{collection}"
|
23
|
+
json = stub_response(collection => response)
|
24
|
+
expect(http).to receive(:get).with(uri, params).and_return(json)
|
26
25
|
end
|
27
26
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
27
|
+
#-------------------------------------------------------------------------------------------------
|
28
|
+
context "without teams filtering" do
|
29
|
+
it 'get_incidents' do
|
30
|
+
stub_collection_response(:incidents, {}, [{ id: 1 }])
|
31
|
+
expect(pagerduty.get_incidents).to eq([{ id: 1 }])
|
32
|
+
|
33
|
+
stub_collection_response(:incidents, {}, [])
|
34
|
+
expect{ pagerduty.get_incidents }.to raise_exception Exceptions::IncidentsEmptyList
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'get_users' do
|
38
|
+
stub_collection_response(:users, {}, [{ id: 1 }])
|
39
|
+
expect(pagerduty.get_users).to eq [{ id: 1 }]
|
40
|
+
|
41
|
+
stub_collection_response(:users, {}, [])
|
42
|
+
expect{ pagerduty.get_users }.to raise_exception Exceptions::UsersEmptyList
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'get_schedules' do
|
46
|
+
stub_collection_response(:schedules, {}, [{ id: 1 }])
|
47
|
+
expect(pagerduty.get_schedules).to eq [{ id: 1 }]
|
48
|
+
|
49
|
+
stub_collection_response(:schedules, {}, [])
|
50
|
+
expect{ pagerduty.get_schedules }.to raise_exception Exceptions::SchedulesEmptyList
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'get_oncall_user' do
|
54
|
+
stub_collection_response(:oncalls, {}, [{ id: 1, user: 'abc' }])
|
55
|
+
expect(pagerduty.get_oncall_user).to eq('abc')
|
56
|
+
|
57
|
+
stub_collection_response(:oncalls, {}, [])
|
58
|
+
expect{ pagerduty.get_oncall_user }.to raise_exception Exceptions::NoOncallUser
|
59
|
+
end
|
33
60
|
end
|
34
61
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
)
|
39
|
-
|
62
|
+
#-------------------------------------------------------------------------------------------------
|
63
|
+
context "with teams filtering enabled" do
|
64
|
+
let(:teams) { [ 'team-a', 'team-b' ] }
|
65
|
+
let(:teams_filter) { { team_ids: teams } }
|
66
|
+
|
67
|
+
it 'get_incidents' do
|
68
|
+
stub_collection_response(:incidents, teams_filter, [{ id: 1 }])
|
69
|
+
expect(pagerduty.get_incidents).to eq([{ id: 1 }])
|
70
|
+
|
71
|
+
stub_collection_response(:incidents, teams_filter, [])
|
72
|
+
expect{ pagerduty.get_incidents }.to raise_exception Exceptions::IncidentsEmptyList
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'get_users' do
|
76
|
+
stub_collection_response(:users, teams_filter, [{ id: 1 }])
|
77
|
+
expect(pagerduty.get_users).to eq [{ id: 1 }]
|
40
78
|
|
41
|
-
|
42
|
-
|
79
|
+
stub_collection_response(:users, teams_filter, [])
|
80
|
+
expect{ pagerduty.get_users }.to raise_exception Exceptions::UsersEmptyList
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'get_schedules' do
|
84
|
+
stub_collection_response(:schedules, teams_filter, [{ id: 1 }])
|
85
|
+
expect(pagerduty.get_schedules).to eq [{ id: 1 }]
|
86
|
+
|
87
|
+
stub_collection_response(:schedules, teams_filter, [])
|
88
|
+
expect{ pagerduty.get_schedules }.to raise_exception Exceptions::SchedulesEmptyList
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'get_oncall_user' do
|
92
|
+
stub_collection_response(:oncalls, teams_filter, [{ id: 1, user: 'abc' }])
|
93
|
+
expect(pagerduty.get_oncall_user).to eq('abc')
|
94
|
+
|
95
|
+
stub_collection_response(:oncalls, teams_filter, [])
|
96
|
+
expect{ pagerduty.get_oncall_user }.to raise_exception Exceptions::NoOncallUser
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
#-------------------------------------------------------------------------------------------------
|
101
|
+
# Methods that do not change their semantics with teams filtering enabled
|
102
|
+
#-------------------------------------------------------------------------------------------------
|
103
|
+
it 'get_incident' do
|
104
|
+
expect(http).to receive(:get).with('/incidents/ABC123').and_return(
|
105
|
+
stub_response(incident: {})
|
43
106
|
)
|
44
|
-
|
107
|
+
pagerduty.get_incident('ABC123')
|
45
108
|
end
|
46
109
|
|
47
110
|
it 'get_notes_by_incident_id' do
|
48
111
|
expect(http).to receive(:get).with('/incidents/ABC123/notes').and_return(
|
49
|
-
|
112
|
+
stub_response(notes: [{ id: 1 }])
|
50
113
|
)
|
51
114
|
expect(pagerduty.get_notes_by_incident_id('ABC123')).to eq [{ id: 1 }]
|
52
115
|
|
53
116
|
expect(http).to receive(:get).with('/incidents/ABC123/notes').and_return(
|
54
|
-
|
117
|
+
stub_response(notes: [])
|
55
118
|
)
|
56
119
|
expect{ pagerduty.get_notes_by_incident_id('ABC123') }.to raise_exception Exceptions::NotesEmptyList
|
57
120
|
end
|
58
121
|
|
59
122
|
it 'manage_incidents' do
|
60
|
-
params = {
|
61
|
-
|
62
|
-
|
63
|
-
|
123
|
+
params = {
|
124
|
+
incidents: [
|
125
|
+
{ id: 'a', status: 'acknowledged', type: 'incident_reference' },
|
126
|
+
{ id: 'b', status: 'acknowledged', type: 'incident_reference' },
|
127
|
+
]
|
128
|
+
}
|
64
129
|
expect(http).to receive(:put).with('/incidents', params).and_return(
|
65
130
|
OpenStruct.new(body: { users: [] }.to_json, status: 200)
|
66
131
|
)
|
67
132
|
pagerduty.manage_incidents(:acknowledge, ['a', 'b'])
|
68
133
|
end
|
69
134
|
|
70
|
-
it 'get_schedules' do
|
71
|
-
expect(http).to receive(:get).with('/schedules', {}).and_return(
|
72
|
-
OpenStruct.new(body: { schedules: [{ id: 1 }]}.to_json)
|
73
|
-
)
|
74
|
-
expect(pagerduty.get_schedules).to eq [{ id: 1 }]
|
75
|
-
|
76
|
-
expect(http).to receive(:get).with('/schedules', {}).and_return(
|
77
|
-
OpenStruct.new(body: { incidents: []}.to_json)
|
78
|
-
)
|
79
|
-
expect{ pagerduty.get_schedules }.to raise_exception Exceptions::SchedulesEmptyList
|
80
|
-
end
|
81
|
-
|
82
|
-
it 'get_oncall_user' do
|
83
|
-
expect(http).to receive(:get).with('/oncalls', {}).and_return(
|
84
|
-
OpenStruct.new(body: { oncalls: [{ id: 1, user: 'abc' }]}.to_json)
|
85
|
-
)
|
86
|
-
expect(pagerduty.get_oncall_user).to eq('abc')
|
87
|
-
|
88
|
-
expect(http).to receive(:get).with('/oncalls', {}).and_return(
|
89
|
-
OpenStruct.new(body: { incidents: []}.to_json)
|
90
|
-
)
|
91
|
-
expect{ pagerduty.get_oncall_user }.to raise_exception Exceptions::NoOncallUser
|
92
|
-
end
|
93
135
|
|
94
136
|
it 'override' do
|
95
|
-
expect(Time).to receive(:now).and_return(Time.new(2000))
|
137
|
+
expect(Time).to receive(:now).and_return(Time.new(2000, 1, 1, 0, 0, 0, 0))
|
96
138
|
params = { override: {
|
97
139
|
end: '2000-01-01T00:01:10Z',
|
98
140
|
start: '2000-01-01T00:00:10Z',
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lita-pagerduty
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eric Sigler
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-03-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: lita
|