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
@@ -1,209 +1,439 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <% nav = render_erb('_nav.html.erb', binding) %>
5
- <% head = render_erb('_head.html.erb', binding) %>
6
- <% foot = render_erb('_foot.html.erb', binding) %>
7
- <% check_path_escaped = u(@entity) << '/' << u(@check) %>
8
- <% current_time = Time.now %>
9
- <title>Flapjack - Check: <%= h @entity %>:<%= h @check %></title>
10
- <%= head %>
11
- </head>
12
- <body>
13
- <div id="wrap">
14
- <div class="container">
15
- <div class="page-header">
16
- <%= nav %>
17
- <% entity_link = "/entity/" + u(@entity) %>
18
- <h2><%= h @check %> on <a href="<%= entity_link %>" title="entity summary"><%= h @entity %></a></h2>
19
- </div>
20
- <% state_qualifier = @check_enabled ? '' : "DISABLED. Last " %>
21
- <h3><%= state_qualifier %>State: <%= @check_state ? h(@check_state.upcase) : '' %></h3>
22
- <% if @current_unscheduled_maintenance %>
23
- <% ack_msg = "#{@current_unscheduled_maintenance[:summary]}" %>
24
- <% ack_msg = ack_msg.length > 0 ? ack_msg : 'no summary given' %>
25
- <h4>Acknowledged (<%= h ack_msg %>)</h4>
26
- <% start = Time.at(@current_unscheduled_maintenance[:start_time]) %>
27
- <% finish = Time.at(@current_unscheduled_maintenance[:start_time] + @current_unscheduled_maintenance[:duration]) %>
28
- <% remain = time_period_in_words( (finish - current_time).ceil ) %>
29
- <p><%= h start.to_s %> -&gt; <%= h finish.to_s %> (<%= h remain %> remaining)</p>
30
- <form action="/end_unscheduled_maintenance/<%= check_path_escaped %>" method="post">
31
- <input type="submit" value="End Unscheduled Maintenance (Unacknowledge)" class="button">
32
- </form>
33
- <% end %>
34
- <% if (['warning', 'critical', 'unknown'].include?(@check_state) and !@current_scheduled_maintenance) %>
35
- <form action="/acknowledgements/<%= check_path_escaped %>" method="post" class="form-inline">
36
- <input type="hidden" name="acknowledgement_id" value="<%= @acknowledgement_id %>">
37
- <input type="submit" value="<%= @current_unscheduled_maintenance ? 'Replace acknowledgment' : 'Acknowledge' %>" class="button">
38
- with
39
- <label>summary:</label>
40
- <input type="text" name="summary" value="">
41
- <label>duration:</label>
42
- <input type="text" name="duration" value="">
43
- e.g. "5 hours"
44
- </form>
45
- <% end %>
46
- <% if @current_scheduled_maintenance %>
47
- <% maint_msg = "#{@current_scheduled_maintenance[:summary]}" %>
48
- <% maint_msg = maint_msg.length > 0 ? maint_msg : 'no summary given' %>
49
- <h4>In <a href="#scheduled_maintenance_periods">Scheduled Maintenance</a> (<%= h maint_msg %>)</h4>
50
- <% start = Time.at(@current_scheduled_maintenance[:start_time]) %>
1
+ <% page_title "#{h(@check)} on #{h(@entity)}" %>
2
+ <%
3
+ check_path_escaped = u(@entity) << '/' << u(@check)
4
+ current_time = Time.now
5
+ %>
6
+ <div class="page-header">
7
+ <% entity_link = "/entity/" + u(@entity) %>
8
+ <h2><%= h @check %> on <a href="<%= entity_link %>" title="entity summary"><%= h @entity %></a></h2>
9
+ </div>
10
+
11
+ <div class="row">
12
+ <div class="col-md-6">
13
+ <%
14
+ state_qualifier = @check_enabled ? '' : "DISABLED. Last "
15
+ state_class = case @check_state
16
+ when 'ok'
17
+ 'success'
18
+ when 'warning'
19
+ 'warning'
20
+ when 'critical'
21
+ 'danger'
22
+ else
23
+ "info #{@check_state}"
24
+ end
25
+
26
+ %>
27
+
28
+ <div class="alert alert-<%= state_class %>">
29
+ <%= state_qualifier %>State:
30
+ <span class="alert-link"><%= @check_state ? h(@check_state.upcase) : '' %></span>
31
+ </div>
32
+ </div><!-- col-md-6 -->
33
+
34
+ <div class="col-md-6">
35
+ <%
36
+ if !@current_scheduled_maintenance and
37
+ !@current_unscheduled_maintenance and
38
+ !(['warning', 'critical', 'unknown'].include?(@check_state))
39
+ %>
40
+ <div class="alert alert-info">
41
+ <form class="form-horizontal" role="form">
42
+ <div class="form-group">
43
+ <label class="col-md-2 control-label">State</label>
44
+ <div class="col-md-10">
45
+ <p class="form-control-static">
46
+ Not in scheduled or unscheduled maintenance.
47
+ </p>
48
+ </div>
49
+ </div>
50
+
51
+ <div class="form-group">
52
+ <div class="col-md-offset-2 col-md-10">
53
+ <p class="form-control-static">
54
+ <a class='btn btn-primary' href="#scheduled_maintenance_periods">Schedule Maintenance</a>
55
+ </p>
56
+ </div>
57
+ </div>
58
+ </form>
59
+ </div>
60
+ <% end %>
61
+
62
+ <% if @current_unscheduled_maintenance %>
63
+ <div class="alert alert-warning">
64
+
65
+ <form action="/end_unscheduled_maintenance/<%= check_path_escaped %>" method="post" class="form-horizontal" role="form">
66
+
67
+ <div class="form-group">
68
+ <label class="col-md-3 control-label">State</label>
69
+ <div class="col-md-9">
70
+ <p class="form-control-static">
71
+ Acknowledged
72
+ </p>
73
+ </div>
74
+ </div>
75
+
76
+ <div class="form-group">
77
+ <label class="col-md-3 control-label">Reason</label>
78
+ <div class="col-md-9">
79
+ <p class="form-control-static">
80
+ <%
81
+ ack_msg = @current_unscheduled_maintenance[:summary]
82
+ ack_msg ||= 'No summary given'
83
+ %>
84
+ <%= h(ack_msg) %>
85
+ </p>
86
+ </div>
87
+ </div>
88
+
89
+ <div class="form-group">
90
+ <label class="col-md-3 control-label">Started</label>
91
+ <div class="col-md-9">
92
+ <p class="form-control-static">
93
+ <% start = Time.at(@current_unscheduled_maintenance[:start_time]).to_s %>
94
+ <%= h(start) %>
95
+ </p>
96
+ </div>
97
+ </div>
98
+
99
+ <div class="form-group">
100
+ <label class="col-md-3 control-label">Finishing</label>
101
+ <div class="col-md-9">
102
+ <p class="form-control-static">
103
+ <% finish = Time.at(@current_unscheduled_maintenance[:start_time] + @current_unscheduled_maintenance[:duration]) %>
104
+ <%= h(finish) %>
105
+ </p>
106
+ </div>
107
+ </div>
108
+
109
+ <div class="form-group">
110
+ <label class="col-md-3 control-label">Remaining</label>
111
+ <div class="col-md-9">
112
+ <p class="form-control-static">
113
+ <% remaining = time_period_in_words( (finish - current_time).ceil ) %>
114
+ <%= h(remaining) %>
115
+ </p>
116
+ </div>
117
+ </div>
118
+
119
+ <div class="row">
120
+ <div class="col-md-offset-3 col-md-9">
121
+ <p class="form-control-static">
122
+ <button id="end-unscheduled-maintenance" type="submit" class="btn btn-danger">End Unscheduled Maintenance (Unacknowledge)</button>
123
+ </p>
124
+ </div>
125
+ </div>
126
+
127
+ </form>
128
+ </div>
129
+ <% end %>
130
+
131
+ <% if (['warning', 'critical', 'unknown'].include?(@check_state) and !@current_scheduled_maintenance) %>
132
+ <div class="alert alert-warning">
133
+ <% action = @current_unscheduled_maintenance ? "Re-acknowledge" : "Acknowledge" %>
134
+ <h4><%= action %> alert</h4>
135
+ <form action="/acknowledgements/<%= check_path_escaped %>" method="post" class="form-horizontal">
136
+ <div class="form-group">
137
+ <div class="col-sm-12 text-left">
138
+ <label class="col-sm-3 control-label" for="summary">Summary</label>
139
+ <div class="col-sm-9">
140
+ <input type="hidden" name="acknowledgement_id" value="<%= @acknowledgement_id %>">
141
+ <input type="text" class="form-control" name="summary" value=""/>
142
+ </div>
143
+ </div>
144
+ </div>
145
+
146
+ <div class="form-group">
147
+ <div class="col-sm-12">
148
+ <label class="col-sm-3 control-label" for="duration">Duration</label>
149
+ <div class="col-sm-9">
150
+ <input class="col-sm-9 form-control" type="text" name="duration" value="2 hours"/>
151
+ <span class="help-block">
152
+ e.g. "5 hours"
153
+ </span>
154
+ </div>
155
+ </div>
156
+ </div>
157
+
158
+ <div class="form-group">
159
+ <div class="col-sm-12">
160
+ <div class="col-sm-offset-3 col-sm-9">
161
+ <button type="submit" class="btn btn-warning">
162
+ <%= @current_unscheduled_maintenance ? 'Replace acknowledgment' : 'Acknowledge' %>
163
+ </button>
164
+ </div>
165
+ </div>
166
+ </div>
167
+ </form>
168
+ </div>
169
+ <% end %>
170
+
171
+ <% if @current_scheduled_maintenance %>
172
+ <div class="alert alert-warning">
173
+ <div class="row">
174
+ <div class="col-md-3 text-right">State</div>
175
+ <div class="col-md-9">
176
+ <a href="#scheduled_maintenance_periods" class="alert-link">In Scheduled Maintenance</a>
177
+ </div>
178
+ </div>
179
+
180
+ <div class="row">
181
+ <div class="col-md-3 text-right">Reason</div>
182
+ <div class="col-md-9">
183
+ <%
184
+ maint_msg = "#{@current_scheduled_maintenance[:summary]}"
185
+ maint_msg = maint_msg.length > 0 ? maint_msg : 'No summary given'
186
+ %>
187
+ <%= h maint_msg %>
188
+ </div>
189
+ </div>
190
+
191
+ <div class="row">
192
+ <div class="col-md-3 text-right">Started</div>
193
+ <div class="col-md-9">
194
+ <% start = Time.at(@current_scheduled_maintenance[:start_time]).to_s %>
195
+ <%= h(start) %>
196
+ </div>
197
+ </div>
198
+
199
+ <div class="row">
200
+ <div class="col-md-3 text-right">Finishing</div>
201
+ <div class="col-md-9">
51
202
  <% finish = Time.at(@current_scheduled_maintenance[:start_time] + @current_scheduled_maintenance[:duration]) %>
