moose-inventory 0.1.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.
Files changed (74) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +0 -0
  3. data/.gitignore +17 -0
  4. data/.rubocop.yml +793 -0
  5. data/Gemfile +3 -0
  6. data/Guardfile +38 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +31 -0
  9. data/README.md.orig +35 -0
  10. data/Rakefile +1 -0
  11. data/bin/moose_inventory +10 -0
  12. data/config/dotfiles/coveralls.yml +0 -0
  13. data/config/dotfiles/gitignore +17 -0
  14. data/config/dotfiles/rubocop.yml +793 -0
  15. data/lib/moose/inventory/cli/application.rb +30 -0
  16. data/lib/moose/inventory/cli/formatter.rb +92 -0
  17. data/lib/moose/inventory/cli/group.rb +23 -0
  18. data/lib/moose/inventory/cli/group_add.rb +98 -0
  19. data/lib/moose/inventory/cli/group_addchild.rb +21 -0
  20. data/lib/moose/inventory/cli/group_addhost.rb +97 -0
  21. data/lib/moose/inventory/cli/group_addvar.rb +72 -0
  22. data/lib/moose/inventory/cli/group_get.rb +52 -0
  23. data/lib/moose/inventory/cli/group_list.rb +41 -0
  24. data/lib/moose/inventory/cli/group_rm.rb +77 -0
  25. data/lib/moose/inventory/cli/group_rmchild.rb +20 -0
  26. data/lib/moose/inventory/cli/group_rmhost.rb +89 -0
  27. data/lib/moose/inventory/cli/group_rmvar.rb +65 -0
  28. data/lib/moose/inventory/cli/host.rb +24 -0
  29. data/lib/moose/inventory/cli/host_add.rb +93 -0
  30. data/lib/moose/inventory/cli/host_addgroup.rb +88 -0
  31. data/lib/moose/inventory/cli/host_addvar.rb +76 -0
  32. data/lib/moose/inventory/cli/host_get.rb +59 -0
  33. data/lib/moose/inventory/cli/host_list.rb +40 -0
  34. data/lib/moose/inventory/cli/host_rm.rb +62 -0
  35. data/lib/moose/inventory/cli/host_rmgroup.rb +80 -0
  36. data/lib/moose/inventory/cli/host_rmvar.rb +69 -0
  37. data/lib/moose/inventory/config/config.rb +169 -0
  38. data/lib/moose/inventory/db/db.rb +249 -0
  39. data/lib/moose/inventory/db/exceptions.rb +14 -0
  40. data/lib/moose/inventory/db/models.rb +32 -0
  41. data/lib/moose/inventory/moose_inventory_cli.rb +25 -0
  42. data/lib/moose/inventory/version.rb +7 -0
  43. data/moose-inventory.gemspec +45 -0
  44. data/scripts/guard_quality.sh +3 -0
  45. data/scripts/guard_test.sh +2 -0
  46. data/scripts/reports.sh +4 -0
  47. data/spec/config/config.yml +12 -0
  48. data/spec/lib/moose/inventory/cli/application_spec.rb +15 -0
  49. data/spec/lib/moose/inventory/cli/cli_spec.rb +26 -0
  50. data/spec/lib/moose/inventory/cli/formatter_spec.rb +63 -0
  51. data/spec/lib/moose/inventory/cli/group_add_spec.rb +398 -0
  52. data/spec/lib/moose/inventory/cli/group_addhost_spec.rb +251 -0
  53. data/spec/lib/moose/inventory/cli/group_addvar_spec.rb +235 -0
  54. data/spec/lib/moose/inventory/cli/group_get_spec.rb +107 -0
  55. data/spec/lib/moose/inventory/cli/group_list_spec.rb +79 -0
  56. data/spec/lib/moose/inventory/cli/group_rm_spec.rb +191 -0
  57. data/spec/lib/moose/inventory/cli/group_rmhost_spec.rb +215 -0
  58. data/spec/lib/moose/inventory/cli/group_rmvar_spec.rb +202 -0
  59. data/spec/lib/moose/inventory/cli/group_spec.rb +15 -0
  60. data/spec/lib/moose/inventory/cli/host_add_spec.rb +330 -0
  61. data/spec/lib/moose/inventory/cli/host_addgroup_spec.rb +248 -0
  62. data/spec/lib/moose/inventory/cli/host_addvar_spec.rb +233 -0
  63. data/spec/lib/moose/inventory/cli/host_get_spec.rb +106 -0
  64. data/spec/lib/moose/inventory/cli/host_list_spec.rb +83 -0
  65. data/spec/lib/moose/inventory/cli/host_rm_spec.rb +132 -0
  66. data/spec/lib/moose/inventory/cli/host_rmgroup_spec.rb +245 -0
  67. data/spec/lib/moose/inventory/cli/host_rmvar_spec.rb +206 -0
  68. data/spec/lib/moose/inventory/cli/host_spec.rb +12 -0
  69. data/spec/lib/moose/inventory/config/config_spec.rb +80 -0
  70. data/spec/lib/moose/inventory/db/db_spec.rb +184 -0
  71. data/spec/lib/moose/inventory/db/models_spec.rb +150 -0
  72. data/spec/shared/shared_config_setup.rb +21 -0
  73. data/spec/spec_helper.rb +110 -0
  74. metadata +386 -0
