flapjack 1.0.0rc3 → 1.0.0rc5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -2
  3. data/.ruby-version +1 -0
  4. data/CHANGELOG.md +20 -0
  5. data/CONTRIBUTING.md +2 -2
  6. data/Gemfile +1 -1
  7. data/README.md +6 -16
  8. data/build.sh +13 -1
  9. data/etc/flapjack_config.yaml.example +98 -12
  10. data/features/cli.feature +8 -8
  11. data/features/cli_flapjack-nagios-receiver.feature +29 -37
  12. data/features/cli_flapper.feature +24 -12
  13. data/features/cli_simulate-failed-check.feature +2 -2
  14. data/features/notifications.feature +18 -1
  15. data/features/steps/cli_steps.rb +2 -2
  16. data/features/steps/notifications_steps.rb +71 -0
  17. data/features/support/env.rb +7 -6
  18. data/flapjack.gemspec +3 -1
  19. data/lib/flapjack/cli/flapper.rb +74 -25
  20. data/lib/flapjack/cli/import.rb +3 -4
  21. data/lib/flapjack/cli/maintenance.rb +182 -0
  22. data/lib/flapjack/cli/receiver.rb +110 -121
  23. data/lib/flapjack/cli/server.rb +30 -26
  24. data/lib/flapjack/cli/simulate.rb +2 -3
  25. data/lib/flapjack/data/contact.rb +1 -1
  26. data/lib/flapjack/data/entity.rb +425 -32
  27. data/lib/flapjack/data/entity_check.rb +212 -14
  28. data/lib/flapjack/data/event.rb +1 -1
  29. data/lib/flapjack/gateways/aws_sns.rb +134 -0
  30. data/lib/flapjack/gateways/aws_sns/alert.text.erb +5 -0
  31. data/lib/flapjack/gateways/aws_sns/rollup.text.erb +2 -0
  32. data/lib/flapjack/gateways/jabber.rb +2 -2
  33. data/lib/flapjack/gateways/jsonapi/check_methods.rb +1 -1
  34. data/lib/flapjack/gateways/jsonapi/contact_methods.rb +1 -1
  35. data/lib/flapjack/gateways/jsonapi/entity_methods.rb +15 -1
  36. data/lib/flapjack/gateways/jsonapi/metrics_methods.rb +4 -3
  37. data/lib/flapjack/gateways/jsonapi/report_methods.rb +1 -1
  38. data/lib/flapjack/gateways/web.rb +35 -16
  39. data/lib/flapjack/gateways/web/public/css/tablesort.css +0 -16
  40. data/lib/flapjack/gateways/web/public/js/backbone.jsonapi.js +1 -1
  41. data/lib/flapjack/gateways/web/public/js/jquery.tablesorter.widgets.js +0 -45
  42. data/lib/flapjack/gateways/web/public/js/modules/contact.js +2 -2
  43. data/lib/flapjack/gateways/web/public/js/modules/entity.js +2 -2
  44. data/lib/flapjack/gateways/web/public/js/modules/medium.js +4 -4
  45. data/lib/flapjack/gateways/web/public/js/self_stats.js +1 -1
  46. data/lib/flapjack/gateways/web/views/check.html.erb +10 -10
  47. data/lib/flapjack/gateways/web/views/checks.html.erb +1 -1
  48. data/lib/flapjack/gateways/web/views/contact.html.erb +5 -1
  49. data/lib/flapjack/gateways/web/views/edit_contacts.html.erb +3 -4
  50. data/lib/flapjack/gateways/web/views/entities.html.erb +1 -1
  51. data/lib/flapjack/gateways/web/views/index.html.erb +2 -2
  52. data/lib/flapjack/gateways/web/views/layout.erb +3 -3
  53. data/lib/flapjack/gateways/web/views/self_stats.html.erb +5 -6
  54. data/lib/flapjack/notifier.rb +4 -1
  55. data/lib/flapjack/patches.rb +8 -2
  56. data/lib/flapjack/pikelet.rb +3 -1
  57. data/lib/flapjack/version.rb +1 -1
  58. data/libexec/httpbroker.go +1 -1
  59. data/spec/lib/flapjack/coordinator_spec.rb +3 -3
  60. data/spec/lib/flapjack/data/contact_spec.rb +2 -2
  61. data/spec/lib/flapjack/data/entity_check_spec.rb +805 -53
  62. data/spec/lib/flapjack/data/entity_spec.rb +661 -0
  63. data/spec/lib/flapjack/gateways/aws_sns_spec.rb +123 -0
  64. data/spec/lib/flapjack/gateways/jabber_spec.rb +1 -1
  65. data/spec/lib/flapjack/gateways/jsonapi/check_methods_spec.rb +1 -1
  66. data/spec/lib/flapjack/gateways/jsonapi/entity_methods_spec.rb +2 -2
  67. data/spec/lib/flapjack/gateways/pagerduty_spec.rb +1 -1
  68. data/spec/lib/flapjack/gateways/web_spec.rb +11 -11
  69. data/spec/support/profile_all_formatter.rb +10 -10
  70. data/spec/support/uncolored_doc_formatter.rb +66 -4
  71. data/src/flapjack/event.go +1 -1
  72. data/tasks/benchmarks.rake +24 -20
  73. data/tasks/entities.rake +148 -0
  74. data/tmp/dummy_contacts.json +43 -0
  75. data/tmp/dummy_entities.json +37 -1
  76. metadata +43 -7
  77. data/tmp/test_entities.json +0 -1
@@ -4,7 +4,7 @@
4
4
  <h2><%= @adjective.capitalize %> Checks</h2>
5
5
  </div>
6
6
 
7
- <p><%= h @count_failing_checks %> failing out of <%= h @count_all_checks %></p>
7
+ <p><%= h @count_failing_checks %> failing out of <%= h @count_current_checks %></p>
8
8
 
9
9
  <table class="table table-bordered table-hover table-condensed tablesorter">
10
10
  <thead>
@@ -31,7 +31,11 @@
31
31
  <td></td>
32
32
  <td></td>
33
33
  <% else %>
34
- <td><%= h mk.capitalize %></td>
34
+ <% if 'sms'.eql?(mk) %>
35
+ <td><%= h mk.upcase %></td>
36
+ <% else %>
37
+ <td><%= h mk.capitalize %></td>
38
+ <% end %>
35
39
  <td><%= h mv %></td>
36
40
  <td>
37
41
  <% if @contact.media_intervals[mk] %>
@@ -90,13 +90,13 @@
90
90
  <@- labels[type] @>
91
91
  </td>
92
92
  <td>
93
- <input type="text" data-attr="address" class="form-control" value="<@- address @>">
93
+ <input type="text" id="<@- labels[type] @>-address" data-attr="address" class="form-control" value="<@- address @>">
94
94
  </td>
95
95
  <td>
96
- <input type="text" data-attr="interval" class="form-control" value="<@- interval @>">
96
+ <input type="text" id="<@- labels[type] @>-interval" data-attr="interval" class="form-control" value="<@- interval @>">
97
97
  </td>
98
98
  <td>
99
- <input type="text" data-attr="rollup_threshold" class="form-control" value="<@- rollup_threshold @>">
99
+ <input type="text" id="<@- labels[type] @>-rollup_threshold" data-attr="rollup_threshold" class="form-control <@- labels[type] @>-rollup_threshold" value="<@- rollup_threshold @>">
100
100
  </td>
101
101
  </script>
102
102
 
@@ -171,4 +171,3 @@
171
171
 
172
172
  </div>
173
173
  </div>
174
-
@@ -4,7 +4,7 @@
4
4
  <h2><%= h @adjective.capitalize %> Entities</h2>
5
5
  </div>
6
6
 
7
- <p><%= h @count_failing_entities %> failing out of <%= h @count_all_entities %></p>
7
+ <p><%= h @count_failing_entities %> failing out of <%= h @count_current_entities %></p>
8
8
 
9
9
  <% if @entities.length > 0 %>
10
10
  <table class="table table-bordered table-hover table-condensed tablesorter">
@@ -4,5 +4,5 @@
4
4
  <h2>Summary</h2>
5
5
  </div> <!-- page header -->
6
6
 
7
- <h4><a href="<% @base_url %>entities_failing" title="failing entities"><%= h @count_failing_entities %></a> out of <a href="<% @base_url %>entities_all" title="all entities"><%= h @count_all_entities %></a> entities have failing checks</h4>
8
- <h4><a href="<% @base_url %>checks_failing" title="failing checks"><%= h @count_failing_checks %></a> out of <a href="<% @base_url %>checks_all" title="all checks"><%= h @count_all_checks %></a> checks are failing</h4>
7
+ <h4><a href="<% @base_url %>entities_failing" title="failing entities"><%= h @count_failing_entities %></a> out of <a href="<% @base_url %>entities" title="all entities"><%= h @count_current_entities %></a> entities have failing checks</h4>
8
+ <h4><a href="<% @base_url %>checks_failing" title="failing checks"><%= h @count_failing_checks %></a> out of <a href="<% @base_url %>checks_all" title="all checks"><%= h @count_current_checks %></a> checks are failing</h4>
@@ -38,10 +38,10 @@
38
38
  Summary
