flapjack 1.2.2 → 1.3.0rc1
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/.travis.yml +2 -0
- data/CHANGELOG.md +4 -0
- data/etc/flapjack_config.yaml.example +24 -12
- data/features/notifications.feature +12 -0
- data/features/steps/notifications_steps.rb +59 -0
- data/features/support/env.rb +1 -0
- data/flapjack.gemspec +1 -1
- data/lib/flapjack/cli/server.rb +4 -1
- data/lib/flapjack/coordinator.rb +1 -2
- data/lib/flapjack/data/contact.rb +9 -1
- data/lib/flapjack/data/migration.rb +5 -6
- data/lib/flapjack/gateways/sms_nexmo/alert.text.erb +6 -0
- data/lib/flapjack/gateways/sms_nexmo/rollup.text.erb +2 -0
- data/lib/flapjack/gateways/{sms_gammu.rb → sms_nexmo.rb} +59 -55
- data/lib/flapjack/gateways/web/public/js/modules/contact.js +2 -1
- data/lib/flapjack/notifier.rb +1 -1
- data/lib/flapjack/pikelet.rb +2 -2
- data/lib/flapjack/version.rb +1 -1
- data/spec/lib/flapjack/coordinator_spec.rb +1 -3
- data/spec/lib/flapjack/data/contact_spec.rb +2 -2
- data/spec/lib/flapjack/gateways/sms_nexmo_spec.rb +65 -0
- data/tasks/support/flapjack_config_benchmark.yaml +1 -0
- metadata +14 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 185fa9c36254b3a0b485d15b0e68dbf2dc78293f
|
4
|
+
data.tar.gz: 3d1498ef293b573d05c220d937669eb86e27c397
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d70b5835bddcd1fefd168214af474e0cd3dc415a771549cf2565d8f77bbf4818e7a4cd1e885e21f33148da686cc12d37481ae0bc2844d39b28cd66c20a1150fa
|
7
|
+
data.tar.gz: 5cba7f54a06919f5775cae0ab15db54158bbde4d8f21b343d8e204c10fc0a9d5c302423b492b36824d18913169613d691782ba663c9fc9351e1df84ce93884fb
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
## Flapjack Changelog
|
2
2
|
|
3
|
+
# 1.3.0rc1 - 2015-02-13
|
4
|
+
- Feature: Add Nexmo SMS gateway
|
5
|
+
- Bug: Revert addition of sms_gammu gateway #759 (@ali-graham)
|
6
|
+
|
3
7
|
# 1.2.2 - 2015-02-10
|
4
8
|
- Feature: Add the maint subcommand to the chat bot to fix #664 (@someword)
|
5
9
|
- Feature: support for Ruby 2.2, drop support for 1.9, removes Resque due to gem dependencies #760 (@ali-graham)
|
@@ -39,8 +39,8 @@ production:
|
|
39
39
|
queue: notifications
|
40
40
|
email_queue: email_notifications
|
41
41
|
sms_queue: sms_notifications
|
42
|
+
sms_nexmo_queue: sms_nexmo_notifications
|
42
43
|
sms_twilio_queue: sms_twilio_notifications
|
43
|
-
sms_gammu_queue: sms_gammu_notifications
|
44
44
|
sns_queue: sns_notifications
|
45
45
|
jabber_queue: jabber_notifications
|
46
46
|
pagerduty_queue: pagerduty_notifications
|
@@ -117,22 +117,20 @@ production:
|
|
117
117
|
#templates:
|
118
118
|
# rollup.text: '/etc/flapjack/templates/sms_twilio/rollup.text.erb'
|
119
119
|
# alert.text: '/etc/flapjack/templates/sms_twilio/alert.text.erb'
|
120
|
-
# Sends SMS notifications via
|
121
|
-
|
120
|
+
# Sends SMS notifications via Nexmo
|
121
|
+
sms_nexmo:
|
122
122
|
enabled: yes
|
123
|
-
queue:
|
123
|
+
queue: sms_nexmo_notifications
|
124
124
|
from: "xxxxxxxxx"
|
125
|
-
|
126
|
-
|
127
|
-
mysql_username: "gammu"
|
128
|
-
mysql_password: "xxxxxxxx"
|
125
|
+
api_key: "APIKEY"
|
126
|
+
secret: "s3cr3t"
|
129
127
|
logger:
|
130
128
|
level: INFO
|
131
129
|
syslog_errors: yes
|
132
130
|
# location of custom alert templates
|
133
|
-
templates:
|
134
|
-
|
135
|
-
|
131
|
+
#templates:
|
132
|
+
# rollup.text: '/etc/flapjack/templates/sms/rollup.text.erb'
|
133
|
+
# alert.text: '/etc/flapjack/templates/sms/alert.text.erb'
|
136
134
|
# Generates SNS notifications
|
137
135
|
sns:
|
138
136
|
enabled: no
|
@@ -272,6 +270,7 @@ development:
|
|
272
270
|
queue: notifications
|
273
271
|
email_queue: email_notifications
|
274
272
|
sms_queue: sms_notifications
|
273
|
+
sms_nexmo_queue: sms_nexmo_notifications
|
275
274
|
sms_twilio_queue: sms_twilio_notifications
|
276
275
|
jabber_queue: jabber_notifications
|
277
276
|
pagerduty_queue: pagerduty_notifications
|
@@ -348,7 +347,20 @@ development:
|
|
348
347
|
#templates:
|
349
348
|
# rollup.text: '/etc/flapjack/templates/sms_twilio/rollup.text.erb'
|
350
349
|
# alert.text: '/etc/flapjack/templates/sms_twilio/alert.text.erb'
|
351
|
-
#
|
350
|
+
# Sends SMS notifications via Nexmo
|
351
|
+
sms_nexmo:
|
352
|
+
enabled: no
|
353
|
+
queue: sms_nexmo_notifications
|
354
|
+
from: "xxxxxxxxx"
|
355
|
+
api_key: "APIKEY"
|
356
|
+
secret: "s3cr3t"
|
357
|
+
logger:
|
358
|
+
level: INFO
|
359
|
+
syslog_errors: yes
|
360
|
+
# location of custom alert templates
|
361
|
+
#templates:
|
362
|
+
# rollup.text: '/etc/flapjack/templates/sms/rollup.text.erb'
|
363
|
+
# alert.text: '/etc/flapjack/templates/sms/alert.text.erb'
|
352
364
|
# Connects to an XMPP (jabber) server, sends notifications (to rooms and individuals),
|
353
365
|
# handles acknowledgements from jabber users and other commands.
|
354
366
|
jabber:
|
@@ -11,6 +11,13 @@ Feature: notifications
|
|
11
11
|
Then an SMS notification for entity 'example.com' should be queued for the user
|
12
12
|
And an email notification for entity 'example.com' should not be queued for the user
|
13
13
|
|
14
|
+
Scenario: Queue a Nexmo SMS notification
|
15
|
+
Given the user wants to receive Nexmo SMS notifications for entity 'example.com'
|
16
|
+
When an event notification is generated for entity 'example.com'
|
17
|
+
Then a Nexmo SMS notification for entity 'example.com' should be queued for the user
|
18
|
+
And an email notification for entity 'example.com' should not be queued for the user
|
19
|
+
And an SMS notification for entity 'example.com' should not be queued for the user
|
20
|
+
|
14
21
|
Scenario: Queue an SNS notification
|
15
22
|
Given the user wants to receive SNS notifications for entity 'example.com'
|
16
23
|
When an event notification is generated for entity 'example.com'
|
@@ -37,6 +44,11 @@ Feature: notifications
|
|
37
44
|
When the SMS notification handler runs successfully
|
38
45
|
Then the user should receive an SMS notification
|
39
46
|
|
47
|
+
Scenario: Send a queued Nexmo SMS notification
|
48
|
+
Given a user Nexmo SMS notification has been queued for entity 'example.com'
|
49
|
+
When the Nexmo SMS notification handler runs successfully
|
50
|
+
Then the user should receive an Nexmo SMS notification
|
51
|
+
|
40
52
|
Scenario: Send a queued SNS notification
|
41
53
|
Given a user SNS notification has been queued for entity 'example.com'
|
42
54
|
When the SNS notification handler runs successfully
|
@@ -26,6 +26,18 @@ Given /^the user wants to receive SMS notifications for entity '([\w\.\-]+)'$/ d
|
|
26
26
|
:redis => @notifier_redis )
|
27
27
|
end
|
28
28
|
|
29
|
+
Given /^the user wants to receive Nexmo SMS notifications for entity '([\w\.\-]+)'$/ do |entity|
|
30
|
+
add_contact( 'id' => '0999',
|
31
|
+
'first_name' => 'John',
|
32
|
+
'last_name' => 'Smith',
|
33
|
+
'email' => 'johns@example.dom',
|
34
|
+
'media' => {'sms_nexmo' => '+61888888888'} )
|
35
|
+
Flapjack::Data::Entity.add({'id' => '5000',
|
36
|
+
'name' => entity,
|
37
|
+
'contacts' => ["0999"]},
|
38
|
+
:redis => @notifier_redis )
|
39
|
+
end
|
40
|
+
|
29
41
|
Given /^the user wants to receive SNS notifications for entity '([\w\.\-]+)'$/ do |entity|
|
30
42
|
add_contact( 'id' => '0999',
|
31
43
|
'first_name' => 'John',
|
@@ -99,6 +111,11 @@ Then /^an SMS notification for entity '([\w\.\-]+)' should be queued for the use
|
|
99
111
|
expect(queue.select {|n| n['event_id'] =~ /#{entity}:ping/ }).not_to be_empty
|
100
112
|
end
|
101
113
|
|
114
|
+
Then /^a Nexmo SMS notification for entity '([\w\.\-]+)' should be queued for the user$/ do |entity|
|
115
|
+
queue = redis_peek('sms_nexmo_notifications')
|
116
|
+
expect(queue.select {|n| n['event_id'] =~ /#{entity}:ping/ }).not_to be_empty
|
117
|
+
end
|
118
|
+
|
102
119
|
Then /^an SNS notification for entity '([\w\.\-]+)' should be queued for the user$/ do |entity|
|
103
120
|
queue = redis_peek('sns_notifications')
|
104
121
|
expect(queue.select {|n| n['event_id'] =~ /#{entity}:ping/ }).not_to be_empty
|
@@ -114,6 +131,11 @@ Then /^an SMS notification for entity '([\w\.\-]+)' should not be queued for the
|
|
114
131
|
expect(queue.select {|n| n['event_id'] =~ /#{entity}:ping/ }).to be_empty
|
115
132
|
end
|
116
133
|
|
134
|
+
Then /^an Nexmo SMS notification for entity '([\w\.\-]+)' should not be queued for the user$/ do |entity|
|
135
|
+
queue = redis_peek('sms_nexmo_notifications')
|
136
|
+
expect(queue.select {|n| n['event_id'] =~ /#{entity}:ping/ }).to be_empty
|
137
|
+
end
|
138
|
+
|
117
139
|
Then /^an email notification for entity '([\w\.\-]+)' should not be queued for the user$/ do |entity|
|
118
140
|
queue = redis_peek('email_notifications')
|
119
141
|
expect(queue.select {|n| n['event_id'] =~ /#{entity}:ping/ }).to be_empty
|
@@ -139,6 +161,26 @@ Given /^a user SMS notification has been queued for entity '([\w\.\-]+)'$/ do |e
|
|
139
161
|
:redis => @notifier_redis)
|
140
162
|
end
|
141
163
|
|
164
|
+
Given /^a user Nexmo SMS notification has been queued for entity '([\w\.\-]+)'$/ do |entity|
|
165
|
+
Flapjack::Data::Entity.add({'id' => '5000',
|
166
|
+
'name' => entity},
|
167
|
+
:redis => @redis )
|
168
|
+
@sms_nexmo_notification = {'notification_type' => 'problem',
|
169
|
+
'contact_first_name' => 'John',
|
170
|
+
'contact_last_name' => 'Smith',
|
171
|
+
'state' => 'critical',
|
172
|
+
'summary' => 'Socket timeout after 10 seconds',
|
173
|
+
'time' => Time.now.to_i,
|
174
|
+
'event_id' => "#{entity}:ping",
|
175
|
+
'address' => '+61412345678',
|
176
|
+
'id' => 1,
|
177
|
+
'state_duration' => 30,
|
178
|
+
'duration' => 45}
|
179
|
+
|
180
|
+
Flapjack::Data::Alert.add('sms_nexmo_notifications', @sms_nexmo_notification,
|
181
|
+
:redis => @notifier_redis)
|
182
|
+
end
|
183
|
+
|
142
184
|
Given /^a user SNS notification has been queued for entity '([\w\.\-]+)'$/ do |entity|
|
143
185
|
Flapjack::Data::Entity.add({'id' => '5000',
|
144
186
|
'name' => entity},
|
@@ -189,6 +231,19 @@ When /^the SMS notification handler runs successfully$/ do
|
|
189
231
|
drain_alerts('sms_notifications', @sms_messagenet)
|
190
232
|
end
|
191
233
|
|
234
|
+
When /^the Nexmo SMS notification handler runs successfully$/ do
|
235
|
+
# poor man's stubbing
|
236
|
+
Nexmo::Client.class_eval {
|
237
|
+
def send_message(args = {})
|
238
|
+
end
|
239
|
+
}
|
240
|
+
@sms_nexmo = Flapjack::Gateways::SmsNexmo.new(:config => {
|
241
|
+
'api_key' => 'THEAPIKEY', 'secret' => 'secret', 'from' => 'someone',
|
242
|
+
}, :redis_config => @redis_opts, :logger => @logger)
|
243
|
+
|
244
|
+
drain_alerts('sms_nexmo_notifications', @sms_nexmo)
|
245
|
+
end
|
246
|
+
|
192
247
|
When /^the SNS notification handler runs successfully$/ do
|
193
248
|
@request = stub_request(:post, /amazonaws\.com/)
|
194
249
|
|
@@ -264,6 +319,10 @@ Then /^the user should( not)? receive an SMS notification$/ do |negativity|
|
|
264
319
|
expect(@sms_messagenet.instance_variable_get('@sent')).to eq(negativity.nil? ? 1 : 0)
|
265
320
|
end
|
266
321
|
|
322
|
+
Then /^the user should( not)? receive an Nexmo SMS notification$/ do |negativity|
|
323
|
+
expect(@sms_nexmo.instance_variable_get('@sent')).to eq(negativity.nil? ? 1 : 0)
|
324
|
+
end
|
325
|
+
|
267
326
|
Then /^the user should( not)? receive an SNS notification$/ do |negativity|
|
268
327
|
expect(@request).to have_been_requested
|
269
328
|
expect(@aws_sns.instance_variable_get('@sent')).to eq(negativity.nil? ? 1 : 0)
|
data/features/support/env.rb
CHANGED
@@ -168,6 +168,7 @@ Before('@notifier') do
|
|
168
168
|
:redis_config => redis_opts,
|
169
169
|
:config => {'email_queue' => 'email_notifications',
|
170
170
|
'sms_queue' => 'sms_notifications',
|
171
|
+
'sms_nexmo_queue' => 'sms_nexmo_notifications',
|
171
172
|
'sns_queue' => 'sns_notifications',
|
172
173
|
'default_contact_timezone' => 'America/New_York'})
|
173
174
|
@notifier_redis = @notifier.instance_variable_get('@redis')
|
data/flapjack.gemspec
CHANGED
data/lib/flapjack/cli/server.rb
CHANGED
@@ -60,7 +60,10 @@ module Flapjack
|
|
60
60
|
return_value = start_server
|
61
61
|
}
|
62
62
|
puts " done."
|
63
|
-
|
63
|
+
unless return_value.nil? || [Signal.list['INT'] + 128,
|
64
|
+
Signal.list['TERM'] + 128].include?(return_value)
|
65
|
+
exit_now!(return_value)
|
66
|
+
end
|
64
67
|
end
|
65
68
|
end
|
66
69
|
|
data/lib/flapjack/coordinator.rb
CHANGED
@@ -43,7 +43,7 @@ module Flapjack
|
|
43
43
|
loop do
|
44
44
|
while sig = @received_signals.shift do
|
45
45
|
case sig
|
46
|
-
when 'INT', 'TERM'
|
46
|
+
when 'INT', 'TERM'
|
47
47
|
@exit_value = Signal.list[sig] + 128
|
48
48
|
raise Interrupt
|
49
49
|
when 'HUP'
|
@@ -127,7 +127,6 @@ module Flapjack
|
|
127
127
|
Kernel.trap('INT') { @received_signals << 'INT' unless @received_signals.include?('INT') }
|
128
128
|
Kernel.trap('TERM') { @received_signals << 'TERM' unless @received_signals.include?('TERM') }
|
129
129
|
unless RbConfig::CONFIG['host_os'] =~ /mswin|windows|cygwin/i
|
130
|
-
Kernel.trap('QUIT') { @received_signals << 'QUIT' unless @received_signals.include?('QUIT') }
|
131
130
|
Kernel.trap('HUP') { @received_signals << 'HUP' unless @received_signals.include?('HUP') }
|
132
131
|
end
|
133
132
|
end
|
@@ -19,7 +19,15 @@ module Flapjack
|
|
19
19
|
attr_accessor :id, :first_name, :last_name, :email, :media,
|
20
20
|
:media_intervals, :media_rollup_thresholds, :pagerduty_credentials
|
21
21
|
|
22
|
-
ALL_MEDIA = [
|
22
|
+
ALL_MEDIA = [
|
23
|
+
'email',
|
24
|
+
'sms',
|
25
|
+
'sms_twilio',
|
26
|
+
'sms_nexmo',
|
27
|
+
'jabber',
|
28
|
+
'pagerduty',
|
29
|
+
'sns'
|
30
|
+
]
|
23
31
|
|
24
32
|
def self.all(options = {})
|
25
33
|
raise "Redis connection not set" unless redis = options[:redis]
|
@@ -81,12 +81,12 @@ module Flapjack
|
|
81
81
|
:redis => redis, :logger => logger)
|
82
82
|
|
83
83
|
begin
|
84
|
-
logger.warn "Upgrading Flapjack's entity/check Redis indexes..." unless logger.nil?
|
85
|
-
|
86
84
|
check_names = redis.keys('check:*').map {|c| c.sub(/^check:/, '') } |
|
87
85
|
Flapjack::Data::EntityCheck.find_current_names(:redis => redis)
|
88
86
|
|
89
87
|
unless check_names.empty?
|
88
|
+
logger.warn "Upgrading Flapjack's entity/check Redis indexes..." unless logger.nil?
|
89
|
+
|
90
90
|
timestamp = Time.now.to_i
|
91
91
|
|
92
92
|
check_names.each do |ecn|
|
@@ -95,10 +95,9 @@ module Flapjack
|
|
95
95
|
redis.zadd("all_checks:#{entity_name}", timestamp, check)
|
96
96
|
# not deleting the check hashes, they store useful data
|
97
97
|
end
|
98
|
+
logger.warn "Checks indexed." unless logger.nil?
|
98
99
|
end
|
99
100
|
|
100
|
-
logger.warn "Checks indexed." unless logger.nil?
|
101
|
-
|
102
101
|
entity_name_keys = redis.keys("entity_id:*")
|
103
102
|
unless entity_name_keys.empty?
|
104
103
|
ids = redis.mget(*entity_name_keys)
|
@@ -112,10 +111,10 @@ module Flapjack
|
|
112
111
|
redis.del(enk)
|
113
112
|
redis.del("entity:#{entity_id}")
|
114
113
|
end
|
114
|
+
logger.warn "Entities indexed." unless logger.nil?
|
115
115
|
end
|
116
116
|
|
117
|
-
logger.warn "
|
118
|
-
logger.warn "Indexing complete." unless logger.nil?
|
117
|
+
logger.warn "Indexing complete." unless logger.nil? || (check_names.empty? && entity_name_keys.empty?)
|
119
118
|
ensure
|
120
119
|
semaphore.release
|
121
120
|
end
|
@@ -0,0 +1,6 @@
|
|
1
|
+
<% summary = @alert.summary -%>
|
2
|
+
<%= @alert.type_sentence_case %>: '<%= @alert.check %>' on <%= @alert.entity -%>
|
3
|
+
<% unless ['acknowledgement', 'test'].include?(@alert.notification_type) -%>
|
4
|
+
is <%= @alert.state_title_case -%>
|
5
|
+
<% end -%>
|
6
|
+
at <%= Time.at(@alert.time).strftime('%-d %b %H:%M') %><%= (summary.nil? || summary.empty?) ? '' : ", #{summary}" -%>
|
@@ -1,17 +1,19 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require 'em-synchrony'
|
4
|
-
require
|
4
|
+
require 'em-synchrony/em-http'
|
5
|
+
require 'active_support/inflector'
|
6
|
+
|
7
|
+
require 'flapjack/redis_pool'
|
8
|
+
|
5
9
|
require 'flapjack/data/alert'
|
6
10
|
require 'flapjack/utility'
|
7
11
|
|
12
|
+
require 'nexmo'
|
13
|
+
|
8
14
|
module Flapjack
|
9
15
|
module Gateways
|
10
|
-
class
|
11
|
-
INSERT_QUERY = <<-SQL
|
12
|
-
INSERT INTO outbox (InsertIntoDB, TextDecoded, DestinationNumber, CreatorID, Class)
|
13
|
-
VALUES ('%s', '%s', '%s', '%s', %s)
|
14
|
-
SQL
|
16
|
+
class SmsNexmo
|
15
17
|
|
16
18
|
include Flapjack::Utility
|
17
19
|
|
@@ -19,16 +21,10 @@ module Flapjack
|
|
19
21
|
@config = opts[:config]
|
20
22
|
@logger = opts[:logger]
|
21
23
|
@redis_config = opts[:redis_config] || {}
|
22
|
-
|
23
|
-
if @config.nil? || (@config.respond_to?(:empty?) && @config.empty?)
|
24
|
-
@logger.error "sms_gammu config is missing"
|
25
|
-
return
|
26
|
-
end
|
27
|
-
|
28
24
|
@redis = Flapjack::RedisPool.new(:config => @redis_config, :size => 1, :logger => @logger)
|
29
25
|
|
30
26
|
@logger.info("starting")
|
31
|
-
@logger.debug("new
|
27
|
+
@logger.debug("new sms_nexmo gateway pikelet with the following options: #{@config.inspect}")
|
32
28
|
|
33
29
|
@sent = 0
|
34
30
|
end
|
@@ -44,76 +40,84 @@ module Flapjack
|
|
44
40
|
end
|
45
41
|
|
46
42
|
def start
|
47
|
-
@db = Mysql2::EM::Client.new(:host => @config["mysql_host"],
|
48
|
-
:database => @config["mysql_database"],
|
49
|
-
:username => @config["mysql_username"],
|
50
|
-
:password => @config["mysql_password"])
|
51
|
-
|
52
43
|
queue = @config['queue']
|
53
44
|
|
54
45
|
until @should_quit
|
55
46
|
begin
|
56
|
-
@logger.debug("
|
47
|
+
@logger.debug("sms_nexmo gateway is going into blpop mode on #{queue}")
|
57
48
|
deliver( Flapjack::Data::Alert.next(queue, :redis => @redis, :logger => @logger) )
|
58
49
|
rescue => e
|
59
|
-
@logger.error "Error generating or dispatching SMS
|
50
|
+
@logger.error "Error generating or dispatching SMS Nexmo message: #{e.class}: #{e.message}\n" +
|
60
51
|
e.backtrace.join("\n")
|
61
52
|
end
|
62
53
|
end
|
63
54
|
end
|
64
55
|
|
65
56
|
def deliver(alert)
|
66
|
-
|
67
|
-
|
68
|
-
from
|
69
|
-
|
70
|
-
|
57
|
+
api_key = @config["api_key"]
|
58
|
+
secret = @config["secret"]
|
59
|
+
from = @config["from"]
|
60
|
+
|
61
|
+
address = alert.address
|
62
|
+
notification_id = alert.notification_id
|
63
|
+
message_type = alert.rollup ? 'rollup' : 'alert'
|
64
|
+
|
65
|
+
my_dir = File.dirname(__FILE__)
|
66
|
+
sms_template_path = case
|
67
|
+
when @config.has_key?('templates') && @config['templates']["#{message_type}.text"]
|
68
|
+
@config['templates']["#{message_type}.text"]
|
69
|
+
else
|
70
|
+
my_dir + "/sms_nexmo/#{message_type}.text.erb"
|
71
|
+
end
|
72
|
+
sms_template = ERB.new(File.read(sms_template_path), nil, '-')
|
71
73
|
|
72
|
-
|
73
|
-
|
74
|
+
@alert = alert
|
75
|
+
bnd = binding
|
74
76
|
|
75
|
-
|
76
|
-
|
77
|
+
begin
|
78
|
+
message = sms_template.result(bnd).chomp
|
79
|
+
rescue => e
|
80
|
+
@logger.error "Error while excuting the ERB for an sms: " +
|
81
|
+
"ERB being executed: #{sms_template_path}"
|
82
|
+
raise
|
77
83
|
end
|
78
84
|
|
79
|
-
|
80
|
-
|
85
|
+
if @config.nil? || (@config.respond_to?(:empty?) && @config.empty?)
|
86
|
+
@logger.error "Messagenet config is missing"
|
81
87
|
return
|
82
88
|
end
|
83
89
|
|
84
|
-
|
85
|
-
rescue => e
|
86
|
-
@logger.error "Error generating or delivering sms to #{contents['address']}: #{e.class}: #{e.message}"
|
87
|
-
@logger.error e.backtrace.join("\n")
|
88
|
-
raise
|
89
|
-
end
|
90
|
+
errors = []
|
90
91
|
|
91
|
-
|
92
|
-
message_type = @alert.rollup ? 'rollup' : 'alert'
|
93
|
-
template_path = @config['templates']["#{message_type}.text"]
|
94
|
-
template = ERB.new(File.read(template_path), nil, '-')
|
92
|
+
safe_message = truncate(message, 159)
|
95
93
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
94
|
+
[[api_key, "Nexmo api_key is missing"],
|
95
|
+
[secret, "Twilio auth_token is missing"],
|
96
|
+
[from, "SMS from address is missing"],
|
97
|
+
[address, "SMS address is missing"],
|
98
|
+
[notification_id, "Notification id is missing"]].each do |val_err|
|
99
|
+
|
100
|
+
next unless val_err.first.nil? || (val_err.first.respond_to?(:empty?) && val_err.first.empty?)
|
101
|
+
errors << val_err.last
|
102
|
+
end
|
103
|
+
|
104
|
+
unless errors.empty?
|
105
|
+
errors.each {|err| @logger.error err }
|
106
|
+
return
|
103
107
|
end
|
104
|
-
end
|
105
108
|
|
106
|
-
def send_message(message, from, to)
|
107
109
|
begin
|
108
|
-
|
110
|
+
nexmo = Nexmo::Client.new(key: api_key, secret: secret)
|
111
|
+
nexmo.send_message(from: from, to: address, text: safe_message)
|
109
112
|
@sent += 1
|
110
|
-
@alert.record_send_success!
|
111
|
-
@logger.debug "Sent SMS via Gammu"
|
112
113
|
rescue => e
|
113
|
-
@logger.error "
|
114
|
+
@logger.error "Error sending SMS via Nexmo: #{e.message}"
|
114
115
|
end
|
116
|
+
rescue => e
|
117
|
+
@logger.error "Error generating or delivering sms to #{alert.address}: #{e.class}: #{e.message}"
|
118
|
+
@logger.error e.backtrace.join("\n")
|
119
|
+
raise
|
115
120
|
end
|
116
|
-
|
117
121
|
end
|
118
122
|
end
|
119
123
|
end
|
@@ -279,7 +279,7 @@
|
|
279
279
|
initialize: function(options) {
|
280
280
|
var context = this;
|
281
281
|
|
282
|
-
_.each(['email', 'sms', 'sms_twilio', 'sns', 'jabber'], function(type) {
|
282
|
+
_.each(['email', 'sms', 'sms_twilio', 'sms_nexmo', 'sns', 'jabber'], function(type) {
|
283
283
|
var medium = context.collection.find(function(cm) {
|
284
284
|
return cm.get('type') == type;
|
285
285
|
});
|
@@ -335,6 +335,7 @@
|
|
335
335
|
'email' : 'Email',
|
336
336
|
'sms' : 'SMS (MessageNet)',
|
337
337
|
'sms_twilio' : 'SMS (Twilio)',
|
338
|
+
'sms_nexmo' : 'SMS (Nexmo)',
|
338
339
|
'sns' : 'SMS (Amazon SNS)',
|
339
340
|
'jabber' : 'Jabber'
|
340
341
|
};
|
data/lib/flapjack/notifier.rb
CHANGED
@@ -16,7 +16,7 @@ require 'flapjack/utility'
|
|
16
16
|
require 'flapjack/gateways/email'
|
17
17
|
require 'flapjack/gateways/sms_messagenet'
|
18
18
|
require 'flapjack/gateways/sms_twilio'
|
19
|
-
require 'flapjack/gateways/
|
19
|
+
require 'flapjack/gateways/sms_nexmo'
|
20
20
|
require 'flapjack/gateways/aws_sns'
|
21
21
|
|
22
22
|
module Flapjack
|
data/lib/flapjack/pikelet.rb
CHANGED
@@ -24,7 +24,7 @@ require 'flapjack/gateways/pagerduty'
|
|
24
24
|
require 'flapjack/gateways/email'
|
25
25
|
require 'flapjack/gateways/sms_messagenet'
|
26
26
|
require 'flapjack/gateways/sms_twilio'
|
27
|
-
require 'flapjack/gateways/
|
27
|
+
require 'flapjack/gateways/sms_nexmo'
|
28
28
|
require 'flapjack/gateways/aws_sns'
|
29
29
|
require 'flapjack/gateways/web'
|
30
30
|
require 'flapjack/logger'
|
@@ -104,8 +104,8 @@ module Flapjack
|
|
104
104
|
'oobetet' => Flapjack::Gateways::Oobetet,
|
105
105
|
'email' => Flapjack::Gateways::Email,
|
106
106
|
'sms' => Flapjack::Gateways::SmsMessagenet,
|
107
|
-
'sms_gammu' => Flapjack::Gateways::SmsGammu,
|
108
107
|
'sms_twilio' => Flapjack::Gateways::SmsTwilio,
|
108
|
+
'sms_nexmo' => Flapjack::Gateways::SmsNexmo,
|
109
109
|
'sns' => Flapjack::Gateways::AwsSns}
|
110
110
|
|
111
111
|
def self.create(type, opts = {})
|
data/lib/flapjack/version.rb
CHANGED
@@ -171,7 +171,6 @@ describe Flapjack::Coordinator do
|
|
171
171
|
|
172
172
|
expect(Kernel).to receive(:trap).with('INT').and_yield
|
173
173
|
expect(Kernel).to receive(:trap).with('TERM').and_yield
|
174
|
-
expect(Kernel).to receive(:trap).with('QUIT').and_yield
|
175
174
|
expect(Kernel).to receive(:trap).with('HUP').and_yield
|
176
175
|
|
177
176
|
expect(config).to receive(:all).and_return({})
|
@@ -179,7 +178,7 @@ describe Flapjack::Coordinator do
|
|
179
178
|
fc = Flapjack::Coordinator.new(config)
|
180
179
|
|
181
180
|
fc.send(:setup_signals)
|
182
|
-
expect(fc.instance_variable_get('@received_signals')).to eq(['INT', 'TERM', '
|
181
|
+
expect(fc.instance_variable_get('@received_signals')).to eq(['INT', 'TERM', 'HUP'])
|
183
182
|
end
|
184
183
|
|
185
184
|
it "only traps two system signals on Windows" do
|
@@ -189,7 +188,6 @@ describe Flapjack::Coordinator do
|
|
189
188
|
|
190
189
|
expect(Kernel).to receive(:trap).with('INT').and_yield
|
191
190
|
expect(Kernel).to receive(:trap).with('TERM').and_yield
|
192
|
-
expect(Kernel).not_to receive(:trap).with('QUIT')
|
193
191
|
expect(Kernel).not_to receive(:trap).with('HUP')
|
194
192
|
|
195
193
|
expect(config).to receive(:all).and_return({})
|
@@ -22,8 +22,8 @@ describe Flapjack::Data::Contact, :redis => true do
|
|
22
22
|
:tags => Set.new([]),
|
23
23
|
:time_restrictions => [],
|
24
24
|
:unknown_media => [],
|
25
|
-
:warning_media => ['email', 'sms', 'sms_twilio', '
|
26
|
-
:critical_media => ['email', 'sms', 'sms_twilio', '
|
25
|
+
:warning_media => ['email', 'sms', 'sms_twilio', 'sms_nexmo', 'jabber', 'pagerduty', 'sns'],
|
26
|
+
:critical_media => ['email', 'sms', 'sms_twilio', 'sms_nexmo', 'jabber', 'pagerduty', 'sns'],
|
27
27
|
:unknown_blackhole => false,
|
28
28
|
:warning_blackhole => false,
|
29
29
|
:critical_blackhole => false}
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'nexmo'
|
3
|
+
require 'flapjack/gateways/sms_nexmo'
|
4
|
+
|
5
|
+
describe Flapjack::Gateways::SmsNexmo, :logger => true do
|
6
|
+
let(:lock) { double(Monitor) }
|
7
|
+
|
8
|
+
let(:redis) { double('redis') }
|
9
|
+
|
10
|
+
let(:nexmo_client) { double(Nexmo::Client) }
|
11
|
+
|
12
|
+
let(:config) { {'api_key' => 'THEAPIKEY',
|
13
|
+
'secret' => 'secret',
|
14
|
+
'from' => 'flapjack'
|
15
|
+
}
|
16
|
+
}
|
17
|
+
|
18
|
+
let(:time) { Time.new(2013, 10, 31, 13, 45) }
|
19
|
+
|
20
|
+
let(:time_str) { Time.at(time).strftime('%-d %b %H:%M') }
|
21
|
+
|
22
|
+
let(:message) { {'notification_type' => 'recovery',
|
23
|
+
'contact_first_name' => 'John',
|
24
|
+
'contact_last_name' => 'Smith',
|
25
|
+
'state' => 'ok',
|
26
|
+
'summary' => 'smile',
|
27
|
+
'last_state' => 'problem',
|
28
|
+
'last_summary' => 'frown',
|
29
|
+
'time' => time.to_i,
|
30
|
+
'address' => '0034123456789',
|
31
|
+
'event_id' => 'example.com:ping',
|
32
|
+
'id' => '123456789',
|
33
|
+
'duration' => 55,
|
34
|
+
'state_duration' => 23
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
it "sends an SMS message" do
|
39
|
+
EM.synchrony do
|
40
|
+
expect(Flapjack::RedisPool).to receive(:new).and_return(redis)
|
41
|
+
expect(Nexmo::Client).to receive(:new).and_return(nexmo_client)
|
42
|
+
expect(nexmo_client).to receive(:send_message).
|
43
|
+
with(from: "flapjack",
|
44
|
+
to: "0034123456789",
|
45
|
+
text: "Recovery: 'ping' on example.com is OK at 31 Oct 13:45, smile")
|
46
|
+
|
47
|
+
alert = Flapjack::Data::Alert.new(message, :logger => @logger)
|
48
|
+
sms_nexmo = Flapjack::Gateways::SmsNexmo.new(:config => config, :logger => @logger)
|
49
|
+
sms_nexmo.deliver(alert)
|
50
|
+
EM.stop
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
it "does not send an SMS message with an invalid configuration" do
|
55
|
+
EM.synchrony do
|
56
|
+
expect(Flapjack::RedisPool).to receive(:new).and_return(redis)
|
57
|
+
expect_any_instance_of(Nexmo::Client).not_to receive(:send_message)
|
58
|
+
|
59
|
+
alert = Flapjack::Data::Alert.new(message, :logger => @logger)
|
60
|
+
sms_nexmo = Flapjack::Gateways::SmsNexmo.new(:config => config.reject {|k, v| k == 'secret'}, :logger => @logger)
|
61
|
+
sms_nexmo.deliver(alert)
|
62
|
+
EM.stop
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -21,6 +21,7 @@ test:
|
|
21
21
|
queue: notifications
|
22
22
|
email_queue: email_notifications
|
23
23
|
sms_queue: sms_notifications
|
24
|
+
sms_nexmo_queue: sms_nexmo_notifications
|
24
25
|
jabber_queue: jabber_notifications
|
25
26
|
pagerduty_queue: pagerduty_notifications
|
26
27
|
notification_log_file: log/notification_test.log
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: flapjack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lindsay Holmwood
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2015-02-
|
14
|
+
date: 2015-02-13 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: dante
|
@@ -350,19 +350,19 @@ dependencies:
|
|
350
350
|
- !ruby/object:Gem::Version
|
351
351
|
version: 1.6.2.1
|
352
352
|
- !ruby/object:Gem::Dependency
|
353
|
-
name:
|
353
|
+
name: nexmo
|
354
354
|
requirement: !ruby/object:Gem::Requirement
|
355
355
|
requirements:
|
356
|
-
- -
|
356
|
+
- - '='
|
357
357
|
- !ruby/object:Gem::Version
|
358
|
-
version:
|
358
|
+
version: 2.0.0
|
359
359
|
type: :runtime
|
360
360
|
prerelease: false
|
361
361
|
version_requirements: !ruby/object:Gem::Requirement
|
362
362
|
requirements:
|
363
|
-
- -
|
363
|
+
- - '='
|
364
364
|
- !ruby/object:Gem::Version
|
365
|
-
version:
|
365
|
+
version: 2.0.0
|
366
366
|
description: Flapjack is a distributed monitoring notification system that provides
|
367
367
|
a scalable method for processing streams of events from Nagios and deciding who
|
368
368
|
should be notified
|
@@ -470,10 +470,12 @@ files:
|
|
470
470
|
- lib/flapjack/gateways/oobetet.rb
|
471
471
|
- lib/flapjack/gateways/pagerduty.rb
|
472
472
|
- lib/flapjack/gateways/pagerduty/alert.text.erb
|
473
|
-
- lib/flapjack/gateways/sms_gammu.rb
|
474
473
|
- lib/flapjack/gateways/sms_messagenet.rb
|
475
474
|
- lib/flapjack/gateways/sms_messagenet/alert.text.erb
|
476
475
|
- lib/flapjack/gateways/sms_messagenet/rollup.text.erb
|
476
|
+
- lib/flapjack/gateways/sms_nexmo.rb
|
477
|
+
- lib/flapjack/gateways/sms_nexmo/alert.text.erb
|
478
|
+
- lib/flapjack/gateways/sms_nexmo/rollup.text.erb
|
477
479
|
- lib/flapjack/gateways/sms_twilio.rb
|
478
480
|
- lib/flapjack/gateways/sms_twilio/alert.text.erb
|
479
481
|
- lib/flapjack/gateways/sms_twilio/rollup.text.erb
|
@@ -576,6 +578,7 @@ files:
|
|
576
578
|
- spec/lib/flapjack/gateways/oobetet_spec.rb
|
577
579
|
- spec/lib/flapjack/gateways/pagerduty_spec.rb
|
578
580
|
- spec/lib/flapjack/gateways/sms_messagenet_spec.rb
|
581
|
+
- spec/lib/flapjack/gateways/sms_nexmo_spec.rb
|
579
582
|
- spec/lib/flapjack/gateways/sms_twilio_spec.rb
|
580
583
|
- spec/lib/flapjack/gateways/web/views/check.html.erb_spec.rb
|
581
584
|
- spec/lib/flapjack/gateways/web/views/contact.html.erb_spec.rb
|
@@ -635,9 +638,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
635
638
|
version: '0'
|
636
639
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
637
640
|
requirements:
|
638
|
-
- - "
|
641
|
+
- - ">"
|
639
642
|
- !ruby/object:Gem::Version
|
640
|
-
version:
|
643
|
+
version: 1.3.1
|
641
644
|
requirements: []
|
642
645
|
rubyforge_project:
|
643
646
|
rubygems_version: 2.4.5
|
@@ -699,6 +702,7 @@ test_files:
|
|
699
702
|
- spec/lib/flapjack/gateways/oobetet_spec.rb
|
700
703
|
- spec/lib/flapjack/gateways/pagerduty_spec.rb
|
701
704
|
- spec/lib/flapjack/gateways/sms_messagenet_spec.rb
|
705
|
+
- spec/lib/flapjack/gateways/sms_nexmo_spec.rb
|
702
706
|
- spec/lib/flapjack/gateways/sms_twilio_spec.rb
|
703
707
|
- spec/lib/flapjack/gateways/web/views/check.html.erb_spec.rb
|
704
708
|
- spec/lib/flapjack/gateways/web/views/contact.html.erb_spec.rb
|