flapjack 0.9.1 → 0.9.2

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: 0b98530923891264cb55c429358ca9597f1ef4ca
4
- data.tar.gz: c957beff3e8d6942157ac1e085cd912932f9e287
3
+ metadata.gz: 9aed6403dfdbf11787e5b39b0224f04c00294b8c
4
+ data.tar.gz: 2220ec7584002c684b8b6fdb26c843bb580486d4
5
5
  SHA512:
6
- metadata.gz: dd3e6b3b9af05c5f40ea6f884f985d7b5d6765eb4493f40ee12a12f8a51360933c971227b0afab1f0dd6b57f8c851c5e39276300e319610598208c945288f7aa
7
- data.tar.gz: 8ecf0255ef2f7e6cdac040f62a3b8468138bb74bca9e024fbf8111d8743bedba5d861791d2d17ace0cba27ee70c0befc12155195b79b60ae9e4e2ad4ae31f861
6
+ metadata.gz: 729f88348650bbcbf3f8eb7787a177d22dad350e17fc89333e166c057b57425062fecbe336754b0acb755b61946520900ecb21c003795b40097adbd0eaffe2b6
7
+ data.tar.gz: f9925153a749408ebd31304306835d821e9367df09cda4c5067b5bb5ff70b3b29d7cd4e5b07b4d4fde9abb4d3e93adc2f5d5c2667686174df75f9d756164a982
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  ## Flapjack Changelog
2
2
 
3
+ # 0.9.2 - 2014-07-17
4
+ - Feature: Add ability to disable check via JSON API #529 (@ali-graham)
5
+ - Feature: Jabber - Resource in JID should be supported in the config #557 (@jessereynolds)
6
+ - Feature: Jabber - add an 'identifiers' list to the config #558 (@jessereynolds)
7
+ - Feature: Jabber - handle HipChat style status updates as per XEP-0085 #559 (@jessereynolds)
8
+
3
9
  # 0.9.1 - 2014-06-27
4
10
  - Bug: PATCHing blackhole properties for notification rule changes other blackholes - further fixes #504 (@ali-graham)
5
11
  - Bug: JSONAPI get all entities/contacts with empty db e3725fc (@ali-graham)
@@ -87,6 +87,8 @@ production:
87
87
  jabberid: "flapjack@jabber.example.com"
88
88
  password: "good-password"
89
89
  alias: "flapjack"
90
+ identifiers:
91
+ - "@flapjack"
90
92
  rooms:
91
93
  - "gimp@conference.jabber.example.com"
92
94
  - "log@conference.jabber.example.com"
@@ -50,9 +50,17 @@ module Flapjack
50
50
  @redis = Flapjack::RedisPool.new(:config => @redis_config, :size => 2)
51
51
 
52
52
  @logger = opts[:logger]
53
+ @logger.debug("Jabber Initializing")
53
54
 
54
55
  @buffer = []
55
56
  @hostname = Socket.gethostname
57
+
58
+ # FIXME: i suspect the following should be in #setup so a config reload updates @identifiers
59
+ # I moved it here so the rspec passes :-/
60
+ @alias = @config['alias'] || 'flapjack'
61
+ @identifiers = ((@config['identifiers'] || []) + [@alias]).uniq
62
+ @logger.debug("I will respond to the following identifiers: #{@identifiers.join(', ')}")
63
+
56
64
  super()
57
65
  end
58
66
 
@@ -65,7 +73,9 @@ module Flapjack
65
73
  end
66
74
 
67
75
  def setup
68
- @flapjack_jid = Blather::JID.new((@config['jabberid'] || 'flapjack') + '/' + @hostname)
76
+ jid = @config['jabberid'] || 'flapjack'
77
+ jid += '/' + @hostname unless jid.include?('/')
78
+ @flapjack_jid = Blather::JID.new(jid)
69
79
 
70
80
  super(@flapjack_jid, @config['password'], @config['server'], @config['port'].to_i)
71
81
 
@@ -80,13 +90,19 @@ module Flapjack
80
90
  end
81
91
  end
82
92
 
