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