a2 0.1.1 → 0.2.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/Gemfile.lock +1 -1
- data/README.md +12 -8
- data/lib/a2/client.rb +14 -0
- data/lib/a2/client/config_mgmt.rb +8 -0
- data/lib/a2/client/reporting.rb +9 -0
- data/lib/a2/command.rb +1 -0
- data/lib/a2/commands/compliance.rb +14 -0
- data/lib/a2/commands/infra.rb +2 -0
- data/lib/a2/mixins/filtered.rb +22 -22
- data/lib/a2/mixins/paginated.rb +9 -16
- data/lib/a2/parser.rb +1 -0
- data/lib/a2/subcommands/infra.rb +30 -5
- data/lib/a2/subcommands/node_mgmt.rb +2 -7
- data/lib/a2/subcommands/reporting.rb +30 -0
- data/lib/a2/subcommands/team.rb +0 -1
- data/lib/a2/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5ab4e4782cc17d7bdd25d29feda56c81d4dbff2e911f19e9d723f5ecf66801f7
|
4
|
+
data.tar.gz: 4993432169fd2305698ee7f1106b0b2a83576eef287ac7065d2543ed38b1cae4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5cdab720df6fc757d7392598e2ddefed1dfe0883013aca3eb63c95b9b8644ea02de60967b751758c73b312da36d2280ee758a1ae6cbbd92ba9a109ae9d1086ed
|
7
|
+
data.tar.gz: e61c4e157f94ff5aca7f69808967cafa12c487bb0978af6726b6772e71d69774791e04c4b04c512ab31857faa15fcca510e645cfc8f3b1d81f6a33b2f2894e3b
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -27,15 +27,11 @@ SSL_NO_VERIFY=true
|
|
27
27
|
List the available commands:
|
28
28
|
|
29
29
|
$ a2 --help
|
30
|
-
Usage: a2 [options] {
|
30
|
+
Usage: a2 [options] {compliance | help | iam | infra | nodemgmt | version}
|
31
31
|
|
32
32
|
Available commands:
|
33
|
-
|
34
|
-
|
35
|
-
list-node-status-counts
|
36
|
-
list-nodes
|
37
|
-
list-orgs
|
38
|
-
show-attributes
|
33
|
+
compliance Compliance management commands
|
34
|
+
export-node-reports
|
39
35
|
help Provide help for individual commands
|
40
36
|
iam Identity access management commands
|
41
37
|
add-membership
|
@@ -52,7 +48,15 @@ List the available commands:
|
|
52
48
|
remove-membership
|
53
49
|
update-team
|
54
50
|
update-user
|
55
|
-
|
51
|
+
infra Chef Infra config management commands
|
52
|
+
list-missing-nodes
|
53
|
+
list-node-runs
|
54
|
+
list-node-status-counts
|
55
|
+
list-nodes
|
56
|
+
list-orgs
|
57
|
+
show-attributes
|
58
|
+
show-node-run
|
59
|
+
nodemgmt Node management commands
|
56
60
|
bulk-delete-by-filter
|
57
61
|
bulk-delete-by-ids
|
58
62
|
delete
|
data/lib/a2/client.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require_relative 'client/config_mgmt'
|
2
2
|
require_relative 'client/nodes'
|
3
|
+
require_relative 'client/reporting'
|
3
4
|
require_relative 'client/teams'
|
4
5
|
require_relative 'client/users'
|
5
6
|
|
@@ -7,6 +8,7 @@ module A2
|
|
7
8
|
class Client
|
8
9
|
include A2::Client::ConfigMgmt
|
9
10
|
include A2::Client::Nodes
|
11
|
+
include A2::Client::Reporting
|
10
12
|
include A2::Client::Teams
|
11
13
|
include A2::Client::Users
|
12
14
|
|
@@ -45,6 +47,18 @@ module A2
|
|
45
47
|
JSON.parse(response.body)
|
46
48
|
end
|
47
49
|
|
50
|
+
def download_report(path, json, output_file)
|
51
|
+
File.open(output_file, "w") do |file|
|
52
|
+
HTTParty.post(File.join(@automate_url, path).to_s, {
|
53
|
+
verify: !@ssl_no_verify,
|
54
|
+
headers: {"api-token" => @automate_token},
|
55
|
+
body: json
|
56
|
+
}) do |fragment|
|
57
|
+
file.write(fragment)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
48
62
|
def delete(path)
|
49
63
|
response = HTTParty.delete(File.join(@automate_url, path).to_s, {
|
50
64
|
verify: !@ssl_no_verify,
|
@@ -9,6 +9,10 @@ module A2
|
|
9
9
|
get "/api/v0/cfgmgmt/stats/missing_node_duration_counts#{query_string}"
|
10
10
|
end
|
11
11
|
|
12
|
+
def list_all_node_runs(node_id, query_string = '')
|
13
|
+
get "/api/v0/cfgmgmt/nodes/#{node_id}/runs#{query_string}"
|
14
|
+
end
|
15
|
+
|
12
16
|
def list_all_node_status_counts(query_string = '')
|
13
17
|
get "/api/v0/cfgmgmt/stats/node_counts#{query_string}"
|
14
18
|
end
|
@@ -20,6 +24,10 @@ module A2
|
|
20
24
|
def show_attributes(node_id)
|
21
25
|
get "/api/v0/cfgmgmt/nodes/#{node_id}/attribute"
|
22
26
|
end
|
27
|
+
|
28
|
+
def show_node_run(node_id, run_id, query_string = '')
|
29
|
+
get "/api/v0/cfgmgmt/nodes/#{node_id}/runs/#{run_id}#{query_string}"
|
30
|
+
end
|
23
31
|
end
|
24
32
|
end
|
25
33
|
end
|
data/lib/a2/command.rb
CHANGED
@@ -0,0 +1,14 @@
|
|
1
|
+
require_relative '../subcommands/reporting'
|
2
|
+
|
3
|
+
module A2
|
4
|
+
module Command
|
5
|
+
class Compliance < CmdParse::Command
|
6
|
+
def initialize
|
7
|
+
super('compliance')
|
8
|
+
short_desc('Compliance management commands')
|
9
|
+
long_desc('Compliance management commands')
|
10
|
+
add_command(A2::Subcommand::Reporting::ExportNodeReports.new)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/a2/commands/infra.rb
CHANGED
@@ -9,9 +9,11 @@ module A2
|
|
9
9
|
long_desc('Chef Infra config management commands')
|
10
10
|
add_command(A2::Subcommand::Infra::ListAllCheckedInNodes.new)
|
11
11
|
add_command(A2::Subcommand::Infra::ListMissingNodesCount.new)
|
12
|
+
add_command(A2::Subcommand::Infra::ListNodeRuns.new)
|
12
13
|
add_command(A2::Subcommand::Infra::ListNodeStatusCounts.new)
|
13
14
|
add_command(A2::Subcommand::Infra::ListOrganizations.new)
|
14
15
|
add_command(A2::Subcommand::Infra::ShowAttributes.new)
|
16
|
+
add_command(A2::Subcommand::Infra::ShowNodeRun.new)
|
15
17
|
end
|
16
18
|
end
|
17
19
|
end
|
data/lib/a2/mixins/filtered.rb
CHANGED
@@ -1,44 +1,44 @@
|
|
1
1
|
module A2
|
2
|
-
|
2
|
+
class Filtered < CmdParse::Command
|
3
3
|
def initialize(name, opts = {})
|
4
4
|
set_custom_opts!(opts)
|
5
5
|
super(name, opts)
|
6
|
-
set_filter_optparse_options!(options)
|
6
|
+
set_filter_optparse_options!(options, @query_filter)
|
7
7
|
end
|
8
8
|
|
9
9
|
def set_custom_opts!(opts)
|
10
10
|
@opt ||= {}
|
11
|
-
@
|
11
|
+
@query_filter = opts.delete(:query_filter) || false
|
12
|
+
@filter_key = opts.delete(:filter_key) || 'key'
|
12
13
|
end
|
13
14
|
|
14
|
-
def set_filter_optparse_options!(options)
|
15
|
+
def set_filter_optparse_options!(options, query_filter)
|
15
16
|
options.on('-f', '--filters FILTERS', 'A comma-separated list of filters.') do |filters|
|
16
17
|
@opt[:filters] = filters
|
17
18
|
end
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
@opt[:query_filter]
|
19
|
+
if query_filter
|
20
|
+
# Only available for query parameter filters
|
21
|
+
options.on('-S', '--start-time START', 'Earliest most recent check-in node information to return. Formatted iso8601 (YYYY-MM-DD\'T\'HH:mm:ssZ)') do |start_time|
|
22
|
+
@opt[:start] = start_time
|
23
|
+
end
|
24
|
+
options.on('-E', '--end-time END', 'Latest most recent check-in node information to return. Formatted iso8601 (YYYY-MM-DD\'T\'HH:mm:ssZ)') do |end_time|
|
25
|
+
@opt[:end] = end_time
|
26
|
+
end
|
27
|
+
else
|
28
|
+
# Only available for POST body filters
|
29
|
+
options.on('-j', '--json-file FILE', 'Path to a json file containing a filter payload.') do |file|
|
30
|
+
@opt[:json_file] = file
|
31
|
+
end
|
32
|
+
end
|
33
33
|
end
|
34
34
|
|
35
35
|
def parse_filters(filters)
|
36
36
|
parsed_filters = []
|
37
37
|
filters.split(',').each do |f|
|
38
|
-
k
|
38
|
+
k,*v = f.split(':')
|
39
39
|
parsed_filters << {
|
40
|
-
|
41
|
-
'values' => [v]
|
40
|
+
@filter_key => k,
|
41
|
+
'values' => [v.join(':')]
|
42
42
|
}
|
43
43
|
end
|
44
44
|
parsed_filters
|
data/lib/a2/mixins/paginated.rb
CHANGED
@@ -1,33 +1,26 @@
|
|
1
1
|
module A2
|
2
|
-
|
3
|
-
include A2::Filtered
|
2
|
+
class Paginated < Filtered
|
4
3
|
def initialize(name, opts = {})
|
5
|
-
|
4
|
+
disable_sort_opts = opts.delete(:disable_sort_opts) || false
|
6
5
|
super(name, opts)
|
7
|
-
@opt =
|
8
|
-
order: 'ASC'
|
9
|
-
}
|
6
|
+
@opt[:order] = 'ASC' unless disable_sort_opts
|
10
7
|
options.on('-o', '--order ORDER', 'Return the results in ascending or descending order. Default is "ASC".') do |order|
|
11
8
|
@opt[:order] = order
|
12
|
-
end
|
9
|
+
end unless disable_sort_opts
|
10
|
+
options.on('-s', '--sort SORT', 'Sort the results on a specific field.') do |sort|
|
11
|
+
@opt[:sort] = sort
|
12
|
+
end unless disable_sort_opts
|
13
13
|
options.on('-p', '--page PAGE', Integer, 'Starting page for the results. Default is 0') do |page|
|
14
14
|
@opt[:page] = page
|
15
15
|
end
|
16
16
|
options.on('-P', '--per-page PER_PAGE', Integer, 'The number of results on each page. Default is 100') do |per_page|
|
17
17
|
@opt[:per_page] = per_page
|
18
18
|
end
|
19
|
-
options
|
20
|
-
@opt[:sort] = sort
|
21
|
-
end
|
22
|
-
set_filter_optparse_options!(options)
|
23
|
-
end
|
24
|
-
|
25
|
-
def generate_paginated_json_filters
|
26
|
-
generate_json_filters
|
19
|
+
set_filter_optparse_options!(options, @query_filter)
|
27
20
|
end
|
28
21
|
|
29
22
|
def with_paginated_filter_json(&block)
|
30
|
-
json =
|
23
|
+
json = generate_json_filters
|
31
24
|
yield(json)
|
32
25
|
end
|
33
26
|
|
data/lib/a2/parser.rb
CHANGED
@@ -5,6 +5,7 @@ module A2
|
|
5
5
|
parser.main_options.version = A2::VERSION
|
6
6
|
parser.add_command(CmdParse::HelpCommand.new)
|
7
7
|
parser.add_command(CmdParse::VersionCommand.new)
|
8
|
+
parser.add_command(A2::Command::Compliance.new)
|
8
9
|
parser.add_command(A2::Command::IAM.new)
|
9
10
|
parser.add_command(A2::Command::Infra.new)
|
10
11
|
parser.add_command(A2::Command::NodeMgmt.new)
|
data/lib/a2/subcommands/infra.rb
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
module A2
|
2
2
|
module Subcommand
|
3
3
|
module Infra
|
4
|
-
class ListAllCheckedInNodes <
|
5
|
-
include A2::Paginated
|
4
|
+
class ListAllCheckedInNodes < Paginated
|
6
5
|
def initialize
|
7
6
|
super('list-nodes', takes_commands: false, query_filter: true)
|
8
7
|
end
|
9
8
|
|
10
9
|
def execute
|
11
|
-
|
10
|
+
with_paginated_filter_query do |query_string|
|
12
11
|
puts JSON.pretty_generate(A2::Client.new(command_parser.data).list_all_checked_in_nodes(query_string))
|
13
12
|
end
|
14
13
|
end
|
@@ -26,8 +25,18 @@ module A2
|
|
26
25
|
puts JSON.pretty_generate(A2::Client.new(command_parser.data).list_all_missing_nodes_count(@opt[:durations]))
|
27
26
|
end
|
28
27
|
end
|
29
|
-
class
|
30
|
-
|
28
|
+
class ListNodeRuns < Paginated
|
29
|
+
def initialize
|
30
|
+
super('list-node-runs', takes_commands: false, query_filter: true, disable_sort_opts: true)
|
31
|
+
end
|
32
|
+
|
33
|
+
def execute(node_id)
|
34
|
+
with_paginated_filter_query do |query_string|
|
35
|
+
puts JSON.pretty_generate(A2::Client.new(command_parser.data).list_all_node_runs(node_id, query_string))
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
class ListNodeStatusCounts < Filtered
|
31
40
|
def initialize
|
32
41
|
super('list-node-status-counts', takes_commands: false, query_filter: true)
|
33
42
|
end
|
@@ -56,6 +65,22 @@ module A2
|
|
56
65
|
puts JSON.pretty_generate(A2::Client.new(command_parser.data).show_attributes(node_id))
|
57
66
|
end
|
58
67
|
end
|
68
|
+
class ShowNodeRun < CmdParse::Command
|
69
|
+
def initialize
|
70
|
+
super('show-node-run', takes_commands: false)
|
71
|
+
@opt = {}
|
72
|
+
options.on('-E', '--end-time END', "End time on the node's run. Formatted iso8601 (YYYY-MM-DD\'T\'HH:mm:ssZ)") do |end_time|
|
73
|
+
@opt[:end_time] = end_time
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def execute(node_id, run_id)
|
78
|
+
query_string = ''
|
79
|
+
query_string = "?end_time=#{@opt[:end_time]}" if @opt[:end_time]
|
80
|
+
|
81
|
+
puts JSON.pretty_generate(A2::Client.new(command_parser.data).show_node_run(node_id, run_id, query_string))
|
82
|
+
end
|
83
|
+
end
|
59
84
|
end
|
60
85
|
end
|
61
86
|
end
|
@@ -10,8 +10,7 @@ module A2
|
|
10
10
|
puts JSON.pretty_generate(A2::Client.new(command_parser.data).get_managed_node(id))
|
11
11
|
end
|
12
12
|
end
|
13
|
-
class Search <
|
14
|
-
include A2::Paginated
|
13
|
+
class Search < Paginated
|
15
14
|
|
16
15
|
def initialize
|
17
16
|
super('search', takes_commands: false)
|
@@ -25,7 +24,6 @@ module A2
|
|
25
24
|
end
|
26
25
|
class Delete < CmdParse::Command
|
27
26
|
include A2::Approved
|
28
|
-
|
29
27
|
def initialize
|
30
28
|
super('delete', takes_commands: false)
|
31
29
|
end
|
@@ -38,7 +36,6 @@ module A2
|
|
38
36
|
end
|
39
37
|
class BulkDeleteById < CmdParse::Command
|
40
38
|
include A2::Approved
|
41
|
-
|
42
39
|
def initialize
|
43
40
|
super('bulk-delete-by-ids', takes_commands: false)
|
44
41
|
end
|
@@ -49,10 +46,8 @@ module A2
|
|
49
46
|
end
|
50
47
|
end
|
51
48
|
end
|
52
|
-
class BulkDeleteByFilter <
|
49
|
+
class BulkDeleteByFilter < Paginated
|
53
50
|
include A2::Approved
|
54
|
-
include A2::Paginated
|
55
|
-
|
56
51
|
def initialize
|
57
52
|
super('bulk-delete-by-filter', takes_commands: false)
|
58
53
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module A2
|
2
|
+
module Subcommand
|
3
|
+
module Reporting
|
4
|
+
class ExportNodeReports < Paginated
|
5
|
+
def initialize
|
6
|
+
super('export-node-reports', takes_commands: false, filter_key: 'type')
|
7
|
+
@opt[:type] = 'csv'
|
8
|
+
options.on('-n', '--name NAME', 'Name of the profile (as defined in inspec.yml).') do |name|
|
9
|
+
@opt[:name] = name
|
10
|
+
end
|
11
|
+
options.on('-O', '--owner OWNER', 'Automate user associated with the profile.') do |owner|
|
12
|
+
@opt[:owner] = owner
|
13
|
+
end
|
14
|
+
options.on('-o', '--output OUTPUT_TYPE', 'Desired report data format (either "csv" or "json"). Default value is "csv".') do |output_type|
|
15
|
+
@opt[:type] = output_type
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def execute(filename = nil, output_type = 'csv')
|
20
|
+
# Workaround for bug: https://github.com/chef/automate/issues/4926
|
21
|
+
@opt[:order] = @opt[:order].downcase.eql?('asc') ? 0 : 1
|
22
|
+
with_paginated_filter_json do |json|
|
23
|
+
filename ||= "report-#{Time.now.strftime('%Y%m%d%H%M%S')}.#{@opt[:type]}"
|
24
|
+
response = A2::Client.new(command_parser.data).export_node_reports(json, filename)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/a2/subcommands/team.rb
CHANGED
data/lib/a2/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: a2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- gscho
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-04-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -106,9 +106,11 @@ files:
|
|
106
106
|
- lib/a2/client.rb
|
107
107
|
- lib/a2/client/config_mgmt.rb
|
108
108
|
- lib/a2/client/nodes.rb
|
109
|
+
- lib/a2/client/reporting.rb
|
109
110
|
- lib/a2/client/teams.rb
|
110
111
|
- lib/a2/client/users.rb
|
111
112
|
- lib/a2/command.rb
|
113
|
+
- lib/a2/commands/compliance.rb
|
112
114
|
- lib/a2/commands/iam.rb
|
113
115
|
- lib/a2/commands/infra.rb
|
114
116
|
- lib/a2/commands/node_mgmt.rb
|
@@ -118,6 +120,7 @@ files:
|
|
118
120
|
- lib/a2/parser.rb
|
119
121
|
- lib/a2/subcommands/infra.rb
|
120
122
|
- lib/a2/subcommands/node_mgmt.rb
|
123
|
+
- lib/a2/subcommands/reporting.rb
|
121
124
|
- lib/a2/subcommands/team.rb
|
122
125
|
- lib/a2/subcommands/user.rb
|
123
126
|
- lib/a2/version.rb
|