class Wavefront::Cli::Alerts

Attributes

arguments[RW]
options[RW]
wfa[RW]

Public Instance Methods

export_alert(id) click to toggle source
# File lib/wavefront/cli/alerts.rb, line 87
def export_alert(id)
  begin
    resp = wfa.get_alert(id)
  rescue => e
    puts e if @options[:debug]
    raise 'Unable to retrieve alert.'
  end

  return if options[:noop]

  case options[:alertformat].to_sym
  when :json
    puts JSON.pretty_generate(resp)
  when :yaml
    puts resp.to_yaml
  when :human
    puts humanize([resp])
  else
    puts 'unknown output format.'
  end
end
format_result(result, format) click to toggle source
# File lib/wavefront/cli/alerts.rb, line 109
def format_result(result, format)
  #
  # Call a suitable method to display the output of the API call,
  # which is JSON.
  #
  return if noop

  case format
  when :ruby
    pp result
  when :json
    puts JSON.pretty_generate(JSON.parse(result))
  when :yaml
    puts JSON.parse(result).to_yaml
  when :human
    puts humanize(JSON.parse(result))
  else
    raise "Invalid output format '#{format}'. See --help for more detail."
  end
end
human_line(k, v) click to toggle source
# File lib/wavefront/cli/alerts.rb, line 185
def human_line(k, v)
  ('%-22s%s' % [k, v]).rstrip
end
human_line_additionalInformation(k, v) click to toggle source
# File lib/wavefront/cli/alerts.rb, line 219
def human_line_additionalInformation(k, v)
  human_line(k, indent_wrap(v))
end
human_line_alertStates(k, v) click to toggle source
# File lib/wavefront/cli/alerts.rb, line 215
def human_line_alertStates(k, v)
  human_line(k, v.join(','))
end
human_line_created(k, v) click to toggle source
# File lib/wavefront/cli/alerts.rb, line 189
def human_line_created(k, v)
  #
  # The 'created' and 'updated' timestamps are in epoch
  # milliseconds
  #
  human_line(k, "#{Time.at(v / 1000)} (#{v})")
end
human_line_hostsUsed(k, v) click to toggle source
# File lib/wavefront/cli/alerts.rb, line 201
def human_line_hostsUsed(k, v)
  #
  # Put each host on its own line, indented. Does this by
  # returning an array.
  #
  return k unless v && v.is_a?(Array) && ! v.empty?
  v.sort!
  [human_line(k, v.shift)] + v.map {|el| human_line('', el)}
end
human_line_metricsUsed(k, v) click to toggle source
# File lib/wavefront/cli/alerts.rb, line 211
def human_line_metricsUsed(k, v)
  human_line_hostsUsed(k, v)
end
human_line_updated(k, v) click to toggle source
# File lib/wavefront/cli/alerts.rb, line 197
def human_line_updated(k, v)
  human_line_created(k, v)
end
humanize(alerts) click to toggle source
# File lib/wavefront/cli/alerts.rb, line 153
def humanize(alerts)
  #
  # Selectively display alert information in an easily
  # human-readable format. I have chosen not to display certain
  # fields which I don't think are useful in this context. I also
  # wish to put the fields in order. Here are the fields I want, in
  # the order I want them.
  #
  row_order = %w(name created severity condition displayExpression
                 minutes resolveAfterMinutes updated alertStates
                 metricsUsed hostsUsed additionalInformation)

  # build up an array of lines then turn it into a string and
  # return it
  #
  # Most things get printed with the human_line() method, but some
  # data needs special handling. To do that, just add a method
  # called human_line_key() where key is something in row_order,
  # and it will be found.
  #
  x = alerts.map do |alert|
    row_order.map do |key|
      lm = "human_line_#{key}"
      if self.respond_to?(lm)
        self.method(lm.to_sym).call(key, alert[key])
      else
        human_line(key, alert[key])
      end
    end.<< ''
  end
end
import_alert() click to toggle source
# File lib/wavefront/cli/alerts.rb, line 69
def import_alert
  raw = load_file(options[:'<file>'])

  begin
    prepped = wfa.import_to_create(raw)
  rescue => e
    puts e if options[:debug]
    raise 'could not parse input.'
  end

  begin
    wfa.create_alert(prepped)
    puts 'Alert imported.' unless options[:noop]
  rescue RestClient::BadRequest
    raise '400 error: alert probably exists.'
  end
end
indent_wrap(line, cols=78, offset=22) click to toggle source
# File lib/wavefront/cli/alerts.rb, line 223
def indent_wrap(line, cols=78, offset=22)
  #
  # hanging indent long lines to fit in an 80-column terminal
  #
  return unless line
  line.gsub(/(.{1,#{cols - offset}})(\s+|\Z)/, "\\1\n#{' ' *
            offset}").rstrip
end
run() click to toggle source
# File lib/wavefront/cli/alerts.rb, line 27
def run
  raise 'Missing token.' if ! @options[:token] || @options[:token].empty?
  raise 'Missing query.' if arguments.empty?
  valid_format?(@options[:alertformat].to_sym)

  @wfa = Wavefront::Alerting.new(@options[:token], @options[:endpoint],
                                @options[:debug], {
    noop: @options[:noop], verbose: @options[:verbose]})

  if options[:export]
    export_alert(options[:'<timestamp>'])
    return
  end

  if options[:import]
    import_alert
    return
  end

  query = arguments[0].to_sym
  valid_state?(wfa, query)
  options = { host: @options[:endpoint] }

  if @options[:shared]
    options[:shared_tags] = @options[:shared].delete(' ').split(',')
  end

  if @options[:private]
    options[:private_tags] = @options[:private].delete(' ').split(',')
  end

  begin
    result = wfa.send(query, options)
  rescue => e
    puts e if @options[:debug]
    raise 'Unable to execute query.'
  end

  format_result(result, @options[:alertformat].to_sym)
  exit
end
valid_format?(fmt) click to toggle source
# File lib/wavefront/cli/alerts.rb, line 130
def valid_format?(fmt)
  fmt = fmt.to_sym if fmt.is_a?(String)

  unless Wavefront::Client::ALERT_FORMATS.include?(fmt)
    raise 'Output format must be one of: ' +
      Wavefront::Client::ALERT_FORMATS.join(', ') + '.'
  end
  true
end
valid_state?(wfa, state) click to toggle source
# File lib/wavefront/cli/alerts.rb, line 140
def valid_state?(wfa, state)
  #
  # Check the alert type we've been given is valid. There needs to
  # be a public method in the 'alerting' class for every one.
  #
  states = %w(active affected_by_maintenance all invalid snoozed)

  unless states.include?(state.to_s)
    raise "State must be one of: #{states.join(', ')}."
  end
  true
end