flapjack 0.6.35 → 0.6.36

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -6,10 +6,11 @@ group :test do
6
6
  gem 'rspec'
7
7
  gem 'cucumber'
8
8
  gem 'delorean'
9
- gem 'rack-test'
9
+ gem 'rack-test', :git => "git://github.com/brynary/rack-test.git", :ref => "8153c07"
10
10
  gem 'resque_spec'
11
11
  gem 'webmock'
12
12
  gem 'guard'
13
+ gem 'rb-fsevent', '~> 0.9.1'
13
14
  gem 'guard-rspec'
14
15
  gem 'guard-cucumber'
15
16
  gem 'fuubar'
@@ -3,8 +3,8 @@
3
3
  # A HTTP-based API server, which provides queries to determine the status of
4
4
  # entities and the checks that are reported against them.
5
5
  #
6
- # There's a matching flapjack-diner gem which consumes data from this API
7
- # (currently at https://github.com/ali-graham/flapjack-diner -- this will change.)
6
+ # There's a matching flapjack-diner gem at https://github.com/flpjck/flapjack-diner
7
+ # which consumes data from this API.
8
8
 
9
9
  require 'time'
10
10
 
@@ -15,9 +15,34 @@ require 'flapjack/pikelet'
15
15
 
16
16
  require 'flapjack/api/entity_presenter'
17
17
 
18
+ require 'flapjack/data/contact'
18
19
  require 'flapjack/data/entity'
19
20
  require 'flapjack/data/entity_check'
20
21
 
22
+ # from https://github.com/sinatra/sinatra/issues/501
23
+ # TODO move to its own file
24
+ module Rack
25
+ class JsonParamsParser < Struct.new(:app)
26
+ def call(env)
27
+ if env['rack.input'] and not input_parsed?(env) and type_match?(env)
28
+ env['rack.request.form_input'] = env['rack.input']
29
+ data = env['rack.input'].read
30
+ env['rack.request.form_hash'] = data.empty?? {} : JSON.parse(data)
31
+ end
32
+ app.call(env)
33
+ end
34
+
35
+ def input_parsed? env
36
+ env['rack.request.form_input'].eql? env['rack.input']
37
+ end
38
+
39
+ def type_match? env
40
+ type = env['CONTENT_TYPE'] and
41
+ type.split(/\s*[;,]\s*/, 2).first.downcase == 'application/json'
42
+ end
43
+ end
44
+ end
45
+
21
46
  module Flapjack
22
47
 
23
48
  class API < Sinatra::Base
@@ -27,14 +52,18 @@ module Flapjack
27
52
  rescue_exception = Proc.new { |env, exception|
28
53
  logger.error exception.message
29
54
  logger.error exception.backtrace.join("\n")
30
- [503, {}, {:status => 503, :reason => exception.message}.to_json]
55
+ [503, {}, {:errors => [exception.message]}.to_json]
31
56
  }
32
57
 
33
58
  use Rack::FiberPool, :size => 25, :rescue_exception => rescue_exception
34
59
  end
35
60
  use Rack::MethodOverride
61
+ use Rack::JsonParamsParser
62
+
36
63
  extend Flapjack::Pikelet
37
64
 
65
+ set :show_exceptions, 'development'.eql?(FLAPJACK_ENV)
66
+
38
67
  before do
39
68
  # will only initialise the first time it's run
40
69
  Flapjack::API.bootstrap
@@ -226,8 +255,61 @@ module Flapjack
226
255
  status 204
227
256
  end
228
257
 