83
- register_handler :message, :groupchat?, :body => /^#{@config['alias']}:\s+/ do |stanza|
93
+ body_matchers = @identifiers.inject([]) do |memo, identifier|
94
+ @logger.debug("identifier: #{identifier}, memo: #{memo}")
95
+ memo << {:body => /^#{identifier}[:\s]/}
96
+ memo
97
+ end
98
+ @logger.debug("body_matchers: #{body_matchers}")
99
+ register_handler :message, :groupchat?, body_matchers do |stanza|
84
100
  EventMachine::Synchrony.next_tick do
85
101
  on_groupchat(stanza)
86
102
  end
87
103
  end
88
104
 
89
- register_handler :message, :chat? do |stanza|
105
+ register_handler :message, :chat?, :body do |stanza|
90
106
  EventMachine::Synchrony.next_tick do
91
107
  on_chat(stanza)
92
108
  end
@@ -111,11 +127,11 @@ module Flapjack
111
127
  @logger.info("Joining room #{room}")
112
128
  presence = Blather::Stanza::Presence.new
113
129
  presence.from = @flapjack_jid
114
- presence.to = Blather::JID.new("#{room}/#{@config['alias']}")
130
+ presence.to = Blather::JID.new("#{room}/#{@alias}")
115
131
  presence << "<x xmlns='http://jabber.org/protocol/muc'><history maxstanzas='0'></x>"
116
132
  EventMachine::Synchrony.next_tick do
117
133
  write presence
118
- say(room, "flapjack jabber gateway started at #{Time.now}, hello!", :groupchat)
134
+ say(room, "flapjack jabber gateway started at #{Time.now}, hello! Try typing 'help'.", :groupchat)
119
135
  end
120
136
  end
121
137
  end
@@ -160,7 +176,7 @@ module Flapjack
160
176
  out
161
177
  end
162
178
 
163
- def interpreter(command_raw,from)
179
+ def interpreter(command_raw, from)
164
180
  msg = nil
165
181
  action = nil
166
182
  entity_check = nil
@@ -239,7 +255,8 @@ module Flapjack
239
255
  t = Process.times
240
256
  fqdn = `/bin/hostname -f`.chomp
241
257
  pid = Process.pid
242
- msg = "Flapjack #{Flapjack::VERSION} process #{pid} on #{fqdn} \n" +
258
+ msg = "Flapjack #{Flapjack::VERSION} process #{pid} on #{fqdn}\n" +
259
+ "Identifiers: #{@identifiers.join(', ')}\n" +
243
260
  "Boot time: #{@boot_time}\n" +
244
261
  "User CPU Time: #{t.utime}\n" +
245
262
  "System CPU Time: #{t.stime}\n" +
@@ -537,18 +554,23 @@ module Flapjack
537
554
  return if @should_quit
538
555
  @logger.debug("groupchat message received: #{stanza.inspect}")
539
556
 
540
- if stanza.body =~ /^#{@config['alias']}:\s+(.*)/m
541
- command = $1
557
+ the_command = nil
558
+ @identifiers.each do |identifier|
559
+ if stanza.body =~ /^#{identifier}:?\s*(.*)/m
560
+ the_command = $1
561
+ @logger.debug("matched identifier: #{identifier}, command: #{the_command.inspect}")
562
+ break
563
+ end
542
564
  end
543
565
 
544
566
  from = stanza.from
545
567
 
546
568
  begin
547
- results = interpreter(command, from.resource.to_s)
569
+ results = interpreter(the_command, from.to_s)
548
570
  msg = results[:msg]
549
571
  action = results[:action]
550
572
  rescue => e
551
- @logger.error("Exception when interpreting command '#{command}' - #{e.class}, #{e.message}")
573
+ @logger.debug("Exception when interpreting command '#{the_command}' - #{e.class}, #{e.message}")
552
574
  msg = "Oops, something went wrong processing that command (#{e.class}, #{e.message})"
553
575
  end
554
576
 
@@ -571,8 +593,10 @@ module Flapjack
571
593
  command = stanza.body
572
594
  end
573
595
 
596
+ from = stanza.from
597
+
574
598
  begin
575
- results = interpreter(command)
599
+ results = interpreter(command, from.resource.to_s)
576
600
  msg = results[:msg]
577
601
  action = results[:action]
578
602
  rescue => e
@@ -98,6 +98,8 @@ module Flapjack
98
98
 
99
99
  set :dump_errors, false
100
100
 
101
+ set :protection, :except => :path_traversal
102
+
101
103
  rescue_error = Proc.new {|status, exception, request_info, *msg|
102
104
  if !msg || msg.empty?
103
105
  trace = exception.backtrace.join("\n")
@@ -31,8 +31,24 @@ module Flapjack
31
31
  app.helpers Flapjack::Gateways::JSONAPI::Helpers
32
32
  app.helpers Flapjack::Gateways::JSONAPI::CheckMethods::Helpers
33
33
 
34
+ app.patch %r{^/checks/(.+)$} do
35
+ checks_for_check_names(params[:captures][0].split(',')).each do |check|
36
+ apply_json_patch('checks') do |op, property, linked, value|
37
+ case op
38
+ when 'replace'
39
+ if ['enabled'].include?(property)
40
+ # explicitly checking for false being passed in
41
+ check.disable! if value.is_a?(FalseClass)
42
+ end
43
+ end
44
+ end
45
+ end
46
+
47
+ status 204
48
+ end
49
+
34
50
  # create a scheduled maintenance period for a check on an entity
35
- app.post %r{^/scheduled_maintenances/checks/([^/]+)$} do
51
+ app.post %r{^/scheduled_maintenances/checks/(.+)$} do
36
52
  scheduled_maintenances = wrapped_params('scheduled_maintenances')
37
53
  checks_for_check_names(params[:captures][0].split(',')).each do |check|
38
54
  scheduled_maintenances.each do |wp|
@@ -50,7 +66,7 @@ module Flapjack
50
66
  # create an acknowledgement for a service on an entity
51
67
  # NB currently, this does not acknowledge a specific failure event, just
52
68
  # the entity-check as a whole
53
- app.post %r{^/unscheduled_maintenances/checks/([^/]+)$} do
69
+ app.post %r{^/unscheduled_maintenances/checks/(.+)$} do
54
70
  unscheduled_maintenances = wrapped_params('unscheduled_maintenances', false)
55
71
  checks_for_check_names(params[:captures][0].split(',')).each do |check|
56
72
  unscheduled_maintenances.each do |wp|
@@ -69,7 +85,7 @@ module Flapjack
69
85
  status 204
70
86
  end
71
87
 
72
- app.patch %r{^/unscheduled_maintenances/checks/([^/]+)$} do
88
+ app.patch %r{^/unscheduled_maintenances/checks/(.+)$} do
73
89
  checks_for_check_names(params[:captures][0].split(',')).each do |check|
74
90
  apply_json_patch('unscheduled_maintenances') do |op, property, linked, value|
75
91
  case op
@@ -84,7 +100,7 @@ module Flapjack
84
100
  status 204
85
101
  end
86
102
 
87
- app.delete %r{^/scheduled_maintenances/checks/([^/]+)$} do
103
+ app.delete %r{^/scheduled_maintenances/checks/(.+)$} do
88
104
  start_time = validate_and_parsetime(params[:start_time])
89
105
  halt( err(403, "start time must be provided") ) unless start_time
90
106
 
@@ -94,7 +110,7 @@ module Flapjack
94
110
  status 204
95
111
  end
96
112
 
97
- app.post %r{^/test_notifications/checks/([^/]+)$} do
113
+ app.post %r{^/test_notifications/checks/(.+)$} do
98
114
  test_notifications = wrapped_params('test_notifications', false)
99
115
  checks_for_check_names(params[:captures][0].split(',')).each do |check|
100
116
  test_notifications.each do |wp|
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  module Flapjack
4
- VERSION = "0.9.1"
4
+ VERSION = "0.9.2"
5
5
  end
6
6
 
@@ -3,13 +3,14 @@ require 'flapjack/gateways/jabber'
3
3
 
4
4
  describe Flapjack::Gateways::Jabber, :logger => true do
5
5
 
6
- let(:config) { {'queue' => 'jabber_notifications',
7
- 'server' => 'example.com',
8
- 'port' => '5222',
9
- 'jabberid' => 'flapjack@example.com',
10
- 'password' => 'password',
11
- 'alias' => 'flapjack',
12
- 'rooms' => ['flapjacktest@conference.example.com']
6
+ let(:config) { {'queue' => 'jabber_notifications',
7
+ 'server' => 'example.com',
8
+ 'port' => '5222',
9
+ 'jabberid' => 'flapjack@example.com',
10
+ 'password' => 'password',
11
+ 'alias' => 'flapjack',
12
+ 'identifiers' => ['@flapjack'],
13
+ 'rooms' => ['flapjacktest@conference.example.com']
13
14
  }
14
15
  }
15
16
 
@@ -26,10 +27,11 @@ describe Flapjack::Gateways::Jabber, :logger => true do
26
27
  expect(fj).to receive(:register_handler).with(:ready).and_yield(stanza)
27
28
  expect(fj).to receive(:on_ready).with(stanza)
28
29
 
29
- expect(fj).to receive(:register_handler).with(:message, :groupchat?, :body => /^flapjack:\s+/).and_yield(stanza)
30
+ body_matchers = [{:body => /^@flapjack[:\s]/}, {:body => /^flapjack[:\s]/}]
31
+ expect(fj).to receive(:register_handler).with(:message, :groupchat?, body_matchers).and_yield(stanza)
30
32
  expect(fj).to receive(:on_groupchat).with(stanza)
31
33
 
32
- expect(fj).to receive(:register_handler).with(:message, :chat?).and_yield(stanza)
34
+ expect(fj).to receive(:register_handler).with(:message, :chat?, :body).and_yield(stanza)
33
35
  expect(fj).to receive(:on_chat).with(stanza)
34
36
 
35
37
  expect(fj).to receive(:register_handler).with(:disconnected).and_yield(stanza)
@@ -52,9 +54,8 @@ describe Flapjack::Gateways::Jabber, :logger => true do
52
54
  end
53
55
 
54
56
  it "receives an acknowledgement message" do
55
- expect(stanza).to receive(:body).and_return('flapjack: ACKID 1f8ac10f fixing now duration: 90m')
57
+ expect(stanza).to receive(:body).twice.and_return('flapjack: ACKID 1f8ac10f fixing now duration: 90m')
56
58
  from = double('from')
57
- expect(from).to receive(:resource).and_return('sender')
58
59
  expect(from).to receive(:stripped).and_return('sender')
59
60
  expect(stanza).to receive(:from).and_return(from)
60
61
 
@@ -85,12 +86,11 @@ describe Flapjack::Gateways::Jabber, :logger => true do
85
86
  end
86
87
 
87
88
  it "strips XML tags from the received message" do
88
- expect(stanza).to receive(:body).
89
+ expect(stanza).to receive(:body).twice.
89
90
  and_return('flapjack: tell me about <span style="text-decoration: underline;">' +
90
91
  '<a href="http://example.org/">example.org</a></span>')
91
92
 
92
93
  from = double('from')
93
- expect(from).to receive(:resource).and_return('sender')
94
94
  expect(from).to receive(:stripped).and_return('sender')
95
95
  expect(stanza).to receive(:from).and_return(from)
96
96
 
@@ -119,11 +119,10 @@ describe Flapjack::Gateways::Jabber, :logger => true do
119
119
  end
120
120
 
121
121
  it "handles a message with a newline in it" do
122
- expect(stanza).to receive(:body).
122
+ expect(stanza).to receive(:body).twice.
123
123
  and_return("flapjack: tell me about \nexample.com")
124
124
 
125
125
  from = double('from')
126
- expect(from).to receive(:resource).and_return('sender')
127
126
  expect(from).to receive(:stripped).and_return('sender')
128
127
  expect(stanza).to receive(:from).and_return(from)
129
128
 
@@ -152,9 +151,8 @@ describe Flapjack::Gateways::Jabber, :logger => true do
152
151
  end
153
152
 
154
153
  it "receives a message it doesn't understand" do
155
- expect(stanza).to receive(:body).once.and_return('flapjack: hello!')
154
+ expect(stanza).to receive(:body).twice.and_return('flapjack: hello!')
156
155
  from = double('from')
157
- expect(from).to receive(:resource).and_return('sender')
158
156
  expect(from).to receive(:stripped).and_return('sender')
159
157
  expect(stanza).to receive(:from).and_return(from)
160
158
 
@@ -9,11 +9,26 @@ describe 'Flapjack::Gateways::JSONAPI::CheckMethods', :sinatra => true, :logger
9
9
  let(:entity_check) { double(Flapjack::Data::EntityCheck) }
10
10
 
11
11
  let(:entity_name) { 'www.example.net'}
12
- let(:entity_name_esc) { URI.escape(entity_name) }
13
12
  let(:check) { 'ping' }
13
+ let(:check_esc) { URI.escape(entity_name + ':' + check) }
14
14
 
15
15
  let(:check_presenter) { double(Flapjack::Gateways::JSONAPI::CheckPresenter) }
16
16
 
17
+ it 'disables a check' do
18
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
19
+ with(entity_name, :redis => redis).and_return(entity)
20
+ expect(Flapjack::Data::EntityCheck).to receive(:for_entity).
21
+ with(entity, check, :redis => redis).and_return(entity_check)
22
+
23
+ expect(entity_check).to receive(:disable!)
24
+
25
+ apatch "/checks/#{check_esc}",
26
+ [{:op => 'replace', :path => '/checks/0/enabled', :value => false}].to_json,
27
+ jsonapi_patch_env
28
+ expect(last_response.status).to eq(204)
29
+
30
+ end
31
+
17
32
  it "creates an acknowledgement for an entity check" do
18
33
  expect(Flapjack::Data::Entity).to receive(:find_by_name).
19
34
  with(entity_name, :redis => redis).and_return(entity)
@@ -26,7 +41,7 @@ describe 'Flapjack::Gateways::JSONAPI::CheckMethods', :sinatra => true, :logger
26
41
  expect(Flapjack::Data::Event).to receive(:create_acknowledgement).
27
42
  with(entity_name, check, :redis => redis, :duration => (4 * 60 * 60))
28
43
 
29
- apost "/unscheduled_maintenances/checks/#{entity_name}:#{check}", {}, jsonapi_post_env
44
+ apost "/unscheduled_maintenances/checks/#{check_esc}", {}, jsonapi_post_env
30
45
  expect(last_response.status).to eq(204)
31
46
  end
32
47
 
@@ -40,7 +55,23 @@ describe 'Flapjack::Gateways::JSONAPI::CheckMethods', :sinatra => true, :logger
40
55
  expect(Flapjack::Data::Entity).to receive(:find_by_name).
41
56
  with(entity_name, :redis => redis).and_return(entity)
42
57
 
43
- apatch "/unscheduled_maintenances/checks/#{entity_name}:#{check}",
58
+ apatch "/unscheduled_maintenances/checks/#{check_esc}",
59
+ [{:op => 'replace', :path => '/unscheduled_maintenances/0/end_time', :value => end_time.iso8601}].to_json,
60
+ jsonapi_patch_env
61
+ expect(last_response.status).to eq(204)
62
+ end
63
+
64
+ it "ends an unscheduled maintenance period for an entity check with a / in the check name" do
65
+ end_time = Time.now + (60 * 60) # an hour from now
66
+ expect(entity_check).to receive(:end_unscheduled_maintenance).with(end_time.to_i)
67
+
68
+ expect(Flapjack::Data::EntityCheck).to receive(:for_entity).
69
+ with(entity, 'Disk/Memory Usage', :redis => redis).and_return(entity_check)
70
+
71
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
72
+ with(entity_name, :redis => redis).and_return(entity)
73
+
74
+ apatch "/unscheduled_maintenances/checks/#{URI.escape(entity_name + ':Disk/Memory Usage')}",
44
75
  [{:op => 'replace', :path => '/unscheduled_maintenances/0/end_time', :value => end_time.iso8601}].to_json,
45
76
  jsonapi_patch_env
46
77
  expect(last_response.status).to eq(204)
@@ -57,7 +88,7 @@ describe 'Flapjack::Gateways::JSONAPI::CheckMethods', :sinatra => true, :logger
57
88
  expect(entity_check).to receive(:create_scheduled_maintenance).
58
89
  with(start.getutc.to_i, duration, :summary => 'test')
59
90
 
60
- apost "/scheduled_maintenances/checks/#{entity_name}:#{check}",
91
+ apost "/scheduled_maintenances/checks/#{check_esc}",
61
92
  {:scheduled_maintenances => [{:start_time => start.iso8601, :summary => 'test', :duration => duration}]}.to_json,
62
93
  jsonapi_post_env
63
94
  expect(last_response.status).to eq(204)
@@ -66,7 +97,7 @@ describe 'Flapjack::Gateways::JSONAPI::CheckMethods', :sinatra => true, :logger
66
97
  it "doesn't create a scheduled maintenance period for an entity check if the start time isn't passed" do
67
98
  duration = (2 * 60 * 60) # two hours
68
99
 
69
- apost "/scheduled_maintenances/checks/#{entity_name}:#{check}",
100
+ apost "/scheduled_maintenances/checks/#{check_esc}",
70
101
  {:summary => 'test', :duration => duration}.to_json, jsonapi_post_env
71
102
  expect(last_response.status).to eq(403)
72
103
  end
@@ -81,7 +112,7 @@ describe 'Flapjack::Gateways::JSONAPI::CheckMethods', :sinatra => true, :logger
81
112
  expect(Flapjack::Data::Entity).to receive(:find_by_name).
82
113
  with(entity_name, :redis => redis).and_return(entity)
83
114
 
84
- adelete "/scheduled_maintenances/checks/#{entity_name}:#{check}",
115
+ adelete "/scheduled_maintenances/checks/#{check_esc}",
85
116
  :start_time => start_time.iso8601
86
117
  expect(last_response.status).to eq(204)
87
118
  end
@@ -89,7 +120,7 @@ describe 'Flapjack::Gateways::JSONAPI::CheckMethods', :sinatra => true, :logger
89
120
  it "doesn't delete a scheduled maintenance period if the start time isn't passed" do
90
121
  expect(entity_check).not_to receive(:end_scheduled_maintenance)
91
122
 
92
- adelete "/scheduled_maintenances/checks/#{entity_name}:#{check}"
123
+ adelete "/scheduled_maintenances/checks/#{check_esc}"
93
124
  expect(last_response.status).to eq(403)
94
125
  end
95
126
 
@@ -109,7 +140,7 @@ describe 'Flapjack::Gateways::JSONAPI::CheckMethods', :sinatra => true, :logger
109
140
  expect(Flapjack::Data::Entity).to receive(:find_by_name).
110
141
  with(entity_name, :redis => redis).and_return(entity)
111
142
 
112
- adelete "/scheduled_maintenances/checks/#{entity_name}:#{check},#{entity_name}:foo",
143
+ adelete "/scheduled_maintenances/checks/#{check_esc},#{entity_name}:foo",
113
144
  :start_time => start_time.iso8601
114
145
  expect(last_response.status).to eq(204)
115
146
  end
@@ -127,7 +158,7 @@ describe 'Flapjack::Gateways::JSONAPI::CheckMethods', :sinatra => true, :logger
127
158
  expect(Flapjack::Data::Event).to receive(:test_notifications).
128
159
  with(entity_name, check, hash_including(:redis => redis))
129
160
 
130
- apost "/test_notifications/checks/#{entity_name}:#{check}"
161
+ apost "/test_notifications/checks/#{check_esc}"
131
162
  expect(last_response.status).to eq(204)
132
163
  end
133
164
 
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: 0.9.1
4
+ version: 0.9.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lindsay Holmwood
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2014-06-26 00:00:00.000000000 Z
13
+ date: 2014-07-17 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: dante