lita-pagerduty 0.2.0 → 1.0.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.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +1 -1
  3. data/.rubocop.yml +6 -5
  4. data/README.md +11 -9
  5. data/Rakefile +4 -2
  6. data/lib/exceptions.rb +11 -0
  7. data/lib/lita-pagerduty.rb +7 -29
  8. data/lib/lita/commands/ack.rb +15 -0
  9. data/lib/lita/commands/ack_all.rb +21 -0
  10. data/lib/lita/commands/ack_mine.rb +26 -0
  11. data/lib/lita/commands/base.rb +75 -0
  12. data/lib/lita/commands/forget.rb +13 -0
  13. data/lib/lita/commands/identify.rb +13 -0
  14. data/lib/lita/commands/incident.rb +13 -0
  15. data/lib/lita/commands/incidents_all.rb +18 -0
  16. data/lib/lita/commands/incidents_mine.rb +23 -0
  17. data/lib/lita/commands/notes.rb +15 -0
  18. data/lib/lita/commands/on_call_list.rb +13 -0
  19. data/lib/lita/commands/on_call_lookup.rb +41 -0
  20. data/lib/lita/commands/pager_me.rb +48 -0
  21. data/lib/lita/commands/resolve.rb +15 -0
  22. data/lib/lita/commands/resolve_all.rb +21 -0
  23. data/lib/lita/commands/resolve_mine.rb +26 -0
  24. data/lib/lita/handlers/commands.yml +30 -0
  25. data/lib/lita/handlers/pagerduty.rb +57 -0
  26. data/lib/pagerduty.rb +94 -0
  27. data/lib/store.rb +20 -0
  28. data/lita-pagerduty.gemspec +1 -2
  29. data/locales/en.yml +2 -2
  30. data/spec/lita/handlers/ack_all_spec.rb +26 -0
  31. data/spec/lita/handlers/ack_id_spec.rb +23 -0
  32. data/spec/lita/handlers/ack_mine_spec.rb +38 -0
  33. data/spec/lita/handlers/forget_spec.rb +22 -0
  34. data/spec/lita/handlers/identify_email_spec.rb +22 -0
  35. data/spec/lita/handlers/incident_id_spec.rb +23 -0
  36. data/spec/lita/handlers/incidents_all_spec.rb +31 -0
  37. data/spec/lita/handlers/incidents_mine_spec.rb +35 -0
  38. data/spec/lita/handlers/notes_spec.rb +29 -0
  39. data/spec/lita/handlers/on_call_list_spec.rb +21 -0
  40. data/spec/lita/handlers/on_call_lookup_spec.rb +29 -0
  41. data/spec/lita/handlers/pager_me_spec.rb +56 -0
  42. data/spec/lita/handlers/resolve_all_spec.rb +26 -0
  43. data/spec/lita/handlers/resolve_id_spec.rb +21 -0
  44. data/spec/lita/handlers/resolve_mine_spec.rb +38 -0
  45. data/spec/pagerduty_spec.rb +106 -0
  46. data/spec/spec_helper.rb +3 -189
  47. data/templates/.gitkeep +0 -0
  48. metadata +57 -35
  49. data/lib/lita/handlers/pagerduty_ack.rb +0 -77
  50. data/lib/lita/handlers/pagerduty_incident.rb +0 -68
  51. data/lib/lita/handlers/pagerduty_note.rb +0 -50
  52. data/lib/lita/handlers/pagerduty_resolve.rb +0 -77
  53. data/lib/lita/handlers/pagerduty_utility.rb +0 -136
  54. data/lib/pagerduty_helper/incident.rb +0 -64
  55. data/lib/pagerduty_helper/regex.rb +0 -8
  56. data/lib/pagerduty_helper/utility.rb +0 -43
  57. data/spec/lita/handlers/pagerduty_ack_spec.rb +0 -95
  58. data/spec/lita/handlers/pagerduty_incident_spec.rb +0 -103
  59. data/spec/lita/handlers/pagerduty_note_spec.rb +0 -43
  60. data/spec/lita/handlers/pagerduty_resolve_spec.rb +0 -95
  61. data/spec/lita/handlers/pagerduty_utility_spec.rb +0 -59
