flapjack 0.7.35 → 0.8.0

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 (114) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -1
  3. data/Gemfile +3 -4
  4. data/Guardfile +1 -1
  5. data/README.md +38 -19
  6. data/Rakefile +1 -3
  7. data/etc/flapjack_config.yaml.example +11 -1
  8. data/features/steps/cli_steps.rb +3 -3
  9. data/features/steps/events_steps.rb +7 -6
  10. data/features/steps/flapjack-netsaint-parser_steps.rb +8 -8
  11. data/features/steps/notifications_steps.rb +10 -10
  12. data/features/steps/packaging-lintian_steps.rb +5 -9
  13. data/features/steps/time_travel_steps.rb +1 -1
  14. data/flapjack.gemspec +4 -3
  15. data/lib/flapjack/data/contact.rb +78 -6
  16. data/lib/flapjack/data/entity.rb +11 -2
  17. data/lib/flapjack/data/notification_rule.rb +67 -59
  18. data/lib/flapjack/data/semaphore.rb +44 -0
  19. data/lib/flapjack/gateways/api.rb +24 -28
  20. data/lib/flapjack/gateways/api/contact_methods.rb +1 -2
  21. data/lib/flapjack/gateways/api/entity_methods.rb +3 -3
  22. data/lib/flapjack/gateways/jsonapi.rb +249 -0
  23. data/lib/flapjack/gateways/jsonapi/contact_methods.rb +544 -0
  24. data/lib/flapjack/gateways/jsonapi/entity_check_presenter.rb +217 -0
  25. data/lib/flapjack/gateways/jsonapi/entity_methods.rb +350 -0
  26. data/lib/flapjack/gateways/jsonapi/entity_presenter.rb +75 -0
  27. data/lib/flapjack/gateways/jsonapi/rack/json_params_parser.rb +32 -0
  28. data/lib/flapjack/gateways/web.rb +78 -12
  29. data/lib/flapjack/gateways/web/public/css/bootstrap-theme.css +397 -0
  30. data/lib/flapjack/gateways/web/public/css/bootstrap-theme.min.css +7 -0
  31. data/lib/flapjack/gateways/web/public/css/bootstrap.css +7118 -0
  32. data/lib/flapjack/gateways/web/public/css/bootstrap.min.css +6 -8
  33. data/lib/flapjack/gateways/web/public/css/font-awesome.css +1338 -0
  34. data/lib/flapjack/gateways/web/public/css/font-awesome.min.css +4 -0
  35. data/lib/flapjack/gateways/web/public/css/screen.css +80 -0
  36. data/lib/flapjack/gateways/web/public/css/select2-bootstrap.css +87 -0
  37. data/lib/flapjack/gateways/web/public/css/select2.css +615 -0
  38. data/lib/flapjack/gateways/web/public/fonts/FontAwesome.otf +0 -0
  39. data/lib/flapjack/gateways/web/public/fonts/fontawesome-webfont.eot +0 -0
  40. data/lib/flapjack/gateways/web/public/fonts/fontawesome-webfont.svg +414 -0
  41. data/lib/flapjack/gateways/web/public/fonts/fontawesome-webfont.ttf +0 -0
  42. data/lib/flapjack/gateways/web/public/fonts/fontawesome-webfont.woff +0 -0
  43. data/lib/flapjack/gateways/web/public/fonts/glyphicons-halflings-regular.eot +0 -0
  44. data/lib/flapjack/gateways/web/public/fonts/glyphicons-halflings-regular.svg +229 -0
  45. data/lib/flapjack/gateways/web/public/fonts/glyphicons-halflings-regular.ttf +0 -0
  46. data/lib/flapjack/gateways/web/public/fonts/glyphicons-halflings-regular.woff +0 -0
  47. data/lib/flapjack/gateways/web/public/img/flapjack-2013-notext-transparent-300-300.png +0 -0
  48. data/lib/flapjack/gateways/web/public/img/select2.png +0 -0
  49. data/lib/flapjack/gateways/web/public/img/select2x2.png +0 -0
  50. data/lib/flapjack/gateways/web/public/js/backbone-min.js +2 -0
  51. data/lib/flapjack/gateways/web/public/js/backbone.js +1581 -0
  52. data/lib/flapjack/gateways/web/public/js/backbone.jsonapi.js +75 -0
  53. data/lib/flapjack/gateways/web/public/js/bootstrap.js +2276 -0
  54. data/lib/flapjack/gateways/web/public/js/contacts.js +225 -0
  55. data/lib/flapjack/gateways/web/public/js/jquery-1.10.2.js +9789 -0
  56. data/lib/flapjack/gateways/web/public/js/jquery-1.10.2.min.js +6 -0
  57. data/lib/flapjack/gateways/web/public/js/select2.js +3255 -0
  58. data/lib/flapjack/gateways/web/public/js/select2.min.js +22 -0
  59. data/lib/flapjack/gateways/web/public/js/underscore-min.js +6 -0
  60. data/lib/flapjack/gateways/web/public/js/underscore.js +1276 -0
  61. data/lib/flapjack/gateways/web/views/check.html.erb +423 -193
  62. data/lib/flapjack/gateways/web/views/checks.html.erb +51 -71
  63. data/lib/flapjack/gateways/web/views/contact.html.erb +142 -164
  64. data/lib/flapjack/gateways/web/views/contacts.html.erb +20 -40
  65. data/lib/flapjack/gateways/web/views/edit_contacts.html.erb +83 -0
  66. data/lib/flapjack/gateways/web/views/entities.html.erb +18 -37
  67. data/lib/flapjack/gateways/web/views/entity.html.erb +46 -65
  68. data/lib/flapjack/gateways/web/views/index.html.erb +6 -27
  69. data/lib/flapjack/gateways/web/views/layout.erb +95 -0
  70. data/lib/flapjack/gateways/web/views/self_stats.html.erb +100 -114
  71. data/lib/flapjack/pikelet.rb +4 -2
  72. data/lib/flapjack/version.rb +1 -1
  73. data/spec/lib/flapjack/coordinator_spec.rb +120 -120
  74. data/spec/lib/flapjack/data/contact_spec.rb +66 -58
  75. data/spec/lib/flapjack/data/entity_check_spec.rb +179 -179
  76. data/spec/lib/flapjack/data/entity_spec.rb +71 -71
  77. data/spec/lib/flapjack/data/event_spec.rb +34 -30
  78. data/spec/lib/flapjack/data/message_spec.rb +6 -6
  79. data/spec/lib/flapjack/data/notification_rule_spec.rb +24 -24
  80. data/spec/lib/flapjack/data/notification_spec.rb +19 -19
  81. data/spec/lib/flapjack/data/semaphore_spec.rb +24 -0
  82. data/spec/lib/flapjack/data/tag_spec.rb +11 -10
  83. data/spec/lib/flapjack/gateways/api/contact_methods_spec.rb +201 -201
  84. data/spec/lib/flapjack/gateways/api/entity_check_presenter_spec.rb +55 -55
  85. data/spec/lib/flapjack/gateways/api/entity_methods_spec.rb +257 -257
  86. data/spec/lib/flapjack/gateways/api/entity_presenter_spec.rb +26 -26
  87. data/spec/lib/flapjack/gateways/api_spec.rb +1 -1
  88. data/spec/lib/flapjack/gateways/email_spec.rb +4 -4
  89. data/spec/lib/flapjack/gateways/jabber_spec.rb +77 -77
  90. data/spec/lib/flapjack/gateways/jsonapi/contact_methods_spec.rb +830 -0
  91. data/spec/lib/flapjack/gateways/jsonapi/entity_check_presenter_spec.rb +211 -0
  92. data/spec/lib/flapjack/gateways/jsonapi/entity_methods_spec.rb +863 -0
  93. data/spec/lib/flapjack/gateways/jsonapi/entity_presenter_spec.rb +108 -0
  94. data/spec/lib/flapjack/gateways/jsonapi_spec.rb +8 -0
  95. data/spec/lib/flapjack/gateways/oobetet_spec.rb +35 -35
  96. data/spec/lib/flapjack/gateways/pagerduty_spec.rb +40 -40
  97. data/spec/lib/flapjack/gateways/sms_messagenet_spec.rb +3 -3
  98. data/spec/lib/flapjack/gateways/web/views/check.html.erb_spec.rb +1 -1
  99. data/spec/lib/flapjack/gateways/web/views/contact.html.erb_spec.rb +5 -5
  100. data/spec/lib/flapjack/gateways/web/views/index.html.erb_spec.rb +1 -1
  101. data/spec/lib/flapjack/gateways/web_spec.rb +73 -74
  102. data/spec/lib/flapjack/logger_spec.rb +13 -13
  103. data/spec/lib/flapjack/pikelet_spec.rb +33 -33
  104. data/spec/lib/flapjack/processor_spec.rb +22 -22
  105. data/spec/lib/flapjack/redis_pool_spec.rb +1 -1
  106. data/spec/lib/flapjack/utility_spec.rb +12 -12
  107. data/spec/spec_helper.rb +9 -9
  108. data/spec/support/erb_view_helper.rb +4 -0
  109. metadata +107 -96
  110. data/lib/flapjack/gateways/web/public/css/flapjack.css +0 -49
  111. data/lib/flapjack/gateways/web/views/_css.html.erb +0 -42
  112. data/lib/flapjack/gateways/web/views/_foot.html.erb +0 -3
  113. data/lib/flapjack/gateways/web/views/_head.html.erb +0 -5
  114. data/lib/flapjack/gateways/web/views/_nav.html.erb +0 -10
