Class: WavefrontCli::Event

Inherits:
Base
  • Object
show all
Includes:
Wavefront::Mixins, Mixin::Tag
Defined in:
lib/wavefront-cli/event.rb

Overview

CLI coverage for the v2 ‘event’ API.

Constant Summary

Constants included from Constants

Constants::ALL_PAGE_SIZE, Constants::DEFAULT_CONFIG, Constants::DEFAULT_OPTS, Constants::EVENT_STATE_DIR, Constants::HUMAN_TIME_FORMAT, Constants::HUMAN_TIME_FORMAT_MS, Constants::SEARCH_SPLIT

Instance Attribute Summary collapse

Attributes inherited from Base

#klass, #klass_word, #options, #wf

Instance Method Summary collapse

Methods included from Mixin::Tag

#do_tag_add, #do_tag_clear, #do_tag_delete, #do_tag_pathsearch, #do_tag_set, #do_tags

Methods inherited from Base

#_sdk_class, #cannot_noop!, #check_response_blocks, #check_status, #cli_output_class, #conds_to_query, #descriptive_name, #dispatch, #display, #display_api_error, #display_class, #display_no_api_response, #do_delete, #do_describe, #do_dump, #do_import, #do_search, #do_set, #do_undelete, #dump_json, #dump_yaml, #extract_values, #failed_validation_message, #format_var, #handle_error, #handle_response, #hcl_fields, #import_to_create, #initialize, #item_dump_call, #load_display_class, #matching_method, #method_word_list, #mk_creds, #mk_opts, #name_of_do_method, #no_api_response, #ok_exit, #one_or_all, #options_and_exit, #parseable_output, #range_hash, #require_sdk_class, #run, #search_key, #smart_delete, #smart_delete_message, #status_error_handler, #unsupported_format_message, #validate_id, #validate_opts, #validate_tags, #validator_exception, #validator_method, #warning_message

Constructor Details

This class inherits a constructor from WavefrontCli::Base

Instance Attribute Details

#state_dirObject (readonly)

Returns the value of attribute state_dir.



14
15
16
# File 'lib/wavefront-cli/event.rb', line 14

def state_dir
  @state_dir
end

Instance Method Details

#annotations(opts) ⇒ Object

rubocop:enable Metrics/AbcSize rubocop:enable Metrics/MethodLength



118
119
120
121
122
123
124
# File 'lib/wavefront-cli/event.rb', line 118

def annotations(opts)
  {}.tap do |r|
    r[:details] = opts[:desc] if opts[:desc]
    r[:severity] = opts[:severity] if opts[:severity]
    r[:type] = opts[:type] if opts[:type]
  end
end

#create_body(opts, t_start) ⇒ Object

return [Hash] body for #create() method

rubocop:disable Metrics/MethodLength rubocop:disable Metrics/AbcSize



101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/wavefront-cli/event.rb', line 101

def create_body(opts, t_start)
  { name: opts[:'<event>'],
    startTime: t_start,
    annotations: annotations(opts) }.tap do |r|
      r[:hosts] = opts[:host] if opts[:host]
      r[:tags] = opts[:evtag] if opts[:evtag]

      if opts[:instant]
        r[:endTime] = t_start + 1
      elsif opts[:end]
        r[:endTime] = parse_time(opts[:end], true)
      end
    end
end

#create_dir(state_dir) ⇒ Object



193
194
195
196
197
198
199
200
# File 'lib/wavefront-cli/event.rb', line 193

def create_dir(state_dir)
  FileUtils.mkdir_p(state_dir)
  raise unless state_dir.exist? && state_dir.directory? &&
               state_dir.writable?
rescue StandardError
  raise(WavefrontCli::Exception::SystemError,
        "Cannot create writable system directory at '#{state_dir}'.")
end

#create_state_file(id) ⇒ Object

Write a state file. We put the hosts bound to the event into the file. These aren’t currently used by anything in the CLI, but they might be useful to someone, somewhere, someday.



173
174
175
176
177
178
179
# File 'lib/wavefront-cli/event.rb', line 173

def create_state_file(id)
  fname = state_dir + id
  File.open(fname, 'w') { |fh| fh.puts(event_file_data) }
  puts "Event state recorded at #{fname}."
rescue StandardError
  puts 'NOTICE: event was created but state file was not.'
end

#do_close(id = nil) ⇒ Object

The user doesn’t have to give us an event ID. If no event name is given, we’ll pop the last event off the stack. If an event name is given and it doesn’t look like a full WF event name, we’ll look for something on the stack. If it does look like a real event, we’ll make an API call straight away.



48
49
50
51
52
53
54
55
56
57
58
# File 'lib/wavefront-cli/event.rb', line 48

def do_close(id = nil)
  id ||= options[:'<id>']
  ev = local_event(id)
  ev_file = event_file(id)

  abort "No locally stored event matches '#{id}'." unless ev

  res = wf.close(ev)
  ev_file.unlink if ev_file&.exist? && res.status.code == 200
  res
end

#do_create(opts = nil) ⇒ Object



28
29
30
31
32
33
34
35
36
# File 'lib/wavefront-cli/event.rb', line 28

def do_create(opts = nil)
  opts ||= options
  opts[:start] = Time.now unless opts[:start]
  t_start = parse_time(opts[:start], true)
  body = create_body(opts, t_start)
  resp = wf.create(body)
  create_state_file(resp.response[:id]) if state_file_needed?(opts)
  resp
end

#do_listObject



24
25
26
# File 'lib/wavefront-cli/event.rb', line 24