258
+ post '/entities' do
259
+ pass unless 'application/json'.eql?(request.content_type)
260
+ content_type :json
261
+
262
+ errors = []
263
+ ret = nil
264
+
265
+ entities = params[:entities]
266
+ if entities && entities.is_a?(Enumerable) && entities.any? {|e| !e['id'].nil?}
267
+ entities.each do |entity|
268
+ unless entity['id']
269
+ errors << "Entity not imported as it has no id: #{entity.inspect}"
270
+ next
271
+ end
272
+ Flapjack::Data::Entity.add(entity, :redis => @@redis)
273
+ end
274
+ ret = 200
275
+ else
276
+ ret = 403
277
+ errors << "No valid entities were submitted"
278
+ end
279
+ errors.empty? ? ret : [ret, {}, {:errors => [errors]}.to_json]
280
+ end
281
+
282
+ post '/contacts' do
283
+ begin
284
+ pass unless 'application/json'.eql?(request.content_type)
285
+ content_type :json
286
+
287
+ errors = []
288
+ ret = nil
289
+
290
+ contacts = params[:contacts]
291
+ if contacts && contacts.is_a?(Enumerable) && contacts.any? {|c| !c['id'].nil?}
292
+ Flapjack::Data::Contact.delete_all
293
+ contacts.each do |contact|
294
+ unless contact['id']
295
+ logger.warn "Contact not imported as it has no id: #{contact.inspect}"
296
+ next
297
+ end
298
+ Flapjack::Data::Contact.add(contact, :redis => @@redis)
299
+ end
300
+ ret = 200
301
+ else
302
+ ret = 403
303
+ errors << "No valid contacts were submitted"
304
+ end
305
+ errors.empty? ? ret : [ret, {}, {:errors => [errors]}.to_json]
306
+ rescue Exception => e
307
+ puts e.message
308
+ end
309
+ end
310
+
229
311
  not_found do
230
- [404, {}, {:status => 404, :reason => "Not found"}.to_json]
312
+ [404, {}, {:errors => ["Not found"]}.to_json]
231
313
  end
232
314
 
233
315
  private
@@ -25,6 +25,21 @@ module Flapjack
25
25
  union
26
26
  end
27
27
 
28
+ def self.delete_all(options = {})
29
+ raise "Redis connection not set" unless redis = options[:redis]
30
+
31
+ contacts = redis.keys('contact:*')
32
+
33
+ contacts.each do |c|
34
+ c =~ /^contact:(\d+)$/
35
+ id = $1
36
+
37
+ redis.del("contact:#{id}")
38
+ redis.del("contact_media:#{id}")
39
+ redis.del("contact_pagerduty:#{id}")
40
+ end
41
+ end
42
+
28
43
  # NB: should probably be called in the context of a Redis multi block; not doing so
29
44
  # here as calling classes may well be adding/updating multiple records in the one
30
45
  # operation
@@ -34,9 +49,9 @@ module Flapjack
34
49
  redis.del("contact:#{contact['id']}")
35
50
  redis.del("contact_media:#{contact['id']}")
36
51
  redis.del("contact_pagerduty:#{contact['id']}")
