wavefront-cli 2.1.4 → 2.1.5
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.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/.rubocop.yml +1147 -0
- data/README.md +1 -1
- data/lib/wavefront-cli/alert.rb +2 -3
- data/lib/wavefront-cli/base.rb +27 -20
- data/lib/wavefront-cli/commands/alert.rb +0 -1
- data/lib/wavefront-cli/commands/event.rb +3 -2
- data/lib/wavefront-cli/commands/query.rb +0 -1
- data/lib/wavefront-cli/commands/window.rb +0 -1
- data/lib/wavefront-cli/commands/write.rb +0 -1
- data/lib/wavefront-cli/constants.rb +0 -1
- data/lib/wavefront-cli/controller.rb +5 -5
- data/lib/wavefront-cli/display/alert.rb +3 -5
- data/lib/wavefront-cli/display/dashboard.rb +3 -3
- data/lib/wavefront-cli/display/webhook.rb +2 -2
- data/lib/wavefront-cli/display/write.rb +1 -1
- data/lib/wavefront-cli/event.rb +67 -53
- data/lib/wavefront-cli/integration.rb +0 -1
- data/lib/wavefront-cli/maintenancewindow.rb +36 -20
- data/lib/wavefront-cli/opt_handler.rb +1 -1
- data/lib/wavefront-cli/query.rb +44 -27
- data/lib/wavefront-cli/string.rb +13 -25
- data/lib/wavefront-cli/version.rb +1 -1
- data/lib/wavefront-cli/write.rb +2 -7
- data/spec/.rubocop.yml +16 -0
- data/spec/spec_helper.rb +55 -55
- data/spec/wavefront-cli/alert_spec.rb +8 -8
- data/spec/wavefront-cli/base_spec.rb +1 -1
- data/spec/wavefront-cli/cloudintegration_spec.rb +6 -6
- data/spec/wavefront-cli/commands/base_spec.rb +0 -2
- data/spec/wavefront-cli/controller_spec.rb +5 -5
- data/spec/wavefront-cli/dashboard_spec.rb +8 -8
- data/spec/wavefront-cli/display/base_spec.rb +22 -23
- data/spec/wavefront-cli/display/printer/long_spec.rb +30 -28
- data/spec/wavefront-cli/event_spec.rb +8 -8
- data/spec/wavefront-cli/externallink_spec.rb +6 -6
- data/spec/wavefront-cli/maintanancewindow_spec.rb +8 -9
- data/spec/wavefront-cli/opt_handler_spec.rb +4 -5
- data/spec/wavefront-cli/proxy_spec.rb +8 -8
- data/spec/wavefront-cli/savedsearch_spec.rb +6 -6
- data/spec/wavefront-cli/source_spec.rb +8 -8
- data/spec/wavefront-cli/string_spec.rb +2 -3
- data/spec/wavefront-cli/webhook_spec.rb +8 -8
- data/wavefront-cli.gemspec +3 -3
- metadata +20 -5
    
        data/README.md
    CHANGED
    
    | @@ -1,5 +1,5 @@ | |
| 1 1 | 
             
            # Wavefront CLI
         | 
