wavefront-cli 3.2.0 → 3.2.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 +4 -4
- data/HISTORY.md +5 -0
- data/lib/wavefront-cli/alert.rb +14 -12
- data/lib/wavefront-cli/base.rb +15 -20
- data/lib/wavefront-cli/command_mixins/acl.rb +84 -0
- data/lib/wavefront-cli/command_mixins/tag.rb +28 -0
- data/lib/wavefront-cli/commands/alert.rb +4 -0
- data/lib/wavefront-cli/commands/base.rb +2 -4
- data/lib/wavefront-cli/controller.rb +1 -2
- data/lib/wavefront-cli/dashboard.rb +6 -143
- data/lib/wavefront-cli/derivedmetric.rb +4 -14
- data/lib/wavefront-cli/display/alert.rb +8 -0
- data/lib/wavefront-cli/event.rb +2 -0
- data/lib/wavefront-cli/source.rb +3 -0
- data/lib/wavefront-cli/version.rb +1 -1
- data/spec/.rubocop.yml +1 -1
- data/spec/spec_helper.rb +73 -11
- data/spec/wavefront-cli/alert_spec.rb +31 -9
- data/spec/wavefront-cli/config_spec.rb +61 -23
- data/spec/wavefront-cli/controller_spec.rb +11 -7
- data/spec/wavefront-cli/dashboard_spec.rb +12 -26
- data/spec/wavefront-cli/derivedmetric_spec.rb +4 -2
- data/spec/wavefront-cli/maintenancewindow_spec.rb +4 -2
- data/spec/wavefront-cli/notificant_spec.rb +4 -2
- data/spec/wavefront-cli/opt_handler_spec.rb +1 -1
- data/spec/wavefront-cli/stdlib/array_spec.rb +1 -0
- data/wavefront-cli.gemspec +3 -3
- metadata +12 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0cbeefd7b752bca0b1a5a3b886219b8ff0df8d6407ac1c3589e21f04faa1df7e
|
4
|
+
data.tar.gz: 36bbb2c1753d13d5911f91c0959af065d250e2d582b503d5731bd067ea1eebc9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c9a1cb2a6a26f242fb5a992497e4346d4844395d34c74958c03575116a6cdcbe712a4364bb6bf7a23fd8bb73d356b3905e4aa722305e3df228cdf84d28bf4613
|
7
|
+
data.tar.gz: 4f48260461f4222092f383dbd175d90ce4e0a1c58b7ff78260035b106abd14e86e71a6cf98f3d4e3b34bcefd7532db938f8c770fcdbf506f78ef3ca524a9daea
|
data/HISTORY.md
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 3.2.1 (09/05/2019)
|
4
|
+
* Fix for new API ACL format.
|
5
|
+
* Require 3.3.0 of [the SDK](https://github.com/snltd/wavefront-sdk).
|
6
|
+
|
3
7
|
## 3.2.0 (30/04/2019)
|
4
8
|
* New `apitoken` command lets you manage your own API tokens.
|
9
|
+
* Support for alert ACLs.
|
5
10
|
* Require 3.2.0 of [the SDK](https://github.com/snltd/wavefront-sdk).
|
6
11
|
|
7
12
|
## 3.1.4 (02/05/2019)
|
data/lib/wavefront-cli/alert.rb
CHANGED
@@ -1,13 +1,18 @@
|
|
1
1
|
require_relative 'base'
|
2
|
+
require_relative 'command_mixins/tag'
|
3
|
+
require_relative 'command_mixins/acl'
|
2
4
|
|
3
5
|
module WavefrontCli
|
4
6
|
#
|
5
7
|
# CLI coverage for the v2 'alert' API.
|
6
8
|
#
|
7
9
|
class Alert < WavefrontCli::Base
|
10
|
+
include WavefrontCli::Mixin::Tag
|
11
|
+
include WavefrontCli::Mixin::Acl
|
12
|
+
|
8
13
|
def import_fields
|
9
14
|
%w[name condition minutes target severity displayExpression
|
10
|
-
tags additionalInformation]
|
15
|
+
tags additionalInformation resolveAfterMinutes]
|
11
16
|
end
|
12
17
|
|
13
18
|
def do_describe
|
@@ -22,25 +27,22 @@ module WavefrontCli
|
|
22
27
|
wf.unsnooze(options[:'<id>'])
|
23
28
|
end
|
24
29
|
|
25
|
-
# rubocop:disable Metrics/AbcSize
|
26
30
|
def do_delete
|
27
|
-
|
28
|
-
|
29
|
-
word = if wf.describe(options[:'<id>']).status.code == 200
|
30
|
-
'Soft'
|
31
|
-
else
|
32
|
-
'Permanently'
|
33
|
-
end
|
31
|
+
smart_delete
|
32
|
+
end
|
34
33
|
|
35
|
-
|
36
|
-
wf.
|
34
|
+
def do_clone
|
35
|
+
wf.clone(options[:'<id>'], options[:version]&.to_i)
|
37
36
|
end
|
38
|
-
# rubocop:enable Metrics/AbcSize
|
39
37
|
|
40
38
|
def do_summary
|
41
39
|
wf.summary
|
42
40
|
end
|
43
41
|
|
42
|
+
def do_latest
|
43
|
+
wf.versions(options[:'<id>'])
|
44
|
+
end
|
45
|
+
|
44
46
|
def do_history
|
45
47
|
wf.history(options[:'<id>'], options[:offset], options[:limit])
|
46
48
|
end
|
data/lib/wavefront-cli/base.rb
CHANGED
@@ -394,6 +394,21 @@ module WavefrontCli
|
|
394
394
|
wf.delete(options[:'<id>'])
|
395
395
|
end
|
396
396
|
|
397
|
+
# Some objects support soft deleting. To handle that, call this
|
398
|
+
# method from do_delete
|
399
|
+
#
|
400
|
+
def smart_delete(object_type = klass_word)
|
401
|
+
cannot_noop!
|
402
|
+
puts smart_delete_message(object_type)
|
403
|
+
wf.delete(options[:'<id>'])
|
404
|
+
end
|
405
|
+
|
406
|
+
def smart_delete_message(object_type)
|
407
|
+
desc = wf.describe(options[:'<id>'])
|
408
|
+
word = desc.ok? ? 'Soft' : 'Permanently'
|
409
|
+
format("%s deleting %s '%s'", word, object_type, options[:'<id>'])
|
410
|
+
end
|
411
|
+
|
397
412
|
def do_undelete
|
398
413
|
wf.undelete(options[:'<id>'])
|
399
414
|
end
|
@@ -445,26 +460,6 @@ module WavefrontCli
|
|
445
460
|
end
|
446
461
|
end
|
447
462
|
|
448
|
-
def do_tags
|
449
|
-
wf.tags(options[:'<id>'])
|
450
|
-
end
|
451
|
-
|
452
|
-
def do_tag_add
|
453
|
-
wf.tag_add(options[:'<id>'], options[:'<tag>'].first)
|
454
|
-
end
|
455
|
-
|
456
|
-
def do_tag_delete
|
457
|
-
wf.tag_delete(options[:'<id>'], options[:'<tag>'].first)
|
458
|
-
end
|
459
|
-
|
460
|
-
def do_tag_set
|
461
|
-
wf.tag_set(options[:'<id>'], options[:'<tag>'])
|
462
|
-
end
|
463
|
-
|
464
|
-
def do_tag_clear
|
465
|
-
wf.tag_set(options[:'<id>'], [])
|
466
|
-
end
|
467
|
-
|
468
463
|
# Most things will re-import with the POST method if you remove
|
469
464
|
# the ID.
|
470
465
|
#
|
@@ -0,0 +1,84 @@
|
|
1
|
+
module WavefrontCli
|
2
|
+
module Mixin
|
3
|
+
#
|
4
|
+
# Standard ACL commands. Mix this module in to get ACL support.
|
5
|
+
#
|
6
|
+
module Acl
|
7
|
+
def do_acls
|
8
|
+
wf.acls([options[:'<id>']])
|
9
|
+
end
|
10
|
+
|
11
|
+
def do_acl_clear
|
12
|
+
wf.acl_set(options[:'<id>'], [], [everyone_id])
|
13
|
+
do_acls
|
14
|
+
end
|
15
|
+
|
16
|
+
def do_acl_grant
|
17
|
+
return grant_view if options[:view]
|
18
|
+
return grant_modify if options[:modify]
|
19
|
+
|
20
|
+
raise WavefrontCli::Exception::InsufficientData
|
21
|
+
end
|
22
|
+
|
23
|
+
def do_acl_revoke
|
24
|
+
return revoke_view if options[:view]
|
25
|
+
return revoke_modify if options[:modify]
|
26
|
+
|
27
|
+
raise WavefrontCli::Exception::InsufficientData
|
28
|
+
end
|
29
|
+
|
30
|
+
# @return [String] UUID of 'Everyone' group
|
31
|
+
# @raise WavefrontCli::Exception::UserGroupNotFound if group
|
32
|
+
# does not exist. This is caught in the controller.
|
33
|
+
#
|
34
|
+
def everyone_id
|
35
|
+
require 'wavefront-sdk/search'
|
36
|
+
wfs = Wavefront::Search.new(mk_creds, mk_opts)
|
37
|
+
query = conds_to_query(['name=Everyone'])
|
38
|
+
wfs.search(:usergroup, query).response.items.first.id
|
39
|
+
rescue RuntimeError
|
40
|
+
raise WavefrontCli::Exception::UserGroupNotFound, 'Everyone'
|
41
|
+
end
|
42
|
+
|
43
|
+
def grant_modify
|
44
|
+
wf.acl_add(options[:'<id>'], [], options[:'<name>'])
|
45
|
+
do_acls
|
46
|
+
end
|
47
|
+
|
48
|
+
def grant_view
|
49
|
+
wf.acl_add(options[:'<id>'], options[:'<name>'], [])
|
50
|
+
do_acls
|
51
|
+
end
|
52
|
+
|
53
|
+
def revoke_view
|
54
|
+
wf.acl_delete(options[:'<id>'], options[:'<name>'], [])
|
55
|
+
do_acls
|
56
|
+
end
|
57
|
+
|
58
|
+
def revoke_modify
|
59
|
+
wf.acl_delete(options[:'<id>'], [], options[:'<name>'])
|
60
|
+
do_acls
|
61
|
+
end
|
62
|
+
|
63
|
+
# @param action [Symbol] :grant_to or :revoke_from
|
64
|
+
# @return [Wavefront::Response]
|
65
|
+
#
|
66
|
+
def _acl_action(action)
|
67
|
+
entity_type, entities = acl_entities
|
68
|
+
|
69
|
+
resp = send(format('%s_%s', action, entity_type),
|
70
|
+
options[:'<id>'],
|
71
|
+
entities)
|
72
|
+
|
73
|
+
print_status(resp.status)
|
74
|
+
do_acls
|
75
|
+
end
|
76
|
+
|
77
|
+
def print_status(status)
|
78
|
+
puts status.message unless status.message.empty?
|
79
|
+
rescue NoMethodError
|
80
|
+
nil
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module WavefrontCli
|
2
|
+
module Mixin
|
3
|
+
#
|
4
|
+
# Standard tag commands
|
5
|
+
#
|
6
|
+
module Tag
|
7
|
+
def do_tags
|
8
|
+
wf.tags(options[:'<id>'])
|
9
|
+
end
|
10
|
+
|
11
|
+
def do_tag_add
|
12
|
+
wf.tag_add(options[:'<id>'], options[:'<tag>'].first)
|
13
|
+
end
|
14
|
+
|
15
|
+
def do_tag_delete
|
16
|
+
wf.tag_delete(options[:'<id>'], options[:'<tag>'].first)
|
17
|
+
end
|
18
|
+
|
19
|
+
def do_tag_set
|
20
|
+
wf.tag_set(options[:'<id>'], options[:'<tag>'])
|
21
|
+
end
|
22
|
+
|
23
|
+
def do_tag_clear
|
24
|
+
wf.tag_set(options[:'<id>'], [])
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -13,8 +13,11 @@ class WavefrontCommandAlert < WavefrontCommandBase
|
|
13
13
|
"snoozed #{CMN} [-o offset] [-L limit]",
|
14
14
|
"describe #{CMN} [-v version] <id>",
|
15
15
|
"delete #{CMN} <id>",
|
16
|
+
"clone #{CMN} [-v version] <id>",
|
16
17
|
"undelete #{CMN} <id>",
|
17
18
|
"history #{CMN} [-o offset] [-L limit] <id>",
|
19
|
+
"clone #{CMN} [-v version] <id>",
|
20
|
+
"latest #{CMN} <id>",
|
18
21
|
"import #{CMN} <file>",
|
19
22
|
"snooze #{CMN} [-T time] <id>",
|
20
23
|
"update #{CMN} <key=value> <id>",
|
@@ -29,6 +32,7 @@ class WavefrontCommandAlert < WavefrontCommandBase
|
|
29
32
|
"queries #{CMN} [-b] [<id>]",
|
30
33
|
"install #{CMN} <id>",
|
31
34
|
"uninstall #{CMN} <id>",
|
35
|
+
acl_commands,
|
32
36
|
"summary #{CMN} [-a]"]
|
33
37
|
end
|
34
38
|
|
@@ -50,10 +50,8 @@ class WavefrontCommandBase
|
|
50
50
|
def acl_commands
|
51
51
|
["acls #{CMN} <id>",
|
52
52
|
"acl #{CMN} clear <id>",
|
53
|
-
"acl #{CMN} grant (view | modify) on <id> to "
|
54
|
-
|
55
|
-
"acl #{CMN} revoke (view | modify) on <id> from " \
|
56
|
-
'(user | group) <name>...']
|
53
|
+
"acl #{CMN} grant (view | modify) on <id> to <name>...",
|
54
|
+
"acl #{CMN} revoke (view | modify) on <id> from <name>..."]
|
57
55
|
end
|
58
56
|
|
59
57
|
# Inheriting classes must override this method
|
@@ -142,8 +142,7 @@ class WavefrontCliController
|
|
142
142
|
abort "Unsupported writer '#{e.message}'."
|
143
143
|
rescue StandardError => e
|
144
144
|
warn "general error: #{e}"
|
145
|
-
warn "
|
146
|
-
warn "Backtrace:\n\t#{e.backtrace.join("\n\t")}" if opts[:debug]
|
145
|
+
warn "Backtrace:\n\t#{e.backtrace.join("\n\t")}"
|
147
146
|
abort
|
148
147
|
end
|
149
148
|
# rubocop:enable Metrics/MethodLength
|
@@ -1,10 +1,15 @@
|
|
1
1
|
require_relative 'base'
|
2
|
+
require_relative 'command_mixins/tag'
|
3
|
+
require_relative 'command_mixins/acl'
|
2
4
|
|
3
5
|
module WavefrontCli
|
4
6
|
#
|
5
7
|
# CLI coverage for the v2 'dashboard' API.
|
6
8
|
#
|
7
9
|
class Dashboard < WavefrontCli::Base
|
10
|
+
include WavefrontCli::Mixin::Tag
|
11
|
+
include WavefrontCli::Mixin::Acl
|
12
|
+
|
8
13
|
def list_filter(list)
|
9
14
|
return list unless options[:nosystem]
|
10
15
|
list.tap { |l| l.response.items.delete_if { |d| d[:systemOwned] } }
|
@@ -14,20 +19,9 @@ module WavefrontCli
|
|
14
19
|
wf.describe(options[:'<id>'], options[:version])
|
15
20
|
end
|
16
21
|
|
17
|
-
# rubocop:disable Metrics/AbcSize
|
18
22
|
def do_delete
|
19
|
-
|
20
|
-
|
21
|
-
word = if wf.describe(options[:'<id>']).status.code == 200
|
22
|
-
'Soft'
|
23
|
-
else
|
24
|
-
'Permanently'
|
25
|
-
end
|
26
|
-
|
27
|
-
puts "#{word} deleting dashboard '#{options[:'<id>']}'."
|
28
|
-
wf.delete(options[:'<id>'])
|
23
|
+
smart_delete
|
29
24
|
end
|
30
|
-
# rubocop:enable Metrics/AbcSize
|
31
25
|
|
32
26
|
def do_history
|
33
27
|
wf.history(options[:'<id>'])
|
@@ -59,136 +53,5 @@ module WavefrontCli
|
|
59
53
|
wf.unfavorite(options[:'<id>'])
|
60
54
|
do_favs
|
61
55
|
end
|
62
|
-
|
63
|
-
def do_acls
|
64
|
-
wf.acls([options[:'<id>']])
|
65
|
-
end
|
66
|
-
|
67
|
-
def do_acl_clear
|
68
|
-
wf.acl_set(options[:'<id>'], [], [id: everyone_id, name: 'Everyone'])
|
69
|
-
do_acls
|
70
|
-
end
|
71
|
-
|
72
|
-
def do_acl_grant
|
73
|
-
acl_action(:grant_to)
|
74
|
-
end
|
75
|
-
|
76
|
-
def do_acl_revoke
|
77
|
-
acl_action(:revoke_from)
|
78
|
-
end
|
79
|
-
|
80
|
-
# Based on command-line options, return an array describing the
|
81
|
-
# users or groups (entities) which will be granted or revoked a
|
82
|
-
# privilege.
|
83
|
-
# @return [Array] [type_of_entity, [Hash]...]
|
84
|
-
#
|
85
|
-
def acl_entities
|
86
|
-
acl_type = options[:modify] ? :modify : :view
|
87
|
-
|
88
|
-
if options[:user]
|
89
|
-
[:users, user_lists(acl_type, options[:'<name>'])]
|
90
|
-
else
|
91
|
-
[:groups, group_lists(acl_type, options[:'<name>'])]
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
# Make a list of users to be given to the SDK ACL methods. Users
|
96
|
-
# are defined as a Hash, with keys :id and :name.
|
97
|
-
# @param acl_type [Symbol] :view or :modify
|
98
|
-
# @param users [Array] user names
|
99
|
-
# @return [Array[Hash]]
|
100
|
-
#
|
101
|
-
def user_lists(acl_type, users)
|
102
|
-
{ view: [], modify: [] }.tap do |l|
|
103
|
-
l[acl_type] = users.map { |u| { id: u, name: u } }
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
# Generate arrays ready for passing to the SDK acl methods
|
108
|
-
# @return see #user_lists, but name and id are not the same.
|
109
|
-
#
|
110
|
-
def group_lists(acl_type, groups)
|
111
|
-
{ view: [], modify: [] }.tap do |l|
|
112
|
-
l[acl_type] = groups.each_with_object([]) do |g, a|
|
113
|
-
name = group_name(g)
|
114
|
-
|
115
|
-
if name.nil?
|
116
|
-
puts "Cannot find group with id '#{g}'."
|
117
|
-
next
|
118
|
-
end
|
119
|
-
|
120
|
-
a.<< ({ id: g, name: name })
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
private
|
126
|
-
|
127
|
-
# When given an ACL action (grant or revoke), call the right
|
128
|
-
# method with the right arguments.
|
129
|
-
# @param action [Symbol] :grant_to or :revoke_from
|
130
|
-
# @return [Wavefront::Response]
|
131
|
-
#
|
132
|
-
def acl_action(action)
|
133
|
-
entity_type, entities = acl_entities
|
134
|
-
|
135
|
-
resp = send(format('%s_%s', action, entity_type),
|
136
|
-
options[:'<id>'],
|
137
|
-
entities)
|
138
|
-
|
139
|
-
print_status(resp.status)
|
140
|
-
do_acls
|
141
|
-
end
|
142
|
-
|
143
|
-
# The #grant_to_ and #revoke_from_ methods are called by
|
144
|
-
# #acl_action, and speak to the SDK. They all return a
|
145
|
-
# Wavefront::Response object.
|
146
|
-
#
|
147
|
-
def grant_to_users(id, lists)
|
148
|
-
wf.acl_add(id, lists[:view], lists[:modify])
|
149
|
-
end
|
150
|
-
|
151
|
-
def revoke_from_users(id, lists)
|
152
|
-
wf.acl_delete(id, lists[:view], lists[:modify])
|
153
|
-
end
|
154
|
-
|
155
|
-
def grant_to_groups(id, lists)
|
156
|
-
wf.acl_add(id, lists[:view], lists[:modify])
|
157
|
-
end
|
158
|
-
|
159
|
-
def revoke_from_groups(id, lists)
|
160
|
-
wf.acl_delete(id, lists[:view], lists[:modify])
|
161
|
-
end
|
162
|
-
|
163
|
-
def print_status(status)
|
164
|
-
puts status.message unless status.message.empty?
|
165
|
-
rescue NoMethodError
|
166
|
-
nil
|
167
|
-
end
|
168
|
-
|
169
|
-
# Get the name of a user group, given the ID.
|
170
|
-
# @param group_id [String] UUID of a group
|
171
|
-
# @return [String, Nil] name of group, nil if it does not exist
|
172
|
-
#
|
173
|
-
def group_name(group_id)
|
174
|
-
require 'wavefront-sdk/usergroup'
|
175
|
-
wfs = Wavefront::UserGroup.new(mk_creds, mk_opts)
|
176
|
-
wfs.describe(group_id).response.name
|
177
|
-
rescue RuntimeError
|
178
|
-
nil
|
179
|
-
end
|
180
|
-
|
181
|
-
# @return [String] UUID of 'Everyone' group
|
182
|
-
# @raise WavefrontCli::Exception::UserGroupNotFound if group
|
183
|
-
# does not exist. This is caught in the controller.
|
184
|
-
#
|
185
|
-
def everyone_id
|
186
|
-
require 'wavefront-sdk/search'
|
187
|
-
wfs = Wavefront::Search.new(mk_creds, mk_opts)
|
188
|
-
query = conds_to_query(['name=Everyone'])
|
189
|
-
wfs.search(:usergroup, query).response.items.first.id
|
190
|
-
rescue RuntimeError
|
191
|
-
raise WavefrontCli::Exception::UserGroupNotFound, 'Everyone'
|
192
|
-
end
|
193
56
|
end
|
194
57
|
end
|
@@ -1,10 +1,13 @@
|
|
1
1
|
require_relative 'base'
|
2
|
+
require_relative 'command_mixins/tag'
|
2
3
|
|
3
4
|
module WavefrontCli
|
4
5
|
#
|
5
6
|
# CLI coverage for the v2 'derivedmetric' API.
|
6
7
|
#
|
7
8
|
class DerivedMetric < WavefrontCli::Base
|
9
|
+
include WavefrontCli::Mixin::Tag
|
10
|
+
|
8
11
|
def validator_exception
|
9
12
|
Wavefront::Exception::InvalidDerivedMetricId
|
10
13
|
end
|
@@ -13,22 +16,9 @@ module WavefrontCli
|
|
13
16
|
wf.describe(options[:'<id>'], options[:version])
|
14
17
|
end
|
15
18
|
|
16
|
-
# rubocop:disable Metrics/AbcSize
|
17
19
|
def do_delete
|
18
|
-
|
19
|
-
|
20
|
-
word = if wf.describe(options[:'<id>']).status.code == 200
|
21
|
-
'Soft'
|
22
|
-
else
|
23
|
-
'Permanently'
|
24
|
-
end
|
25
|
-
|
26
|
-
puts format('%s deleting derived metric definition %s', word,
|
27
|
-
options[:'<id>'])
|
28
|
-
|
29
|
-
wf.delete(options[:'<id>'])
|
20
|
+
smart_delete('derived metric')
|
30
21
|
end
|
31
|
-
# rubocop:enable Metrics/AbcSize
|
32
22
|
|
33
23
|
def do_history
|
34
24
|
wf.history(options[:'<id>'])
|
@@ -48,6 +48,10 @@ module WavefrontDisplay
|
|
48
48
|
puts "Unsnoozed alert '#{options[:'<id>']}'."
|
49
49
|
end
|
50
50
|
|
51
|
+
def do_latest
|
52
|
+
puts data.max
|
53
|
+
end
|
54
|
+
|
51
55
|
# rubocop:disable Metrics/AbcSize
|
52
56
|
def do_summary
|
53
57
|
kw = data.keys.map(&:size).max + 2
|
@@ -63,5 +67,9 @@ module WavefrontDisplay
|
|
63
67
|
multicolumn(:id, :condition)
|
64
68
|
end
|
65
69
|
end
|
70
|
+
|
71
|
+
def do_version
|
72
|
+
puts data.max
|
73
|
+
end
|
66
74
|
end
|
67
75
|
end
|
data/lib/wavefront-cli/event.rb
CHANGED
@@ -2,6 +2,7 @@ require 'fileutils'
|
|
2
2
|
require 'open3'
|
3
3
|
require 'wavefront-sdk/support/mixins'
|
4
4
|
require_relative 'base'
|
5
|
+
require_relative 'command_mixins/tag'
|
5
6
|
|
6
7
|
EVENT_STATE_DIR = Pathname.new('/var/tmp/wavefront')
|
7
8
|
|
@@ -12,6 +13,7 @@ module WavefrontCli
|
|
12
13
|
class Event < Base
|
13
14
|
attr_reader :state_dir
|
14
15
|
include Wavefront::Mixins
|
16
|
+
include WavefrontCli::Mixin::Tag
|
15
17
|
|
16
18
|
def post_initialize(_options)
|
17
19
|
@state_dir = EVENT_STATE_DIR + (Etc.getlogin || 'notty')
|
data/lib/wavefront-cli/source.rb
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
require_relative 'base'
|
2
|
+
require_relative 'command_mixins/tag'
|
2
3
|
|
3
4
|
module WavefrontCli
|
4
5
|
#
|
5
6
|
# CLI coverage for the v2 'source' API.
|
6
7
|
#
|
7
8
|
class Source < WavefrontCli::Base
|
9
|
+
include WavefrontCli::Mixin::Tag
|
10
|
+
|
8
11
|
def do_list
|
9
12
|
wf.list(options[:limit], options[:cursor])
|
10
13
|
end
|
@@ -1 +1 @@
|
|
1
|
-
WF_CLI_VERSION = '3.2.
|
1
|
+
WF_CLI_VERSION = '3.2.1'.freeze
|
data/spec/.rubocop.yml
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -64,6 +64,8 @@ class DummyResponse
|
|
64
64
|
def empty?
|
65
65
|
false
|
66
66
|
end
|
67
|
+
|
68
|
+
def status; end
|
67
69
|
end
|
68
70
|
|
69
71
|
CANNED_RESPONSE = DummyResponse.new
|
@@ -75,9 +77,11 @@ CANNED_RESPONSE = DummyResponse.new
|
|
75
77
|
# @param cmd [String] command line args to supply to the Wavefront
|
76
78
|
# command
|
77
79
|
# @param call [Hash]
|
80
|
+
# @param spies [Array[Hash]] array of spies to set up, for stubbing
|
81
|
+
# methods in any class. Hash has keys :class, :method, :return.
|
78
82
|
# rubocop:disable Metrics/AbcSize
|
79
83
|
# rubocop:disable Metrics/PerceivedComplexity
|
80
|
-
def cmd_to_call(word, args, call, sdk_class = nil,
|
84
|
+
def cmd_to_call(word, args, call, sdk_class = nil, spies = [])
|
81
85
|
headers = { 'Accept': /.*/,
|
82
86
|
'Accept-Encoding': /.*/,
|
83
87
|
'Authorization': 'Bearer 0123456789-ABCDEF',
|
@@ -115,16 +119,10 @@ def cmd_to_call(word, args, call, sdk_class = nil, extra_method = nil)
|
|
115
119
|
end
|
116
120
|
|
117
121
|
require "wavefront-sdk/#{sdk_class.name.split('::').last.downcase}"
|
118
|
-
|
119
|
-
# thing we're interested in. For instance when you
|
120
|
-
# favourite a dashboard, the CLI calls do_favs to display
|
121
|
-
# the new favourite list, sending another API call, which
|
122
|
-
# has been tested elsewhere.
|
123
|
-
#
|
124
|
-
if extra_method
|
122
|
+
spies.each do |spy|
|
125
123
|
Spy.on_instance_method(
|
126
|
-
Object.const_get(
|
127
|
-
).and_return(
|
124
|
+
Object.const_get(spy[:class]), spy[:method]
|
125
|
+
).and_return(spy[:return])
|
128
126
|
end
|
129
127
|
|
130
128
|
Spy.on_instance_method(
|
@@ -315,11 +313,75 @@ def tag_tests(cmd, id, bad_id, pth = nil, klass = nil)
|
|
315
313
|
"tag delete #{id} #{BAD_TAG}"])
|
316
314
|
end
|
317
315
|
|
316
|
+
def acl_tests(cmd, id, bad_id, pth = nil, klass = nil)
|
317
|
+
gid1 = '2659191e-aad4-4302-a94e-9667e1517127'
|
318
|
+
pth ||= cmd
|
319
|
+
|
320
|
+
cmd_to_call(cmd, "acls #{id}", { path: "/api/v2/#{pth}/acl?id=#{id}" },
|
321
|
+
klass)
|
322
|
+
|
323
|
+
spies = [{ class: "WavefrontCli::#{cmd.capitalize}",
|
324
|
+
method: :do_acls,
|
325
|
+
return: true }]
|
326
|
+
|
327
|
+
cmd_to_call(cmd, "acl clear #{id}",
|
328
|
+
{ method: :put,
|
329
|
+
path: "/api/v2/#{pth}/acl/set",
|
330
|
+
body: [{ entityId: id,
|
331
|
+
viewAcl: [],
|
332
|
+
modifyAcl: %w[abcd-1234] }].to_json,
|
333
|
+
headers: JSON_POST_HEADERS }, klass, [
|
334
|
+
{ class: "WavefrontCli::#{cmd.capitalize}",
|
335
|
+
method: :everyone_id,
|
336
|
+
return: 'abcd-1234' },
|
337
|
+
{ class: "WavefrontCli::#{cmd.capitalize}",
|
338
|
+
method: :do_acls,
|
339
|
+
return: true }
|
340
|
+
])
|
341
|
+
|
342
|
+
cmd_to_call(cmd, "acl grant view on #{id} to testuser1 testuser2",
|
343
|
+
{ method: :post,
|
344
|
+
path: "/api/v2/#{pth}/acl/add",
|
345
|
+
body: [{ entityId: id,
|
346
|
+
viewAcl: %w[testuser1 testuser2],
|
347
|
+
modifyAcl: [] }].to_json,
|
348
|
+
headers: JSON_POST_HEADERS }, klass, spies)
|
349
|
+
cmd_to_call(cmd, "acl revoke view on #{id} from testuser1",
|
350
|
+
{ method: :post,
|
351
|
+
path: "/api/v2/#{pth}/acl/remove",
|
352
|
+
body: [{ entityId: id,
|
353
|
+
viewAcl: %w[testuser1],
|
354
|
+
modifyAcl: [] }].to_json,
|
355
|
+
headers: JSON_POST_HEADERS }, klass, spies)
|
356
|
+
|
357
|
+
cmd_to_call(cmd, "acl grant modify on #{id} to testuser1",
|
358
|
+
{ method: :post,
|
359
|
+
path: "/api/v2/#{pth}/acl/add",
|
360
|
+
body: [{ entityId: id,
|
361
|
+
viewAcl: [],
|
362
|
+
modifyAcl: %w[testuser1] }].to_json,
|
363
|
+
headers: JSON_POST_HEADERS }, klass, spies)
|
364
|
+
cmd_to_call(cmd, "acl revoke modify on #{id} from testuser1",
|
365
|
+
{ method: :post,
|
366
|
+
path: "/api/v2/#{pth}/acl/remove",
|
367
|
+
body: [{ entityId: id,
|
368
|
+
viewAcl: [],
|
369
|
+
modifyAcl: %w[testuser1] }].to_json,
|
370
|
+
headers: JSON_POST_HEADERS }, klass, spies)
|
371
|
+
|
372
|
+
invalid_ids(cmd, ["acls #{bad_id}",
|
373
|
+
"acl clear #{bad_id}",
|
374
|
+
"acl grant modify on #{bad_id} to testuser1",
|
375
|
+
"acl revoke view on #{bad_id} from #{gid1}"])
|
376
|
+
end
|
377
|
+
|
378
|
+
# Unit tests
|
379
|
+
#
|
318
380
|
class CliMethodTest < MiniTest::Test
|
319
381
|
attr_reader :wf
|
320
382
|
|
321
383
|
def setup
|
322
|
-
@wf =
|
384
|
+
@wf = cliclass.new({})
|
323
385
|
end
|
324
386
|
|
325
387
|
def import_tester(word, have_fields, do_not_have_fields = [])
|
@@ -19,16 +19,29 @@ require_relative '../spec_helper'
|
|
19
19
|
require_relative "../../lib/wavefront-cli/#{word}"
|
20
20
|
|
21
21
|
describe "#{word} command" do
|
22
|
-
missing_creds(word, ['list',
|
23
|
-
|
24
|
-
"
|
25
|
-
'
|
26
|
-
|
22
|
+
missing_creds(word, ['list',
|
23
|
+
"describe #{id}",
|
24
|
+
"snooze #{id}",
|
25
|
+
'queries',
|
26
|
+
'snoozed',
|
27
|
+
"clone #{id}",
|
28
|
+
"install #{id}",
|
29
|
+
"uninstall #{id}",
|
30
|
+
'firing',
|
31
|
+
'currently firing',
|
32
|
+
'summary',
|
33
|
+
"acls #{id}",
|
34
|
+
"acl grant view on #{id} to testuser1",
|
35
|
+
"acl revoke modify on #{id} from group1",
|
36
|
+
"delete #{id}",
|
37
|
+
"undelete #{id}",
|
38
|
+
"history #{id}"])
|
27
39
|
list_tests(word)
|
28
40
|
cmd_to_call(word, "describe #{id}", path: "/api/v2/#{word}/#{id}")
|
29
41
|
cmd_to_call(word, "describe -v 7 #{id}",
|
30
42
|
path: "/api/v2/#{word}/#{id}/history/7")
|
31
43
|
cmd_to_call(word, "history #{id}", path: "/api/v2/#{word}/#{id}/history")
|
44
|
+
cmd_to_call(word, "latest #{id}", path: "/api/v2/#{word}/#{id}/history")
|
32
45
|
|
33
46
|
it 'deletes with a check on inTrash' do
|
34
47
|
stub_request(:get,
|
@@ -43,6 +56,12 @@ describe "#{word} command" do
|
|
43
56
|
method: :delete, path: "/api/v2/#{word}/#{id}")
|
44
57
|
end
|
45
58
|
|
59
|
+
cmd_to_call(word, "clone #{id}",
|
60
|
+
method: :post, path: "/api/v2/#{word}/#{id}/clone")
|
61
|
+
cmd_to_call(word, "clone #{id} -v 5",
|
62
|
+
method: :post,
|
63
|
+
path: "/api/v2/#{word}/#{id}/clone",
|
64
|
+
body: { id: id, v: 5, name: nil })
|
46
65
|
cmd_to_call(word, "undelete #{id}",
|
47
66
|
method: :post, path: "/api/v2/#{word}/#{id}/undelete")
|
48
67
|
cmd_to_call(word, "snooze #{id}",
|
@@ -90,15 +109,18 @@ describe "#{word} command" do
|
|
90
109
|
tag_tests(word, id, bad_id)
|
91
110
|
noop_tests(word, id, true)
|
92
111
|
test_list_output(word)
|
112
|
+
acl_tests(word, id, bad_id)
|
93
113
|
end
|
94
114
|
|
95
|
-
CliClass = WavefrontCli::Alert
|
96
|
-
|
97
115
|
class TestAlertMethods < CliMethodTest
|
98
116
|
def test_import_method
|
99
117
|
import_tester(:window,
|
100
|
-
%i[
|
101
|
-
|
118
|
+
%i[condition displayExpression resolveAfterMinutes
|
119
|
+
minutes severity tags target name],
|
102
120
|
%i[id])
|
103
121
|
end
|
122
|
+
|
123
|
+
def cliclass
|
124
|
+
WavefrontCli::Alert
|
125
|
+
end
|
104
126
|
end
|
@@ -85,59 +85,97 @@ class WavefrontCliConfigTest < MiniTest::Test
|
|
85
85
|
input_list = %w[2501b9c3-61e3-4f07-bee2-250aa06a9cab
|
86
86
|
test.wavefront.com myproxy json]
|
87
87
|
|
88
|
-
|
89
|
-
wfo.
|
88
|
+
out, err = capture_io do
|
89
|
+
x = wfo.stub(:read_input, proc { input_list.shift }) do
|
90
|
+
wfo.create_profile('prof')
|
91
|
+
end
|
92
|
+
|
93
|
+
assert_instance_of(IniFile, x)
|
94
|
+
assert_equal('2501b9c3-61e3-4f07-bee2-250aa06a9cab',
|
95
|
+
x[:prof]['token'])
|
96
|
+
assert_equal('test.wavefront.com', x[:prof]['endpoint'])
|
97
|
+
assert_equal('myproxy', x[:prof]['proxy'])
|
98
|
+
assert_equal('json', x[:prof]['format'])
|
90
99
|
end
|
91
100
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
101
|
+
assert_match(/Creating profile 'prof'./, out)
|
102
|
+
assert_match(/Wavefront API token/, out)
|
103
|
+
assert_match(/Wavefront API endpoint/, out)
|
104
|
+
assert_match(/Wavefront proxy endpoint/, out)
|
105
|
+
assert_match(/default output format/, out)
|
106
|
+
assert_empty(err)
|
97
107
|
end
|
98
108
|
|
99
109
|
def test_create_profile_2
|
100
110
|
input_list = ['2501b9c3-61e3-4f07-bee2-250aa06a9cab', '', '', '']
|
101
111
|
|
102
|
-
|
103
|
-
wfo.
|
112
|
+
out, err = capture_io do
|
113
|
+
x = wfo.stub(:read_input, proc { input_list.shift }) do
|
114
|
+
wfo.create_profile('prof')
|
115
|
+
end
|
116
|
+
|
117
|
+
assert_instance_of(IniFile, x)
|
118
|
+
assert_equal('2501b9c3-61e3-4f07-bee2-250aa06a9cab',
|
119
|
+
x[:prof]['token'])
|
120
|
+
assert_equal('metrics.wavefront.com', x[:prof]['endpoint'])
|
121
|
+
assert_equal('wavefront', x[:prof]['proxy'])
|
122
|
+
assert_equal('human', x[:prof]['format'])
|
104
123
|
end
|
105
124
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
125
|
+
assert_match(/Creating profile 'prof'./, out)
|
126
|
+
assert_match(/Wavefront API token/, out)
|
127
|
+
assert_match(/Wavefront API endpoint/, out)
|
128
|
+
assert_match(/Wavefront proxy endpoint/, out)
|
129
|
+
assert_match(/default output format/, out)
|
130
|
+
assert_empty(err)
|
111
131
|
end
|
112
132
|
|
113
133
|
def test_create_profile_3
|
114
134
|
input_list = ['X501b9c3-61e3-4f07-bee2-250aa06a9cab', '', '', '']
|
115
135
|
|
116
|
-
|
117
|
-
|
118
|
-
wfo.
|
136
|
+
out, err = capture_io do
|
137
|
+
assert_raises(WavefrontCli::Exception::InvalidValue) do
|
138
|
+
wfo.stub(:read_input, proc { input_list.shift }) do
|
139
|
+
wfo.create_profile('prof')
|
140
|
+
end
|
119
141
|
end
|
120
142
|
end
|
143
|
+
|
144
|
+
assert_match(/Creating profile 'prof'./, out)
|
145
|
+
assert_match(/Wavefront API token/, out)
|
146
|
+
assert_empty(err)
|
121
147
|
end
|
122
148
|
|
123
149
|
def test_create_profile_4
|
124
150
|
input_list = ['2501b9c3-61e3-4f07-bee2-250aa06a9cab', 'end', '', '']
|
125
151
|
|
126
|
-
|
127
|
-
|
128
|
-
wfo.
|
152
|
+
out, err = capture_io do
|
153
|
+
assert_raises(WavefrontCli::Exception::InvalidValue) do
|
154
|
+
wfo.stub(:read_input, proc { input_list.shift }) do
|
155
|
+
wfo.create_profile('prof')
|
156
|
+
end
|
129
157
|
end
|
130
158
|
end
|
159
|
+
|
160
|
+
assert_match(/Creating profile 'prof'./, out)
|
161
|
+
assert_match(/Wavefront API token/, out)
|
162
|
+
assert_empty(err)
|
131
163
|
end
|
132
164
|
|
133
165
|
def test_create_profile_5
|
134
166
|
input_list = ['', '', '', '']
|
135
167
|
|
136
|
-
|
137
|
-
|
138
|
-
wfo.
|
168
|
+
out, err = capture_io do
|
169
|
+
assert_raises(WavefrontCli::Exception::MandatoryValue) do
|
170
|
+
wfo.stub(:read_input, proc { input_list.shift }) do
|
171
|
+
wfo.create_profile('prof')
|
172
|
+
end
|
139
173
|
end
|
140
174
|
end
|
175
|
+
|
176
|
+
assert_match(/Creating profile 'prof'./, out)
|
177
|
+
assert_match(/Wavefront API token/, out)
|
178
|
+
assert_empty(err)
|
141
179
|
end
|
142
180
|
|
143
181
|
def test_do_setup; end
|
@@ -7,7 +7,7 @@ require_relative '../../lib/wavefront-cli/controller'
|
|
7
7
|
#
|
8
8
|
class WavefrontCliHelpTest < MiniTest::Test
|
9
9
|
def test_no_args
|
10
|
-
WavefrontCliController.new([])
|
10
|
+
capture_io { WavefrontCliController.new([]) }
|
11
11
|
rescue SystemExit => e
|
12
12
|
assert_equal(1, e.status)
|
13
13
|
assert_match(/^Usage/, e.message)
|
@@ -16,14 +16,14 @@ class WavefrontCliHelpTest < MiniTest::Test
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def test_version
|
19
|
-
WavefrontCliController.new(%w[--version])
|
19
|
+
capture_io { WavefrontCliController.new(%w[--version]) }
|
20
20
|
rescue SystemExit => e
|
21
21
|
assert_equal(1, e.status)
|
22
22
|
assert_match(/^\d+\.\d+\.\d+$/, e.message)
|
23
23
|
end
|
24
24
|
|
25
25
|
def test_help
|
26
|
-
WavefrontCliController.new(%w[--help])
|
26
|
+
capture_io { WavefrontCliController.new(%w[--help]) }
|
27
27
|
rescue SystemExit => e
|
28
28
|
assert_equal(1, e.status)
|
29
29
|
assert_match(/^Commands:$/, e.message)
|
@@ -33,7 +33,7 @@ class WavefrontCliHelpTest < MiniTest::Test
|
|
33
33
|
def test_command_help
|
34
34
|
CMDS.each do |cmd|
|
35
35
|
begin
|
36
|
-
WavefrontCliController.new([cmd, '--help'])
|
36
|
+
capture_io { WavefrontCliController.new([cmd, '--help']) }
|
37
37
|
rescue SystemExit => e
|
38
38
|
assert(e.message.split("\n").map(&:size).max <= TW)
|
39
39
|
assert_equal(1, e.status)
|
@@ -46,15 +46,19 @@ class WavefrontCliHelpTest < MiniTest::Test
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def test_malformed_config
|
49
|
-
|
50
|
-
|
49
|
+
capture_io do
|
50
|
+
WavefrontCliController.new(['alert', 'list',
|
51
|
+
"--config=#{RES_DIR}/malformed.conf"])
|
52
|
+
end
|
51
53
|
rescue SystemExit => e
|
52
54
|
assert_equal(1, e.status)
|
53
55
|
assert e.message.start_with?('Could not load configuration file')
|
54
56
|
end
|
55
57
|
|
56
58
|
def test_missing_config
|
57
|
-
|
59
|
+
capture_io do
|
60
|
+
WavefrontCliController.new(%w[alert list --config=/no/such/file])
|
61
|
+
end
|
58
62
|
rescue SystemExit => e
|
59
63
|
assert_equal(1, e.status)
|
60
64
|
assert_equal("Configuration file '/no/such/file' not found.", e.message)
|
@@ -7,28 +7,6 @@ word = 'dashboard'
|
|
7
7
|
require_relative '../spec_helper'
|
8
8
|
require_relative "../../lib/wavefront-cli/#{word}"
|
9
9
|
|
10
|
-
# Method tests. CLI tests follow
|
11
|
-
#
|
12
|
-
class WavefrontCliDashboardTest < MiniTest::Test
|
13
|
-
attr_reader :wf
|
14
|
-
|
15
|
-
def setup
|
16
|
-
@wf = WavefrontCli::Dashboard.new({})
|
17
|
-
end
|
18
|
-
|
19
|
-
def test_user_lists
|
20
|
-
assert_equal({ modify: [],
|
21
|
-
view: [{ name: 'a@bc.com', id: 'a@bc.com' },
|
22
|
-
{ name: 'x@yz.com', id: 'x@yz.com' }] },
|
23
|
-
wf.user_lists(:view, %w[a@bc.com x@yz.com]))
|
24
|
-
|
25
|
-
assert_equal({ view: [],
|
26
|
-
modify: [{ name: 'a@bc.com', id: 'a@bc.com' },
|
27
|
-
{ name: 'x@yz.com', id: 'x@yz.com' }] },
|
28
|
-
wf.user_lists(:modify, %w[a@bc.com x@yz.com]))
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
10
|
describe "#{word} command" do
|
33
11
|
missing_creds(word, ['list', "describe #{id}", "delete #{id}",
|
34
12
|
"undelete #{id}", "history #{id}"])
|
@@ -73,30 +51,38 @@ describe "#{word} command" do
|
|
73
51
|
sort: { field: 'id',
|
74
52
|
ascending: true } }.to_json)
|
75
53
|
|
54
|
+
spies = [{ class: 'WavefrontCli::Dashboard',
|
55
|
+
method: :do_favs,
|
56
|
+
return: nil }]
|
57
|
+
|
76
58
|
cmd_to_call(word,
|
77
59
|
"fav #{id}",
|
78
60
|
{ method: :post,
|
79
61
|
path: "/api/v2/#{word}/#{id}/favorite" },
|
80
62
|
nil,
|
81
|
-
|
63
|
+
spies)
|
82
64
|
|
83
65
|
cmd_to_call(word,
|
84
66
|
"unfav #{id}",
|
85
67
|
{ method: :post,
|
86
68
|
path: "/api/v2/#{word}/#{id}/unfavorite" },
|
87
69
|
nil,
|
88
|
-
|
70
|
+
spies)
|
71
|
+
|
89
72
|
cmd_to_call(word, "undelete #{id}",
|
90
73
|
method: :post, path: "/api/v2/#{word}/#{id}/undelete")
|
91
74
|
invalid_ids(word, ["describe #{bad_id}", "delete #{bad_id}",
|
92
75
|
"undelete #{bad_id}"])
|
93
76
|
tag_tests(word, id, bad_id)
|
94
77
|
test_list_output(word)
|
78
|
+
acl_tests(word, id, bad_id)
|
95
79
|
end
|
96
80
|
|
97
|
-
CliClass = WavefrontCli::Dashboard
|
98
|
-
|
99
81
|
class TestAlertMethods < CliMethodTest
|
82
|
+
def cliclass
|
83
|
+
WavefrontCli::Dashboard
|
84
|
+
end
|
85
|
+
|
100
86
|
def test_import_method
|
101
87
|
import_tester(:dashboard,
|
102
88
|
%i[description name parameters tags url creatorId
|
@@ -80,12 +80,14 @@ describe "#{word} command" do
|
|
80
80
|
test_list_output(word, k)
|
81
81
|
end
|
82
82
|
|
83
|
-
CliClass = WavefrontCli::DerivedMetric
|
84
|
-
|
85
83
|
class TestDerivedMetricMethods < CliMethodTest
|
86
84
|
def test_import_method
|
87
85
|
import_tester(:derivedmetric,
|
88
86
|
%i[tags minutes name query metricsUsed hostsUsed],
|
89
87
|
%i[id])
|
90
88
|
end
|
89
|
+
|
90
|
+
def cliclass
|
91
|
+
WavefrontCli::DerivedMetric
|
92
|
+
end
|
91
93
|
end
|
@@ -37,9 +37,11 @@ describe "#{word} command" do
|
|
37
37
|
test_list_output(word, k)
|
38
38
|
end
|
39
39
|
|
40
|
-
CliClass = WavefrontCli::MaintenanceWindow
|
41
|
-
|
42
40
|
class TestMaintenanceWindowMethods < CliMethodTest
|
41
|
+
def cliclass
|
42
|
+
WavefrontCli::MaintenanceWindow
|
43
|
+
end
|
44
|
+
|
43
45
|
def test_import_method
|
44
46
|
import_tester(:window,
|
45
47
|
%i[startTimeInSeconds endTimeInSeconds
|
@@ -34,12 +34,14 @@ describe "#{word} command" do
|
|
34
34
|
test_list_output(word)
|
35
35
|
end
|
36
36
|
|
37
|
-
CliClass = WavefrontCli::Notificant
|
38
|
-
|
39
37
|
class TestNotificantMethods < CliMethodTest
|
40
38
|
def test_import_method
|
41
39
|
import_tester(:notificant,
|
42
40
|
%i[method title creatorId triggers template],
|
43
41
|
%i[id])
|
44
42
|
end
|
43
|
+
|
44
|
+
def cliclass
|
45
|
+
WavefrontCli::Notificant
|
46
|
+
end
|
45
47
|
end
|
@@ -20,7 +20,7 @@ class OptHandlerTest < MiniTest::Test
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def test_missing_config
|
23
|
-
WavefrontCli::OptHandler.new(config: '/no/such/file')
|
23
|
+
capture_io { WavefrontCli::OptHandler.new(config: '/no/such/file') }
|
24
24
|
rescue SystemExit => e
|
25
25
|
assert_equal(1, e.status)
|
26
26
|
assert_match("Configuration file '/no/such/file' not found.", e.message)
|
data/wavefront-cli.gemspec
CHANGED
@@ -24,13 +24,13 @@ Gem::Specification.new do |gem|
|
|
24
24
|
|
25
25
|
gem.add_runtime_dependency 'docopt', '~> 0.6.0'
|
26
26
|
gem.add_runtime_dependency 'inifile', '~> 3.0'
|
27
|
-
gem.add_runtime_dependency 'wavefront-sdk', '~> 3.
|
27
|
+
gem.add_runtime_dependency 'wavefront-sdk', '~> 3.3', '>= 3.3.0'
|
28
28
|
|
29
29
|
gem.add_development_dependency 'minitest', '~> 5.11', '>= 5.11.0'
|
30
30
|
gem.add_development_dependency 'rake', '~> 12.0'
|
31
31
|
gem.add_development_dependency 'rubocop', '~> 0.54.0'
|
32
|
-
gem.add_development_dependency 'spy', '~> 0.
|
33
|
-
gem.add_development_dependency 'webmock', '~> 3.
|
32
|
+
gem.add_development_dependency 'spy', '~> 1.0.0'
|
33
|
+
gem.add_development_dependency 'webmock', '~> 3.5'
|
34
34
|
gem.add_development_dependency 'yard', '~> 0.9.5'
|
35
35
|
|
36
36
|
gem.required_ruby_version = Gem::Requirement.new('>= 2.3.0')
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wavefront-cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.2.
|
4
|
+
version: 3.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Fisher
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-05-
|
11
|
+
date: 2019-05-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: docopt
|
@@ -44,20 +44,20 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 3.
|
47
|
+
version: 3.3.0
|
48
48
|
- - "~>"
|
49
49
|
- !ruby/object:Gem::Version
|
50
|
-
version: '3.
|
50
|
+
version: '3.3'
|
51
51
|
type: :runtime
|
52
52
|
prerelease: false
|
53
53
|
version_requirements: !ruby/object:Gem::Requirement
|
54
54
|
requirements:
|
55
55
|
- - ">="
|
56
56
|
- !ruby/object:Gem::Version
|
57
|
-
version: 3.
|
57
|
+
version: 3.3.0
|
58
58
|
- - "~>"
|
59
59
|
- !ruby/object:Gem::Version
|
60
|
-
version: '3.
|
60
|
+
version: '3.3'
|
61
61
|
- !ruby/object:Gem::Dependency
|
62
62
|
name: minitest
|
63
63
|
requirement: !ruby/object:Gem::Requirement
|
@@ -112,28 +112,28 @@ dependencies:
|
|
112
112
|
requirements:
|
113
113
|
- - "~>"
|
114
114
|
- !ruby/object:Gem::Version
|
115
|
-
version: 0.
|
115
|
+
version: 1.0.0
|
116
116
|
type: :development
|
117
117
|
prerelease: false
|
118
118
|
version_requirements: !ruby/object:Gem::Requirement
|
119
119
|
requirements:
|
120
120
|
- - "~>"
|
121
121
|
- !ruby/object:Gem::Version
|
122
|
-
version: 0.
|
122
|
+
version: 1.0.0
|
123
123
|
- !ruby/object:Gem::Dependency
|
124
124
|
name: webmock
|
125
125
|
requirement: !ruby/object:Gem::Requirement
|
126
126
|
requirements:
|
127
127
|
- - "~>"
|
128
128
|
- !ruby/object:Gem::Version
|
129
|
-
version: '3.
|
129
|
+
version: '3.5'
|
130
130
|
type: :development
|
131
131
|
prerelease: false
|
132
132
|
version_requirements: !ruby/object:Gem::Requirement
|
133
133
|
requirements:
|
134
134
|
- - "~>"
|
135
135
|
- !ruby/object:Gem::Version
|
136
|
-
version: '3.
|
136
|
+
version: '3.5'
|
137
137
|
- !ruby/object:Gem::Dependency
|
138
138
|
name: yard
|
139
139
|
requirement: !ruby/object:Gem::Requirement
|
@@ -169,6 +169,8 @@ files:
|
|
169
169
|
- lib/wavefront-cli/apitoken.rb
|
170
170
|
- lib/wavefront-cli/base.rb
|
171
171
|
- lib/wavefront-cli/cloudintegration.rb
|
172
|
+
- lib/wavefront-cli/command_mixins/acl.rb
|
173
|
+
- lib/wavefront-cli/command_mixins/tag.rb
|
172
174
|
- lib/wavefront-cli/commands/.rubocop.yml
|
173
175
|
- lib/wavefront-cli/commands/alert.rb
|
174
176
|
- lib/wavefront-cli/commands/apitoken.rb
|