wavefront-sdk 0.0.1

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.
Files changed (60) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +20 -0
  3. data/.gitignore +4 -0
  4. data/.rubocop.yml +1157 -0
  5. data/.travis.yml +16 -0
  6. data/Gemfile +2 -0
  7. data/Gemfile.lock +58 -0
  8. data/LICENSE.txt +27 -0
  9. data/README.md +103 -0
  10. data/Rakefile +18 -0
  11. data/lib/wavefront-sdk/alert.rb +195 -0
  12. data/lib/wavefront-sdk/base.rb +251 -0
  13. data/lib/wavefront-sdk/cloudintegration.rb +88 -0
  14. data/lib/wavefront-sdk/credentials.rb +79 -0
  15. data/lib/wavefront-sdk/dashboard.rb +157 -0
  16. data/lib/wavefront-sdk/event.rb +173 -0
  17. data/lib/wavefront-sdk/exception.rb +39 -0
  18. data/lib/wavefront-sdk/externallink.rb +77 -0
  19. data/lib/wavefront-sdk/maintenancewindow.rb +75 -0
  20. data/lib/wavefront-sdk/message.rb +36 -0
  21. data/lib/wavefront-sdk/metric.rb +52 -0
  22. data/lib/wavefront-sdk/mixins.rb +60 -0
  23. data/lib/wavefront-sdk/proxy.rb +95 -0
  24. data/lib/wavefront-sdk/query.rb +96 -0
  25. data/lib/wavefront-sdk/response.rb +56 -0
  26. data/lib/wavefront-sdk/savedsearch.rb +88 -0
  27. data/lib/wavefront-sdk/search.rb +58 -0
  28. data/lib/wavefront-sdk/source.rb +131 -0
  29. data/lib/wavefront-sdk/user.rb +108 -0
  30. data/lib/wavefront-sdk/validators.rb +395 -0
  31. data/lib/wavefront-sdk/version.rb +1 -0
  32. data/lib/wavefront-sdk/webhook.rb +73 -0
  33. data/lib/wavefront-sdk/write.rb +225 -0
  34. data/pkg/wavefront-client-3.5.0.gem +0 -0
  35. data/spec/.rubocop.yml +14 -0
  36. data/spec/spec_helper.rb +157 -0
  37. data/spec/wavefront-sdk/alert_spec.rb +83 -0
  38. data/spec/wavefront-sdk/base_spec.rb +88 -0
  39. data/spec/wavefront-sdk/cloudintegration_spec.rb +54 -0
  40. data/spec/wavefront-sdk/credentials_spec.rb +55 -0
  41. data/spec/wavefront-sdk/dashboard_spec.rb +74 -0
  42. data/spec/wavefront-sdk/event_spec.rb +83 -0
  43. data/spec/wavefront-sdk/externallink_spec.rb +65 -0
  44. data/spec/wavefront-sdk/maintenancewindow_spec.rb +48 -0
  45. data/spec/wavefront-sdk/message_spec.rb +19 -0
  46. data/spec/wavefront-sdk/metric_spec.rb +21 -0
  47. data/spec/wavefront-sdk/mixins_spec.rb +27 -0
  48. data/spec/wavefront-sdk/proxy_spec.rb +41 -0
  49. data/spec/wavefront-sdk/query_spec.rb +51 -0
  50. data/spec/wavefront-sdk/resources/test.conf +10 -0
  51. data/spec/wavefront-sdk/response_spec.rb +47 -0
  52. data/spec/wavefront-sdk/savedsearch_spec.rb +54 -0
  53. data/spec/wavefront-sdk/search_spec.rb +47 -0
  54. data/spec/wavefront-sdk/source_spec.rb +48 -0
  55. data/spec/wavefront-sdk/user_spec.rb +56 -0
  56. data/spec/wavefront-sdk/validators_spec.rb +238 -0
  57. data/spec/wavefront-sdk/webhook_spec.rb +50 -0
  58. data/spec/wavefront-sdk/write_spec.rb +167 -0
  59. data/wavefront-sdk.gemspec +34 -0
  60. metadata +269 -0