| 2 | 
            -
            [](https://travis-ci.org/snltd/wavefront-cli) [](https://travis-ci.org/snltd/wavefront-cli) [](https://codeclimate.com/github/snltd/wavefront-cli/maintainability) [](https://gemnasium.com/github.com/snltd/wavefront-cli) [](https://badge.fury.io/rb/wavefront-cli) 
         | 
| 3 3 |  | 
| 4 4 |  | 
| 5 5 | 
             
            This package provides a command-line interface to
         | 
    
        data/lib/wavefront-cli/alert.rb
    CHANGED
    
    | @@ -41,10 +41,9 @@ module WavefrontCli | |
| 41 41 | 
             
                #
         | 
| 42 42 | 
             
                # @param raw [Hash] Ruby hash of imported data
         | 
| 43 43 | 
             
                #
         | 
| 44 | 
            -
                # rubocop:disable Metrics/MethodLength
         | 
| 45 44 | 
             
                def import_to_create(raw)
         | 
| 46 | 
            -
                  ret = %w | 
| 47 | 
            -
                           additionalInformation | 
| 45 | 
            +
                  ret = %w[name condition minutes target severity displayExpression
         | 
| 46 | 
            +
                           additionalInformation].each_with_object({}) do |k, aggr|
         | 
| 48 47 | 
             
                    aggr[k.to_sym] = raw[k]
         | 
| 49 48 | 
             
                  end
         | 
| 50 49 |  | 
    
        data/lib/wavefront-cli/base.rb
    CHANGED
    
    | @@ -29,10 +29,7 @@ module WavefrontCli | |
| 29 29 | 
             
                  @klass_word = sdk_class.split('::').last.downcase
         | 
| 30 30 | 
             
                  validate_input
         | 
| 31 31 |  | 
| 32 | 
            -
                  if options | 
| 33 | 
            -
                    puts options
         | 
| 34 | 
            -
                    exit 0
         | 
| 35 | 
            -
                  end
         | 
| 32 | 
            +
                  options_and_exit if options[:help]
         | 
| 36 33 |  | 
| 37 34 | 
             
                  require File.join('wavefront-sdk', @klass_word)
         | 
| 38 35 | 
             
                  @klass = Object.const_get(sdk_class)
         | 
| @@ -40,6 +37,11 @@ module WavefrontCli | |
| 40 37 | 
             
                  send(:post_initialize, options) if respond_to?(:post_initialize)
         | 
| 41 38 | 
             
                end
         | 
| 42 39 |  | 
| 40 | 
            +
                def options_and_exit
         | 
| 41 | 
            +
                  puts options
         | 
| 42 | 
            +
                  exit 0
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
             | 
| 43 45 | 
             
                def run
         | 
| 44 46 | 
             
                  @wf = klass.new(mk_creds, mk_opts)
         | 
| 45 47 | 
             
                  dispatch
         | 
| @@ -65,8 +67,8 @@ module WavefrontCli | |
| 65 67 | 
             
                  send(:extra_validation) if respond_to?(:extra_validation)
         | 
| 66 68 | 
             
                end
         | 
| 67 69 |  | 
| 68 | 
            -
                def validate_tags
         | 
| 69 | 
            -
                  Array(options[ | 
| 70 | 
            +
                def validate_tags(key = :'<tag>')
         | 
| 71 | 
            +
                  Array(options[key]).each do |t|
         | 
| 70 72 | 
             
                    begin
         | 
| 71 73 | 
             
                      send(:wf_tag?, t)
         | 
| 72 74 | 
             
                    rescue Wavefront::Exception::InvalidTag
         | 
| @@ -89,8 +91,7 @@ module WavefrontCli | |
| 89 91 | 
             
                def mk_creds
         | 
| 90 92 | 
             
                  { token:    options[:token],
         | 
| 91 93 | 
             
                    endpoint: options[:endpoint],
         | 
| 92 | 
            -
                    agent:    "wavefront-cli-#{WF_CLI_VERSION}"
         | 
| 93 | 
            -
                  }
         | 
| 94 | 
            +
                    agent:    "wavefront-cli-#{WF_CLI_VERSION}" }
         | 
| 94 95 | 
             
                end
         | 
| 95 96 |  | 
| 96 97 | 
             
                # Make a common wavefront-sdk options object from standard CLI
         | 
| @@ -101,8 +102,7 @@ module WavefrontCli | |
| 101 102 | 
             
                def mk_opts
         | 
| 102 103 | 
             
                  { debug:   options[:debug],
         | 
| 103 104 | 
             
                    verbose: options[:verbose],
         | 
| 104 | 
            -
                    noop:    options[:noop] | 
| 105 | 
            -
                  }
         | 
| 105 | 
            +
                    noop:    options[:noop] }
         | 
| 106 106 | 
             
                end
         | 
| 107 107 |  | 
| 108 108 | 
             
                # To allow a user to default to different output formats for
         | 
| @@ -143,7 +143,7 @@ module WavefrontCli | |
| 143 143 | 
             
                  #
         | 
| 144 144 | 
             
                  m_list.sort_by(&:length).reverse.each do |m|
         | 
| 145 145 | 
             
                    if m.reject { |w| options[w.to_sym] }.empty?
         | 
| 146 | 
            -
                      method = (%w | 
| 146 | 
            +
                      method = (%w[do] + m).join('_')
         | 
| 147 147 | 
             
                      return display(public_send(method), method)
         | 
| 148 148 | 
             
                    end
         | 
| 149 149 | 
             
                  end
         | 
| @@ -171,7 +171,7 @@ module WavefrontCli | |
| 171 171 | 
             
                def display(data, method)
         | 
| 172 172 | 
             
                  exit if options[:noop]
         | 
| 173 173 |  | 
| 174 | 
            -
                  [ | 
| 174 | 
            +
                  %i[status response].each do |b|
         | 
| 175 175 | 
             
                    abort "no #{b} block in API response" unless data.respond_to?(b)
         | 
| 176 176 | 
             
                  end
         | 
| 177 177 |  | 
| @@ -274,7 +274,7 @@ module WavefrontCli | |
| 274 274 |  | 
| 275 275 | 
             
                  begin
         | 
| 276 276 | 
             
                    prepped = import_to_create(raw)
         | 
| 277 | 
            -
                  rescue => e
         | 
| 277 | 
            +
                  rescue StandardError => e
         | 
| 278 278 | 
             
                    puts e if options[:debug]
         | 
| 279 279 | 
             
                    raise 'could not parse input.'
         | 
| 280 280 | 
             
                  end
         | 
| @@ -299,16 +299,23 @@ module WavefrontCli | |
| 299 299 | 
             
                  require 'wavefront-sdk/search'
         | 
| 300 300 | 
             
                  wfs = Wavefront::Search.new(mk_creds, mk_opts)
         | 
| 301 301 |  | 
| 302 | 
            -
                  query = options[:'<condition>'] | 
| 303 | 
            -
             | 
| 302 | 
            +
                  query = conds_to_query(options[:'<condition>'])
         | 
| 303 | 
            +
             | 
| 304 | 
            +
                  wfs.search(klass_word, query, limit: options[:limit],
         | 
| 305 | 
            +
                                                offset: options[:offset] ||
         | 
| 306 | 
            +
                                                        options[:cursor])
         | 
| 307 | 
            +
                end
         | 
| 308 | 
            +
             | 
| 309 | 
            +
                # Turn a list of search conditions into an API query
         | 
| 310 | 
            +
                #
         | 
| 311 | 
            +
                def conds_to_query(conds)
         | 
| 312 | 
            +
                  conds.each_with_object([]) do |cond, aggr|
         | 
| 313 | 
            +
                    key, value = cond.split(/\W/, 2)
         | 
| 304 314 | 
             
                    q = { key: key, value: value }
         | 
| 305 | 
            -
                    q[:matchingMethod] = 'EXACT' if  | 
| 306 | 
            -
                    q[:matchingMethod] = 'STARTSWITH' if  | 
| 315 | 
            +
                    q[:matchingMethod] = 'EXACT' if cond.start_with?("#{key}=")
         | 
| 316 | 
            +
                    q[:matchingMethod] = 'STARTSWITH' if cond.start_with?("#{key}^")
         | 
| 307 317 | 
             
                    aggr.<< q
         | 
| 308 318 | 
             
                  end
         | 
| 309 | 
            -
             | 
| 310 | 
            -
                  wfs.search(klass_word, query, { limit: options[:limit],
         | 
| 311 | 
            -
                                                  offset: options[:offset] || options[:cursor]})
         | 
| 312 319 | 
             
                end
         | 
| 313 320 |  | 
| 314 321 | 
             
                def do_tags
         | 
| @@ -12,13 +12,13 @@ class WavefrontCommandEvent < WavefrontCommandBase | |
| 12 12 | 
             
                  '[-o cursor]',
         | 
| 13 13 | 
             
                 "describe #{CMN} [-f format] <id>",
         | 
| 14 14 | 
             
                 "create #{CMN} [-d description] [-s time] [-i | -e time] " \
         | 
| 15 | 
            -
                 '[-S severity] [-T type] [-H host...] [-N] <event>',
         | 
| 15 | 
            +
                 '[-S severity] [-T type] [-H host...] [-g tag...] [-N] <event>',
         | 
| 16 16 | 
             
                 "close #{CMN} [<id>]",
         | 
| 17 17 | 
             
                 "delete #{CMN} <id>",
         | 
| 18 18 | 
             
                 "update #{CMN} <key=value> <id>",
         | 
| 19 19 | 
             
                 "search #{CMN} [-f format] [-o offset] [-L limit] [-l] <condition>...",
         | 
| 20 20 | 
             
                 "wrap #{CMN} [-C command] [-d description] [-S severity] [-T type] " \
         | 
| 21 | 
            -
                 '[-H host...] <event>',
         | 
| 21 | 
            +
                 '[-H host...] [-g tag...] <event>',
         | 
| 22 22 | 
             
                 tag_commands,
         | 
| 23 23 | 
             
                 'show [-D]']
         | 
| 24 24 | 
             
              end
         | 
| @@ -37,6 +37,7 @@ class WavefrontCommandEvent < WavefrontCommandBase | |
| 37 37 | 
             
                 '-H, --host=STRING         source to which event applies',
         | 
| 38 38 | 
             
                 '-N, --nostate             do not create a local file recording ' \
         | 
| 39 39 | 
             
                 'the event',
         | 
| 40 | 
            +
                 '-g, --evtag=TAG           event tag',
         | 
| 40 41 | 
             
                 '-C, --command=COMMAND     command to run',
         | 
| 41 42 | 
             
                 '-f, --format=STRING       output format']
         | 
| 42 43 | 
             
              end
         | 
| @@ -12,7 +12,6 @@ class WavefrontCommandQuery < WavefrontCommandBase | |
| 12 12 | 
             
                       '[-ivO] [-S mode] [-N name] [-p points] <query>',
         | 
| 13 13 | 
             
                 "raw #{CMN} [-H host] [-s time] [-e time] [-f format] <metric>"]
         | 
