flapjack 1.6.0 → 2.0.0b1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +4 -6
- data/.gitmodules +1 -1
- data/.rspec +1 -1
- data/.ruby-version +1 -1
- data/.travis.yml +12 -13
- data/CHANGELOG.md +2 -9
- data/CONTRIBUTING.md +7 -2
- data/Gemfile +4 -13
- data/LICENCE +1 -0
- data/README.md +8 -2
- data/Rakefile +2 -2
- data/bin/flapjack +3 -12
- data/build.sh +4 -2
- data/etc/flapjack_config.toml.example +273 -0
- data/features/ack_after_sched_maint.feature +18 -21
- data/features/cli.feature +11 -71
- data/features/cli_flapjack-feed-events.feature +14 -15
- data/features/cli_flapjack-nagios-receiver.feature +12 -41
- data/features/cli_flapper.feature +12 -41
- data/features/cli_purge.feature +5 -6
- data/features/cli_receive-events.feature +6 -7
- data/features/cli_simulate-failed-check.feature +5 -6
- data/features/events.feature +206 -181
- data/features/events_check_names.feature +4 -7
- data/features/notification_rules.feature +144 -223
- data/features/notifications.feature +65 -57
- data/features/rollup.feature +45 -47
- data/features/steps/cli_steps.rb +4 -5
- data/features/steps/events_steps.rb +163 -373
- data/features/steps/notifications_steps.rb +408 -264
- data/features/steps/packaging-lintian_steps.rb +0 -4
- data/features/steps/time_travel_steps.rb +0 -26
- data/features/support/daemons.rb +6 -31
- data/features/support/env.rb +65 -74
- data/flapjack.gemspec +22 -24
- data/lib/flapjack.rb +14 -7
- data/lib/flapjack/cli/flapper.rb +74 -173
- data/lib/flapjack/cli/maintenance.rb +278 -109
- data/lib/flapjack/cli/migrate.rb +950 -0
- data/lib/flapjack/cli/purge.rb +19 -22
- data/lib/flapjack/cli/receiver.rb +150 -326
- data/lib/flapjack/cli/server.rb +8 -235
- data/lib/flapjack/cli/simulate.rb +42 -57
- data/lib/flapjack/configuration.rb +51 -37
- data/lib/flapjack/coordinator.rb +138 -129
- data/lib/flapjack/data/acknowledgement.rb +177 -0
- data/lib/flapjack/data/alert.rb +97 -158
- data/lib/flapjack/data/check.rb +611 -0
- data/lib/flapjack/data/condition.rb +70 -0
- data/lib/flapjack/data/contact.rb +226 -456
- data/lib/flapjack/data/event.rb +96 -184
- data/lib/flapjack/data/extensions/associations.rb +59 -0
- data/lib/flapjack/data/extensions/short_name.rb +25 -0
- data/lib/flapjack/data/medium.rb +428 -0
- data/lib/flapjack/data/metrics.rb +194 -0
- data/lib/flapjack/data/notification.rb +22 -281
- data/lib/flapjack/data/rule.rb +473 -0
- data/lib/flapjack/data/scheduled_maintenance.rb +244 -0
- data/lib/flapjack/data/state.rb +221 -0
- data/lib/flapjack/data/statistic.rb +112 -0
- data/lib/flapjack/data/tag.rb +277 -0
- data/lib/flapjack/data/test_notification.rb +182 -0
- data/lib/flapjack/data/unscheduled_maintenance.rb +159 -0
- data/lib/flapjack/data/validators/id_validator.rb +20 -0
- data/lib/flapjack/exceptions.rb +6 -0
- data/lib/flapjack/filters/acknowledgement.rb +23 -16
- data/lib/flapjack/filters/base.rb +0 -5
- data/lib/flapjack/filters/delays.rb +53 -43
- data/lib/flapjack/filters/ok.rb +23 -14
- data/lib/flapjack/filters/scheduled_maintenance.rb +3 -3
- data/lib/flapjack/filters/unscheduled_maintenance.rb +12 -3
- data/lib/flapjack/gateways/aws_sns.rb +65 -49
- data/lib/flapjack/gateways/aws_sns/alert.text.erb +2 -2
- data/lib/flapjack/gateways/aws_sns/alert_subject.text.erb +2 -2
- data/lib/flapjack/gateways/aws_sns/rollup_subject.text.erb +1 -1
- data/lib/flapjack/gateways/email.rb +107 -90
- data/lib/flapjack/gateways/email/alert.html.erb +19 -18
- data/lib/flapjack/gateways/email/alert.text.erb +20 -14
- data/lib/flapjack/gateways/email/alert_subject.text.erb +2 -1
- data/lib/flapjack/gateways/email/rollup.html.erb +14 -13
- data/lib/flapjack/gateways/email/rollup.text.erb +13 -10
- data/lib/flapjack/gateways/jabber.rb +679 -671
- data/lib/flapjack/gateways/jabber/alert.text.erb +9 -6
- data/lib/flapjack/gateways/jsonapi.rb +164 -350
- data/lib/flapjack/gateways/jsonapi/data/join_descriptor.rb +44 -0
- data/lib/flapjack/gateways/jsonapi/data/method_descriptor.rb +21 -0
- data/lib/flapjack/gateways/jsonapi/helpers/headers.rb +63 -0
- data/lib/flapjack/gateways/jsonapi/helpers/miscellaneous.rb +136 -0
- data/lib/flapjack/gateways/jsonapi/helpers/resources.rb +227 -0
- data/lib/flapjack/gateways/jsonapi/helpers/serialiser.rb +313 -0
- data/lib/flapjack/gateways/jsonapi/helpers/swagger_docs.rb +322 -0
- data/lib/flapjack/gateways/jsonapi/methods/association_delete.rb +115 -0
- data/lib/flapjack/gateways/jsonapi/methods/association_get.rb +288 -0
- data/lib/flapjack/gateways/jsonapi/methods/association_patch.rb +178 -0
- data/lib/flapjack/gateways/jsonapi/methods/association_post.rb +116 -0
- data/lib/flapjack/gateways/jsonapi/methods/metrics.rb +71 -0
- data/lib/flapjack/gateways/jsonapi/methods/resource_delete.rb +119 -0
- data/lib/flapjack/gateways/jsonapi/methods/resource_get.rb +186 -0
- data/lib/flapjack/gateways/jsonapi/methods/resource_patch.rb +239 -0
- data/lib/flapjack/gateways/jsonapi/methods/resource_post.rb +197 -0
- data/lib/flapjack/gateways/jsonapi/middleware/array_param_fixer.rb +27 -0
- data/lib/flapjack/gateways/jsonapi/{rack → middleware}/json_params_parser.rb +7 -6
- data/lib/flapjack/gateways/jsonapi/middleware/request_timestamp.rb +18 -0
- data/lib/flapjack/gateways/oobetet.rb +222 -170
- data/lib/flapjack/gateways/pager_duty.rb +388 -0
- data/lib/flapjack/gateways/pager_duty/alert.text.erb +13 -0
- data/lib/flapjack/gateways/slack.rb +56 -48
- data/lib/flapjack/gateways/slack/alert.text.erb +1 -1
- data/lib/flapjack/gateways/slack/rollup.text.erb +1 -1
- data/lib/flapjack/gateways/sms_aspsms.rb +155 -0
- data/lib/flapjack/gateways/sms_aspsms/alert.text.erb +7 -0
- data/lib/flapjack/gateways/sms_aspsms/rollup.text.erb +2 -0
- data/lib/flapjack/gateways/sms_messagenet.rb +77 -57
- data/lib/flapjack/gateways/sms_messagenet/alert.text.erb +3 -2
- data/lib/flapjack/gateways/sms_nexmo.rb +53 -51
- data/lib/flapjack/gateways/sms_nexmo/alert.text.erb +2 -2
- data/lib/flapjack/gateways/sms_nexmo/rollup.text.erb +1 -1
- data/lib/flapjack/gateways/sms_twilio.rb +79 -62
- data/lib/flapjack/gateways/sms_twilio/alert.text.erb +3 -2
- data/lib/flapjack/gateways/web.rb +437 -345
- data/lib/flapjack/gateways/web/middleware/request_timestamp.rb +18 -0
- data/lib/flapjack/gateways/web/public/css/bootstrap.css +3793 -4340
- data/lib/flapjack/gateways/web/public/css/bootstrap.css.map +1 -0
- data/lib/flapjack/gateways/web/public/fonts/glyphicons-halflings-regular.eot +0 -0
- data/lib/flapjack/gateways/web/public/fonts/glyphicons-halflings-regular.svg +273 -214
- data/lib/flapjack/gateways/web/public/fonts/glyphicons-halflings-regular.ttf +0 -0
- data/lib/flapjack/gateways/web/public/fonts/glyphicons-halflings-regular.woff +0 -0
- data/lib/flapjack/gateways/web/public/fonts/glyphicons-halflings-regular.woff2 +0 -0
- data/lib/flapjack/gateways/web/public/js/bootstrap.js +1637 -1607
- data/lib/flapjack/gateways/web/public/js/self_stats.js +1 -2
- data/lib/flapjack/gateways/web/views/_pagination.html.erb +19 -0
- data/lib/flapjack/gateways/web/views/check.html.erb +159 -121
- data/lib/flapjack/gateways/web/views/checks.html.erb +82 -41
- data/lib/flapjack/gateways/web/views/contact.html.erb +59 -71
- data/lib/flapjack/gateways/web/views/contacts.html.erb +32 -8
- data/lib/flapjack/gateways/web/views/index.html.erb +2 -2
- data/lib/flapjack/gateways/web/views/{layout.erb → layout.html.erb} +7 -23
- data/lib/flapjack/gateways/web/views/self_stats.html.erb +32 -33
- data/lib/flapjack/gateways/web/views/tag.html.erb +32 -0
- data/lib/flapjack/gateways/web/views/tags.html.erb +51 -0
- data/lib/flapjack/logger.rb +34 -3
- data/lib/flapjack/notifier.rb +180 -112
- data/lib/flapjack/patches.rb +8 -63
- data/lib/flapjack/pikelet.rb +185 -143
- data/lib/flapjack/processor.rb +323 -191
- data/lib/flapjack/record_queue.rb +33 -0
- data/lib/flapjack/redis_proxy.rb +66 -0
- data/lib/flapjack/utility.rb +21 -15
- data/lib/flapjack/version.rb +2 -1
- data/libexec/httpbroker.go +218 -14
- data/libexec/oneoff.go +13 -10
- data/spec/lib/flapjack/configuration_spec.rb +286 -0
- data/spec/lib/flapjack/coordinator_spec.rb +103 -157
- data/spec/lib/flapjack/data/check_spec.rb +175 -0
- data/spec/lib/flapjack/data/contact_spec.rb +26 -349
- data/spec/lib/flapjack/data/event_spec.rb +76 -291
- data/spec/lib/flapjack/data/medium_spec.rb +19 -0
- data/spec/lib/flapjack/data/rule_spec.rb +43 -0
- data/spec/lib/flapjack/data/scheduled_maintenance_spec.rb +976 -0
- data/spec/lib/flapjack/data/unscheduled_maintenance_spec.rb +34 -0
- data/spec/lib/flapjack/gateways/aws_sns_spec.rb +111 -60
- data/spec/lib/flapjack/gateways/email_spec.rb +194 -161
- data/spec/lib/flapjack/gateways/jabber_spec.rb +961 -162
- data/spec/lib/flapjack/gateways/jsonapi/methods/check_links_spec.rb +155 -0
- data/spec/lib/flapjack/gateways/jsonapi/methods/checks_spec.rb +426 -0
- data/spec/lib/flapjack/gateways/jsonapi/methods/contact_links_spec.rb +217 -0
- data/spec/lib/flapjack/gateways/jsonapi/methods/contacts_spec.rb +425 -0
- data/spec/lib/flapjack/gateways/jsonapi/methods/events_spec.rb +271 -0
- data/spec/lib/flapjack/gateways/jsonapi/methods/media_spec.rb +257 -0
- data/spec/lib/flapjack/gateways/jsonapi/methods/medium_links_spec.rb +163 -0
- data/spec/lib/flapjack/gateways/jsonapi/methods/metrics_spec.rb +8 -0
- data/spec/lib/flapjack/gateways/jsonapi/methods/rule_links_spec.rb +212 -0
- data/spec/lib/flapjack/gateways/jsonapi/methods/rules_spec.rb +289 -0
- data/spec/lib/flapjack/gateways/jsonapi/methods/scheduled_maintenance_links_spec.rb +49 -0
- data/spec/lib/flapjack/gateways/jsonapi/methods/scheduled_maintenances_spec.rb +242 -0
- data/spec/lib/flapjack/gateways/jsonapi/methods/tag_links_spec.rb +274 -0
- data/spec/lib/flapjack/gateways/jsonapi/methods/tags_spec.rb +302 -0
- data/spec/lib/flapjack/gateways/jsonapi/methods/unscheduled_maintenance_links_spec.rb +49 -0
- data/spec/lib/flapjack/gateways/jsonapi/methods/unscheduled_maintenances_spec.rb +339 -0
- data/spec/lib/flapjack/gateways/jsonapi_spec.rb +1 -1
- data/spec/lib/flapjack/gateways/oobetet_spec.rb +151 -79
- data/spec/lib/flapjack/gateways/pager_duty_spec.rb +353 -0
- data/spec/lib/flapjack/gateways/slack_spec.rb +53 -53
- data/spec/lib/flapjack/gateways/sms_aspsms_spec.rb +106 -0
- data/spec/lib/flapjack/gateways/sms_messagenet_spec.rb +111 -54
- data/spec/lib/flapjack/gateways/sms_nexmo_spec.rb +50 -51
- data/spec/lib/flapjack/gateways/sms_twilio_spec.rb +108 -48
- data/spec/lib/flapjack/gateways/web_spec.rb +144 -216
- data/spec/lib/flapjack/notifier_spec.rb +132 -1
- data/spec/lib/flapjack/pikelet_spec.rb +111 -50
- data/spec/lib/flapjack/processor_spec.rb +210 -40
- data/spec/lib/flapjack/redis_proxy_spec.rb +45 -0
- data/spec/lib/flapjack/utility_spec.rb +11 -15
- data/spec/service_consumers/fixture_data.rb +547 -0
- data/spec/service_consumers/pact_helper.rb +21 -32
- data/spec/service_consumers/pacts/flapjack-diner_v2.0.json +4652 -0
- data/spec/service_consumers/provider_states_for_flapjack-diner.rb +279 -322
- data/spec/service_consumers/provider_support.rb +8 -0
- data/spec/spec_helper.rb +34 -44
- data/spec/support/erb_view_helper.rb +1 -1
- data/spec/support/factories.rb +58 -0
- data/spec/support/jsonapi_helper.rb +15 -26
- data/spec/support/mock_logger.rb +43 -0
- data/spec/support/xmpp_comparable.rb +24 -0
- data/src/flapjack/transport_test.go +30 -1
- data/tasks/dump_keys.rake +82 -0
- data/tasks/events.rake +7 -7
- data/tasks/support/flapjack_config_benchmark.toml +28 -0
- data/tasks/support/flapjack_config_benchmark.yaml +0 -2
- metadata +175 -222
- data/Guardfile +0 -14
- data/etc/flapjack_config.yaml.example +0 -477
- data/features/cli_flapjack-populator.feature +0 -90
- data/features/support/silent_system.rb +0 -4
- data/lib/flapjack/cli/import.rb +0 -108
- data/lib/flapjack/data/entity.rb +0 -652
- data/lib/flapjack/data/entity_check.rb +0 -1044
- data/lib/flapjack/data/message.rb +0 -56
- data/lib/flapjack/data/migration.rb +0 -234
- data/lib/flapjack/data/notification_rule.rb +0 -425
- data/lib/flapjack/data/semaphore.rb +0 -44
- data/lib/flapjack/data/tagged.rb +0 -48
- data/lib/flapjack/gateways/jsonapi/check_methods.rb +0 -206
- data/lib/flapjack/gateways/jsonapi/check_presenter.rb +0 -221
- data/lib/flapjack/gateways/jsonapi/contact_methods.rb +0 -186
- data/lib/flapjack/gateways/jsonapi/entity_methods.rb +0 -223
- data/lib/flapjack/gateways/jsonapi/medium_methods.rb +0 -185
- data/lib/flapjack/gateways/jsonapi/metrics_methods.rb +0 -132
- data/lib/flapjack/gateways/jsonapi/notification_rule_methods.rb +0 -141
- data/lib/flapjack/gateways/jsonapi/pagerduty_credential_methods.rb +0 -139
- data/lib/flapjack/gateways/jsonapi/report_methods.rb +0 -146
- data/lib/flapjack/gateways/pagerduty.rb +0 -318
- data/lib/flapjack/gateways/pagerduty/alert.text.erb +0 -10
- data/lib/flapjack/gateways/web/public/css/select2-bootstrap.css +0 -87
- data/lib/flapjack/gateways/web/public/css/select2.css +0 -615
- data/lib/flapjack/gateways/web/public/css/tablesort.css +0 -67
- data/lib/flapjack/gateways/web/public/img/select2-spinner.gif +0 -0
- data/lib/flapjack/gateways/web/public/img/select2.png +0 -0
- data/lib/flapjack/gateways/web/public/img/select2x2.png +0 -0
- data/lib/flapjack/gateways/web/public/js/backbone.js +0 -1581
- data/lib/flapjack/gateways/web/public/js/backbone.jsonapi.js +0 -322
- data/lib/flapjack/gateways/web/public/js/flapjack.js +0 -82
- data/lib/flapjack/gateways/web/public/js/jquery.tablesorter.js +0 -1640
- data/lib/flapjack/gateways/web/public/js/jquery.tablesorter.widgets.js +0 -1390
- data/lib/flapjack/gateways/web/public/js/modules/contact.js +0 -520
- data/lib/flapjack/gateways/web/public/js/modules/entity.js +0 -28
- data/lib/flapjack/gateways/web/public/js/modules/medium.js +0 -40
- data/lib/flapjack/gateways/web/public/js/select2.js +0 -3397
- data/lib/flapjack/gateways/web/public/js/tablesort.js +0 -44
- data/lib/flapjack/gateways/web/public/js/underscore.js +0 -1276
- data/lib/flapjack/gateways/web/views/edit_contacts.html.erb +0 -173
- data/lib/flapjack/gateways/web/views/entities.html.erb +0 -30
- data/lib/flapjack/gateways/web/views/entity.html.erb +0 -51
- data/lib/flapjack/rack_logger.rb +0 -47
- data/lib/flapjack/redis_pool.rb +0 -42
- data/spec/lib/flapjack/data/entity_check_spec.rb +0 -1418
- data/spec/lib/flapjack/data/entity_spec.rb +0 -872
- data/spec/lib/flapjack/data/message_spec.rb +0 -30
- data/spec/lib/flapjack/data/migration_spec.rb +0 -104
- data/spec/lib/flapjack/data/notification_rule_spec.rb +0 -232
- data/spec/lib/flapjack/data/notification_spec.rb +0 -53
- data/spec/lib/flapjack/data/semaphore_spec.rb +0 -24
- data/spec/lib/flapjack/filters/acknowledgement_spec.rb +0 -6
- data/spec/lib/flapjack/filters/delays_spec.rb +0 -6
- data/spec/lib/flapjack/filters/ok_spec.rb +0 -6
- data/spec/lib/flapjack/filters/scheduled_maintenance_spec.rb +0 -6
- data/spec/lib/flapjack/filters/unscheduled_maintenance_spec.rb +0 -6
- data/spec/lib/flapjack/gateways/jsonapi/check_methods_spec.rb +0 -315
- data/spec/lib/flapjack/gateways/jsonapi/check_presenter_spec.rb +0 -223
- data/spec/lib/flapjack/gateways/jsonapi/contact_methods_spec.rb +0 -131
- data/spec/lib/flapjack/gateways/jsonapi/entity_methods_spec.rb +0 -389
- data/spec/lib/flapjack/gateways/jsonapi/medium_methods_spec.rb +0 -231
- data/spec/lib/flapjack/gateways/jsonapi/notification_rule_methods_spec.rb +0 -169
- data/spec/lib/flapjack/gateways/jsonapi/pagerduty_credential_methods_spec.rb +0 -114
- data/spec/lib/flapjack/gateways/jsonapi/report_methods_spec.rb +0 -590
- data/spec/lib/flapjack/gateways/pagerduty_spec.rb +0 -249
- data/spec/lib/flapjack/gateways/web/views/check.html.erb_spec.rb +0 -21
- data/spec/lib/flapjack/gateways/web/views/contact.html.erb_spec.rb +0 -24
- data/spec/lib/flapjack/gateways/web/views/index.html.erb_spec.rb +0 -16
- data/spec/lib/flapjack/redis_pool_spec.rb +0 -29
- data/spec/service_consumers/pacts/flapjack-diner_v1.0.json +0 -4702
- data/tasks/entities.rake +0 -151
- data/tasks/profile.rake +0 -282
- data/tmp/acknowledge.rb +0 -13
- data/tmp/create_config_yaml.rb +0 -16
- data/tmp/create_event_ok.rb +0 -30
- data/tmp/create_event_unknown.rb +0 -30
- data/tmp/create_events_failure.rb +0 -34
- data/tmp/create_events_ok.rb +0 -32
- data/tmp/create_events_ok_fail_ack_ok.rb +0 -53
- data/tmp/create_events_ok_failure.rb +0 -41
- data/tmp/create_events_ok_failure_ack.rb +0 -53
- data/tmp/dummy_contacts.json +0 -43
- data/tmp/dummy_entities.json +0 -37
- data/tmp/generate_nagios_test_hosts.rb +0 -16
- data/tmp/notification_rules.rb +0 -73
- data/tmp/parse_config_yaml.rb +0 -7
- data/tmp/redis_find_spurious_unknown_states.rb +0 -52
- data/tmp/test_json_post.rb +0 -19
- data/tmp/test_notification_rules_api.rb +0 -171
data/lib/flapjack/cli/flapper.rb
CHANGED
@@ -1,29 +1,11 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require 'eventmachine'
|
4
3
|
require 'socket'
|
5
|
-
require 'dante'
|
6
4
|
|
7
5
|
module Flapjack
|
8
6
|
module CLI
|
9
7
|
class Flapper
|
10
8
|
|
11
|
-
def self.local_ip
|
12
|
-
# turn off reverse DNS resolution temporarily
|
13
|
-
orig, Socket.do_not_reverse_lookup = Socket.do_not_reverse_lookup, true
|
14
|
-
|
15
|
-
begin
|
16
|
-
UDPSocket.open do |s|
|
17
|
-
s.connect '64.233.187.99', 1
|
18
|
-
s.addr.last
|
19
|
-
end
|
20
|
-
rescue Errno::ENETUNREACH => e
|
21
|
-
'127.0.0.1'
|
22
|
-
end
|
23
|
-
ensure
|
24
|
-
Socket.do_not_reverse_lookup = orig
|
25
|
-
end
|
26
|
-
|
27
9
|
def initialize(global_options, options)
|
28
10
|
@global_options = global_options
|
29
11
|
@options = options
|
@@ -38,79 +20,16 @@ module Flapjack
|
|
38
20
|
@config_env = @config.all
|
39
21
|
|
40
22
|
if @config_env.nil? || @config_env.empty?
|
41
|
-
exit_now! "No config data
|
42
|
-
end
|
43
|
-
|
44
|
-
@pidfile = case
|
45
|
-
when !@options[:pidfile].nil?
|
46
|
-
@options[:pidfile]
|
47
|
-
when !@config_env['pid_dir'].nil?
|
48
|
-
File.join(@config_env['pid_dir'], 'flapper.pid')
|
49
|
-
else
|
50
|
-
"/var/run/flapjack/flapper.pid"
|
51
|
-
end
|
52
|
-
|
53
|
-
@logfile = case
|
54
|
-
when !@options[:logfile].nil?
|
55
|
-
@options[:logfile]
|
56
|
-
when !@config_env['log_dir'].nil?
|
57
|
-
File.join(@config_env['log_dir'], 'flapper.log')
|
58
|
-
else
|
59
|
-
"/var/run/flapjack/flapper.log"
|
23
|
+
exit_now! "No config data found in '#{global_options[:config]}'"
|
60
24
|
end
|
61
25
|
end
|
62
26
|
|
63
27
|
def start
|
64
|
-
|
65
|
-
|
66
|
-
else
|
67
|
-
print "flapper starting..."
|
68
|
-
main_umask = nil
|
69
|
-
if @options[:daemonize]
|
70
|
-
main_umask = File.umask
|
71
|
-
else
|
72
|
-
print "\n"
|
73
|
-
end
|
74
|
-
runner.execute(:daemonize => @options[:daemonize]) do
|
75
|
-
File.umask(main_umask) if @options[:daemonize]
|
76
|
-
main(@options['bind-ip'] || Flapjack::CLI::Flapper.local_ip, @options['bind-port'].to_i, @options[:frequency])
|
77
|
-
end
|
78
|
-
puts " done."
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
def stop
|
83
|
-
pid = get_pid
|
84
|
-
if runner.daemon_running?
|
85
|
-
print "flapper stopping..."
|
86
|
-
runner.execute(:kill => true)
|
87
|
-
puts " done."
|
88
|
-
else
|
89
|
-
puts "flapper is not running."
|
90
|
-
end
|
91
|
-
exit_now! unless wait_pid_gone(pid)
|
92
|
-
end
|
93
|
-
|
94
|
-
def restart
|
95
|
-
print "flapper restarting..."
|
96
|
-
main_umask = File.umask
|
97
|
-
runner.execute(:daemonize => true, :restart => true) do
|
98
|
-
File.umask(main_umask)
|
99
|
-
main(@options['bind-ip'], @options['bind-port'].to_i, @options[:frequency])
|
100
|
-
end
|
28
|
+
puts "flapper starting..."
|
29
|
+
main(@options['bind-ip'] || Flapjack::CLI::Flapper.local_ip, @options['bind-port'].to_i, @options[:frequency])
|
101
30
|
puts " done."
|
102
31
|
end
|
103
32
|
|
104
|
-
def status
|
105
|
-
if runner.daemon_running?
|
106
|
-
pid = get_pid
|
107
|
-
uptime = Time.now - File.stat(@pidfile).ctime
|
108
|
-
puts "flapper is running: pid #{pid}, uptime #{uptime}"
|
109
|
-
else
|
110
|
-
exit_now! "flapper is not running"
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
33
|
private
|
115
34
|
|
116
35
|
module Receiver
|
@@ -120,36 +39,77 @@ module Flapjack
|
|
120
39
|
end
|
121
40
|
end
|
122
41
|
|
123
|
-
def
|
124
|
-
|
42
|
+
def self.local_ip
|
43
|
+
# turn off reverse DNS resolution temporarily
|
44
|
+
orig, Socket.do_not_reverse_lookup = Socket.do_not_reverse_lookup, true
|
125
45
|
|
126
|
-
|
127
|
-
|
128
|
-
|
46
|
+
begin
|
47
|
+
UDPSocket.open do |s|
|
48
|
+
s.connect '64.233.187.99', 1
|
49
|
+
s.addr.last
|
50
|
+
end
|
51
|
+
rescue Errno::ENETUNREACH => e
|
52
|
+
'127.0.0.1'
|
53
|
+
end
|
54
|
+
ensure
|
55
|
+
Socket.do_not_reverse_lookup = orig
|
129
56
|
end
|
130
57
|
|
131
58
|
def main(bind_ip, bind_port, frequency)
|
132
|
-
raise "bind_port must be an integer" unless bind_port.is_a?(Integer)
|
59
|
+
raise "bind_port must be an integer" unless bind_port.is_a?(Integer)
|
133
60
|
start_every = frequency
|
134
|
-
stop_after
|
135
|
-
|
136
|
-
EM.run do
|
61
|
+
stop_after = frequency.to_f / 2
|
137
62
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
63
|
+
begin
|
64
|
+
loop do
|
65
|
+
begin
|
66
|
+
fds = []
|
67
|
+
Timeout::timeout(stop_after) do
|
68
|
+
puts "#{Time.now}: starting server"
|
69
|
+
|
70
|
+
acceptor = TCPServer.open(bind_ip, bind_port)
|
71
|
+
fds = [acceptor]
|
72
|
+
|
73
|
+
while true
|
74
|
+
if ios = select(fds, [], [], 10)
|
75
|
+
reads = ios.first
|
76
|
+
reads.each do |client|
|
77
|
+
if client == acceptor
|
78
|
+
puts 'Someone connected to server. Adding socket to fds.'
|
79
|
+
client, sockaddr = acceptor.accept
|
80
|
+
fds << client
|
81
|
+
elsif client.eof?
|
82
|
+
puts "Client disconnected"
|
83
|
+
fds.delete(client)
|
84
|
+
client.close
|
85
|
+
else
|
86
|
+
# Perform a blocking-read until new-line is encountered.
|
87
|
+
# We know the client is writing, so as long as it adheres to the
|
88
|
+
# new-line protocol, we shouldn't block for very long.
|
89
|
+
data = client.gets("\n")
|
90
|
+
if data =~ /quit/i
|
91
|
+
fds.delete(client)
|
92
|
+
client.close
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
rescue Timeout::Error
|
149
100
|
puts "#{Time.now}: stopping server"
|
150
|
-
|
101
|
+
ensure
|
102
|
+
# should trigger even for an Interrupt
|
103
|
+
puts "Cleaning up"
|
104
|
+
fds.each {|c| c.close}
|
151
105
|
end
|
106
|
+
|
107
|
+
sleep_for = start_every - stop_after
|
108
|
+
puts "sleeping for #{sleep_for}"
|
109
|
+
sleep(sleep_for)
|
152
110
|
end
|
111
|
+
rescue Interrupt
|
112
|
+
puts "interrupted"
|
153
113
|
end
|
154
114
|
end
|
155
115
|
|
@@ -182,83 +142,24 @@ module Flapjack
|
|
182
142
|
pid = nil
|
183
143
|
end
|
184
144
|
|
185
|
-
|
186
145
|
end
|
187
146
|
end
|
188
147
|
end
|
189
148
|
|
190
|
-
|
191
|
-
desc 'Artificial service that oscillates up and down, for use in http://flapjack.io/docs/1.0/usage/oobetet'
|
149
|
+
desc 'Artificial service that oscillates up and down, for use in http://flapjack.io/docs/2.0/usage/oobetet'
|
192
150
|
command :flapper do |flapper|
|
193
151
|
|
194
|
-
flapper.desc '
|
195
|
-
flapper.command :start do |start|
|
196
|
-
|
197
|
-
start.switch [:d, 'daemonize'], :desc => 'Daemonize',
|
198
|
-
:default_value => true
|
199
|
-
|
200
|
-
start.flag [:p, 'pidfile'], :desc => 'PATH of the pidfile to write to'
|
201
|
-
|
202
|
-
start.flag [:l, 'logfile'], :desc => 'PATH of the logfile to write to'
|
203
|
-
|
204
|
-
start.flag [:b, 'bind-ip'], :desc => 'Override ADDRESS (IPv4 or IPv6) for flapper to bind to'
|
205
|
-
|
206
|
-
start.flag [:P, 'bind-port'], :desc => 'PORT for flapper to bind to (default: 12345)',
|
207
|
-
:default_value => '12345'
|
208
|
-
|
209
|
-
start.flag [:f, 'frequency'], :desc => 'oscillate with a frequency of SECONDS [120]',
|
210
|
-
:default_value => '120.0'
|
152
|
+
flapper.flag [:b, 'bind-ip'], :desc => 'Override ADDRESS (IPv4 or IPv6) for flapper to bind to'
|
211
153
|
|
212
|
-
|
213
|
-
|
214
|
-
cli_flapper.start
|
215
|
-
end
|
216
|
-
end
|
217
|
-
|
218
|
-
flapper.desc 'stop flapper'
|
219
|
-
flapper.command :stop do |stop|
|
154
|
+
flapper.flag [:P, 'bind-port'], :desc => 'PORT for flapper to bind to (default: 12345)',
|
155
|
+
:default_value => '12345'
|
220
156
|
|
221
|
-
|
157
|
+
flapper.flag [:f, 'frequency'], :desc => 'oscillate with a frequency of SECONDS [120]',
|
158
|
+
:default_value => '120.0'
|
222
159
|
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
cli_flapper = Flapjack::CLI::Flapper.new(global_options, options)
|
227
|
-
cli_flapper.stop
|
228
|
-
end
|
160
|
+
flapper.action do |global_options, options, args|
|
161
|
+
cli_flapper = Flapjack::CLI::Flapper.new(global_options, options)
|
162
|
+
cli_flapper.start
|
229
163
|
end
|
230
164
|
|
231
|
-
flapper.desc 'restart flapper'
|
232
|
-
flapper.command :restart do |restart|
|
233
|
-
|
234
|
-
restart.flag [:p, 'pidfile'], :desc => 'PATH of the pidfile to write to'
|
235
|
-
|
236
|
-
restart.flag [:l, 'logfile'], :desc => 'PATH of the logfile to write to'
|
237
|
-
|
238
|
-
restart.flag [:b, 'bind-ip'], :desc => 'Override ADDRESS (IPv4 or IPv6) for flapper to bind to'
|
239
|
-
|
240
|
-
restart.flag [:P, 'bind-port'], :desc => 'PORT for flapper to bind to (default: 12345)',
|
241
|
-
:default_value => 12345
|
242
|
-
|
243
|
-
restart.flag [:f, 'frequency'], :desc => 'oscillate with a frequency of SECONDS [120]',
|
244
|
-
:default_value => 120.0
|
245
|
-
|
246
|
-
restart.action do |global_options, options, args|
|
247
|
-
cli_flapper = Flapjack::CLI::Flapper.new(global_options, options)
|
248
|
-
cli_flapper.restart
|
249
|
-
end
|
250
|
-
end
|
251
|
-
|
252
|
-
flapper.desc 'flapper status'
|
253
|
-
flapper.command :status do |status|
|
254
|
-
|
255
|
-
status.flag [:p, 'pidfile'], :desc => 'PATH of the pidfile to write to'
|
256
|
-
|
257
|
-
status.flag [:l, 'logfile'], :desc => 'PATH of the logfile to write to'
|
258
|
-
|
259
|
-
status.action do |global_options, options, args|
|
260
|
-
cli_flapper = Flapjack::CLI::Flapper.new(global_options, options)
|
261
|
-
cli_flapper.status
|
262
|
-
end
|
263
|
-
end
|
264
165
|
end
|
@@ -1,12 +1,10 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require 'redis'
|
4
|
-
require 'hiredis'
|
5
4
|
|
6
5
|
require 'flapjack/configuration'
|
7
6
|
require 'flapjack/data/event'
|
8
|
-
require 'flapjack/data/
|
9
|
-
require 'flapjack/data/migration'
|
7
|
+
require 'flapjack/data/check'
|
10
8
|
require 'terminal-table'
|
11
9
|
|
12
10
|
module Flapjack
|
@@ -27,92 +25,310 @@ module Flapjack
|
|
27
25
|
@config_env = config.all
|
28
26
|
|
29
27
|
if @config_env.nil? || @config_env.empty?
|
30
|
-
exit_now! "No config data
|
28
|
+
exit_now! "No config data found in '#{global_options[:config]}'"
|
31
29
|
end
|
32
30
|
|
33
|
-
|
34
|
-
|
31
|
+
Flapjack::RedisProxy.config = config.for_redis
|
32
|
+
Zermelo.redis = Flapjack.redis
|
35
33
|
end
|
36
34
|
|
37
|
-
def show
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
35
|
+
def show(base_time = Time.now)
|
36
|
+
state = @options[:state]
|
37
|
+
|
38
|
+
checks = if @options[:check]
|
39
|
+
Flapjack::Data::Check.intersect(:name => Regexp.new(@options[:check])).all
|
40
|
+
else
|
41
|
+
Flapjack::Data::Check.all
|
42
|
+
end
|
43
|
+
|
44
|
+
start_time_begin, start_time_end = self.class.extract_time_range(
|
45
|
+
@options[:started], base_time)
|
46
|
+
|
47
|
+
start_time_begin = start_time_begin.to_i unless start_time_begin.nil?
|
48
|
+
start_time_end = start_time_end.to_i unless start_time_end.nil?
|
49
|
+
|
50
|
+
finish_time_begin, finish_time_end = self.class.extract_time_range(
|
51
|
+
@options[:finishing], base_time)
|
52
|
+
|
53
|
+
finish_time_begin = finish_time_begin.to_i unless finish_time_begin.nil?
|
54
|
+
finish_time_end = finish_time_end.to_i unless finish_time_end.nil?
|
55
|
+
|
56
|
+
duration_range = @options[:duration] ? self.class.extract_duration_range(
|
57
|
+
@options[:duration]) : nil
|
58
|
+
|
59
|
+
start_time_range = Zermelo::Filters::IndexRange.new(start_time_begin,
|
60
|
+
start_time_end, :by_score => true)
|
61
|
+
finish_time_range = Zermelo::Filters::IndexRange.new(finish_time_begin,
|
62
|
+
finish_time_end, :by_score => true)
|
63
|
+
|
64
|
+
maintenances = case @options[:type].downcase
|
65
|
+
when 'scheduled'
|
66
|
+
checks.inject([]) do |memo, check|
|
67
|
+
|
68
|
+
maints = check.scheduled_maintenances.
|
69
|
+
intersect(:start_time => start_time_range, :end_time => finish_time_range).all
|
70
|
+
|
71
|
+
if !maints.empty?
|
72
|
+
filtered = duration_range.nil? ? maints :
|
73
|
+
self.class.filter_duration(maints, duration_range)
|
74
|
+
memo += filtered
|
75
|
+
end
|
76
|
+
|
77
|
+
memo
|
78
|
+
end
|
79
|
+
when 'unscheduled'
|
80
|
+
checks.inject([]) do |memo, check|
|
81
|
+
|
82
|
+
maints = check.unscheduled_maintenances.
|
83
|
+
intersect(:start_time => start_time_range, :end_time => finish_time_range).all
|
84
|
+
|
85
|
+
if !maints.empty?
|
86
|
+
filtered = duration_range.nil? ? maints :
|
87
|
+
self.class.filter_duration(maints, duration_range)
|
88
|
+
memo += filtered
|
89
|
+
end
|
90
|
+
|
91
|
+
memo
|
92
|
+
end
|
42
93
|
end
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
# Convert the unix timestamps of the start and end time back into readable times
|
49
|
-
m.each { |k, v| row.push(k.to_s.end_with?('time') ? Time.at(v) : v) }
|
50
|
-
rows.push(row)
|
94
|
+
|
95
|
+
rows = maintenances.collect do |maint|
|
96
|
+
[maint.check.name,
|
97
|
+
Time.at(maint.start_time), maint.end_time - maint.start_time,
|
98
|
+
maint.summary, Time.at(maint.end_time)]
|
51
99
|
end
|
52
|
-
puts Terminal::Table.new :headings => ['
|
100
|
+
puts Terminal::Table.new :headings => ['Check',
|
101
|
+
'Start', 'Duration (s)', 'Reason', 'End'], :rows => rows
|
102
|
+
puts "Found #{rows.count} maintenances"
|
53
103
|
maintenances
|
54
104
|
end
|
55
105
|
|
56
106
|
def delete
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
107
|
+
base_time = Time.now
|
108
|
+
|
109
|
+
maintenances = show(base_time)
|
110
|
+
|
111
|
+
unless @options[:apply]
|
112
|
+
exit_now!('The following maintenances would be deleted. Run this ' +
|
113
|
+
'command again with --apply true to remove them.')
|
114
|
+
end
|
115
|
+
|
116
|
+
errors = {}
|
117
|
+
maintenances.each do |maint|
|
118
|
+
check = maint.check
|
119
|
+
identifier = "#{check.name}:#{check.start}"
|
120
|
+
if maint.end_time < base_time
|
121
|
+
errors[identifier] = "Maintenance can't be deleted as it finished in the past"
|
122
|
+
else
|
123
|
+
success = case @options[:type]
|
124
|
+
when 'scheduled'
|
125
|
+
check.end_scheduled_maintenance(maint, base_time)
|
126
|
+
when 'unscheduled'
|
127
|
+
check.clear_unscheduled_maintenance(base_time)
|
128
|
+
end
|
129
|
+
errors[identifier] = "The following maintenance failed to delete: #{entry}" unless success
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
if errors.empty?
|
134
|
+
puts "The maintenances above have been deleted"
|
135
|
+
else
|
136
|
+
puts(errors.map {|k, v| "#{k}: #{v}" }.join("\n"))
|
137
|
+
exit_now!('Failed to delete maintenances')
|
138
|
+
end
|
62
139
|
end
|
63
140
|
|
64
141
|
def create
|
65
|
-
errors =
|
66
|
-
|
67
|
-
|
142
|
+
errors = {}
|
143
|
+
|
144
|
+
check_names = @options[:check].is_a?(String) ? @options[:check].split(',') : @options[:check]
|
145
|
+
|
146
|
+
started = Chronic.parse(@options[:started])
|
147
|
+
raise "Failed to parse start time #{@options[:started]}" if started.nil?
|
148
|
+
|
149
|
+
duration = ChronicDuration.parse(@options[:duration])
|
150
|
+
raise "Failed to parse duration #{@options[:duration]}" if duration.nil?
|
151
|
+
|
152
|
+
check_names.each do |check_name|
|
153
|
+
check = Flapjack::Data::Check.intersect(:name => check_names).all.first
|
154
|
+
|
155
|
+
if check.nil?
|
156
|
+
# Create the check if it doesn't exist, so we can schedule maintenance against it
|
157
|
+
check = Flapjack::Data::Check.new(:name => check_name)
|
158
|
+
check.save
|
159
|
+
end
|
160
|
+
|
161
|
+
success = case @options[:type]
|
162
|
+
when 'scheduled'
|
163
|
+
|
164
|
+
sched_maint = Flapjack::Data::ScheduledMaintenance.new(:start_time => started,
|
165
|
+
:end_time => started + duration, :summary => @options[:reason])
|
166
|
+
sched_maint.save
|
167
|
+
|
168
|
+
check.scheduled_maintenances << sched_maint
|
169
|
+
when 'unscheduled'
|
170
|
+
unsched_maint = Flapjack::Data::UnscheduledMaintenance.new(:start_time => started,
|
171
|
+
:end_time => started + duration, :summary => @options[:reason])
|
172
|
+
unsched_maint.save
|
173
|
+
|
174
|
+
check.set_unscheduled_maintenance(unsched_maint)
|
175
|
+
end
|
176
|
+
identifier = "#{check_name}:#{started}"
|
177
|
+
errors[identifier] = "The following check failed to create: #{identifier}" unless success
|
178
|
+
end
|
179
|
+
|
180
|
+
if errors.empty?
|
181
|
+
puts "The maintenances specified have been created"
|
182
|
+
else
|
183
|
+
puts(errors.map {|k, v| "#{k}: #{v}" }.join("\n"))
|
184
|
+
exit_now!('Failed to create maintenances')
|
185
|
+
end
|
68
186
|
end
|
69
187
|
|
70
188
|
private
|
71
189
|
|
72
|
-
def
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
190
|
+
def self.filter_duration(maints, duration_range)
|
191
|
+
maints.select do |maint|
|
192
|
+
dur = maint.duration
|
193
|
+
lower = duration_range.first
|
194
|
+
upper = duration_range.last
|
195
|
+
|
196
|
+
(lower.nil? && upper.nil?) || ((lower.nil? || (dur >= lower)) &&
|
197
|
+
(upper.nil? || (dur < upper)))
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
def self.extract_duration_range(duration_in_words)
|
202
|
+
return nil if duration_in_words.nil?
|
203
|
+
|
204
|
+
dur_words = duration_in_words.downcase
|
205
|
+
|
206
|
+
case dur_words
|
207
|
+
when /^(?:equal to|less than|more than)/
|
208
|
+
cdur_words = dur_words.gsub(/^(equal to|less than|more than) /, '')
|
209
|
+
parsed_dur = ChronicDuration.parse(cdur_words)
|
210
|
+
case dur_words
|
211
|
+
when /^equal to/
|
212
|
+
[parsed_dur, parsed_dur + 1]
|
213
|
+
when /^less than/
|
214
|
+
[nil, parsed_dur]
|
215
|
+
when /^more than/
|
216
|
+
[parsed_dur, nil]
|
217
|
+
end
|
218
|
+
when /^between/
|
219
|
+
first, second = dur_words.match(/between (.*) and (.*)/).captures
|
220
|
+
|
221
|
+
# If the first time only contains only a single word, the unit (and past/future) is
|
222
|
+
# most likely directly after the first word of the the second time
|
223
|
+
# eg between 3 and 4 hours
|
224
|
+
suffix = second.match(/\w (.*)/) ? second.match(/\w (.*)/).captures.first : ''
|
225
|
+
first = "#{first} #{suffix}" unless / /.match(first)
|
226
|
+
|
227
|
+
[ChronicDuration.parse(first), ChronicDuration.parse(second)].sort
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
# returns two timestamps, the start and end of the calculated time range. if
|
232
|
+
# either one is nil that indicates that the range is unbounded at that end.
|
233
|
+
# Start is inclusive of that second, end is exclusive.
|
234
|
+
def self.extract_time_range(time_period_in_words, base_time)
|
235
|
+
return nil if time_period_in_words.nil?
|
236
|
+
|
237
|
+
time_words = time_period_in_words.downcase
|
238
|
+
|
239
|
+
# Chronic can't parse timestamps for strings starting with before, after or in some cases, on.
|
240
|
+
# Strip the before or after for the conversion only, but use it for the comparison later
|
241
|
+
ctime_words = time_words.gsub(/^(on|before|after) /, '')
|
242
|
+
|
243
|
+
case time_words
|
244
|
+
# Between 3 and 4 hours ago translates to more than 3 hours ago, less than 4 hours ago
|
245
|
+
when /^between/
|
246
|
+
first, second = time_words.match(/between (.*) and (.*)/).captures
|
247
|
+
|
248
|
+
# If the first time only contains only a single word, the unit (and past/future) is
|
249
|
+
# most likely directly after the first word of the the second time
|
250
|
+
# eg between 3 and 4 hours ago
|
251
|
+
suffix = second.match(/\w (.*)/) ? second.match(/\w (.*)/).captures.first : ''
|
252
|
+
first = "#{first} #{suffix}" unless / /.match(first)
|
253
|
+
|
254
|
+
[Chronic.parse(first, :now => base_time),
|
255
|
+
Chronic.parse(second, :now => base_time)].sort
|
256
|
+
when /^on/
|
257
|
+
# e.g. On 1/1/15. We use Chronic to work out the minimum and maximum timestamp.
|
258
|
+
parsed = Chronic.parse(ctime, :guess => false, :now => base_time)
|
259
|
+
[parsed.first, parsed.last]
|
260
|
+
when /^(less than|more than|before|after)/
|
261
|
+
input_time = Chronic.parse(ctime_words, :keep_zero => true, :now => base_time) ||
|
262
|
+
Chronic.parse("#{ctime_words} from now", :keep_zero => true, :now => base_time)
|
263
|
+
case time_words
|
264
|
+
when /^less than .+ ago$/, /^more than/, /^after/
|
265
|
+
[input_time, nil]
|
266
|
+
when /^less than/, /^more than .+ ago$/, /^before/
|
267
|
+
[nil, input_time]
|
268
|
+
end
|
269
|
+
end
|
79
270
|
end
|
80
271
|
|
81
272
|
end
|
82
273
|
end
|
83
274
|
end
|
84
275
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
276
|
+
def common_arguments(cmd_type, gli_cmd)
|
277
|
+
|
278
|
+
if [:show, :delete, :create].include?(cmd_type)
|
279
|
+
gli_cmd.flag ['check', :c],
|
280
|
+
:desc => 'The check for the maintenance window to occur on. This can ' +
|
281
|
+
'be a string, or a Ruby regex of the form \'http*\' or \'[[:lower:]]\'',
|
282
|
+
:required => :create.eql?(cmd_type)
|
283
|
+
|
284
|
+
gli_cmd.flag ['reason', :r],
|
285
|
+
:desc => 'The reason for the maintenance window to occur. This can ' +
|
286
|
+
'be a string, or a Ruby regex of the form \'Downtime for *\' or ' +
|
287
|
+
'\'[[:lower:]]\''
|
288
|
+
|
289
|
+
gli_cmd.flag ['start', 'started', 'starting', :s],
|
290
|
+
:desc => 'The start time for the maintenance window. This should ' +
|
291
|
+
'be prefixed with "more than", "less than", "on", "before", ' +
|
292
|
+
'or "after", or of the form "between T1 and T2"',
|
293
|
+
:must_match => /^(?:more than|less than|on|before|after|between)\s+.+$/
|
294
|
+
|
295
|
+
gli_cmd.flag ['duration', :d],
|
296
|
+
:desc => 'The total duration of the maintenance window. This should ' +
|
297
|
+
'be prefixed with "more than", "less than", or "equal to", ' +
|
298
|
+
'or of the form "between M and N hours". This should be an ' +
|
299
|
+
' interval',
|
300
|
+
:must_match => /^(?:more than|less than|equal to|between)\s+.+$/
|
301
|
+
end
|
94
302
|
|
95
|
-
|
96
|
-
|
303
|
+
if [:show, :delete].include?(cmd_type)
|
304
|
+
gli_cmd.flag ['finish', 'finished', 'finishing', 'remain', 'remained', 'remaining', 'end', :f],
|
305
|
+
:desc => 'The finishing time for the maintenance window. This should ' +
|
306
|
+
'prefixed with "more than", "less than", "on", "before", or ' +
|
307
|
+
'"after", or of the form "between T1 and T2"' ,
|
308
|
+
:must_match => /^(?:more than|less than|on|before|after|between)\s+.+$/
|
97
309
|
|
98
|
-
|
99
|
-
:desc => 'The
|
310
|
+
gli_cmd.flag ['state', :st],
|
311
|
+
:desc => 'The state that the check is currently in',
|
312
|
+
:must_match => %w(ok warning critical unknown)
|
313
|
+
end
|
100
314
|
|
101
|
-
|
102
|
-
|
315
|
+
if [:show, :delete, :create].include?(cmd_type)
|
316
|
+
gli_cmd.flag ['type', :t],
|
317
|
+
:desc => 'The type of maintenance scheduled',
|
318
|
+
:required => true,
|
319
|
+
:default_value => 'scheduled',
|
320
|
+
:must_match => %w(scheduled unscheduled)
|
321
|
+
end
|
103
322
|
|
104
|
-
|
105
|
-
:desc => 'The total duration of the maintenance window, eg \'equal to 5 hours\'. This should be prefixed with \'more than\', \'less than\', \'before, \'after\' or \'equal to\', or or of the form \'between 3 and 4 hours\'. This should be an interval'
|
323
|
+
end
|
106
324
|
|
107
|
-
|
108
|
-
|
325
|
+
desc 'Show, create and delete maintenance windows'
|
326
|
+
command :maintenance do |maintenance|
|
109
327
|
|
110
|
-
|
111
|
-
|
328
|
+
maintenance.desc 'Show maintenance windows according to criteria (default: all ongoing maintenance)'
|
329
|
+
maintenance.command :show do |show|
|
112
330
|
|
113
|
-
show
|
114
|
-
:desc => 'The type of maintenance scheduled',
|
115
|
-
:default_value => 'scheduled'
|
331
|
+
common_arguments(:show, show)
|
116
332
|
|
117
333
|
show.action do |global_options,options,args|
|
118
334
|
maintenance = Flapjack::CLI::Maintenance.new(global_options, options)
|
@@ -123,34 +339,11 @@ command :maintenance do |maintenance|
|
|
123
339
|
maintenance.desc 'Delete maintenance windows according to criteria (default: all ongoing maintenance)'
|
124
340
|
maintenance.command :delete do |delete|
|
125
341
|
|
126
|
-
delete.flag ['apply'
|
342
|
+
delete.flag [:a, 'apply'],
|
127
343
|
:desc => 'Whether this deletion should occur',
|
128
344
|
:default_value => false
|
129
345
|
|
130
|
-
delete
|
131
|
-
:desc => 'The entity for the maintenance window to occur on. This can be a string, or a ruby regex of the form \'db*\' or \'[[:lower:]]\''
|
132
|
-
|
133
|
-
delete.flag ['check', :c],
|
134
|
-
:desc => 'The check for the maintenance window to occur on. This can be a string, or a ruby regex of the form \'http*\' or \'[[:lower:]]\''
|
135
|
-
|
136
|
-
delete.flag ['reason', :r],
|
137
|
-
:desc => 'The reason for the maintenance window to occur. This can be a string, or a ruby regex of the form \'Downtime for *\' or \'[[:lower:]]\''
|
138
|
-
|
139
|
-
delete.flag ['start', 'started', 'starting', :s],
|
140
|
-
:desc => 'The start time for the maintenance window, eg \'before 10am\'. This should be prefixed with \'more than\', \'less than\', \'on\', \'before\', or \'after\', or of the form \'between times and time\''
|
141
|
-
|
142
|
-
delete.flag ['duration', :d],
|
143
|
-
:desc => 'The total duration of the maintenance window, eg \'equal to 5 hours\'. This should be prefixed with \'more than\', \'less than\', \'before, \'after\' or \'equal to\', or or of the form \'between 3 and 4 hours\'. This should be an interval'
|
144
|
-
|
145
|
-
delete.flag ['finish', 'finished', 'finishing', 'remain', 'remained', 'remaining', 'end', :f],
|
146
|
-
:desc => 'The finishing time for the maintenance window, eg \'more than 1 year from now\'. This should be prefixed with \'more than\', \'less than\', \'on\', \'before\', or \'after\', or of the form \'between time and time\''
|
147
|
-
|
148
|
-
delete.flag ['state', :st],
|
149
|
-
:desc => 'The state that the check is currently in'
|
150
|
-
|
151
|
-
delete.flag ['type', :t],
|
152
|
-
:desc => 'The type of maintenance scheduled',
|
153
|
-
:default_value => 'scheduled'
|
346
|
+
common_arguments(:delete, delete)
|
154
347
|
|
155
348
|
delete.action do |global_options,options,args|
|
156
349
|
maintenance = Flapjack::CLI::Maintenance.new(global_options, options)
|
@@ -161,31 +354,7 @@ command :maintenance do |maintenance|
|
|
161
354
|
maintenance.desc 'Create a maintenance window'
|
162
355
|
maintenance.command :create do |create|
|
163
356
|
|
164
|
-
create
|
165
|
-
:desc => 'The entity for the maintenance window to occur on. This can be a comma separated list',
|
166
|
-
:type => Array,
|
167
|
-
:required => true
|
168
|
-
|
169
|
-
create.flag ['check', :c],
|
170
|
-
:desc => 'The check for the maintenance window to occur on. This can be a comma separated list',
|
171
|
-
:type => Array,
|
172
|
-
:required => true
|
173
|
-
|
174
|
-
create.flag ['reason', :r],
|
175
|
-
:desc => 'The reason for the maintenance window to occur',
|
176
|
-
:required => true
|
177
|
-
|
178
|
-
create.flag ['start', 'started', 'starting', :s],
|
179
|
-
:desc => 'The start time for the maintenance window, eg \'now\' or \'in 3 hours\'',
|
180
|
-
:required => true
|
181
|
-
|
182
|
-
create.flag ['duration', :d],
|
183
|
-
:desc => 'The total duration of the maintenance window, eg \'30 minutes\'. This should be an interval',
|
184
|
-
:required => true
|
185
|
-
|
186
|
-
create.flag ['type', :t],
|
187
|
-
:desc => 'The type of maintenance scheduled (\'scheduled\')',
|
188
|
-
:default_value => 'scheduled'
|
357
|
+
common_arguments(:create, create)
|
189
358
|
|
190
359
|
create.action do |global_options,options,args|
|
191
360
|
maintenance = Flapjack::CLI::Maintenance.new(global_options, options)
|