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.
- checksums.yaml +7 -0
- data/.codeclimate.yml +20 -0
- data/.gitignore +4 -0
- data/.rubocop.yml +1157 -0
- data/.travis.yml +16 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +58 -0
- data/LICENSE.txt +27 -0
- data/README.md +103 -0
- data/Rakefile +18 -0
- data/lib/wavefront-sdk/alert.rb +195 -0
- data/lib/wavefront-sdk/base.rb +251 -0
- data/lib/wavefront-sdk/cloudintegration.rb +88 -0
- data/lib/wavefront-sdk/credentials.rb +79 -0
- data/lib/wavefront-sdk/dashboard.rb +157 -0
- data/lib/wavefront-sdk/event.rb +173 -0
- data/lib/wavefront-sdk/exception.rb +39 -0
- data/lib/wavefront-sdk/externallink.rb +77 -0
- data/lib/wavefront-sdk/maintenancewindow.rb +75 -0
- data/lib/wavefront-sdk/message.rb +36 -0
- data/lib/wavefront-sdk/metric.rb +52 -0
- data/lib/wavefront-sdk/mixins.rb +60 -0
- data/lib/wavefront-sdk/proxy.rb +95 -0
- data/lib/wavefront-sdk/query.rb +96 -0
- data/lib/wavefront-sdk/response.rb +56 -0
- data/lib/wavefront-sdk/savedsearch.rb +88 -0
- data/lib/wavefront-sdk/search.rb +58 -0
- data/lib/wavefront-sdk/source.rb +131 -0
- data/lib/wavefront-sdk/user.rb +108 -0
- data/lib/wavefront-sdk/validators.rb +395 -0
- data/lib/wavefront-sdk/version.rb +1 -0
- data/lib/wavefront-sdk/webhook.rb +73 -0
- data/lib/wavefront-sdk/write.rb +225 -0
- data/pkg/wavefront-client-3.5.0.gem +0 -0
- data/spec/.rubocop.yml +14 -0
- data/spec/spec_helper.rb +157 -0
- data/spec/wavefront-sdk/alert_spec.rb +83 -0
- data/spec/wavefront-sdk/base_spec.rb +88 -0
- data/spec/wavefront-sdk/cloudintegration_spec.rb +54 -0
- data/spec/wavefront-sdk/credentials_spec.rb +55 -0
- data/spec/wavefront-sdk/dashboard_spec.rb +74 -0
- data/spec/wavefront-sdk/event_spec.rb +83 -0
- data/spec/wavefront-sdk/externallink_spec.rb +65 -0
- data/spec/wavefront-sdk/maintenancewindow_spec.rb +48 -0
- data/spec/wavefront-sdk/message_spec.rb +19 -0
- data/spec/wavefront-sdk/metric_spec.rb +21 -0
- data/spec/wavefront-sdk/mixins_spec.rb +27 -0
- data/spec/wavefront-sdk/proxy_spec.rb +41 -0
- data/spec/wavefront-sdk/query_spec.rb +51 -0
- data/spec/wavefront-sdk/resources/test.conf +10 -0
- data/spec/wavefront-sdk/response_spec.rb +47 -0
- data/spec/wavefront-sdk/savedsearch_spec.rb +54 -0
- data/spec/wavefront-sdk/search_spec.rb +47 -0
- data/spec/wavefront-sdk/source_spec.rb +48 -0
- data/spec/wavefront-sdk/user_spec.rb +56 -0
- data/spec/wavefront-sdk/validators_spec.rb +238 -0
- data/spec/wavefront-sdk/webhook_spec.rb +50 -0
- data/spec/wavefront-sdk/write_spec.rb +167 -0
- data/wavefront-sdk.gemspec +34 -0
- metadata +269 -0
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'json'
|
2
|
+
require_relative './exception'
|
3
|
+
|
4
|
+
module Wavefront
|
5
|
+
|
6
|
+
# Every API path has its own response class, which allows us to
|
7
|
+
# provide a stable interface. If the API changes underneath us,
|
8
|
+
# the SDK will break in a predictable way, throwing a
|
9
|
+
# Wavefront::Exception::InvalidResponse exception.
|
10
|
+
#
|
11
|
+
# Most Wavefront::Response classes present the returned data in
|
12
|
+
# two parts, each accessible by dot notation.
|
13
|
+
# #status is the status object, which normally contains
|
14
|
+
# 'result', 'message', and 'code'. It is a struct.
|
15
|
+
# #response contains the JSON response body, turned into a Ruby
|
16
|
+
# hash.
|
17
|
+
#
|
18
|
+
class Response
|
19
|
+
class Base
|
20
|
+
attr_reader :status, :response, :debug
|
21
|
+
|
22
|
+
# Create and return a Wavefront::Response object
|
23
|
+
# @param json [String] a raw response body from the Wavefront API
|
24
|
+
# @param status [Integer] HTTP return code from the API
|
25
|
+
# @param debug [Boolean] whether or not to print the exception
|
26
|
+
# message if one is thrown
|
27
|
+
# @raise Wavefront::InvalidResponse if the response cannot be
|
28
|
+
# parsed
|
29
|
+
# @return a Wavefront::Response object
|
30
|
+
#
|
31
|
+
def initialize(json, status, debug = false)
|
32
|
+
@debug = debug
|
33
|
+
populate(JSON.parse(json, symbolize_names: true), status)
|
34
|
+
rescue => e
|
35
|
+
puts e.message if debug
|
36
|
+
raise Wavefront::Exception::InvalidResponse
|
37
|
+
end
|
38
|
+
|
39
|
+
def populate(raw, _status = 200)
|
40
|
+
if raw.key?(:status)
|
41
|
+
@status = Struct.new(*raw[:status].keys).
|
42
|
+
new(*raw[:status].values).freeze
|
43
|
+
end
|
44
|
+
|
45
|
+
if raw.key?(:response)
|
46
|
+
if raw[:response].key?(:items)
|
47
|
+
@response = Struct.new(*raw[:response].keys).
|
48
|
+
new(*raw[:response].values).freeze
|
49
|
+
else
|
50
|
+
@response = raw[:response]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require_relative './base'
|
2
|
+
|
3
|
+
module Wavefront
|
4
|
+
#
|
5
|
+
# View and manage Cloud Integrations. These are identified by
|
6
|
+
# a UUID.
|
7
|
+
#
|
8
|
+
class SavedSearch < Wavefront::Base
|
9
|
+
|
10
|
+
# GET /api/v2/savedsearch
|
11
|
+
# Get all saved searches for a user.
|
12
|
+
#
|
13
|
+
# @param offset [Int] saved search at which the list begins
|
14
|
+
# @param limit [Int] the number of saved searches to return
|
15
|
+
# @return [Hash]
|
16
|
+
#
|
17
|
+
def list(offset = 0, limit = 100)
|
18
|
+
api_get('', { offset: offset, limit: limit })
|
19
|
+
end
|
20
|
+
|
21
|
+
# POST /api/v2/savedsearch
|
22
|
+
# Create a saved search. Refer to the Swagger API docs for
|
23
|
+
# valid keys.
|
24
|
+
#
|
25
|
+
# @param body [Hash] description of saved search
|
26
|
+
# @return [Hash]
|
27
|
+
#
|
28
|
+
def create(body)
|
29
|
+
raise ArgumentError unless body.is_a?(Hash)
|
30
|
+
api_post('', body, 'application/json')
|
31
|
+
end
|
32
|
+
|
33
|
+
# DELETE /api/v2/savedsearch/{id}
|
34
|
+
# Delete a specific saved search.
|
35
|
+
#
|
36
|
+
# @param id [String] ID of the saved search
|
37
|
+
# @return [Hash]
|
38
|
+
#
|
39
|
+
def delete(id)
|
40
|
+
wf_savedsearch_id?(id)
|
41
|
+
api_delete(id)
|
42
|
+
end
|
43
|
+
|
44
|
+
# GET /api/v2/savedsearch/{id}
|
45
|
+
# Get a specific saved search.
|
46
|
+
#
|
47
|
+
# @param id [String] ID of the saved search
|
48
|
+
# @return [Hash]
|
49
|
+
#
|
50
|
+
def describe(id)
|
51
|
+
wf_savedsearch_id?(id)
|
52
|
+
api_get(id)
|
53
|
+
end
|
54
|
+
|
55
|
+
# PUT /api/v2/savedsearch/{id}
|
56
|
+
# Update a specific saved search.
|
57
|
+
#
|
58
|
+
# @param id [String] ID of the saved search
|
59
|
+
# @param body [Hash] description of saved search
|
60
|
+
#
|
61
|
+
def update(id, body)
|
62
|
+
wf_savedsearch_id?(id)
|
63
|
+
raise ArgumentError unless body.is_a?(Hash)
|
64
|
+
api_put(id, body)
|
65
|
+
end
|
66
|
+
|
67
|
+
# GET /api/v2/savedsearch/type/{entitytype}
|
68
|
+
# Get all saved searches for a specific entity type for a user.
|
69
|
+
#
|
70
|
+
# @param entitytype [String] type of entity to retrieve
|
71
|
+
# @param offset [Int] saved search at which the list begins
|
72
|
+
# @param limit [Int] the number of saved searches to return
|
73
|
+
# @return [Hash]
|
74
|
+
#
|
75
|
+
def entity(entitytype, offset = 0, limit = 100)
|
76
|
+
wf_savedsearch_entity?(entitytype)
|
77
|
+
api_get(['type', entitytype].uri_concat, { offset: offset,
|
78
|
+
limit: limit })
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# A standard response
|
84
|
+
#
|
85
|
+
class Response
|
86
|
+
class SavedSearch < Base; end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require_relative './base'
|
2
|
+
|
3
|
+
module Wavefront
|
4
|
+
#
|
5
|
+
# Manage and query Wavefront searches. The /search API path has a
|
6
|
+
# lot of paths, with a lot of duplication. The current state of
|
7
|
+
# this class covers the whole API with two methods, but leaves a
|
8
|
+
# lot up to the user. It may grow, with convenience methods.
|
9
|
+
#
|
10
|
+
class Search < Wavefront::Base
|
11
|
+
|
12
|
+
# POST /api/v2/search/agent
|
13
|
+
# POST /api/v2/search/agent/deleted
|
14
|
+
# Run a search query. This single method maps to many API paths.
|
15
|
+
#
|
16
|
+
# @param entity [String] the type of Wavefront object you wish
|
17
|
+
# to search
|
18
|
+
# @param body [Hash] the query to use for searching. Refer to
|
19
|
+
# the Wavefront Swagger docs for the correct format.
|
20
|
+
# @param deleted [Boolean] whether to search deleted (true) or
|
21
|
+
# active (false) entities
|
22
|
+
#
|
23
|
+
def search(entity = nil, body = nil, deleted = false)
|
24
|
+
raise ArgumentError unless entity.is_a?(String)
|
25
|
+
raise ArgumentError unless body.is_a?(Hash)
|
26
|
+
path = ['agent']
|
27
|
+
path.<< 'deleted' if deleted
|
28
|
+
api_post(path, body, 'application/json')
|
29
|
+
end
|
30
|
+
|
31
|
+
# @param entity [String] the type of Wavefront object you wish
|
32
|
+
# to search
|
33
|
+
# @param body [Hash] the query to use for searching. Refer to
|
34
|
+
# the Wavefront Swagger docs for the correct format.
|
35
|
+
# @param deleted [Boolean] whether to search deleted (true) or
|
36
|
+
# active (false) entities
|
37
|
+
# @param facet [String] the facet on which to search. If this is
|
38
|
+
# false, the assumption is that multiple facets will be
|
39
|
+
# specified in the body. See the Swagger docs for more
|
40
|
+
# information.
|
41
|
+
#
|
42
|
+
def facet_search(entity = nil, body = nil, deleted = false,
|
43
|
+
facet = false)
|
44
|
+
raise ArgumentError unless entity.is_a?(String)
|
45
|
+
raise ArgumentError unless body.is_a?(Hash)
|
46
|
+
path = ['agent']
|
47
|
+
path.<< 'deleted' if deleted
|
48
|
+
path.<< facet ? facet : 'facets'
|
49
|
+
api_post(path, body, 'application/json')
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# A standard response
|
54
|
+
#
|
55
|
+
class Response
|
56
|
+
class Search < Base; end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
require_relative './base'
|
2
|
+
|
3
|
+
module Wavefront
|
4
|
+
#
|
5
|
+
# View and manage source metadata.
|
6
|
+
#
|
7
|
+
class Source < Wavefront::Base
|
8
|
+
|
9
|
+
# GET /api/v2/source
|
10
|
+
# Get all sources for a customer
|
11
|
+
#
|
12
|
+
# @param offset [Int] source at which the list begins
|
13
|
+
# @param limit [Int] the number of sources to return
|
14
|
+
# @return [Hash]
|
15
|
+
#
|
16
|
+
def list(offset = 0, limit = 100)
|
17
|
+
api_get('', { offset: offset, limit: limit })
|
18
|
+
end
|
19
|
+
|
20
|
+
# POST /api/v2/source
|
21
|
+
# Create metadata (description or tags) for a specific source.
|
22
|
+
#
|
23
|
+
# Refer to the Swagger API docs for valid keys.
|
24
|
+
#
|
25
|
+
# @param body [Hash] description of source
|
26
|
+
# @return [Hash]
|
27
|
+
#
|
28
|
+
def create(body)
|
29
|
+
raise ArgumentError unless body.is_a?(Hash)
|
30
|
+
api_post('', body, 'application/json')
|
31
|
+
end
|
32
|
+
|
33
|
+
# DELETE /api/v2/source/{id}
|
34
|
+
# Delete metadata (description and tags) for a specific source.
|
35
|
+
#
|
36
|
+
# @param id [String] ID of the source
|
37
|
+
# @return [Hash]
|
38
|
+
#
|
39
|
+
def delete(id)
|
40
|
+
wf_source_id?(id)
|
41
|
+
api_delete(id)
|
42
|
+
end
|
43
|
+
|
44
|
+
# GET /api/v2/source/{id}
|
45
|
+
# Get a specific source for a customer.
|
46
|
+
#
|
47
|
+
# @param id [String] ID of the source
|
48
|
+
# @return [Hash]
|
49
|
+
#
|
50
|
+
def describe(id, version = nil)
|
51
|
+
wf_source_id?(id)
|
52
|
+
wf_version?(version) if version
|
53
|
+
fragments = [id]
|
54
|
+
fragments += ['history', version] if version
|
55
|
+
api_get(fragments.uri_concat)
|
56
|
+
end
|
57
|
+
|
58
|
+
# PUT /api/v2/source/{id}
|
59
|
+
# Update metadata (description or tags) for a specific source.
|
60
|
+
#
|
61
|
+
# Refer to the Swagger API docs for valid keys.
|
62
|
+
#
|
63
|
+
# @param body [Hash] description of source
|
64
|
+
# @return [Hash]
|
65
|
+
#
|
66
|
+
def update(id, body)
|
67
|
+
wf_source_id?(id)
|
68
|
+
raise ArgumentError unless body.is_a?(Hash)
|
69
|
+
api_put(id, body)
|
70
|
+
end
|
71
|
+
|
72
|
+
# GET /api/v2/source/{id}/tag
|
73
|
+
# Get all tags associated with a specific source.
|
74
|
+
#
|
75
|
+
# @param id [String] ID of the source
|
76
|
+
# @returns [Hash] object describing the source with status and
|
77
|
+
# response keys
|
78
|
+
#
|
79
|
+
def tags(id)
|
80
|
+
wf_source_id?(id)
|
81
|
+
api_get([id, 'tag'].uri_concat)
|
82
|
+
end
|
83
|
+
|
84
|
+
# POST /api/v2/source/{id}/tag
|
85
|
+
# Set all tags associated with a specific source.
|
86
|
+
#
|
87
|
+
# @param id [String] ID of the source
|
88
|
+
# @param tags [Array] list of tags to set.
|
89
|
+
# @returns [Hash] object describing the source with status and
|
90
|
+
# response keys
|
91
|
+
#
|
92
|
+
def tag_set(id, tags)
|
93
|
+
wf_source_id?(id)
|
94
|
+
tags = Array(tags)
|
95
|
+
tags.each { |t| wf_string?(t) }
|
96
|
+
api_post([id, 'tag'].uri_concat, tags.to_json, 'application/json')
|
97
|
+
end
|
98
|
+
|
99
|
+
# DELETE /api/v2/source/{id}/tag/{tagValue}
|
100
|
+
# Remove a tag from a specific source.
|
101
|
+
#
|
102
|
+
# @param id [String] ID of the source
|
103
|
+
# @param tag [String] tag to delete
|
104
|
+
# @returns [Hash] object with 'status' key and empty 'repsonse'
|
105
|
+
#
|
106
|
+
def tag_delete(id, tag)
|
107
|
+
wf_source_id?(id)
|
108
|
+
wf_string?(tag)
|
109
|
+
api_delete([id, 'tag', tag].uri_concat)
|
110
|
+
end
|
111
|
+
|
112
|
+
# PUT /api/v2/source/{id}/tag/{tagValue}
|
113
|
+
# Add a tag to a specific source
|
114
|
+
#
|
115
|
+
# @param id [String] ID of the source
|
116
|
+
# @param tag [String] tag to set.
|
117
|
+
# @returns [Hash] object with 'status' key and empty 'repsonse'
|
118
|
+
#
|
119
|
+
def tag_add(id, tag)
|
120
|
+
wf_source_id?(id)
|
121
|
+
wf_string?(tag)
|
122
|
+
api_put([id, 'tag', tag].uri_concat)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
# A standard response
|
127
|
+
#
|
128
|
+
class Response
|
129
|
+
class Source < Base; end
|
130
|
+
end
|
131
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require_relative './base'
|
2
|
+
|
3
|
+
module Wavefront
|
4
|
+
#
|
5
|
+
# Manage and query Wavefront users
|
6
|
+
#
|
7
|
+
class User < Wavefront::Base
|
8
|
+
|
9
|
+
# GET /api/v2/user
|
10
|
+
# Get all users.
|
11
|
+
#
|
12
|
+
def list
|
13
|
+
api_get('')
|
14
|
+
end
|
15
|
+
|
16
|
+
# POST /api/v2/user
|
17
|
+
# Creates or updates a user
|
18
|
+
#
|
19
|
+
# @param body [Hash] a hash of parameters describing the user.
|
20
|
+
# Please refer to the Wavefront Swagger docs for key:value
|
21
|
+
# information
|
22
|
+
# @return [Hash]
|
23
|
+
#
|
24
|
+
def create(body, send_email = false)
|
25
|
+
raise ArgumentError unless body.is_a?(Hash)
|
26
|
+
api_post("?sendEmail=#{send_email}", body, 'application/json')
|
27
|
+
end
|
28
|
+
|
29
|
+
# DELETE /api/v2/user/{id}
|
30
|
+
# Delete a specific user.
|
31
|
+
#
|
32
|
+
# @param id [String] ID of the user
|
33
|
+
# @return [Hash]
|
34
|
+
#
|
35
|
+
def delete(id)
|
36
|
+
wf_user_id?(id)
|
37
|
+
api_delete(id)
|
38
|
+
end
|
39
|
+
|
40
|
+
# GET /api/v2/user/{id}
|
41
|
+
# Retrieves a user by identifier (email addr).
|
42
|
+
#
|
43
|
+
# @param id [String] ID of the user
|
44
|
+
# @return [Hash]
|
45
|
+
#
|
46
|
+
def describe(id)
|
47
|
+
wf_user_id?(id)
|
48
|
+
api_get(id)
|
49
|
+
end
|
50
|
+
|
51
|
+
# PUT /api/v2/user/{id}/grant
|
52
|
+
# Grants a specific user permission.
|
53
|
+
#
|
54
|
+
# @param id [String] ID of the user
|
55
|
+
# @param group [String] group to add user to. We do not validate
|
56
|
+
# this so that changes to the API do not mandate changes to
|
57
|
+
# the SDK. At the time of writing, valid values are browse,
|
58
|
+
# agent_management, alerts_management, dashboard_management,
|
59
|
+
# embedded_charts, events_management,
|
60
|
+
# external_links_management, host_tag_management,
|
61
|
+
# metrics_management, user_management,
|
62
|
+
# @return [Hash]
|
63
|
+
#
|
64
|
+
def grant(id, group)
|
65
|
+
wf_user_id?(id)
|
66
|
+
raise ArgumentError unless group.is_a?(String)
|
67
|
+
api_post([id, 'grant'].uri_concat, "group=#{group}",
|
68
|
+
'application/x-www-form-urlencoded')
|
69
|
+
end
|
70
|
+
|
71
|
+
# PUT /api/v2/user/{id}/revoke
|
72
|
+
# Revokes a specific user permission.
|
73
|
+
#
|
74
|
+
# @param id [String] ID of the user
|
75
|
+
# @param group [String] group to add user to. We do not validate
|
76
|
+
# this so that changes to the API do not mandate changes to
|
77
|
+
# the SDK. See #update for valid values.
|
78
|
+
# @return [Hash]
|
79
|
+
#
|
80
|
+
def revoke(id, group)
|
81
|
+
wf_user_id?(id)
|
82
|
+
raise ArgumentError unless group.is_a?(String)
|
83
|
+
api_post([id, 'revoke'].uri_concat, "group=#{group}",
|
84
|
+
'application/x-www-form-urlencoded')
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
class Response
|
89
|
+
|
90
|
+
# The User response forges status and response methods to look
|
91
|
+
# like other classes and create a more consistent interface.
|
92
|
+
#
|
93
|
+
class User < Base
|
94
|
+
def populate(raw, status)
|
95
|
+
@response = if raw.is_a?(Array)
|
96
|
+
Struct.new(:items).new(raw).freeze
|
97
|
+
elsif raw.is_a?(Hash)
|
98
|
+
Struct.new(*raw.keys).new(*raw.values).freeze
|
99
|
+
end
|
100
|
+
|
101
|
+
result = status == 200 ? 'OK' : 'ERROR'
|
102
|
+
|
103
|
+
@status = Struct.new(:result, :message, :code).
|
104
|
+
new(result, nil, status)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,395 @@
|
|
1
|
+
require_relative './exception'
|
2
|
+
|
3
|
+
module Wavefront
|
4
|
+
#
|
5
|
+
# A module of mixins to validate input. The Wavefront documentation
|
6
|
+
# lays down restrictions on types and sizes of various inputs, which
|
7
|
+
# we will check on the user's behalf. Most of the information used in
|
8
|
+
# this file comes from https://community.wavefront.com/docs/DOC-1031
|
9
|
+
# Some comes from the Swagger API documentation, some has come
|
10
|
+
# directly from Wavefront engineers.
|
11
|
+
#
|
12
|
+
module Validators
|
13
|
+
|
14
|
+
# Ensure the given argument is a valid external link template
|
15
|
+
#
|
16
|
+
# @return true if it is valid
|
17
|
+
# @raise Wavefront::Exception::InvalidTemplate if not
|
18
|
+
#
|
19
|
+
def wf_link_template?(v)
|
20
|
+
if v.is_a?(String) && (v.start_with?('http://') ||
|
21
|
+
v.start_with?('https://'))
|
22
|
+
return true
|
23
|
+
end
|
24
|
+
|
25
|
+
raise Wavefront::Exception::InvalidLinkTemplate
|
26
|
+
end
|
27
|
+
|
28
|
+
# Ensure the given argument is a valid Wavefront metric name, or
|
29
|
+
# path.
|
30
|
+
#
|
31
|
+
# @param v [String] the metric name to validate
|
32
|
+
# @return True if the metric name is valid
|
33
|
+
# @raise Wavefront::Exception::InvalidMetricName if metric name
|
34
|
+
# is not valid.
|
35
|
+
#
|
36
|
+
def wf_metric_name?(v)
|
37
|
+
if v.is_a?(String) && v.size < 1024 &&
|
38
|
+
(v.match(/^[\w\-\.]+$/) || v.match(%r{^\"[\w\-\.\/,]+\"$}))
|
39
|
+
return true
|
40
|
+
end
|
41
|
+
|
42
|
+
raise Wavefront::Exception::InvalidMetricName
|
43
|
+
end
|
44
|
+
|
45
|
+
# Ensure the given argument is a valid name, for instance for an
|
46
|
+
# event. Names can contain, AFAIK, word characters.
|
47
|
+
#
|
48
|
+
# @param v [String] the name to validate
|
49
|
+
# @return true if the name is valid
|
50
|
+
# raise Wavefront::Exception::InvalidName if name is not valid
|
51
|
+
#
|
52
|
+
def wf_name?(v)
|
53
|
+
return true if v.is_a?(String) && v.size < 1024 && v =~ /^\w+$/
|
54
|
+
raise Wavefront::Exception::InvalidName
|
55
|
+
end
|
56
|
+
|
57
|
+
# Ensure the given argument is a valid string, for a tag name.
|
58
|
+
#
|
59
|
+
# @param v [String] the string name to validate
|
60
|
+
# @return True if the string is valid
|
61
|
+
# @raise Wavefront::Exception::InvalidString if string is not valid.
|
62
|
+
#
|
63
|
+
def wf_string?(v)
|
64
|
+
#
|
65
|
+
# Only allows PCRE "word" characters, spaces, full-stops and
|
66
|
+
# commas in tags and descriptions. This might be too restrictive,
|
67
|
+
# but if it is, this is the only place we need to change it.
|
68
|
+
#
|
69
|
+
return true if v.is_a?(String) && v.size < 1024 && v =~ /^[\-\w \.,]*$/
|
70
|
+
|
71
|
+
raise Wavefront::Exception::InvalidString
|
72
|
+
end
|
73
|
+
|
74
|
+
# Ensure the given argument is a valid timestamp
|
75
|
+
#
|
76
|
+
# @param v [DateTime] the timestamp name to validate
|
77
|
+
# @return True if the value is valid
|
78
|
+
# @raise Wavefront::Exception::InvalidTimestamp
|
79
|
+
#
|
80
|
+
def wf_ts?(v)
|
81
|
+
return true if v.is_a?(Time) || v.is_a?(Date)
|
82
|
+
raise Wavefront::Exception::InvalidTimestamp
|
83
|
+
end
|
84
|
+
|
85
|
+
# Ensure the given argument is a valid millisecond epoch
|
86
|
+
# timestamp. We do no checking of the value, because who am I to
|
87
|
+
# say that the user doesn't want to send a point relating to 1ms
|
88
|
+
# after the epoch, or a thousand years in the future?
|
89
|
+
#
|
90
|
+
# @param v [Integer] the timestamp name to validate
|
91
|
+
# @return True if the value is valid
|
92
|
+
# @raise Wavefront::Exception::InvalidTimestamp
|
93
|
+
#
|
94
|
+
def wf_ms_ts?(v)
|
95
|
+
return true if v.is_a?(Numeric)
|
96
|
+
raise Wavefront::Exception::InvalidTimestamp
|
97
|
+
end
|
98
|
+
|
99
|
+
# Ensure the given argument is a valid epoch timestamp. Again,
|
100
|
+
# no range checking.
|
101
|
+
#
|
102
|
+
# @param v [String, Integer]
|
103
|
+
# @return True if the timestamp is valid
|
104
|
+
# @raise Wavefront::Exception::InvalidMaintenanceWindow
|
105
|
+
#
|
106
|
+
def wf_epoch?(v)
|
107
|
+
return true if v.is_a?(Numeric)
|
108
|
+
raise Wavefront::Exception::InvalidTimestamp
|
109
|
+
end
|
110
|
+
|
111
|
+
# Ensure one, or an array, of tags are valid. These tags are
|
112
|
+
# used as source tags, or tags for maintenance windows etc. They
|
113
|
+
# can contain letters, numbers, -, _ and :, and must be less
|
114
|
+
# than 256 characters long
|
115
|
+
#
|
116
|
+
# @param v [String, Array] a tag or list of tags
|
117
|
+
# @return True if all tags are valid
|
118
|
+
# @raise Wavefront::Exception::InvalidTag
|
119
|
+
#
|
120
|
+
def wf_tag?(*v)
|
121
|
+
Array(*v).each do |t|
|
122
|
+
unless t.is_a?(String) && t.size < 255 && t =~ /^[\w:\-\.]+$/
|
123
|
+
raise Wavefront::Exception::InvalidTag
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
true
|
128
|
+
end
|
129
|
+
|
130
|
+
# Ensure the given argument is a valid Wavefront value. Can be
|
131
|
+
# any form of Numeric, including standard notation.
|
132
|
+
#
|
133
|
+
# @param v [Numeric] the source name to validate
|
134
|
+
# @return True if the value is valid
|
135
|
+
# @raise Wavefront::Exception::InvalidValue if the value is not valid
|
136
|
+
#
|
137
|
+
def wf_value?(v)
|
138
|
+
return true if v.is_a?(Numeric)
|
139
|
+
raise Wavefront::Exception::InvalidMetricValue
|
140
|
+
end
|
141
|
+
|
142
|
+
# Ensure the given argument is a valid version number
|
143
|
+
#
|
144
|
+
# @param [Integer] the version number to validate
|
145
|
+
# @return True if the version is valid
|
146
|
+
# @raise Wavefront::Exception::InvalidVersion if the alert ID is
|
147
|
+
# not valid
|
148
|
+
#
|
149
|
+
def wf_version?(v)
|
150
|
+
v = v.to_i if v.is_a?(String) && v =~ /^\d+$/
|
151
|
+
return true if v.is_a?(Integer) && v > 0
|
152
|
+
raise Wavefront::Exception::InvalidVersion
|
153
|
+
end
|
154
|
+
|
155
|
+
# Ensure a hash of key:value point tags are value. Not to be
|
156
|
+
# confused with source tags.
|
157
|
+
#
|
158
|
+
# @param tags [Hash] a hash of key:value tags
|
159
|
+
# @return True if all tags are valid
|
160
|
+
# @raise Wavefront::Exception::InvalidTag if any tags in the has
|
161
|
+
# do not validate
|
162
|
+
#
|
163
|
+
def wf_point_tags?(tags)
|
164
|
+
raise Wavefront::Exception::InvalidTag unless tags.is_a?(Hash)
|
165
|
+
|
166
|
+
tags.each do |k, v|
|
167
|
+
unless (k.size + v.size < 254) && k.match(/^[\w\-\.:]+$/)
|
168
|
+
raise Wavefront::Exception::InvalidTag
|
169
|
+
end
|
170
|
+
end
|
171
|
+
true
|
172
|
+
end
|
173
|
+
|
174
|
+
# Ensure the given argument is a valid Wavefront proxy ID
|
175
|
+
#
|
176
|
+
# @param v [String] the proxy ID to validate
|
177
|
+
# @return True if the proxy ID is valid
|
178
|
+
# @raise Wavefront::Exception::InvalidProxyId if the proxy ID
|
179
|
+
# is not valid
|
180
|
+
#
|
181
|
+
def wf_proxy_id?(v)
|
182
|
+
if v.is_a?(String) && v.match(
|
183
|
+
/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/
|
184
|
+
)
|
185
|
+
return true
|
186
|
+
end
|
187
|
+
|
188
|
+
raise Wavefront::Exception::InvalidProxyId
|
189
|
+
end
|
190
|
+
|
191
|
+
# Ensure the given argument is a valid Wavefront alert ID.
|
192
|
+
# Alerts are identified by the epoch-nanosecond at which they
|
193
|
+
# were created.
|
194
|
+
#
|
195
|
+
# @param v [String] the alert ID to validate
|
196
|
+
# @return True if the alert ID is valid
|
197
|
+
# @raise Wavefront::Exception::InvalidAlertId if the alert ID is
|
198
|
+
# not valid
|
199
|
+
#
|
200
|
+
def wf_alert_id?(v)
|
201
|
+
v = v.to_s if v.is_a?(Numeric)
|
202
|
+
return true if v.is_a?(String) && v.match(/^\d{13}$/)
|
203
|
+
raise Wavefront::Exception::InvalidAlertId
|
204
|
+
end
|
205
|
+
|
206
|
+
# Ensure the given argument is a valid Wavefront cloud
|
207
|
+
# integration ID
|
208
|
+
#
|
209
|
+
# @param v [String] the integration name to validate
|
210
|
+
# @return True if the integration name is valid
|
211
|
+
# @raise Wavefront::Exception::InvalidCloudIntegrationId if the
|
212
|
+
# integration ID is not valid
|
213
|
+
#
|
214
|
+
def wf_cloudintegration_id?(v)
|
215
|
+
if v.is_a?(String) && v.match(
|
216
|
+
/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/
|
217
|
+
)
|
218
|
+
return true
|
219
|
+
end
|
220
|
+
|
221
|
+
raise Wavefront::Exception::InvalidCloudIntegrationId
|
222
|
+
end
|
223
|
+
|
224
|
+
# There doesn't seem to be a public statement on what's allowed
|
225
|
+
# in a dashboard name. For now I'm going to assume up to 255 word
|
226
|
+
# characters.
|
227
|
+
#
|
228
|
+
# @param v [String] the dashboard ID to validate
|
229
|
+
# @return true if the dashboard ID is valid
|
230
|
+
# @raise Wavefront::Exception::InvalidDashboardID if the
|
231
|
+
# dashboard ID is not valid
|
232
|
+
#
|
233
|
+
def wf_dashboard_id?(v)
|
234
|
+
return true if v.is_a?(String) && v.size < 256 && v.match(/^[\w\-]+$/)
|
235
|
+
raise Wavefront::Exception::InvalidDashboardId
|
236
|
+
end
|
237
|
+
|
238
|
+
# Ensure the given argument is a valid event ID. Event IDs are
|
239
|
+
# an epoch-millisecond timestamp followed by a : followed by the
|
240
|
+
# name of the event.
|
241
|
+
#
|
242
|
+
# @param v [String] the event ID to validate
|
243
|
+
# @return true if the event ID is valid
|
244
|
+
# @raise Wavefront::Exception::InvalidEventID if the
|
245
|
+
# event ID is not valid
|
246
|
+
#
|
247
|
+
def wf_event_id?(v)
|
248
|
+
return true if v.is_a?(String) && v =~ /^\d{13}:[\w\- ]+$/
|
249
|
+
raise Wavefront::Exception::InvalidEventId
|
250
|
+
end
|
251
|
+
|
252
|
+
# Ensure the given argument is a valid external Link ID
|
253
|
+
#
|
254
|
+
# @param v [String] the external link ID to validate
|
255
|
+
# @return True if the link ID is valid
|
256
|
+
# @raise Wavefront::Exception::InvalidExternalLinkId if the
|
257
|
+
# link ID is not valid
|
258
|
+
#
|
259
|
+
def wf_link_id?(v)
|
260
|
+
return true if v.is_a?(String) && v =~ /^\w{16}$/
|
261
|
+
raise Wavefront::Exception::InvalidExternalLinkId
|
262
|
+
end
|
263
|
+
|
264
|
+
# Ensure the given argument is a valid maintenance window ID.
|
265
|
+
# IDs are the millisecond epoch timestamp at which the window
|
266
|
+
# was created.
|
267
|
+
#
|
268
|
+
# @param v [String, Integer]
|
269
|
+
# @return True if the ID is valid
|
270
|
+
# @raise Wavefront::Exception::InvalidMaintenanceWindowId
|
271
|
+
#
|
272
|
+
def wf_maintenance_window_id?(v)
|
273
|
+
v = v.to_s if v.is_a?(Numeric)
|
274
|
+
return true if v.is_a?(String) && v =~ /^\d{13}$/
|
275
|
+
|
276
|
+
raise Wavefront::Exception::InvalidMaintenanceWindowId
|
277
|
+
end
|
278
|
+
|
279
|
+
# Ensure the given argument is a valid alert severity
|
280
|
+
#
|
281
|
+
# @param v [String] severity
|
282
|
+
# @return true if valid
|
283
|
+
# @raise Wavefront::Exceptions::InvalidAlertSeverity if not
|
284
|
+
# valid
|
285
|
+
#
|
286
|
+
def wf_alert_severity?(v)
|
287
|
+
return true if %w(INFO SMOKE WARN SEVERE).include?(v)
|
288
|
+
raise Wavefront::Exception::InvalidAlertSeverity
|
289
|
+
end
|
290
|
+
|
291
|
+
# Ensure the given argument is a valid message ID
|
292
|
+
#
|
293
|
+
# @param v [String] severity
|
294
|
+
# @return true if valid
|
295
|
+
# @raise Wavefront::Exceptions::InvalidMessageId if not
|
296
|
+
# valid
|
297
|
+
#
|
298
|
+
def wf_message_id?(v)
|
299
|
+
return true if v.is_a?(String) && v =~ /^\w+$/
|
300
|
+
raise Wavefront::Exception::InvalidMessageId
|
301
|
+
end
|
302
|
+
|
303
|
+
# Ensure the given argument is a valid query granularity
|
304
|
+
#
|
305
|
+
# @param v [String] granularity
|
306
|
+
# @return true if valid
|
307
|
+
# @raise Wavefront::Exceptions::InvalidGranularity if not
|
308
|
+
# valid
|
309
|
+
#
|
310
|
+
def wf_granularity?(v)
|
311
|
+
return true if %w(d h m s).include?(v.to_s)
|
312
|
+
raise Wavefront::Exception::InvalidGranularity
|
313
|
+
end
|
314
|
+
|
315
|
+
# Ensure the given argument is a valid saved search ID.
|
316
|
+
#
|
317
|
+
# @param v [String] saved search ID
|
318
|
+
# @return true if valid
|
319
|
+
# @raise Wavefront::Exceptions::InvalidSavedSearchId if not valid
|
320
|
+
#
|
321
|
+
def wf_savedsearch_id?(v)
|
322
|
+
return true if v.is_a?(String) && v =~ /^\w{8}$/
|
323
|
+
raise Wavefront::Exception::InvalidSavedSearchId
|
324
|
+
end
|
325
|
+
|
326
|
+
# Ensure the given argument is a valid saved search entity type.
|
327
|
+
#
|
328
|
+
# @param v [String] entity type
|
329
|
+
# @return true if valid
|
330
|
+
# @raise Wavefront::Exceptions::InvalidSavedSearchEntity if not
|
331
|
+
# valid
|
332
|
+
#
|
333
|
+
def wf_savedsearch_entity?(v)
|
334
|
+
return true if %w(DASHBOARD ALERT MAINTENANCE_WINDOW
|
335
|
+
NOTIFICANT EVENT SOURCE EXTERNAL_LINK AGENT
|
336
|
+
CLOUD_INTEGRATION).include?(v)
|
337
|
+
raise Wavefront::Exception::InvalidSavedSearchEntity
|
338
|
+
end
|
339
|
+
|
340
|
+
# Ensure the given argument is a valid Wavefront source name
|
341
|
+
#
|
342
|
+
# @param v [String] the source name to validate
|
343
|
+
# @return True if the source name is valid
|
344
|
+
# @raise Wavefront::Exception::InvalidSourceId if the source name
|
345
|
+
# is not valid
|
346
|
+
#
|
347
|
+
def wf_source_id?(v)
|
348
|
+
if v.is_a?(String) && v.match(/^[\w\.\-]+$/) && v.size < 1024
|
349
|
+
return true
|
350
|
+
end
|
351
|
+
|
352
|
+
raise Wavefront::Exception::InvalidSourceId
|
353
|
+
end
|
354
|
+
|
355
|
+
# Ensure the given argument is a valid user.
|
356
|
+
#
|
357
|
+
# @param v [String] user identifier
|
358
|
+
# @return true if valid
|
359
|
+
# @raise Wavefront::Exceptions::InvalidUserId if not valid
|
360
|
+
#
|
361
|
+
def wf_user_id?(v)
|
362
|
+
return true if v.is_a?(String) &&
|
363
|
+
v =~ /\A([\w+\-].?)+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z/i
|
364
|
+
raise Wavefront::Exception::InvalidUserId
|
365
|
+
end
|
366
|
+
|
367
|
+
# Ensure the given argument is a valid webhook ID.
|
368
|
+
#
|
369
|
+
# @param v [String] webhook ID
|
370
|
+
# @return true if valid
|
371
|
+
# @raise Wavefront::Exceptions::InvalidWebhook if not valid
|
372
|
+
#
|
373
|
+
def wf_webhook_id?(v)
|
374
|
+
return true if v.is_a?(String) && v =~ /^[a-zA-Z0-9]{16}$/
|
375
|
+
raise Wavefront::Exception::InvalidWebhookId
|
376
|
+
end
|
377
|
+
|
378
|
+
# Validate a point so it conforms to the standard described in
|
379
|
+
# https://community.wavefront.com/docs/DOC-1031
|
380
|
+
#
|
381
|
+
# @param v [Hash] description of point
|
382
|
+
# @return true if valie
|
383
|
+
# @raise whichever exception is thrown first when validating
|
384
|
+
# each component of the point.
|
385
|
+
#
|
386
|
+
def wf_point?(v)
|
387
|
+
wf_metric_name?(v[:path])
|
388
|
+
wf_value?(v[:value])
|
389
|
+
wf_epoch?(v[:ts]) if v[:ts]
|
390
|
+
wf_source_id?(v[:source]) if v[:source]
|
391
|
+
wf_point_tags?(v[:tags]) if v[:tags]
|
392
|
+
true
|
393
|
+
end
|
394
|
+
end
|
395
|
+
end
|