| 14 14 | 
             
              end
         | 
| 15 | 
            -
             | 
| 16 15 | 
             
              def _options
         | 
| 17 16 | 
             
                [common_options,
         | 
| 18 17 | 
             
                 '-g, --granularity=STRING  query granularity (d, h, m, or s)',
         | 
| @@ -1,9 +1,9 @@ | |
| 1 1 | 
             
            # For development against a local checkout of the SDK, uncomment
         | 
| 2 2 | 
             
            # this block
         | 
| 3 3 | 
             
            #
         | 
| 4 | 
            -
             | 
| 5 | 
            -
             | 
| 6 | 
            -
             | 
| 4 | 
            +
            dir = Pathname.new(__FILE__).dirname.realpath.parent.parent.parent
         | 
| 5 | 
            +
            $LOAD_PATH.<< dir + 'lib'
         | 
| 6 | 
            +
            $LOAD_PATH.<< dir + 'wavefront-sdk' + 'lib'
         | 
| 7 7 |  | 
| 8 8 | 
             
            require 'pathname'
         | 
| 9 9 | 
             
            require 'pp'
         | 
| @@ -82,14 +82,14 @@ class WavefrontCliController | |
| 82 82 | 
             
                Object.const_get('WavefrontCli').const_get(cmds[cmd].sdk_class).new(opts)
         | 
| 83 83 | 
             
              rescue WavefrontCli::Exception::UnhandledCommand
         | 
| 84 84 | 
             
                abort 'Fatal error. Unsupported command.'
         | 
| 85 | 
            -
              rescue => e
         | 
| 85 | 
            +
              rescue StandardError => e
         | 
| 86 86 | 
             
                p e
         | 
| 87 87 | 
             
              end
         | 
| 88 88 |  | 
| 89 89 | 
             
              def run_command(hook)
         | 
| 90 90 | 
             
                hook.validate_opts
         | 
| 91 91 | 
             
                hook.run
         | 
| 92 | 
            -
              rescue => e
         | 
| 92 | 
            +
              rescue StandardError => e
         | 
| 93 93 | 
             
                $stderr.puts "general error: #{e}"
         | 
| 94 94 | 
             
                $stderr.puts "re-run with '-D' for stack trace." unless opts[:debug]
         | 
| 95 95 | 
             
                $stderr.puts "Backtrace:\n\t#{e.backtrace.join("\n\t")}" if opts[:debug]
         | 
| @@ -6,9 +6,9 @@ module WavefrontDisplay | |
| 6 6 | 
             
              #
         | 
| 7 7 | 
             
              class Alert < Base
         | 
| 8 8 | 
             
                def do_list
         | 
| 9 | 
            -
                  long_output [ | 
| 10 | 
            -
             | 
| 11 | 
            -
             | 
| 9 | 
            +
                  long_output %i[id minutes target status tags hostsUsed
         | 
| 10 | 
            +
                                 condition displayExpression severity
         | 
| 11 | 
            +
                                 additionalInformation]
         | 
| 12 12 | 
             
                end
         | 
| 13 13 |  | 
| 14 14 | 
             
                def do_list_brief
         | 
| @@ -37,8 +37,6 @@ module WavefrontDisplay | |
| 37 37 | 
             
                def do_unsnooze
         | 
| 38 38 | 
             
                  puts "Unsnoozed alert '#{options[:'<id>']}'."
         | 
| 39 39 | 
             
                end
         | 
| 40 | 
            -
             | 
| 41 | 
            -
                # rubocop:disable Metrics/AbcSize
         | 
| 42 40 | 
             
                def do_summary
         | 
| 43 41 | 
             
                  kw = data.keys.map(&:size).max + 2
         | 
| 44 42 | 
             
                  data.delete_if { |_k, v| v.zero? } unless options[:all]
         | 
| @@ -6,9 +6,9 @@ module WavefrontDisplay | |
| 6 6 | 
             
              #
         | 
| 7 7 | 
             
              class Dashboard < Base
         | 
| 8 8 | 
             
                def do_list
         | 
| 9 | 
            -
                  long_output [ | 
| 10 | 
            -
             | 
| 11 | 
            -
             | 
| 9 | 
            +
                  long_output %i[id minutes target status tags hostsUsed
         | 
| 10 | 
            +
                                 condition displayExpression severity
         | 
| 11 | 
            +
                                 additionalInformation]
         | 
| 12 12 | 
             
                end
         | 
| 13 13 |  | 
| 14 14 | 
             
                def do_describe
         | 
| @@ -6,8 +6,8 @@ module WavefrontDisplay | |
| 6 6 | 
             
              #
         | 
| 7 7 | 
             
              class Webhook < Base
         | 
| 8 8 | 
             
                def do_list
         | 
| 9 | 
            -
                  long_output([ | 
| 10 | 
            -
             | 
| 9 | 
            +
                  long_output(%i[id title description createdEpochMillis
         | 
| 10 | 
            +
                                 updatedEpochMillis updaterId creatorId])
         | 
| 11 11 | 
             
                end
         | 
| 12 12 |  | 
| 13 13 | 
             
                def do_list_brief
         | 
    
        data/lib/wavefront-cli/event.rb
    CHANGED
    
    | @@ -4,7 +4,6 @@ require_relative './base' | |
| 4 4 | 
             
            require 'open3'
         | 
| 5 5 |  | 
| 6 6 | 
             
            EVENT_STATE_DIR = Pathname.new('/var/tmp/wavefront')
         | 
| 7 | 
            -
             | 
| 8 7 | 
             
            module WavefrontCli
         | 
| 9 8 | 
             
              #
         | 
| 10 9 | 
             
              # CLI coverage for the v2 'event' API.
         | 
| @@ -14,19 +13,14 @@ module WavefrontCli | |
| 14 13 | 
             
                include Wavefront::Mixins
         | 
| 15 14 |  | 
| 16 15 | 
             
                def post_initialize(_options)
         | 
| 17 | 
            -
                   | 
| 18 | 
            -
                    @state_dir = EVENT_STATE_DIR + Etc.getlogin
         | 
| 19 | 
            -
                  rescue
         | 
| 20 | 
            -
                    @state_dir = EVENT_STATE_DIR + 'notty'
         | 
| 21 | 
            -
                  end
         | 
| 22 | 
            -
             | 
| 16 | 
            +
                  @state_dir = EVENT_STATE_DIR + (Etc.getlogin || 'notty')
         | 
| 23 17 | 
             
                  create_state_dir
         | 
| 24 18 | 
             
                end
         | 
| 25 19 |  | 
| 26 20 | 
             
                def do_list
         | 
| 27 | 
            -
                  options[:start]  | 
| 28 | 
            -
             | 
| 29 | 
            -
             | 
| 21 | 
            +
                  wf.list(options[:start]  || Time.now - 600,
         | 
| 22 | 
            +
                          options[:end]    || Time.now,
         | 
| 23 | 
            +
                          options[:limit]  || 100,
         | 
| 30 24 | 
             
                          options[:cursor] || nil)
         | 
| 31 25 | 
             
                end
         | 
| 32 26 |  | 
| @@ -38,6 +32,7 @@ module WavefrontCli | |
| 38 32 | 
             
                # You can override the options generated by docopt. This is how
         | 
| 39 33 | 
             
                # #wrap() works.
         | 
| 40 34 | 
             
                #
         | 
| 35 | 
            +
                # rubocop:disable Metrics/CyclomaticComplexity
         | 
| 41 36 | 
             
                def do_create(opts = nil)
         | 
| 42 37 | 
             
                  opts ||= options
         | 
| 43 38 |  | 
| @@ -45,20 +40,7 @@ module WavefrontCli | |
| 45 40 |  | 
| 46 41 | 
             
                  t_start = parse_time(opts[:start], true)
         | 
| 47 42 |  | 
| 48 | 
            -
                  body =  | 
| 49 | 
            -
                           startTime:   t_start,
         | 
| 50 | 
            -
                           annotations: {} }
         | 
| 51 | 
            -
             | 
| 52 | 
            -
                  body[:annotations][:details] = opts[:desc] if opts[:desc]
         | 
| 53 | 
            -
                  body[:annotations][:severity] = opts[:severity] if opts[:severity]
         | 
| 54 | 
            -
                  body[:annotations][:type] = opts[:type] if opts[:type]
         | 
| 55 | 
            -
                  body[:hosts] = opts[:host] if opts[:host]
         | 
| 56 | 
            -
             | 
| 57 | 
            -
                  if opts[:instant]
         | 
| 58 | 
            -
                    body[:endTime] = t_start + 1
         | 
| 59 | 
            -
                  elsif opts[:end]
         | 
| 60 | 
            -
                    body[:endTime] = parse_time(opts[:end], true)
         | 
| 61 | 
            -
                  end
         | 
| 43 | 
            +
                  body = create_body(opts, t_start)
         | 
| 62 44 |  | 
| 63 45 | 
             
                  resp = wf.create(body)
         | 
| 64 46 |  | 
| @@ -77,16 +59,8 @@ module WavefrontCli | |
| 77 59 | 
             
                #
         | 
| 78 60 | 
             
                def do_close(id = nil)
         | 
| 79 61 | 
             
                  id ||= options[:'<id>']
         | 
| 80 | 
            -
                  ev_file = nil
         | 
| 81 | 
            -
             | 
| 82 | 
            -
                  ev = if !id
         | 
| 83 | 
            -
                         pop_event
         | 
| 84 | 
            -
                       elsif id =~ /^\d{13}:.+/
         | 
| 85 | 
            -
                         ev_file = state_dir + id
         | 
| 86 | 
            -
                         id
         | 
| 87 | 
            -
                       else
         | 
| 88 | 
            -
                         pop_event(id)
         | 
| 89 | 
            -
                       end
         | 
| 62 | 
            +
                  ev_file = id =~ /^\d{13}:.+/ ? state_dir + id : nil
         | 
| 63 | 
            +
                  ev = local_event(id)
         | 
| 90 64 |  | 
| 91 65 | 
             
                  abort "No locally stored event matches '#{id}'." unless ev
         | 
| 92 66 |  | 
| @@ -96,11 +70,7 @@ module WavefrontCli | |
| 96 70 | 
             
                end
         | 
| 97 71 |  | 
| 98 72 | 
             
                def do_show
         | 
| 99 | 
            -
                   | 
| 100 | 
            -
                    events = state_dir.children
         | 
| 101 | 
            -
                  rescue Errno::ENOENT
         | 
| 102 | 
            -
                    raise 'There is no event state directory on this host.'
         | 
| 103 | 
            -
                  end
         | 
| 73 | 
            +
                  events = local_event_list
         | 
| 104 74 |  | 
| 105 75 | 
             
                  if events.size.zero?
         | 
| 106 76 | 
             
                    puts 'No open events.'
         | 
| @@ -123,6 +93,46 @@ module WavefrontCli | |
| 123 93 |  | 
| 124 94 | 
             
                private
         | 
| 125 95 |  | 
| 96 | 
            +
                # return [Hash] body for #create() method
         | 
| 97 | 
            +
                #
         | 
| 98 | 
            +
                def create_body(opts, t_start)
         | 
| 99 | 
            +
                  body = { name:        opts[:'<event>'],
         | 
| 100 | 
            +
                           startTime:   t_start,
         | 
| 101 | 
            +
                           annotations: {} }
         | 
| 102 | 
            +
             | 
| 103 | 
            +
                  body[:annotations][:details] = opts[:desc] if opts[:desc]
         | 
| 104 | 
            +
                  body[:annotations][:severity] = opts[:severity] if opts[:severity]
         | 
| 105 | 
            +
                  body[:annotations][:type] = opts[:type] if opts[:type]
         | 
| 106 | 
            +
                  body[:hosts] = opts[:host] if opts[:host]
         | 
| 107 | 
            +
                  body[:tags] = opts[:evtag] if opts[:evtag]
         | 
| 108 | 
            +
             | 
| 109 | 
            +
                  if opts[:instant]
         | 
| 110 | 
            +
                    body[:endTime] = t_start + 1
         | 
| 111 | 
            +
                  elsif opts[:end]
         | 
| 112 | 
            +
                    body[:endTime] = parse_time(opts[:end], true)
         | 
| 113 | 
            +
                  end
         | 
| 114 | 
            +
             | 
| 115 | 
            +
                  body
         | 
| 116 | 
            +
                end
         | 
| 117 | 
            +
             | 
| 118 | 
            +
                # @return a local event from the stack directory
         | 
| 119 | 
            +
                #
         | 
| 120 | 
            +
                def local_event(id)
         | 
| 121 | 
            +
                  if !id
         | 
| 122 | 
            +
                    pop_event
         | 
| 123 | 
            +
                  elsif id =~ /^\d{13}:.+/
         | 
| 124 | 
            +
                    id
         | 
| 125 | 
            +
                  else
         | 
| 126 | 
            +
                    pop_event(id)
         | 
| 127 | 
            +
                  end
         | 
| 128 | 
            +
                end
         | 
| 129 | 
            +
             | 
| 130 | 
            +
                def local_event_list
         | 
| 131 | 
            +
                  state_dir.children
         | 
| 132 | 
            +
                rescue Errno::ENOENT
         | 
| 133 | 
            +
                  raise 'There is no event state directory on this host.'
         | 
| 134 | 
            +
                end
         | 
| 135 | 
            +
             | 
| 126 136 | 
             
                # Run a command, stream stderr and stdout to the screen (they
         | 
| 127 137 | 
             
                # get combined -- could be an issue for someone somewhere) and
         | 
| 128 138 | 
             
                # return the command's exit code
         | 
| @@ -130,19 +140,17 @@ module WavefrontCli | |
| 130 140 | 
             
                # rubocop:disable Lint/AssignmentInCondition
         | 
| 131 141 | 
             
                #
         | 
| 132 142 | 
             
                def run_wrapped_cmd(cmd)
         | 
| 133 | 
            -
                   | 
| 134 | 
            -
             | 
| 143 | 
            +
                  separator = '-' * (TW - 4)
         | 
| 144 | 
            +
             | 
| 145 | 
            +
                  puts "Command output follows, on STDERR:\n#{separator}"
         | 
| 135 146 | 
             
                  ret = nil
         | 
| 136 147 |  | 
| 137 148 | 
             
                  Open3.popen2e(cmd) do |_in, out, thr|
         | 
| 138 | 
            -
                    while l = out.gets
         | 
| 139 | 
            -
                      STDERR.puts l
         | 
| 140 | 
            -
                    end
         | 
| 141 | 
            -
             | 
| 149 | 
            +
                    while l = out.gets do STDERR.puts(l) end
         | 
| 142 150 | 
             
                    ret = thr.value.exitstatus
         | 
| 143 151 | 
             
                  end
         | 
| 144 152 |  | 
| 145 | 
            -
                  puts  | 
| 153 | 
            +
                  puts separator
         | 
| 146 154 | 
             
                  ret
         | 
| 147 155 | 
             
                end
         | 
| 148 156 |  | 
| @@ -155,7 +163,7 @@ module WavefrontCli | |
| 155 163 |  | 
| 156 164 | 
             
                  begin
         | 
| 157 165 | 
             
                    File.open(fname, 'w') { hosts.to_s }
         | 
| 158 | 
            -
                  rescue
         | 
| 166 | 
            +
                  rescue StandardError
         | 
| 159 167 | 
             
                    raise 'Event was created but state file was not.'
         | 
| 160 168 | 
             
                  end
         | 
| 161 169 |  | 
| @@ -172,6 +180,7 @@ module WavefrontCli | |
| 172 180 | 
             
                def validate_input
         | 
| 173 181 | 
             
                  validate_id if options[:'<id>'] && !options[:close]
         | 
| 174 182 | 
             
                  validate_tags if options[:'<tag>']
         | 
| 183 | 
            +
                  validate_tags(:evtag) if options[:evtag]
         | 
| 175 184 | 
             
                  send(:extra_validation) if respond_to?(:extra_validation)
         | 
| 176 185 | 
             
                end
         | 
| 177 186 |  | 
| @@ -180,20 +189,25 @@ module WavefrontCli | |
| 180 189 | 
             
                # Chances are you'll only ever have one in-play at once.
         | 
| 181 190 | 
             
                #
         | 
| 182 191 | 
             
                # @param name [String] name of event
         | 
| 183 | 
            -
                #  | 
| 192 | 
            +
                # @eturn an array of [timestamp, event_name]
         | 
| 184 193 | 
             
                #
         | 
| 185 | 
            -
                def pop_event(name =  | 
| 194 | 
            +
                def pop_event(name = nil)
         | 
| 186 195 | 
             
                  return false unless state_dir.exist?
         | 
| 187 196 |  | 
| 188 | 
            -
                  list =  | 
| 189 | 
            -
             | 
| 190 | 
            -
                  list.select! { |f| f.basename.to_s.split(':').last == name } if name
         | 
| 191 | 
            -
             | 
| 197 | 
            +
                  list = local_events_with_name(name)
         | 
| 192 198 | 
             
                  return false if list.empty?
         | 
| 193 199 |  | 
| 194 200 | 
             
                  ev_file = list.sort.last
         | 
| 195 201 | 
             
                  File.unlink(ev_file)
         | 
| 196 202 | 
             
                  ev_file.basename.to_s
         | 
| 197 203 | 
             
                end
         | 
| 204 | 
            +
             | 
| 205 | 
            +
                def local_events_with_name(name = nil)
         | 
| 206 | 
            +
                  list = local_event_list
         | 
| 207 | 
            +
             | 
| 208 | 
            +
                  return list unless name
         | 
| 209 | 
            +
             | 
| 210 | 
            +
                  list.select { |f| f.basename.to_s.split(':').last == name }
         | 
| 211 | 
            +
                end
         | 
| 198 212 | 
             
              end
         | 
| 199 213 | 
             
            end
         | 
| @@ -6,7 +6,6 @@ module WavefrontCli | |
| 6 6 | 
             
              # CLI coverage for the v2 'maintenancewindow' API.
         | 
| 7 7 | 
             
              #
         | 
| 8 8 | 
             
              class MaintenanceWindow < WavefrontCli::Base
         | 
| 9 | 
            -
             | 
| 10 9 | 
             
                include Wavefront::Mixins
         | 
| 11 10 |  | 
| 12 11 | 
             
                def validator_method
         | 
| @@ -18,24 +17,10 @@ module WavefrontCli | |
| 18 17 | 
             
                end
         | 
| 19 18 |  | 
| 20 19 | 
             
                def do_create
         | 
| 21 | 
            -
                  body =  | 
| 22 | 
            -
             | 
| 23 | 
            -
                  body[:startTimeInSeconds] = if options[:start]
         | 
| 24 | 
            -
                                                parse_time(options[:start])
         | 
| 25 | 
            -
                                              else
         | 
| 26 | 
            -
                                                Time.now.to_i
         | 
| 27 | 
            -
                                              end
         | 
| 28 | 
            -
             | 
| 29 | 
            -
                  body[:endTimeInSeconds] = if options[:end]
         | 
| 30 | 
            -
                                              parse_time(options[:end])
         | 
| 31 | 
            -
                                            else
         | 
| 32 | 
            -
                                              body[:startTimeInSeconds] + 3600
         | 
| 33 | 
            -
                                            end
         | 
| 34 | 
            -
             | 
| 35 | 
            -
                  body[:reason] = options[:desc] if options[:desc]
         | 
| 20 | 
            +
                  body = build_body
         | 
| 36 21 |  | 
| 37 | 
            -
                  [%i | 
| 38 | 
            -
                   %i | 
| 22 | 
            +
                  [%i[CustomerTags atag], %i[HostTags htag],
         | 
| 23 | 
            +
                   %i[HostNames host]].each do |key, opt|
         | 
| 39 24 | 
             
                    k = ('relevant' + key.to_s).to_sym
         | 
| 40 25 | 
             
                    body[k] = options[opt] unless options[opt].empty?
         | 
| 41 26 | 
             
                  end
         | 
| @@ -43,10 +28,41 @@ module WavefrontCli | |
| 43 28 | 
             
                  wf.create(body)
         | 
| 44 29 | 
             
                end
         | 
| 45 30 |  | 
| 31 | 
            +
                def build_body
         | 
| 32 | 
            +
                  ret = { title:              options[:'<title>'],
         | 
| 33 | 
            +
                          startTimeInSeconds: window_start,
         | 
| 34 | 
            +
                          endTimeInSeconds:   window_end }
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                  ret[:reason] = options[:desc] if options[:desc]
         | 
| 37 | 
            +
                  ret
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                # @return [Integer] start time of window, in seconds. If not
         | 
| 41 | 
            +
                #   given as an option, start it now
         | 
| 42 | 
            +
                #
         | 
| 43 | 
            +
                def window_start
         | 
| 44 | 
            +
                  if options[:start]
         | 
| 45 | 
            +
                    parse_time(options[:start])
         | 
| 46 | 
            +
                  else
         | 
| 47 | 
            +
                    Time.now.to_i
         | 
| 48 | 
            +
                  end
         | 
| 49 | 
            +
                end
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                # @return [Integer] end time of window, in seconds. If not
         | 
| 52 | 
            +
                #   given as an option, end it in an hour
         | 
| 53 | 
            +
                #
         | 
| 54 | 
            +
                def window_end
         | 
| 55 | 
            +
                  if options[:end]
         | 
| 56 | 
            +
                    parse_time(options[:end])
         | 
| 57 | 
            +
                  else
         | 
| 58 | 
            +
                    window_start + 3600
         | 
| 59 | 
            +
                  end
         | 
| 60 | 
            +
                end
         | 
| 61 | 
            +
             | 
| 46 62 | 
             
                def do_extend_by
         | 
| 47 63 | 
             
                  begin
         | 
| 48 64 | 
             
                    to_add = options[:'<time>'].to_seconds
         | 
| 49 | 
            -
                  rescue
         | 
| 65 | 
            +
                  rescue ArgumentError
         | 
| 50 66 | 
             
                    abort "Could not parse time range '#{options[:'<time>']}'."
         | 
| 51 67 | 
             
                  end
         | 
| 52 68 |  | 
| @@ -63,7 +79,7 @@ module WavefrontCli | |
| 63 79 | 
             
                end
         | 
| 64 80 |  | 
| 65 81 | 
             
                def change_end_time(ts)
         | 
| 66 | 
            -
                  wf.update(options[:'<id>'],  | 
| 82 | 
            +
                  wf.update(options[:'<id>'], endTimeInSeconds: ts)
         | 
| 67 83 | 
             
                end
         | 
| 68 84 | 
             
              end
         | 
| 69 85 | 
             
            end
         |