moose-inventory 1.0.8 → 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 +5 -5
- data/.github/workflows/ci.yml +49 -0
- data/.github/workflows/release.yml +58 -0
- data/.gitignore +1 -1
- data/.gitleaks.toml +9 -0
- data/.rubocop.yml +19 -784
- data/BACKLOG.md +290 -0
- data/Gemfile.lock +95 -0
- data/README.md +38 -9
- data/Rakefile +1 -1
- data/bin/moose-inventory +1 -1
- data/docs/release/publishing.md +109 -0
- data/docs/release/release-readiness.md +55 -0
- data/docs/security-audit-2026-05-21.md +71 -0
- data/docs/security-audit-2026-05-26-rerun.md +75 -0
- data/docs/security-audit-2026-05-26.md +63 -0
- data/lib/moose_inventory/cli/formatter.rb +16 -17
- data/lib/moose_inventory/cli/group.rb +4 -1
- data/lib/moose_inventory/cli/group_add.rb +89 -75
- data/lib/moose_inventory/cli/group_addchild.rb +84 -71
- data/lib/moose_inventory/cli/group_addhost.rb +78 -69
- data/lib/moose_inventory/cli/group_addvar.rb +37 -37
- data/lib/moose_inventory/cli/group_get.rb +23 -26
- data/lib/moose_inventory/cli/group_list.rb +12 -15
- data/lib/moose_inventory/cli/group_listvars.rb +12 -14
- data/lib/moose_inventory/cli/group_rm.rb +104 -76
- data/lib/moose_inventory/cli/group_rmchild.rb +99 -54
- data/lib/moose_inventory/cli/group_rmhost.rb +64 -60
- data/lib/moose_inventory/cli/group_rmvar.rb +5 -5
- data/lib/moose_inventory/cli/helpers.rb +76 -0
- data/lib/moose_inventory/cli/host.rb +4 -1
- data/lib/moose_inventory/cli/host_add.rb +51 -66
- data/lib/moose_inventory/cli/host_addgroup.rb +77 -68
- data/lib/moose_inventory/cli/host_addvar.rb +6 -6
- data/lib/moose_inventory/cli/host_get.rb +15 -18
- data/lib/moose_inventory/cli/host_list.rb +3 -3
- data/lib/moose_inventory/cli/host_listvars.rb +21 -23
- data/lib/moose_inventory/cli/host_rm.rb +9 -9
- data/lib/moose_inventory/cli/host_rmgroup.rb +63 -60
- data/lib/moose_inventory/cli/host_rmvar.rb +3 -3
- data/lib/moose_inventory/config/config.rb +43 -40
- data/lib/moose_inventory/db/db.rb +92 -52
- data/lib/moose_inventory/db/models.rb +11 -12
- data/lib/moose_inventory/inventory_context.rb +50 -0
- data/lib/moose_inventory/operations/add_associations.rb +127 -0
- data/lib/moose_inventory/operations/add_groups.rb +115 -0
- data/lib/moose_inventory/operations/add_hosts.rb +110 -0
- data/lib/moose_inventory/operations/group_child_relations.rb +118 -0
- data/lib/moose_inventory/operations/group_cleanup.rb +55 -0
- data/lib/moose_inventory/operations/remove_associations.rb +101 -0
- data/lib/moose_inventory/operations/remove_groups.rb +79 -0
- data/lib/moose_inventory/version.rb +1 -1
- data/moose-inventory.gemspec +38 -20
- data/scripts/check.sh +10 -0
- data/scripts/ci/check_permissions.sh +35 -0
- data/scripts/ci/check_rubocop.sh +28 -0
- data/scripts/ci/check_secrets.sh +26 -0
- data/scripts/ci/check_security.sh +68 -0
- data/scripts/ci/install_security_tools.sh +47 -0
- data/scripts/ci/package_sanity.sh +46 -0
- data/scripts/files.rb +1 -4
- data/scripts/install_dependencies.sh +19 -0
- data/scripts/reports.sh +2 -2
- data/spec/lib/moose_inventory/cli/cli_spec.rb +13 -14
- data/spec/lib/moose_inventory/cli/group_add_spec.rb +118 -119
- data/spec/lib/moose_inventory/cli/group_addchild_spec.rb +49 -51
- data/spec/lib/moose_inventory/cli/group_addhost_spec.rb +80 -83
- data/spec/lib/moose_inventory/cli/group_addvar_spec.rb +91 -91
- data/spec/lib/moose_inventory/cli/group_get_spec.rb +22 -23
- data/spec/lib/moose_inventory/cli/group_list_spec.rb +19 -20
- data/spec/lib/moose_inventory/cli/group_listvar_spec.rb +35 -36
- data/spec/lib/moose_inventory/cli/group_rm_spec.rb +115 -78
- data/spec/lib/moose_inventory/cli/group_rmchild_spec.rb +86 -45
- data/spec/lib/moose_inventory/cli/group_rmhost_spec.rb +43 -46
- data/spec/lib/moose_inventory/cli/group_rmvar_spec.rb +131 -131
- data/spec/lib/moose_inventory/cli/group_spec.rb +9 -9
- data/spec/lib/moose_inventory/cli/host_add_spec.rb +103 -43
- data/spec/lib/moose_inventory/cli/host_addgroup_spec.rb +78 -80
- data/spec/lib/moose_inventory/cli/host_addvar_spec.rb +122 -122
- data/spec/lib/moose_inventory/cli/host_get_spec.rb +16 -16
- data/spec/lib/moose_inventory/cli/host_list_spec.rb +8 -8
- data/spec/lib/moose_inventory/cli/host_listvar_spec.rb +50 -52
- data/spec/lib/moose_inventory/cli/host_rm_spec.rb +12 -12
- data/spec/lib/moose_inventory/cli/host_rmgroup_spec.rb +48 -51
- data/spec/lib/moose_inventory/cli/host_rmvar_spec.rb +136 -136
- data/spec/lib/moose_inventory/config/config_spec.rb +16 -3
- data/spec/lib/moose_inventory/db/db_spec.rb +386 -2
- data/spec/lib/moose_inventory/db/models_spec.rb +10 -11
- data/spec/lib/moose_inventory/operations/add_associations_spec.rb +77 -0
- data/spec/lib/moose_inventory/operations/add_groups_spec.rb +65 -0
- data/spec/lib/moose_inventory/operations/add_hosts_spec.rb +69 -0
- data/spec/lib/moose_inventory/operations/group_child_relations_spec.rb +76 -0
- data/spec/lib/moose_inventory/operations/remove_associations_spec.rb +78 -0
- data/spec/lib/moose_inventory/operations/remove_groups_spec.rb +57 -0
- data/spec/shared/shared_config_setup.rb +2 -2
- data/spec/spec_helper.rb +7 -8
- metadata +157 -105
- data/.coveralls.yml +0 -0
- data/Guardfile +0 -38
- data/config/dotfiles/coveralls.yml +0 -0
- data/config/dotfiles/gitignore +0 -20
- data/config/dotfiles/rubocop.yml +0 -793
- data/scripts/guard_quality.sh +0 -3
- data/scripts/guard_test.sh +0 -2
|
@@ -1,92 +1,105 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'thor'
|
|
2
|
-
require_relative '
|
|
4
|
+
require_relative 'formatter'
|
|
5
|
+
require_relative '../inventory_context'
|
|
6
|
+
require_relative '../operations/group_child_relations'
|
|
3
7
|
|
|
4
8
|
module Moose
|
|
5
9
|
module Inventory
|
|
6
10
|
module Cli
|
|
7
11
|
##
|
|
8
12
|
# Implemention of the "group addchild" methods of the CLI
|
|
9
|
-
class Group < Thor
|
|
13
|
+
class Group < Thor
|
|
10
14
|
#==========================
|
|
11
15
|
desc 'addchild PARENTGROUP CHILDGROUP_1 [CHILDGROUP_2 ... ]',
|
|
12
16
|
'Associate one or more child-groups CHILDGROUP_n with PARENTGROUP'
|
|
13
17
|
def addchild(*argv)
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
abort("ERROR: Cannot manually manipulate the automatic group 'ungrouped'.")
|
|
18
|
+
abort_if_missing_args(argv, 2, '2 or more')
|
|
19
|
+
|
|
20
|
+
pname = argv[0].downcase
|
|
21
|
+
cnames = normalize_names(argv.slice(1, argv.length - 1))
|
|
22
|
+
|
|
23
|
+
abort_if_automatic_group([pname] + cnames)
|
|
24
|
+
|
|
25
|
+
result = add_children_to_group(pname, cnames)
|
|
26
|
+
|
|
27
|
+
if result.warning_count.zero?
|
|
28
|
+
puts 'Succeeded.'
|
|
29
|
+
else
|
|
30
|
+
puts 'Succeeded, with warnings.'
|
|
28
31
|
end
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
#
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
cnames.each do |cname|
|
|
51
|
-
fmt.puts 2, "- add association {group:#{pname} <-> group:#{cname}}..."
|
|
52
|
-
|
|
53
|
-
# Check against existing associations
|
|
54
|
-
unless groups_ds[name: cname].nil?
|
|
55
|
-
warn_count += 1
|
|
56
|
-
fmt.warn "Association {group:#{pname} <-> group:#{cname}}}"\
|
|
57
|
-
" already exists, skipping.\n"
|
|
58
|
-
fmt.puts 4, '- already exists, skipping.'
|
|
59
|
-
fmt.puts 4, '- OK'
|
|
60
|
-
next
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
# Add new association
|
|
64
|
-
cgroup = db.models[:group].find(name: cname)
|
|
65
|
-
if cgroup.nil?
|
|
66
|
-
warn_count += 1
|
|
67
|
-
fmt.warn "Group '#{cname}' does not exist and will be created.\n"
|
|
68
|
-
fmt.puts 4, '- child group does not exist, creating now...'
|
|
69
|
-
cgroup = db.models[:group].create(name: cname)
|
|
70
|
-
fmt.puts 6, '- OK'
|
|
71
|
-
end
|
|
72
|
-
pgroup.add_child(cgroup)
|
|
73
|
-
fmt.puts 4, '- OK'
|
|
74
|
-
end
|
|
75
|
-
fmt.puts 2, '- all OK'
|
|
76
|
-
end # Transaction end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
def add_children_to_group(parent_name, child_names)
|
|
37
|
+
context = Moose::Inventory::InventoryContext.new(db: db)
|
|
38
|
+
operation = Moose::Inventory::Operations::GroupChildRelations.new(context: context)
|
|
39
|
+
|
|
40
|
+
begin
|
|
41
|
+
db.transaction do
|
|
42
|
+
puts "Associate parent group '#{parent_name}' with child group(s) '#{child_names.join(',')}':"
|
|
43
|
+
parent_group = fetch_existing_group_for_child_relation(context, parent_name)
|
|
44
|
+
result = operation.add_children(
|
|
45
|
+
parent_group: parent_group,
|
|
46
|
+
parent_name: parent_name,
|
|
47
|
+
child_names: child_names
|
|
48
|
+
)
|
|
49
|
+
render_addchild_events(result.events)
|
|
50
|
+
fmt.puts 2, '- all OK'
|
|
51
|
+
return result
|
|
52
|
+
end
|
|
77
53
|
rescue db.exceptions[:moose] => e
|
|
78
|
-
|
|
54
|
+
abort("ERROR: #{e}")
|
|
79
55
|
end
|
|
80
|
-
|
|
81
|
-
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def fetch_existing_group_for_child_relation(context, name)
|
|
59
|
+
fmt.puts 2, "- retrieve group '#{name}'..."
|
|
60
|
+
group = context.find_group(name)
|
|
61
|
+
abort("ERROR: The group '#{name}' does not exist.") if group.nil?
|
|
62
|
+
|
|
63
|
+
fmt.puts 4, '- OK'
|
|
64
|
+
group
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def render_addchild_events(events)
|
|
68
|
+
events.each { |event| render_addchild_event(event) }
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def render_addchild_event(event)
|
|
72
|
+
payload = event.payload
|
|
73
|
+
|
|
74
|
+
return render_addchild_warning(event.type, payload) if addchild_warning?(event.type)
|
|
75
|
+
return render_addchild_existing(payload) if event.type == :already_exists_skipping
|
|
76
|
+
|
|
77
|
+
case event.type
|
|
78
|
+
when :adding_child_association
|
|
79
|
+
fmt.puts 2, "- add association {group:#{payload[:parent]} <-> group:#{payload[:child]}}..."
|
|
80
|
+
when :child_group_creating_now
|
|
81
|
+
fmt.puts 4, '- child group does not exist, creating now...'
|
|
82
|
+
when :ok
|
|
83
|
+
fmt.puts payload[:indent], '- OK'
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def addchild_warning?(type)
|
|
88
|
+
%i[child_association_exists child_group_missing].include?(type)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def render_addchild_warning(type, payload)
|
|
92
|
+
if type == :child_association_exists
|
|
93
|
+
fmt.warn "Association {group:#{payload[:parent]} <-> group:#{payload[:child]}}} already exists, skipping.\n"
|
|
82
94
|
else
|
|
83
|
-
|
|
95
|
+
fmt.warn "Group '#{payload[:name]}' does not exist and will be created.\n"
|
|
84
96
|
end
|
|
85
|
-
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def render_addchild_existing(payload)
|
|
100
|
+
fmt.puts payload[:indent], '- already exists, skipping.'
|
|
86
101
|
end
|
|
87
102
|
end
|
|
88
103
|
end
|
|
89
104
|
end
|
|
90
105
|
end
|
|
91
|
-
|
|
92
|
-
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'thor'
|
|
2
|
-
require_relative '
|
|
4
|
+
require_relative 'formatter'
|
|
5
|
+
require_relative '../inventory_context'
|
|
6
|
+
require_relative '../operations/add_associations'
|
|
3
7
|
|
|
4
8
|
module Moose
|
|
5
9
|
module Inventory
|
|
@@ -10,88 +14,93 @@ module Moose
|
|
|
10
14
|
#==========================
|
|
11
15
|
desc 'addhost NAME HOSTNAME',
|
|
12
16
|
'Associate a host HOSTNAME with the group NAME'
|
|
13
|
-
def addhost(*args)
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
def addhost(*args)
|
|
18
|
+
abort_if_missing_args(args, 2, '2 or more')
|
|
19
|
+
|
|
20
|
+
name = args[0].downcase
|
|
21
|
+
hosts = normalize_names(args.slice(1, args.length - 1))
|
|
22
|
+
|
|
23
|
+
abort_if_automatic_group([name])
|
|
19
24
|
|
|
20
|
-
|
|
21
|
-
name = args[0].downcase
|
|
22
|
-
hosts = args.slice(1, args.length - 1).uniq.map(&:downcase)
|
|
25
|
+
result = add_hosts_to_group(name, hosts)
|
|
23
26
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
+
if result.warning_count.zero?
|
|
28
|
+
puts 'Succeeded.'
|
|
29
|
+
else
|
|
30
|
+
puts 'Succeeded, with warnings.'
|
|
27
31
|
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
private
|
|
28
35
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
36
|
+
def add_hosts_to_group(name, hosts)
|
|
37
|
+
context = Moose::Inventory::InventoryContext.new(db: db)
|
|
38
|
+
operation = Moose::Inventory::Operations::AddAssociations.new(context: context)
|
|
32
39
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
begin
|
|
36
|
-
db.transaction do # Transaction start
|
|
40
|
+
begin
|
|
41
|
+
db.transaction do
|
|
37
42
|
puts "Associate group '#{name}' with host(s) '#{hosts.join(',')}':"
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
if group.nil?
|
|
42
|
-
abort("ERROR: The group '#{name}' does not exist.")
|
|
43
|
-
end
|
|
44
|
-
fmt.puts 4, '- OK'
|
|
45
|
-
|
|
46
|
-
# Associate group with the hosts
|
|
47
|
-
ungrouped = db.models[:group].find_or_create(name: 'ungrouped')
|
|
48
|
-
hosts_ds = group.hosts_dataset
|
|
49
|
-
hosts.each do |h| # rubocop:disable Style/Next
|
|
50
|
-
fmt.puts 2, "- add association {group:#{name} <-> host:#{ h }}..."
|
|
51
|
-
|
|
52
|
-
# Check against existing associations
|
|
53
|
-
unless hosts_ds[name: h].nil?
|
|
54
|
-
warn_count += 1
|
|
55
|
-
fmt.warn "Association {group:#{name} <-> host:#{ h }} already"\
|
|
56
|
-
" exists, skipping.\n"
|
|
57
|
-
fmt.puts 4, '- already exists, skipping.'
|
|
58
|
-
fmt.puts 4, '- OK'
|
|
59
|
-
next
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
# Add new association
|
|
63
|
-
host = db.models[:host].find(name: h)
|
|
64
|
-
if host.nil?
|
|
65
|
-
warn_count += 1
|
|
66
|
-
fmt.warn "Host '#{h}' does not exist and will be created.\n"
|
|
67
|
-
fmt.puts 4, '- host does not exist, creating now...'
|
|
68
|
-
host = db.models[:host].create(name: h)
|
|
69
|
-
fmt.puts 6, '- OK'
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
group.add_host(host)
|
|
73
|
-
fmt.puts 4, '- OK'
|
|
74
|
-
|
|
75
|
-
# Remove the host from the ungrouped group, if necessary
|
|
76
|
-
unless host.groups_dataset[name: 'ungrouped'].nil?
|
|
77
|
-
fmt.puts 2,'- remove automatic association '\
|
|
78
|
-
"{group:ungrouped <-> host:#{h}}..."
|
|
79
|
-
host.remove_group(ungrouped)
|
|
80
|
-
fmt.puts 4, '- OK'
|
|
81
|
-
end
|
|
82
|
-
end
|
|
43
|
+
group = fetch_existing_group_for_addhost(context, name)
|
|
44
|
+
result = operation.group_to_hosts(group: group, group_name: name, host_names: hosts)
|
|
45
|
+
render_group_addhost_events(result.events)
|
|
83
46
|
fmt.puts 2, '- all OK'
|
|
84
|
-
|
|
47
|
+
return result
|
|
48
|
+
end
|
|
85
49
|
rescue db.exceptions[:moose] => e
|
|
86
50
|
abort("ERROR: #{e.message}")
|
|
87
51
|
end
|
|
88
|
-
|
|
89
|
-
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def fetch_existing_group_for_addhost(context, name)
|
|
55
|
+
fmt.puts 2, "- retrieve group '#{name}'..."
|
|
56
|
+
group = context.find_group(name)
|
|
57
|
+
abort("ERROR: The group '#{name}' does not exist.") if group.nil?
|
|
58
|
+
|
|
59
|
+
fmt.puts 4, '- OK'
|
|
60
|
+
group
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def render_group_addhost_events(events)
|
|
64
|
+
events.each { |event| render_group_addhost_event(event) }
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def render_group_addhost_event(event)
|
|
68
|
+
payload = event.payload
|
|
69
|
+
|
|
70
|
+
return render_group_addhost_warning(event.type, payload) if group_addhost_warning?(event.type)
|
|
71
|
+
return render_group_addhost_status(payload) if event.type == :already_exists_skipping
|
|
72
|
+
|
|
73
|
+
render_group_addhost_output(event.type, payload)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def group_addhost_warning?(type)
|
|
77
|
+
%i[group_host_association_exists host_missing_created].include?(type)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def render_group_addhost_warning(type, payload)
|
|
81
|
+
if type == :group_host_association_exists
|
|
82
|
+
fmt.warn "Association {group:#{payload[:group]} <-> host:#{payload[:host]}} already exists, skipping.\n"
|
|
90
83
|
else
|
|
91
|
-
|
|
84
|
+
fmt.warn "Host '#{payload[:name]}' does not exist and will be created.\n"
|
|
92
85
|
end
|
|
93
86
|
end
|
|
94
87
|
|
|
88
|
+
def render_group_addhost_status(payload)
|
|
89
|
+
fmt.puts payload[:indent], '- already exists, skipping.'
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def render_group_addhost_output(type, payload)
|
|
93
|
+
case type
|
|
94
|
+
when :adding_group_host_association
|
|
95
|
+
fmt.puts 2, "- add association {group:#{payload[:group]} <-> host:#{payload[:host]}}..."
|
|
96
|
+
when :host_creating_now
|
|
97
|
+
fmt.puts 4, '- host does not exist, creating now...'
|
|
98
|
+
when :removing_automatic_group
|
|
99
|
+
fmt.puts 2, "- remove automatic association {group:ungrouped <-> host:#{payload[:host]}}..."
|
|
100
|
+
when :ok
|
|
101
|
+
fmt.puts payload[:indent], '- OK'
|
|
102
|
+
end
|
|
103
|
+
end
|
|
95
104
|
end
|
|
96
105
|
end
|
|
97
106
|
end
|
|
@@ -22,49 +22,49 @@ module Moose
|
|
|
22
22
|
# Arguments
|
|
23
23
|
name = args[0].downcase
|
|
24
24
|
vars = args.slice(1, args.length - 1).uniq
|
|
25
|
-
|
|
26
|
-
# Transaction
|
|
27
|
-
db.transaction do # Transaction start
|
|
28
|
-
puts "Add variables '#{vars.join(",")}' to group '#{name}':"
|
|
29
|
-
fmt.puts 2,"- retrieve group '#{name}'..."
|
|
30
|
-
group = db.models[:group].find(name: name)
|
|
31
|
-
if group.nil?
|
|
32
|
-
fail db.exceptions[:moose],
|
|
33
|
-
"The group '#{name}' does not exist."
|
|
34
|
-
end
|
|
35
|
-
fmt.puts 4, '- OK'
|
|
36
|
-
|
|
37
|
-
groupvars_ds = group.groupvars_dataset
|
|
38
|
-
vars.each do |v|
|
|
39
|
-
fmt.puts 2, "- add variable '#{v}'..."
|
|
40
|
-
vararray = v.split('=')
|
|
41
25
|
|
|
42
|
-
|
|
26
|
+
# Transaction
|
|
27
|
+
db.transaction do # Transaction start
|
|
28
|
+
puts "Add variables '#{vars.join(',')}' to group '#{name}':"
|
|
29
|
+
fmt.puts 2, "- retrieve group '#{name}'..."
|
|
30
|
+
group = db.models[:group].find(name: name)
|
|
31
|
+
if group.nil?
|
|
43
32
|
fail db.exceptions[:moose],
|
|
44
|
-
"
|
|
33
|
+
"The group '#{name}' does not exist."
|
|
45
34
|
end
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
35
|
+
fmt.puts 4, '- OK'
|
|
36
|
+
|
|
37
|
+
groupvars_ds = group.groupvars_dataset
|
|
38
|
+
vars.each do |v|
|
|
39
|
+
fmt.puts 2, "- add variable '#{v}'..."
|
|
40
|
+
vararray = v.split('=')
|
|
41
|
+
|
|
42
|
+
if v.start_with?('=') || v.end_with?('=') || vararray.length != 2
|
|
43
|
+
fail db.exceptions[:moose],
|
|
44
|
+
"Incorrect format in '{#{v}}'. Expected 'key=value'."
|
|
55
45
|
end
|
|
56
|
-
|
|
57
|
-
#
|
|
58
|
-
groupvar =
|
|
59
|
-
|
|
60
|
-
|
|
46
|
+
|
|
47
|
+
# Check against existing associations
|
|
48
|
+
groupvar = groupvars_ds[name: vararray[0]]
|
|
49
|
+
if !groupvar.nil?
|
|
50
|
+
unless groupvar[:value] == vararray[1]
|
|
51
|
+
fmt.puts 4, '- already exists, applying as an update...'
|
|
52
|
+
update = db.models[:groupvar].find(id: groupvar[:id])
|
|
53
|
+
update[:value] = vararray[1]
|
|
54
|
+
update.save
|
|
55
|
+
end
|
|
56
|
+
else
|
|
57
|
+
# groupvar doesn't exist, so create and associate
|
|
58
|
+
groupvar = db.models[:groupvar].create(name: vararray[0],
|
|
59
|
+
value: vararray[1])
|
|
60
|
+
group.add_groupvar(groupvar)
|
|
61
|
+
end
|
|
62
|
+
fmt.puts 4, '- OK'
|
|
61
63
|
end
|
|
62
|
-
fmt.puts
|
|
63
|
-
end
|
|
64
|
-
fmt.puts 2, '- all OK'
|
|
65
|
-
end # Transaction end
|
|
64
|
+
fmt.puts 2, '- all OK'
|
|
65
|
+
end # Transaction end
|
|
66
66
|
|
|
67
|
-
|
|
67
|
+
puts 'Succeeded.'
|
|
68
68
|
end
|
|
69
69
|
end
|
|
70
70
|
end
|
|
@@ -9,13 +9,13 @@ module Moose
|
|
|
9
9
|
class Group
|
|
10
10
|
desc 'get GROUP_1 [GROUP_2 ...]', 'Get groups GROUP_n from the inventory'
|
|
11
11
|
def get(*argv) # rubocop:disable Metrics/AbcSize
|
|
12
|
-
if argv.
|
|
12
|
+
if argv.empty?
|
|
13
13
|
abort('ERROR: Wrong number of arguments, '\
|
|
14
14
|
"#{argv.length} for 1 or more")
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
# Convenience
|
|
18
|
-
db
|
|
18
|
+
db = Moose::Inventory::DB
|
|
19
19
|
fmt = Moose::Inventory::Cli::Formatter
|
|
20
20
|
|
|
21
21
|
# Arguments
|
|
@@ -25,32 +25,29 @@ module Moose
|
|
|
25
25
|
results = {}
|
|
26
26
|
names.each do |name|
|
|
27
27
|
group = db.models[:group].find(name: name)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
unless groupvars.length == 0
|
|
49
|
-
results[group[:name].to_sym][:groupvars] = groupvars
|
|
50
|
-
end
|
|
28
|
+
|
|
29
|
+
next if group.nil?
|
|
30
|
+
hosts = group.hosts_dataset.map(:name)
|
|
31
|
+
|
|
32
|
+
children = group.children_dataset.map(:name)
|
|
33
|
+
|
|
34
|
+
groupvars = {}
|
|
35
|
+
group.groupvars_dataset.each do |gv|
|
|
36
|
+
groupvars[gv[:name].to_sym] = gv[:value]
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
results[group[:name].to_sym] = {}
|
|
40
|
+
results[group[:name].to_sym][:hosts] = hosts unless hosts.empty?
|
|
41
|
+
|
|
42
|
+
unless children.empty?
|
|
43
|
+
results[group[:name].to_sym][:children] = children
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
unless groupvars.empty?
|
|
47
|
+
results[group[:name].to_sym][:groupvars] = groupvars
|
|
51
48
|
end
|
|
52
49
|
end
|
|
53
|
-
|
|
50
|
+
|
|
54
51
|
fmt.dump(results)
|
|
55
52
|
end
|
|
56
53
|
end
|
|
@@ -12,41 +12,38 @@ module Moose
|
|
|
12
12
|
'List the groups, together with any associated hosts and groupvars'
|
|
13
13
|
def list # rubocop:disable Metrics/AbcSize
|
|
14
14
|
# Convenience
|
|
15
|
-
db
|
|
15
|
+
db = Moose::Inventory::DB
|
|
16
16
|
confopts = Moose::Inventory::Config._confopts
|
|
17
|
-
|
|
17
|
+
|
|
18
18
|
# Process
|
|
19
19
|
results = {}
|
|
20
20
|
db.models[:group].all.each do |group|
|
|
21
|
-
|
|
22
21
|
hosts = group.hosts_dataset.map(:name)
|
|
23
22
|
|
|
24
23
|
# Hide the automatic ungrouped group, if it's empty
|
|
25
|
-
next if group[:name] == 'ungrouped' && hosts.
|
|
24
|
+
next if group[:name] == 'ungrouped' && hosts.empty?
|
|
26
25
|
|
|
27
26
|
children = group.children_dataset.map(:name)
|
|
28
|
-
|
|
27
|
+
|
|
29
28
|
groupvars = {}
|
|
30
29
|
group.groupvars_dataset.each do |gv|
|
|
31
30
|
groupvars[gv[:name].to_sym] = gv[:value]
|
|
32
31
|
end
|
|
33
32
|
|
|
34
|
-
|
|
35
33
|
results[group[:name].to_sym] = {}
|
|
36
|
-
unless hosts.
|
|
34
|
+
unless hosts.empty? && (confopts[:ansible] != true)
|
|
37
35
|
results[group[:name].to_sym][:hosts] = hosts
|
|
38
36
|
end
|
|
39
37
|
|
|
40
|
-
unless children.
|
|
38
|
+
unless children.empty?
|
|
41
39
|
results[group[:name].to_sym][:children] = children
|
|
42
40
|
end
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
end
|
|
41
|
+
|
|
42
|
+
next if groupvars.empty?
|
|
43
|
+
if confopts[:ansible] == true
|
|
44
|
+
results[group[:name].to_sym][:vars] = groupvars
|
|
45
|
+
else
|
|
46
|
+
results[group[:name].to_sym][:groupvars] = groupvars
|
|
50
47
|
end
|
|
51
48
|
end
|
|
52
49
|
Formatter.out(results)
|
|
@@ -19,23 +19,22 @@ module Moose
|
|
|
19
19
|
# Note, the Ansible spects don't call for a "--group GROUPNAME" method.
|
|
20
20
|
# So, strictly, there is no Ansible compatibility for this method.
|
|
21
21
|
# Instead, the Ansible compatibility included herein is for consistency
|
|
22
|
-
# with the "hosts listvars" method, which services the Ansible
|
|
22
|
+
# with the "hosts listvars" method, which services the Ansible
|
|
23
23
|
# "--host HOSTNAME" specs.
|
|
24
|
-
|
|
24
|
+
|
|
25
25
|
# sanity
|
|
26
26
|
if confopts[:ansible] == true
|
|
27
27
|
if argv.length != 1
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
abort('ERROR: Wrong number of arguments for Ansible mode, '\
|
|
29
|
+
"#{args.length} for 1.")
|
|
30
30
|
end
|
|
31
31
|
else
|
|
32
|
-
if argv.
|
|
32
|
+
if argv.empty?
|
|
33
33
|
abort('ERROR: Wrong number of arguments, '\
|
|
34
34
|
"#{args.length} for 1 or more.")
|
|
35
35
|
end
|
|
36
36
|
end
|
|
37
37
|
|
|
38
|
-
|
|
39
38
|
# Convenience
|
|
40
39
|
db = Moose::Inventory::DB
|
|
41
40
|
fmt = Moose::Inventory::Cli::Formatter
|
|
@@ -43,10 +42,10 @@ module Moose
|
|
|
43
42
|
# Arguments
|
|
44
43
|
names = argv.uniq.map(&:downcase)
|
|
45
44
|
|
|
46
|
-
#process
|
|
45
|
+
# process
|
|
47
46
|
results = {}
|
|
48
|
-
|
|
49
|
-
if confopts[:ansible] == true
|
|
47
|
+
|
|
48
|
+
if confopts[:ansible] == true
|
|
50
49
|
# This is the implementation per Ansible specs
|
|
51
50
|
name = names.first
|
|
52
51
|
group = db.models[:group].find(name: name)
|
|
@@ -61,11 +60,10 @@ module Moose
|
|
|
61
60
|
# This our more flexible implementation
|
|
62
61
|
names.each do |name|
|
|
63
62
|
group = db.models[:group].find(name: name)
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
end
|
|
63
|
+
next if group.nil?
|
|
64
|
+
results[name.to_sym] = {}
|
|
65
|
+
group.groupvars_dataset.each do |gv|
|
|
66
|
+
results[name.to_sym][gv[:name].to_sym] = gv[:value]
|
|
69
67
|
end
|
|
70
68
|
end
|
|
71
69
|
end
|