moose-inventory 2.0 → 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/.github/workflows/release.yml +2 -0
- data/.gitignore +2 -1
- data/.rubocop.yml +21 -0
- data/BACKLOG.md +630 -8
- data/Gemfile +2 -0
- data/Gemfile.lock +1 -1
- data/README.md +315 -39
- data/Rakefile +2 -0
- data/bin/moose-inventory +2 -1
- data/docs/architecture/architecture-and-trust-boundaries.md +444 -0
- data/docs/compatibility/cli-output-compatibility.md +76 -0
- data/docs/governance/approval-register.md +37 -0
- data/docs/maintenance/database-backup-restore-guidance.md +162 -0
- data/docs/maintenance/package-maintenance-and-agent-boundaries.md +260 -0
- data/docs/process/conformance-gap-analysis-2026-05-28.md +192 -0
- data/docs/product/product-brief.md +161 -0
- data/docs/product/requirements-baseline.md +477 -0
- data/docs/qa/qa-documentation-and-release-gates.md +283 -0
- data/docs/release/package-provenance-hardening.md +126 -0
- data/docs/release/publishing.md +11 -3
- data/docs/release/release-environment-protection.md +70 -0
- data/docs/release/release-readiness.md +23 -4
- data/docs/security/accepted-risk-register.md +84 -0
- data/docs/security/security-privacy-process.md +287 -0
- data/docs/security-audit-2026-05-26-rerun.md +2 -2
- data/docs/ux/cli-workflow-notes.md +287 -0
- data/examples/ansible/ansible.cfg +3 -0
- data/examples/ansible/inventory/moose_inventory.yml +5 -0
- data/examples/ansible/inventory_plugins/moose_inventory.py +100 -0
- data/examples/ci/README.md +16 -0
- data/examples/ci/github-actions/inventory-review.yml +38 -0
- data/examples/ci/inventory/example-snapshot.yml +19 -0
- data/examples/ci/scripts/validate-inventory-snapshot.sh +30 -0
- data/lib/moose_inventory/cli/application.rb +133 -5
- data/lib/moose_inventory/cli/association_rendering.rb +74 -0
- data/lib/moose_inventory/cli/association_rendering_support.rb +89 -0
- data/lib/moose_inventory/cli/audit.rb +62 -0
- data/lib/moose_inventory/cli/audit_recording.rb +40 -0
- data/lib/moose_inventory/cli/child_relation_rendering.rb +110 -0
- data/lib/moose_inventory/cli/console.rb +135 -0
- data/lib/moose_inventory/cli/db.rb +64 -0
- data/lib/moose_inventory/cli/factory.rb +28 -0
- data/lib/moose_inventory/cli/formatter.rb +8 -12
- data/lib/moose_inventory/cli/group.rb +5 -2
- data/lib/moose_inventory/cli/group_add.rb +11 -9
- data/lib/moose_inventory/cli/group_addchild.rb +23 -65
- data/lib/moose_inventory/cli/group_addhost.rb +16 -67
- data/lib/moose_inventory/cli/group_addvar.rb +27 -47
- data/lib/moose_inventory/cli/group_get.rb +8 -42
- data/lib/moose_inventory/cli/group_list.rb +7 -40
- data/lib/moose_inventory/cli/group_listvars.rb +9 -55
- data/lib/moose_inventory/cli/group_rm.rb +12 -10
- data/lib/moose_inventory/cli/group_rmchild.rb +26 -82
- data/lib/moose_inventory/cli/group_rmhost.rb +18 -53
- data/lib/moose_inventory/cli/group_rmvar.rb +30 -41
- data/lib/moose_inventory/cli/group_tags.rb +33 -0
- data/lib/moose_inventory/cli/helpers.rb +68 -1
- data/lib/moose_inventory/cli/host.rb +6 -3
- data/lib/moose_inventory/cli/host_add.rb +69 -29
- data/lib/moose_inventory/cli/host_addgroup.rb +22 -58
- data/lib/moose_inventory/cli/host_addvar.rb +28 -52
- data/lib/moose_inventory/cli/host_get.rb +9 -37
- data/lib/moose_inventory/cli/host_list.rb +24 -21
- data/lib/moose_inventory/cli/host_listvars.rb +9 -62
- data/lib/moose_inventory/cli/host_rm.rb +60 -42
- data/lib/moose_inventory/cli/host_rmgroup.rb +25 -44
- data/lib/moose_inventory/cli/host_rmvar.rb +31 -45
- data/lib/moose_inventory/cli/host_tags.rb +33 -0
- data/lib/moose_inventory/cli/listvars_support.rb +55 -0
- data/lib/moose_inventory/cli/plan_rendering.rb +50 -0
- data/lib/moose_inventory/cli/relation_transaction_support.rb +51 -0
- data/lib/moose_inventory/cli/tag_support.rb +97 -0
- data/lib/moose_inventory/cli/variable_rendering.rb +67 -0
- data/lib/moose_inventory/config/config.rb +185 -108
- data/lib/moose_inventory/db/db.rb +170 -195
- data/lib/moose_inventory/db/exceptions.rb +6 -3
- data/lib/moose_inventory/db/models.rb +16 -0
- data/lib/moose_inventory/db/schema_migrations.rb +248 -0
- data/lib/moose_inventory/inventory_context.rb +68 -2
- data/lib/moose_inventory/operations/add_associations.rb +20 -16
- data/lib/moose_inventory/operations/add_groups.rb +21 -13
- data/lib/moose_inventory/operations/add_hosts.rb +30 -17
- data/lib/moose_inventory/operations/add_variables.rb +77 -0
- data/lib/moose_inventory/operations/entity_variable_operation_support.rb +46 -0
- data/lib/moose_inventory/operations/group_child_relations.rb +23 -16
- data/lib/moose_inventory/operations/group_cleanup.rb +23 -8
- data/lib/moose_inventory/operations/import_inventory_snapshot.rb +41 -0
- data/lib/moose_inventory/operations/inventory_doctor.rb +172 -0
- data/lib/moose_inventory/operations/inventory_snapshot.rb +60 -0
- data/lib/moose_inventory/operations/inventory_snapshot_applier.rb +112 -0
- data/lib/moose_inventory/operations/inventory_snapshot_preview.rb +174 -0
- data/lib/moose_inventory/operations/inventory_snapshot_validator.rb +134 -0
- data/lib/moose_inventory/operations/operation_event_support.rb +27 -0
- data/lib/moose_inventory/operations/query_inventory/base_query.rb +24 -0
- data/lib/moose_inventory/operations/query_inventory/group_queries.rb +86 -0
- data/lib/moose_inventory/operations/query_inventory/host_queries.rb +106 -0
- data/lib/moose_inventory/operations/query_inventory.rb +47 -0
- data/lib/moose_inventory/operations/remove_associations.rb +30 -18
- data/lib/moose_inventory/operations/remove_groups.rb +12 -12
- data/lib/moose_inventory/operations/remove_hosts.rb +68 -0
- data/lib/moose_inventory/operations/remove_variables.rb +67 -0
- data/lib/moose_inventory/runtime_options.rb +31 -0
- data/lib/moose_inventory/version.rb +3 -1
- data/lib/moose_inventory.rb +10 -7
- data/moose-inventory.gemspec +19 -35
- data/scripts/check.sh +1 -0
- data/scripts/ci/check_generated_artifacts.sh +41 -0
- data/scripts/ci/check_permissions.sh +2 -0
- data/scripts/ci/check_rubocop.sh +30 -25
- data/scripts/files.rb +5 -4
- data/spec/examples/ci_examples_spec.rb +37 -0
- data/spec/lib/moose_inventory/ansible_plugin_examples_spec.rb +29 -0
- data/spec/lib/moose_inventory/cli/application_doctor_spec.rb +50 -0
- data/spec/lib/moose_inventory/cli/application_import_export_spec.rb +100 -0
- data/spec/lib/moose_inventory/cli/application_spec.rb +25 -15
- data/spec/lib/moose_inventory/cli/audit_spec.rb +56 -0
- data/spec/lib/moose_inventory/cli/cli_spec.rb +15 -19
- data/spec/lib/moose_inventory/cli/console_spec.rb +98 -0
- data/spec/lib/moose_inventory/cli/factory_spec.rb +27 -0
- data/spec/lib/moose_inventory/cli/formatter_spec.rb +95 -3
- data/spec/lib/moose_inventory/cli/group_add_spec.rb +140 -116
- data/spec/lib/moose_inventory/cli/group_addchild_spec.rb +89 -35
- data/spec/lib/moose_inventory/cli/group_addhost_spec.rb +81 -84
- data/spec/lib/moose_inventory/cli/group_addvar_spec.rb +65 -68
- data/spec/lib/moose_inventory/cli/group_get_spec.rb +17 -33
- data/spec/lib/moose_inventory/cli/group_list_spec.rb +16 -38
- data/spec/lib/moose_inventory/cli/group_listvar_spec.rb +33 -40
- data/spec/lib/moose_inventory/cli/group_rm_spec.rb +136 -96
- data/spec/lib/moose_inventory/cli/group_rmchild_spec.rb +66 -41
- data/spec/lib/moose_inventory/cli/group_rmhost_spec.rb +76 -78
- data/spec/lib/moose_inventory/cli/group_rmvar_spec.rb +57 -63
- data/spec/lib/moose_inventory/cli/group_spec.rb +2 -0
- data/spec/lib/moose_inventory/cli/helpers_spec.rb +146 -0
- data/spec/lib/moose_inventory/cli/host_add_spec.rb +170 -116
- data/spec/lib/moose_inventory/cli/host_addgroup_spec.rb +100 -83
- data/spec/lib/moose_inventory/cli/host_addvar_spec.rb +92 -74
- data/spec/lib/moose_inventory/cli/host_get_spec.rb +14 -33
- data/spec/lib/moose_inventory/cli/host_list_spec.rb +41 -33
- data/spec/lib/moose_inventory/cli/host_listvar_spec.rb +45 -53
- data/spec/lib/moose_inventory/cli/host_rm_spec.rb +66 -48
- data/spec/lib/moose_inventory/cli/host_rmgroup_spec.rb +73 -83
- data/spec/lib/moose_inventory/cli/host_rmvar_spec.rb +56 -63
- data/spec/lib/moose_inventory/cli/host_spec.rb +2 -0
- data/spec/lib/moose_inventory/cli/tags_spec.rb +81 -0
- data/spec/lib/moose_inventory/config/config_spec.rb +41 -3
- data/spec/lib/moose_inventory/db/db_spec.rb +396 -36
- data/spec/lib/moose_inventory/db/exceptions_spec.rb +18 -0
- data/spec/lib/moose_inventory/db/models_spec.rb +7 -3
- data/spec/lib/moose_inventory/db_lifecycle_spec.rb +73 -0
- data/spec/lib/moose_inventory/inventory_context_spec.rb +10 -0
- data/spec/lib/moose_inventory/operations/add_associations_spec.rb +34 -0
- data/spec/lib/moose_inventory/operations/add_groups_spec.rb +15 -0
- data/spec/lib/moose_inventory/operations/add_hosts_spec.rb +13 -0
- data/spec/lib/moose_inventory/operations/add_variables_spec.rb +103 -0
- data/spec/lib/moose_inventory/operations/group_child_relations_spec.rb +46 -0
- data/spec/lib/moose_inventory/operations/import_inventory_snapshot_spec.rb +226 -0
- data/spec/lib/moose_inventory/operations/inventory_doctor_spec.rb +77 -0
- data/spec/lib/moose_inventory/operations/inventory_snapshot_spec.rb +50 -0
- data/spec/lib/moose_inventory/operations/operation_event_support_spec.rb +78 -0
- data/spec/lib/moose_inventory/operations/query_inventory_spec.rb +146 -0
- data/spec/lib/moose_inventory/operations/remove_associations_spec.rb +35 -0
- data/spec/lib/moose_inventory/operations/remove_groups_spec.rb +21 -0
- data/spec/lib/moose_inventory/operations/remove_hosts_spec.rb +55 -0
- data/spec/lib/moose_inventory/operations/remove_variables_spec.rb +83 -0
- data/spec/shared/shared_config_setup.rb +4 -3
- data/spec/spec_helper.rb +50 -40
- data/spec/support/cli_harness.rb +33 -0
- metadata +80 -41
|
@@ -1,48 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# rubocop:disable Metrics/BlockLength
|
|
1
4
|
require 'spec_helper'
|
|
2
5
|
|
|
3
|
-
# TODO: the usual respond_to? method doesn't seem to work on Thor objects.
|
|
4
6
|
# Why not? For now, we'll check against instance_methods.
|
|
5
7
|
|
|
6
8
|
RSpec.describe Moose::Inventory::Cli::Group do
|
|
7
9
|
before(:all) do
|
|
8
|
-
|
|
9
|
-
@mockarg_parts = {
|
|
10
|
-
config: File.join(spec_root, 'config/config.yml'),
|
|
11
|
-
format: 'yaml',
|
|
12
|
-
env: 'test',
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
@mockargs = []
|
|
16
|
-
@mockarg_parts.each do |key, val|
|
|
17
|
-
@mockargs << "--#{key}"
|
|
18
|
-
@mockargs << val
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
@config = Moose::Inventory::Config
|
|
22
|
-
@config.init(@mockargs)
|
|
23
|
-
|
|
24
|
-
@db = Moose::Inventory::DB
|
|
25
|
-
@db.init if @db.db.nil?
|
|
26
|
-
|
|
27
|
-
@console = Moose::Inventory::Cli::Formatter
|
|
28
|
-
@group = Moose::Inventory::Cli::Group
|
|
29
|
-
@app = Moose::Inventory::Cli::Application
|
|
10
|
+
setup_cli_harness(command_class: Moose::Inventory::Cli::Group, command_ivar: :@group)
|
|
30
11
|
end
|
|
31
12
|
|
|
32
13
|
before(:each) do
|
|
33
|
-
|
|
14
|
+
reset_cli_harness
|
|
34
15
|
end
|
|
35
16
|
|
|
36
17
|
describe 'rmvar' do
|
|
37
18
|
it 'should be responsive' do
|
|
38
|
-
result = @group.
|
|
19
|
+
result = @group.method_defined?(:rmvar, false)
|
|
39
20
|
expect(result).to eq(true)
|
|
40
21
|
end
|
|
41
22
|
|
|
42
23
|
#-----------------
|
|
43
24
|
it '<missing args> ... should abort with an error' do
|
|
44
25
|
actual = runner do
|
|
45
|
-
@app.start(%w
|
|
26
|
+
@app.start(%w[group rmvar])
|
|
46
27
|
end
|
|
47
28
|
|
|
48
29
|
# Check output
|
|
@@ -56,16 +37,16 @@ RSpec.describe Moose::Inventory::Cli::Group do
|
|
|
56
37
|
group_name = 'does-not-exist'
|
|
57
38
|
var_name = 'foo=bar'
|
|
58
39
|
actual = runner do
|
|
59
|
-
@app.start(%W
|
|
40
|
+
@app.start(%W[group rmvar #{group_name} #{var_name} --yes])
|
|
60
41
|
end
|
|
61
42
|
|
|
62
43
|
# Check output
|
|
63
44
|
desired = { aborted: true }
|
|
64
45
|
desired[:STDOUT] =
|
|
65
|
-
"Remove variable(s) '#{var_name}' from group '#{group_name}':\n"\
|
|
66
|
-
"
|
|
46
|
+
"Remove variable(s) '#{var_name}' from group '#{group_name}':\n " \
|
|
47
|
+
"- retrieve group '#{group_name}'...\n"
|
|
67
48
|
desired[:STDERR] =
|
|
68
|
-
"An error occurred during a transaction, any changes have been rolled back.\n"\
|
|
49
|
+
"An error occurred during a transaction, any changes have been rolled back.\n" \
|
|
69
50
|
"ERROR: The group '#{group_name}' does not exist.\n"
|
|
70
51
|
expected(actual, desired)
|
|
71
52
|
end
|
|
@@ -77,44 +58,57 @@ RSpec.describe Moose::Inventory::Cli::Group do
|
|
|
77
58
|
|
|
78
59
|
group_name = 'test1'
|
|
79
60
|
@db.models[:group].create(name: group_name)
|
|
80
|
-
|
|
81
|
-
var = { name: 'foo', value: 'bar' }
|
|
82
|
-
cases = %w(
|
|
61
|
+
cases = %w[
|
|
83
62
|
=bar
|
|
84
63
|
foo=bar=
|
|
85
64
|
=foo=bar
|
|
86
65
|
foo=bar=extra
|
|
87
|
-
|
|
66
|
+
]
|
|
88
67
|
|
|
89
68
|
cases.each do |args|
|
|
90
69
|
actual = runner do
|
|
91
|
-
@app.start(%W
|
|
70
|
+
@app.start(%W[group rmvar #{group_name} #{args} --yes])
|
|
92
71
|
end
|
|
93
72
|
# @console.out(actual,'p')
|
|
94
73
|
|
|
95
74
|
desired = { aborted: true }
|
|
96
75
|
desired[:STDOUT] =
|
|
97
|
-
"Remove variable(s) '#{args}' from group '#{group_name}':\n"\
|
|
98
|
-
"
|
|
99
|
-
"
|
|
100
|
-
"
|
|
76
|
+
"Remove variable(s) '#{args}' from group '#{group_name}':\n " \
|
|
77
|
+
"- retrieve group '#{group_name}'...\n " \
|
|
78
|
+
"- OK\n " \
|
|
79
|
+
"- remove variable '#{args}'...\n"
|
|
101
80
|
desired[:STDERR] =
|
|
102
|
-
"An error occurred during a transaction, any changes have been rolled back.\n"\
|
|
81
|
+
"An error occurred during a transaction, any changes have been rolled back.\n" \
|
|
103
82
|
"ERROR: Incorrect format in {#{args}}. Expected 'key' or 'key=value'.\n"
|
|
104
83
|
|
|
105
84
|
expected(actual, desired)
|
|
106
85
|
end
|
|
107
86
|
end
|
|
108
87
|
|
|
88
|
+
#------------------------
|
|
89
|
+
it 'GROUP key --dry-run should not remove the group variable' do
|
|
90
|
+
group_name = 'group_test'
|
|
91
|
+
@db.models[:group].create(name: group_name)
|
|
92
|
+
runner { @app.start(%W[group addvar #{group_name} var1=val1]) }
|
|
93
|
+
|
|
94
|
+
actual = runner { @app.start(%W[group rmvar #{group_name} var1 --dry-run]) }
|
|
95
|
+
|
|
96
|
+
expect(actual[:unexpected]).to eq(false)
|
|
97
|
+
expect(actual[:aborted]).to eq(false)
|
|
98
|
+
expect(actual[:STDOUT]).to include('Dry run complete. No changes applied.')
|
|
99
|
+
group = @db.models[:group].find(name: group_name)
|
|
100
|
+
expect(group.groupvars_dataset[name: 'var1']).not_to be_nil
|
|
101
|
+
end
|
|
102
|
+
|
|
109
103
|
#------------------------
|
|
110
104
|
it 'GROUP <valid args> ... should remove the group variable' do
|
|
111
105
|
group_name = 'group_test'
|
|
112
106
|
var = { name: 'foo', value: 'bar' }
|
|
113
|
-
cases = %W
|
|
107
|
+
cases = %W[
|
|
114
108
|
#{var[:name]}
|
|
115
109
|
#{var[:name]}=
|
|
116
110
|
#{var[:name]}=#{var[:value]}
|
|
117
|
-
|
|
111
|
+
]
|
|
118
112
|
cases.each do |example|
|
|
119
113
|
# reset the db
|
|
120
114
|
@db.reset
|
|
@@ -122,24 +116,24 @@ RSpec.describe Moose::Inventory::Cli::Group do
|
|
|
122
116
|
# Add an initial group and groupvar
|
|
123
117
|
@db.models[:group].create(name: group_name)
|
|
124
118
|
runner do
|
|
125
|
-
@app.start(%W
|
|
119
|
+
@app.start(%W[group addvar #{group_name} #{var[:name]}=#{var[:value]}])
|
|
126
120
|
end
|
|
127
121
|
|
|
128
122
|
# Try to remove the groupvar using the case example valid args
|
|
129
123
|
actual = runner do
|
|
130
|
-
@app.start(%W
|
|
124
|
+
@app.start(%W[group rmvar #{group_name} #{example} --yes])
|
|
131
125
|
end
|
|
132
126
|
# @console.out(actual,'p')
|
|
133
127
|
|
|
134
128
|
# Check the output
|
|
135
129
|
desired = { aborted: false }
|
|
136
130
|
desired[:STDOUT] =
|
|
137
|
-
"Remove variable(s) '#{example}' from group '#{group_name}':\n"\
|
|
138
|
-
"
|
|
139
|
-
"
|
|
140
|
-
"
|
|
141
|
-
"
|
|
142
|
-
"
|
|
131
|
+
"Remove variable(s) '#{example}' from group '#{group_name}':\n " \
|
|
132
|
+
"- retrieve group '#{group_name}'...\n " \
|
|
133
|
+
"- OK\n " \
|
|
134
|
+
"- remove variable '#{example}'...\n " \
|
|
135
|
+
"- OK\n " \
|
|
136
|
+
"- all OK\n" \
|
|
143
137
|
"Succeeded.\n"
|
|
144
138
|
|
|
145
139
|
# @console.out(desired,'p')
|
|
@@ -160,36 +154,35 @@ RSpec.describe Moose::Inventory::Cli::Group do
|
|
|
160
154
|
group_name = 'test_group'
|
|
161
155
|
varsarray = [
|
|
162
156
|
{ name: 'var1', value: 'val1' },
|
|
163
|
-
{ name: 'var2', value: 'val2' }
|
|
157
|
+
{ name: 'var2', value: 'val2' }
|
|
164
158
|
]
|
|
165
159
|
|
|
166
|
-
vars =
|
|
167
|
-
|
|
168
|
-
vars << "#{var[:name]}=#{var[:value]}"
|
|
160
|
+
vars = varsarray.map do |var|
|
|
161
|
+
"#{var[:name]}=#{var[:value]}"
|
|
169
162
|
end
|
|
170
163
|
|
|
171
164
|
@db.models[:group].create(name: group_name)
|
|
172
|
-
|
|
173
|
-
@app.start(%W
|
|
165
|
+
runner do
|
|
166
|
+
@app.start(%W[group addvar #{group_name}] + vars)
|
|
174
167
|
end
|
|
175
168
|
|
|
176
169
|
actual = runner do
|
|
177
|
-
@app.start(%W
|
|
170
|
+
@app.start(%W[group rmvar #{group_name} --yes] + vars)
|
|
178
171
|
end
|
|
179
172
|
# @console.out(actual,'y')
|
|
180
173
|
|
|
181
174
|
desired = { aborted: false }
|
|
182
175
|
desired[:STDOUT] =
|
|
183
|
-
"Remove variable(s) '#{vars.join(',')}' from group '#{group_name}':\n"\
|
|
184
|
-
"
|
|
185
|
-
"
|
|
176
|
+
"Remove variable(s) '#{vars.join(',')}' from group '#{group_name}':\n " \
|
|
177
|
+
"- retrieve group '#{group_name}'...\n " \
|
|
178
|
+
"- OK\n"
|
|
186
179
|
vars.each do |var|
|
|
187
180
|
desired[:STDOUT] = desired[:STDOUT] +
|
|
188
|
-
" - remove variable '#{var}'...\n"\
|
|
189
|
-
"
|
|
181
|
+
" - remove variable '#{var}'...\n " \
|
|
182
|
+
"- OK\n"
|
|
190
183
|
end
|
|
191
184
|
desired[:STDOUT] = desired[:STDOUT] +
|
|
192
|
-
" - all OK\n"\
|
|
185
|
+
" - all OK\n" \
|
|
193
186
|
"Succeeded.\n"
|
|
194
187
|
expected(actual, desired)
|
|
195
188
|
|
|
@@ -200,3 +193,4 @@ RSpec.describe Moose::Inventory::Cli::Group do
|
|
|
200
193
|
end
|
|
201
194
|
end
|
|
202
195
|
end
|
|
196
|
+
# rubocop:enable Metrics/BlockLength
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
# rubocop:disable Metrics/BlockLength
|
|
6
|
+
RSpec.describe Moose::Inventory::Cli::Helpers do
|
|
7
|
+
subject(:helper) { helper_class.new }
|
|
8
|
+
|
|
9
|
+
let(:helper_class) do
|
|
10
|
+
Class.new do
|
|
11
|
+
include Moose::Inventory::Cli::Helpers
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
let(:inventory_context) { instance_double(Moose::Inventory::InventoryContext) }
|
|
16
|
+
let(:automatic_group) { instance_double('AutomaticGroup') }
|
|
17
|
+
|
|
18
|
+
before do
|
|
19
|
+
helper.instance_variable_set(:@inventory_context, inventory_context)
|
|
20
|
+
allow(inventory_context).to receive(:automatic_group).and_return(automatic_group)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
describe 'small helper methods' do
|
|
24
|
+
it 'checks whether an association dataset contains a named record' do
|
|
25
|
+
dataset = instance_double('Dataset')
|
|
26
|
+
|
|
27
|
+
expect(helper.send(:association_exists?, nil, 'alpha')).to eq(false)
|
|
28
|
+
allow(dataset).to receive(:[]).with(name: 'alpha').and_return(nil)
|
|
29
|
+
expect(helper.send(:association_exists?, dataset, 'alpha')).to eq(false)
|
|
30
|
+
allow(dataset).to receive(:[]).with(name: 'beta').and_return({ name: 'beta' })
|
|
31
|
+
expect(helper.send(:association_exists?, dataset, 'beta')).to eq(true)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it 'converts exceptions to strings' do
|
|
35
|
+
expect(helper.send(:exception_to_s, RuntimeError.new('boom'))).to eq('boom')
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it 'returns the automatic group through the inventory context' do
|
|
39
|
+
expect(helper.send(:automatic_group)).to eq(automatic_group)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
describe 'run_group_relation_transaction' do
|
|
44
|
+
it 'prints the heading and success marker for a successful transaction' do
|
|
45
|
+
allow(Moose::Inventory::DB).to receive(:transaction).and_yield
|
|
46
|
+
expect(Moose::Inventory::Cli::Formatter).to receive(:puts).with(2, '- all OK')
|
|
47
|
+
|
|
48
|
+
result = nil
|
|
49
|
+
actual = runner do
|
|
50
|
+
result = helper.send(:run_group_relation_transaction, heading: 'Heading') { :done }
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
expect(result).to eq(:done)
|
|
54
|
+
expected(actual, aborted: false, STDOUT: "Heading\n", STDERR: '')
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it 'aborts with the Moose exception message when no custom handler is supplied' do
|
|
58
|
+
error = Moose::Inventory::DB::MooseDBException.new('boom')
|
|
59
|
+
allow(Moose::Inventory::DB).to receive(:transaction).and_raise(error)
|
|
60
|
+
allow(Moose::Inventory::DB).to receive(:exceptions).and_return({ moose: Moose::Inventory::DB::MooseDBException })
|
|
61
|
+
|
|
62
|
+
actual = runner do
|
|
63
|
+
helper.send(:run_group_relation_transaction, heading: 'Heading') { :done }
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
expected(actual, aborted: true, STDOUT: '', STDERR: "ERROR: boom\n")
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it 'uses the custom Moose exception handler when provided' do
|
|
70
|
+
error = Moose::Inventory::DB::MooseDBException.new('boom')
|
|
71
|
+
allow(Moose::Inventory::DB).to receive(:transaction).and_raise(error)
|
|
72
|
+
allow(Moose::Inventory::DB).to receive(:exceptions).and_return({ moose: Moose::Inventory::DB::MooseDBException })
|
|
73
|
+
|
|
74
|
+
actual = runner do
|
|
75
|
+
helper.send(
|
|
76
|
+
:run_group_relation_transaction,
|
|
77
|
+
heading: 'Heading',
|
|
78
|
+
on_error: ->(e) { "wrapped #{e.message}" }
|
|
79
|
+
) { :done }
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
expected(actual, aborted: true, STDOUT: '', STDERR: "ERROR: wrapped boom\n")
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
describe 'automatic-group helpers' do
|
|
87
|
+
it 'removes the automatic group from a host when present' do
|
|
88
|
+
host = instance_double('Host')
|
|
89
|
+
dataset = instance_double('Dataset')
|
|
90
|
+
ungrouped = instance_double('Group')
|
|
91
|
+
allow(host).to receive(:groups_dataset).and_return(dataset)
|
|
92
|
+
allow(dataset).to receive(:[]).with(name: 'ungrouped').and_return(ungrouped)
|
|
93
|
+
expect(Moose::Inventory::Cli::Formatter).to receive(:puts).with(2, 'remove auto')
|
|
94
|
+
expect(host).to receive(:remove_group).with(ungrouped)
|
|
95
|
+
expect(Moose::Inventory::Cli::Formatter).to receive(:puts).with(4, '- OK')
|
|
96
|
+
|
|
97
|
+
helper.send(:remove_automatic_group_from_host, host, indent: 2, message: 'remove auto')
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
it 'does nothing when the automatic group is not present' do
|
|
101
|
+
host = instance_double('Host')
|
|
102
|
+
dataset = instance_double('Dataset')
|
|
103
|
+
allow(host).to receive(:groups_dataset).and_return(dataset)
|
|
104
|
+
allow(dataset).to receive(:[]).with(name: 'ungrouped').and_return(nil)
|
|
105
|
+
|
|
106
|
+
expect(Moose::Inventory::Cli::Formatter).not_to receive(:puts)
|
|
107
|
+
expect(host).not_to receive(:remove_group)
|
|
108
|
+
|
|
109
|
+
helper.send(:remove_automatic_group_from_host, host, indent: 2, message: 'remove auto')
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
it 'adds the automatic group when the last non-automatic group is removed' do
|
|
113
|
+
host = instance_double('Host')
|
|
114
|
+
dataset = instance_double('Dataset', count: 1)
|
|
115
|
+
allow(host).to receive(:groups_dataset).and_return(dataset)
|
|
116
|
+
expect(Moose::Inventory::Cli::Formatter).to receive(:puts).with(2, 'add auto')
|
|
117
|
+
expect(host).to receive(:add_group).with(automatic_group)
|
|
118
|
+
expect(Moose::Inventory::Cli::Formatter).to receive(:puts).with(4, '- OK')
|
|
119
|
+
|
|
120
|
+
helper.send(:add_automatic_group_to_host_if_last_group, host, indent: 2, message: 'add auto')
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it 'adds the automatic group when a host has no groups' do
|
|
124
|
+
host = instance_double('Host')
|
|
125
|
+
dataset = instance_double('Dataset', count: 0)
|
|
126
|
+
allow(host).to receive(:groups_dataset).and_return(dataset)
|
|
127
|
+
expect(Moose::Inventory::Cli::Formatter).to receive(:puts).with(2, 'add auto')
|
|
128
|
+
expect(host).to receive(:add_group).with(automatic_group)
|
|
129
|
+
expect(Moose::Inventory::Cli::Formatter).to receive(:puts).with(4, '- OK')
|
|
130
|
+
|
|
131
|
+
helper.send(:add_automatic_group_to_host_if_no_groups, host, indent: 2, message: 'add auto')
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
it 'does nothing when the group count does not match the requested threshold' do
|
|
135
|
+
host = instance_double('Host')
|
|
136
|
+
dataset = instance_double('Dataset', count: 2)
|
|
137
|
+
allow(host).to receive(:groups_dataset).and_return(dataset)
|
|
138
|
+
|
|
139
|
+
expect(Moose::Inventory::Cli::Formatter).not_to receive(:puts)
|
|
140
|
+
expect(host).not_to receive(:add_group)
|
|
141
|
+
|
|
142
|
+
helper.send(:add_automatic_group_to_host_if_group_count, host, 1, indent: 2, message: 'add auto')
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
# rubocop:enable Metrics/BlockLength
|