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,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