52
- <% remain = time_period_in_words( (finish - current_time).ceil ) %>
53
- <p><%= h start.to_s %> -&gt; <%= h finish.to_s %> (<%= h remain %> remaining)</p>
54
- <% end %>
55
- <h3>Output: <%= h @check_summary %></h3>
56
- <p><%= h @check_details %></p>
57
- <table class="table table-hover table-condensed">
58
- <tr>
59
- <td>Last state change:</td>
60
- <td><%= h relative_time_ago(Time.at(@check_last_change.to_i)) %> ago</td>
61
- <td><%= h Time.at(@check_last_change.to_i).to_s %></td>
62
- <td>&nbsp;</td>
63
- </tr>
64
- <tr>
65
- <td>Last update:</td>
66
- <td><%= h relative_time_ago(Time.at(@check_last_update.to_i)) %> ago</td>
67
- <td><%= h Time.at(@check_last_update.to_i).to_s %></td>
68
- <td>&nbsp;</td>
69
- </tr>
70
- <% [:critical, :warning, :unknown, :recovery, :acknowledgement].each do |type| %>
71
- <tr>
72
- <td>Last <%= h type.to_s %> notification:</td>
73
- <td><%= @last_notifications[type] ? h(@last_notifications[type][:relative]) : 'never' %></td>
74
- <td><%= @last_notifications[type] ? h(@last_notifications[type][:time].to_s) : '&nbsp;' %></td>
75
- <td><%= @last_notifications[type] ? h(@last_notifications[type][:summary]) : '&nbsp;' %></td>
76
- </tr>
77
- <% end %>
78
- </table>
79
-
80
- <div id="currency">
81
- <% if @check_enabled %>
82
- Enabled ...
83
- <form action="/checks/<%= check_path_escaped %>" method="post" style="display:inline-block">
84
- <input type='hidden' name='_method' value='delete'>
85
- <input type='submit' value="Disable" class='button'>
203
+ <%= h(finish) %>
204
+ </div>
205
+ </div>
206
+
207
+ <div class="row">
208
+ <div class="col-md-3 text-right">Remaining</div>
209
+ <div class="col-md-9">
210
+ <% remaining = time_period_in_words( (finish - current_time).ceil ) %>
211
+ <%= h(remaining) %>
212
+ </div>
213
+ </div>
214
+ </div>
215
+ <% end %>
216
+ </div><!-- col-md-6 -->
217
+ </div><!-- row -->
218
+
219
+ <div class="row">
220
+ <div class="col-md-6">
221
+ <h3>Output: <%= h @check_summary %></h3>
222
+ <p><%= h @check_details %></p>
223
+ <table class="table table-hover table-condensed">
224
+ <tr>
225
+ <td>Last state change:</td>
226
+ <td><%= h relative_time_ago(Time.at(@check_last_change.to_i)) %> ago</td>
227
+ <td><%= h Time.at(@check_last_change.to_i).to_s %></td>
228
+ <td>&nbsp;</td>
229
+ </tr>
230
+ <tr>
231
+ <td>Last update:</td>
232
+ <td><%= h relative_time_ago(Time.at(@check_last_update.to_i)) %> ago</td>
233
+ <td><%= h Time.at(@check_last_update.to_i).to_s %></td>
234
+ <td>&nbsp;</td>
235
+ </tr>
236
+ <% [:critical, :warning, :unknown, :recovery, :acknowledgement].each do |type| %>
237
+ <tr>
238
+ <td>Last <%= h type.to_s %> notification:</td>
239
+ <td><%= @last_notifications[type] ? h(@last_notifications[type][:relative]) : 'never' %></td>
240
+ <td><%= @last_notifications[type] ? h(@last_notifications[type][:time].to_s) : '&nbsp;' %></td>
241
+ <td><%= @last_notifications[type] ? h(@last_notifications[type][:summary]) : '&nbsp;' %></td>
242
+ </tr>
243
+ <% end %>
244
+ </table>
245
+ </div><!-- col-md-6 -->
246
+
247
+ <div class="col-md-6">
248
+ <h3>Recent state changes</h3>
249
+ <% if @state_changes && !@state_changes.empty? %>
250
+ <table class="table table-hover table-condensed">
251
+ <tr>
252
+ <th>Timestamp</th>
253
+ <th>State</th>
254
+ <th>Summary</th>
255
+ </tr>
256
+ <% @state_changes.each do |state_change| %>
257
+ <tr>
258
+ <td><%= h Time.at(state_change[:timestamp]).to_s %></td>
259
+ <td><%= h state_change[:state] %></td>
260
+ <td><%= h state_change[:summary] %></td>
261
+ </tr>
262
+ <% end %>
263
+ </table>
264
+ <% else %>
265
+ <p>No state changes recorded for this check.</p>
266
+ <% end %>
267
+ </div><!-- col-md-6 -->
268
+ </div><!-- row -->
269
+
270
+ <div class="row">
271
+ <div class="col-md-12">
272
+ <a name="scheduled_maintenance_periods"></a>
273
+ <h3>Scheduled Maintenance Periods</h3>
274
+ <% if @scheduled_maintenances && !@scheduled_maintenances.empty? %>
275
+ <table class="table table-bordered table-hover table-condensed">
276
+ <tr>
277
+ <th>Start</th>
278
+ <th>End</th>
279
+ <th>Duration</th>
280
+ <th>Summary</th>
281
+ <th>Actions</th>
282
+ </tr>
283
+
284
+ <% @scheduled_maintenances.sort_by {|s| s[:start_time]}.each do |scheduled_maintenance| %>
285
+ <%
286
+ start_time = scheduled_maintenance[:start_time]
287
+ end_time = scheduled_maintenance[:end_time]
288
+ duration = scheduled_maintenance[:duration]
289
+ summary = scheduled_maintenance[:summary]
290
+ %>
291
+ <tr>
292
+ <td><%= h Time.at(start_time).to_s %></td>
293
+ <td><%= h Time.at(end_time).to_s %></td>
294
+ <td><%= h(ChronicDuration.output(duration, :keep_zero => true) || '0 secs') %></td>
295
+ <td><%= h summary %></td>
296
+ <td>
297
+ <% if end_time > current_time.to_i %>
298
+ <% label = (start_time > current_time.to_i) ? 'Delete' : 'End Now' %>
299
+ <form action="/scheduled_maintenances/<%= check_path_escaped %>" method="post">
300
+ <input type="hidden" name="_method" value="delete">
301
+ <input type="hidden" name="start_time" value="<%= start_time %>">
302
+ <button type="submit" class="btn btn-danger"><%= label %></button>
86
303
  </form>
