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
data/.travis.yml
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
language: ruby
|
2
|
+
cache: bundler
|
3
|
+
rvm:
|
4
|
+
- 2.2.7
|
5
|
+
- 2.3.4
|
6
|
+
- 2.4.1
|
7
|
+
before_install: gem install bundler --no-rdoc --no-ri
|
8
|
+
deploy:
|
9
|
+
provider: rubygems
|
10
|
+
api_key:
|
11
|
+
secure: dfmL5JwBn+u3cUmyAaDsApDa7ljGajGNz3GDcKd2J8FOt7+a758/lmL8EQ34sDT1ZFotrxn/y1RbgXlaDxAE1XDfrZbjckmx7a6wa2sqR3kBraJ2tx7CiXodbw3Z8XZf9WLb0kYGmlLtI73GNcuunMt/9f1cobqWISRLHw6b7amlO7GW2ZBZgzRS+N8TSS2dicIvKMo5HoMYU+uWLM4zDFBPnGNcMiWxh8ysLzJoKqA9kbBUyCVEZ03MlV7G71ObvWCLasKnZ3W5U+K1NbgU7mgMYfl9KIcA4y9hQ9hUCijk40SmT7ffy3P2gq8zblC/4x5Eefpau9X/bdLwXoRCIzqk05t4f45wstj2auHGK0HJwOYRtx8apdaLSgyJ5lQpGcbCRu40WR9mDkaM8m9n3u2o6GJmftCg3AN1QtsourmQB84x67LEbHzValMaokrbCol4XeWqlC+dCNLPixemQRBvcNfI3V9C6RqVGfjpoGlSTI+RkQqwm01PcxpeqIVfdMd1wnfUuAOywUO6UpvtK9TZaxg0NnVElXpPseQbtzulLwZ7R5Y3A4Ss8Z7w43c1KHxTkg54FWUOp065ItjAc4lmyORXq/2+F7sMvRN6dtCLaXTUlkYuU3cjFLIPlLGFYgqq4T4xQa+e5NEK1XW7nghv+IRfKfyVeZsB0WpY+uc=
|
12
|
+
gem: wavefront-sdk
|
13
|
+
on:
|
14
|
+
tags: true
|
15
|
+
repo: snltd/wavefront-sdk
|
16
|
+
ruby: 2.3.4
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
wavefront-sdk (0.0.1)
|
5
|
+
faraday (>= 0.12.1, < 0.13)
|
6
|
+
inifile (>= 3.0.0)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
addressable (2.5.1)
|
12
|
+
public_suffix (~> 2.0, >= 2.0.2)
|
13
|
+
ast (2.3.0)
|
14
|
+
crack (0.4.3)
|
15
|
+
safe_yaml (~> 1.0.0)
|
16
|
+
faraday (0.12.1)
|
17
|
+
multipart-post (>= 1.2, < 3)
|
18
|
+
hashdiff (0.3.2)
|
19
|
+
inifile (3.0.0)
|
20
|
+
minitest (5.8.5)
|
21
|
+
multipart-post (2.0.0)
|
22
|
+
parser (2.4.0.0)
|
23
|
+
ast (~> 2.2)
|
24
|
+
powerpack (0.1.1)
|
25
|
+
public_suffix (2.0.5)
|
26
|
+
rainbow (2.2.1)
|
27
|
+
rake (12.0.0)
|
28
|
+
rubocop (0.47.1)
|
29
|
+
parser (>= 2.3.3.1, < 3.0)
|
30
|
+
powerpack (~> 0.1)
|
31
|
+
rainbow (>= 1.99.1, < 3.0)
|
32
|
+
ruby-progressbar (~> 1.7)
|
33
|
+
unicode-display_width (~> 1.0, >= 1.0.1)
|
34
|
+
ruby-progressbar (1.8.1)
|
35
|
+
safe_yaml (1.0.4)
|
36
|
+
spy (0.4.5)
|
37
|
+
unicode-display_width (1.1.3)
|
38
|
+
webmock (2.3.2)
|
39
|
+
addressable (>= 2.3.6)
|
40
|
+
crack (>= 0.3.2)
|
41
|
+
hashdiff
|
42
|
+
yard (0.9.5)
|
43
|
+
|
44
|
+
PLATFORMS
|
45
|
+
ruby
|
46
|
+
|
47
|
+
DEPENDENCIES
|
48
|
+
bundler (~> 1.3)
|
49
|
+
minitest (~> 5.8, >= 5.8.0)
|
50
|
+
rake (~> 12.0)
|
51
|
+
rubocop (~> 0.47.0)
|
52
|
+
spy (~> 0.4.0)
|
53
|
+
wavefront-sdk!
|
54
|
+
webmock (~> 2.3, >= 2.3.2)
|
55
|
+
yard (~> 0.9.5)
|
56
|
+
|
57
|
+
BUNDLED WITH
|
58
|
+
1.14.6
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
Copyright (c) 2017, Sysdef Ltd
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
5
|
+
modification, are permitted provided that the following conditions
|
6
|
+
are met:
|
7
|
+
|
8
|
+
* Redistributions of source code must retain the above copyright
|
9
|
+
notice, this list of conditions and the following disclaimer.
|
10
|
+
|
11
|
+
* Redistributions in binary form must reproduce the above copyright
|
12
|
+
notice, this list of conditions and the following disclaimer in
|
13
|
+
the documentation and/or other materials provided with the
|
14
|
+
distribution.
|
15
|
+
|
16
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
17
|
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
18
|
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
19
|
+
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
20
|
+
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
21
|
+
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
22
|
+
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
24
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
25
|
+
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
26
|
+
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
27
|
+
POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
# wavefront-sdk [](https://travis-ci.org/snltd/wavefront-sdk) [](https://codeclimate.com/github/snltd/wavefront-sdk) [](https://codeclimate.com/github/snltd/wavefront-sdk) [](https://snyk.io/test/github/snltd/wavefront-sdk)
|
2
|
+
|
3
|
+
This is a Ruby SDK for v2 of
|
4
|
+
[Wavefront](https://www.wavefront.com/)'s public API. It supports Ruby >= 2.2.
|
5
|
+
|
6
|
+
Note that it currently has major version number `0`. This means *it
|
7
|
+
is not finished*. Until version `1` comes out, I reserve the right
|
8
|
+
to change, break, and befoul the code and the gem.
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
```
|
13
|
+
$ gem install wavefront-sdk
|
14
|
+
```
|
15
|
+
|
16
|
+
or to build locally,
|
17
|
+
|
18
|
+
```
|
19
|
+
$ gem build wavefront-sdk.gemspec
|
20
|
+
```
|
21
|
+
|
22
|
+
## Examples
|
23
|
+
|
24
|
+
First, let's list the IDs of the users in our account. The `list()` method
|
25
|
+
will return a `Wavefront::Response::User` object with a list of items. Most
|
26
|
+
response classes behave this way.
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
# Define our API endpoint. (This is not a valid token!)
|
30
|
+
|
31
|
+
CREDS = { endpoint: 'metrics.wavefront.com',
|
32
|
+
token: 'c7a1ff30-0dd8-fa60-e14d-f58f91bafc0e' }
|
33
|
+
|
34
|
+
require 'wavefront-sdk/user'
|
35
|
+
|
36
|
+
# You can pass in a Ruby logger object, and tell the SDK to be
|
37
|
+
# verbose.
|
38
|
+
|
39
|
+
require 'logger'
|
40
|
+
log = Logger.new(STDOUT)
|
41
|
+
|
42
|
+
wf = Wavefront::User.new(CREDS, verbose: true, logger: log)
|
43
|
+
|
44
|
+
wf.list.response.items.each { |user| puts user[:identifier] }
|
45
|
+
|
46
|
+
# And delete the user 'lolex@oldplace.com'
|
47
|
+
|
48
|
+
wf.delete('lolex@oldplace.com')
|
49
|
+
```
|
50
|
+
|
51
|
+
Retrieve a timeseries over the last 10 minutes, with one minute bucket
|
52
|
+
granularity. We will describe the time as a Ruby object, but could also use
|
53
|
+
an epoch timestamp.
|
54
|
+
|
55
|
+
|
56
|
+
```ruby
|
57
|
+
require 'wavefront-sdk/query'
|
58
|
+
|
59
|
+
Wavefront::Query.new(CREDS).query(
|
60
|
+
'ts("prod.www.host.tenant.physicalmem.usage")',
|
61
|
+
:m,
|
62
|
+
(Time.now - 600)
|
63
|
+
)
|
64
|
+
```
|
65
|
+
|
66
|
+
We can write points too, assuming we have a proxy. You can't write points
|
67
|
+
directly via the API. Unlike all other classes, this one requires the proxy
|
68
|
+
address and port as its credential hash.
|
69
|
+
|
70
|
+
```ruby
|
71
|
+
require 'wavefront-sdk/write'
|
72
|
+
|
73
|
+
W_CREDS = { proxy: 'wavefront.localnet', port: 2878 }
|
74
|
+
|
75
|
+
wf = Wavefront::Write.new(W_CREDS, debug: true)
|
76
|
+
|
77
|
+
task = wf.write( [{ path: 'dev.test.sdk', value: 10 }])
|
78
|
+
|
79
|
+
p task.response
|
80
|
+
#<struct sent=1, rejected=0, unsent=0>
|
81
|
+
puts task.status.result
|
82
|
+
#OK
|
83
|
+
```
|
84
|
+
|
85
|
+
The SDK also provides a helper class for extracting credentials from a
|
86
|
+
configuration file. If you don't supply a file, defaults will be
|
87
|
+
used.
|
88
|
+
|
89
|
+
```ruby
|
90
|
+
require 'wavefront-sdk/credentials'
|
91
|
+
|
92
|
+
c = Wavefront::Credentials.new
|
93
|
+
|
94
|
+
# Now use that to list the proxies in our account
|
95
|
+
|
96
|
+
require 'wavefront-sdk/proxy'
|
97
|
+
|
98
|
+
p Wavefront::Proxy.new(c.creds).list
|
99
|
+
|
100
|
+
# It works for proxies too:
|
101
|
+
|
102
|
+
wf = Wavefront::Write.new(c.proxy)
|
103
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'yard'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rubocop/rake_task'
|
4
|
+
|
5
|
+
task default: :test
|
6
|
+
|
7
|
+
Rake::TestTask.new do |t|
|
8
|
+
t.pattern = 'spec/wavefront-sdk/*_spec.rb'
|
9
|
+
t.warning = false
|
10
|
+
end
|
11
|
+
|
12
|
+
RuboCop::RakeTask.new(:rubocop) do |t|
|
13
|
+
t.options = ['--display-cop-names']
|
14
|
+
end
|
15
|
+
|
16
|
+
YARD::Rake::YardocTask.new do |t|
|
17
|
+
t.files = ['lib/wavefront-sdk/*rb']
|
18
|
+
end
|
@@ -0,0 +1,195 @@
|
|
1
|
+
require_relative './base'
|
2
|
+
|
3
|
+
module Wavefront
|
4
|
+
#
|
5
|
+
# View and manage alerts. Alerts are identified by their millisecond
|
6
|
+
# epoch timestamp. Returns a Wavefront::Response::Alert object.
|
7
|
+
#
|
8
|
+
class Alert < Wavefront::Base
|
9
|
+
|
10
|
+
# GET /api/v2/alert
|
11
|
+
# Get all alerts for a customer
|
12
|
+
#
|
13
|
+
# @param offset [Int] alert at which the list begins
|
14
|
+
# @param limit [Int] the number of alerts 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/alert
|
22
|
+
# Create a specific alert. We used to validate input here, but
|
23
|
+
# this couples the SDK too tightly to the API. Now it's just a
|
24
|
+
# generic POST of a hash.
|
25
|
+
#
|
26
|
+
# @param body [Hash] description of alert
|
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/alert/{id}
|
35
|
+
# Delete a specific alert.
|
36
|
+
#
|
37
|
+
# Deleting an active alert moves it to 'trash', from where it can
|
38
|
+
# be restored with an #undelete operation. Deleting an alert in
|
39
|
+
# 'trash' removes it for ever.
|
40
|
+
#
|
41
|
+
# @param id [String] ID of the alert
|
42
|
+
# @return [Hash]
|
43
|
+
#
|
44
|
+
def delete(id)
|
45
|
+
wf_alert_id?(id)
|
46
|
+
api_delete(id)
|
47
|
+
end
|
48
|
+
|
49
|
+
# GET /api/v2/alert/{id}
|
50
|
+
# GET /api/v2/alert/{id}/history/{version}
|
51
|
+
# Get a specific alert / Get a specific historical version of a
|
52
|
+
# specific alert.
|
53
|
+
#
|
54
|
+
# @param id [String] ID of the alert
|
55
|
+
# @param version [Integer] version of alert
|
56
|
+
# @return [Hash]
|
57
|
+
#
|
58
|
+
def describe(id, version = nil)
|
59
|
+
wf_alert_id?(id)
|
60
|
+
wf_version?(version) if version
|
61
|
+
fragments = [id]
|
62
|
+
fragments += ['history', version] if version
|
63
|
+
api_get(fragments.uri_concat)
|
64
|
+
end
|
65
|
+
|
66
|
+
# PUT /api/v2/alert/{id}
|
67
|
+
# Update a specific alert.
|
68
|
+
#
|
69
|
+
# @param id [String] a Wavefront alert ID
|
70
|
+
# @param body [Hash] description of event. See body_desc()
|
71
|
+
# @return [Hash]
|
72
|
+
#
|
73
|
+
def update(id, body)
|
74
|
+
wf_alert_id?(id)
|
75
|
+
raise ArgumentError unless body.is_a?(Hash)
|
76
|
+
api_put(id, body, 'application/json')
|
77
|
+
end
|
78
|
+
|
79
|
+
# GET /api/v2/alert/{id}/history
|
80
|
+
# Get the version history of a specific alert.
|
81
|
+
#
|
82
|
+
# @param id [String] ID of the alert
|
83
|
+
# @return [Hash]
|
84
|
+
#
|
85
|
+
def history(id)
|
86
|
+
wf_alert_id?(id)
|
87
|
+
api_get([id, 'history'].uri_concat)
|
88
|
+
end
|
89
|
+
|
90
|
+
# POST /api/v2/alert/{id}/snooze
|
91
|
+
# Snooze a specific alert for some number of seconds.
|
92
|
+
#
|
93
|
+
# @param id [String] ID of the alert
|
94
|
+
# @param time [Integer] how many seconds to snooze for. Nil is indefinite
|
95
|
+
# @returns [Hash] object describing the alert with status and
|
96
|
+
# response keys
|
97
|
+
#
|
98
|
+
def snooze(id, seconds = nil)
|
99
|
+
wf_alert_id?(id)
|
100
|
+
qs = seconds ? "?seconds=#{seconds}" : ''
|
101
|
+
api_post([id, "snooze#{qs}"].uri_concat, nil)
|
102
|
+
end
|
103
|
+
|
104
|
+
# GET /api/v2/alert/{id}/tag
|
105
|
+
# Get all tags associated with a specific alert.
|
106
|
+
#
|
107
|
+
# @param id [String] ID of the alert
|
108
|
+
# @returns [Hash] object describing the alert with status and
|
109
|
+
# response keys
|
110
|
+
#
|
111
|
+
def tags(id)
|
112
|
+
wf_alert_id?(id)
|
113
|
+
api_get([id, 'tag'].uri_concat)
|
114
|
+
end
|
115
|
+
|
116
|
+
# POST /api/v2/alert/{id}/tag
|
117
|
+
# Set all tags associated with a specific alert.
|
118
|
+
#
|
119
|
+
# @param id [String] ID of the alert
|
120
|
+
# @param tags [Array] list of tags to set.
|
121
|
+
# @returns [Hash] object describing the alert with status and
|
122
|
+
# response keys
|
123
|
+
#
|
124
|
+
def tag_set(id, tags)
|
125
|
+
wf_alert_id?(id)
|
126
|
+
tags = Array(tags)
|
127
|
+
tags.each { |t| wf_string?(t) }
|
128
|
+
api_post([id, 'tag'].uri_concat, tags.to_json, 'application/json')
|
129
|
+
end
|
130
|
+
|
131
|
+
# DELETE /api/v2/alert/{id}/tag/{tagValue}
|
132
|
+
# Remove a tag from a specific alert.
|
133
|
+
#
|
134
|
+
# @param id [String] ID of the alert
|
135
|
+
# @param tag [String] tag to delete
|
136
|
+
# @returns [Hash] object with 'status' key and empty 'repsonse'
|
137
|
+
#
|
138
|
+
def tag_delete(id, tag)
|
139
|
+
wf_alert_id?(id)
|
140
|
+
wf_string?(tag)
|
141
|
+
api_delete([id, 'tag', tag].uri_concat)
|
142
|
+
end
|
143
|
+
|
144
|
+
# PUT /api/v2/alert/{id}/tag/{tagValue}
|
145
|
+
# Add a tag to a specific alert.
|
146
|
+
#
|
147
|
+
# @param id [String] ID of the alert
|
148
|
+
# @param tag [String] tag to set.
|
149
|
+
# @returns [Hash] object with 'status' key and empty 'repsonse'
|
150
|
+
#
|
151
|
+
def tag_add(id, tag)
|
152
|
+
wf_alert_id?(id)
|
153
|
+
wf_string?(tag)
|
154
|
+
api_put([id, 'tag', tag].uri_concat)
|
155
|
+
end
|
156
|
+
|
157
|
+
# POST /api/v2/alert/{id}/undelete
|
158
|
+
# Undelete a specific alert.
|
159
|
+
#
|
160
|
+
# @param id [String] ID of the alert
|
161
|
+
# @return [Hash]
|
162
|
+
#
|
163
|
+
def undelete(id)
|
164
|
+
wf_alert_id?(id)
|
165
|
+
api_post([id, 'undelete'].uri_concat)
|
166
|
+
end
|
167
|
+
|
168
|
+
# POST /api/v2/alert/{id}/unsnooze
|
169
|
+
# Unsnooze a specific alert.
|
170
|
+
#
|
171
|
+
# @param id [String] ID of the alert
|
172
|
+
# @returns [Hash] object describing the alert with status and
|
173
|
+
# response keys
|
174
|
+
#
|
175
|
+
def unsnooze(id)
|
176
|
+
wf_alert_id?(id)
|
177
|
+
api_post([id, 'unsnooze'].uri_concat)
|
178
|
+
end
|
179
|
+
|
180
|
+
# GET /api/v2/alert/summary
|
181
|
+
# Count alerts of various statuses for a customer
|
182
|
+
#
|
183
|
+
# @return [Hash]
|
184
|
+
#
|
185
|
+
def summary
|
186
|
+
api_get('summary')
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
# A standard response
|
191
|
+
#
|
192
|
+
class Response
|
193
|
+
class Alert < Base; end
|
194
|
+
end
|
195
|
+
end
|
@@ -0,0 +1,251 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'time'
|
3
|
+
require 'faraday'
|
4
|
+
require 'pp'
|
5
|
+
require 'ostruct'
|
6
|
+
require_relative './exception'
|
7
|
+
require_relative './mixins'
|
8
|
+
require_relative './response'
|
9
|
+
require_relative './validators'
|
10
|
+
require_relative './version'
|
11
|
+
|
12
|
+
module Wavefront
|
13
|
+
#
|
14
|
+
# Abstract class from which all API classes inherit. When you make
|
15
|
+
# any call to the Wavefront API from this SDK, you are returned an
|
16
|
+
# OpenStruct object.
|
17
|
+
#
|
18
|
+
# @returns a Wavefront::Class::Response object where Class matches
|
19
|
+
# the inheriting class name.
|
20
|
+
#
|
21
|
+
class Base
|
22
|
+
include Wavefront::Validators
|
23
|
+
include Wavefront::Mixins
|
24
|
+
attr_reader :opts, :debug, :noop, :verbose, :net, :api_base, :conn,
|
25
|
+
:update_keys, :logger
|
26
|
+
|
27
|
+
# Create a new API object. This will always be called from a
|
28
|
+
# class which inherits this one. If the inheriting class defines
|
29
|
+
# #post_initialize, that method will be called afterwards, with
|
30
|
+
# the same arguments.
|
31
|
+
#
|
32
|
+
# @param creds [Hash] must contain the keys `endpoint` (the
|
33
|
+
# Wavefront API server) and `token`, the user token with which
|
34
|
+
# you wish to access the endpoint. Can optionally contain
|
35
|
+
# `agent`, which will become the `user-agent` string sent with
|
36
|
+
# all requests.
|
37
|
+
# @param opts [Hash] options governing class behaviour. Expected
|
38
|
+
# keys are `debug`, `noop` and `verbose`, all boolean; and
|
39
|
+
# `logger`, which must be a standard Ruby logger object. You
|
40
|
+
# can also pass :response_only. If this is true, you will only
|
41
|
+
# be returned a hash of the 'response' object returned by
|
42
|
+
# Wavefront.
|
43
|
+
# @return [Nil]
|
44
|
+
#
|
45
|
+
def initialize(creds = {}, opts = {})
|
46
|
+
@opts = opts
|
47
|
+
@debug = opts[:debug] || false
|
48
|
+
@noop = opts[:noop] || false
|
49
|
+
@verbose = opts[:verbose] || false
|
50
|
+
@logger = opts[:logger] || nil
|
51
|
+
setup_endpoint(creds)
|
52
|
+
|
53
|
+
post_initialize(creds, opts) if respond_to?(:post_initialize)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Convert an epoch timestamp into epoch milliseconds. If the
|
57
|
+
# timestamp looks like it's already epoch milliseconds, return
|
58
|
+
# it as-is.
|
59
|
+
#
|
60
|
+
# @param t [Integer] epoch timestamp
|
61
|
+
# @return [Ingeter] epoch millisecond timestamp
|
62
|
+
#
|
63
|
+
def time_to_ms(t)
|
64
|
+
return false unless t.is_a?(Integer)
|
65
|
+
return t if t.to_s.size == 13
|
66
|
+
(t.to_f * 1000).round
|
67
|
+
end
|
68
|
+
|
69
|
+
# Derive the first part of the API path from the class name. You
|
70
|
+
# can override this in your class if you wish
|
71
|
+
#
|
72
|
+
# @return [String] portion of API URI
|
73
|
+
#
|
74
|
+
def api_base
|
75
|
+
self.class.name.split('::').last.downcase
|
76
|
+
end
|
77
|
+
|
78
|
+
# Create a Faraday connection object. The server comes from the
|
79
|
+
# endpoint passed to the initializer in the 'creds' hash; the
|
80
|
+
# root of the URI is dynamically derived by the #setup_endpoint
|
81
|
+
# method.
|
82
|
+
#
|
83
|
+
# @param headers [Hash] additional headers
|
84
|
+
# @return [URI::HTTPS]
|
85
|
+
#
|
86
|
+
def mk_conn(path, headers = {})
|
87
|
+
Faraday.new(
|
88
|
+
url: "https://#{net[:endpoint]}" +
|
89
|
+
[net[:api_base], path].uri_concat,
|
90
|
+
headers: net[:headers].merge(headers)
|
91
|
+
)
|
92
|
+
end
|
93
|
+
|
94
|
+
# Make a GET call to the Wavefront API and return the result as
|
95
|
+
# a Ruby hash. Can optionally perform a verbose noop, if the
|
96
|
+
# #noop class variable is set. If #verbose is set, then prints
|
97
|
+
# the information used to build the URI.
|
98
|
+
#
|
99
|
+
# @param path [String] path to be appended to the
|
100
|
+
# #net[:api_base] path.
|
101
|
+
# @param qs [String] optional query string
|
102
|
+
# @return [Hash] API response
|
103
|
+
#
|
104
|
+
def api_get(path, query = {})
|
105
|
+
make_call(mk_conn(path), :get, nil, query)
|
106
|
+
end
|
107
|
+
|
108
|
+
# Make a POST call to the Wavefront API and return the result as
|
109
|
+
# a Ruby hash. Can optionally perform a verbose noop, if the
|
110
|
+
# #noop class variable is set. If #verbose is set, then prints
|
111
|
+
# the information used to build the URI.
|
112
|
+
#
|
113
|
+
# @param path [String] path to be appended to the
|
114
|
+
# #net[:api_base] path.
|
115
|
+
# @param body [String] optional body text to post
|
116
|
+
# @param ctype [String] the content type to use when posting
|
117
|
+
# @return [Hash] API response
|
118
|
+
#
|
119
|
+
def api_post(path, body = nil, ctype = 'text/plain')
|
120
|
+
body = body.to_json unless body.is_a?(String)
|
121
|
+
make_call(mk_conn(path, { 'Content-Type': ctype,
|
122
|
+
'Accept': 'application/json'}),
|
123
|
+
:post, nil, body)
|
124
|
+
end
|
125
|
+
|
126
|
+
# Make a PUT call to the Wavefront API and return the result as
|
127
|
+
# a Ruby hash. Can optionally perform a verbose noop, if the
|
128
|
+
# #noop class variable is set. If #verbose is set, then prints
|
129
|
+
# the information used to build the URI.
|
130
|
+
#
|
131
|
+
# @param path [String] path to be appended to the
|
132
|
+
# #net[:api_base] path.
|
133
|
+
# @param body [String] optional body text to post
|
134
|
+
# @param ctype [String] the content type to use when putting
|
135
|
+
# @return [Hash] API response
|
136
|
+
#
|
137
|
+
def api_put(path, body = nil, ctype = 'application/json')
|
138
|
+
make_call(mk_conn(path, { 'Content-Type': ctype,
|
139
|
+
'Accept': 'application/json' }),
|
140
|
+
:put, nil, body.to_json)
|
141
|
+
end
|
142
|
+
|
143
|
+
# Make a DELETE call to the Wavefront API and return the result
|
144
|
+
# as a Ruby hash. Can optionally perform a verbose noop, if the
|
145
|
+
# #noop class variable is set. If #verbose is set, then prints
|
146
|
+
# the information used to build the URI.
|
147
|
+
#
|
148
|
+
# @param path [String] path to be appended to the
|
149
|
+
# #net[:api_base] path.
|
150
|
+
# @return [Hash] API response
|
151
|
+
#
|
152
|
+
def api_delete(path)
|
153
|
+
make_call(mk_conn(path), :delete)
|
154
|
+
end
|
155
|
+
|
156
|
+
# doing a PUT to update an object requires only a certain subset of
|
157
|
+
# the keys returned by #describe().
|
158
|
+
#
|
159
|
+
# @param body [Hash] a hash of the existing object merged with the
|
160
|
+
# hash describing the user's change(s).
|
161
|
+
# @param keys [Array, String] the keys(s) the user wishes to update
|
162
|
+
# @return [Hash] a hash containing only the keys which need to be
|
163
|
+
# sent to the API. Keys will be symbolized.
|
164
|
+
#
|
165
|
+
def hash_for_update(old, new)
|
166
|
+
raise ArgumentError unless old.is_a?(Hash) && new.is_a?(Hash)
|
167
|
+
|
168
|
+
Hash[old.merge(new).map { |k, v| [k.to_sym, v] }].select do |k, _v|
|
169
|
+
update_keys.include?(k)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
# Send a message to a Ruby logger object if the user supplied
|
174
|
+
# one, or print to standard out if not.
|
175
|
+
#
|
176
|
+
# @param msg [String] the string to print
|
177
|
+
# @param level [Symbol] the level of the message.
|
178
|
+
# :verbose messages equate to a standard INFO log level and
|
179
|
+
# :debug to DEBUG.
|
180
|
+
#
|
181
|
+
def log(msg, level = nil)
|
182
|
+
|
183
|
+
if logger
|
184
|
+
logger.send(level || :info, msg)
|
185
|
+
else
|
186
|
+
# print it unless it's a debug and we're not in debug
|
187
|
+
#
|
188
|
+
return if level == :debug && ! opts[:debug]
|
189
|
+
return if level == :info && ! opts[:verbose]
|
190
|
+
|
191
|
+
puts msg
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
def respond(resp)
|
196
|
+
response_class.send(:new, resp.body, resp.status || {})
|
197
|
+
end
|
198
|
+
|
199
|
+
private
|
200
|
+
|
201
|
+
# Try to describe the actual HTTP calls we make. There's a bit
|
202
|
+
# of clumsy guesswork here
|
203
|
+
#
|
204
|
+
def verbosity(conn, method, *args)
|
205
|
+
log "uri: #{method.upcase} #{conn.url_prefix}"
|
206
|
+
|
207
|
+
if args.last && ! args.last.empty?
|
208
|
+
puts log method == :get ? "params: #{args.last}" :
|
209
|
+
"body: #{args.last}"
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
# Make the API call, or not, if noop is set.
|
214
|
+
#
|
215
|
+
def make_call(conn, method, *args)
|
216
|
+
verbosity(conn, method, *args) if noop || verbose
|
217
|
+
return if noop
|
218
|
+
|
219
|
+
resp = conn.public_send(method, *args)
|
220
|
+
|
221
|
+
if debug
|
222
|
+
require 'pp'
|
223
|
+
pp resp
|
224
|
+
end
|
225
|
+
|
226
|
+
respond(resp)
|
227
|
+
end
|
228
|
+
|
229
|
+
def response_class
|
230
|
+
Object.const_get(
|
231
|
+
"Wavefront::Response::#{self.class.name.split('::').last}")
|
232
|
+
end
|
233
|
+
|
234
|
+
def setup_endpoint(creds)
|
235
|
+
%w(endpoint token).each do |k|
|
236
|
+
raise "creds must contain #{k}" unless creds.key?(k.to_sym)
|
237
|
+
end
|
238
|
+
|
239
|
+
unless creds.key?(:agent) && creds[:agent]
|
240
|
+
creds[:agent] = "wavefront-sdk #{WF_SDK_VERSION}"
|
241
|
+
end
|
242
|
+
|
243
|
+
@net = {
|
244
|
+
headers: { 'Authorization': "Bearer #{creds[:token]}",
|
245
|
+
'user-agent': creds[:agent] },
|
246
|
+
endpoint: creds[:endpoint],
|
247
|
+
api_base: ['', 'api', 'v2', api_base].uri_concat
|
248
|
+
}
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|