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,248 @@
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::Host 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
+
21
+ @config = Moose::Inventory::Config
22
+ @config.init(@mockargs)
23
+
24
+ @db = Moose::Inventory::DB
25
+ @db.init if @db.db.nil?
26
+
27
+ @host = Moose::Inventory::Cli::Host
28
+ @app = Moose::Inventory::Cli::Application
29
+ end
30
+
31
+ before(:each) do
32
+ @db.reset
33
+ end
34
+
35
+ #=======================
36
+ describe 'addgroup' do
37
+ #------------------------
38
+ it 'Host.addgroup() should be responsive' do
39
+ result = @host.instance_methods(false).include?(:addgroup)
40
+ expect(result).to eq(true)
41
+ end
42
+
43
+ #------------------------
44
+ it 'host addgroup <missing args> ... should abort with an error' do
45
+ actual = runner do
46
+ @app.start(%w(host addgroup)) # <- no group given
47
+ end
48
+
49
+ # Check output
50
+ desired = { aborted: true}
51
+ desired[:STDERR] = "ERROR: Wrong number of arguments, 0 for 2 or more.\n"
52
+ expected(actual, desired)
53
+ end
54
+
55
+ #------------------------
56
+ it 'host addgroup HOST GROUP ... should abort if the host does not exist' do
57
+ actual = runner do
58
+ @app.start(%w(host addgroup not-a-host example))
59
+ end
60
+
61
+ # Check output
62
+ desired = { aborted: true}
63
+ desired[:STDOUT] =
64
+ "Associate host 'not-a-host' with groups 'example':\n"\
65
+ " - Retrieve host 'not-a-host'...\n"
66
+ desired[:STDERR] =
67
+ "An error occurred during a transaction, any changes have been rolled back.\n"\
68
+ "ERROR: The host 'not-a-host' was not found in the database.\n"
69
+ expected(actual, desired)
70
+ end
71
+
72
+ #------------------------
73
+ it 'host addgroup HOST GROUP ... should add the host to an existing group' do
74
+ # 1. Should add the host to the group
75
+ # 2. Should remove the host from the 'ungrouped' automatic group
76
+
77
+ name = 'test1'
78
+ group_name = 'testgroup1'
79
+
80
+ runner { @app.start(%W(host add #{name})) }
81
+ @db.models[:group].create(name: group_name)
82
+
83
+ actual = runner { @app.start(%W(host addgroup #{name} #{group_name} )) }
84
+
85
+ # rubocop:disable Metrics/LineLength
86
+ desired = { aborted: false}
87
+ desired[:STDOUT] =
88
+ "Associate host '#{name}' with groups '#{group_name}':\n"\
89
+ " - Retrieve host '#{name}'...\n"\
90
+ " - OK\n"\
91
+ " - Add association {host:#{name} <-> group:#{group_name}}...\n"\
92
+ " - OK\n"\
93
+ " - Remove automatic association {host:#{name} <-> group:ungrouped}...\n"\
94
+ " - OK\n"\
95
+ " - All OK\n"\
96
+ "Succeeded\n"
97
+ expected(actual, desired)
98
+ # rubocop:enable Metrics/LineLength
99
+
100
+ # We should have the correct group associations
101
+ host = @db.models[:host].find(name: name)
102
+ groups = host.groups_dataset
103
+ expect(groups.count).to eq(1)
104
+ expect(groups[name: group_name]).not_to be_nil
105
+ expect(groups[name: 'ungrouped']).to be_nil # redundant, but for clarity!
106
+ end
107
+
108
+ #------------------------
109
+ it 'HOST \'ungrouped\' ... should abort with an error' do
110
+
111
+ name = 'test1'
112
+ group_name = 'ungrouped'
113
+
114
+ runner { @app.start(%W(host add #{name})) }
115
+
116
+ actual = runner { @app.start(%W(host addgroup #{name} #{group_name} )) }
117
+
118
+ desired = { aborted: true}
119
+ desired[:STDERR] =
120
+ "ERROR: Cannot manually manipulate the automatic group 'ungrouped'.\n"
121
+ expected(actual, desired)
122
+ end
123
+
124
+ #------------------------
125
+ it 'HOST GROUP ... should add the host to an group, creating the group if necessary' do
126
+ name = 'test1'
127
+ group_name = 'testgroup1'
128
+
129
+ runner { @app.start(%W(host add #{name})) }
130
+
131
+ # DON'T CREATE THE GROUP! That's the point of the test. ;o)
132
+
133
+ actual = runner { @app.start(%W(host addgroup #{name} #{group_name} )) }
134
+
135
+ # Check output
136
+ desired = { aborted: false}
137
+ desired[:STDOUT] =
138
+ "Associate host '#{name}' with groups '#{group_name}':\n"\
139
+ " - Retrieve host '#{name}'...\n"\
140
+ " - OK\n"\
141
+ " - Add association {host:#{name} <-> group:#{group_name}}...\n"\
142
+ " - Group does not exist, creating now...\n"\
143
+ " - OK\n"\
144
+ " - OK\n"\
145
+ " - Remove automatic association {host:#{name} <-> group:ungrouped}...\n"\
146
+ " - OK\n"\
147
+ " - All OK\n"\
148
+ "Succeeded\n"
149
+ desired[:STDERR] =
150
+ "WARNING: Group '#{group_name}' does not exist and will be created."
151
+ expected(actual, desired)
152
+
153
+ # Check db
154
+ host = @db.models[:host].find(name: name)
155
+ groups = host.groups_dataset
156
+ expect(groups.count).to eq(1)
157
+ expect(groups[name: group_name]).not_to be_nil
158
+ expect(groups[name: 'ungrouped']).to be_nil # redundant, but for clarity!
159
+ end
160
+
161
+ #------------------------
162
+ it 'HOST GROUP ... should skip associations that already '\
163
+ ' exist, but raise a warning.' do
164
+ name = 'test1'
165
+ group_name = 'testgroup1'
166
+
167
+ runner { @app.start(%W(host add #{name})) }
168
+
169
+ # DON'T CREATE THE GROUP! That's the point of the test. ;o)
170
+
171
+ # Run once to make the association
172
+ runner { @app.start(%W(host addgroup #{name} #{group_name} )) }
173
+
174
+ # Run again, to prove expected result
175
+ actual = runner { @app.start(%W(host addgroup #{name} #{group_name} )) }
176
+
177
+ # Check output
178
+ # Note: This time, we don't expect to see any messages about
179
+ # dissociation from 'ungrouped'
180
+ desired = { aborted: false}
181
+ desired[:STDOUT] =
182
+ "Associate host '#{name}' with groups '#{group_name}':\n"\
183
+ " - Retrieve host \'#{name}\'...\n"\
184
+ " - OK\n"\
185
+ " - Add association {host:#{name} <-> group:#{group_name}}...\n"\
186
+ " - Already exists, skipping.\n"\
187
+ " - OK\n"\
188
+ " - All OK\n"\
189
+ "Succeeded\n"
190
+ desired[:STDERR] = "WARNING: Association {host:#{name} <-> group:#{group_name}} already exists, skipping."
191
+ expected(actual, desired)
192
+
193
+ # Check db
194
+ host = @db.models[:host].find(name: name)
195
+ groups = host.groups_dataset
196
+ expect(groups.count).to eq(1)
197
+ expect(groups[name: group_name]).not_to be_nil
198
+ expect(groups[name: 'ungrouped']).to be_nil # redundant, but for clarity!
199
+ end
200
+
201
+ #------------------------
202
+ it 'host addgroup GROUP1 GROUP1 ... should add the host to'\
203
+ ' multiple groups at once' do
204
+ name = 'test1'
205
+ group_names = %w(group1 group2 group3)
206
+
207
+ runner { @app.start(%W(host add #{name})) }
208
+
209
+ actual = runner { @app.start(%W(host addgroup #{name}) + group_names) }
210
+
211
+ # Check output
212
+ desired = { aborted: false, STDERR: ''}
213
+ desired[:STDOUT] =
214
+ "Associate host '#{name}' with groups '#{group_names.join(',')}':\n"\
215
+ " - Retrieve host '#{name}'...\n"\
216
+ " - OK\n"
217
+ group_names.each do |group|
218
+ desired[:STDOUT] = desired[:STDOUT] +
219
+ " - Add association {host:#{name} <-> group:#{group}}...\n"\
220
+ " - Group does not exist, creating now...\n"\
221
+ " - OK\n"\
222
+ " - OK\n"
223
+
224
+ desired[:STDERR] = desired[:STDERR] +
225
+ "WARNING: Group '#{group}' does not exist and will be created."
226
+ end
227
+ desired[:STDOUT] = desired[:STDOUT] +
228
+ " - Remove automatic association {host:#{name} <-> group:ungrouped}...\n"\
229
+ " - OK\n"\
230
+ " - All OK\n"\
231
+ "Succeeded\n"
232
+ expected(actual, desired)
233
+
234
+
235
+ # We should have group associations
236
+ host = @db.models[:host].find(name: name)
237
+ groups = host.groups_dataset
238
+ expect(groups).not_to be_nil
239
+
240
+ # There should be 3 relationships, but not with 'ungrouped'
241
+ expect(groups.count).to eq(3)
242
+ group_names.each do |group|
243
+ expect(groups[name: group]).not_to be_nil
244
+ end
245
+ expect(groups[name: 'ungrouped']).to be_nil
246
+ end
247
+ end
248
+ end
@@ -0,0 +1,233 @@
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::Host 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
+
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
+ @host = Moose::Inventory::Cli::Host
29
+ @app = Moose::Inventory::Cli::Application
30
+ end
31
+
32
+ before(:each) do
33
+ @db.reset
34
+ end
35
+
36
+ #==================
37
+ describe 'addvar' do
38
+ #-----------------
39
+ it 'should be responsive' do
40
+ result = @host.instance_methods(false).include?(:addvar)
41
+ expect(result).to eq(true)
42
+ end
43
+
44
+ #-----------------
45
+ it 'host addvar <missing args> ... should abort with an error' do
46
+ actual = runner do
47
+ @app.start(%w(host addvar)) # <- no group given
48
+ end
49
+
50
+ # Check output
51
+ desired = { aborted: true}
52
+ desired[:STDERR] = "ERROR: Wrong number of arguments, 0 for 2 or more.\n"
53
+ expected(actual, desired)
54
+ end
55
+
56
+ #------------------------
57
+ it 'host addvar HOST key=value ... should abort if the host does not exist' do
58
+ host_name ='not-a-host'
59
+ host_var = "foo=bar"
60
+
61
+ actual = runner do
62
+ @app.start(%W(host addvar #{host_name} #{host_var}))
63
+ end
64
+
65
+ # Check output
66
+ desired = { aborted: true}
67
+ desired[:STDOUT] =
68
+ "Add variables '#{host_var}' to host '#{host_name}':\n"\
69
+ " - retrieve host '#{host_name}'...\n"
70
+ desired[:STDERR] =
71
+ "An error occurred during a transaction, any changes have been rolled back.\n"\
72
+ "ERROR: The host '#{host_name}' does not exist.\n"
73
+ expected(actual, desired)
74
+ end
75
+
76
+ #------------------------
77
+ it 'host addvar HOST <malformed> ... should abort with an error' do
78
+ # 1. Should add the var to the db
79
+ # 2. Should associate the host with the var
80
+
81
+ host_name = 'test1'
82
+ @db.models[:host].create(name: host_name)
83
+
84
+ var = {name: 'var1', value: "testval"}
85
+ cases = %W(
86
+ testvar
87
+ testvar=
88
+ =testval
89
+ testvar=testval=
90
+ =testvar=testval
91
+ testvar=testval=extra
92
+ )
93
+
94
+ cases.each do |args|
95
+ actual = runner do
96
+ @app.start(%W(host addvar #{host_name} #{args} ))
97
+ end
98
+ #@console.out(actual,'p')
99
+
100
+ desired = { aborted: true}
101
+ desired[:STDOUT] =
102
+ "Add variables '#{args}' to host '#{host_name}':\n"\
103
+ " - retrieve host '#{host_name}'...\n"\
104
+ " - OK\n"\
105
+ " - add variable '#{args}'...\n"
106
+
107
+ desired[:STDERR] =
108
+ "An error occurred during a transaction, any changes have been rolled back.\n"\
109
+ "ERROR: Incorrect format in '{#{args}}'. Expected 'key=value'.\n"
110
+
111
+ expected(actual, desired)
112
+ end
113
+ end
114
+
115
+ #------------------------
116
+ it 'host addvar HOST key=value ... should associate the host with the key/value pair' do
117
+ # 1. Should add the var to the db
118
+ # 2. Should associate the host with the var
119
+
120
+ host_name = 'test1'
121
+ var = {name: 'var1', value: "testval"}
122
+
123
+ @db.models[:host].create(name: host_name)
124
+
125
+ actual = runner do
126
+ @app.start(%W(host addvar #{host_name} #{var[:name]}=#{var[:value]} ))
127
+ end
128
+ #@console.out(actual,'p')
129
+
130
+ desired = { aborted: false}
131
+ desired[:STDOUT] =
132
+ "Add variables '#{var[:name]}=#{var[:value]}' to host '#{host_name}':\n"\
133
+ " - retrieve host '#{host_name}'...\n"\
134
+ " - OK\n"\
135
+ " - add variable '#{var[:name]}=#{var[:value]}'...\n"\
136
+ " - OK\n"\
137
+ " - all OK\n"\
138
+ "Succeeded.\n"
139
+ expected(actual, desired)
140
+
141
+ # We should have the correct hostvar associations
142
+ host = @db.models[:host].find(name: host_name)
143
+ hostvars = host.hostvars_dataset
144
+ expect(hostvars.count).to eq(1)
145
+ expect(hostvars[name: var[:name]]).not_to be_nil
146
+ expect(hostvars[name: var[:name]][:value]).to eq(var[:value])
147
+ end
148
+
149
+ #------------------------
150
+ it 'host addvar HOST key1=value1 key2=value2 ... should associate the host with multiple key/value pairs' do
151
+ # 1. Should add the var to the db
152
+ # 2. Should associate the host with the var
153
+
154
+ host_name = 'test1'
155
+ varsarray = [
156
+ {name: 'var1', value: "val1"},
157
+ {name: 'var2', value: "val2"}
158
+ ]
159
+
160
+ vars = []
161
+ varsarray.each do |var|
162
+ vars << "#{var[:name]}=#{var[:value]}"
163
+ end
164
+
165
+ @db.models[:host].create(name: host_name)
166
+
167
+ actual = runner do
168
+ @app.start(%W(host addvar #{host_name}) + vars )
169
+ end
170
+ #@console.out(actual,'p')
171
+
172
+ desired = { aborted: false}
173
+ desired[:STDOUT] =
174
+ "Add variables '#{vars.join(',')}' to host '#{host_name}':\n"\
175
+ " - retrieve host '#{host_name}'...\n"\
176
+ " - OK\n"
177
+ vars.each do |var|
178
+ desired[:STDOUT] = desired[:STDOUT] +
179
+ " - add variable '#{var}'...\n"\
180
+ " - OK\n"
181
+ end
182
+ desired[:STDOUT] = desired[:STDOUT] +
183
+ " - all OK\n"\
184
+ "Succeeded.\n"
185
+ expected(actual, desired)
186
+
187
+ # We should have the correct hostvar associations
188
+ host = @db.models[:host].find(name: host_name)
189
+ hostvars = host.hostvars_dataset
190
+ expect(hostvars.count).to eq(vars.length)
191
+ end
192
+
193
+ #------------------------
194
+ it 'host addvar HOST key=value ... should update an already existing association' do
195
+ # 1. Should add the var to the db
196
+ # 2. Should associate the host with the var
197
+
198
+ host_name = 'test1'
199
+ var = {name: 'var1', value: "testval"}
200
+
201
+ @db.models[:host].create(name: host_name)
202
+ runner { @app.start(%W(host addvar #{host_name} #{var[:name]}=#{var[:value]} )) }
203
+
204
+ var[:value] = "newtestval"
205
+ actual = runner do
206
+ @app.start(%W(host addvar #{host_name} #{var[:name]}=#{var[:value]} ))
207
+ end
208
+ #@console.out(actual,'p')
209
+
210
+ desired = { aborted: false}
211
+ desired[:STDOUT] =
212
+ "Add variables '#{var[:name]}=#{var[:value]}' to host '#{host_name}':\n"\
213
+ " - retrieve host '#{host_name}'...\n"\
214
+ " - OK\n"\
215
+ " - add variable '#{var[:name]}=#{var[:value]}'...\n"\
216
+ " - already exists, applying as an update...\n"\
217
+ " - OK\n"\
218
+ " - all OK\n"\
219
+ "Succeeded.\n"
220
+ expected(actual, desired)
221
+
222
+ # We should have the correct hostvar associations
223
+ host = @db.models[:host].find(name: host_name)
224
+ hostvars = host.hostvars_dataset
225
+ expect(hostvars.count).to eq(1)
226
+ expect(hostvars[name: var[:name]]).not_to be_nil
227
+ expect(hostvars[name: var[:name]][:value]).to eq(var[:value])
228
+
229
+ hostvars = @db.models[:hostvar].all
230
+ expect(hostvars.count).to eq(1)
231
+ end
232
+ end
233
+ end