@@ -0,0 +1,39 @@
1
+ module Wavefront
2
+ #
3
+ # Simple exception classes
4
+ #
5
+ class Exception
6
+ class EmptyMetricName < ::Exception; end
7
+ class InvalidAlertId < ::Exception; end
8
+ class InvalidAlertSeverity < ::Exception; end
9
+ class InvalidCloudIntegrationId < ::Exception; end
10
+ class InvalidDashboardId < ::Exception; end
11
+ class InvalidEndpoint < ::Exception; end
12
+ class InvalidEventId < ::Exception; end
13
+ class InvalidExternalLinkId < ::Exception; end
14
+ class InvalidGranularity < ::Exception; end
15
+ class InvalidHostname < ::Exception; end
16
+ class InvalidMaintenanceWindowId < ::Exception; end
17
+ class InvalidMessageId < ::Exception; end
18
+ class InvalidMetricName < ::Exception; end
19
+ class InvalidMetricValue < ::Exception; end
20
+ class InvalidName < ::Exception; end
21
+ class InvalidPoint < ::Exception; end
22
+ class InvalidPrefixLength < ::Exception; end
23
+ class InvalidProxyId < ::Exception; end
24
+ class InvalidResponse < ::Exception; end
25
+ class InvalidSavedSearchId < ::Exception; end
26
+ class InvalidSavedSearchEntity < ::Exception; end
27
+ class InvalidSourceId < ::Exception; end
28
+ class InvalidString < ::Exception; end
29
+ class InvalidTag < ::Exception; end
30
+ class InvalidLinkTemplate < ::Exception; end
31
+ class InvalidTimeFormat < ::Exception; end
32
+ class InvalidTimestamp < ::Exception; end
33
+ class InvalidUserId < ::Exception; end
34
+ class InvalidWebhookId < ::Exception; end
35
+ class InvalidVersion < ::Exception; end
36
+ class NotImplemented < ::Exception; end
37
+ class ValueOutOfRange < ::Exception; end
38
+ end
39
+ end
@@ -0,0 +1,77 @@
1
+ require_relative './base'
2
+
3
+ module Wavefront
4
+ #
5
+ # Manage and query Wavefront external links.
6
+ #
7
+ class ExternalLink < Wavefront::Base
8
+ def api_base
9
+ '/extlink'
10
+ end
11
+
12
+ # GET /api/v2/extlink
13
+ # Get all external links for a customer
14
+ #
15
+ # @param offset [Int] link at which the list begins
16
+ # @param limit [Int] the number of link to return
17
+ #
18
+ def list(offset = 0, limit = 100)
19
+ api_get('', { offset: offset, limit: limit })
20
+ end
21
+
22
+ # POST /api/v2/extlink
23
+ # Create a specific external link.
24
+ #
25
+ # @param name [String] a plaintext name for the link
26
+ # @param template [String] a mustache template for the link target
27
+ # @param description [String] a plaintext description of the link
28
+ # @return [Hash]
29
+ #
30
+ def create(body)
31
+ raise ArgumentError unless body.is_a?(Hash)
32
+ api_post('', body, 'application/json')
33
+ end
34
+
35
+ # DELETE /api/v2/extlink/{id}
36
+ # Delete a specific external link.
37
+ #
38
+ # @param id [String] ID of the link
39
+ # @return [Hash]
40
+ #
41
+ def delete(id)
42
+ wf_link_id?(id)
43
+ api_delete(id)
44
+ end
45
+
46
+ # GET /api/v2/extlink/{id}
47
+ # Get a specific external link.
48
+ #
49
+ # @param id [String] ID of the limnk
50
+ # @return [Hash]
51
+ #
52
+ def describe(id)
53
+ wf_link_id?(id)
54
+ api_get(id)
55
+ end
56
+
57
+ # PUT /api/v2/extlink/{id}
58
+ # Update a specific external link.
59
+ #
60
+ # @param id [String] ID of the link
61
+ # @param payload [Hash] a key:value hash where the key is the
62
+ # property to change and the value is its desired value
63
+ # @return [Hash]
64
+ #
65
+ def update(id, body)
66
+ wf_link_id?(id)
67
+ raise ArgumentError unless body.is_a?(Hash)
68
+ api_put(id, body)
69
+ end
70
+ end
71
+
72
+ # A standard response.
73
+ #
74
+ class Response
75
+ class ExternalLink < Base; end
76
+ end
77
+ end
@@ -0,0 +1,75 @@
1
+ require_relative './base'
2
+
3
+ module Wavefront
4
+ #
5
+ # Manage and query Wavefront maintenance windows
6
+ #
7
+ class MaintenanceWindow < Wavefront::Base
8
+
9
+ # GET /api/v2/maintenancewindow
10
+ # Get all maintenance windows for a customer.
11
+ #
12
+ # @param offset [Integer] window at which the list begins
13
+ # @param limit [Integer] the number of window to return
14
+ #
15
+ def list(offset = 0, limit = 100)
16
+ api_get('', { offset: offset, limit: limit })
17
+ end
18
+
19
+ # POST /api/v2/maintenancewindow
20
+ # Create a maintenance window.
21
+ #
22
+ # We used to validate input here but do not any more.
23
+ #
24
+ # @param body [Hash] a hash of parameters describing the window.
25
+ # Please refer to the Wavefront Swagger docs for key:value
26
+ # information
27
+ # @return [Hash]
28
+ #
29
+ def create(body)
30
+ raise ArgumentError unless body.is_a?(Hash)
31
+ api_post('', body, 'application/json')
32
+ end
33
+
34
+ # DELETE /api/v2/maintenancewindow/{id}
35
+ # Delete a specific maintenance window.
36
+ #
37
+ # @param id [String, Integer] ID of the maintenance window
38
+ # @return [Hash]
39
+ #
40
+ def delete(id)
41
+ wf_maintenance_window_id?(id)
42
+ api_delete(id)
43
+ end
44
+
45
+ # GET /api/v2/maintenancewindow/{id}
46
+ # Get a specific maintenance window.
47
+ #
48
+ # @param id [String, Integer] ID of the maintenance window
49
+ # @return [Hash]
50
+ #
51
+ def describe(id)
52
+ wf_maintenance_window_id?(id)
53
+ api_get(id)
54
+ end
55
+
56
+ # PUT /api/v2/maintenancewindow/{id}
57
+ # Update a specific maintenance window.
58
+ #
59
+ # @param body [Hash] a hash of parameters describing the window.
60
+ # @return [Hash]
61
+ # @raise any validation errors from body
62
+ #
63
+ def update(id, body)
64
+ wf_maintenance_window_id?(id)
65
+ raise ArgumentError unless body.is_a?(Hash)
66
+ api_put(id, body)
67
+ end
68
+ end
69
+
70
+ # A standard response.
71
+ #
72
+ class Response
73
+ class MaintenanceWindow < Base; end
74
+ end
75
+ end
@@ -0,0 +1,36 @@
1
+ require_relative './base'
2
+
3
+ module Wavefront
4
+ #
5
+ # Manage and query Wavefront messages.
6
+ #
7
+ class Message < Wavefront::Base
8
+
9
+ # GET /api/v2/message
10
+ # Gets messages applicable to the current user, i.e. within time
11
+ # range and distribution scope
12
+ #
13
+ # @param offset [Int] agent at which the list begins
14
+ # @param limit [Int] the number of agents to return
15
+ #
16
+ def list(offset = 0, limit = 100, unread_only = true)
17
+ api_get('', { offset: offset, limit: limit, unreadOnly: unread_only })
18
+ end
19
+
20
+ # POST /api/v2/message/{id}/read
21
+ # Mark a specific message as read
22
+ #
23
+ # @param [id] message ID to mark as read
24
+ #
25
+ def read(id)
26
+ wf_message_id?(id)
27
+ api_post([id, 'read'].uri_concat)
28
+ end
29
+ end
30
+
31
+ # A standard response.
32
+ #
33
+ class Response
34
+ class Message < Base; end
35
+ end
36
+ end
@@ -0,0 +1,52 @@
1
+ require_relative './base'
2
+
3
+ module Wavefront
4
+ #
5
+ # Query Wavefront metrics.
6
+ #
7
+ class Metric < Wavefront::Base
8
+ def api_base
9
+ 'chart/metric'
10
+ end
11
+
12
+ # GET /api/v2/chart/metric/detail
13
+ # Get more details on a metric, including reporting sources and
14
+ # approximate last time reported
15
+ #
16
+ # @param offset [Int] agent at which the list begins
17
+ # @param limit [Int] the number of agents to return
18
+ #
19
+ def detail(metric, sources = [], cursor = nil)
20
+ raise ArgumentError unless metric.is_a?(String)
21
+ raise ArgumentError unless sources.is_a?(Array)
22
+
23
+ q = [[:m, metric]]
24
+
25
+ if cursor
26
+ raise ArgumentError unless cursor.is_a?(String)
27
+ q.<< [:c, cursor]
28
+ end
29
+
30
+ sources.each { |s| q.<< [:h, s] }
31
+
32
+ api_get('detail', q)
33
+ end
34
+ end
35
+
36
+ class Response
37
+
38
+ # The Metric response forges status and response methods to look
39
+ # like other classes and create a more consistent interface.
40
+ #
41
+ class Metric < Base
42
+ def populate(raw, status)
43
+ @response = Struct.new(*raw.keys).new(*raw.values).freeze
44
+
45
+ result = status == 200 ? 'OK' : 'ERROR'
46
+
47
+ @status = Struct.new(:result, :message, :code).
48
+ new(result, raw[:message] || raw[:error], status)
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,60 @@
1
+ require_relative './exception'
2
+
3
+ module Wavefront
4
+ module Mixins
5
+ # Return a time as an integer, however it might come in.
6
+ #
7
+ # @param t [Integer, String, Time] timestamp
8
+ # @param ms [Boolean] whether to return epoch milliseconds
9
+ # @return [Integer] epoch time in seconds
10
+ # @raise Wavefront::InvalidTimestamp
11
+ #
12
+ def parse_time(t, ms = false)
13
+ #
14
+ # Numbers, or things that look like numbers, pass straight
15
+ # through. No validation, because maybe the user means one
16
+ # second past the epoch, or the year 2525.
17
+ #
18
+ return t if t.is_a?(Integer)
19
+
20
+ if t.is_a?(String)
21
+ return t.to_i if t.match(/^\d+$/)
22
+ begin
23
+ t = DateTime.parse("#{t} #{Time.now.getlocal.zone}")
24
+ rescue
25
+ raise Wavefront::Exception::InvalidTimestamp
26
+ end
27
+ end
28
+
29
+ ms ? t.to_datetime.strftime('%Q').to_i : t.strftime('%s').to_i
30
+ end
31
+ end
32
+ end
33
+
34
+ # Extensions to the Hash class
35
+ #
36
+ class Hash
37
+
38
+ # Convert a tag hash into a string. The quoting is recommended in
39
+ # the WF wire-format guide. No validation is performed here.
40
+ #
41
+ def to_wf_tag
42
+ self.map { |k, v| "#{k}=\"#{v}\"" }.join(' ')
43
+ end
44
+ end
45
+
46
+ # Extensions to stdlib Array
47
+ #
48
+ class Array
49
+
50
+ # Join strings together to make a URI path in a way that is more
51
+ # flexible than URI::Join. Removes multiple and trailing
52
+ # separators. Does not have to produce fully qualified paths. Has
53
+ # no concept of protocols, hostnames, or query strings.
54
+ #
55
+ # @return [String] a URI path
56
+ #
57
+ def uri_concat
58
+ self.join('/').squeeze('/').sub(/\/$/, '').sub(/\/\?/, '?')
59
+ end
60
+ end
@@ -0,0 +1,95 @@
1
+ require_relative './base'
2
+
3
+ module Wavefront
4
+ #
5
+ # Manage and query Wavefront proxies.
6
+ #
7
+ class Proxy < Wavefront::Base
8
+
9
+ # GET /api/v2/proxy
10
+ # Get all proxies for a customer
11
+ #
12
+ # @param offset [Int] proxy at which the list begins
13
+ # @param limit [Int] the number of proxies to return
14
+ #
15
+ def list(offset = 0, limit = 100)
16
+ api_get('', { offset: offset, limit: limit })
17
+ end
18
+
19
+ # DELETE /api/v2/proxy/{id}
20
+ # Delete a specific proxy
21
+ #
22
+ # Deleting an active proxy moves it to 'trash', from where it
23
+ # can be restored with an #undelete operation. Deleting an proxy
24
+ # in 'trash' removes it for ever.
25
+ #
26
+ # @param id [String] ID of the proxy
27
+ # @return [Hash]
28
+ #
29
+ def delete(id)
30
+ wf_proxy_id?(id)
31
+ api_delete(id)
32
+ end
33
+
34
+ # GET /api/v2/proxy/{id}
35
+ # Get a specific proxy
36
+ #
37
+ # @param id [String] ID of the proxy
38
+ # @return [Hash]
39
+ #
40
+ def describe(id)
41
+ wf_proxy_id?(id)
42
+ api_get(id)
43
+ end
44
+
45
+ # POST /api/v2/proxy/{id}/undelete
46
+ # Undelete a specific proxy
47
+ #
48
+ # Move an proxy from 'trash' back into active service.
49
+ #
50
+ # @param id [String] ID of the proxy
51
+ # @return [Hash]
52
+ #
53
+ def undelete(id)
54
+ wf_proxy_id?(id)
55
+ api_post([id, 'undelete'].uri_concat)
56
+ end
57
+
58
+ # PUT /api/v2/proxy/{id}
59
+ # Update the name of a specific proxy
60
+ #
61
+ # Rename an proxy. This changes the human-readable name, not the
62
+ # unique identifier.
63
+ #
64
+ # @param id [String] ID of the proxy
65
+ # @param name [String] new name
66
+ # @return [Hash]
67
+ #
68
+ def rename(id, name)
69
+ wf_proxy_id?(id)
70
+ wf_string?(name)
71
+ update(id, {name: name})
72
+ end
73
+
74
+ # A generic function to change properties of an proxy. So far as I
75
+ # know, only the 'name' property can currently be changed, and we
76
+ # supply a dedicated #rename method for that.
77
+ #
78
+ # @param id [String] ID of the proxy
79
+ # @param payload [Hash] a key: value hash, where the key is the
80
+ # property to change and the value is its desired value. No
81
+ # validation is performed on any part of the payload.
82
+ # @return [Hash]
83
+ #
84
+ def update(id, payload)
85
+ wf_proxy_id?(id)
86
+ api_put(id, payload)
87
+ end
88
+ end
89
+
90
+ # A standard response
91
+ #
92
+ class Response
93
+ class Proxy < Base; end
94
+ end
95
+ end
@@ -0,0 +1,96 @@
1
+ require_relative './base'
2
+
3
+ module Wavefront
4
+ #
5
+ # Query Wavefront metrics.
6
+ #
7
+ class Query < Wavefront::Base
8
+ def api_base
9
+ 'chart'
10
+ end
11
+
12
+ # GET /api/v2/chart/api
13
+ # Perform a charting query against Wavefront servers that
14
+ # returns the appropriate points in the specified time window
15
+ # and granularity. Any options can be pased through in the
16
+ # options hash. This means the SDK does not have to closely
17
+ # track the API, but also means the burden of data validation is
18
+ # down to the user.
19
+ #
20
+ # @param query [String] Wavefront query to run
21
+ # @param granularity [String] the required granularity for the
22
+ # reported data
23
+ # @param t_start [Time, Integer] The start of the query window.
24
+ # May be a Ruby Time object, or epoch milliseconds
25
+ # @param t_end [Time, Integer] The end of the query window.
26
+ # May be a Ruby Time object, or epoch milliseconds.
27
+ # @param options [Hash] any other options defined in the API
28
+ #
29
+ def query(query, granularity = nil, t_start = nil, t_end = nil,
30
+ options = {})
31
+
32
+ raise ArgumentError unless query.is_a?(String)
33
+ wf_granularity?(granularity)
34
+ raise Wavefront::Exception::InvalidTimestamp if t_start.nil?
35
+
36
+ options[:q] = query
37
+ options[:g] = granularity
38
+ options[:s] = parse_time(t_start, true)
39
+ options[:e] = parse_time(t_end, true) if t_end
40
+
41
+ options.delete_if do |k, v|
42
+ v == false && k != :i
43
+ end
44
+
45
+ api_get('api', options)
46
+ end
47
+
48
+ # GET /api/v2/chart/raw
49
+ # Perform a raw data query against Wavefront servers that
50
+ # returns second granularity points grouped by tags
51
+ #
52
+ # @param metric [String] metric to query ingested points for
53
+ # (cannot contain wildcards)
54
+ # @param source [String] source to query ingested points for
55
+ # (cannot contain wildcards).
56
+ # @param t_start [Time, Integer] start time of window: defaults
57
+ # to one hour before t_end
58
+ # @param t_start [Time, Integer] start time of window: defaults
59
+ # to now
60
+ #
61
+ def raw(metric, source = nil, t_start = nil, t_end = nil)
62
+ raise ArgumentError unless metric.is_a?(String)
63
+
64
+ options = { metric: metric, }
65
+
66
+ if source
67
+ wf_source_id?(source)
68
+ options[:source] = source
69
+ end
70
+
71
+ options[:startTime] = parse_time(t_start, true) if t_start
72
+ options[:endTime] = parse_time(t_end, true) if t_end
73
+
74
+ api_get('raw', options)
75
+ end
76
+ end
77
+
78
+ class Response
79
+
80
+ # The Query response forges status and response methods to look
81
+ # like other classes and create a more consistent interface
82
+ #
83
+ class Query < Base
84
+ def populate(raw, status)
85
+ @response = Struct.new(*raw.keys).new(*raw.values).freeze
86
+
87
+ result = status == 200 ? 'OK' : 'ERROR'
88
+
89
+ if raw.key?(:warnings) || raw.key?(:error)
90
+ @status = Struct.new(:result, :message, :code).
91
+ new(result, raw[:message] || raw[:error], status)
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end