@@ -0,0 +1,63 @@
1
+ require 'spec_helper'
2
+
3
+ # TODO: the usual respond_to? method doesn't seem to work on Thor objects.
4
+ # Why not? For now, we'll check against instance_methods.
5
+
6
+ RSpec.describe Moose::Inventory::Cli::Formatter do
7
+ before(:all) do
8
+ @formatter = Moose::Inventory::Cli::Formatter
9
+ end
10
+
11
+ # ============================
12
+ describe 'out' do
13
+ # --------------------
14
+ it 'Formatter.out() method should be responsive' do
15
+ expect(@formatter.respond_to?(:out)).to eq(true)
16
+ end
17
+
18
+ # --------------------
19
+ it 'out(<object>, \'yaml\') ... should output as yaml' do
20
+ test = { name: 'turkey', data: [1, 2, 3] }
21
+
22
+ actual = runner { @formatter.out(test, 'yaml') }
23
+
24
+ desired = { aborted: false, STDOUT: '', STDERR: '' }
25
+ desired[:STDOUT] = test.to_yaml
26
+
27
+ expected(actual, desired)
28
+ end
29
+
30
+ it 'out(<object>, \'json\') ... should output as ugly json' do
31
+ test = { name: 'turkey', data: [1, 2, 3] }
32
+
33
+ actual = runner { @formatter.out(test, 'json') }
34
+
35
+ desired = { aborted: false, STDOUT: '', STDERR: '' }
36
+ desired[:STDOUT] = test.to_json + "\n"
37
+
38
+ expected(actual, desired)
39
+ end
40
+
41
+ it 'out(<object>, \'prettyjson\') ... should output as pretty json' do
42
+ test = { name: 'turkey', data: [1, 2, 3] }
43
+
44
+ actual = runner { @formatter.out(test, 'prettyjson') }
45
+
46
+ desired = { aborted: false, STDOUT: '', STDERR: '' }
47
+ desired[:STDOUT] = JSON.pretty_generate(test) + "\n"
48
+
49
+ expected(actual, desired)
50
+ end
51
+
52
+ it 'out(<object>, \'unknown-type\') ... should abort with an error' do
53
+ test = { name: 'turkey', data: [1, 2, 3] }
54
+
55
+ actual = runner { @formatter.out(test, 'unknown-type') }
56
+
57
+ desired = { aborted: true, STDOUT: '', STDERR: '' }
58
+ desired[:STDERR] = "Output format 'unknown-type' is not yet supported.\n"
59
+
60
+ expected(actual, desired)
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,398 @@
1
+ require 'spec_helper'
2
+
3
+ # TODO: the usual respond_to? method doesn't seem to work on Thor objects.
4
+ # Why not? For now, we'll check against instance_methods.
5
+
6
+ RSpec.describe Moose::Inventory::Cli::Group do
7
+ before(:all) do
8
+ # Set up the configuration object
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
+ @mockargs << '--trace' # extra info for debugging
21
+
22
+ @console = Moose::Inventory::Cli::Formatter
23
+
24
+ @config = Moose::Inventory::Config
25
+ @config.init(@mockargs)
26
+
27
+ @db = Moose::Inventory::DB
28
+ @db.init if @db.db.nil?
29
+
30
+ @host = Moose::Inventory::Cli::Host
31
+ @group = Moose::Inventory::Cli::Group
32
+ @app = Moose::Inventory::Cli::Application
33
+ end
34
+
35
+ before(:each) do
36
+ @db.reset
37
+ end
38
+
39
+ # ============================
40
+ describe 'add' do
41
+ # --------------------
42
+ it 'Group.add() method should be responsive' do
43
+ result = @group.instance_methods(false).include?(:add)
44
+ expect(result).to eq(true)
45
+ end
46
+
47
+ # --------------------
48
+ it '<no arguments> ... should bail with an error' do
49
+ actual = runner { @app.start(%w(group add)) }
50
+
51
+ desired = {aborted: true}
52
+ desired[:STDERR] = "ERROR: Wrong number of arguments, 0 for 1 or more.\n"
53
+ expected(actual, desired)
54
+ end
55
+
56
+ # --------------------
57
+ it 'ungrouped ... should abort with an error' do
58
+ actual = runner { @app.start(%W(group add ungrouped)) }
59
+
60
+ # Check output
61
+ desired = {aborted: true}
62
+ desired[:STDERR] =
63
+ "ERROR: Cannot manually manipulate the automatic group 'ungrouped'\n"
64
+ expected(actual, desired)
65
+ end
66
+
67
+ # --------------------
68
+ it 'GROUP ... should add a group to the db' do
69
+ name = 'test'
70
+ actual = runner { @app.start(%W(group add #{name})) }
71
+
72
+ #@console.out(actual)
73
+
74
+ # Check output
75
+ desired = {}
76
+ desired[:STDOUT] =
77
+ "Add group '#{name}':\n"\
78
+ " - create group...\n"\
79
+ " - OK\n"\
80
+ " - all OK\n"\
81
+ "Succeeded\n"
82
+
83
+ expected(actual, desired)
84
+
85
+ # Check db
86
+ group = @db.models[:group].find(name: name)
87
+ expect(group[:name]).to eq(name)
88
+ end
89
+
90
+ # --------------------
91
+ it 'GROUP ... should skip GROUP creation if it already exists' do
92
+ name = 'test-group'
93
+ @db.models[:group].create(name: name)
94
+
95
+ actual = runner { @app.start(%W(group add #{name})) }
96
+
97
+ #@console.out(actual)
98
+
99
+ # Check output
100
+ desired = {}
101
+ desired[:STDOUT] =
102
+ "Add group '#{name}':\n"\
103
+ " - create group...\n"\
104
+ " - already exists, skipping.\n"\
105
+ " - OK\n"\
106
+ " - all OK\n"\
107
+ "Succeeded, with warnings.\n"
108
+ desired[:STDERR] =
109
+ "WARNING: Group '#{name}' already exists, skipping creation.\n"
110
+
111
+ expected(actual, desired)
112
+
113
+
114
+ expected(actual, desired)
115
+ end
116
+
117
+ # --------------------
118
+ it 'GROUP1 GROUP2 GROUP3 ... should add multiple groups' do
119
+ names = %w(test1 test2 test3)
120
+
121
+ actual = runner { @app.start(%w(group add) + names) }
122
+
123
+ #@console.out(actual)
124
+
125
+ # Check output
126
+ desired = {STDOUT: ''}
127
+ names.each do |name|
128
+ desired[:STDOUT] = desired[:STDOUT] +
129
+ "Add group '#{name}':\n"\
130
+ " - create group...\n"\
131
+ " - OK\n"\
132
+ " - all OK\n"\
133
+ end
134
+ desired[:STDOUT] = desired[:STDOUT] + "Succeeded\n"
135
+
136
+ expected(actual, desired)
137
+
138
+ # Check db
139
+ names.each do |name|
140
+ group = @db.models[:group].find(name: name)
141
+ expect(group[:name]).to eq(name)
142
+ end
143
+ end
144
+
145
+ # --------------------
146
+ it 'GROUP1 --hosts HOST1 ... should add the '\
147
+ 'group and associate it with existing hosts' do
148
+
149
+ host_name = 'test-host'
150
+ @db.models[:host].create(name: host_name)
151
+
152
+ group_name = 'test-group'
153
+ actual = runner do
154
+ @app.start(%W(group add #{group_name} --hosts #{host_name}))
155
+ end
156
+
157
+ #@console.out(actual)
158
+
159
+ # Check output
160
+ desired = {}
161
+ desired[:STDOUT] =
162
+ "Add group '#{group_name}':\n"\
163
+ " - create group...\n"\
164
+ " - OK\n"\
165
+ " - add association {group:#{group_name} <-> host:#{host_name}}...\n"\
166
+ " - OK\n"\
167
+ " - all OK\n"\
168
+ "Succeeded\n"
169
+
170
+ expected(actual, desired)
171
+
172
+ # Check db
173
+ group = @db.models[:group].find(name: group_name)
174
+ hosts = group.hosts_dataset
175
+ expect(hosts).not_to be_nil
176
+ expect(hosts.count).to eq(1)
177
+ expect(hosts[name: host_name]).not_to be_nil
178
+ end
179
+
180
+ # --------------------
181
+ it 'GROUP1 --hosts HOST ... should create HOST if necessary, and warn' do
182
+ host_name = 'test-host'
183
+
184
+ # DON'T CREATE THE HOST! That's the point!
185
+
186
+ group_name = 'test-group'
187
+ actual = runner do
188
+ @app.start(%W(group add #{group_name} --hosts #{host_name}))
189
+ end
190
+
191
+ #@console.out(actual)
192
+
193
+ # Check output
194
+ desired = {}
195
+ desired[:STDOUT] =
196
+ "Add group '#{group_name}':\n"\
197
+ " - create group...\n"\
198
+ " - OK\n"\
199
+ " - add association {group:#{group_name} <-> host:#{host_name}}...\n"\
200
+ " - host doesn't exist, creating now...\n"\
201
+ " - OK\n"\
202
+ " - OK\n"\
203
+ " - all OK\n"\
204
+ "Succeeded, with warnings.\n"
205
+ desired[:STDERR] =
206
+ "WARNING: Host '#{host_name}' doesn't exist, but will be created.\n"
207
+
208
+ expected(actual, desired)
209
+
210
+ # Check db
211
+ group = @db.models[:group].find(name: group_name)
212
+ hosts = group.hosts_dataset
213
+ expect(hosts).not_to be_nil
214
+ expect(hosts.count).to eq(1)
215
+ expect(hosts[name: host_name]).not_to be_nil
216
+ end
217
+
218
+ # --------------------
219
+ it 'GROUP1 --hosts HOST ... should skip if association already exists, and warn' do
220
+ host_name = 'test-host'
221
+ group_name = 'test-group'
222
+
223
+ # Create group and association
224
+ runner { @app.start(%W(group add #{group_name} --hosts #{host_name})) }
225
+
226
+ # Do it again, to prove that we skip
227
+ actual = runner do
228
+ @app.start(%W(group add #{group_name} --hosts #{host_name}))
229
+ end
230
+
231
+ #@console.out(actual, 'y')
232
+
233
+ # Check output
234
+ desired = {}
235
+ desired[:STDOUT] =
236
+ "Add group '#{group_name}':\n"\
237
+ " - create group...\n"\
238
+ " - already exists, skipping.\n"\
239
+ " - OK\n"\
240
+ " - add association {group:#{group_name} <-> host:#{host_name}}...\n"\
241
+ " - already exists, skipping.\n"\
242
+ " - OK\n"\
243
+ " - all OK\n"\
244
+ "Succeeded, with warnings.\n"
245
+ desired[:STDERR] =
246
+ "WARNING: Group '#{group_name}' already exists, skipping creation.\n"\
247
+ "WARNING: Association {group:#{group_name} <-> host:#{host_name}} already exists, skipping creation.\n"
248
+
249
+ expected(actual, desired)
250
+
251
+ # Check db
252
+ group = @db.models[:group].find(name: group_name)
253
+ hosts = group.hosts_dataset
254
+ expect(hosts).not_to be_nil
255
+ expect(hosts.count).to eq(1)
256
+ expect(hosts[name: host_name]).not_to be_nil
257
+ end
258
+
259
+ # --------------------
260
+ it 'GROUP --hosts HOST1,HOST2 ... should add the group and '\
261
+ 'associate it with multiple hosts' do
262
+
263
+ # The group should be added
264
+ # Each host should be associated with the group
265
+ # Each host should be removed from the automatic 'ungrouped' group
266
+
267
+ group_name = 'test-group'
268
+ host_names = %w(host1 host2 host3)
269
+
270
+ # Add just the first host. This ensure that we cover paths for both
271
+ # and existing host (with an 'ungrouped' association) and for none
272
+ # existing groups.
273
+ tmp = runner { @app.start(%W(host add #{host_names[0]})) }
274
+
275
+ #@console.out(tmp, 'y')
276
+
277
+ # Now run the actual group addition
278
+ actual = runner do
279
+ @app.start(%W(group add #{group_name} --hosts #{host_names.join(',')}))
280
+ end
281
+
282
+ #@console.out(actual,'y')
283
+
284
+ # Check output
285
+ desired = { aborted: false, STDERR: '', STDOUT: '' }
286
+ desired[:STDOUT] =
287
+ "Add group '#{group_name}':\n"\
288
+ " - create group...\n"\
289
+ " - OK\n"\
290
+ " - add association {group:#{group_name} <-> host:#{host_names[0]}}...\n"\
291
+ " - OK\n"\
292
+ " - remove automatic association {group:ungrouped <-> host:#{host_names[0]}}...\n"\
293
+ " - OK\n"
294
+
295
+ host_names.slice(1, host_names.length - 1 ).each do |host_name|
296
+ desired[:STDOUT] = desired[:STDOUT] +
297
+ " - add association {group:#{group_name} <-> host:#{host_name}}...\n"\
298
+ " - host doesn't exist, creating now...\n"\
299
+ " - OK\n"\
300
+ " - OK\n"
301
+ desired[:STDERR] = desired[:STDERR] +
302
+ "WARNING: Host '#{host_name}' doesn't exist, but will be created.\n"
303
+ end
304
+ desired[:STDOUT] = desired[:STDOUT] +
305
+ " - all OK\n"\
306
+ "Succeeded, with warnings.\n"
307
+
308
+ expected(actual, desired)
309
+
310
+ # Check db
311
+ group = @db.models[:group].find(name: group_name)
312
+ hosts = group.hosts_dataset
313
+ expect(hosts.count).to eq(host_names.count)
314
+ hosts.each do |host|
315
+ groups_ds = host.groups_dataset
316
+ expect(groups_ds.count).to eq(1)
317
+ expect(groups_ds[name: 'ungrouped']).to be_nil # i.e. not 'ungrouped'
318
+ end
319
+ end
320
+
321
+ # --------------------
322
+ it 'HOST --groups GROUP1,ungrouped ... should bail '\
323
+ 'with an error' do
324
+ name = 'testhost'
325
+ group_names = %w(group1 ungrouped)
326
+
327
+ actual = runner do
328
+ @app.start(%W(host add #{name} --groups #{group_names.join(',')}))
329
+ end
330
+
331
+ # Check output
332
+ desired = { aborted: true, STDERR: '', STDOUT: '' }
333
+ desired[:STDERR] =
334
+ "ERROR: Cannot manually manipulate the automatic group 'ungrouped'.\n"
335
+
336
+ expected(actual, desired)
337
+ end
338
+
339
+ # --------------------
340
+ it 'HOST1 HOST2 --groups GROUP1,GROUP2 ... should add multiple '\
341
+ 'groups, associating each with multiple hosts' do
342
+ #
343
+ host_names = %w(host1 host2 host3)
344
+ # Note, relies on auto-generation of hosts
345
+
346
+ group_names = %w(group1 group2 group3)
347
+ actual = runner do
348
+ @app.start(%w(group add) + group_names + %W(--hosts #{host_names.join(',')}))
349
+ end
350
+
351
+ #@console.out(actual,'y')
352
+
353
+ # Check output
354
+ desired = { aborted: false, STDERR: '', STDOUT: '' }
355
+ first_pass = true
356
+ group_names.each do |group|
357
+ desired[:STDOUT] = desired[:STDOUT] +
358
+ "Add group '#{group}':\n"\
359
+ " - create group...\n"\
360
+ " - OK\n"
361
+
362
+ host_names.each do |host|
363
+ desired[:STDOUT] = desired[:STDOUT] +
364
+ " - add association {group:#{group} <-> host:#{host}}...\n"
365
+ if first_pass
366
+ desired[:STDOUT] = desired[:STDOUT] +
367
+ " - host doesn't exist, creating now...\n"\
368
+ " - OK\n"
369
+ end
370
+ desired[:STDOUT] = desired[:STDOUT] +
371
+ " - OK\n"
372
+ end
373
+ desired[:STDOUT] = desired[:STDOUT] +
374
+ " - all OK\n"
375
+ first_pass = false
376
+ end
377
+
378
+ desired[:STDOUT] = desired[:STDOUT] + "Succeeded, with warnings.\n"
379
+ host_names.each do |host|
380
+ desired[:STDERR] = desired[:STDERR] +
381
+ "WARNING: Host '#{host}' doesn't exist, but will be created.\n"
382
+ end
383
+ expected(actual, desired)
384
+
385
+ # Check db
386
+ group_names.each do |name|
387
+ group = @db.models[:group].find(name: name)
388
+ expect(group).not_to be_nil
389
+ hosts = group.hosts_dataset
390
+ expect(hosts.count).to eq(host_names.count)
391
+ host_names.each do |host|
392
+ expect(hosts[name: host]).not_to be_nil
393
+ expect(hosts[name: host].groups_dataset[name: 'ungrouped']).to be_nil
394
+ end
395
+ end
396
+ end
397
+ end
398
+ end