flapjack 1.2.2 → 1.3.0rc1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 08eb6e473cdb410cd9628953cee45bd15105e730
4
- data.tar.gz: e70c64ec5ee5fbaebcd0a57ea28279637baa9ae8
3
+ metadata.gz: 185fa9c36254b3a0b485d15b0e68dbf2dc78293f
4
+ data.tar.gz: 3d1498ef293b573d05c220d937669eb86e27c397
5
5
  SHA512:
6
- metadata.gz: ba9fe3aab9ae6f58038f663737a478991bfc378a263f1e83919ff608f6bcc5b44883a71f36f9568ec38a53f8273df044802034d2ca6540be70d5930aabb3ba07
7
- data.tar.gz: e95391893e56e8b8fe95c46db61777b861e6b470889d61e578ffd3a856a6da39c95626c6f58519145768346795f57c859d17bbc6bb234cdc91a5766b6a80470c
6
+ metadata.gz: d70b5835bddcd1fefd168214af474e0cd3dc415a771549cf2565d8f77bbf4818e7a4cd1e885e21f33148da686cc12d37481ae0bc2844d39b28cd66c20a1150fa
7
+ data.tar.gz: 5cba7f54a06919f5775cae0ab15db54158bbde4d8f21b343d8e204c10fc0a9d5c302423b492b36824d18913169613d691782ba663c9fc9351e1df84ce93884fb
data/.travis.yml CHANGED
@@ -3,6 +3,8 @@ rvm:
3
3
  - '2.0'
4
4
  - '2.1'
5
5
  - '2.2'
6
+ env:
7
+ - GOPATH=$TRAVIS_BUILD_DIR
6
8
  services:
7
9
  - redis-server
8
10
  before_script:
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 Gammu
121
- sms_gammu:
120
+ # Sends SMS notifications via Nexmo
121
+ sms_nexmo:
122
122
  enabled: yes
123
- queue: sms_gammu_notifications
123
+ queue: sms_nexmo_notifications
124
124
  from: "xxxxxxxxx"
125
- mysql_host: "x.x.x.x"
126
- mysql_database: "gammu"
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
- rollup.text: '/etc/flapjack/templates/sms_gammu/rollup.text.erb'
135
- alert.text: '/etc/flapjack/templates/sms_gammu/alert.text.erb'
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
- # Generates SNS notifications
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)
@@ -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
@@ -42,5 +42,5 @@ Gem::Specification.new do |gem|
42
42
  gem.add_dependency 'rake'
43
43
  gem.add_dependency 'gli', '= 2.12.0'
44
44
  gem.add_dependency 'nokogiri', '= 1.6.2.1'
45
- gem.add_dependency 'mysql2'
45
+ gem.add_dependency 'nexmo', '= 2.0.0'
46
46
  end
@@ -60,7 +60,10 @@ module Flapjack
60
60
  return_value = start_server
61
61
  }
62
62
  puts " done."
63
- exit_now!(return_value) unless return_value.nil?
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
 
@@ -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', 'QUIT'
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 = ['email', 'sms', 'sms_twilio', 'sms_gammu', 'jabber', 'pagerduty', 'sns']
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 "Entities indexed." unless logger.nil?
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}" -%>
@@ -0,0 +1,2 @@
1
+ <%= @alert.type_sentence_case %>: <%= @alert.rollup_states_summary -%>
2
+ (<%= @alert.rollup_states_detail_text(:max_checks_per_state => 3) -%>)
@@ -1,17 +1,19 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'em-synchrony'
4
- require "em-synchrony/mysql2"
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 SmsGammu
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 sms_gammu gateway pikelet with the following options: #{@config.inspect}")
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("sms_gammu gateway is going into blpop mode on #{queue}")
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 Gammu message: #{e.class}: #{e.message}\n" +
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
- @alert = alert
67
- address = @alert.address
68
- from = @config["from"]
69
- message = prepare_message
70
- errors = []
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
- [[from, "SMS from address is missing"],
73
- [address, "SMS address is missing"]].each do |val_err|
74
+ @alert = alert
75
+ bnd = binding
74
76
 
75
- next unless val_err.first.nil? || (val_err.first.respond_to?(:empty?) && val_err.first.empty?)
76
- errors << val_err.last
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
- unless errors.empty?
80
- errors.each {|err| @logger.error err }
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
- send_message(message, from, address)
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
- def prepare_message
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
- begin
97
- message = template.result(binding).chomp
98
- truncate(message, 159)
99
- rescue => e
100
- @logger.error "Error while excuting the ERB for an sms: " +
101
- "ERB being executed: #{template_path}"
102
- raise
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
- @db.query(INSERT_QUERY % [Time.now, message, to, from, 1])
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 "Failed to send SMS via Gammu: #{e.class}, #{e.message}"
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
  };
@@ -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/sms_gammu'
19
+ require 'flapjack/gateways/sms_nexmo'
20
20
  require 'flapjack/gateways/aws_sns'
21
21
 
22
22
  module Flapjack
@@ -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/sms_gammu'
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 = {})
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  module Flapjack
4
- VERSION = "1.2.2"
4
+ VERSION = "1.3.0rc1"
5
5
  end
6
6
 
@@ -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', 'QUIT', 'HUP'])
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', 'sms_gammu', 'jabber', 'pagerduty', 'sns'],
26
- :critical_media => ['email', 'sms', 'sms_twilio', 'sms_gammu', 'jabber', 'pagerduty', 'sns'],
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.2.2
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-10 00:00:00.000000000 Z
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: mysql2
353
+ name: nexmo
354
354
  requirement: !ruby/object:Gem::Requirement
355
355
  requirements:
356
- - - ">="
356
+ - - '='
357
357
  - !ruby/object:Gem::Version
358
- version: '0'
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: '0'
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: '0'
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