87
304
  <% else %>
88
- Disabled
305
+ &nbsp;
89
306
  <% end %>
307
+ </td>
308
+ </tr>
309
+ </table>
310
+ </div><!-- col-md-12 -->
311
+ <% end %>
312
+ <% else %>
313
+ <p>No maintenance is scheduled</p>
314
+ <% end %>
315
+ </div><!-- row -->
90
316
 
91
- <a name="scheduled_maintenance_periods"></a>
92
- <h3>Scheduled Maintenance Periods</h3>
93
- <% if @scheduled_maintenances && !@scheduled_maintenances.empty? %>
94
- <table class="table table-bordered table-hover table-condensed">
95
- <tr>
96
- <th>Start</th>
97
- <th>End</th>
98
- <th>Duration</th>
99
- <th>Summary</th>
100
- <th>Actions</th>
101
- </tr>
102
-
103
- <% @scheduled_maintenances.sort_by {|s| s[:start_time]}.each do |scheduled_maintenance| %>
104
- <% start_time = scheduled_maintenance[:start_time]
105
- end_time = scheduled_maintenance[:end_time]
106
- duration = scheduled_maintenance[:duration]
107
- summary = scheduled_maintenance[:summary]
108
- %>
109
- <tr>
110
- <td><%= h Time.at(start_time).to_s %></td>
111
- <td><%= h Time.at(end_time).to_s %></td>
112
- <td><%= h(ChronicDuration.output(duration, :keep_zero => true) || '0 secs') %></td>
113
- <td><%= h summary %></td>
114
- <td>
115
- <% if end_time > current_time.to_i %>
116
- <% label = (start_time > current_time.to_i) ? 'Delete' : 'End Now' %>
117
- <form action="/scheduled_maintenances/<%= check_path_escaped %>" method="post">
118
- <input type="hidden" name="_method" value="delete">
119
- <input type="hidden" name="start_time" value="<%= start_time %>">
120
- <input type="submit" value="<%= label %>" class="button">
121
- </form>
122
- <% else %>
123
- &nbsp;
124
- <% end %>
125
- </td>
126
- </tr>
127
- <% end %>
317
+ <div class="row">
318
+ <div class="col-md-8">
128
319
 
