lita-pagerduty 1.0.0 → 1.1.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/.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
|