@@ -0,0 +1,211 @@
1
+ require 'spec_helper'
2
+ require 'flapjack/gateways/jsonapi/entity_check_presenter'
3
+
4
+ describe 'Flapjack::Gateways::JSONAPI::EntityCheckPresenter' do
5
+
6
+ let(:entity_check) { double(Flapjack::Data::EntityCheck) }
7
+
8
+ let(:time) { Time.now.to_i }
9
+
10
+ let(:states) {
11
+ [{:state => 'critical', :timestamp => time - (4 * 60 * 60)},
12
+ {:state => 'ok', :timestamp => time - (4 * 60 * 60) + (5 * 60)},
13
+ {:state => 'critical', :timestamp => time - (3 * 60 * 60)},
14
+ {:state => 'ok', :timestamp => time - (3 * 60 * 60) + (10 * 60)},
15
+ {:state => 'critical', :timestamp => time - (2 * 60 * 60)},
16
+ {:state => 'ok', :timestamp => time - (2 * 60 * 60) + (15 * 60)},
17
+ {:state => 'critical', :timestamp => time - (1 * 60 * 60)},
18
+ {:state => 'ok', :timestamp => time - (1 * 60 * 60) + (20 * 60)}
19
+ ]
20
+ }
21
+
22
+ # one overlap at start, one overlap at end, one wholly overlapping,
23
+ # one wholly contained
24
+ let(:maintenances) {
25
+ [{:start_time => time - ((4 * 60 * 60) + (1 * 60)), # 1 minute before outage starts
26
+ :end_time => time - (4 * 60 * 60) + (2 * 60), # 2 minutes after outage starts
27
+ :duration => (3 * 60)},
28
+ {:start_time => time - (3 * 60 * 60) + (8 * 60), # 2 minutes before outage ends
29
+ :end_time => time - (3 * 60 * 60) + (11 * 60), # 1 minute after outage ends
30
+ :duration => (3 * 60)},
31
+ {:start_time => time - ((2 * 60 * 60) + (1 * 60)), # 1 minute before outage starts
32
+ :end_time => time - (2 * 60 * 60) + (17 * 60), # 2 minutes after outage ends
33
+ :duration => (3 * 60)},
34
+ {:start_time => time - (1 * 60 * 60) + (1 * 60), # 1 minute after outage starts
35
+ :end_time => time - (1 * 60 * 60) + (10 * 60), # 10 minutes before outage ends
36
+ :duration => (9 * 60)}
37
+ ]
38
+ }
39
+
40
+ it "returns a list of outage hashes for an entity check" do
41
+ expect(entity_check).to receive(:historical_states).
42
+ with(time - (5 * 60 * 60), time - (2 * 60 * 60)).and_return(states)
43
+
44
+ expect(entity_check).to receive(:historical_state_before).
45
+ with(time - (4 * 60 * 60)).and_return(nil)
46
+
47
+ ecp = Flapjack::Gateways::JSONAPI::EntityCheckPresenter.new(entity_check)
48
+ outages = ecp.outages(time - (5 * 60 * 60), time - (2 * 60 * 60))
49
+ expect(outages).not_to be_nil
50
+ expect(outages).to be_an(Array)
51
+ expect(outages.size).to eq(4)
52
+
53
+ # TODO check the data in those hashes
54
+ end
55
+
56
+ it "returns a list of outage hashes with no start and end time set" do
57
+ expect(entity_check).to receive(:historical_states).
58
+ with(nil, nil).and_return(states)
59
+
60
+ expect(entity_check).to receive(:historical_state_before).
61
+ with(time - (4 * 60 * 60)).and_return(nil)
62
+
63
+ ecp = Flapjack::Gateways::JSONAPI::EntityCheckPresenter.new(entity_check)
64
+ outages = ecp.outages(nil, nil)
65
+ expect(outages).not_to be_nil
66
+ expect(outages).to be_an(Array)
67
+ expect(outages.size).to eq(4)
68
+
69
+ # TODO check the data in those hashes
70
+ end
71
+
72
+ it "returns a consolidated list of outage hashes with repeated state events" do
73
+ states[1][:state] = 'critical'
74
+ states[2][:state] = 'ok'
75
+
76
+ expect(entity_check).to receive(:historical_states).
77
+ with(nil, nil).and_return(states)
78
+
79
+ expect(entity_check).to receive(:historical_state_before).
80
+ with(time - (4 * 60 * 60)).and_return(nil)
81
+
82
+ ecp = Flapjack::Gateways::JSONAPI::EntityCheckPresenter.new(entity_check)
83
+ outages = ecp.outages(nil, nil)
84
+ expect(outages).not_to be_nil
85
+ expect(outages).to be_an(Array)
86
+ expect(outages.size).to eq(3)
87
+ end
88
+
89
+ it "returns a (small) outage hash for a single state change" do
90
+ expect(entity_check).to receive(:historical_states).
91
+ with(nil, nil).and_return([{:state => 'critical', :timestamp => time - (4 * 60 * 60)}])
92
+ expect(entity_check).to receive(:historical_state_before).
93
+ with(time - (4 * 60 * 60)).and_return(nil)
94
+
95
+ ecp = Flapjack::Gateways::JSONAPI::EntityCheckPresenter.new(entity_check)
96
+ outages = ecp.outages(nil, nil)
97
+ expect(outages).not_to be_nil
98
+ expect(outages).to be_an(Array)
99
+ expect(outages.size).to eq(1)
100
+ end
101
+
102
+ it "a list of unscheduled maintenances for an entity check" do
103
+ expect(entity_check).to receive(:maintenances).
104
+ with(time - (12 * 60 * 60), time, :scheduled => false).and_return(maintenances)
105
+
106
+ expect(entity_check).to receive(:maintenances).
107
+ with(nil, time - (12 * 60 * 60), :scheduled => false).and_return([])
108
+
109
+ ecp = Flapjack::Gateways::JSONAPI::EntityCheckPresenter.new(entity_check)
110
+ unsched_maint = ecp.unscheduled_maintenances(time - (12 * 60 * 60), time)
111
+
112
+ expect(unsched_maint).to be_an(Array)
113
+ expect(unsched_maint.size).to eq(4)
114
+
115
+ # TODO check the data in those hashes
116
+ end
117
+
118
+ it "a list of scheduled maintenances for an entity check" do
119
+ expect(entity_check).to receive(:maintenances).
120
+ with(time - (12 * 60 * 60), time, :scheduled => true).and_return(maintenances)
121
+
122
+ expect(entity_check).to receive(:maintenances).
123
+ with(nil, time - (12 * 60 * 60), :scheduled => true).and_return([])
124
+
125
+ ecp = Flapjack::Gateways::JSONAPI::EntityCheckPresenter.new(entity_check)
126
+ sched_maint = ecp.scheduled_maintenances(time - (12 * 60 * 60), time)
127
+
128
+ expect(sched_maint).to be_an(Array)
129
+ expect(sched_maint.size).to eq(4)
130
+
131
+ # TODO check the data in those hashes
132
+ end
133
+
134
+ it "returns downtime and percentage for a downtime check" do
135
+ expect(entity_check).to receive(:historical_states).
136
+ with(time - (12 * 60 * 60), time).and_return(states)
137
+
138
+ expect(entity_check).to receive(:historical_state_before).
139
+ with(time - (4 * 60 * 60)).and_return(nil)
140
+
141
+ expect(entity_check).to receive(:maintenances).
142
+ with(time - (12 * 60 * 60), time, :scheduled => true).and_return(maintenances)
143
+
144
+ expect(entity_check).to receive(:maintenances).
145
+ with(nil, time - (12 * 60 * 60), :scheduled => true).and_return([])
146
+
147
+ ecp = Flapjack::Gateways::JSONAPI::EntityCheckPresenter.new(entity_check)
148
+ downtimes = ecp.downtime(time - (12 * 60 * 60), time)
149
+
150
+ # 22 minutes, 3 + 8 + 11
151
+ expect(downtimes).to be_a(Hash)
152
+ expect(downtimes[:total_seconds]).to eq({'critical' => (22 * 60),
153
+ 'ok' => ((12 * 60 * 60) - (22 * 60))})
154
+ expect(downtimes[:percentages]).to eq({'critical' => (((22 * 60) * 100.0) / (12 * 60 * 60)),
155
+ 'ok' => ((((12 * 60 * 60) - (22 * 60)) * 100.0) / (12 * 60 *60))})
156
+ expect(downtimes[:downtime]).to be_an(Array)
157
+ # the last outage gets split by the intervening maintenance period,
158
+ # but the fully covered one gets removed.
159
+ expect(downtimes[:downtime].size).to eq(4)
160
+ end
161
+
162
+ it "returns downtime (but no percentage) for an unbounded downtime check" do
163
+ expect(entity_check).to receive(:historical_states).
164
+ with(nil, nil).and_return(states)
165
+
166
+ expect(entity_check).to receive(:historical_state_before).
167
+ with(time - (4 * 60 * 60)).and_return(nil)
168
+
169
+ expect(entity_check).to receive(:maintenances).
170
+ with(nil, nil, :scheduled => true).and_return(maintenances)
171
+
172
+ ecp = Flapjack::Gateways::JSONAPI::EntityCheckPresenter.new(entity_check)
173
+ downtimes = ecp.downtime(nil, nil)
174
+
175
+ # 22 minutes, 3 + 8 + 11
176
+ expect(downtimes).to be_a(Hash)
177
+ expect(downtimes[:total_seconds]).to eq({'critical' => (22 * 60)})
178
+ expect(downtimes[:percentages]).to eq({'critical' => nil})
179
+ expect(downtimes[:downtime]).to be_an(Array)
180
+ # the last outage gets split by the intervening maintenance period,
181
+ # but the fully covered one gets removed.
182
+ expect(downtimes[:downtime].size).to eq(4)
183
+ end
184
+
185
+ it "returns downtime and handles an unfinished problem state" do
186
+ current = [{:state => 'critical', :timestamp => time - (4 * 60 * 60)},
187
+ {:state => 'ok', :timestamp => time - (4 * 60 * 60) + (5 * 60)},
188
+ {:state => 'critical', :timestamp => time - (3 * 60 * 60)}]
189
+
190
+ expect(entity_check).to receive(:historical_states).
191
+ with(nil, nil).and_return(current)
192
+
193
+ expect(entity_check).to receive(:historical_state_before).
194
+ with(time - (4 * 60 * 60)).and_return(nil)
195
+
196
+ expect(entity_check).to receive(:maintenances).
197
+ with(nil, nil, :scheduled => true).and_return([])
198
+
199
+ ecp = Flapjack::Gateways::JSONAPI::EntityCheckPresenter.new(entity_check)
200
+ downtimes = ecp.downtime(nil, nil)
201
+
202
+ expect(downtimes).to be_a(Hash)
203
+ expect(downtimes[:total_seconds]).to eq({'critical' => (5 * 60)})
204
+ expect(downtimes[:percentages]).to eq({'critical' => nil})
205
+ expect(downtimes[:downtime]).to be_an(Array)
206
+ # the last outage gets split by the intervening maintenance period,
207
+ # but the fully covered one gets removed.
208
+ expect(downtimes[:downtime].size).to eq(2)
209
+ end
210
+
211
+ end
@@ -0,0 +1,863 @@
1
+ require 'spec_helper'
2
+ require 'flapjack/gateways/jsonapi'
3
+
4
+ describe 'Flapjack::Gateways::JSONAPI::EntityMethods', :sinatra => true, :logger => true do
5
+
6
+ def app
7
+ Flapjack::Gateways::JSONAPI
8
+ end
9
+
10
+ let(:entity) { double(Flapjack::Data::Entity) }
11
+ let(:entity_check) { double(Flapjack::Data::EntityCheck) }
12
+
13
+ let(:entity_name) { 'www.example.net'}
14
+ let(:entity_name_esc) { URI.escape(entity_name) }
15
+ let(:check) { 'ping' }
16
+
17
+ let(:entity_presenter) { double(Flapjack::Gateways::JSONAPI::EntityPresenter) }
18
+ let(:entity_check_presenter) { double(Flapjack::Gateways::JSONAPI::EntityCheckPresenter) }
19
+
20
+ let(:redis) { double(::Redis) }
21
+
22
+ before(:all) do
23
+ Flapjack::Gateways::JSONAPI.class_eval {
24
+ set :raise_errors, true
25
+ }
26
+ end
27
+
28
+ before(:each) do
29
+ expect(Flapjack::RedisPool).to receive(:new).and_return(redis)
30
+ Flapjack::Gateways::JSONAPI.instance_variable_set('@config', {})
31
+ Flapjack::Gateways::JSONAPI.instance_variable_set('@logger', @logger)
32
+ Flapjack::Gateways::JSONAPI.start
33
+ end
34
+
35
+ it "returns a list of checks for an entity" do
36
+ expect(entity).to receive(:check_list).and_return([check])
37
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
38
+ with(entity_name, :redis => redis).and_return(entity)
39
+
40
+ aget "/checks/#{entity_name_esc}"
41
+ expect(last_response).to be_ok
42
+ expect(last_response.body).to eq([check].to_json)
43
+ end
44
+
45
+ context 'non-bulk API calls' do
46
+
47
+ it "returns the status for all checks on an entity" do
48
+ status = double('status', :to_json => 'status!'.to_json)
49
+ result = {:entity => entity_name, :check => check, :status => status}
50
+ expect(entity_presenter).to receive(:status).and_return(result)
51
+
52
+ expect(Flapjack::Gateways::JSONAPI::EntityPresenter).to receive(:new).
53
+ with(entity, :redis => redis).and_return(entity_presenter)
54
+
55
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
56
+ with(entity_name, :redis => redis).and_return(entity)
57
+
58
+ aget "/status/#{entity_name_esc}"
59
+ expect(last_response).to be_ok
60
+ expect(last_response.body).to eq(['status!'].to_json)
61
+ end
62
+
63
+ it "should not show the status for an entity that's not found" do
64
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
65
+ with(entity_name, :redis => redis).and_return(nil)
66
+
67
+ aget "/status/#{entity_name_esc}"
68
+ expect(last_response.status).to eq(404)
69
+ end
70
+
71
+ it "returns the status for a check on an entity" do
72
+ status = double('status', :to_json => 'status!'.to_json)
73
+ expect(entity_check_presenter).to receive(:status).and_return(status)
74
+
75
+ expect(Flapjack::Gateways::JSONAPI::EntityCheckPresenter).to receive(:new).
76
+ with(entity_check).and_return(entity_check_presenter)
77
+
78
+ expect(Flapjack::Data::EntityCheck).to receive(:for_entity).
79
+ with(entity, check, :redis => redis).and_return(entity_check)
80
+
81
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
82
+ with(entity_name, :redis => redis).and_return(entity)
83
+
84
+ aget "/status/#{entity_name_esc}/#{check}"
85
+ expect(last_response).to be_ok
86
+ expect(last_response.body).to eq('status!'.to_json)
87
+ end
88
+
89
+ it "should not show the status for a check on an entity that's not found" do
90
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
91
+ with(entity_name, :redis => redis).and_return(nil)
92
+
93
+ aget "/status/#{entity_name_esc}/#{check}"
94
+ expect(last_response.status).to eq(404)
95
+ end
96
+
97
+ it "should not show the status for a check that's not found on an entity" do
98
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
99
+ with(entity_name, :redis => redis).and_return(entity)
100
+
101
+ expect(Flapjack::Data::EntityCheck).to receive(:for_entity).
102
+ with(entity, check, :redis => redis).and_return(nil)
103
+
104
+ aget "/status/#{entity_name_esc}/#{check}"
105
+ expect(last_response.status).to eq(404)
106
+ end
107
+
108
+ it "returns a list of scheduled maintenance periods for an entity" do
109
+ sched = double('sched', :to_json => 'sched!'.to_json)
110
+ result = {:entity => entity_name, :check => check, :scheduled_maintenances => sched}
111
+ expect(entity_presenter).to receive(:scheduled_maintenances).with(nil, nil).and_return(result)
112
+ expect(Flapjack::Gateways::JSONAPI::EntityPresenter).to receive(:new).
113
+ with(entity, :redis => redis).and_return(entity_presenter)
114
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
115
+ with(entity_name, :redis => redis).and_return(entity)
116
+
117
+ aget "/scheduled_maintenances/#{entity_name_esc}"
118
+ expect(last_response).to be_ok
119
+ expect(last_response.body).to eq([{:check => check, :scheduled_maintenance => sched}].to_json)
120
+ end
121
+
122
+ it "returns a list of scheduled maintenance periods within a time window for an entity" do
123
+ start = Time.parse('1 Jan 2012')
124
+ finish = Time.parse('6 Jan 2012')
125
+
126
+ sched = double('sched', :to_json => 'sched!'.to_json)
127
+ result = {:entity => entity_name, :check => check, :scheduled_maintenances => sched}
128
+ expect(entity_presenter).to receive(:scheduled_maintenances).with(start.to_i, finish.to_i).and_return(result)
129
+ expect(Flapjack::Gateways::JSONAPI::EntityPresenter).to receive(:new).
130
+ with(entity, :redis => redis).and_return(entity_presenter)
131
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
132
+ with(entity_name, :redis => redis).and_return(entity)
133
+
134
+ aget "/scheduled_maintenances/#{entity_name_esc}?" +
135
+ "start_time=#{CGI.escape(start.iso8601)}&end_time=#{CGI.escape(finish.iso8601)}"
136
+ expect(last_response).to be_ok
137
+ expect(last_response.body).to eq([{:check => check, :scheduled_maintenance => sched}].to_json)
138
+ end
139
+
140
+ it "returns a list of scheduled maintenance periods for a check on an entity" do
141
+ sched = double('sched', :to_json => 'sched!'.to_json)
142
+ expect(entity_check_presenter).to receive(:scheduled_maintenances).with(nil, nil).and_return(sched)
143
+ expect(Flapjack::Gateways::JSONAPI::EntityCheckPresenter).to receive(:new).
144
+ with(entity_check).and_return(entity_check_presenter)
145
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
146
+ with(entity_name, :redis => redis).and_return(entity)
147
+ expect(Flapjack::Data::EntityCheck).to receive(:for_entity).
148
+ with(entity, check, :redis => redis).and_return(entity_check)
149
+
150
+ aget "/scheduled_maintenances/#{entity_name_esc}/#{check}"
151
+ expect(last_response).to be_ok
152
+ expect(last_response.body).to eq('sched!'.to_json)
153
+ end
154
+
155
+ it "creates an acknowledgement for an entity check" do
156
+ expect(entity_check).to receive(:entity_name).and_return(entity_name)
157
+ expect(entity_check).to receive(:check).and_return(check)
158
+
159
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
160
+ with(entity_name, :redis => redis).and_return(entity)
161
+ expect(Flapjack::Data::EntityCheck).to receive(:for_entity).
162
+ with(entity, check, :redis => redis).and_return(entity_check)
163
+ expect(Flapjack::Data::Event).to receive(:create_acknowledgement).
164
+ with(entity_name, check, :summary => nil, :duration => (4 * 60 * 60), :redis => redis)
165
+
166
+ apost "/acknowledgements/#{entity_name_esc}/#{check}"
167
+ expect(last_response.status).to eq(204)
168
+ end
169
+
170
+ it "returns a list of unscheduled maintenance periods for an entity" do
171
+ unsched = double('unsched', :to_json => 'unsched!'.to_json)
172
+ result = {:entity => entity_name, :check => check, :unscheduled_maintenances => unsched}
173
+ expect(entity_presenter).to receive(:unscheduled_maintenances).with(nil, nil).and_return(result)
174
+ expect(Flapjack::Gateways::JSONAPI::EntityPresenter).to receive(:new).
175
+ with(entity, :redis => redis).and_return(entity_presenter)
176
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
177
+ with(entity_name, :redis => redis).and_return(entity)
178
+
179
+ aget "/unscheduled_maintenances/#{entity_name_esc}"
180
+ expect(last_response).to be_ok
181
+ expect(last_response.body).to eq([{:check => check, :unscheduled_maintenance => unsched}].to_json)
182
+ end
183
+
184
+ it "returns a list of unscheduled maintenance periods for a check on an entity" do
185
+ unsched = double('unsched', :to_json => 'unsched!'.to_json)
186
+ expect(entity_check_presenter).to receive(:unscheduled_maintenances).with(nil, nil).and_return(unsched)
187
+ expect(Flapjack::Gateways::JSONAPI::EntityCheckPresenter).to receive(:new).
188
+ with(entity_check).and_return(entity_check_presenter)
189
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
190
+ with(entity_name, :redis => redis).and_return(entity)
191
+ expect(Flapjack::Data::EntityCheck).to receive(:for_entity).
192
+ with(entity, check, :redis => redis).and_return(entity_check)
193
+
194
+ aget "/unscheduled_maintenances/#{entity_name_esc}/#{check}"
195
+ expect(last_response).to be_ok
196
+ expect(last_response.body).to eq('unsched!'.to_json)
197
+ end
198
+
199
+ it "returns a list of unscheduled maintenance periods within a time window for a check an entity" do
200
+ start = Time.parse('1 Jan 2012')
201
+ finish = Time.parse('6 Jan 2012')
202
+
203
+ unsched = double('unsched', :to_json => 'unsched!'.to_json)
204
+ expect(entity_check_presenter).to receive(:unscheduled_maintenances).with(start.to_i, finish.to_i).and_return(unsched)
205
+ expect(Flapjack::Gateways::JSONAPI::EntityCheckPresenter).to receive(:new).
206
+ with(entity_check).and_return(entity_check_presenter)
207
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
208
+ with(entity_name, :redis => redis).and_return(entity)
209
+ expect(Flapjack::Data::EntityCheck).to receive(:for_entity).
210
+ with(entity, check, :redis => redis).and_return(entity_check)
211
+
212
+ aget "/unscheduled_maintenances/#{entity_name_esc}/#{check}" +
213
+ "?start_time=#{CGI.escape(start.iso8601)}&end_time=#{CGI.escape(finish.iso8601)}"
214
+ expect(last_response).to be_ok
215
+ expect(last_response.body).to eq('unsched!'.to_json)
216
+ end
217
+
218
+ it "returns a list of outages for an entity" do
219
+ out = double('out', :to_json => 'out!'.to_json)
220
+ result = {:entity => entity_name, :check => check, :outages => out}
221
+ expect(entity_presenter).to receive(:outages).with(nil, nil).and_return(result)
222
+ expect(Flapjack::Gateways::JSONAPI::EntityPresenter).to receive(:new).
223
+ with(entity, :redis => redis).and_return(entity_presenter)
224
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
225
+ with(entity_name, :redis => redis).and_return(entity)
226
+
227
+ aget "/outages/#{entity_name_esc}"
228
+ expect(last_response).to be_ok
229
+ expect(last_response.body).to eq([{:check => check, :outages => out}].to_json)
230
+ end
231
+
232
+ it "returns a list of outages for a check on an entity" do
233
+ out = double('out', :to_json => 'out!'.to_json)
234
+ expect(entity_check_presenter).to receive(:outages).with(nil, nil).and_return(out)
235
+ expect(Flapjack::Gateways::JSONAPI::EntityCheckPresenter).to receive(:new).
236
+ with(entity_check).and_return(entity_check_presenter)
237
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
238
+ with(entity_name, :redis => redis).and_return(entity)
239
+ expect(Flapjack::Data::EntityCheck).to receive(:for_entity).
240
+ with(entity, check, :redis => redis).and_return(entity_check)
241
+
242
+ aget "/outages/#{entity_name_esc}/#{check}"
243
+ expect(last_response).to be_ok
244
+ expect(last_response.body).to eq('out!'.to_json)
245
+ end
246
+
247
+ it "returns a list of downtimes for an entity" do
248
+ down = double('down', :to_json => 'down!'.to_json)
249
+ result = {:entity => entity_name, :check => check, :downtime => down}
250
+ expect(entity_presenter).to receive(:downtime).with(nil, nil).and_return(result)
251
+ expect(Flapjack::Gateways::JSONAPI::EntityPresenter).to receive(:new).
252
+ with(entity, :redis => redis).and_return(entity_presenter)
253
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
254
+ with(entity_name, :redis => redis).and_return(entity)
255
+
256
+ aget "/downtime/#{entity_name_esc}"
257
+ expect(last_response).to be_ok
258
+ expect(last_response.body).to eq([{:check => check, :downtime => down}].to_json)
259
+ end
260
+
261
+ it "returns a list of downtimes for a check on an entity" do
262
+ down = double('down', :to_json => 'down!'.to_json)
263
+ expect(entity_check_presenter).to receive(:downtime).with(nil, nil).and_return(down)
264
+ expect(Flapjack::Gateways::JSONAPI::EntityCheckPresenter).to receive(:new).
265
+ with(entity_check).and_return(entity_check_presenter)
266
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
267
+ with(entity_name, :redis => redis).and_return(entity)
268
+ expect(Flapjack::Data::EntityCheck).to receive(:for_entity).
269
+ with(entity, check, :redis => redis).and_return(entity_check)
270
+
271
+ aget "/downtime/#{entity_name_esc}/#{check}"
272
+ expect(last_response).to be_ok
273
+ expect(last_response.body).to eq('down!'.to_json)
274
+ end
275
+
276
+ it "creates a test notification event for check on an entity" do
277
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
278
+ with(entity_name, :redis => redis).and_return(entity)
279
+ expect(entity).to receive(:name).and_return(entity_name)
280
+ expect(entity_check).to receive(:entity).and_return(entity)
281
+ expect(entity_check).to receive(:entity_name).and_return(entity_name)
282
+ expect(entity_check).to receive(:check).and_return('foo')
283
+ expect(Flapjack::Data::EntityCheck).to receive(:for_entity).
284
+ with(entity, 'foo', :redis => redis).and_return(entity_check)
285
+
286
+ expect(Flapjack::Data::Event).to receive(:test_notifications).
287
+ with(entity_name, 'foo', hash_including(:redis => redis))
288
+
289
+ apost "/test_notifications/#{entity_name_esc}/foo"
290
+ expect(last_response.status).to eq(204)
291
+ end
292
+
293
+ end
294
+
295
+ context 'bulk API calls' do
296
+
297
+ it "returns the status for all checks on an entity" do
298
+ status = double('status')
299
+ result = [{:entity => entity_name, :check => check, :status => status}]
300
+ expect(entity_presenter).to receive(:status).and_return(result)
301
+
302
+ expect(Flapjack::Gateways::JSONAPI::EntityPresenter).to receive(:new).
303
+ with(entity, :redis => redis).and_return(entity_presenter)
304
+
305
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
306
+ with(entity_name, :redis => redis).and_return(entity)
307
+
308
+ aget "/status", :entity => entity_name
309
+ expect(last_response.body).to eq(result.to_json)
310
+ end
311
+
312
+ it "should not show the status for an entity that's not found" do
313
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
314
+ with(entity_name, :redis => redis).and_return(nil)
315
+
316
+ aget "/status", :entity => entity_name
317
+ expect(last_response.status).to eq(404)
318
+ end
319
+
320
+ it "returns the status for a check on an entity" do
321
+ status = double('status')
322
+ result = [{:entity => entity_name, :check => check, :status => status}]
323
+ expect(entity_check_presenter).to receive(:status).and_return(status)
324
+
325
+ expect(Flapjack::Gateways::JSONAPI::EntityCheckPresenter).to receive(:new).
326
+ with(entity_check).and_return(entity_check_presenter)
327
+
328
+ expect(Flapjack::Data::EntityCheck).to receive(:for_entity).
329
+ with(entity, check, :redis => redis).and_return(entity_check)
330
+
331
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
332
+ with(entity_name, :redis => redis).and_return(entity)
333
+
334
+ aget "/status", :check => {entity_name => check}
335
+ expect(last_response).to be_ok
336
+ expect(last_response.body).to eq(result.to_json)
337
+ end
338
+
339
+ it "should not show the status for a check on an entity that's not found" do
340
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
341
+ with(entity_name, :redis => redis).and_return(nil)
342
+
343
+ aget "/status", :check => {entity_name => check}
344
+ expect(last_response.status).to eq(404)
345
+ end
346
+
347
+ it "should not show the status for a check that's not found on an entity" do
348
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
349
+ with(entity_name, :redis => redis).and_return(entity)
350
+
351
+ expect(Flapjack::Data::EntityCheck).to receive(:for_entity).
352
+ with(entity, check, :redis => redis).and_return(nil)
353
+
354
+ aget "/status", :check => {entity_name => check}
355
+ expect(last_response.status).to eq(404)
356
+ end
357
+
358
+ it "creates an acknowledgement for an entity check" do
359
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
360
+ with(entity_name, :redis => redis).and_return(entity)
361
+ expect(Flapjack::Data::EntityCheck).to receive(:for_entity).
362
+ with(entity, check, :redis => redis).and_return(entity_check)
363
+
364
+ expect(entity_check).to receive(:entity_name).and_return(entity_name)
365
+ expect(entity_check).to receive(:check).and_return(check)
366
+
367
+ expect(Flapjack::Data::Event).to receive(:create_acknowledgement).
368
+ with(entity_name, check, :summary => nil, :duration => (4 * 60 * 60), :redis => redis)
369
+
370
+ apost '/acknowledgements',:check => {entity_name => check}
371
+ expect(last_response.status).to eq(204)
372
+ end
373
+
374
+ it "deletes an unscheduled maintenance period for an entity check" do
375
+ end_time = Time.now + (60 * 60) # an hour from now
376
+ expect(entity_check).to receive(:end_unscheduled_maintenance).with(end_time.to_i)
377
+
378
+ expect(Flapjack::Data::EntityCheck).to receive(:for_entity).
379
+ with(entity, check, :redis => redis).and_return(entity_check)
380
+
381
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
382
+ with(entity_name, :redis => redis).and_return(entity)
383
+
384
+ adelete "/unscheduled_maintenances", :check => {entity_name => check}, :end_time => end_time.iso8601
385
+ expect(last_response.status).to eq(204)
386
+ end
387
+
388
+ it "creates a scheduled maintenance period for an entity check" do
389
+ start = Time.now + (60 * 60) # an hour from now
390
+ duration = (2 * 60 * 60) # two hours
391
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
392
+ with(entity_name, :redis => redis).and_return(entity)
393
+ expect(Flapjack::Data::EntityCheck).to receive(:for_entity).
394
+ with(entity, check, :redis => redis).and_return(entity_check)
395
+ expect(entity_check).to receive(:create_scheduled_maintenance).
396
+ with(start.getutc.to_i, duration, :summary => 'test')
397
+
398
+ apost "/scheduled_maintenances/#{entity_name_esc}/#{check}?" +
399
+ "start_time=#{CGI.escape(start.iso8601)}&summary=test&duration=#{duration}"
400
+ expect(last_response.status).to eq(204)
401
+ end
402
+
403
+ it "doesn't create a scheduled maintenance period if the start time isn't passed" do
404
+ duration = (2 * 60 * 60) # two hours
405
+
406
+ apost "/scheduled_maintenances/#{entity_name_esc}/#{check}?" +
407
+ "summary=test&duration=#{duration}"
408
+ expect(last_response.status).to eq(403)
409
+ end
410
+
411
+ it "deletes a scheduled maintenance period for an entity check" do
412
+ start_time = Time.now + (60 * 60) # an hour from now
413
+ expect(entity_check).to receive(:end_scheduled_maintenance).with(start_time.to_i)
414
+
415
+ expect(Flapjack::Data::EntityCheck).to receive(:for_entity).
416
+ with(entity, check, :redis => redis).and_return(entity_check)
417
+
418
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
419
+ with(entity_name, :redis => redis).and_return(entity)
420
+
421
+ adelete "/scheduled_maintenances", :check => {entity_name => check}, :start_time => start_time.iso8601
422
+ expect(last_response.status).to eq(204)
423
+ end
424
+
425
+ it "doesn't delete a scheduled maintenance period if the start time isn't passed" do
426
+ expect(entity_check).not_to receive(:end_scheduled_maintenance)
427
+
428
+ adelete "/scheduled_maintenances", :check => {entity_name => check}
429
+ expect(last_response.status).to eq(403)
430
+ end
431
+
432
+ it "deletes scheduled maintenance periods for multiple entity checks" do
433
+ start_time = Time.now + (60 * 60) # an hour from now
434
+
435
+ entity_check_2 = double(Flapjack::Data::EntityCheck)
436
+
437
+ expect(entity_check).to receive(:end_scheduled_maintenance).with(start_time.to_i)
438
+ expect(entity_check_2).to receive(:end_scheduled_maintenance).with(start_time.to_i)
439
+
440
+ expect(Flapjack::Data::EntityCheck).to receive(:for_entity).
441
+ with(entity, check, :redis => redis).and_return(entity_check)
442
+ expect(Flapjack::Data::EntityCheck).to receive(:for_entity).
443
+ with(entity, 'foo', :redis => redis).and_return(entity_check_2)
444
+
445
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
446
+ with(entity_name, :redis => redis).and_return(entity)
447
+
448
+ adelete "/scheduled_maintenances", :check => {entity_name => [check, 'foo']}, :start_time => start_time.iso8601
449
+ expect(last_response.status).to eq(204)
450
+ end
451
+
452
+ it "returns a list of scheduled maintenance periods for an entity" do
453
+ sm = double('sched_maint')
454
+ result = [{:entity => entity_name, :check => check, :scheduled_maintenances => sm}]
455
+
456
+ expect(entity_presenter).to receive(:scheduled_maintenances).with(nil, nil).and_return(result)
457
+
458
+ expect(Flapjack::Gateways::JSONAPI::EntityPresenter).to receive(:new).
459
+ with(entity, :redis => redis).and_return(entity_presenter)
460
+
461
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
462
+ with(entity_name, :redis => redis).and_return(entity)
463
+
464
+ aget "/scheduled_maintenances", :entity => entity_name
465
+ expect(last_response).to be_ok
466
+ expect(last_response.body).to eq(result.to_json)
467
+ end
468
+
469
+ it "returns a list of scheduled maintenance periods within a time window for an entity" do
470
+ start = Time.parse('1 Jan 2012')
471
+ finish = Time.parse('6 Jan 2012')
472
+
473
+ sm = double('sched_maint')
474
+ result = [{:entity => entity_name, :check => check, :scheduled_maintenances => sm}]
475
+
476
+ expect(entity_presenter).to receive(:scheduled_maintenances).with(start.to_i, finish.to_i).and_return(result)
477
+
478
+ expect(Flapjack::Gateways::JSONAPI::EntityPresenter).to receive(:new).
479
+ with(entity, :redis => redis).and_return(entity_presenter)
480
+
481
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
482
+ with(entity_name, :redis => redis).and_return(entity)
483
+
484
+ aget "/scheduled_maintenances", :entity => entity_name,
485
+ :start_time => start.iso8601, :end_time => finish.iso8601
486
+ expect(last_response).to be_ok
487
+ expect(last_response.body).to eq(result.to_json)
488
+ end
489
+
490
+ it "returns a list of scheduled maintenance periods for a check on an entity" do
491
+ sm = double('sched_maint')
492
+ result = [{:entity => entity_name, :check => check, :scheduled_maintenances => sm}]
493
+
494
+ expect(entity_check_presenter).to receive(:scheduled_maintenances).with(nil, nil).and_return(sm)
495
+
496
+ expect(Flapjack::Gateways::JSONAPI::EntityCheckPresenter).to receive(:new).
497
+ with(entity_check).and_return(entity_check_presenter)
498
+
499
+ expect(Flapjack::Data::EntityCheck).to receive(:for_entity).
500
+ with(entity, check, :redis => redis).and_return(entity_check)
501
+
502
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
503
+ with(entity_name, :redis => redis).and_return(entity)
504
+
505
+ aget "/scheduled_maintenances", :check => {entity_name => check}
506
+ expect(last_response).to be_ok
507
+ expect(last_response.body).to eq(result.to_json)
508
+ end
509
+
510
+ it "returns a list of unscheduled maintenance periods for an entity" do
511
+ um = double('unsched_maint')
512
+ result = [{:entity => entity_name, :check => check, :unscheduled_maintenances => um}]
513
+
514
+ expect(entity_presenter).to receive(:unscheduled_maintenances).with(nil, nil).and_return(result)
515
+
516
+ expect(Flapjack::Gateways::JSONAPI::EntityPresenter).to receive(:new).
517
+ with(entity, :redis => redis).and_return(entity_presenter)
518
+
519
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
520
+ with(entity_name, :redis => redis).and_return(entity)
521
+
522
+ aget "/unscheduled_maintenances", :entity => entity_name
523
+ expect(last_response).to be_ok
524
+ expect(last_response.body).to eq(result.to_json)
525
+ end
526
+
527
+ it "returns a list of unscheduled maintenance periods for a check on an entity" do
528
+ um = double('unsched_maint')
529
+ result = [{:entity => entity_name, :check => check, :unscheduled_maintenances => um}]
530
+
531
+ expect(entity_check_presenter).to receive(:unscheduled_maintenances).with(nil, nil).and_return(um)
532
+
533
+ expect(Flapjack::Gateways::JSONAPI::EntityCheckPresenter).to receive(:new).
534
+ with(entity_check).and_return(entity_check_presenter)
535
+
536
+ expect(Flapjack::Data::EntityCheck).to receive(:for_entity).
537
+ with(entity, check, :redis => redis).and_return(entity_check)
538
+
539
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
540
+ with(entity_name, :redis => redis).and_return(entity)
541
+
542
+ aget "/unscheduled_maintenances", :check => {entity_name => check}
543
+ expect(last_response).to be_ok
544
+ expect(last_response.body).to eq(result.to_json)
545
+ end
546
+
547
+ it "returns a list of unscheduled maintenance periods within a time window for a check an entity" do
548
+ start = Time.parse('1 Jan 2012')
549
+ finish = Time.parse('6 Jan 2012')
550
+
551
+ um = double('unsched_maint')
552
+ result = [{:entity => entity_name, :check => check, :unscheduled_maintenances => um}]
553
+
554
+ expect(entity_check_presenter).to receive(:unscheduled_maintenances).with(start.to_i, finish.to_i).and_return(um)
555
+
556
+ expect(Flapjack::Gateways::JSONAPI::EntityCheckPresenter).to receive(:new).
557
+ with(entity_check).and_return(entity_check_presenter)
558
+
559
+ expect(Flapjack::Data::EntityCheck).to receive(:for_entity).
560
+ with(entity, check, :redis => redis).and_return(entity_check)
561
+
562
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
563
+ with(entity_name, :redis => redis).and_return(entity)
564
+
565
+ aget "/unscheduled_maintenances", :check => {entity_name => check},
566
+ :start_time => start.iso8601, :end_time => finish.iso8601
567
+ expect(last_response).to be_ok
568
+ expect(last_response.body).to eq(result.to_json)
569
+ end
570
+
571
+ it "returns a list of outages, for one whole entity and two checks on another entity" do
572
+ outages_1 = double('outages_1')
573
+ outages_2 = double('outages_2')
574
+ outages_3 = double('outages_3')
575
+
576
+ entity_2_name = 'entity_2'
577
+ entity_2 = double(Flapjack::Data::Entity)
578
+
579
+ result = [{:entity => entity_name, :check => check, :outages => outages_1},
580
+ {:entity => entity_2_name, :check => 'foo', :outages => outages_2},
581
+ {:entity => entity_2_name, :check => 'bar', :outages => outages_3}]
582
+
583
+ foo_check = double(Flapjack::Data::EntityCheck)
584
+ bar_check = double(Flapjack::Data::EntityCheck)
585
+
586
+ foo_check_presenter = double(Flapjack::Gateways::JSONAPI::EntityCheckPresenter)
587
+ bar_check_presenter = double(Flapjack::Gateways::JSONAPI::EntityCheckPresenter)
588
+
589
+ expect(entity_presenter).to receive(:outages).with(nil, nil).and_return(result[0])
590
+ expect(foo_check_presenter).to receive(:outages).with(nil, nil).and_return(outages_2)
591
+ expect(bar_check_presenter).to receive(:outages).with(nil, nil).and_return(outages_3)
592
+
593
+ expect(Flapjack::Gateways::JSONAPI::EntityPresenter).to receive(:new).
594
+ with(entity, :redis => redis).and_return(entity_presenter)
595
+
596
+ expect(Flapjack::Gateways::JSONAPI::EntityCheckPresenter).to receive(:new).
597
+ with(foo_check).and_return(foo_check_presenter)
598
+ expect(Flapjack::Gateways::JSONAPI::EntityCheckPresenter).to receive(:new).
599
+ with(bar_check).and_return(bar_check_presenter)
600
+
601
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
602
+ with(entity_name, :redis => redis).and_return(entity)
603
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
604
+ with(entity_2_name, :redis => redis).and_return(entity_2)
605
+
606
+ expect(Flapjack::Data::EntityCheck).to receive(:for_entity).
607
+ with(entity_2, 'foo', :redis => redis).and_return(foo_check)
608
+ expect(Flapjack::Data::EntityCheck).to receive(:for_entity).
609
+ with(entity_2, 'bar', :redis => redis).and_return(bar_check)
610
+
611
+ aget "/outages", :entity => entity_name, :check => {entity_2_name => ['foo', 'bar']}
612
+ expect(last_response).to be_ok
613
+ expect(last_response.body).to eq(result.to_json)
614
+ end
615
+
616
+ it "returns a list of outages for a check on an entity" do
617
+ outages = double('outages')
618
+ result = [{:entity => entity_name, :check => check, :outages => outages}]
619
+
620
+ expect(entity_check_presenter).to receive(:outages).with(nil, nil).and_return(outages)
621
+
622
+ expect(Flapjack::Gateways::JSONAPI::EntityCheckPresenter).to receive(:new).
623
+ with(entity_check).and_return(entity_check_presenter)
624
+
625
+ expect(Flapjack::Data::EntityCheck).to receive(:for_entity).
626
+ with(entity, check, :redis => redis).and_return(entity_check)
627
+
628
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
629
+ with(entity_name, :redis => redis).and_return(entity)
630
+
631
+ aget "/outages", :check => {entity_name => check}
632
+ expect(last_response).to be_ok
633
+ expect(last_response.body).to eq(result.to_json)
634
+ end
635
+
636
+ it "returns a list of downtimes for an entity" do
637
+ downtime = double('downtime')
638
+ result = [{:entity => entity_name, :check => check, :downtime => downtime}]
639
+
640
+ expect(entity_presenter).to receive(:downtime).with(nil, nil).and_return(result)
641
+
642
+ expect(Flapjack::Gateways::JSONAPI::EntityPresenter).to receive(:new).
643
+ with(entity, :redis => redis).and_return(entity_presenter)
644
+
645
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
646
+ with(entity_name, :redis => redis).and_return(entity)
647
+
648
+ aget "/downtime", :entity => entity_name
649
+ expect(last_response).to be_ok
650
+ expect(last_response.body).to eq(result.to_json)
651
+ end
652
+
653
+ it "returns a list of downtimes for a check on an entity" do
654
+ downtime = double('downtime')
655
+ result = [{:entity => entity_name, :check => check, :downtime => downtime}]
656
+
657
+ expect(entity_check_presenter).to receive(:downtime).with(nil, nil).and_return(downtime)
658
+
659
+ expect(Flapjack::Gateways::JSONAPI::EntityCheckPresenter).to receive(:new).
660
+ with(entity_check).and_return(entity_check_presenter)
661
+
662
+ expect(Flapjack::Data::EntityCheck).to receive(:for_entity).
663
+ with(entity, check, :redis => redis).and_return(entity_check)
664
+
665
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
666
+ with(entity_name, :redis => redis).and_return(entity)
667
+
668
+ aget "/downtime", :check => {entity_name => check}
669
+ expect(last_response).to be_ok
670
+ expect(last_response.body).to eq(result.to_json)
671
+ end
672
+
673
+ it "creates test notification events for all checks on an entity" do
674
+ expect(entity).to receive(:check_list).and_return([check, 'foo'])
675
+ expect(entity).to receive(:name).twice.and_return(entity_name)
676
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
677
+ with(entity_name, :redis => redis).and_return(entity)
678
+
679
+ expect(entity_check).to receive(:entity).and_return(entity)
680
+ expect(entity_check).to receive(:entity_name).and_return(entity_name)
681
+ expect(entity_check).to receive(:check).and_return(check)
682
+
683
+ expect(Flapjack::Data::EntityCheck).to receive(:for_entity).
684
+ with(entity, check, :redis => redis).and_return(entity_check)
685
+
686
+ entity_check_2 = double(Flapjack::Data::EntityCheck)
687
+ expect(entity_check_2).to receive(:entity).and_return(entity)
688
+ expect(entity_check_2).to receive(:entity_name).and_return(entity_name)
689
+ expect(entity_check_2).to receive(:check).and_return('foo')
690
+
691
+ expect(Flapjack::Data::EntityCheck).to receive(:for_entity).
692
+ with(entity, 'foo', :redis => redis).and_return(entity_check_2)
693
+
694
+ expect(Flapjack::Data::Event).to receive(:test_notifications).
695
+ with(entity_name, check, hash_including(:redis => redis))
696
+
697
+ expect(Flapjack::Data::Event).to receive(:test_notifications).
698
+ with(entity_name, 'foo', hash_including(:redis => redis))
699
+
700
+ apost '/test_notifications', :entity => entity_name
701
+ expect(last_response.status).to eq(204)
702
+ end
703
+
704
+ it "creates a test notification event for check on an entity" do
705
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
706
+ with(entity_name, :redis => redis).and_return(entity)
707
+ expect(entity).to receive(:name).and_return(entity_name)
708
+ expect(entity_check).to receive(:entity).and_return(entity)
709
+ expect(entity_check).to receive(:entity_name).and_return(entity_name)
710
+ expect(entity_check).to receive(:check).and_return(check)
711
+ expect(Flapjack::Data::EntityCheck).to receive(:for_entity).
712
+ with(entity, check, :redis => redis).and_return(entity_check)
713
+
714
+ expect(Flapjack::Data::Event).to receive(:test_notifications).
715
+ with(entity_name, check, hash_including(:redis => redis))
716
+
717
+ apost '/test_notifications', :check => {entity_name => check}
718
+ expect(last_response.status).to eq(204)
719
+ end
720
+
721
+ it "creates entities from a submitted list" do
722
+ entities = {'entities' =>
723
+ [
724
+ {"id" => "10001",
725
+ "name" => "clientx-app-01",
726
+ "contacts" => ["0362","0363","0364"]
727
+ },
728
+ {"id" => "10002",
729
+ "name" => "clientx-app-02",
730
+ "contacts" => ["0362"]
731
+ }
732
+ ]
733
+ }
734
+ expect(Flapjack::Data::Entity).to receive(:add).twice
735
+
736
+ apost "/entities", entities.to_json, {'CONTENT_TYPE' => 'application/json'}
737
+ expect(last_response.status).to eq(204)
738
+ end
739
+
740
+ it "does not create entities if the data is improperly formatted" do
741
+ expect(Flapjack::Data::Entity).not_to receive(:add)
742
+
743
+ apost "/entities", {'entities' => ["Hello", "there"]}.to_json,
744
+ {'CONTENT_TYPE' => 'application/json'}
745
+ expect(last_response.status).to eq(403)
746
+ end
747
+
748
+ it "does not create entities if they don't contain an id" do
749
+ entities = {'entities' =>
750
+ [
751
+ {"id" => "10001",
752
+ "name" => "clientx-app-01",
753
+ "contacts" => ["0362","0363","0364"]
754
+ },
755
+ {"name" => "clientx-app-02",
756
+ "contacts" => ["0362"]
757
+ }
758
+ ]
759
+ }
760
+ expect(Flapjack::Data::Entity).to receive(:add)
761
+
762
+ apost "/entities", entities.to_json, {'CONTENT_TYPE' => 'application/json'}
763
+ expect(last_response.status).to eq(403)
764
+ end
765
+
766
+ end
767
+
768
+ context "tags" do
769
+
770
+ it "sets a single tag on an entity and returns current tags" do
771
+ expect(entity).to receive(:add_tags).with('web')
772
+ expect(entity).to receive(:tags).and_return(['web'])
773
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
774
+ with(entity_name, :redis => redis).and_return(entity)
775
+
776
+ apost "entities/#{entity_name}/tags", :tag => 'web'
777
+ expect(last_response).to be_ok
778
+ expect(last_response.body).to eq(['web'].to_json)
779
+ end
780
+
781
+ it "does not set a single tag on an entity that's not found" do
782
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
783
+ with(entity_name, :redis => redis).and_return(nil)
784
+
785
+ apost "entities/#{entity_name}/tags", :tag => 'web'
786
+ expect(last_response.status).to eq(404)
787
+ end
788
+
789
+ it "sets multiple tags on an entity and returns current tags" do
790
+ expect(entity).to receive(:add_tags).with('web', 'app')
791
+ expect(entity).to receive(:tags).and_return(['web', 'app'])
792
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
793
+ with(entity_name, :redis => redis).and_return(entity)
794
+
795
+ # NB submitted at a lower level as tag[]=web&tag[]=app
796
+ apost "entities/#{entity_name}/tags", :tag => ['web', 'app']
797
+ expect(last_response).to be_ok
798
+ expect(last_response.body).to eq(['web', 'app'].to_json)
799
+ end
800
+
801
+ it "does not set multiple tags on an entity that's not found" do
802
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
803
+ with(entity_name, :redis => redis).and_return(nil)
804
+
805
+ apost "entities/#{entity_name}/tags", :tag => ['web', 'app']
806
+ expect(last_response.status).to eq(404)
807
+ end
808
+
809
+ it "removes a single tag from an entity" do
810
+ expect(entity).to receive(:delete_tags).with('web')
811
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
812
+ with(entity_name, :redis => redis).and_return(entity)
813
+
814
+ adelete "entities/#{entity_name}/tags", :tag => 'web'
815
+ expect(last_response.status).to eq(204)
816
+ end
817
+
818
+ it "does not remove a single tag from an entity that's not found" do
819
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
820
+ with(entity_name, :redis => redis).and_return(nil)
821
+
822
+ adelete "entities/#{entity_name}/tags", :tag => 'web'
823
+ expect(last_response.status).to eq(404)
824
+ end
825
+
826
+ it "removes multiple tags from an entity" do
827
+ expect(entity).to receive(:delete_tags).with('web', 'app')
828
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
829
+ with(entity_name, :redis => redis).and_return(entity)
830
+
831
+ adelete "entities/#{entity_name}/tags", :tag => ['web', 'app']
832
+ expect(last_response.status).to eq(204)
833
+ end
834
+
835
+ it "does not remove multiple tags from an entity that's not found" do
836
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
837
+ with(entity_name, :redis => redis).and_return(nil)
838
+
839
+ adelete "entities/#{entity_name}/tags", :tag => ['web', 'app']
840
+ expect(last_response.status).to eq(404)
841
+ end
842
+
843
+ it "gets all tags on an entity" do
844
+ expect(entity).to receive(:tags).and_return(['web', 'app'])
845
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
846
+ with(entity_name, :redis => redis).and_return(entity)
847
+
848
+ aget "entities/#{entity_name}/tags"
849
+ expect(last_response).to be_ok
850
+ expect(last_response.body).to eq(['web', 'app'].to_json)
851
+ end
852
+
853
+ it "does not get all tags on an entity that's not found" do
854
+ expect(Flapjack::Data::Entity).to receive(:find_by_name).
855
+ with(entity_name, :redis => redis).and_return(nil)
856
+
857
+ aget "entities/#{entity_name}/tags"
858
+ expect(last_response.status).to eq(404)
859
+ end
860
+
861
+ end
862
+
863
+ end