39
39
  </a>
40
40
  </li>
41
- <li<%= include_active?('entities_all') %>>
42
- <a title="All Entities" href="<%= @base_url %>entities_all">
41
+ <li<%= include_active?('entities') %>>
42
+ <a title="Entities" href="<%= @base_url %>entities">
43
43
  <i class="fa fa-bullseye fa-lg"></i>
44
- All Entities
44
+ Entities
45
45
  </a>
46
46
  </li>
47
47
  <li<%= include_active?('entities_failing') %>>
@@ -41,16 +41,16 @@
41
41
  <td><%= h @events_queued %></td>
42
42
  </tr>
43
43
  <tr>
44
- <td>Number of entities:</td>
45
- <td><%= h @count_all_entities %></td>
44
+ <td>Number of enabled entities:</td>
45
+ <td><%= h @count_current_entities %></td>
46
46
  </tr>
47
47
  <tr>
48
48
  <td>Number of failing entities:</td>
49
49
  <td><%= h @count_failing_entities %></td>
50
50
  </tr>
51
51
  <tr>
52
- <td>Number of checks:</td>
53
- <td><%= h @count_all_checks %></td>
52
+ <td>Number of enabled checks:</td>
53
+ <td><%= h @count_current_checks %></td>
54
54
  </tr>
55
55
  <tr>
56
56
  <td>Number of failing checks:</td>
@@ -127,6 +127,5 @@
127
127
  <p>
128
128
  <a class="btn btn-success" href="<% @base_url %>self_stats.json">View as JSON</a>
129
129
  Learn how to
130
- <a href="https://github.com/flapjack/flapjack/wiki/Gathering-internal-statistics-with-collectd">
131
- use these metrics</a>.
130
+ <a href="http://flapjack.io/docs/1.0/development/Gathering-internal-statistics-with-collectd"> use these metrics</a>.
132
131
  </p>
@@ -15,6 +15,7 @@ require 'flapjack/utility'
15
15
 
16
16
  require 'flapjack/gateways/email'
17
17
  require 'flapjack/gateways/sms_messagenet'
18
+ require 'flapjack/gateways/aws_sns'
18
19
 
19
20
  module Flapjack
20
21
 
@@ -50,7 +51,7 @@ module Flapjack
50
51
  tz = ActiveSupport::TimeZone.new(tz_string)
51
52
  rescue ArgumentError
52
53
  logger.error("Invalid timezone string specified in default_contact_timezone or TZ (#{tz_string})")
53
- exit 1
54
+ exit_now!
54
55
  end
55
56
  @default_contact_timezone = tz
56
57
  end
@@ -165,6 +166,8 @@ module Flapjack
165
166
  when :email
166
167
  # FIXME(@auxesis): change Resque jobs to use raw blpop
167
168
  Resque.enqueue_to(@queues['email'], Flapjack::Gateways::Email, contents)
169
+ when :sns
170
+ Resque.enqueue_to(@queues['sns'], Flapjack::Gateways::AwsSns, contents)
168
171
  else
169
172
  @redis.rpush(@queues[media_type.to_s], Oj.dump(contents))
170
173
  end
@@ -127,7 +127,7 @@ module GLI
127
127
 
128
128
  class GLIOptionParser
129
129
  class NormalCommandOptionParser
130
- def parse!(parsing_result)
130
+ def parse!(parsing_result,argument_handling_strategy)
131
131
  parsed_command_options = {}
132
132
  command = parsing_result.command
133
133
  arguments = nil
@@ -146,7 +146,9 @@ module GLI
146
146
  command_finder = CommandFinder.new(command.commands,command.get_default_command)
147
147
  next_command_name = arguments.shift
148
148
 
149
- verify_required_options!(command.flags,parsed_command_options[command])
149
+ gli_major_version, gli_minor_version = GLI::VERSION.split('.')
150
+ required_options = [command.flags, parsing_result.command, parsed_command_options[command]]
151
+ verify_required_options!(*required_options)
150
152
 
151
153
  begin
152
154
  command = command_finder.find_command(next_command_name)
@@ -181,6 +183,10 @@ module GLI
181
183
  parsing_result.command_options = command_options
182
184
  parsing_result.command = command
183
185
  parsing_result.arguments = Array(arguments.compact)
186
+
187
+ # Lets validate the arguments now that we know for sure the command that is invoked
188
+ verify_arguments!(parsing_result.arguments, parsing_result.command) if argument_handling_strategy == :strict
189
+
184
190
  parsing_result
185
191
  end
186
192
  end
@@ -25,6 +25,7 @@ require 'flapjack/gateways/oobetet'
25
25
  require 'flapjack/gateways/pagerduty'
26
26
  require 'flapjack/gateways/email'
27
27
  require 'flapjack/gateways/sms_messagenet'
28
+ require 'flapjack/gateways/aws_sns'
28
29
  require 'flapjack/gateways/web'
29
30
  require 'flapjack/logger'
30
31
  require 'thin/version'
@@ -156,7 +157,8 @@ module Flapjack
156
157
  class Resque < Flapjack::Pikelet::Base
157
158
 
158
159
  PIKELET_TYPES = {'email' => Flapjack::Gateways::Email,
159
- 'sms' => Flapjack::Gateways::SmsMessagenet}
160
+ 'sms' => Flapjack::Gateways::SmsMessagenet,
161
+ 'sns' => Flapjack::Gateways::AwsSns}
160
162
 
161
163
  def self.create(type, opts = {})
