moose-inventory 1.0.7 → 1.0.9

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.
Files changed (81) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/ci.yml +35 -0
  3. data/.gitignore +1 -1
  4. data/BACKLOG.md +184 -0
  5. data/Gemfile.lock +60 -0
  6. data/README.md +23 -5
  7. data/bin/moose-inventory +1 -1
  8. data/docs/release/publishing.md +113 -0
  9. data/docs/release/release-readiness.md +41 -0
  10. data/docs/security-audit-2026-05-21.md +71 -0
  11. data/lib/moose_inventory/cli/formatter.rb +16 -17
  12. data/lib/moose_inventory/cli/group.rb +1 -1
  13. data/lib/moose_inventory/cli/group_add.rb +19 -21
  14. data/lib/moose_inventory/cli/group_addchild.rb +36 -40
  15. data/lib/moose_inventory/cli/group_addhost.rb +14 -18
  16. data/lib/moose_inventory/cli/group_addvar.rb +37 -37
  17. data/lib/moose_inventory/cli/group_get.rb +23 -26
  18. data/lib/moose_inventory/cli/group_list.rb +12 -15
  19. data/lib/moose_inventory/cli/group_listvars.rb +12 -14
  20. data/lib/moose_inventory/cli/group_rm.rb +36 -21
  21. data/lib/moose_inventory/cli/group_rmchild.rb +5 -6
  22. data/lib/moose_inventory/cli/group_rmhost.rb +12 -16
  23. data/lib/moose_inventory/cli/group_rmvar.rb +5 -5
  24. data/lib/moose_inventory/cli/host.rb +1 -1
  25. data/lib/moose_inventory/cli/host_add.rb +18 -18
  26. data/lib/moose_inventory/cli/host_addgroup.rb +9 -9
  27. data/lib/moose_inventory/cli/host_addvar.rb +6 -6
  28. data/lib/moose_inventory/cli/host_get.rb +15 -18
  29. data/lib/moose_inventory/cli/host_list.rb +3 -3
  30. data/lib/moose_inventory/cli/host_listvars.rb +21 -23
  31. data/lib/moose_inventory/cli/host_rm.rb +9 -9
  32. data/lib/moose_inventory/cli/host_rmgroup.rb +5 -5
  33. data/lib/moose_inventory/cli/host_rmvar.rb +3 -3
  34. data/lib/moose_inventory/config/config.rb +43 -40
  35. data/lib/moose_inventory/db/db.rb +70 -50
  36. data/lib/moose_inventory/db/models.rb +11 -12
  37. data/lib/moose_inventory/version.rb +1 -1
  38. data/moose-inventory.gemspec +35 -20
  39. data/scripts/check.sh +8 -0
  40. data/scripts/ci/check_permissions.sh +32 -0
  41. data/scripts/ci/check_security.sh +50 -0
  42. data/scripts/ci/package_sanity.sh +46 -0
  43. data/scripts/files.rb +1 -4
  44. data/scripts/install_dependencies.sh +17 -0
  45. data/scripts/reports.sh +2 -2
  46. data/spec/lib/moose_inventory/cli/cli_spec.rb +13 -14
  47. data/spec/lib/moose_inventory/cli/group_add_spec.rb +118 -119
  48. data/spec/lib/moose_inventory/cli/group_addchild_spec.rb +49 -51
  49. data/spec/lib/moose_inventory/cli/group_addhost_spec.rb +80 -83
  50. data/spec/lib/moose_inventory/cli/group_addvar_spec.rb +91 -91
  51. data/spec/lib/moose_inventory/cli/group_get_spec.rb +22 -23
  52. data/spec/lib/moose_inventory/cli/group_list_spec.rb +19 -20
  53. data/spec/lib/moose_inventory/cli/group_listvar_spec.rb +35 -36
  54. data/spec/lib/moose_inventory/cli/group_rm_spec.rb +103 -49
  55. data/spec/lib/moose_inventory/cli/group_rmchild_spec.rb +41 -45
  56. data/spec/lib/moose_inventory/cli/group_rmhost_spec.rb +43 -46
  57. data/spec/lib/moose_inventory/cli/group_rmvar_spec.rb +131 -131
  58. data/spec/lib/moose_inventory/cli/group_spec.rb +9 -9
  59. data/spec/lib/moose_inventory/cli/host_add_spec.rb +103 -43
  60. data/spec/lib/moose_inventory/cli/host_addgroup_spec.rb +78 -80
  61. data/spec/lib/moose_inventory/cli/host_addvar_spec.rb +122 -122
  62. data/spec/lib/moose_inventory/cli/host_get_spec.rb +16 -16
  63. data/spec/lib/moose_inventory/cli/host_list_spec.rb +8 -8
  64. data/spec/lib/moose_inventory/cli/host_listvar_spec.rb +50 -52
  65. data/spec/lib/moose_inventory/cli/host_rm_spec.rb +12 -12
  66. data/spec/lib/moose_inventory/cli/host_rmgroup_spec.rb +48 -51
  67. data/spec/lib/moose_inventory/cli/host_rmvar_spec.rb +136 -136
  68. data/spec/lib/moose_inventory/config/config_spec.rb +16 -3
  69. data/spec/lib/moose_inventory/db/db_spec.rb +224 -2
  70. data/spec/lib/moose_inventory/db/models_spec.rb +10 -11
  71. data/spec/shared/shared_config_setup.rb +2 -2
  72. data/spec/spec_helper.rb +7 -8
  73. metadata +99 -136
  74. data/.coveralls.yml +0 -0
  75. data/.rubocop.yml +0 -793
  76. data/Guardfile +0 -38
  77. data/config/dotfiles/coveralls.yml +0 -0
  78. data/config/dotfiles/gitignore +0 -20
  79. data/config/dotfiles/rubocop.yml +0 -793
  80. data/scripts/guard_quality.sh +0 -3
  81. data/scripts/guard_test.sh +0 -2