129
- </table>
130
- <% else %>
131
- <p>No maintenance is scheduled</p>
132
- <% end %>
133
- <h4>Add Scheduled Maintenance</h4>
134
- <form action="/scheduled_maintenances/<%= check_path_escaped %>" method="post" class="form-horizontal">
135
- <div class="control-group">
136
- <label class="control-label" for="start_time">Start time:</label>
137
- <div class="controls">
138
- <input type="text" name="start_time" class="text" size="20" maxlength="80" value="">
139
- e.g. "today 4pm", "two hours hence", "friday 2pm", "2012-01-28 13:00"
320
+ <div class="panel panel-default">
321
+ <div class="panel-heading">
322
+ <h3 class="panel-title">Add Scheduled Maintenance</h4>
323
+ </div>
324
+ <div class="panel-body">
325
+ <form action="/scheduled_maintenances/<%= check_path_escaped %>" method="post" role="form" class="form-horizontal">
326
+
327
+ <div class="form-group">
328
+ <label class="col-sm-2 control-label" for="start_time">Start time:</label>
329
+ <div class="col-sm-9">
330
+ <input type="text" name="start_time" class="form-control" size="20" maxlength="80" value="">
331
+ <span class="help-block">
332
+ e.g. "today 4pm", "two hours hence", "friday 2pm", "2012-01-28 13:00"
333
+ </span>
334
+ </div>
335
+ </div>
336
+
337
+ <div class="form-group">
338
+ <label class="col-sm-2 control-label" for="duration">Duration:</label>
339
+ <div class="col-sm-9">
340
+ <input type="text" name="duration" class="form-control" size="20" maxlength="80" value="">
341
+ <span class="help-block">
342
+ e.g. "1 hour", "2:30:00", "three days", etc
343
+ </span>
140
344
  </div>