162
164
  self.new(type, PIKELET_TYPES[type], :config => opts[:config],
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  module Flapjack
4
- VERSION = "1.0.0rc3"
4
+ VERSION = "1.0.0rc5"
5
5
  end
6
6
 
@@ -15,7 +15,7 @@ import (
15
15
 
16
16
  // State is a basic representation of a Flapjack event, with some extra field.
17
17
  // The extra fields handle state expiry.
18
- // Find more at https://github.com/flapjack/flapjack/wiki/DATA_STRUCTURES
18
+ // Find more at http://flapjack.io/docs/1.0/development/DATA_STRUCTURES
19
19
  type State struct {
20
20
  flapjack.Event
21
21
  TTL int64 `json:"ttl"`
@@ -33,7 +33,7 @@ describe Flapjack::Coordinator do
33
33
  and_return(processor)
34
34
 
35
35
  expect(EM).to receive(:stop)
36
- expect(EM::Synchrony).to receive(:sleep).and_return {
36
+ expect(EM::Synchrony).to receive(:sleep) {
37
37
  fc.instance_variable_set('@received_signals', ['INT'])
38
38
  }
39
39
 
@@ -102,7 +102,7 @@ describe Flapjack::Coordinator do
102
102
  and_return(notifier)
103
103
 
104
104
  expect(EM).to receive(:stop)
105
- expect(EM::Synchrony).to receive(:sleep).and_return {
105
+ expect(EM::Synchrony).to receive(:sleep) {
106
106
  fc.instance_variable_set('@received_signals', ['INT'])
107
107
  }
108
108
 
@@ -136,7 +136,7 @@ describe Flapjack::Coordinator do
136
136
  and_return(processor)
137
137
 
138
138
  expect(EM).to receive(:stop)
139
- expect(EM::Synchrony).to receive(:sleep).and_return {
139
+ expect(EM::Synchrony).to receive(:sleep) {
140
140
  fc.instance_variable_set('@received_signals', ['INT'])
141
141
  }
142
142
 
@@ -27,8 +27,8 @@ describe Flapjack::Data::Contact, :redis => true do
27
27
  :tags => Flapjack::Data::TagSet.new([]),
28
28
  :time_restrictions => [],
29
29
  :unknown_media => [],
30
- :warning_media => ['email', 'sms', 'jabber', 'pagerduty'],
31
- :critical_media => ['email', 'sms', 'jabber', 'pagerduty'],
30
+ :warning_media => ['email', 'sms', 'jabber', 'pagerduty', 'sns'],
31
+ :critical_media => ['email', 'sms', 'jabber', 'pagerduty', 'sns'],
32
32
  :unknown_blackhole => false,
33
33
  :warning_blackhole => false,
34
34
  :critical_blackhole => false}
@@ -10,17 +10,28 @@ describe Flapjack::Data::EntityCheck, :redis => true do
10
10
  let(:check) { 'ping' }
11
11
 
12
12
  let(:half_an_hour) { 30 * 60 }
13
+ let(:t) { Time.now.to_i }
14
+ let(:five_minutes) { 60 * 5 }
15
+ let(:five_hours_ago) { t - (60 * 60 * 5) }
16
+ let(:four_hours_ago) { t - (60 * 60 * 4) }
17
+ let(:three_hours_ago) { t - (60 * 60 * 3) }
18
+ let(:two_hours_ago) { t - (60 * 60 * 2) }
19
+ let(:one_hour) { 60 * 60 }
20
+ let(:two_hours) { 60 * 60 * 2 }
21
+ let(:three_hours) { 60 * 60 * 3 }
22
+ let(:five_hours) { 60 * 60 * 5 }
23
+ let(:seven_hours) { 60 * 60 * 7 }
13
24
 
14
25
  before(:each) do
15
- Flapjack::Data::Contact.add({'id' => '362',
16
- 'first_name' => 'John',
17
- 'last_name' => 'Johnson',
18
- 'email' => 'johnj@example.com' },
19
- :redis => @redis)
20
-
21
- Flapjack::Data::Entity.add({'id' => '5000',
22
- 'name' => name,
23
- 'contacts' => ['362']},
26
+ Flapjack::Data::Contact.add({ 'id' => '362',
27
+ 'first_name' => 'John',
28
+ 'last_name' => 'Johnson',
29
+ 'email' => 'johnj@example.com' },
30
+ :redis => @redis)
31
+
32
+ Flapjack::Data::Entity.add({ 'id' => '5000',
33
+ 'name' => name,
34
+ 'contacts' => ['362'] },
24
35
  :redis => @redis)
25
36
  end
26
37
 
@@ -110,9 +121,9 @@ describe Flapjack::Data::EntityCheck, :redis => true do
110
121
  t = Time.now.to_i
111
122
 
112
123
  ec.create_unscheduled_maintenance(t, half_an_hour, :summary => 'oops')
113
- expect(ec.current_maintenance).to eq({:start_time => t,
114
- :duration => half_an_hour,
115
- :summary => 'oops'})
124
+ expect(ec.current_maintenance).to eq(:start_time => t,
125
+ :duration => half_an_hour,
126
+ :summary => 'oops')
116
127
  end
117
128
 
118
129
  it "creates an unscheduled maintenance period" do
@@ -148,7 +159,7 @@ describe Flapjack::Data::EntityCheck, :redis => true do
148
159
  later_t = t + (15 * 60)
149
160
  ec = Flapjack::Data::EntityCheck.for_entity_name(name, check, :redis => @redis)
150
161
  ec.create_unscheduled_maintenance(t, half_an_hour, :summary => 'oops')
151
- Delorean.time_travel_to( Time.at(later_t) )
162
+ Delorean.time_travel_to(Time.at(later_t))
152
163
  ec.create_unscheduled_maintenance(later_t, half_an_hour, :summary => 'spoo')
153
164
 
154
165
  expect(ec).to be_in_unscheduled_maintenance
@@ -180,6 +191,34 @@ describe Flapjack::Data::EntityCheck, :redis => true do
180
191
  expect(duration_curr).to eq(half_an_hour)
181
192
  end
182
193
 
194
+ it "creates an unscheduled maintenance period from a human readable time" do
195
+ Flapjack::Data::EntityCheck.create_maintenance(:redis => @redis, :entity => name, :check => check, :type => 'unscheduled', :started => '14/3/2027 3pm', :duration => '30 minutes', :reason => 'oops')
196
+ t = Time.local(2027, 3, 14, 15, 0).to_i
197
+
198
+ ec = Flapjack::Data::EntityCheck.for_entity_name(name, check, :redis => @redis)
199
+ expect(ec).to be_in_unscheduled_maintenance
200
+
201
+ umps = ec.maintenances(nil, nil, :scheduled => false)
202
+ expect(umps).not_to be_nil
203
+ expect(umps).to be_an(Array)
204
+ expect(umps.size).to eq(1)
205
+ expect(umps[0]).to be_a(Hash)
206
+
207
+ start_time = umps[0][:start_time]
208
+ expect(start_time).not_to be_nil
209
+ expect(start_time).to be_an(Integer)
210
+ expect(start_time).to eq(t)
211
+
212
+ duration = umps[0][:duration]
213
+ expect(duration).not_to be_nil
214
+ expect(duration).to be_a(Float)
215
+ expect(duration).to eq(1800.0)
216
+
217
+ summary = @redis.get("#{name}:#{check}:#{t}:unscheduled_maintenance:summary")
218
+ expect(summary).not_to be_nil
219
+ expect(summary).to eq('oops')
220
+ end
221
+
183
222
  it "ends an unscheduled maintenance period", :time => true do
184
223
  t = Time.now.to_i
185
224
  later_t = t + (15 * 60)
@@ -188,7 +227,7 @@ describe Flapjack::Data::EntityCheck, :redis => true do
188
227
  ec.create_unscheduled_maintenance(t, half_an_hour, :summary => 'oops')
189
228
  expect(ec).to be_in_unscheduled_maintenance
190
229
 
191
- Delorean.time_travel_to( Time.at(later_t) )
230
+ Delorean.time_travel_to(Time.at(later_t))
192
231
  expect(ec).to be_in_unscheduled_maintenance
193
232
  ec.end_unscheduled_maintenance(later_t)
194
233
  expect(ec).not_to be_in_unscheduled_maintenance
@@ -214,7 +253,7 @@ describe Flapjack::Data::EntityCheck, :redis => true do
214
253
  t = Time.now.to_i
215
254
  ec = Flapjack::Data::EntityCheck.for_entity_name(name, check, :redis => @redis)
216
255
  ec.create_scheduled_maintenance(t + (60 * 60),
217
- half_an_hour, :summary => "30 minutes")
256
+ half_an_hour, :summary => "30 minutes")
218
257
 
219
258
  smps = ec.maintenances(nil, nil, :scheduled => true)
220
259
  expect(smps).not_to be_nil
@@ -238,7 +277,7 @@ describe Flapjack::Data::EntityCheck, :redis => true do
238
277
  t = Time.now.to_i
239
278
  ec = Flapjack::Data::EntityCheck.for_entity_name(name, check, :redis => @redis)
240
279
  ec.create_scheduled_maintenance(t - (60 * 60),
241
- 2 * (60 * 60), :summary => "2 hours")
280
+ 2 * (60 * 60), :summary => "2 hours")
242
281
 
243
282
  smps = ec.maintenances(nil, nil, :scheduled => true)
244
283
  expect(smps).not_to be_nil
@@ -257,11 +296,37 @@ describe Flapjack::Data::EntityCheck, :redis => true do
257
296
  expect(duration).to eq(2 * (60 * 60))
258
297
  end
259
298
 
299
+ it "creates an scheduled maintenance period from a human readable time" do
300
+ Flapjack::Data::EntityCheck.create_maintenance(:redis => @redis, :entity => name, :check => check, :type => 'scheduled', :started => '14/3/2027 3pm', :duration => '30 minutes', :reason => 'oops')
301
+ t = Time.local(2027, 3, 14, 15, 0).to_i
302
+ ec = Flapjack::Data::EntityCheck.for_entity_name(name, check, :redis => @redis)
303
+
304
+ smps = ec.maintenances(nil, nil, :scheduled => true)
305
+ expect(smps).not_to be_nil
306
+ expect(smps).to be_an(Array)
307
+ expect(smps.size).to eq(1)
308
+ expect(smps[0]).to be_a(Hash)
309
+
310
+ start_time = smps[0][:start_time]
311
+ expect(start_time).not_to be_nil
312
+ expect(start_time).to be_an(Integer)
313
+ expect(start_time).to eq(t)
314
+
315
+ duration = smps[0][:duration]
316
+ expect(duration).not_to be_nil
317
+ expect(duration).to be_a(Float)
318
+ expect(duration).to eq(1800.0)
319
+
320
+ summary = @redis.get("#{name}:#{check}:#{t}:scheduled_maintenance:summary")
321
+ expect(summary).not_to be_nil
322
+ expect(summary).to eq('oops')
323
+ end
324
+
260
325
  it "removes a scheduled maintenance period for a future time" do
261
326
  t = Time.now.to_i
262
327
  ec = Flapjack::Data::EntityCheck.for_entity_name(name, check, :redis => @redis)
263
328
  ec.create_scheduled_maintenance(t + (60 * 60),
264
- 2 * (60 * 60), :summary => "2 hours")
329
+ 2 * (60 * 60), :summary => "2 hours")
265
330
 
266
331
  ec.end_scheduled_maintenance(t + (60 * 60))
267
332
 
@@ -277,9 +342,9 @@ describe Flapjack::Data::EntityCheck, :redis => true do
277
342
  t = Time.now.to_i
278
343
  ec = Flapjack::Data::EntityCheck.for_entity_name(name, check, :redis => @redis)
279
344
  ec.create_scheduled_maintenance(t + (60 * 60),
280
- 2 * (60 * 60), :summary => "2 hours")
345
+ 2 * (60 * 60), :summary => "2 hours")
281
346
 
282
- Delorean.time_travel_to( Time.at(t + (90 * 60)) )
347
+ Delorean.time_travel_to(Time.at(t + (90 * 60)))
283
348
 
284
349
  ec.end_scheduled_maintenance(t + (60 * 60))
285
350
 
@@ -295,9 +360,9 @@ describe Flapjack::Data::EntityCheck, :redis => true do
295
360
  t = Time.now.to_i
296
361
  ec = Flapjack::Data::EntityCheck.for_entity_name(name, check, :redis => @redis)
297
362
  ec.create_scheduled_maintenance(t + (60 * 60),
298
- 2 * (60 * 60), :summary => "2 hours")
363
+ 2 * (60 * 60), :summary => "2 hours")
299
364
 
300
- Delorean.time_travel_to( Time.at(t + (6 * (60 * 60)) ))
365
+ Delorean.time_travel_to(Time.at(t + (6 * (60 * 60))))
301
366
 
302
367
  ec.end_scheduled_maintenance(t + (60 * 60))
303
368
 
@@ -310,55 +375,742 @@ describe Flapjack::Data::EntityCheck, :redis => true do
310
375
  end
311
376
 
312
377
  it "returns a list of scheduled maintenance periods" do
313
- t = Time.now.to_i
314
- five_hours_ago = t - (60 * 60 * 5)
315
- three_hours_ago = t - (60 * 60 * 3)
316
-
317
378
  ec = Flapjack::Data::EntityCheck.for_entity_name(name, check, :redis => @redis)
318
379
  ec.create_scheduled_maintenance(five_hours_ago, half_an_hour,
319
- :summary => "first")
380
+ :summary => "first")
320
381
  ec.create_scheduled_maintenance(three_hours_ago, half_an_hour,
321
- :summary => "second")
382
+ :summary => "second")
322
383
 
