wavefront-sdk 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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 [![Build Status](https://travis-ci.org/snltd/wavefront-sdk.svg?branch=master)](https://travis-ci.org/snltd/wavefront-sdk) [![Code Climate](https://codeclimate.com/github/snltd/wavefront-sdk/badges/gpa.svg)](https://codeclimate.com/github/snltd/wavefront-sdk) [![Issue Count](https://codeclimate.com/github/snltd/wavefront-sdk/badges/issue_count.svg)](https://codeclimate.com/github/snltd/wavefront-sdk) [![Known Vulnerabilities](https://snyk.io/test/github/snltd/wavefront-sdk/badge.svg)](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
|