141
345
  </div>
142
- <div class="control-group">
143
- <label class="control-label" for="duration">Duration:</label>
144
- <div class="controls">
145
- <input type="text" name="duration" class="text" size="20" maxlength="80" value="">
146
- e.g. "1 hour", "2:30:00", "three days", etc
346
+
347
+ <div class="col-sm-9 col-md-offset-2">
348
+ <div class="alert alert-info">
349
+ Times given will be interpreted in the local timezone of
350
+ <span class="alert-link"><%= h(local_timezone) %></span>
147
351
  </div>
148
352
  </div>
149
- <div class="control-group">
150
- <label class="control-label" for="summary">Summary:</label>
151
- <div class="controls">
152
- <input type="text" name="summary" class="text" size="80" maxlength="160" value="">
353
+
354
+ <div class="form-group">
355
+ <label class="col-sm-2 control-label" for="summary">Summary:</label>
356
+ <div class="col-sm-9">
357
+ <input type="text" name="summary" class="form-control" size="80" maxlength="160" value="">
153
358
  </div>
154
359
  </div>
155
- <div class="control-group">
156
- <div class="controls">
157
- <input type="submit" value="Save" class="button">
360
+
361
+ <div class="form-group">
362
+ <div class="col-sm-2"></div>
363
+ <div class="col-sm-9">
364
+ <button type="submit" class="btn btn-success">Save</button>
158
365
  </div>