323
384
  smp = ec.maintenances(nil, nil, :scheduled => true)
324
385
  expect(smp).not_to be_nil
325
386
  expect(smp).to be_an(Array)
326
387
  expect(smp.size).to eq(2)
327
- expect(smp[0]).to eq({:start_time => five_hours_ago,
328
- :end_time => five_hours_ago + half_an_hour,
329
- :duration => half_an_hour,
330
- :summary => "first"})
331
- expect(smp[1]).to eq({:start_time => three_hours_ago,
332
- :end_time => three_hours_ago + half_an_hour,
333
- :duration => half_an_hour,
334
- :summary => "second"})
388
+ expect(smp[0]).to eq(:start_time => five_hours_ago,
389
+ :end_time => five_hours_ago + half_an_hour,
390
+ :duration => half_an_hour,
391
+ :summary => "first")
392
+ expect(smp[1]).to eq(:start_time => three_hours_ago,
393
+ :end_time => three_hours_ago + half_an_hour,
394
+ :duration => half_an_hour,
395
+ :summary => "second")
335
396
  end
336
397
 
337
398
  it "returns a list of unscheduled maintenance periods" do
338
- t = Time.now.to_i
339
- five_hours_ago = t - (60 * 60 * 5)
340
- three_hours_ago = t - (60 * 60 * 3)
341
-
342
399
  ec = Flapjack::Data::EntityCheck.for_entity_name(name, check, :redis => @redis)
343
400
  ec.create_unscheduled_maintenance(five_hours_ago,
344
- half_an_hour, :summary => "first")
401
+ half_an_hour, :summary => "first")
345
402
  ec.create_unscheduled_maintenance(three_hours_ago,
346
- half_an_hour, :summary => "second")
403
+ half_an_hour, :summary => "second")
347
404
 
348
405
  ump = ec.maintenances(nil, nil, :scheduled => false)
349
406
  expect(ump).not_to be_nil
350
407
  expect(ump).to be_an(Array)
351
408
  expect(ump.size).to eq(2)
352
- expect(ump[0]).to eq({:start_time => five_hours_ago,
353
- :end_time => five_hours_ago + half_an_hour,
354
- :duration => half_an_hour,
355
- :summary => "first"})
356
- expect(ump[1]).to eq({:start_time => three_hours_ago,
357
- :end_time => three_hours_ago + half_an_hour,
358
- :duration => half_an_hour,
359
- :summary => "second"})
409
+ expect(ump[0]).to eq(:start_time => five_hours_ago,
410
+ :end_time => five_hours_ago + half_an_hour,
411
+ :duration => half_an_hour,
412
+ :summary => "first")
413
+ expect(ump[1]).to eq(:start_time => three_hours_ago,
414
+ :end_time => three_hours_ago + half_an_hour,
415
+ :duration => half_an_hour,
416
+ :summary => "second")
360
417
  end
361
418
 