37
- redis.hset("contact:#{contact['id']}", 'first_name', contact['first_name'])
38
- redis.hset("contact:#{contact['id']}", 'last_name', contact['last_name'])
39
- redis.hset("contact:#{contact['id']}", 'email', contact['email'])
52
+ ['first_name', 'last_name', 'email'].each do |field|
53
+ redis.hset("contact:#{contact['id']}", field, contact[field])
54
+ end
40
55
  contact['media'].each_pair {|medium, address|
41
56
  case medium
42
57
  when 'pagerduty'
@@ -60,6 +60,17 @@ module Flapjack
60
60
  @redis.exists("#{@key}:scheduled_maintenance")
61
61
  end
62
62
 
63
+ # return data about current maintenance (scheduled or unscheduled, as specified)
64
+ def current_maintenance(opts)
65
+ sched = opts[:scheduled] ? 'scheduled' : 'unscheduled'
66
+ ts = @redis.get("#{@key}:#{sched}_maintenance")
67
+ return unless ts
68
+ {:start_time => ts.to_i,
69
+ :duration => @redis.zscore("#{@key}:#{sched}_maintenances", ts),
70
+ :summary => @redis.get("#{@key}:#{ts}:#{sched}_maintenance:summary"),
71
+ }
72
+ end
73
+
63
74
  # creates, or modifies, an event object and adds it to the events list in redis
64
75
  # 'type' => 'service',
65
76
  # 'state' => state,
@@ -136,7 +147,28 @@ module Flapjack
136
147
  @redis.zadd("#{@key}:sorted_scheduled_maintenance_timestamps", start_time, start_time)
137
148
 
138
149
  # scheduled maintenance periods have changed, revalidate
139
- update_scheduled_maintenance(:revalidate => true)
150
+ update_current_scheduled_maintenance(:revalidate => true)
151
+ end
152
+
153
+ # change the end time of a scheduled maintenance (including when one is current)
154
+ def update_scheduled_maintenance(start_time, patches = {})
155
+
156
+ # check if there is such a scheduled maintenance period
157
+ old_duration = @redis.zscore("#{@key}:scheduled_maintenances", start_time)
158
+ raise ArgumentError, 'no such scheduled maintenance period can be found' unless old_duration
159
+ raise ArgumentError, 'no handled patches have been supplied' unless patches[:end_time]
160
+
161
+ if patches[:end_time]
162
+ end_time = patches[:end_time]
163
+ raise ArgumentError unless end_time > start_time
164
+ old_end_time = start_time + old_duration
165
+ duration = end_time - start_time
166
+ @redis.zadd("#{@key}:scheduled_maintenances", duration, start_time)
167
+ end
168
+
169
+ # scheduled maintenance periods have changed, revalidate
170
+ update_current_scheduled_maintenance(:revalidate => true)
171
+
140
172
  end
141
173
 
142
174
  # delete a scheduled maintenance
@@ -148,12 +180,12 @@ module Flapjack
148
180
  @redis.zremrangebyscore("#{@key}:sorted_scheduled_maintenance_timestamps", start_time, start_time)
149
181
 
150
182
  # scheduled maintenance periods have changed, revalidate
151
- update_scheduled_maintenance(:revalidate => true)
183
+ update_current_scheduled_maintenance(:revalidate => true)
152
184
  end
153
185
 
154
186
  # if not in scheduled maintenance, looks in scheduled maintenance list for a check to see if
155
187
  # current state should be set to scheduled maintenance, and sets it as appropriate
156
- def update_scheduled_maintenance(opts = {})
188
+ def update_current_scheduled_maintenance(opts = {})
157
189
  if opts[:revalidate]
158
190
  @redis.del("#{@key}:scheduled_maintenance")
159
191
  else
@@ -252,7 +284,6 @@ module Flapjack
252
284
  ln = {:problem => last_problem_notification,
253
285
  :recovery => last_recovery_notification,
254
286
  :acknowledgement => last_acknowledgement_notification }
255
- puts "***** last_notifications_of_each_type for #{@key.inspect}: #{ln.inspect}"
256
287
  ln
257
288
  end
258
289
 
@@ -161,7 +161,7 @@ module Flapjack
161
161
  result[:skip_filters] = true
162
162
  end
163
163
 
164
- entity_check.update_scheduled_maintenance
164
+ entity_check.update_current_scheduled_maintenance
165
165
 
166
166
  # Action events represent human or automated interaction with Flapjack
167
167
  when 'action'
@@ -21,7 +21,8 @@ module Flapjack
21
21
  @log.error "Filter: Acknowledgement: unknown entity for event '#{event.id}'"
22
22
  else
23
23
  ec.create_unscheduled_maintenance(:start_time => timestamp,
24
- :duration => (event.duration || (4 * 60 * 60)))
24
+ :duration => (event.duration || (4 * 60 * 60)),
25
+ :summary => event.summary)
25
26
  message = "unscheduled maintenance created for #{event.id}"
26
27
  end
27
28
  else
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  module Flapjack
4
- VERSION = "0.6.35"
4
+ VERSION = "0.6.36"
5
5
  end
@@ -62,9 +62,9 @@ module Flapjack
62
62
  end
63
63
 
64
64
  get '/check' do
65
- begin
65
+ #begin
66
66
  @entity = params[:entity]
67
- @check = params[:check]
67
+ @check = params[:check]
68
68
 
69
69
  entity_check = get_entity_check(@entity, @check)
70
70
  return 404 if entity_check.nil?
@@ -76,17 +76,18 @@ module Flapjack
76
76
  @check_last_change = last_change
77
77
  @check_summary = entity_check.summary
78
78
  @last_notifications = entity_check.last_notifications_of_each_type
79
- @in_scheduled_maintenance = entity_check.in_scheduled_maintenance?
80
- @in_unscheduled_maintenance = entity_check.in_unscheduled_maintenance?
81
79
  @scheduled_maintenances = entity_check.maintenances(nil, nil, :scheduled => true)
82
80
  @acknowledgement_id = entity_check.failed? ?
83
81
  entity_check.event_count_at(entity_check.last_change) : nil
84
82
 
83
+ @current_scheduled_maintenance = entity_check.current_maintenance(:scheduled => true)
84
+ @current_unscheduled_maintenance = entity_check.current_maintenance(:scheduled => false)
85
+
85
86
  haml :check
86
- rescue Exception => e
87
- puts e.message
88
- puts e.backtrace.join("\n")
89
- end
87
+ #rescue Exception => e
88
+ # puts e.message
89
+ # puts e.backtrace.join("\n")
90
+ #end
90
91
 
