wavefront-cli 4.2.1 → 4.3.0
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/.codeclimate.yml +1 -0
- data/.rubocop.yml +1 -14
- data/.travis.yml +4 -4
- data/Gemfile +2 -0
- data/HISTORY.md +82 -60
- data/Rakefile +2 -0
- data/bin/wf +1 -0
- data/lib/wavefront-cli/alert.rb +13 -5
- data/lib/wavefront-cli/apitoken.rb +2 -0
- data/lib/wavefront-cli/base.rb +95 -47
- data/lib/wavefront-cli/cloudintegration.rb +6 -0
- data/lib/wavefront-cli/command_mixins/acl.rb +6 -1
- data/lib/wavefront-cli/command_mixins/tag.rb +2 -0
- data/lib/wavefront-cli/commands/.rubocop.yml +3 -4
- data/lib/wavefront-cli/commands/alert.rb +2 -1
- data/lib/wavefront-cli/commands/apitoken.rb +6 -0
- data/lib/wavefront-cli/commands/base.rb +30 -21
- data/lib/wavefront-cli/commands/cloudintegration.rb +2 -0
- data/lib/wavefront-cli/commands/config.rb +2 -0
- data/lib/wavefront-cli/commands/dashboard.rb +2 -0
- data/lib/wavefront-cli/commands/derivedmetric.rb +2 -0
- data/lib/wavefront-cli/commands/event.rb +3 -1
- data/lib/wavefront-cli/commands/integration.rb +2 -1
- data/lib/wavefront-cli/commands/link.rb +2 -0
- data/lib/wavefront-cli/commands/message.rb +2 -0
- data/lib/wavefront-cli/commands/metric.rb +2 -0
- data/lib/wavefront-cli/commands/notificant.rb +2 -0
- data/lib/wavefront-cli/commands/proxy.rb +2 -0
- data/lib/wavefront-cli/commands/query.rb +2 -0
- data/lib/wavefront-cli/commands/savedsearch.rb +2 -0
- data/lib/wavefront-cli/commands/serviceaccount.rb +58 -0
- data/lib/wavefront-cli/commands/settings.rb +2 -0
- data/lib/wavefront-cli/commands/source.rb +3 -1
- data/lib/wavefront-cli/commands/user.rb +4 -1
- data/lib/wavefront-cli/commands/usergroup.rb +3 -0
- data/lib/wavefront-cli/commands/webhook.rb +2 -0
- data/lib/wavefront-cli/commands/window.rb +2 -0
- data/lib/wavefront-cli/commands/write.rb +2 -0
- data/lib/wavefront-cli/config.rb +23 -12
- data/lib/wavefront-cli/constants.rb +10 -4
- data/lib/wavefront-cli/controller.rb +53 -22
- data/lib/wavefront-cli/dashboard.rb +3 -0
- data/lib/wavefront-cli/derivedmetric.rb +12 -11
- data/lib/wavefront-cli/display/alert.rb +7 -4
- data/lib/wavefront-cli/display/apitoken.rb +2 -0
- data/lib/wavefront-cli/display/base.rb +34 -8
- data/lib/wavefront-cli/display/cloudintegration.rb +4 -2
- data/lib/wavefront-cli/display/dashboard.rb +2 -0
- data/lib/wavefront-cli/display/derivedmetric.rb +2 -0
- data/lib/wavefront-cli/display/distribution.rb +2 -0
- data/lib/wavefront-cli/display/event.rb +2 -0
- data/lib/wavefront-cli/display/externallink.rb +2 -0
- data/lib/wavefront-cli/display/integration.rb +2 -0
- data/lib/wavefront-cli/display/maintenancewindow.rb +2 -0
- data/lib/wavefront-cli/display/message.rb +7 -3
- data/lib/wavefront-cli/display/metric.rb +3 -1
- data/lib/wavefront-cli/display/notificant.rb +3 -1
- data/lib/wavefront-cli/display/printer/long.rb +36 -11
- data/lib/wavefront-cli/display/printer/sparkline.rb +3 -0
- data/lib/wavefront-cli/display/printer/terse.rb +6 -1
- data/lib/wavefront-cli/display/proxy.rb +2 -0
- data/lib/wavefront-cli/display/query.rb +35 -24
- data/lib/wavefront-cli/display/savedsearch.rb +2 -0
- data/lib/wavefront-cli/display/serviceaccount.rb +60 -0
- data/lib/wavefront-cli/display/settings.rb +2 -0
- data/lib/wavefront-cli/display/source.rb +18 -4
- data/lib/wavefront-cli/display/user.rb +56 -10
- data/lib/wavefront-cli/display/usergroup.rb +25 -19
- data/lib/wavefront-cli/display/webhook.rb +2 -0
- data/lib/wavefront-cli/display/write.rb +6 -2
- data/lib/wavefront-cli/event.rb +83 -62
- data/lib/wavefront-cli/exception.rb +3 -0
- data/lib/wavefront-cli/externallink.rb +6 -4
- data/lib/wavefront-cli/integration.rb +2 -0
- data/lib/wavefront-cli/maintenancewindow.rb +28 -17
- data/lib/wavefront-cli/message.rb +4 -0
- data/lib/wavefront-cli/metric.rb +4 -1
- data/lib/wavefront-cli/notificant.rb +2 -0
- data/lib/wavefront-cli/opt_handler.rb +2 -0
- data/lib/wavefront-cli/output/base.rb +8 -3
- data/lib/wavefront-cli/output/csv.rb +2 -0
- data/lib/wavefront-cli/output/csv/base.rb +2 -0
- data/lib/wavefront-cli/output/csv/query.rb +14 -7
- data/lib/wavefront-cli/output/hcl.rb +2 -0
- data/lib/wavefront-cli/output/hcl/alert.rb +2 -0
- data/lib/wavefront-cli/output/hcl/base.rb +10 -4
- data/lib/wavefront-cli/output/hcl/dashboard.rb +17 -8
- data/lib/wavefront-cli/output/hcl/notificant.rb +2 -0
- data/lib/wavefront-cli/output/hcl/stdlib/array.rb +2 -0
- data/lib/wavefront-cli/output/hcl/stdlib/string.rb +2 -0
- data/lib/wavefront-cli/output/json.rb +2 -0
- data/lib/wavefront-cli/output/ruby.rb +2 -0
- data/lib/wavefront-cli/output/wavefront.rb +2 -0
- data/lib/wavefront-cli/output/wavefront/query.rb +7 -4
- data/lib/wavefront-cli/output/yaml.rb +2 -0
- data/lib/wavefront-cli/proxy.rb +15 -3
- data/lib/wavefront-cli/query.rb +14 -12
- data/lib/wavefront-cli/savedsearch.rb +2 -0
- data/lib/wavefront-cli/serviceaccount.rb +179 -0
- data/lib/wavefront-cli/settings.rb +2 -0
- data/lib/wavefront-cli/source.rb +2 -0
- data/lib/wavefront-cli/stdlib/array.rb +3 -0
- data/lib/wavefront-cli/stdlib/string.rb +17 -11
- data/lib/wavefront-cli/user.rb +10 -4
- data/lib/wavefront-cli/usergroup.rb +4 -2
- data/lib/wavefront-cli/version.rb +3 -1
- data/lib/wavefront-cli/webhook.rb +2 -0
- data/lib/wavefront-cli/write.rb +80 -46
- data/spec/.rubocop.yml +3 -16
- data/spec/constants.rb +21 -0
- data/spec/spec_helper.rb +8 -422
- data/spec/support/command_base.rb +82 -0
- data/spec/support/minitest_assertions.rb +262 -0
- data/spec/support/output_tester.rb +32 -0
- data/spec/support/supported_commands.rb +19 -0
- data/spec/test_mixins/acl.rb +169 -0
- data/spec/test_mixins/delete.rb +25 -0
- data/spec/test_mixins/deleteundelete.rb +106 -0
- data/spec/test_mixins/describe.rb +24 -0
- data/spec/test_mixins/dump.rb +43 -0
- data/spec/test_mixins/general.rb +11 -0
- data/spec/test_mixins/history.rb +35 -0
- data/spec/test_mixins/import.rb +65 -0
- data/spec/test_mixins/list.rb +29 -0
- data/spec/test_mixins/search.rb +98 -0
- data/spec/test_mixins/set.rb +47 -0
- data/spec/test_mixins/tag.rb +99 -0
- data/spec/wavefront-cli/alert_spec.rb +288 -111
- data/spec/wavefront-cli/apitoken_spec.rb +53 -24
- data/spec/wavefront-cli/base_spec.rb +9 -27
- data/spec/wavefront-cli/cloudintegration_spec.rb +65 -29
- data/spec/wavefront-cli/commands/alert_spec.rb +1 -0
- data/spec/wavefront-cli/commands/base_spec.rb +15 -13
- data/spec/wavefront-cli/commands/cloudintegration_spec.rb +1 -0
- data/spec/wavefront-cli/commands/config_spec.rb +3 -0
- data/spec/wavefront-cli/commands/dashboard_spec.rb +1 -0
- data/spec/wavefront-cli/commands/derivedmetric_spec.rb +1 -0
- data/spec/wavefront-cli/commands/event_spec.rb +1 -0
- data/spec/wavefront-cli/commands/link_spec.rb +1 -0
- data/spec/wavefront-cli/commands/message_spec.rb +1 -0
- data/spec/wavefront-cli/commands/metric_spec.rb +1 -0
- data/spec/wavefront-cli/commands/proxy_spec.rb +1 -0
- data/spec/wavefront-cli/commands/query_spec.rb +1 -0
- data/spec/wavefront-cli/commands/webhook_spec.rb +1 -0
- data/spec/wavefront-cli/commands/window_spec.rb +1 -0
- data/spec/wavefront-cli/commands/write_spec.rb +1 -0
- data/spec/wavefront-cli/config_spec.rb +25 -14
- data/spec/wavefront-cli/controller_spec.rb +13 -3
- data/spec/wavefront-cli/dashboard_spec.rb +125 -76
- data/spec/wavefront-cli/derivedmetric_spec.rb +83 -67
- data/spec/wavefront-cli/display/base_spec.rb +5 -7
- data/spec/wavefront-cli/display/printer/long_spec.rb +20 -16
- data/spec/wavefront-cli/display/printer/terse_spec.rb +5 -4
- data/spec/wavefront-cli/event_spec.rb +360 -18
- data/spec/wavefront-cli/externallink_spec.rb +92 -58
- data/spec/wavefront-cli/integration_spec.rb +129 -31
- data/spec/wavefront-cli/maintenancewindow_spec.rb +270 -32
- data/spec/wavefront-cli/message_spec.rb +73 -30
- data/spec/wavefront-cli/metric_spec.rb +60 -22
- data/spec/wavefront-cli/notificant_spec.rb +45 -32
- data/spec/wavefront-cli/opt_handler_spec.rb +4 -1
- data/spec/wavefront-cli/output/csv/query_spec.rb +21 -19
- data/spec/wavefront-cli/output/csv_spec.rb +5 -2
- data/spec/wavefront-cli/output/hcl_spec.rb +5 -2
- data/spec/wavefront-cli/output/helpers.rb +18 -0
- data/spec/wavefront-cli/output/json_spec.rb +3 -1
- data/spec/wavefront-cli/output/ruby_spec.rb +3 -1
- data/spec/wavefront-cli/output/wavefront/query_spec.rb +3 -1
- data/spec/wavefront-cli/output/wavefront_spec.rb +6 -4
- data/spec/wavefront-cli/output/yaml_spec.rb +3 -1
- data/spec/wavefront-cli/proxy_spec.rb +49 -27
- data/spec/wavefront-cli/query_spec.rb +174 -92
- data/spec/wavefront-cli/resources/responses/query.json +1 -0
- data/spec/wavefront-cli/resources/updates/alert.json +15 -0
- data/spec/wavefront-cli/resources/updates/dashboard.json +1 -0
- data/spec/wavefront-cli/savedsearch_spec.rb +35 -18
- data/spec/wavefront-cli/serviceaccount_spec.rb +399 -0
- data/spec/wavefront-cli/settings_spec.rb +42 -11
- data/spec/wavefront-cli/source_spec.rb +120 -23
- data/spec/wavefront-cli/stdlib/array_spec.rb +2 -1
- data/spec/wavefront-cli/stdlib/string_spec.rb +9 -6
- data/spec/wavefront-cli/user_spec.rb +278 -108
- data/spec/wavefront-cli/usergroup_spec.rb +152 -102
- data/spec/wavefront-cli/webhook_spec.rb +30 -15
- data/spec/wavefront-cli/write_spec.rb +25 -1
- data/wavefront-cli.gemspec +5 -3
- metadata +65 -21
- data/spec/wavefront-cli/commands/spec_helper.rb +0 -3
- data/spec/wavefront-cli/display/spec_helper.rb +0 -3
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require_relative 'base'
|
|
2
4
|
require_relative 'printer/sparkline'
|
|
3
5
|
|
|
@@ -6,21 +8,26 @@ module WavefrontDisplay
|
|
|
6
8
|
# Format human-readable output for queries.
|
|
7
9
|
#
|
|
8
10
|
class Query < Base
|
|
9
|
-
# rubocop:disable Metrics/AbcSize
|
|
10
11
|
def do_default
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
@data = default_data_object
|
|
13
|
+
long_output
|
|
14
|
+
rescue StandardError
|
|
15
|
+
raise(WavefrontCli::Exception::InvalidQuery,
|
|
16
|
+
data[:errorMessage].split("\n").first)
|
|
17
|
+
end
|
|
15
18
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
def default_data_object
|
|
20
|
+
{ name: data.name,
|
|
21
|
+
query: data.query,
|
|
22
|
+
timeseries: mk_timeseries(data),
|
|
23
|
+
events: mk_events(data) }.tap do |d|
|
|
24
|
+
d[:warnings] = data[:warnings] if show_warnings?
|
|
25
|
+
end
|
|
26
|
+
end
|
|
19
27
|
|
|
20
|
-
|
|
21
|
-
|
|
28
|
+
def show_warnings?
|
|
29
|
+
data.key?(:warnings) && !options[:nowarn]
|
|
22
30
|
end
|
|
23
|
-
# rubocop:enable Metrics/AbcSize
|
|
24
31
|
|
|
25
32
|
# Prioritizing keys does not make sense in this context
|
|
26
33
|
#
|
|
@@ -43,6 +50,7 @@ module WavefrontDisplay
|
|
|
43
50
|
|
|
44
51
|
def mk_events(data)
|
|
45
52
|
return [] unless data.key?(:events)
|
|
53
|
+
|
|
46
54
|
data[:events].map { |s| humanize_event(s) }
|
|
47
55
|
end
|
|
48
56
|
|
|
@@ -75,25 +83,28 @@ module WavefrontDisplay
|
|
|
75
83
|
data
|
|
76
84
|
end
|
|
77
85
|
|
|
78
|
-
#
|
|
86
|
+
# Prepare a padded line with the timestamp and value. If it's the
|
|
87
|
+
# @return [String]
|
|
88
|
+
#
|
|
79
89
|
def humanize_series(data)
|
|
80
90
|
last_date = nil
|
|
81
91
|
|
|
82
|
-
data.map
|
|
83
|
-
|
|
84
|
-
ht = human_time(row[:timestamp])
|
|
85
|
-
val = row[:value]
|
|
86
|
-
else
|
|
87
|
-
ht = human_time(row[0])
|
|
88
|
-
val = row[1]
|
|
89
|
-
end
|
|
90
|
-
|
|
92
|
+
data.map do |row|
|
|
93
|
+
ht, val = row_time_and_val(row)
|
|
91
94
|
date, time = ht.split
|
|
92
|
-
|
|
95
|
+
date_string = date == last_date ? '' : date
|
|
93
96
|
last_date = date
|
|
94
|
-
format('%-
|
|
97
|
+
format('%-12<series>s %<time>s %<value>s',
|
|
98
|
+
series: date_string, time: time, value: val)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def row_time_and_val(row)
|
|
103
|
+
if row.is_a?(Hash)
|
|
104
|
+
[human_time(row[:timestamp]), row[:value]]
|
|
105
|
+
else
|
|
106
|
+
[human_time(row[0]), row[1]]
|
|
95
107
|
end
|
|
96
|
-
# rubocop:enable Metrics/MethodLength
|
|
97
108
|
end
|
|
98
109
|
end
|
|
99
110
|
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'base'
|
|
4
|
+
|
|
5
|
+
module WavefrontDisplay
|
|
6
|
+
#
|
|
7
|
+
# Format human-readable output for service account commands.
|
|
8
|
+
#
|
|
9
|
+
class ServiceAccount < Base
|
|
10
|
+
def do_describe
|
|
11
|
+
long_output
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def do_list_brief
|
|
15
|
+
multicolumn(:identifier, :description)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def do_activate
|
|
19
|
+
puts format("Activated service account '#{options[:'<id>']}'.")
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def do_deactivate
|
|
23
|
+
puts format("Deactivated service account '#{options[:'<id>']}'.")
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def do_groups
|
|
27
|
+
if data[:userGroups].empty?
|
|
28
|
+
puts 'Account does not belong to any groups.'
|
|
29
|
+
else
|
|
30
|
+
data[:userGroups].each { |u| puts format('%<id>s (%<name>s)', u) }
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
alias do_join do_groups
|
|
35
|
+
alias do_leave do_groups
|
|
36
|
+
|
|
37
|
+
def do_privileges
|
|
38
|
+
if data[:groups].empty?
|
|
39
|
+
puts 'Account does not have any Wavefront privileges.'
|
|
40
|
+
else
|
|
41
|
+
puts data[:groups]
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
alias do_grant do_privileges
|
|
46
|
+
alias do_revoke do_privileges
|
|
47
|
+
|
|
48
|
+
def do_apitoken_list
|
|
49
|
+
if data.empty?
|
|
50
|
+
puts 'Account does not have any tokens.'
|
|
51
|
+
else
|
|
52
|
+
multicolumn(:tokenID, :tokenName)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def search_identifier_key
|
|
57
|
+
:identifier
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require_relative 'base'
|
|
2
4
|
|
|
3
5
|
module WavefrontDisplay
|
|
@@ -12,19 +14,31 @@ module WavefrontDisplay
|
|
|
12
14
|
|
|
13
15
|
def do_list_brief
|
|
14
16
|
massage_data
|
|
17
|
+
terse_data
|
|
15
18
|
multicolumn(:id, :description)
|
|
16
19
|
end
|
|
17
20
|
|
|
21
|
+
def do_search_brief
|
|
22
|
+
return multicolumn(:id) unless data.empty?
|
|
23
|
+
|
|
24
|
+
puts 'No matches.'
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def terse_data
|
|
30
|
+
@data.map! do |e|
|
|
31
|
+
{ id: e[:id], description: e[:description] || '<no description>' }
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
18
35
|
def massage_data
|
|
19
36
|
return if options[:all]
|
|
37
|
+
|
|
20
38
|
drop_cluster_sources
|
|
21
39
|
drop_hidden_sources
|
|
22
40
|
end
|
|
23
41
|
|
|
24
|
-
def do_search_brief
|
|
25
|
-
multicolumn(:id)
|
|
26
|
-
end
|
|
27
|
-
|
|
28
42
|
# Filter out any sources with 'hidden=true'
|
|
29
43
|
#
|
|
30
44
|
def drop_hidden_sources
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require_relative 'base'
|
|
2
4
|
|
|
3
5
|
module WavefrontDisplay
|
|
@@ -10,33 +12,77 @@ module WavefrontDisplay
|
|
|
10
12
|
end
|
|
11
13
|
|
|
12
14
|
def do_groups
|
|
13
|
-
|
|
15
|
+
groups = data.first.userGroups
|
|
16
|
+
|
|
17
|
+
if groups.empty?
|
|
14
18
|
puts 'User does not belong to any groups.'
|
|
15
19
|
else
|
|
16
|
-
|
|
20
|
+
groups.each { |u| puts format('%<id>s (%<name>s)', u) }
|
|
17
21
|
end
|
|
18
22
|
end
|
|
19
23
|
|
|
24
|
+
def do_privileges
|
|
25
|
+
puts(if data.first[:groups].empty?
|
|
26
|
+
'User does not have any Wavefront privileges.'
|
|
27
|
+
else
|
|
28
|
+
data.first[:groups]
|
|
29
|
+
end)
|
|
30
|
+
end
|
|
31
|
+
|
|
20
32
|
def do_create
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
33
|
+
info = data[0]
|
|
34
|
+
puts format("Created user '%<user>s'.\nPermission groups\n" \
|
|
35
|
+
"%<perm_groups>s\nUser groups\n%<user_groups>s",
|
|
36
|
+
user: info[:identifier],
|
|
37
|
+
perm_groups: groups_as_string(info[:groups]),
|
|
38
|
+
user_groups: user_groups_as_string(info[:userGroups]))
|
|
26
39
|
end
|
|
27
40
|
|
|
28
41
|
def groups_as_string(groups)
|
|
29
42
|
return ' <none>' if groups.empty?
|
|
30
|
-
|
|
43
|
+
|
|
44
|
+
data.response.groups.map do |g|
|
|
45
|
+
format(' %<group>s', group: g)
|
|
46
|
+
end.join("\n ")
|
|
31
47
|
end
|
|
32
48
|
|
|
33
49
|
def user_groups_as_string(groups)
|
|
34
50
|
return ' <none>' if groups.empty?
|
|
35
|
-
|
|
51
|
+
|
|
52
|
+
groups.map { |g| format(' %<name>s (%<id>s)', g) }.join("\n")
|
|
36
53
|
end
|
|
37
54
|
|
|
38
55
|
def do_delete
|
|
39
|
-
puts format('Deleted
|
|
56
|
+
puts format('Deleted %<quoted_user>s.',
|
|
57
|
+
quoted_user: quoted(options[:'<user>']))
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def do_invite
|
|
61
|
+
puts format("Sent invitation to '%<id>s'.", id: options[:'<id>'])
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def do_grant
|
|
65
|
+
puts format("Granted '%<priv>s' to '%<id>s'.",
|
|
66
|
+
priv: options[:'<privilege>'],
|
|
67
|
+
id: options[:'<id>'])
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def do_revoke
|
|
71
|
+
puts format("Revoked '%<priv>s' from '%<id>s'.",
|
|
72
|
+
priv: options[:'<privilege>'],
|
|
73
|
+
id: options[:'<id>'])
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def do_join
|
|
77
|
+
puts format("Added '%<id>s' to %<quoted_group>s.",
|
|
78
|
+
id: options[:'<id>'],
|
|
79
|
+
quoted_group: quoted(options[:'<group>']))
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def do_leave
|
|
83
|
+
puts format("Removed '%<id>s' from %<quoted_group>s.",
|
|
84
|
+
id: options[:'<id>'],
|
|
85
|
+
quoted_group: quoted(options[:'<group>']))
|
|
40
86
|
end
|
|
41
87
|
end
|
|
42
88
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require_relative 'base'
|
|
2
4
|
|
|
3
5
|
module WavefrontDisplay
|
|
@@ -10,43 +12,47 @@ module WavefrontDisplay
|
|
|
10
12
|
end
|
|
11
13
|
|
|
12
14
|
def do_delete
|
|
13
|
-
puts "Deleted user group '#{options[:'<id>']}."
|
|
15
|
+
puts "Deleted user group '#{options[:'<id>']}'."
|
|
14
16
|
end
|
|
15
17
|
|
|
16
18
|
def do_add_user
|
|
17
|
-
puts format(
|
|
18
|
-
options[:'<
|
|
19
|
+
puts format("Added %<quoted_user>s to '%<group_id>s'.",
|
|
20
|
+
quoted_user: quoted(options[:'<user>']),
|
|
21
|
+
group_id: options[:'<id>']).fold(TW, 0)
|
|
19
22
|
end
|
|
20
23
|
|
|
21
24
|
def do_remove_user
|
|
22
|
-
puts format("Removed
|
|
23
|
-
options[:'<
|
|
25
|
+
puts format("Removed %<quoted_user>s from '%<group_id>s'.",
|
|
26
|
+
quoted_user: quoted(options[:'<user>']),
|
|
27
|
+
group_id: options[:'<id>']).fold(TW, 0)
|
|
24
28
|
end
|
|
25
29
|
|
|
26
30
|
def do_grant
|
|
27
|
-
puts format("Granted '
|
|
28
|
-
options[:'<permission>'],
|
|
31
|
+
puts format("Granted '%<perm>s' permission to '%<group_id>s'.",
|
|
32
|
+
perm: options[:'<permission>'],
|
|
33
|
+
group_id: options[:'<id>'])
|
|
29
34
|
end
|
|
30
35
|
|
|
31
36
|
def do_revoke
|
|
32
|
-
puts format("Revoked '
|
|
33
|
-
options[:'<permission>'],
|
|
37
|
+
puts format("Revoked '%<perm>s' permission from '%<group_id>s'.",
|
|
38
|
+
perm: options[:'<permission>'],
|
|
39
|
+
group_id: options[:'<id>'])
|
|
34
40
|
end
|
|
35
41
|
|
|
36
42
|
def do_users
|
|
37
|
-
if data.users.empty?
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
43
|
+
puts(if !data.include?(:users) || data[:users].empty?
|
|
44
|
+
"No users in group '#{options[:'<id>']}'."
|
|
45
|
+
else
|
|
46
|
+
data[:users]
|
|
47
|
+
end)
|
|
42
48
|
end
|
|
43
49
|
|
|
44
50
|
def do_permissions
|
|
45
|
-
if data.permissions.empty?
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
51
|
+
puts(if !data.include?(:permissions) || data[:permissions].empty?
|
|
52
|
+
"Group '#{options[:'<id>']}' has no permissions."
|
|
53
|
+
else
|
|
54
|
+
data[:permissions]
|
|
55
|
+
end)
|
|
50
56
|
end
|
|
51
57
|
end
|
|
52
58
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require_relative 'base'
|
|
2
4
|
|
|
3
5
|
module WavefrontDisplay
|
|
@@ -23,8 +25,10 @@ module WavefrontDisplay
|
|
|
23
25
|
end
|
|
24
26
|
|
|
25
27
|
def report
|
|
26
|
-
%w[sent rejected unsent].each do |
|
|
27
|
-
puts format(' %
|
|
28
|
+
%w[sent rejected unsent].each do |status|
|
|
29
|
+
puts format(' %12<status>s %<count>d',
|
|
30
|
+
status: status,
|
|
31
|
+
count: data[status])
|
|
28
32
|
end
|
|
29
33
|
end
|
|
30
34
|
end
|
data/lib/wavefront-cli/event.rb
CHANGED
|
@@ -1,71 +1,54 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'fileutils'
|
|
2
4
|
require 'open3'
|
|
3
5
|
require 'wavefront-sdk/support/mixins'
|
|
4
6
|
require_relative 'base'
|
|
5
7
|
require_relative 'command_mixins/tag'
|
|
6
8
|
|
|
7
|
-
EVENT_STATE_DIR = Pathname.new('/var/tmp/wavefront')
|
|
8
|
-
|
|
9
9
|
module WavefrontCli
|
|
10
10
|
#
|
|
11
11
|
# CLI coverage for the v2 'event' API.
|
|
12
12
|
#
|
|
13
13
|
class Event < Base
|
|
14
14
|
attr_reader :state_dir
|
|
15
|
+
|
|
15
16
|
include Wavefront::Mixins
|
|
16
17
|
include WavefrontCli::Mixin::Tag
|
|
17
18
|
|
|
18
19
|
def post_initialize(_options)
|
|
19
|
-
@state_dir =
|
|
20
|
-
|
|
20
|
+
@state_dir = event_state_dir + (Etc.getlogin || 'notty')
|
|
21
|
+
create_dir(state_dir)
|
|
21
22
|
end
|
|
22
23
|
|
|
23
24
|
def do_list
|
|
24
|
-
wf.list(
|
|
25
|
-
options[:end] || Time.now,
|
|
26
|
-
options[:limit] || 100,
|
|
27
|
-
options[:cursor] || nil)
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def do_set
|
|
31
|
-
k, v = options[:'<key=value>'].split('=')
|
|
32
|
-
wf.update(options[:'<id>'], k => v)
|
|
25
|
+
wf.list(*list_args)
|
|
33
26
|
end
|
|
34
27
|
|
|
35
|
-
# You can override the options generated by docopt. This is how
|
|
36
|
-
# #wrap() works.
|
|
37
|
-
#
|
|
38
|
-
# rubocop:disable Metrics/AbcSize
|
|
39
28
|
def do_create(opts = nil)
|
|
40
29
|
opts ||= options
|
|
41
|
-
|
|
42
30
|
opts[:start] = Time.now unless opts[:start]
|
|
43
|
-
|
|
44
31
|
t_start = parse_time(opts[:start], true)
|
|
45
|
-
|
|
46
32
|
body = create_body(opts, t_start)
|
|
47
|
-
|
|
48
33
|
resp = wf.create(body)
|
|
49
|
-
|
|
50
|
-
unless opts[:nostate] || opts[:end] || opts[:instant]
|
|
51
|
-
create_state_file(resp.response[:id], opts[:host])
|
|
52
|
-
end
|
|
53
|
-
|
|
34
|
+
create_state_file(resp.response[:id]) if state_file_needed?(opts)
|
|
54
35
|
resp
|
|
55
36
|
end
|
|
56
|
-
|
|
37
|
+
|
|
38
|
+
def state_file_needed?(opts)
|
|
39
|
+
!(opts[:nostate] || opts[:end] || opts[:instant])
|
|
40
|
+
end
|
|
57
41
|
|
|
58
42
|
# The user doesn't have to give us an event ID. If no event
|
|
59
43
|
# name is given, we'll pop the last event off the stack. If an
|
|
60
44
|
# event name is given and it doesn't look like a full WF event
|
|
61
45
|
# name, we'll look for something on the stack. If it does look
|
|
62
|
-
# like a real event, we'll make
|
|
46
|
+
# like a real event, we'll make an API call straight away.
|
|
63
47
|
#
|
|
64
|
-
# rubocop:disable Metrics/AbcSize
|
|
65
48
|
def do_close(id = nil)
|
|
66
49
|
id ||= options[:'<id>']
|
|
67
|
-
ev_file = id =~ /^\d{13}:.+/ ? state_dir + id : nil
|
|
68
50
|
ev = local_event(id)
|
|
51
|
+
ev_file = event_file(id)
|
|
69
52
|
|
|
70
53
|
abort "No locally stored event matches '#{id}'." unless ev
|
|
71
54
|
|
|
@@ -73,7 +56,10 @@ module WavefrontCli
|
|
|
73
56
|
ev_file.unlink if ev_file&.exist? && res.status.code == 200
|
|
74
57
|
res
|
|
75
58
|
end
|
|
76
|
-
|
|
59
|
+
|
|
60
|
+
def event_file(id)
|
|
61
|
+
id =~ /^\d{13}:.+/ ? state_dir + id : nil
|
|
62
|
+
end
|
|
77
63
|
|
|
78
64
|
def do_show
|
|
79
65
|
events = local_event_list
|
|
@@ -93,41 +79,47 @@ module WavefrontCli
|
|
|
93
79
|
event_id = do_create(create_opts).response.id
|
|
94
80
|
exit_code = run_wrapped_cmd(options[:command])
|
|
95
81
|
do_close(event_id)
|
|
96
|
-
puts "Command exited #{exit_code}"
|
|
82
|
+
puts "Command exited #{exit_code}."
|
|
97
83
|
exit exit_code
|
|
98
84
|
end
|
|
99
85
|
|
|
100
|
-
|
|
86
|
+
# We can override the temp directory with the WF_EVENT_STATE_DIR. This is
|
|
87
|
+
# primarily for testing.
|
|
88
|
+
#
|
|
89
|
+
def event_state_dir
|
|
90
|
+
if ENV['WF_EVENT_STATE_DIR']
|
|
91
|
+
Pathname.new(ENV['WF_EVENT_STATE_DIR'])
|
|
92
|
+
else
|
|
93
|
+
EVENT_STATE_DIR
|
|
94
|
+
end
|
|
95
|
+
end
|
|
101
96
|
|
|
102
97
|
# return [Hash] body for #create() method
|
|
103
98
|
#
|
|
104
|
-
# rubocop:disable Metrics/AbcSize
|
|
105
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
|
106
|
-
# rubocop:disable Metrics/PerceivedComplexity
|
|
107
99
|
# rubocop:disable Metrics/MethodLength
|
|
108
100
|
def create_body(opts, t_start)
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
elsif opts[:end]
|
|
122
|
-
body[:endTime] = parse_time(opts[:end], true)
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
body
|
|
101
|
+
{ name: opts[:'<event>'],
|
|
102
|
+
startTime: t_start,
|
|
103
|
+
annotations: annotations(opts) }.tap do |r|
|
|
104
|
+
r[:hosts] = opts[:host] if opts[:host]
|
|
105
|
+
r[:tags] = opts[:evtag] if opts[:evtag]
|
|
106
|
+
|
|
107
|
+
if opts[:instant]
|
|
108
|
+
r[:endTime] = t_start + 1
|
|
109
|
+
elsif opts[:end]
|
|
110
|
+
r[:endTime] = parse_time(opts[:end], true)
|
|
111
|
+
end
|
|
112
|
+
end
|
|
126
113
|
end
|
|
127
114
|
# rubocop:enable Metrics/MethodLength
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
115
|
+
|
|
116
|
+
def annotations(opts)
|
|
117
|
+
{}.tap do |r|
|
|
118
|
+
r[:details] = opts[:desc] if opts[:desc]
|
|
119
|
+
r[:severity] = opts[:severity] if opts[:severity]
|
|
120
|
+
r[:type] = opts[:type] if opts[:type]
|
|
121
|
+
end
|
|
122
|
+
end
|
|
131
123
|
|
|
132
124
|
# @return a local event from the stack directory
|
|
133
125
|
#
|
|
@@ -142,7 +134,10 @@ module WavefrontCli
|
|
|
142
134
|
end
|
|
143
135
|
|
|
144
136
|
def local_event_list
|
|
145
|
-
state_dir.children
|
|
137
|
+
events = state_dir.children
|
|
138
|
+
abort 'No locally recorded events.' if events.empty?
|
|
139
|
+
|
|
140
|
+
events
|
|
146
141
|
rescue Errno::ENOENT
|
|
147
142
|
raise(WavefrontCli::Exception::SystemError,
|
|
148
143
|
'There is no event state directory on this host.')
|
|
@@ -160,7 +155,7 @@ module WavefrontCli
|
|
|
160
155
|
|
|
161
156
|
Open3.popen2e(cmd) do |_in, out, thr|
|
|
162
157
|
# rubocop:disable Lint/AssignmentInCondition
|
|
163
|
-
while l = out.gets do
|
|
158
|
+
while l = out.gets do warn l end
|
|
164
159
|
# rubocop:enable Lint/AssignmentInCondition
|
|
165
160
|
ret = thr.value.exitstatus
|
|
166
161
|
end
|
|
@@ -173,15 +168,27 @@ module WavefrontCli
|
|
|
173
168
|
# file. These aren't currently used by anything in the CLI, but they
|
|
174
169
|
# might be useful to someone, somewhere, someday.
|
|
175
170
|
#
|
|
176
|
-
def create_state_file(id
|
|
171
|
+
def create_state_file(id)
|
|
177
172
|
fname = state_dir + id
|
|
178
|
-
File.open(fname, 'w') {
|
|
173
|
+
File.open(fname, 'w') { |fh| fh.puts(event_file_data) }
|
|
179
174
|
puts "Event state recorded at #{fname}."
|
|
180
175
|
rescue StandardError
|
|
181
176
|
puts 'NOTICE: event was created but state file was not.'
|
|
182
177
|
end
|
|
183
178
|
|
|
184
|
-
|
|
179
|
+
# Record event data in the state file. We don't currently use it, but it
|
|
180
|
+
# might be useful to someone someday.
|
|
181
|
+
#
|
|
182
|
+
# @return [String]
|
|
183
|
+
#
|
|
184
|
+
def event_file_data
|
|
185
|
+
{ hosts: options[:host],
|
|
186
|
+
description: options[:desc],
|
|
187
|
+
severity: options[:severity],
|
|
188
|
+
tags: options[:evtag] }.to_json
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def create_dir(state_dir)
|
|
185
192
|
FileUtils.mkdir_p(state_dir)
|
|
186
193
|
raise unless state_dir.exist? && state_dir.directory? &&
|
|
187
194
|
state_dir.writable?
|
|
@@ -217,10 +224,24 @@ module WavefrontCli
|
|
|
217
224
|
|
|
218
225
|
def local_events_with_name(name = nil)
|
|
219
226
|
list = local_event_list
|
|
220
|
-
|
|
221
227
|
return list unless name
|
|
222
228
|
|
|
223
229
|
list.select { |f| f.basename.to_s.split(':').last == name }
|
|
224
230
|
end
|
|
231
|
+
|
|
232
|
+
def list_args
|
|
233
|
+
[window_start,
|
|
234
|
+
window_end,
|
|
235
|
+
options[:limit] || 100,
|
|
236
|
+
options[:cursor] || nil]
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
def window_start
|
|
240
|
+
parse_time((options[:start] || Time.now - 600), true)
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
def window_end
|
|
244
|
+
parse_time((options[:end] || Time.now), true)
|
|
245
|
+
end
|
|
225
246
|
end
|
|
226
247
|
end
|