Class: Wavefront::Base

Inherits:
Object
  • Object
show all
Includes:
Mixins, Validators
Defined in:
lib/wavefront-sdk/base.rb

Overview

Abstract class from which all API classes inherit. When you make any call to the Wavefront API from this SDK, you are returned an OpenStruct object.

rubocop:disable Metrics/ClassLength

Returns:

  • a Wavefront::Response object

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Mixins

#parse_relative_time, #parse_time, #relative_time, #time_multiplier

Methods included from Validators

#wf_alert_id?, #wf_alert_severity?, #wf_cloudintegration_id?, #wf_dashboard_id?, #wf_derivedmetric_id?, #wf_epoch?, #wf_event_id?, #wf_granularity?, #wf_integration_id?, #wf_link_id?, #wf_link_template?, #wf_maintenance_window_id?, #wf_message_id?, #wf_metric_name?, #wf_ms_ts?, #wf_name?, #wf_notificant_id?, #wf_point?, #wf_point_tag?, #wf_point_tags?, #wf_proxy_id?, #wf_savedsearch_entity?, #wf_savedsearch_id?, #wf_source_id?, #wf_string?, #wf_tag?, #wf_ts?, #wf_user_id?, #wf_value?, #wf_version?, #wf_webhook_id?

Constructor Details

#initialize(creds = {}, opts = {}) ⇒ Nil

Create a new API object. This will always be called from a class which inherits this one. If the inheriting class defines #post_initialize, that method will be called afterwards, with the same arguments.

Parameters:

  • creds (Hash) (defaults to: {})

    must contain the keys endpoint (the Wavefront API server) and token, the user token with which you wish to access the endpoint. Can optionally contain agent, which will become the user-agent string sent with all requests.

  • opts (Hash) (defaults to: {})

    options governing class behaviour. Expected keys are debug, noop and verbose, all boolean; and logger, which must be a standard Ruby logger object. You can also pass :response_only. If this is true, you will only be returned a hash of the ‘response’ object returned by Wavefront.



46
47
48
49
50
51
52
53
54
55
# File 'lib/wavefront-sdk/base.rb', line 46

def initialize(creds = {}, opts = {})
  @opts  = opts
  @debug = opts[:debug] || false
  @noop = opts[:noop] || false
  @verbose = opts[:verbose] || false
  @logger = opts[:logger] || nil
  setup_endpoint(creds)

  post_initialize(creds, opts) if respond_to?(:post_initialize)
end

Instance Attribute Details

#connObject (readonly)

Returns the value of attribute conn.



25
26
27
# File 'lib/wavefront-sdk/base.rb', line 25

def conn
  @conn
end

#debugObject (readonly)

Returns the value of attribute debug.



25
26
27
# File 'lib/wavefront-sdk/base.rb', line 25

def debug
  @debug
end

#loggerObject (readonly)

Returns the value of attribute logger.



25
26
27
# File 'lib/wavefront-sdk/base.rb', line 25

def logger
  @logger
end

#netObject (readonly)

Returns the value of attribute net.



25
26
27
# File 'lib/wavefront-sdk/base.rb', line 25

def net
  @net
end

#noopObject (readonly)

Returns the value of attribute noop.



25
26
27
# File 'lib/wavefront-sdk/base.rb', line 25

def noop
  @noop
end

#optsObject (readonly)

Returns the value of attribute opts.



25
26
27
# File 'lib/wavefront-sdk/base.rb', line 25

def opts
  @opts
end

#update_keysObject (readonly)

Returns the value of attribute update_keys.



25
26
27
# File 'lib/wavefront-sdk/base.rb', line 25

def update_keys
  @update_keys
end

#verboseObject (readonly)

Returns the value of attribute verbose.



25
26
27
# File 'lib/wavefront-sdk/base.rb', line 25

def verbose
  @verbose
end

Instance Method Details

#api_baseString

Derive the first part of the API path from the class name. You can override this in your class if you wish

Returns:

  • (String)

    portion of API URI



75
76
77
# File 'lib/wavefront-sdk/base.rb', line 75

def api_base
  self.class.name.split('::').last.downcase
end

#api_delete(path) ⇒ Hash

Make a DELETE call to the Wavefront API and return the result as a Ruby hash. Can optionally perform a verbose noop, if the #noop class variable is set. If #verbose is set, then prints the information used to build the URI.

Parameters:

  • path (String)

    path to be appended to the #net path.

Returns:

  • (Hash)

    API response



154
155
156
# File 'lib/wavefront-sdk/base.rb', line 154

def api_delete(path)
  make_call(mk_conn(path), :delete)
end

#api_get(path, query = {}) ⇒ Hash

Make a GET call to the Wavefront API and return the result as a Ruby hash. Can optionally perform a verbose noop, if the #noop class variable is set. If #verbose is set, then prints the information used to build the URI.

Parameters:

  • path (String)

    path to be appended to the #net path.

  • query (Hash) (defaults to: {})

    optional key-value pairs with will be made into aquery string

Returns:

  • (Hash)

    API response



106
107
108
# File 'lib/wavefront-sdk/base.rb', line 106

def api_get(path, query = {})
  make_call(mk_conn(path), :get, nil, query)
end

#api_pathObject



231
232
233
# File 'lib/wavefront-sdk/base.rb', line 231

def api_path
  ['', 'api', 'v2', api_base].uri_concat
end

#api_post(path, body = nil, ctype = 'text/plain') ⇒ Hash