159
366
  </div>
160
- </form>
161
- <p>Times given will be interpreted in the local timezone of <%= h local_timezone %></p>
162
- <% if @state_changes && !@state_changes.empty? %>
163
- <h3>Recent state changes</h3>
164
- <table class="table table-bordered table-hover table-condensed">
165
- <tr>
166
- <th>Timestamp</th>
167
- <th>State</th>
168
- <th>Summary</th>
169
- </tr>
170
- <% @state_changes.each do |state_change| %>
171
- <tr>
172
- <td><%= h Time.at(state_change[:timestamp]).to_s %></td>
173
- <td><%= h state_change[:state] %></td>
174
- <td><%= h state_change[:summary] %></td>
175
- </tr>
176
- <% end %>
177
- </table>
178
- <% end %>
179
- <h3>Contacts</h3>
180
- <% if @contacts && !@contacts.empty? %>
181
- <table class="table table-bordered table-hover table-condensed">
182
- <tr>
183
- <th>Name</th>
184
- <th>Media</th>
185
- </tr>
186
- <% @contacts.sort_by {|c| [c.first_name, c.last_name] }.each do |contact| %>
187
- <tr>
188
- <td><a href="/contacts/<%= contact.id %>" title="contact details"><%= h contact.name %></a></td>
189
- <td>
190
- <% if contact.media && !contact.media.empty? %>
191
- <p><%= h contact.media.keys.collect(&:capitalize).join(", ") %></p>
192
- <% else %>
193
- <p>No media</p>
194
- <% end %>
195
- </td>
196
- </tr>
197
- <% end %>
198
- </table>
199
- <% else %>
200
- <p>No contacts</p>
367
+ </form><!-- form-horizontal-->
368
+
369
+ </div><!-- panel-body -->
370
+ </div><!-- panel panel-default -->
371
+ </div><!-- col-md-8 -->
372
+ </div><!-- row -->
373
+
374
+
375
+ <div class="row">
376
+ <div class="col-md-8">
377
+ <h3>Contacts</h3>
378
+ <% if @contacts && !@contacts.empty? %>
379
+ <table class="table table-bordered table-hover table-condensed">
380
+ <tr>
381
+ <th>Name</th>
382
+ <th>Media</th>
383
+ </tr>
384
+ <% @contacts.sort_by {|c| [c.first_name, c.last_name] }.each do |contact| %>
385
+ <tr>
386
+ <td><a href="/contacts/<%= contact.id %>" title="contact details"><%= h contact.name %></a></td>
387
+ <td>
388
+ <% if contact.media && !contact.media.empty? %>
389
+ <p><%= h contact.media.keys.collect(&:capitalize).join(", ") %></p>
390
+ <% else %>
391
+ <p>No media</p>
392
+ <% end %>
393
+ </td>
394
+ </tr>
201
395
  <% end %>