def do_list
  wf.list(*list_args)
end

#do_showObject



64
65
66
67
68
69
70
71
72
73
74
# File 'lib/wavefront-cli/event.rb', line 64

def do_show
  events = local_event_list

  if events.size.zero?
    puts 'No open events.'
  else
    events.sort.reverse_each { |e| puts e.basename }
  end

  exit
end

#do_wrapObject



76
77
78
79
80
81
82
83
84
# File 'lib/wavefront-cli/event.rb', line 76

def do_wrap
  create_opts = options
  create_opts[:desc] ||= create_opts[:command]
  event_id = do_create(create_opts).response.id
  exit_code = run_wrapped_cmd(options[:command])
  do_close(event_id)
  puts "Command exited #{exit_code}."
  exit exit_code
end

#event_file(id) ⇒ Object



60
61
62
# File 'lib/wavefront-cli/event.rb', line 60

def event_file(id)
  id =~ /^\d{13}:.+/ ? state_dir + id : nil
end

#event_file_dataString

Record event data in the state file. We don’t currently use it, but it might be useful to someone someday.

Returns:



186
187
188
189
190
191
# File 'lib/wavefront-cli/event.rb', line 186

def event_file_data
  { hosts: options[:host],
    description: options[:desc],
    severity: options[:severity],
    tags: options[:evtag] }.to_json
end

#event_state_dirObject

We can override the temp directory with the WF_EVENT_STATE_DIR. This is primarily for testing.



89
90
91
92
93
94
95
# File 'lib/wavefront-cli/event.rb', line 89

def event_state_dir
  if ENV['WF_EVENT_STATE_DIR']
    Pathname.new(ENV['WF_EVENT_STATE_DIR'])
  else
    EVENT_STATE_DIR
  end
end

#list_argsObject



234
235
236
237
238
239
# File 'lib/wavefront-cli/event.rb', line 234

def list_args
  [window_start,
   window_end,
   options[:limit] || 100,
   options[:cursor] || nil]
end

#local_event(id) ⇒ Object

Returns a local event from the stack directory.

Returns:

  • a local event from the stack directory



128
129
130
131
132
133
134
135
136
# File 'lib/wavefront-cli/event.rb', line 128

def local_event(id)
  if !id
    pop_event
  elsif id =~ /^\d{13}:.+/
    id
  else
    pop_event(id)
  end
end

#local_event_listObject



138
139
140
141
142
143
144
145
146
# File 'lib/wavefront-cli/event.rb', line 138

def local_event_list
  events = state_dir.children
  abort 'No locally recorded events.' if events.empty?

  events
rescue Errno::ENOENT
  raise(WavefrontCli::Exception::SystemError,
        'There is no event state directory on this host.')
end

#local_events_with_name(name = nil) ⇒ Object



227
228
229
230
231
232
# File 'lib/wavefront-cli/event.rb', line 227

def local_events_with_name(name = nil)
  list = local_event_list
  return list unless name

  list.select { |f| f.basename.to_s.split(':').last == name }
end

#pop_event(name = nil) ⇒ Object

Get the last event this script created. If you supply a name, you get the last event with that name. If not, you get the last event. Chances are you’ll only ever have one in-play at once.

Parameters:

  • name (String) (defaults to: nil)

    name of event



216
217
218
219
220
221
222
223
224
225
# File 'lib/wavefront-cli/event.rb', line 216

def pop_event(name = nil)
  return false unless state_dir.exist?

  list = local_events_with_name(name)
  return false if list.empty?

  ev_file = list.max
  File.unlink(ev_file)
  ev_file.basename.to_s
end

#post_initialize(_options) ⇒ Object



19
20
21
22
# File 'lib/wavefront-cli/event.rb', line 19

def post_initialize(_options)
  @state_dir = event_state_dir + (Etc.getlogin || 'notty')
  create_dir(state_dir)
end

#run_wrapped_cmd(cmd) ⇒ Object

Run a command, stream stderr and stdout to the screen (they get combined – could be an issue for someone somewhere) and return the command’s exit code



152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/wavefront-cli/event.rb', line 152

def run_wrapped_cmd(cmd)
  separator = '-' * (TW - 4)

  puts "Command output follows, on STDERR:\n#{separator}"
  ret = nil

  Open3.popen2e(cmd) do |_in, out, thr|
    # rubocop:disable Lint/AssignmentInCondition
    while l = out.gets do warn l end
    # rubocop:enable Lint/AssignmentInCondition
    ret = thr.value.exitstatus
  end

  puts separator
  ret
end

#state_file_needed?(opts) ⇒ Boolean

Returns:

  • (Boolean)


38
39
40
# File 'lib/wavefront-cli/event.rb', line 38

def state_file_needed?(opts)
  !(opts[:nostate] || opts[:end] || opts[:instant])
end

#validate_inputObject



202
203
204
205
206
207
# File 'lib/wavefront-cli/event.rb', line 202

def validate_input
  validate_id if options[:'<id>'] && !options[:close]
  validate_tags if options[:'<tag>']
  validate_tags(:evtag) if options[:evtag]
  send(:extra_validation) if respond_to?(:extra_validation)
end

#window_endObject



245
246
247
# File 'lib/wavefront-cli/event.rb', line 245

def window_end
  parse_time((options[:end] || Time.now), true)
end

#window_startObject



241
242
243
# File 'lib/wavefront-cli/event.rb', line 241

def window_start
  parse_time((options[:start] || Time.now - 600), true)
end