Make a POST call to the Wavefront API and return the result as a Ruby hash. Can optionally perform a verbose noop, if the #noop class variable is set. If #verbose is set, then prints the information used to build the URI.

Parameters:

  • path (String)

    path to be appended to the #net path.

  • body (String) (defaults to: nil)

    optional body text to post

  • ctype (String) (defaults to: 'text/plain')

    the content type to use when posting

Returns:

  • (Hash)

    API response



121
122
123
124
125
126
# File 'lib/wavefront-sdk/base.rb', line 121

def api_post(path, body = nil, ctype = 'text/plain')
  body = body.to_json unless body.is_a?(String)
  make_call(mk_conn(path,  'Content-Type': ctype,
                           'Accept': 'application/json'),
            :post, nil, body)
end

#api_put(path, body = nil, ctype = 'application/json') ⇒ Hash

Make a PUT call to the Wavefront API and return the result as a Ruby hash. Can optionally perform a verbose noop, if the #noop class variable is set. If #verbose is set, then prints the information used to build the URI.

Parameters:

  • path (String)

    path to be appended to the #net path.

  • body (String) (defaults to: nil)

    optional body text to post

  • ctype (String) (defaults to: 'application/json')

    the content type to use when putting

Returns:

  • (Hash)

    API response



139
140
141
142
143
# File 'lib/wavefront-sdk/base.rb', line 139

def api_put(path, body = nil, ctype = 'application/json')
  make_call(mk_conn(path,  'Content-Type': ctype,
                           'Accept': 'application/json'),
            :put, nil, body.to_json)
end

#everythingObject

Return all objects using a lazy enumerator

Returns:

  • Enumerable



217
218
219
220
221
222
223
224
225
226
227
228
229
# File 'lib/wavefront-sdk/base.rb', line 217

def everything
  Enumerator.new do |y|
    offset = 0
    limit = 100

    loop do
      resp = api_get('', offset: offset, limit: limit).response
      resp.items.map { |i| y.<< i }
      offset += limit
      raise StopIteration unless resp.moreItems == true
    end
  end.lazy
end

#hash_for_update(old, new) ⇒ Hash

doing a PUT to update an object requires only a certain subset of the keys returned by #describe(). This method takes the existing description of an object and turns it into a new has which can be PUT.

Parameters:

  • old (Hash)

    a hash of the existing object

  • new (Hash)

    the keys you wish to update

Returns:

  • (Hash)

    a hash containing only the keys which need to be sent to the API. Keys will be symbolized.

Raises:

  • (ArgumentError)


168
169
170
171
172
173
174
# File 'lib/wavefront-sdk/base.rb', line 168

def hash_for_update(old, new)
  raise ArgumentError unless old.is_a?(Hash) && new.is_a?(Hash)

  Hash[old.merge(new).map { |k, v| [k.to_sym, v] }].select do |k, _v|
    update_keys.include?(k)
  end
end

#log(msg, level = nil) ⇒ Object

Send a message to a Ruby logger object if the user supplied one, or print to standard out if not.

Parameters:

  • msg (String)

    the string to print

  • level (Symbol) (defaults to: nil)

    the level of the message. :verbose messages equate to a standard INFO log level and :debug to DEBUG.



184
185
186
187
188
189
190
# File 'lib/wavefront-sdk/base.rb', line 184

def log(msg, level = nil)
  if logger
    logger.send(level || :info, msg)
  else
    print_message(msg, level)
  end
end

#mk_conn(path, headers = {}) ⇒ URI::HTTPS

Create a Faraday connection object. The server comes from the endpoint passed to the initializer in the ‘creds’ hash; the root of the URI is dynamically derived by the #setup_endpoint method.

Parameters:

  • headers (Hash) (defaults to: {})

    additional headers

Returns:

  • (URI::HTTPS)


87
88
89
90
91
92
93
# File 'lib/wavefront-sdk/base.rb', line 87

def mk_conn(path, headers = {})
  Faraday.new(
    url:     Addressable::URI.encode("https://#{net[:endpoint]}" +
             [net[:api_base], path].uri_concat),
    headers: net[:headers].merge(headers)
  )
end

Print it unless it’s a debug and we’re not in debug



194
195
196
197
198
# File 'lib/wavefront-sdk/base.rb', line 194

def print_message(msg, level)
  return if level == :debug && !opts[:debug]
  return if level == :info && !opts[:verbose]
  puts msg
end

#respond(resp) ⇒ Object

If we need to massage a raw response to fit what the Wavefront::Response class expects (I’m looking at you, ‘User’), a class can provide a #response_shim method.



204
205
206
207
208
209
210
211
212
# File 'lib/wavefront-sdk/base.rb', line 204

def respond(resp)
  body = if respond_to?(:response_shim)
           response_shim(resp.body, resp.status)
         else
           resp.body
         end

  Wavefront::Response.new(body, resp.status, debug)
end

#time_to_ms(time) ⇒ Ingeter

Convert an epoch timestamp into epoch milliseconds. If the timestamp looks like it’s already epoch milliseconds, return it as-is.

Parameters:

  • t (Integer)

    epoch timestamp

Returns:

  • (Ingeter)

    epoch millisecond timestamp



64
65
66
67
68
# File 'lib/wavefront-sdk/base.rb', line 64

def time_to_ms(time)
  return false unless time.is_a?(Integer)
  return time if time.to_s.size == 13
  (time.to_f * 1000).round
end