91
92
  end
92
93
 
@@ -105,15 +106,13 @@ module Flapjack
105
106
  ack = entity_check.create_acknowledgement('summary' => (@summary || ''),
106
107
  'acknowledgement_id' => @acknowledgement_id, 'duration' => @duration)
107
108
 
108
- # FIXME: make this a flash message on the check page and delete the acknowledge page
109
- @acknowledge_success = !!ack
110
- [201, haml(:acknowledge)]
109
+ redirect back
111
110
  end
112
111
 
113
112
  # FIXME: there is bound to be a more idiomatic / restful way of doing this
114
113
  post '/end_unscheduled_maintenance/:entity/:check' do
115
114
  @entity = params[:entity]
116
- @check = params[:check]
115
+ @check = params[:check]
117
116
 
118
117
  entity_check = get_entity_check(@entity, @check)
119
118
  return 404 if entity_check.nil?
@@ -130,7 +129,7 @@ module Flapjack
130
129
  duration = ChronicDuration.parse(params[:duration])
131
130
  summary = params[:summary]
132
131
 
133
- entity_check = get_entity_check(params[:entity], params[:check])
132
+ entity_check = get_entity_check(params[:entity], params[:check])
134
133
  return 404 if entity_check.nil?
135
134
 
136
135
  entity_check.create_scheduled_maintenance(:start_time => start_time,
@@ -139,6 +138,33 @@ module Flapjack
139
138
  redirect back
140
139
  end
141
140
 
141
+ # modify scheduled maintenance
142
+ patch '/scheduled_maintenances/:entity/:check' do
143
+
144
+ begin
145
+ puts "params: #{params.inspect}"
146
+
147
+ entity_check = get_entity_check(params[:entity], params[:check])
148
+ return 404 if entity_check.nil?
149
+
150
+ end_time = Chronic.parse(params[:end_time]).to_i
151
+ start_time = params[:start_time].to_i
152
+ raise ArgumentError, "start time parsed to zero" unless start_time > 0
153
+
154
+ patches = {}
155
+ patches[:end_time] = end_time if end_time && (end_time > start_time)
156
+
157
+ raise ArgumentError.new("no valid data received to patch with") if patches.empty?
158
+
159
+ entity_check.update_scheduled_maintenance(start_time, patches)
160
+ redirect back
161
+
162
+ rescue Exception => e
163
+ puts e.message
164
+ puts e.backtrace.join("\n")
165
+ end
166
+ end
167
+
142
168
  # delete a scheduled maintenance
143
169
  delete '/scheduled_maintenances/:entity/:check' do
144
170
  entity_check = get_entity_check(params[:entity], params[:check])
@@ -49,7 +49,7 @@
49
49
  %form{:action => "/acknowledgements/#{@entity}/#{@check}", :method => "post"}
50
50
  %h2
51
51
  State: #{@check_state ? @check_state.upcase : ''}
52
- - if (['warning', 'critical'].include?(@check_state) and !(@in_unscheduled_maintenance || @in_scheduled_maintenance))
52
+ - if (['warning', 'critical'].include?(@check_state) and !(@current_unscheduled_maintenance || @current_scheduled_maintenance))
53
53
  %input{:type => 'hidden', :name => 'acknowledgement_id', :value => "#{@acknowledgement_id}"}
54
54
  %input{:type => 'submit', :value => 'Acknowledge', :class => 'button'}
55
55
  with
@@ -59,14 +59,13 @@
59
59
  %label{:for => 'duration'}
60
60
  duration:
61
61
  %input{:type => 'text', :name => 'duration', :value => ''}
62
- - if @in_unscheduled_maintenance
63
- %h3 (Acknowledged)
64
- - if @in_scheduled_maintenance
65
- %h3 (Scheduled Maintenance)
66
- - if @in_unscheduled_maintenance
62
+ - if @current_unscheduled_maintenance
63
+ %h3 (Acknowledged - #{@current_unscheduled_maintenance[:summary]})
67
64
  %form{:action => "/end_unscheduled_maintenance/#{@entity}/#{@check}", :method => "post"}
68
65
  %p
69
66
  %input{:type => 'submit', :value => 'End Unscheduled Maintenance (Unacknowledge)', :class => 'button'}
67
+ - if @current_scheduled_maintenance
68
+ %h3 (Scheduled Maintenance - #{@current_scheduled_maintenance[:summary]})
70
69
  %h3 Output: #{@check_summary}
71
70
  %table
72
71
  %tr
@@ -128,12 +127,19 @@
128
127
  %td= summary
129
128
  %td
130
129
  - if end_time > Time.now.to_i
131
- %form{ :action => "/scheduled_maintenances/#{@entity}/#{@check}", :method => "post"}
132
- %input{:type => 'hidden', :name => '_method', :value => 'delete'}
133
- %input{:type => 'hidden', :name => 'start_time', :value => start_time}
134
- %input{:type => 'submit', :value => 'Delete', :class => 'button'}
130
+ - if start_time > Time.now.to_i
131
+ %form{ :action => "/scheduled_maintenances/#{@entity}/#{@check}", :method => "post"}
132
+ %input{:type => 'hidden', :name => '_method', :value => 'delete'}
133
+ %input{:type => 'hidden', :name => 'start_time', :value => start_time}
134
+ %input{:type => 'submit', :value => 'Delete', :class => 'button'}
135
+ - else
136
+ %form{ :action => "/scheduled_maintenances/#{@entity}/#{@check}", :method => "post"}
137
+ %input{:type => 'hidden', :name => '_method', :value => 'patch'}
138
+ %input{:type => 'hidden', :name => 'start_time', :value => start_time}
139
+ %input{:type => 'hidden', :name => 'end_time', :value => 'now'}
140
+ %input{:type => 'submit', :value => 'End Now', :class => 'button'}
135
141
  - else
136
- %p No scheduled maintenance
142
+ %p No maintenance is scheduled
137
143
  %h4 Add Scheduled Maintenace
138
144
  %form{:action => "/scheduled_maintenances/#{@entity}/#{@check}", :method => "post"}
139
145
  %fieldset
@@ -167,4 +167,103 @@ describe 'Flapjack::API', :sinatra => true do
167
167
  last_response.body.should == result_json
168
168
  end
169
169
 
170
+ it "creates entities from a submitted list" do
171
+ entities = {'entities' =>
172
+ [
173
+ {"id" => "10001",
174
+ "name" => "clientx-app-01",
175
+ "contacts" => ["0362","0363","0364"]
176
+ },
177
+ {"id" => "10002",
178
+ "name" => "clientx-app-02",
179
+ "contacts" => ["0362"]
180
+ }
181
+ ]
182
+ }
183
+ Flapjack::Data::Entity.should_receive(:add).twice
184
+
185
+ post "/entities", entities.to_json, {'CONTENT_TYPE' => 'application/json'}
186
+ last_response.status.should == 200
187
+ end
188
+
189
+ it "does not create entities if the data is improperly formatted" do
190
+ Flapjack::Data::Entity.should_not_receive(:add)
191
+
192
+ post "/entities", {'entities' => ["Hello", "there"]}.to_json,
193
+ {'CONTENT_TYPE' => 'application/json'}
194
+ last_response.status.should == 403
195
+ end
196
+
197
+ it "does not create entities if they don't contain an id" do
198
+ entities = {'entities' =>
199
+ [
200
+ {"id" => "10001",
201
+ "name" => "clientx-app-01",
202
+ "contacts" => ["0362","0363","0364"]
203
+ },
204
+ {"name" => "clientx-app-02",
205
+ "contacts" => ["0362"]
206
+ }
207
+ ]
208
+ }
209
+ Flapjack::Data::Entity.should_receive(:add)
210
+
211
+ post "/entities", entities.to_json, {'CONTENT_TYPE' => 'application/json'}
212
+ last_response.status.should == 200
213
+ end
214
+
215
+ it "creates contacts from a submitted list" do
216
+ contacts = {'contacts' =>
217
+ [{"id" => "0362",
218
+ "first_name" => "John",
219
+ "last_name" => "Smith",
220
+ "email" => "johns@example.dom",
221
+ "media" => {"email" => "johns@example.dom",
222
+ "jabber" => "johns@conference.localhost"}},
223
+ {"id" => "0363",
224
+ "first_name" => "Jane",
225
+ "last_name" => "Jones",
226
+ "email" => "jane@example.dom",
227
+ "media" => {"email" => "jane@example.dom"}}
228
+ ]
229
+ }
230
+
231
+ Flapjack::Data::Contact.should_receive(:delete_all)
232
+ Flapjack::Data::Contact.should_receive(:add).twice
233
+
234
+ post "/contacts", contacts.to_json, {'CONTENT_TYPE' => 'application/json'}
235
+ last_response.status.should == 200
236
+ end
237
+
238
+ it "does not create contacts if the data is improperly formatted" do
239
+ Flapjack::Data::Contact.should_not_receive(:delete_all)
240
+ Flapjack::Data::Contact.should_not_receive(:add)
241
+
242
+ post "/contacts", {'contacts' => ["Hello", "again"]}.to_json,
243
+ {'CONTENT_TYPE' => 'application/json'}
244
+ last_response.status.should == 403
245
+ end
246
+
247
+ it "does not create contacts if they don't contain an id" do
248
+ contacts = {'contacts' =>
249
+ [{"id" => "0362",
250
+ "first_name" => "John",
251
+ "last_name" => "Smith",
252
+ "email" => "johns@example.dom",
253
+ "media" => {"email" => "johns@example.dom",
254
+ "jabber" => "johns@conference.localhost"}},
255
+ {"first_name" => "Jane",
256
+ "last_name" => "Jones",
257
+ "email" => "jane@example.dom",
258
+ "media" => {"email" => "jane@example.dom"}}
259
+ ]
260
+ }
261
+
262
+ Flapjack::Data::Contact.should_receive(:delete_all)
263
+ Flapjack::Data::Contact.should_receive(:add)
264
+
265
+ post "/contacts", contacts.to_json, {'CONTENT_TYPE' => 'application/json'}
266
+ last_response.status.should == 200
267
+ end
268
+
170
269
  end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ require 'flapjack/data/contact'
4
+
5
+ describe Flapjack::Data::Contact, :redis => true do
6
+
7
+ it "finds all contacts for a check on an entity"
8
+
9
+ it "deletes all contacts"
10
+
11
+ it "adds a contact"
12
+
13
+ it "returns pagerduty credentials for a contact"
14
+
15
+ end
@@ -152,6 +152,10 @@ describe Flapjack::Data::EntityCheck, :redis => true do
152
152
 
153
153
  it "creates a scheduled maintenance period covering the current time"
154
154
 
155
+ it "updates a scheduled maintenance period for a future time"
156
+
157
+ it "updates a scheduled maintenance period covering the current time"
158
+
155
159
  it "removes a scheduled maintenance period for a future time"
156
160
 
157
161
  it "removes a scheduled maintenance period covering a current time"
@@ -395,4 +399,4 @@ describe Flapjack::Data::EntityCheck, :redis => true do
395
399
  ec.last_recovery_notification.should == t
396
400
  end
397
401
 
398
- end
402
+ end
@@ -101,10 +101,10 @@ describe Flapjack::Web, :sinatra => true, :redis => true do
101
101
  entity_check.should_receive(:last_change).and_return(time - (3 * 60 * 60))
102
102
  entity_check.should_receive(:summary).and_return('all good')
103
103
  entity_check.should_receive(:last_notifications_of_each_type).and_return(last_notifications)
104
- entity_check.should_receive(:in_scheduled_maintenance?).and_return(false)
105
- entity_check.should_receive(:in_unscheduled_maintenance?).and_return(false)
106
104
  entity_check.should_receive(:maintenances).with(nil, nil, :scheduled => true).and_return([])
107
105
  entity_check.should_receive(:failed?).and_return(false)
106
+ entity_check.should_receive(:current_maintenance).with(:scheduled => true).and_return(false)
107
+ entity_check.should_receive(:current_maintenance).with(:scheduled => false).and_return(false)
108
108
 
109
109
  Flapjack::Data::Entity.should_receive(:find_by_name).
110
110
  with(entity_name, :redis => @redis).and_return(entity)
@@ -142,7 +142,7 @@ describe Flapjack::Web, :sinatra => true, :redis => true do
142
142
  with(an_instance_of(Hash))
143
143
 
144
144
  post "/acknowledgements/#{entity_name_esc}/ping"
145
- last_response.status.should == 201
145
+ last_response.status.should == 302
146
146
  end
147
147
 
148
148
  it "creates a scheduled maintenance period for an entity check" do
@@ -169,6 +169,26 @@ describe Flapjack::Web, :sinatra => true, :redis => true do
169
169
  last_response.status.should == 302
170
170
  end
171
171
 
172
+ # FIXME: how to support the patch http method? ... also, is putting the post data into the url the
173
+ # way to go here?
174
+ it "updates a scheduled maintenance period for an entity check" do
175
+ t = Time.now.to_i
176
+
177
+ start_time = t - (24 * 60 * 60)
178
+
179
+ Flapjack::Data::Entity.should_receive(:find_by_name).
180
+ with(entity_name, :redis => @redis).and_return(entity)
181
+
182
+ Flapjack::Data::EntityCheck.should_receive(:for_entity).
183
+ with(entity, 'ping', :redis => @redis).and_return(entity_check)
184
+
185
+ entity_check.should_receive(:update_scheduled_maintenance).
186
+ with(start_time, {:end_time => t})
187
+
188
+ patch "/scheduled_maintenances/#{entity_name_esc}/ping", {"start_time" => start_time, "end_time" => 'now'}
189
+ last_response.status.should == 302
190
+ end
191
+
172
192
  it "deletes a scheduled maintenance period for an entity check" do
173
193
  t = Time.now.to_i
174
194
 
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.6.35
4
+ version: 0.6.36
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2012-09-25 00:00:00.000000000 Z
14
+ date: 2012-09-27 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: daemons
@@ -458,7 +458,6 @@ files:
458
458
  - lib/flapjack/utility.rb
459
459
  - lib/flapjack/version.rb
460
460
  - lib/flapjack/web.rb
461
- - lib/flapjack/web/views/acknowledge.haml
462
461
  - lib/flapjack/web/views/check.haml
463
462
  - lib/flapjack/web/views/index.haml
464
463
  - lib/flapjack/web/views/self_stats.haml
@@ -495,6 +494,7 @@ files:
495
494
  - spec/lib/flapjack/api/entity_presenter_spec.rb
496
495
  - spec/lib/flapjack/api_spec.rb
497
496
  - spec/lib/flapjack/coordinator_spec.rb
497
+ - spec/lib/flapjack/data/contact_spec.rb
498
498
  - spec/lib/flapjack/data/entity_check_spec.rb
499
499
  - spec/lib/flapjack/data/entity_spec.rb
500
500
  - spec/lib/flapjack/data/event_spec.rb
@@ -567,6 +567,7 @@ test_files:
567
567
  - spec/lib/flapjack/api/entity_presenter_spec.rb
568
568
  - spec/lib/flapjack/api_spec.rb
569
569
  - spec/lib/flapjack/coordinator_spec.rb
570
+ - spec/lib/flapjack/data/contact_spec.rb
570
571
  - spec/lib/flapjack/data/entity_check_spec.rb
571
572
  - spec/lib/flapjack/data/entity_spec.rb
572
573
  - spec/lib/flapjack/data/event_spec.rb
@@ -1,55 +0,0 @@
1
- !!! 5
2
- %html
3
- %head
4
- :css
5
- * { margin: 0; padding: 0; }
6
- html { font-size: 62.5%; }
7
- body { font-size: 16px; }
8
- div#wrapper {
9
- margin: 24px auto;
10
- width: 1000px;
11
- }
12
- h1, h2, h3, h4, h5 {
13
- font-family: Helvetica Neue, sans-serif;
14
- margin-bottom: 12px;
15
- }
16
- table {
17
- text-align: left;
18
- width: 100%;
19
- }
20
- table th {
21
- font-family: Helvetica Neue, sans-serif;
22
- background-color: #eee;
23
- }
24
- table td, table th {
25
- padding: 4px;
26
- }
27
- table td.critical {
28
- background-color: #fb9a99;
29
- }
30
- table td.down {
31
- background-color: #fb9a99;
32
- }
33
- table td.warning {
34
- background-color: #f9bb34;
35
- }
36
- table td.ok {
37
- background-color: #B2DF8A;
38
- }
39
- table td.up {
40
- background-color: #B2DF8A;
41
- }
42
- %body
43
- %div#wrapper
44
- %p
45
- %a(title='Dashboard' href='/') All Checks
46
- |
47
- %a(title='Dashboard' href='/failing') Failing Checks
48
- - if @acknowledge_success
49
- %h1
50
- %a(href="/check?entity=#{@entity}&check=#{@check}") #{@check} on #{@entity}
51
- has been acknowledged
52
- - else
53
- %h1
54
- Failed to acknowledge
55
- %a(href="/check?entity=#{@entity}&check=#{@check}") #{@check} on #{@entity}