@@ -1,50 +0,0 @@
1
- # Lita-related code
2
- module Lita
3
- # Plugin-related code
4
- module Handlers
5
- # Note-related routes
6
- class PagerdutyNote < Handler
7
- namespace 'Pagerduty'
8
-
9
- include ::PagerdutyHelper::Incident
10
- include ::PagerdutyHelper::Regex
11
- include ::PagerdutyHelper::Utility
12
-
13
- route(
14
- /^pager\snotes\s#{INCIDENT_ID_PATTERN}$/,
15
- :notes,
16
- command: true,
17
- help: {
18
- t('help.notes.syntax') => t('help.notes.desc')
19
- }
20
- )
21
-
22
- route(
23
- /^pager\snote\s#{INCIDENT_ID_PATTERN}\s(.+)$/,
24
- :note,
25
- command: true,
26
- help: {
27
- t('help.note.syntax') => t('help.note.desc')
28
- }
29
- )
30
-
31
- # rubocop:disable Metrics/AbcSize
32
- def notes(response)
33
- incident_id = response.match_data['incident_id']
34
- incident = fetch_incident(incident_id)
35
- return response.reply(t('incident.not_found', id: incident_id)) if incident == 'No results'
36
- return response.reply("#{incident_id}: No notes") unless incident.notes.notes.count > 0
37
- incident.notes.notes.each do |note|
38
- response.reply(format_note(incident, note))
39
- end
40
- end
41
- # rubocop:enable Metrics/AbcSize
42
-
43
- def note(response)
44
- response.reply(t('error.not_implemented'))
45
- end
46
- end
47
-
48
- Lita.register_handler(PagerdutyNote)
49
- end
50
- end
@@ -1,77 +0,0 @@
1
- # Lita-related code
2
- module Lita
3
- # Plugin-related code
4
- module Handlers
5
- # Resolve-related routes
6
- class PagerdutyResolve < Handler
7
- namespace 'Pagerduty'
8
-
9
- include ::PagerdutyHelper::Incident
10
- include ::PagerdutyHelper::Regex
11
- include ::PagerdutyHelper::Utility
12
-
13
- route(
14
- /^pager\sresolve\sall$/,
15
- :resolve_all,
16
- command: true,
17
- help: {
18
- t('help.resolve_all.syntax') => t('help.resolve_all.desc')
19
- }
20
- )
21
-
22
- route(
23
- /^pager\sresolve\smine$/,
24
- :resolve_mine,
25
- command: true,
26
- help: {
27
- t('help.resolve_mine.syntax') => t('help.resolve_mine.desc')
28
- }
29
- )
30
-
31
- route(
32
- /^pager\sresolve\s#{INCIDENT_ID_PATTERN}$/,
33
- :resolve,
34
- command: true,
35
- help: {
36
- t('help.resolve.syntax') => t('help.resolve.desc')
37
- }
38
- )
39
-
40
- # rubocop:disable Metrics/AbcSize
41
- def resolve_all(response)
42
- incidents = fetch_all_incidents
43
- return response.reply(t('incident.none')) unless incidents.count > 0
44
- completed = []
45
- incidents.each do |incident|
46
- result = resolve_incident(incident.id)
47
- completed.push(incident.id) if result == "#{incident.id}: Incident resolved"
48
- response.reply(t('all.resolved', list: completed.join(',')))
49
- end
50
- end
51
- # rubocop:enable Metrics/AbcSize
52
-
53
- # rubocop:disable Metrics/AbcSize
54
- def resolve_mine(response)
55
- email = fetch_user(response.user)
56
- return response.reply(t('identify.missing')) unless email
57
- incidents = fetch_my_incidents(email)
58
- return response.reply(t('incident.none_mine')) unless incidents.count > 0
59
- completed = []
60
- incidents.each do |incident|
61
- result = resolve_incident(incident.id)
62
- completed.push(incident.id) if result == "#{incident.id}: Incident resolved"
63
- response.reply(t('all.resolved', list: completed.join(',')))
64
- end
65
- end
66
- # rubocop:enable Metrics/AbcSize
67
-
68
- def resolve(response)
69
- incident_id = response.match_data['incident_id']
70
- return if incident_id == 'all' || incident_id == 'mine'
71
- response.reply(resolve_incident(incident_id))
72
- end
73
- end
74
-
75
- Lita.register_handler(PagerdutyResolve)
76
- end
77
- end
@@ -1,136 +0,0 @@
1
- require 'time'
2
-
3
- # Lita-related code
4
- module Lita
5
- # Plugin-related code
6
- module Handlers
7
- # Utility-ish routes
8
- class PagerdutyUtility < Handler
9
- config :api_key, required: true
10
- config :subdomain, required: true
11
-
12
- namespace 'Pagerduty'
13
-
14
- include ::PagerdutyHelper::Incident
15
- include ::PagerdutyHelper::Regex
16
- include ::PagerdutyHelper::Utility
17
-
18
- route(
19
- /^pager\soncall$/,
20
- :on_call_list,
21
- command: true,
22
- help: {
23
- t('help.on_call_list.syntax') => t('help.on_call_list.desc')
24
- }
25
- )
26
-
27
- route(
28
- /^pager\soncall\s(.*)$/,
29
- :on_call_lookup,
30
- command: true,
31
- help: {
32
- t('help.on_call_lookup.syntax') => t('help.on_call_lookup.desc')
33
- }
34
- )
35
-
36
- route(
37
- /^pager\sidentify\s#{EMAIL_PATTERN}$/,
38
- :identify,
39
- command: true,
40
- help: {
41
- t('help.identify.syntax') => t('help.identify.desc')
42
- }
43
- )
44
-
45
- route(
46
- /^pager\sforget$/,
47
- :forget,
48
- command: true,
49
- help: {
50
- t('help.forget.syntax') => t('help.forget.desc')
51
- }
52
- )
53
-
54
- route(
55
- /^pager\s+me\s+(.+?)\s+(\d+)m?$/,
56
- :pager_me,
57
- command: true,
58
- help: { t('help.pager_me.syntax') => t('help.pager_me.desc') }
59
- )
60
-
61
- def on_call_list(response)
62
- schedules = pd_client.get_schedules.schedules
63
- if schedules.any?
64
- schedule_list = schedules.map(&:name).join("\n")
65
- response.reply(t('on_call_list.response', schedules: schedule_list))
66
- else
67
- response.reply(t('on_call_list.no_schedules_found'))
68
- end
69
- end
70
-
71
- # rubocop:disable Metrics/AbcSize
72
- def on_call_lookup(response)
73
- schedule_name = response.match_data[1].strip
74
- schedule = pd_client.get_schedules.schedules.find { |s| s.name.casecmp(schedule_name) == 0 }
75
-
76
- unless schedule
77
- return response.reply(t('on_call_lookup.no_matching_schedule', schedule_name: schedule_name))
78
- end
79
-
80
- if (user = lookup_on_call_user(schedule.id))
81
- response.reply(t('on_call_lookup.response', name: user.name, email: user.email, schedule_name: schedule_name))
82
- else
83
- response.reply(t('on_call_lookup.no_one_on_call', schedule_name: schedule_name))
84
- end
85
- end
86
- # rubocop:enable Metrics/AbcSize
87
-
88
- # rubocop:disable Metrics/AbcSize
89
- def pager_me(response)
90
- schedule_name = response.match_data[1].strip
91
- schedule = pd_client.get_schedules.schedules.find { |s| s.name.casecmp(schedule_name) == 0 }
92
- return response.reply(t('on_call_lookup.no_matching_schedule', schedule_name: schedule_name)) unless schedule
93
-
94
- email = fetch_user(response.user)
95
- return response.reply(t('identify.missing')) unless email
96
-
97
- users = pd_client.get_users(query: email)
98
- return response.reply(t('identify.unrecognised')) unless users.total == 1
99
-
100
- override = take_pager(schedule.id, users.users.first.id, response.match_data[2].strip.to_i)
101
- return response.reply(t('pager_me.failure')) unless override
102
-
103
- response.reply(t('pager_me.success', name: override.user.name, email: override.user.email, finish: override.end))
104
- end
105
- # rubocop:enable Metrics/AbcSize
106
-
107
- def identify(response)
108
- email = response.match_data['email']
109
- stored_email = fetch_user(response.user)
110
- return response.reply(t('identify.already')) if stored_email
111
- store_user(response.user, email)
112
- response.reply(t('identify.complete'))
113
- end
114
-
115
- def forget(response)
116
- stored_email = fetch_user(response.user)
117
- return response.reply(t('forget.unknown')) unless stored_email
118
- delete_user(response.user)
119
- response.reply(t('forget.complete'))
120
- end
121
-
122
- private
123
-
124
- def lookup_on_call_user(schedule_id)
125
- now = ::Time.now.utc
126
- pd_client.get_schedule_users(
127
- id: schedule_id,
128
- since: now.iso8601,
129
- until: (now + 3600).iso8601
130
- ).first
131
- end
132
- end
133
-
134
- Lita.register_handler(PagerdutyUtility)
135
- end
136
- end
@@ -1,64 +0,0 @@
1
- # Helper Code for PagerDuty Lita Handler
2
- module PagerdutyHelper
3
- # Incident-related functions
4
- module Incident
5
- def format_incident(incident)
6
- t('incident.info', id: incident.id,
7
- subject: incident.trigger_summary_data.subject,
8
- url: incident.html_url,
9
- assigned: incident.assigned_to_user.nil? ? 'none' : incident.assigned_to_user.email)
10
- end
11
-
12
- def resolve_incident(incident_id)
13
- incident = fetch_incident(incident_id)
14
- return t('incident.not_found', id: incident_id) if incident == 'No results'
15
- return t('incident.already_set', id: incident_id, status: incident.status) if incident.status == 'resolved'
16
- results = incident.resolve
17
- if results.key?('status') && results['status'] == 'resolved'
18
- t('incident.resolved', id: incident_id)
19
- else
20
- t('incident.unable_to_resolve', id: incident_id)
21
- end
22
- end
23
-
24
- def fetch_all_incidents
25
- client = pd_client
26
- list = []
27
- # FIXME: Workaround on current PD Gem
28
- client.incidents.incidents.each do |incident|
29
- list.push(incident) if incident.status != 'resolved'
30
- end
31
- list
32
- end
33
-
34
- def fetch_my_incidents(email)
35
- # FIXME: Workaround
36
- incidents = fetch_all_incidents
37
- list = []
38
- incidents.each do |incident|
39
- list.push(incident) if incident.assigned_to_user.email == email
40
- end
41
- list
42
- end
43
-
44
- def fetch_incident(incident_id)
45
- client = pd_client
46
- client.get_incident(id: incident_id)
47
- end
48
-
49
- # rubocop:disable Metrics/AbcSize
50
- def acknowledge_incident(incident_id)
51
- incident = fetch_incident(incident_id)
52
- return t('incident.not_found', id: incident_id) if incident == 'No results'
53
- return t('incident.already_set', id: incident_id, status: incident.status) if incident.status == 'acknowledged'
54
- return t('incident.already_set', id: incident_id, status: incident.status) if incident.status == 'resolved'
55
- results = incident.acknowledge
56
- if results.key?('status') && results['status'] == 'acknowledged'
57
- t('incident.acknowledged', id: incident_id)
58
- else
59
- t('incident.unable_to_acknowledge', id: incident_id)
60
- end
61
- end
62
- # rubocop:enable Metrics/AbcSize
63
- end
64
- end
@@ -1,8 +0,0 @@
1
- # Helper Code for PagerDuty Lita Handler
2
- module PagerdutyHelper
3
- # Utility functions
4
- module Regex
5
- INCIDENT_ID_PATTERN = /(?<incident_id>[a-zA-Z0-9+]+)/
6
- EMAIL_PATTERN = /(?<email>[\w+\-.]+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+)/i
7
- end
8
- end
@@ -1,43 +0,0 @@
1
- # Helper Code for PagerDuty Lita Handler
2
- module PagerdutyHelper
3
- # Utility functions
4
- module Utility
5
- def pd_client
6
- ::Pagerduty.new(token: config.api_key, subdomain: config.subdomain)
7
- end
8
-
9
- def format_note(incident, note)
10
- t('note.show', id: incident.id, content: note.content, email: note.user.email)
11
- end
12
-
13
- def store_user(user, email)
14
- redis.set(format_user(user), email)
15
- end
16
-
17
- def fetch_user(user)
18
- redis.get(format_user(user))
19
- end
20
-
21
- def delete_user(user)
22
- redis.del(format_user(user))
23
- end
24
-
25
- def format_user(user)
26
- "email_#{user.id}"
27
- end
28
-
29
- def take_pager(schedule_id, user_id, duration_mins)
30
- from = ::Time.now.utc + 10
31
- to = from + (60 * duration_mins)
32
-
33
- pd_client.create_schedule_override(
34
- id: schedule_id,
35
- override: {
36
- user_id: user_id,
37
- start: from.iso8601,
38
- end: to.iso8601
39
- }
40
- )
41
- end
42
- end
43
- end
@@ -1,95 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Lita::Handlers::PagerdutyAck, lita_handler: true do
4
- include_context 'basic fixtures'
5
-
6
- it do
7
- is_expected.to route_command('pager ack all').to(:ack_all)
8
- is_expected.to route_command('pager ack mine').to(:ack_mine)
9
- is_expected.to route_command('pager ack ABC123').to(:ack)
10
- end
11
-
12
- describe '#ack_all' do
13
- describe 'when there are acknowledgable incidents' do
14
- it 'shows them as acknowledged' do
15
- expect(Pagerduty).to receive(:new).twice { incidents }
16
- send_command('pager ack all')
17
- expect(replies.last).to eq('Acknowledged: ABC789')
18
- end
19
- end
20
-
21
- describe 'when there are no acknowledgable incidents' do
22
- it 'shows a warning' do
23
- expect(Pagerduty).to receive(:new) { no_incidents }
24
- send_command('pager ack all')
25
- expect(replies.last).to eq('No triggered, open, or acknowledged ' \
26
- 'incidents')
27
- end
28
- end
29
- end
30
-
31
- describe '#ack_mine' do
32
- describe 'when there are acknowledgable incidents for the user' do
33
- it 'shows them as acknowledged' do
34
- bar = Lita::User.create(123, name: 'bar')
35
- expect(Pagerduty).to receive(:new).twice { incidents }
36
- send_command('pager identify bar@example.com', as: bar)
37
- send_command('pager ack mine', as: bar)
38
- expect(replies.last).to eq('Acknowledged: ABC789')
39
- end
40
- end
41
-
42
- describe 'when there are no acknowledgable incidents for the user' do
43
- it 'shows a warning' do
44
- foo = Lita::User.create(123, name: 'foo')
45
- expect(Pagerduty).to receive(:new) { incidents }
46
- send_command('pager identify foo@example.com', as: foo)
47
- send_command('pager ack mine', as: foo)
48
- expect(replies.last).to eq('You have no triggered, open, or ' \
49
- 'acknowledged incidents')
50
- end
51
- end
52
-
53
- describe 'when the user has not identified themselves' do
54
- it 'shows a warning' do
55
- send_command('pager ack mine')
56
- expect(replies.last).to eq('You have not identified yourself (use ' \
57
- 'the help command for more info)')
58
- end
59
- end
60
- end
61
-
62
- describe '#ack' do
63
- describe 'when the incident has not been acknowledged' do
64
- it 'shows the acknowledgement' do
65
- expect(Pagerduty).to receive(:new) { new_incident }
66
- send_command('pager ack ABC123')
67
- expect(replies.last).to eq('ABC123: Incident acknowledged')
68
- end
69
- end
70
-
71
- describe 'when the incident has already been acknowledged' do
72
- it 'shows the warning' do
73
- expect(Pagerduty).to receive(:new) { acknowledged_incident }
74
- send_command('pager ack ABC123')
75
- expect(replies.last).to eq('ABC123: Incident already acknowledged')
76
- end
77
- end
78
-
79
- describe 'when the incident does not exist' do
80
- it 'shows an error' do
81
- expect(Pagerduty).to receive(:new) { no_incident }
82
- send_command('pager ack ABC123')
83
- expect(replies.last).to eq('ABC123: Incident not found')
84
- end
85
- end
86
-
87
- describe 'when the incident cannot be acknowledged' do
88
- it 'shows that its unable to acknowledge' do
89
- expect(Pagerduty).to receive(:new) { unable_to_ack_incident }
90
- send_command('pager ack ABC123')
91
- expect(replies.last).to eq('ABC123: Unable to acknowledge incident')
92
- end
93
- end
94
- end
95
- end