396
+ </table>
397
+ <% else %>
398
+ <p>There are <strong>no contacts</strong> associated with this check.</p>
399
+ <% end %>
400
+ </div><!-- col-md-8 -->
401
+ </div><!-- row -->
402
+
403
+ <div id="zone-of-surprise" class="row">
404
+ <div class="col-md-8 col-md-offset-2">
405
+ <div class="panel panel-danger">
406
+ <div class="panel-heading">
407
+ <h3 class="panel-title">
408
+ <i class="fa fa-warning"></i>
409
+ Zone of Surprise
410
+ </h3>
202
411
  </div>
203
- <div id="push"></div>
204
- </div>
205
- <div id="footer">
206
- <%= foot %>
207
- </div>
208
- </body>
209
- </html>
412
+ <div class="panel-body">
413
+ <% if @check_enabled %>
414
+ <h4>Decommission check</h4>
415
+ <form action="/checks/<%= check_path_escaped %>" method="post" style="display:inline-block" class="pull-right">
416
+ <input type='hidden' name='_method' value='delete'>
417
+ <button type='submit' class="btn btn-danger decommission-check">Decommission Check</button>
418
+ </form>
419
+ <p>
420
+ Hide the check from the Flapjack web interface.
421
+ Use this if you are no longer actively running this check.
422
+ </p>
423
+ <p>
424
+ Flapjack will automatically re-commission this check if it receives another event for it.
425
+ </p>
426
+ <% else %>
427
+ <p>
428
+ This check has been decommissioned.
429
+ </p>
430
+ <p>
431
+ Flapjack will re-commission this check if it receives another event for it.
432
+ </p>
433
+ <% end %>
434
+ </div><!-- panel-body -->
435
+ </div><!-- panel-danger -->
436
+ </div><!-- col-md-8 col-md-offset-2 -->
437
+ </div><!-- row -->
438
+
439
+