moose-inventory 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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