@@ -9,7 +9,7 @@ RSpec.describe Moose::Inventory::Cli::Host do
9
9
  @mockarg_parts = {
10
10
  config: File.join(spec_root, 'config/config.yml'),
11
11
  format: 'yaml',
12
- env: 'test'
12
+ env: 'test',
13
13
  }
14
14
 
15
15
  @mockargs = []
@@ -38,169 +38,169 @@ RSpec.describe Moose::Inventory::Cli::Host do
38
38
  result = @host.instance_methods(false).include?(:rmvar)
39
39
  expect(result).to eq(true)
40
40
  end
41
-
41
+
42
42
  #-----------------
43
- it '<missing args> ... should abort with an error' do
44
- actual = runner do
45
- @app.start(%w(host rmvar)) # <- no group given
46
- end
47
-
48
- # Check output
49
- desired = { aborted: true}
50
- desired[:STDERR] = "ERROR: Wrong number of arguments, 0 for 2 or more.\n"
51
- expected(actual, desired)
52
- end
53
-
54
- #------------------------
55
- it 'HOST key=value ... should abort if the host does not exist' do
56
- host_name = "not-a-host"
57
- var_name = "foo=bar"
58
- actual = runner do
59
- @app.start(%W(host rmvar #{host_name} #{var_name}))
60
- end
61
-
62
- # Check output
63
- desired = { aborted: true}
64
- desired[:STDOUT] =
65
- "Remove variable(s) '#{var_name}' from host '#{host_name}':\n"\
66
- " - retrieve host '#{host_name}'...\n"
67
- desired[:STDERR] =
68
- "An error occurred during a transaction, any changes have been rolled back.\n"\
69
- "ERROR: The host '#{host_name}' does not exist.\n"
70
- expected(actual, desired)
71
- end
72
-
73
- #------------------------
74
- it 'HOST <malformed> ... should abort with an error' do
75
- # 1. Should add the var to the db
76
- # 2. Should associate the host with the var
77
-
78
- host_name = 'test1'
79
- @db.models[:host].create(name: host_name)
80
-
81
- var = {name: 'foo', value: "bar"}
82
- cases = %W(
83
- =bar
84
- foo=bar=
85
- =foo=bar
86
- foo=bar=extra
87
- )
88
-
89
- cases.each do |args|
90
- actual = runner do
91
- @app.start(%W(host rmvar #{host_name} #{args} ))
92
- end
93
- #@console.out(actual,'p')
94
-
95
- desired = { aborted: true}
96
- desired[:STDOUT] =
97
- "Remove variable(s) '#{args}' from host '#{host_name}':\n"\
98
- " - retrieve host '#{host_name}'...\n"\
99
- " - OK\n"\
100
- " - remove variable '#{args}'...\n"
101
- desired[:STDERR] =
102
- "An error occurred during a transaction, any changes have been rolled back.\n"\
103
- "ERROR: Incorrect format in {#{args}}. Expected 'key' or 'key=value'.\n"
104
-
105
- expected(actual, desired)
43
+ it '<missing args> ... should abort with an error' do
44
+ actual = runner do
45
+ @app.start(%w(host rmvar)) # <- no group given
46
+ end
47
+
48
+ # Check output
49
+ desired = { aborted: true }
50
+ desired[:STDERR] = "ERROR: Wrong number of arguments, 0 for 2 or more.\n"
51
+ expected(actual, desired)
52
+ end
53
+
54
+ #------------------------
55
+ it 'HOST key=value ... should abort if the host does not exist' do
56
+ host_name = 'not-a-host'
57
+ var_name = 'foo=bar'
58
+ actual = runner do
59
+ @app.start(%W(host rmvar #{host_name} #{var_name}))
60
+ end
61
+
62
+ # Check output
63
+ desired = { aborted: true }
64
+ desired[:STDOUT] =
65
+ "Remove variable(s) '#{var_name}' from host '#{host_name}':\n"\
66
+ " - retrieve host '#{host_name}'...\n"
67
+ desired[:STDERR] =
68
+ "An error occurred during a transaction, any changes have been rolled back.\n"\
69
+ "ERROR: The host '#{host_name}' does not exist.\n"
70
+ expected(actual, desired)
71
+ end
72
+
73
+ #------------------------
74
+ it 'HOST <malformed> ... should abort with an error' do
75
+ # 1. Should add the var to the db
76
+ # 2. Should associate the host with the var
77
+
78
+ host_name = 'test1'
79
+ @db.models[:host].create(name: host_name)
80
+
81
+ var = { name: 'foo', value: 'bar' }
82
+ cases = %w(
83
+ =bar
84
+ foo=bar=
85
+ =foo=bar
86
+ foo=bar=extra
87
+ )
88
+
89
+ cases.each do |args|
90
+ actual = runner do
91
+ @app.start(%W(host rmvar #{host_name} #{args}))
106
92
  end
93
+ # @console.out(actual,'p')
94
+
95
+ desired = { aborted: true }
96
+ desired[:STDOUT] =
97
+ "Remove variable(s) '#{args}' from host '#{host_name}':\n"\
98
+ " - retrieve host '#{host_name}'...\n"\
99
+ " - OK\n"\
100
+ " - remove variable '#{args}'...\n"
101
+ desired[:STDERR] =
102
+ "An error occurred during a transaction, any changes have been rolled back.\n"\
103
+ "ERROR: Incorrect format in {#{args}}. Expected 'key' or 'key=value'.\n"
104
+
105
+ expected(actual, desired)
107
106
  end
108
-
107
+ end
108
+
109
109
  #------------------------
110
110
  it 'host rmvar HOST <valid args> ... should remove the host variable' do
111
- # 1. Should add the var to the db
112
- # 2. Should associate the host with the var
113
-
114
- host_name = 'test1'
115
-
116
- var = {name: 'foo', value: "bar"}
117
- cases = %W(
118
- #{var[:name]}
119
- #{var[:name]}=
120
- #{var[:name]}=#{var[:value]}
121
- )
122
- cases.each do |example|
123
- # reset the db
124
- @db.reset
125
-
126
- # Add an initial host and hostvar
127
- @db.models[:host].create(name: host_name)
128
- runner do
129
- @app.start(%W(host addvar #{host_name} #{var[:name]}=#{var[:value]} ))
130
- end
131
-
132
- # Try to remove the hostvar using the case example valid args
133
- actual = runner do
134
- @app.start(%W(host rmvar #{host_name} #{example}))
135
- end
136
- #@console.out(actual,'p')
137
-
138
- # Check the output
139
- desired = { aborted: false}
140
- desired[:STDOUT] =
141
- "Remove variable(s) '#{example}' from host '#{host_name}':\n"\
142
- " - retrieve host '#{host_name}'...\n"\
143
- " - OK\n"\
144
- " - remove variable '#{example}'...\n"\
145
- " - OK\n"\
146
- " - all OK\n"\
147
- "Succeeded.\n"
148
-
149
- #@console.out(desired,'p')
150
- expected(actual, desired)
151
-
152
- # Check the db
153
- host = @db.models[:host].find(name: host_name)
154
- hostvars = host.hostvars_dataset
155
- expect(hostvars.count).to eq(0)
156
-
157
- hostvars = @db.models[:hostvar].all
158
- expect(hostvars.count).to eq(0)
159
- end
111
+ # 1. Should add the var to the db
112
+ # 2. Should associate the host with the var
113
+
114
+ host_name = 'test1'
115
+
116
+ var = { name: 'foo', value: 'bar' }
117
+ cases = %W(
118
+ #{var[:name]}
119
+ #{var[:name]}=
120
+ #{var[:name]}=#{var[:value]}
121
+ )
122
+ cases.each do |example|
123
+ # reset the db
124
+ @db.reset
125
+
126
+ # Add an initial host and hostvar
127
+ @db.models[:host].create(name: host_name)
128
+ runner do
129
+ @app.start(%W(host addvar #{host_name} #{var[:name]}=#{var[:value]}))
130
+ end
131
+
132
+ # Try to remove the hostvar using the case example valid args
133
+ actual = runner do
134
+ @app.start(%W(host rmvar #{host_name} #{example}))
135
+ end
136
+ # @console.out(actual,'p')
137
+
138
+ # Check the output
139
+ desired = { aborted: false }
140
+ desired[:STDOUT] =
141
+ "Remove variable(s) '#{example}' from host '#{host_name}':\n"\
142
+ " - retrieve host '#{host_name}'...\n"\
143
+ " - OK\n"\
144
+ " - remove variable '#{example}'...\n"\
145
+ " - OK\n"\
146
+ " - all OK\n"\
147
+ "Succeeded.\n"
148
+
149
+ # @console.out(desired,'p')
150
+ expected(actual, desired)
151
+
152
+ # Check the db
153
+ host = @db.models[:host].find(name: host_name)
154
+ hostvars = host.hostvars_dataset
155
+ expect(hostvars.count).to eq(0)
156
+
157
+ hostvars = @db.models[:hostvar].all
158
+ expect(hostvars.count).to eq(0)
159
+ end
160
160
  end
161
-
161
+
162
162
  #------------------------
163
163
  it 'HOST key1=value1 key2=value2 ... should remove multiple key/value pairs' do
164
164
  host_name = 'test1'
165
- varsarray = [
166
- {name: 'var1', value: "val1"},
167
- {name: 'var2', value: "val2"}
165
+ varsarray = [
166
+ { name: 'var1', value: 'val1' },
167
+ { name: 'var2', value: 'val2' },
168
168
  ]
169
-
169
+
170
170
  vars = []
171
171
  varsarray.each do |var|
172
172
  vars << "#{var[:name]}=#{var[:value]}"
173
173
  end
174
-
174
+
175
175
  @db.models[:host].create(name: host_name)
176
176
  actual = runner do
177
- @app.start(%W(host addvar #{host_name}) + vars )
177
+ @app.start(%W(host addvar #{host_name}) + vars)
178
178
  end
179
-
179
+
180
180
  actual = runner do
181
- @app.start(%W(host rmvar #{host_name}) + vars )
181
+ @app.start(%W(host rmvar #{host_name}) + vars)
182
182
  end
183
- #@console.out(actual,'p')
184
-
185
- desired = { aborted: false}
186
- desired[:STDOUT] =
183
+ # @console.out(actual,'p')
184
+
185
+ desired = { aborted: false }
186
+ desired[:STDOUT] =
187
187
  "Remove variable(s) '#{vars.join(',')}' from host '#{host_name}':\n"\
188
188
  " - retrieve host '#{host_name}'...\n"\
189
189
  " - OK\n"
190
190
  vars.each do |var|
191
- desired[:STDOUT] = desired[:STDOUT] +
192
- " - remove variable '#{var}'...\n"\
193
- " - OK\n"
191
+ desired[:STDOUT] = desired[:STDOUT] +
192
+ " - remove variable '#{var}'...\n"\
193
+ " - OK\n"
194
194
  end
195
- desired[:STDOUT] = desired[:STDOUT] +
196
- " - all OK\n"\
197
- "Succeeded.\n"
195
+ desired[:STDOUT] = desired[:STDOUT] +
196
+ " - all OK\n"\
197
+ "Succeeded.\n"
198
198
  expected(actual, desired)
199
-
199
+
200
200
  # We should have the correct hostvar associations
201
201
  host = @db.models[:host].find(name: host_name)
202
202
  hostvars = host.hostvars_dataset
203
203
  expect(hostvars.count).to eq(0)
204
- end
204
+ end
205
205
  end
206
206
  end
@@ -6,7 +6,7 @@ RSpec.describe 'Moose::Inventory::Config' do
6
6
  @mockarg_parts = {
7
7
  config: File.join(spec_root, 'config/config.yml'),
8
8
  format: 'yaml',
9
- env: 'test'
9
+ env: 'test',
10
10
  }
11
11
 
12
12
  @mockargs = []
@@ -39,7 +39,7 @@ RSpec.describe 'Moose::Inventory::Config' do
39
39
  end
40
40
 
41
41
  it 'should default "--format" to json' do
42
- @config.init([])
42
+ @config.init(['--config', @mockarg_parts[:config]])
43
43
  expect(@config._confopts[:format]).to eq('json')
44
44
  end
45
45
 
@@ -49,7 +49,7 @@ RSpec.describe 'Moose::Inventory::Config' do
49
49
  end
50
50
 
51
51
  it 'should default "--env" to ""' do
52
- @config.init([])
52
+ @config.init(['--config', @mockarg_parts[:config]])
53
53
  expect(@config._confopts[:env]).to eq('')
54
54
  end
55
55
 
@@ -76,5 +76,18 @@ RSpec.describe 'Moose::Inventory::Config' do
76
76
  @config.init(@mockargs)
77
77
  expect(@config._settings[:config][:db]).not_to be_nil
78
78
  end
79
+
80
+ it 'uses safe YAML loading for configuration files' do
81
+ expect(YAML).not_to receive(:load_file)
82
+ expect(YAML).to receive(:safe_load_file).with(
83
+ @mockarg_parts[:config],
84
+ aliases: false,
85
+ permitted_classes: [],
86
+ permitted_symbols: []
87
+ ).and_call_original
88
+
89
+ @config.init(@mockargs)
90
+ expect(@config._settings[:config][:db]).not_to be_nil
91
+ end
79
92
  end
80
93
  end
@@ -1,6 +1,26 @@
1
1
  require 'spec_helper'
2
+ require 'fileutils'
3
+ require 'tmpdir'
2
4
 
3
5
  RSpec.describe 'Moose::Inventory::DB' do
6
+ def with_db_config(db_config)
7
+ saved_db = @db.instance_variable_get(:@db)
8
+ saved_settings = @config._settings.dup
9
+
10
+ begin
11
+ @db.instance_variable_set(:@db, nil)
12
+ @config._settings.clear
13
+ @config._settings[:config] = { db: db_config }
14
+ yield
15
+ ensure
16
+ current_db = @db.instance_variable_get(:@db)
17
+ current_db.disconnect if current_db.respond_to?(:disconnect)
18
+ @db.instance_variable_set(:@db, saved_db)
19
+ @config._settings.clear
20
+ @config._settings.merge!(saved_settings)
21
+ end
22
+ end
23
+
4
24
  #=============================
5
25
  # Initialization
6
26
  #
@@ -10,7 +30,7 @@ RSpec.describe 'Moose::Inventory::DB' do
10
30
  @mockarg_parts = {
11
31
  config: File.join(spec_root, 'config/config.yml'),
12
32
  format: 'yaml',
13
- env: 'test'
33
+ env: 'test',
14
34
  }
15
35
 
16
36
  @mockargs = []
@@ -22,7 +42,7 @@ RSpec.describe 'Moose::Inventory::DB' do
22
42
  @config = Moose::Inventory::Config
23
43
  @config.init(@mockargs)
24
44
 
25
- @db = Moose::Inventory::DB
45
+ @db = Moose::Inventory::DB
26
46
  end
27
47
 
28
48
  #=============================
@@ -47,6 +67,208 @@ RSpec.describe 'Moose::Inventory::DB' do
47
67
 
48
68
  expect(failed).to eq(false)
49
69
  end
70
+
71
+ it 'raises a Moose DB exception for unsupported adapters' do
72
+ saved_db = @db.instance_variable_get(:@db)
73
+ saved_models = @db.instance_variable_get(:@models)
74
+ saved_exceptions = @db.instance_variable_get(:@exceptions)
75
+ saved_settings = @config._settings.dup
76
+
77
+ begin
78
+ @db.instance_variable_set(:@db, nil)
79
+ @db.instance_variable_set(:@models, nil)
80
+ @db.instance_variable_set(:@exceptions, nil)
81
+ @config._settings.clear
82
+ @config._settings[:config] = { db: { adapter: 'unsupported' } }
83
+
84
+ expect { @db.init }.to raise_error(
85
+ Moose::Inventory::DB::MooseDBException,
86
+ /database adapter unsupported is not yet supported/
87
+ )
88
+ expect(@db.exceptions[:moose]).to eq(Moose::Inventory::DB::MooseDBException)
89
+ ensure
90
+ @db.instance_variable_set(:@db, saved_db)
91
+ @db.instance_variable_set(:@models, saved_models)
92
+ @db.instance_variable_set(:@exceptions, saved_exceptions)
93
+ @config._settings.clear
94
+ @config._settings.merge!(saved_settings)
95
+ end
96
+ end
97
+ end
98
+
99
+ describe '.init_exceptions()' do
100
+ it 'is responsive' do
101
+ expect(@db.respond_to?(:init_exceptions)).to eq(true)
102
+ end
103
+ end
104
+
105
+ describe '.connect()' do
106
+ it 'dispatches the documented sqlite3 adapter to the sqlite initializer' do
107
+ with_db_config(adapter: 'sqlite3') do
108
+ expect(@db).to receive(:init_sqlite3) do
109
+ @db.instance_variable_set(:@db, :sqlite_connection)
110
+ end
111
+ @db.connect
112
+ expect(@db.db).to eq(:sqlite_connection)
113
+ end
114
+ end
115
+
116
+ it 'dispatches the documented mysql adapter to the mysql initializer' do
117
+ with_db_config(adapter: 'mysql') do
118
+ expect(@db).to receive(:init_mysql) do
119
+ @db.instance_variable_set(:@db, :mysql_connection)
120
+ end
121
+ @db.connect
122
+ expect(@db.db).to eq(:mysql_connection)
123
+ end
124
+ end
125
+
126
+ it 'dispatches the documented postgresql adapter to the postgresql initializer' do
127
+ with_db_config(adapter: 'postgresql') do
128
+ expect(@db).to receive(:init_postgresql) do
129
+ @db.instance_variable_set(:@db, :postgresql_connection)
130
+ end
131
+ @db.connect
132
+ expect(@db.db).to eq(:postgresql_connection)
133
+ end
134
+ end
135
+ end
136
+
137
+ describe '.init_sqlite3()' do
138
+ it 'raises a Moose DB exception when the configured database file is missing' do
139
+ with_db_config(adapter: 'sqlite3') do
140
+ expect { @db.init_sqlite3 }.to raise_error(
141
+ Moose::Inventory::DB::MooseDBException,
142
+ /Expected key file missing in sqlite3 configuration/
143
+ )
144
+ end
145
+ end
146
+
147
+ it 'creates nested parent directories for configured database files' do
148
+ saved_db = @db.instance_variable_get(:@db)
149
+ saved_settings = @config._settings.dup
150
+ tmpdir = Dir.mktmpdir('moose-inventory-sqlite')
151
+ nested_dbfile = File.join(tmpdir, 'one', 'two', 'inventory.db')
152
+
153
+ begin
154
+ @db.instance_variable_set(:@db, nil)
155
+ @config._settings.clear
156
+ @config._settings[:config] = {
157
+ db: {
158
+ adapter: 'sqlite3',
159
+ file: nested_dbfile,
160
+ },
161
+ }
162
+
163
+ @db.init_sqlite3
164
+
165
+ expect(File.directory?(File.dirname(nested_dbfile))).to eq(true)
166
+ expect(File.file?(nested_dbfile)).to eq(true)
167
+ ensure
168
+ current_db = @db.instance_variable_get(:@db)
169
+ current_db.disconnect if current_db.respond_to?(:disconnect)
170
+ @db.instance_variable_set(:@db, saved_db)
171
+ @config._settings.clear
172
+ @config._settings.merge!(saved_settings)
173
+ FileUtils.remove_entry(tmpdir) if tmpdir && Dir.exist?(tmpdir)
174
+ end
175
+ end
176
+ end
177
+
178
+ describe '.init_mysql()' do
179
+ it 'raises a Moose DB exception when a required connection key is missing' do
180
+ with_db_config(
181
+ adapter: 'mysql',
182
+ database: 'moose_inventory_test',
183
+ user: 'moose',
184
+ password: 'secret'
185
+ ) do
186
+ expect { @db.init_mysql }.to raise_error(
187
+ Moose::Inventory::DB::MooseDBException,
188
+ /Expected key host missing in mysql configuration/
189
+ )
190
+ end
191
+ end
192
+
193
+ it 'uses the mysql2 Sequel adapter with configured connection settings' do
194
+ saved_db = @db.instance_variable_get(:@db)
195
+ saved_settings = @config._settings.dup
196
+ mysql_config = {
197
+ adapter: 'mysql',
198
+ host: 'localhost',
199
+ database: 'moose_inventory_test',
200
+ user: 'moose',
201
+ password: 'secret',
202
+ }
203
+
204
+ begin
205
+ @db.instance_variable_set(:@db, nil)
206
+ @config._settings.clear
207
+ @config._settings[:config] = { db: mysql_config }
208
+
209
+ expect(Sequel).to receive(:mysql2).with(
210
+ user: 'moose',
211
+ password: 'secret',
212
+ host: 'localhost',
213
+ database: 'moose_inventory_test'
214
+ ).and_return(:mysql2_connection)
215
+
216
+ @db.init_mysql
217
+ expect(@db.db).to eq(:mysql2_connection)
218
+ ensure
219
+ @db.instance_variable_set(:@db, saved_db)
220
+ @config._settings.clear
221
+ @config._settings.merge!(saved_settings)
222
+ end
223
+ end
224
+ end
225
+
226
+ describe '.init_postgresql()' do
227
+ it 'raises a Moose DB exception when a required connection key is missing' do
228
+ with_db_config(
229
+ adapter: 'postgresql',
230
+ host: 'localhost',
231
+ database: 'moose_inventory_test',
232
+ password: 'secret'
233
+ ) do
234
+ expect { @db.init_postgresql }.to raise_error(
235
+ Moose::Inventory::DB::MooseDBException,
236
+ /Expected key user missing in postgresql configuration/
237
+ )
238
+ end
239
+ end
240
+
241
+ it 'uses the postgres Sequel adapter with configured connection settings' do
242
+ saved_db = @db.instance_variable_get(:@db)
243
+ saved_settings = @config._settings.dup
244
+ postgresql_config = {
245
+ adapter: 'postgresql',
246
+ host: 'localhost',
247
+ database: 'moose_inventory_test',
248
+ user: 'moose',
249
+ password: 'secret',
250
+ }
251
+
252
+ begin
253
+ @db.instance_variable_set(:@db, nil)
254
+ @config._settings.clear
255
+ @config._settings[:config] = { db: postgresql_config }
256
+
257
+ expect(Sequel).to receive(:postgres).with(
258
+ user: 'moose',
259
+ password: 'secret',
260
+ host: 'localhost',
261
+ database: 'moose_inventory_test'
262
+ ).and_return(:postgresql_connection)
263
+
264
+ @db.init_postgresql
265
+ expect(@db.db).to eq(:postgresql_connection)
266
+ ensure
267
+ @db.instance_variable_set(:@db, saved_db)
268
+ @config._settings.clear
269
+ @config._settings.merge!(saved_settings)
270
+ end
271
+ end
50
272
  end
51
273
 
52
274
  describe '.db' do
@@ -10,7 +10,7 @@ RSpec.describe 'models' do
10
10
  @mockarg_parts = {
11
11
  config: File.join(spec_root, 'config/config.yml'),
12
12
  format: 'yaml',
13
- env: 'test'
13
+ env: 'test',
14
14
  }
15
15
 
16
16
  @mockargs = []
@@ -128,45 +128,44 @@ RSpec.describe 'models' do
128
128
  end
129
129
 
130
130
  it 'should have a many-to-many self-referential relationship (i.e. GROUPS of GROUPS)' do
131
-
132
131
  parent1 = @db.models[:group].create(name: 'parent1')
133
132
  parent2 = @db.models[:group].create(name: 'parent2')
134
133
  child1 = @db.models[:group].create(name: 'child1')
135
134
  child2 = @db.models[:group].create(name: 'child2')
136
135
 
137
- parent1.add_child(child1)
136
+ parent1.add_child(child1)
138
137
  parent1.add_child(child2)
139
138
 
140
- parent2.add_child(child1)
139
+ parent2.add_child(child1)
141
140
  parent2.add_child(child2)
142
-
141
+
143
142
  group = @db.models[:group].find(name: 'parent1')
144
143
  children = group.children_dataset
145
144
 
146
145
  expect(children).not_to be_nil
147
146
  expect(children.count).to eq(2)
148
-
147
+
149
148
  group = @db.models[:group].find(name: 'parent2')
150
149
  children = group.children_dataset
151
150
 
152
151
  expect(children).not_to be_nil
153
152
  expect(children.count).to eq(2)
154
153
  end
155
-
154
+
156
155
  it 'should have relationships with Hostvars' do
157
156
  groupname = 'group-test'
158
157
  groupvarname = 'groupvar-test'
159
158
  groupvarval = '1'
160
-
159
+
161
160
  group = @db.models[:group].create(name: groupname)
162
161
  groupvar = @db.models[:groupvar].create(name: groupvarname,
163
162
  value: groupvarval)
164
-
163
+
165
164
  group.add_groupvar(groupvar)
166
-
165
+
167
166
  group = @db.models[:group].find(name: groupname)
168
167
  groupvars = group.groupvars_dataset
169
-
168
+
170
169
  expect(groupvars).not_to be_nil
171
170
  expect(groupvars.count).to eq(1)
172
171
  expect(groupvars.first[:name]).to eq(groupvarname)