419
+ it "finds current scheduled maintenance periods for multiple entities" do
420
+ ec = nil
421
+
422
+ %w(alpha lima bravo).each do |entity|
423
+ Flapjack::Data::Entity.add({ 'name' => entity }, :redis => @redis)
424
+
425
+ ec = Flapjack::Data::EntityCheck.for_entity_name(entity, check, :redis => @redis)
426
+ ec.create_scheduled_maintenance(five_hours_ago, seven_hours,
427
+ :summary => "Test scheduled maintenance for #{entity}")
428
+ end
429
+
430
+ smp = Flapjack::Data::EntityCheck.find_maintenance(:redis => @redis,
431
+ :type => 'scheduled', :finishing => 'more than 0 minutes from now').sort_by { |k| k[:entity] }
432
+
433
+ expect(smp).to be_an(Array)
434
+ expect(smp.size).to eq(3)
435
+ %w(alpha bravo lima).each_with_index do |entity, index|
436
+ expect(smp[index]).to eq(:entity => entity,
437
+ :check => "ping",
438
+ # The state here is nil due to no check having gone
439
+ # through for this item. This is normally 'critical' or 'ok'
440
+ :state => nil,
441
+ :start_time => five_hours_ago,
442
+ :end_time => five_hours_ago + seven_hours,
443
+ :duration => seven_hours,
444
+ :summary => "Test scheduled maintenance for #{entity}")
445
+ end
446
+ end
447
+
448
+ it "finds current unscheduled maintenance periods for multiple entities" do
449
+ ec = nil
450
+
451
+ %w(alpha bravo lima).each do |entity|
452
+ Flapjack::Data::Entity.add({ 'name' => entity }, :redis => @redis)
453
+
454
+ ec = Flapjack::Data::EntityCheck.for_entity_name(entity, check, :redis => @redis)
455
+ ec.create_unscheduled_maintenance(five_hours_ago, seven_hours, :summary => "Test unscheduled maintenance for #{entity}")
456
+ end
457
+
458
+ ump = Flapjack::Data::EntityCheck.find_maintenance(:redis => @redis, :type => 'unscheduled', :finishing => 'more than 0 minutes from now').sort_by { |k| k[:entity] }
459
+
460
+ expect(ump).not_to be_nil
461
+ expect(ump).to be_an(Array)
462
+ expect(ump.size).to eq(3)
463
+ %w(alpha bravo lima).each_with_index do |entity, index|
464
+ expect(ump[index]).to eq(:entity => entity,
465
+ :check => "ping",
466
+ # The state here is nil due to no check having gone
467
+ # through for this item. This is normally 'critical' or 'ok'
468
+ :state => nil,
469
+ :start_time => five_hours_ago,
470
+ :end_time => five_hours_ago + seven_hours,
471
+ :duration => seven_hours,
472
+ :summary => "Test unscheduled maintenance for #{entity}")
473
+ end
474
+ end
475
+
476
+ it "finds all scheduled maintenance starting more than 3 hours ago" do
477
+ ['more than three hours ago', 'before 3 hours ago'].each do |input|
478
+ ec = Flapjack::Data::EntityCheck.for_entity_name(name, check, :redis => @redis)
479
+
480
+ # Maintenance in the past, now ended
481
+ ec.create_scheduled_maintenance(five_hours_ago, half_an_hour, :summary => "30 minute maintenance")
482
+ # Maintenance started in the past, still running
483
+ ec.create_scheduled_maintenance(three_hours_ago + five_minutes, seven_hours, :summary => "Scheduled maintenance started 3 hours ago")
484
+ ec.create_scheduled_maintenance(four_hours_ago, seven_hours, :summary => "Scheduled maintenance started 4 hours ago")
485
+
486
+ smp = Flapjack::Data::EntityCheck.find_maintenance(:redis => @redis, :type => 'scheduled', :started => input).sort_by { |k| k[:entity] }
487
+
488
+ expect(smp).to be_an(Array)
489
+ expect(smp.size).to eq(2)
490
+
491
+ expect(smp[0]).to eq(:entity => name,
492
+ :check => check,
493
+ # The state here is nil due to no check having gone
494
+ # through for this item. This is normally 'critical' or 'ok'
495
+ :state => nil,
496
+ :start_time => five_hours_ago,
497
+ :end_time => five_hours_ago + half_an_hour,
498
+ :duration => half_an_hour,
499
+ :summary => "30 minute maintenance")
500
+ expect(smp[1]).to eq(:entity => name,
501
+ :check => check,
502
+ # The state here is nil due to no check having gone
503
+ # through for this item. This is normally 'critical' or 'ok'
504
+ :state => nil,
505
+ :start_time => four_hours_ago,
506
+ :end_time => four_hours_ago + seven_hours,
507
+ :duration => seven_hours,
508
+ :summary => "Scheduled maintenance started 4 hours ago")
509
+ end
510
+ end
511
+
512
+ it "finds all scheduled maintenance starting within the next four hours" do
513
+ ['less than four hours ago', 'after 4 hours ago'].each do |input|
514
+ ec = Flapjack::Data::EntityCheck.for_entity_name(name, check, :redis => @redis)
515
+
516
+ # Maintenance in the past, now ended
517
+ ec.create_scheduled_maintenance(five_hours_ago, half_an_hour, :summary => "30 minute maintenance")
518
+ # Maintenance started in the past, still running
519
+ ec.create_scheduled_maintenance(three_hours_ago, seven_hours, :summary => "Scheduled maintenance started 3 hours ago")
520
+ ec.create_scheduled_maintenance(four_hours_ago, seven_hours, :summary => "Scheduled maintenance started 4 hours ago")
521
+
522
+ smp = Flapjack::Data::EntityCheck.find_maintenance(:redis => @redis, :type => 'scheduled', :started => input).sort_by { |k| k[:entity] }
523
+
524
+ expect(smp).to be_an(Array)
525
+ expect(smp.size).to eq(1)
526
+
527
+ expect(smp[0]).to eq(:entity => name,
528
+ :check => check,
529
+ # The state here is nil due to no check having gone
530
+ # through for this item. This is normally 'critical' or 'ok'
531
+ :state => nil,
532
+ :start_time => three_hours_ago,
533
+ :end_time => three_hours_ago + seven_hours,
534
+ :duration => seven_hours,
535
+ :summary => "Scheduled maintenance started 3 hours ago")
536
+ end
537
+ end
538
+
539
+ it "finds all scheduled maintenance ending within the next two hours" do
540
+ ['less than two hours', 'before 2 hours'].each do |input|
541
+ ec = Flapjack::Data::EntityCheck.for_entity_name(name, check, :redis => @redis)
542
+ # Maintenance in the past, now ended
543
+ ec.create_scheduled_maintenance(two_hours_ago + five_minutes, half_an_hour, :summary => "Scheduled maintenance started 3 hours ago")
544
+ # Maintenance started in the past, still running
545
+ ec.create_scheduled_maintenance(three_hours_ago, seven_hours, :summary => "Scheduled maintenance started 3 hours ago for 7 hours")
546
+ ec.create_scheduled_maintenance(five_hours_ago, seven_hours + five_minutes, :summary => "Scheduled maintenance started 5 hours ago")
547
+ # Current maintenance
548
+ ec.create_scheduled_maintenance(t, half_an_hour, :summary => "Scheduled maintenance started now")
549
+ # Future maintenance
550
+ ec.create_scheduled_maintenance(t + five_minutes, half_an_hour, :summary => "Scheduled maintenance starting in 5 minutes")
551
+
552
+ smp = Flapjack::Data::EntityCheck.find_maintenance(:redis => @redis, :type => 'scheduled', :finishing => input).sort_by { |k| k[:entity] }
553
+
554
+ expect(smp).to be_an(Array)
555
+ expect(smp.size).to eq(3)
556
+
557
+ expect(smp[0]).to eq(:entity => name,
558
+ :check => check,
559
+ # The state here is nil due to no check having gone
560
+ # through for this item. This is normally 'critical' or 'ok'
561
+ :state => nil,
562
+ :start_time => two_hours_ago + five_minutes,
563
+ :end_time => two_hours_ago + five_minutes + half_an_hour,
564
+ :duration => half_an_hour,
565
+ :summary => "Scheduled maintenance started 3 hours ago")
566
+ expect(smp[1]).to eq(:entity => name,
567
+ :check => check,
568
+ # The state here is nil due to no check having gone
569
+ # through for this item. This is normally 'critical' or 'ok'
570
+ :state => nil,
571
+ :start_time => t,
572
+ :end_time => t + half_an_hour,
573
+ :duration => half_an_hour,
574
+ :summary => "Scheduled maintenance started now")
575
+ expect(smp[2]).to eq(:entity => name,
576
+ :check => check,
577
+ # The state here is nil due to no check having gone
578
+ # through for this item. This is normally 'critical' or 'ok'
579
+ :state => nil,
580
+ :start_time => t + five_minutes,
581
+ :end_time => t + five_minutes + half_an_hour,
582
+ :duration => half_an_hour,
583
+ :summary => "Scheduled maintenance starting in 5 minutes")
584
+ end
585
+ end
586
+
587
+ it "finds all scheduled maintenance ending between two times (1 hour ago - 2 hours ago)" do
588
+ ec = Flapjack::Data::EntityCheck.for_entity_name(name, check, :redis => @redis)
589
+ # Maintenance in the past, now ended
590
+ ec.create_scheduled_maintenance(two_hours_ago + five_minutes, half_an_hour, :summary => "Scheduled maintenance started 1 hour, 55 minutes ago")
591
+ # Maintenance started in the past, still running
592
+ ec.create_scheduled_maintenance(three_hours_ago, seven_hours, :summary => "Scheduled maintenance started 3 hours ago for 7 hours")
593
+ ec.create_scheduled_maintenance(five_hours_ago, three_hours + five_minutes, :summary => "Scheduled maintenance started 5 hours ago")
594
+ # Future maintenance
595
+ ec.create_scheduled_maintenance(t + five_minutes, half_an_hour, :summary => "Scheduled maintenance starting in 5 minutes")
596
+
597
+ smp = Flapjack::Data::EntityCheck.find_maintenance(:redis => @redis, :type => 'scheduled', :finishing => 'between one and two hours ago').sort_by { |k| k[:entity] }
598
+
599
+ expect(smp).to be_an(Array)
600
+ expect(smp.size).to eq(2)
601
+
602
+ expect(smp[0]).to eq(:entity => name,
603
+ :check => check,
604
+ # The state here is nil due to no check having gone
605
+ # through for this item. This is normally 'critical' or 'ok'
606
+ :state => nil,
607
+ :start_time => five_hours_ago,
608
+ :end_time => five_hours_ago + three_hours + five_minutes,
609
+ :duration => three_hours + five_minutes,
610
+ :summary => "Scheduled maintenance started 5 hours ago")
611
+ expect(smp[1]).to eq(:entity => name,
612
+ :check => check,
613
+ # The state here is nil due to no check having gone
614
+ # through for this item. This is normally 'critical' or 'ok'
615
+ :state => nil,
616
+ :start_time => two_hours_ago + five_minutes,
617
+ :end_time => two_hours_ago + five_minutes + half_an_hour,
618
+ :duration => half_an_hour,
619
+ :summary => "Scheduled maintenance started 1 hour, 55 minutes ago")
620
+ end
621
+
622
+ it "finds all scheduled maintenance ending between two times (1 hour from now - 2 hours from now)" do
623
+ ec = Flapjack::Data::EntityCheck.for_entity_name(name, check, :redis => @redis)
624
+ # Maintenance in the past, now ended
625
+ ec.create_scheduled_maintenance(two_hours_ago + five_minutes, half_an_hour, :summary => "Scheduled maintenance started 1 hour, 55 minutes ago")
626
+ # Maintenance started in the past, still running
627
+ ec.create_scheduled_maintenance(three_hours_ago, five_hours - five_minutes, :summary => "Scheduled maintenance started 3 hours ago for 4 hours, 25 minutes")
628
+ ec.create_scheduled_maintenance(five_hours_ago, three_hours + five_minutes, :summary => "Scheduled maintenance started 5 hours ago")
629
+ # Future maintenance
630
+ ec.create_scheduled_maintenance(t + five_minutes, one_hour, :summary => "Scheduled maintenance starting in 5 minutes")
631
+
632
+ smp = Flapjack::Data::EntityCheck.find_maintenance(:redis => @redis, :type => 'scheduled', :finishing => 'between one and two hours').sort_by { |k| k[:entity] }
633
+
634
+ expect(smp).to be_an(Array)
635
+ expect(smp.size).to eq(2)
636
+
637
+ expect(smp[0]).to eq(:entity => name,
638
+ :check => check,
639
+ # The state here is nil due to no check having gone
640
+ # through for this item. This is normally 'critical' or 'ok'
641
+ :state => nil,
642
+ :start_time => three_hours_ago,
643
+ :end_time => three_hours_ago + five_hours - five_minutes,
644
+ :duration => five_hours - five_minutes,
645
+ :summary => "Scheduled maintenance started 3 hours ago for 4 hours, 25 minutes")
646
+ expect(smp[1]).to eq(:entity => name,
647
+ :check => check,
648
+ # The state here is nil due to no check having gone
649
+ # through for this item. This is normally 'critical' or 'ok'
650
+ :state => nil,
651
+ :start_time => t + five_minutes,
652
+ :end_time => t + five_minutes + one_hour,
653
+ :duration => one_hour,
654
+ :summary => "Scheduled maintenance starting in 5 minutes")
655
+ end
656
+
657
+ it "finds all scheduled maintenance ending in more than two hours" do
658
+ ['more than two hours', 'after 2 hours'].each do |input|
659
+ ec = Flapjack::Data::EntityCheck.for_entity_name(name, check, :redis => @redis)
660
+ # Maintenance in the past, now ended
661
+ ec.create_scheduled_maintenance(two_hours_ago, half_an_hour, :summary => "Scheduled maintenance started 2 hours ago")
662
+ # Maintenance started in the past, still running
663
+ ec.create_scheduled_maintenance(three_hours_ago, seven_hours, :summary => "Scheduled maintenance started 3 hours ago for 7 hours")
664
+ ec.create_scheduled_maintenance(five_hours_ago, seven_hours, :summary => "Scheduled maintenance started 5 hours ago")
665
+ # Current maintenance
666
+ ec.create_scheduled_maintenance(t, half_an_hour, :summary => "Scheduled maintenance started now")
667
+ # Future maintenance
668
+ ec.create_scheduled_maintenance(t + five_minutes, half_an_hour, :summary => "Scheduled maintenance starting in 5 minutes")
669
+
670
+ smp = Flapjack::Data::EntityCheck.find_maintenance(:redis => @redis, :type => 'scheduled', :finishing => input).sort_by { |k| k[:entity] }
671
+
672
+ expect(smp).to be_an(Array)
673
+ expect(smp.size).to eq(1)
674
+
675
+ expect(smp[0]).to eq(:entity => name,
676
+ :check => check,
677
+ # The state here is nil due to no check having gone
678
+ # through for this item. This is normally 'critical' or 'ok'
679
+ :state => nil,
680
+ :start_time => three_hours_ago,
681
+ :end_time => three_hours_ago + seven_hours,
682
+ :duration => seven_hours,
683
+ :summary => "Scheduled maintenance started 3 hours ago for 7 hours")
684
+ end
685
+ end
686
+
687
+ it "finds all scheduled maintenance with a duration of less than one hour" do
688
+ ['less than', 'before'].each do |input|
689
+ ec = Flapjack::Data::EntityCheck.for_entity_name(name, check, :redis => @redis)
690
+ # Maintenance in the past, now ended
691
+ ec.create_scheduled_maintenance(two_hours_ago, half_an_hour, :summary => "Scheduled maintenance started 3 hours ago")
692
+ # Maintenance started in the past, still running
693
+ ec.create_scheduled_maintenance(three_hours_ago, seven_hours, :summary => "Scheduled maintenance started 3 hours ago for 7 hours")
694
+ ec.create_scheduled_maintenance(five_hours_ago, seven_hours, :summary => "Scheduled maintenance started 5 hours ago")
695
+ # Current maintenance
696
+ ec.create_scheduled_maintenance(t, half_an_hour, :summary => "Scheduled maintenance started now")
697
+ # Future maintenance
698
+ ec.create_scheduled_maintenance(t + five_minutes, half_an_hour, :summary => "Scheduled maintenance starting in 5 minutes")
699
+
700
+ smp = Flapjack::Data::EntityCheck.find_maintenance(:redis => @redis, :type => 'scheduled', :duration => "#{input} one hour").sort_by { |k| k[:entity] }
701
+
702
+ expect(smp).to be_an(Array)
703
+ expect(smp.size).to eq(3)
704
+
705
+ expect(smp[0]).to eq(:entity => name,
706
+ :check => check,
707
+ # The state here is nil due to no check having gone
708
+ # through for this item. This is normally 'critical' or 'ok'
709
+ :state => nil,
710
+ :start_time => two_hours_ago,
711
+ :end_time => two_hours_ago + half_an_hour,
712
+ :duration => half_an_hour,
713
+ :summary => "Scheduled maintenance started 3 hours ago")
714
+ expect(smp[1]).to eq(:entity => name,
715
+ :check => check,
716
+ # The state here is nil due to no check having gone
717
+ # through for this item. This is normally 'critical' or 'ok'
718
+ :state => nil,
719
+ :start_time => t,
720
+ :end_time => t + half_an_hour,
721
+ :duration => half_an_hour,
722
+ :summary => "Scheduled maintenance started now")
723
+ expect(smp[2]).to eq(:entity => name,
724
+ :check => check,
725
+ # The state here is nil due to no check having gone
726
+ # through for this item. This is normally 'critical' or 'ok'
727
+ :state => nil,
728
+ :start_time => t + five_minutes,
729
+ :end_time => t + five_minutes + half_an_hour,
730
+ :duration => half_an_hour,
731
+ :summary => "Scheduled maintenance starting in 5 minutes")
732
+ end
733
+ end
734
+
735
+ it "finds all scheduled maintenance with a duration of 30 minutes" do
736
+ ec = Flapjack::Data::EntityCheck.for_entity_name(name, check, :redis => @redis)
737
+ # Maintenance in the past, now ended
738
+ ec.create_scheduled_maintenance(two_hours_ago, half_an_hour, :summary => "Scheduled maintenance started 3 hours ago")
739
+ # Maintenance started in the past, still running
740
+ ec.create_scheduled_maintenance(three_hours_ago, seven_hours, :summary => "Scheduled maintenance started 3 hours ago for 7 hours")
741
+ ec.create_scheduled_maintenance(five_hours_ago, seven_hours, :summary => "Scheduled maintenance started 5 hours ago")
742
+ # Current maintenance
743
+ ec.create_scheduled_maintenance(t, half_an_hour, :summary => "Scheduled maintenance started now")
744
+ # Future maintenance
745
+ ec.create_scheduled_maintenance(t + five_minutes, half_an_hour, :summary => "Scheduled maintenance starting in 5 minutes")
746
+
747
+ smp = Flapjack::Data::EntityCheck.find_maintenance(:redis => @redis, :type => 'scheduled', :duration => '30 minutes').sort_by { |k| k[:entity] }
748
+
749
+ expect(smp).to be_an(Array)
750
+ expect(smp.size).to eq(3)
751
+
752
+ expect(smp[0]).to eq(:entity => name,
753
+ :check => check,
754
+ # The state here is nil due to no check having gone
755
+ # through for this item. This is normally 'critical' or 'ok'
756
+ :state => nil,
757
+ :start_time => two_hours_ago,
758
+ :end_time => two_hours_ago + half_an_hour,
759
+ :duration => half_an_hour,
760
+ :summary => "Scheduled maintenance started 3 hours ago")
761
+ expect(smp[1]).to eq(:entity => name,
762
+ :check => check,
763
+ # The state here is nil due to no check having gone
764
+ # through for this item. This is normally 'critical' or 'ok'
765
+ :state => nil,
766
+ :start_time => t,
767
+ :end_time => t + half_an_hour,
768
+ :duration => half_an_hour,
769
+ :summary => "Scheduled maintenance started now")
770
+ expect(smp[2]).to eq(:entity => name,
771
+ :check => check,
772
+ # The state here is nil due to no check having gone
773
+ # through for this item. This is normally 'critical' or 'ok'
774
+ :state => nil,
775
+ :start_time => t + five_minutes,
776
+ :end_time => t + five_minutes + half_an_hour,
777
+ :duration => half_an_hour,
778
+ :summary => "Scheduled maintenance starting in 5 minutes")
779
+ end
780
+
781
+ it "finds all scheduled maintenance with a duration of between 15 and 65 minutes" do
782
+ ec = Flapjack::Data::EntityCheck.for_entity_name(name, check, :redis => @redis)
783
+ # Maintenance in the past, now ended
784
+ ec.create_scheduled_maintenance(two_hours_ago, half_an_hour, :summary => "Scheduled maintenance started 3 hours ago")
785
+ # Maintenance started in the past, still running
786
+ ec.create_scheduled_maintenance(three_hours_ago, seven_hours, :summary => "Scheduled maintenance started 3 hours ago for 7 hours")
787
+ ec.create_scheduled_maintenance(five_hours_ago, one_hour, :summary => "Scheduled maintenance started 5 hours ago")
788
+ # Current maintenance
789
+ ec.create_scheduled_maintenance(t, half_an_hour, :summary => "Scheduled maintenance started now")
790
+ # Future maintenance
791
+ ec.create_scheduled_maintenance(t + five_minutes, half_an_hour, :summary => "Scheduled maintenance starting in 5 minutes")
792
+
793
+ smp = Flapjack::Data::EntityCheck.find_maintenance(:redis => @redis, :type => 'scheduled', :duration => 'between 15 and 65 minutes').sort_by { |k| k[:entity] }
794
+
795
+ expect(smp).to be_an(Array)
796
+ expect(smp.size).to eq(4)
797
+
798
+ expect(smp[1]).to eq(:entity => name,
799
+ :check => check,
800
+ # The state here is nil due to no check having gone
801
+ # through for this item. This is normally 'critical' or 'ok'
802
+ :state => nil,
803
+ :start_time => two_hours_ago,
804
+ :end_time => two_hours_ago + half_an_hour,
805
+ :duration => half_an_hour,
806
+ :summary => "Scheduled maintenance started 3 hours ago")
807
+ expect(smp[0]).to eq(:entity => name,
808
+ :check => check,
809
+ # The state here is nil due to no check having gone
810
+ # through for this item. This is normally 'critical' or 'ok'
811
+ :state => nil,
812
+ :start_time => five_hours_ago,
813
+ :end_time => five_hours_ago + one_hour,
814
+ :duration => one_hour,
815
+ :summary => "Scheduled maintenance started 5 hours ago")
816
+ expect(smp[2]).to eq(:entity => name,
817
+ :check => check,
818
+ # The state here is nil due to no check having gone
819
+ # through for this item. This is normally 'critical' or 'ok'
820
+ :state => nil,
821
+ :start_time => t,
822
+ :end_time => t + half_an_hour,
823
+ :duration => half_an_hour,
824
+ :summary => "Scheduled maintenance started now")
825
+ expect(smp[3]).to eq(:entity => name,
826
+ :check => check,
827
+ # The state here is nil due to no check having gone
828
+ # through for this item. This is normally 'critical' or 'ok'
829
+ :state => nil,
830
+ :start_time => t + five_minutes,
831
+ :end_time => t + five_minutes + half_an_hour,
832
+ :duration => half_an_hour,
833
+ :summary => "Scheduled maintenance starting in 5 minutes")
834
+ end
835
+
836
+ it "finds all scheduled maintenance with a duration of more than one hour" do
837
+ ['more than, after'].each do |input|
838
+ ec = Flapjack::Data::EntityCheck.for_entity_name(name, check, :redis => @redis)
839
+ # Maintenance in the past, now ended
840
+ ec.create_scheduled_maintenance(two_hours_ago, half_an_hour, :summary => "Scheduled maintenance started 3 hours ago")
841
+ # Maintenance started in the past, still running
842
+ ec.create_scheduled_maintenance(three_hours_ago, seven_hours, :summary => "Scheduled maintenance started 3 hours ago for 7 hours")
843
+ ec.create_scheduled_maintenance(five_hours_ago, seven_hours, :summary => "Scheduled maintenance started 5 hours ago")
844
+ # Current maintenance
845
+ ec.create_scheduled_maintenance(t, half_an_hour, :summary => "Scheduled maintenance started now")
846
+ # Future maintenance
847
+ ec.create_scheduled_maintenance(t + five_minutes, half_an_hour, :summary => "Scheduled maintenance starting in 5 minutes")
848
+
849
+ smp = Flapjack::Data::EntityCheck.find_maintenance(:redis => @redis, :type => 'scheduled', :duration => "#{input} one hour").sort_by { |k| k[:entity] }
850
+
851
+ expect(smp).to be_an(Array)
852
+ expect(smp.size).to eq(2)
853
+
854
+ expect(smp[0]).to eq(:entity => name,
855
+ :check => check,
856
+ # The state here is nil due to no check having gone
857
+ # through for this item. This is normally 'critical' or 'ok'
858
+ :state => nil,
859
+ :start_time => five_hours_ago,
860
+ :end_time => five_hours_ago + seven_hours,
861
+ :duration => seven_hours,
862
+ :summary => "Scheduled maintenance started 5 hours ago")
863
+ expect(smp[1]).to eq(:entity => name,
864
+ :check => check,
865
+ # The state here is nil due to no check having gone
866
+ # through for this item. This is normally 'critical' or 'ok'
867
+ :state => nil,
868
+ :start_time => three_hours_ago,
869
+ :end_time => three_hours_ago + seven_hours,
870
+ :duration => seven_hours,
871
+ :summary => "Scheduled maintenance started 3 hours ago for 7 hours")
872
+ end
873
+ end
874
+
875
+ it "finds all scheduled maintenance with a particular entity name" do
876
+ ['bravo', 'br.*'].each do |input|
877
+ %w(alpha bravo lima).each do |entity|
878
+ Flapjack::Data::Entity.add({ 'name' => entity }, :redis => @redis)
879
+
880
+ ec = Flapjack::Data::EntityCheck.for_entity_name(entity, check, :redis => @redis)
881
+ ec.create_scheduled_maintenance(five_hours_ago, seven_hours, :summary => "Test scheduled maintenance for #{entity}")
882
+ end
883
+
884
+ smp = Flapjack::Data::EntityCheck.find_maintenance(:redis => @redis, :type => 'scheduled', :entity => input ).sort_by { |k| k[:entity] }
885
+
886
+ expect(smp).to be_an(Array)
887
+ expect(smp.size).to eq(1)
888
+ expect(smp[0]).to eq(:entity => "bravo",
889
+ :check => check,
890
+ # The state here is nil due to no check having gone
891
+ # through for this item. This is normally 'critical' or 'ok'
892
+ :state => nil,
893
+ :start_time => five_hours_ago,
894
+ :end_time => five_hours_ago + seven_hours,
895
+ :duration => seven_hours,
896
+ :summary => "Test scheduled maintenance for bravo")
897
+ end
898
+ end
899
+
900
+ it "finds all scheduled maintenance with a particular check name" do
901
+ ['http', 'ht.*'].each do |input|
902
+ %w(ping http ssh).each do |check|
903
+ ec = Flapjack::Data::EntityCheck.for_entity_name(name, check, :redis => @redis)
904
+ ec.create_scheduled_maintenance(five_hours_ago, seven_hours, :summary => "Test scheduled maintenance for #{check}")
905
+ end
906
+
907
+ smp = Flapjack::Data::EntityCheck.find_maintenance(:redis => @redis, :type => 'scheduled', :check => input ).sort_by { |k| k[:entity] }
908
+
909
+ expect(smp).to be_an(Array)
910
+ expect(smp.size).to eq(1)
911
+ expect(smp[0]).to eq(:entity => name,
912
+ :check => "http",
913
+ # The state here is nil due to no check having gone
914
+ # through for this item. This is normally 'critical' or 'ok'
915
+ :state => nil,
916
+ :start_time => five_hours_ago,
917
+ :end_time => five_hours_ago + seven_hours,
918
+ :duration => seven_hours,
919
+ :summary => "Test scheduled maintenance for http")
920
+ end
921
+ end
922
+
923
+ it "finds all scheduled maintenance with a particular summary" do
924
+ ec = Flapjack::Data::EntityCheck.for_entity_name(name, check, :redis => @redis)
925
+
926
+ # Maintenance started in the past, still running
927
+ ec.create_scheduled_maintenance(three_hours_ago, seven_hours, :summary => "Bring me a shrubbery!")
928
+ # Current maintenance
929
+ ec.create_scheduled_maintenance(t, half_an_hour, :summary => "Bring me a shrubbery!")
930
+ # Future maintenance
931
+ ec.create_scheduled_maintenance(t + five_minutes, half_an_hour, :summary => "Scheduled maintenance starting in 5 minutes")
932
+
933
+ smp = Flapjack::Data::EntityCheck.find_maintenance(:redis => @redis, :type => 'scheduled', :reason => "Bring me a shrubbery!").sort_by { |k| k[:entity] }
934
+
935
+ expect(smp).to be_an(Array)
936
+ expect(smp.size).to eq(2)
937
+
938
+ expect(smp[0]).to eq(:entity => name,
939
+ :check => check,
940
+ # The state here is nil due to no check having gone
941
+ # through for this item. This is normally 'critical' or 'ok'
942
+ :state => nil,
943
+ :start_time => three_hours_ago,
944
+ :end_time => three_hours_ago + seven_hours,
945
+ :duration => seven_hours,
946
+ :summary => "Bring me a shrubbery!")
947
+ expect(smp[1]).to eq(:entity => name,
948
+ :check => check,
949
+ # The state here is nil due to no check having gone
950
+ # through for this item. This is normally 'critical' or 'ok'
951
+ :state => nil,
952
+ :start_time => t,
953
+ :end_time => t + half_an_hour,
954
+ :duration => half_an_hour,
955
+ :summary => "Bring me a shrubbery!")
956
+ end
957
+
958
+ it "finds all scheduled maintenance with a summary regex" do
959
+ ec = Flapjack::Data::EntityCheck.for_entity_name(name, check, :redis => @redis)
960
+
961
+ # Maintenance started in the past, still running
962
+ ec.create_scheduled_maintenance(three_hours_ago, seven_hours, :summary => "Bring me a shrubbery!")
963
+ # Current maintenance
964
+ ec.create_scheduled_maintenance(t, half_an_hour, :summary => "Bring me a shrubbery!")
965
+ # Future maintenance
966
+ ec.create_scheduled_maintenance(t + five_minutes, half_an_hour, :summary => "Scheduled maintenance starting in 5 minutes")
967
+
968
+ smp = Flapjack::Data::EntityCheck.find_maintenance(:redis => @redis, :type => 'scheduled', :reason => '.* shrubbery!').sort_by { |k| k[:entity] }
969
+
970
+ expect(smp).to be_an(Array)
971
+ expect(smp.size).to eq(2)
972
+
973
+ expect(smp[0]).to eq(:entity => name,
974
+ :check => check,
975
+ # The state here is nil due to no check having gone
976
+ # through for this item. This is normally 'critical' or 'ok'
977
+ :state => nil,
978
+ :start_time => three_hours_ago,
979
+ :end_time => three_hours_ago + seven_hours,
980
+ :duration => seven_hours,
981
+ :summary => "Bring me a shrubbery!")
982
+ expect(smp[1]).to eq(:entity => name,
983
+ :check => check,
984
+ # The state here is nil due to no check having gone
985
+ # through for this item. This is normally 'critical' or 'ok'
986
+ :state => nil,
987
+ :start_time => t,
988
+ :end_time => t + half_an_hour,
989
+ :duration => half_an_hour,
990
+ :summary => "Bring me a shrubbery!")
991
+ end
992
+
993
+ it "deletes scheduled maintenance from list" do
994
+ ec = Flapjack::Data::EntityCheck.for_entity_name(name, check, :redis => @redis)
995
+ # Current maintenance
996
+ ec.create_scheduled_maintenance(two_hours_ago, seven_hours, :summary => "Scheduled maintenance started 2 hours ago")
997
+ ec.create_scheduled_maintenance(t + half_an_hour, half_an_hour, :summary => "Scheduled maintenance starting in half an hour")
998
+ # Future maintenance
999
+ ec.create_scheduled_maintenance(t + five_minutes, half_an_hour, :summary => "Scheduled maintenance starting in 5 minutes")
1000
+
1001
+ smp = Flapjack::Data::EntityCheck.find_maintenance(:redis => @redis, :type => 'scheduled').sort_by { |k| k[:entity] }
1002
+
1003
+ expect(smp).to be_an(Array)
1004
+ expect(smp.size).to eq(3)
1005
+
1006
+ expect(smp[0]).to eq(:entity => name,
1007
+ :check => check,
1008
+ # The state here is nil due to no check having gone
1009
+ # through for this item. This is normally 'critical' or 'ok'
1010
+ :state => nil,
1011
+ :start_time => two_hours_ago,
1012
+ :end_time => two_hours_ago + seven_hours,
1013
+ :duration => seven_hours,
1014
+ :summary => "Scheduled maintenance started 2 hours ago")
1015
+ expect(smp[1]).to eq(:entity => name,
1016
+ :check => check,
1017
+ # The state here is nil due to no check having gone
1018
+ # through for this item. This is normally 'critical' or 'ok'
1019
+ :state => nil,
1020
+ :start_time => t + five_minutes,
1021
+ :end_time => t + five_minutes + half_an_hour,
1022
+ :duration => half_an_hour,
1023
+ :summary => "Scheduled maintenance starting in 5 minutes")
1024
+ expect(smp[2]).to eq(:entity => name,
1025
+ :check => check,
1026
+ # The state here is nil due to no check having gone
1027
+ # through for this item. This is normally 'critical' or 'ok'
1028
+ :state => nil,
1029
+ :start_time => t + half_an_hour,
1030
+ :end_time => t + half_an_hour + half_an_hour,
1031
+ :duration => half_an_hour,
1032
+ :summary => "Scheduled maintenance starting in half an hour")
1033
+
1034
+ delete = Flapjack::Data::EntityCheck.delete_maintenance(:redis => @redis, :type => 'scheduled', :duration => '30 minutes' )
1035
+ expect(delete).to eq({})
1036
+
1037
+ remain = Flapjack::Data::EntityCheck.find_maintenance(:redis => @redis, :type => 'scheduled').sort_by { |k| k[:entity] }
1038
+
1039
+ expect(remain).to be_an(Array)
1040
+ expect(remain.size).to eq(1)
1041
+
1042
+ expect(remain[0]).to eq(:entity => name,
1043
+ :check => check,
1044
+ # The state here is nil due to no check having gone
1045
+ # through for this item. This is normally 'critical' or 'ok'
1046
+ :state => nil,
1047
+ :start_time => two_hours_ago,
1048
+ :end_time => two_hours_ago + seven_hours,
1049
+ :duration => seven_hours,
1050
+ :summary => "Scheduled maintenance started 2 hours ago")
1051
+ end
1052
+
1053
+ it "deletes unscheduled maintenance from list" do
1054
+ ec = Flapjack::Data::EntityCheck.for_entity_name(name, check, :redis => @redis)
1055
+ ec.create_unscheduled_maintenance(t, half_an_hour, :summary => "Unscheduled maintenance starting now")
1056
+
1057
+ ump = Flapjack::Data::EntityCheck.find_maintenance(:redis => @redis, :type => 'unscheduled').sort_by { |k| k[:entity] }
1058
+ expect(ump).to be_an(Array)
1059
+ expect(ump.size).to eq(1)
1060
+
1061
+ expect(ump[0]).to eq(:entity => name,
1062
+ :check => check,
1063
+ # The state here is nil due to no check having gone
1064
+ # through for this item. This is normally 'critical' or 'ok'
1065
+ :state => nil,
1066
+ :start_time => t,
1067
+ :duration => half_an_hour,
1068
+ :end_time => t + half_an_hour,
1069
+ :summary => "Unscheduled maintenance starting now")
1070
+
1071
+ later_t = t + (15 * 60)
1072
+ Delorean.time_travel_to(Time.at(later_t))
1073
+
1074
+ delete = Flapjack::Data::EntityCheck.delete_maintenance(:redis => @redis, :type => 'unscheduled', :duration => '30 minutes')
1075
+ expect(delete).to eq({})
1076
+
1077
+ remain = Flapjack::Data::EntityCheck.find_maintenance(:redis => @redis, :type => 'unscheduled').sort_by { |k| k[:entity] }
1078
+ expect(remain).to be_an(Array)
1079
+ expect(remain.size).to eq(1)
1080
+
1081
+ expect(remain[0]).to eq(:entity => name,
1082
+ :check => check,
1083
+ # The state here is nil due to no check having gone
1084
+ # through for this item. This is normally 'critical' or 'ok'
1085
+ :state => nil,
1086
+ :start_time => t,
1087
+ :duration => half_an_hour,
1088
+ :end_time => t + half_an_hour,
1089
+ :summary => "Unscheduled maintenance starting now")
1090
+ end
1091
+
1092
+ it "shows errors when deleting maintenance in the past" do
1093
+ Flapjack::Data::EntityCheck.create_maintenance(:redis => @redis, :entity => name, :check => check, :type => 'unscheduled', :started => '14/3/1927 3pm', :duration => '30 minutes', :reason => 'Unscheduled maintenance')
1094
+ t = Time.local(1927, 3, 14, 15, 0).to_i
1095
+ ec = Flapjack::Data::EntityCheck.for_entity_name(name, check, :redis => @redis)
1096
+
1097
+ ump = Flapjack::Data::EntityCheck.find_maintenance(:redis => @redis, :type => 'unscheduled').sort_by { |k| k[:entity] }
1098
+ expect(ump).to be_an(Array)
1099
+ expect(ump.size).to eq(1)
1100
+
1101
+ expect(ump[0]).to eq(:entity => name,
1102
+ :check => check,
1103
+ # The state here is nil due to no check having gone
1104
+ # through for this item. This is normally 'critical' or 'ok'
1105
+ :state => nil,
1106
+ :start_time => t,
1107
+ :duration => half_an_hour,
1108
+ :end_time => t + half_an_hour,
1109
+ :summary => "Unscheduled maintenance")
1110
+
1111
+ delete = Flapjack::Data::EntityCheck.delete_maintenance(:redis => @redis, :type => 'unscheduled', :duration => '30 minutes')
1112
+ expect(delete).to eq({"abc-123:ping:#{t}"=>"Maintenance can't be deleted as it finished in the past"})
1113
+ end
362
1114
  end
363
1115
 
364
1116
  it "returns its state" do
@@ -517,14 +1269,14 @@ describe Flapjack::Data::EntityCheck, :redis => true do
517
1269
  t = Time.now.to_i
518
1270
 
519
1271
  ec.create_scheduled_maintenance(time_before(t, 180),
520
- half_an_hour, :summary => "a")
1272
+ half_an_hour, :summary => "a")
521
1273
  ec.create_scheduled_maintenance(time_before(t, 120),
522
- half_an_hour, :summary => "b")
1274
+ half_an_hour, :summary => "b")
523
1275
  ec.create_scheduled_maintenance(time_before(t, 60),
524
- half_an_hour, :summary => "c")
1276
+ half_an_hour, :summary => "c")
525
1277
 
526
1278
  sched_maint_periods = ec.maintenances(time_before(t, 150), t,
527
- :scheduled => true)
1279
+ :scheduled => true)
528
1280
  expect(sched_maint_periods).not_to be_nil
529
1281
  expect(sched_maint_periods).to be_an(Array)
530
1282
  expect(sched_maint_periods.size).to eq(2)