dop_common 0.13.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.
- checksums.yaml +7 -0
- data/.gitignore +23 -0
- data/.rspec +2 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +176 -0
- data/Gemfile +11 -0
- data/LICENSE.txt +177 -0
- data/README.md +48 -0
- data/Rakefile +49 -0
- data/Vagrantfile +25 -0
- data/bin/dop-puppet-autosign +56 -0
- data/doc/examples/example_deploment_plan_v0.0.1.yaml +302 -0
- data/doc/plan_format_v0.0.1.md +919 -0
- data/doc/plan_format_v0.0.2_snippets.md +56 -0
- data/dop_common.gemspec +44 -0
- data/lib/dop_common/affinity_group.rb +57 -0
- data/lib/dop_common/cli/global_options.rb +37 -0
- data/lib/dop_common/cli/log.rb +51 -0
- data/lib/dop_common/cli/node_selection.rb +62 -0
- data/lib/dop_common/command.rb +125 -0
- data/lib/dop_common/config/helper.rb +39 -0
- data/lib/dop_common/config.rb +66 -0
- data/lib/dop_common/configuration.rb +37 -0
- data/lib/dop_common/credential.rb +152 -0
- data/lib/dop_common/data_disk.rb +62 -0
- data/lib/dop_common/dns.rb +55 -0
- data/lib/dop_common/hash_parser.rb +241 -0
- data/lib/dop_common/hooks.rb +81 -0
- data/lib/dop_common/infrastructure.rb +160 -0
- data/lib/dop_common/infrastructure_properties.rb +185 -0
- data/lib/dop_common/interface.rb +113 -0
- data/lib/dop_common/log.rb +78 -0
- data/lib/dop_common/network.rb +85 -0
- data/lib/dop_common/node/config.rb +159 -0
- data/lib/dop_common/node.rb +442 -0
- data/lib/dop_common/node_filter.rb +74 -0
- data/lib/dop_common/plan.rb +188 -0
- data/lib/dop_common/plan_cache.rb +83 -0
- data/lib/dop_common/plan_store.rb +263 -0
- data/lib/dop_common/pre_processor.rb +73 -0
- data/lib/dop_common/run_options.rb +56 -0
- data/lib/dop_common/signal_handler.rb +58 -0
- data/lib/dop_common/state_store.rb +95 -0
- data/lib/dop_common/step.rb +200 -0
- data/lib/dop_common/step_set.rb +41 -0
- data/lib/dop_common/thread_context_logger.rb +77 -0
- data/lib/dop_common/utils.rb +106 -0
- data/lib/dop_common/validator.rb +53 -0
- data/lib/dop_common/version.rb +3 -0
- data/lib/dop_common.rb +32 -0
- data/lib/hiera/backend/dop_backend.rb +94 -0
- data/lib/hiera/dop_logger.rb +20 -0
- data/spec/data/fake_hook_file_invalid +1 -0
- data/spec/data/fake_hook_file_valid +5 -0
- data/spec/data/fake_keyfile +1 -0
- data/spec/dop-puppet-autosign_spec_disable.rb +33 -0
- data/spec/dop_common/affinity_group_spec.rb +41 -0
- data/spec/dop_common/command_spec.rb +83 -0
- data/spec/dop_common/credential_spec.rb +73 -0
- data/spec/dop_common/data_disk_spec.rb +165 -0
- data/spec/dop_common/dns_spec.rb +33 -0
- data/spec/dop_common/hash_parser_spec.rb +181 -0
- data/spec/dop_common/hooks_spec.rb +33 -0
- data/spec/dop_common/infrastructure_properties_spec.rb +224 -0
- data/spec/dop_common/infrastructure_spec.rb +77 -0
- data/spec/dop_common/interface_spec.rb +192 -0
- data/spec/dop_common/network_spec.rb +92 -0
- data/spec/dop_common/node_filter_spec.rb +70 -0
- data/spec/dop_common/node_spec.rb +623 -0
- data/spec/dop_common/plan_cache_spec.rb +46 -0
- data/spec/dop_common/plan_spec.rb +136 -0
- data/spec/dop_common/plan_store_spec.rb +194 -0
- data/spec/dop_common/pre_processor_spec.rb +27 -0
- data/spec/dop_common/run_options_spec.rb +65 -0
- data/spec/dop_common/signal_handler_spec.rb +31 -0
- data/spec/dop_common/step_set_spec.rb +21 -0
- data/spec/dop_common/step_spec.rb +175 -0
- data/spec/dop_common/utils_spec.rb +27 -0
- data/spec/dop_common/validator_spec.rb +47 -0
- data/spec/example_plans_spec.rb +16 -0
- data/spec/fixtures/example_ssh_key +27 -0
- data/spec/fixtures/example_ssh_key.pub +1 -0
- data/spec/fixtures/incl/root_part.yaml +1 -0
- data/spec/fixtures/incl/some_list.yaml +2 -0
- data/spec/fixtures/other_plan_same_nodes.yaml +19 -0
- data/spec/fixtures/simple_include.yaml +6 -0
- data/spec/fixtures/simple_include_with_errors.yaml +4 -0
- data/spec/fixtures/simple_plan.yaml +19 -0
- data/spec/fixtures/simple_plan_invalid.yaml +18 -0
- data/spec/fixtures/simple_plan_modified.yaml +21 -0
- data/spec/spec_helper.rb +106 -0
- metadata +381 -0
@@ -0,0 +1,623 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DopCommon::Node do
|
4
|
+
before(:each) do
|
5
|
+
@infrastructures = [
|
6
|
+
DopCommon::Infrastructure.new(
|
7
|
+
'rhev',
|
8
|
+
{
|
9
|
+
'type' => 'rhev',
|
10
|
+
'networks' => {
|
11
|
+
'net0' => {},
|
12
|
+
'net1' => {}
|
13
|
+
}
|
14
|
+
}
|
15
|
+
),
|
16
|
+
DopCommon::Infrastructure.new(
|
17
|
+
'rhos',
|
18
|
+
{
|
19
|
+
'type' => 'rhos',
|
20
|
+
'networks' => {
|
21
|
+
'net0' => {},
|
22
|
+
'net1' => {}
|
23
|
+
}
|
24
|
+
}
|
25
|
+
),
|
26
|
+
DopCommon::Infrastructure.new(
|
27
|
+
'vsphere',
|
28
|
+
{
|
29
|
+
'type' => 'vsphere',
|
30
|
+
'networks' => {
|
31
|
+
'net0' => {},
|
32
|
+
'net1' => {}
|
33
|
+
}
|
34
|
+
}
|
35
|
+
),
|
36
|
+
DopCommon::Infrastructure.new('baremetal', {'type' => 'baremetal'}),
|
37
|
+
]
|
38
|
+
end
|
39
|
+
|
40
|
+
describe '#range' do
|
41
|
+
it 'will return nil if the node is not inflatable' do
|
42
|
+
node = DopCommon::Node.new('mynode.example.com', {:range => '1..10'})
|
43
|
+
expect(node.range).to be nil
|
44
|
+
end
|
45
|
+
it 'will return a range object' do
|
46
|
+
node = DopCommon::Node.new('mynode{i}.example.com', {:range => '1..10'})
|
47
|
+
expect(node.range).to be_an_instance_of Range
|
48
|
+
end
|
49
|
+
it 'will throw and exception if the key is not defined' do
|
50
|
+
node = DopCommon::Node.new('mynode{i}.example.com', {})
|
51
|
+
expect{node.range}.to raise_error DopCommon::PlanParsingError
|
52
|
+
end
|
53
|
+
it 'will throw an exception if there are more than two numbers for the range' do
|
54
|
+
node = DopCommon::Node.new('mynode{i}.example.com', {:range => '1..10..100'})
|
55
|
+
expect{node.range}.to raise_error DopCommon::PlanParsingError
|
56
|
+
end
|
57
|
+
it 'will throw an exception if the first number is bigger than the second' do
|
58
|
+
node = DopCommon::Node.new('mynode{i}.example.com', {:range => '10..1'})
|
59
|
+
expect{node.range}.to raise_error DopCommon::PlanParsingError
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe '#digits' do
|
64
|
+
it 'will return the correct number for digits' do
|
65
|
+
node = DopCommon::Node.new('mynode{i}.example.com', {})
|
66
|
+
expect(node.digits).to be DopCommon::Node::DEFAULT_DIGITS
|
67
|
+
node = DopCommon::Node.new('mynode{i}.example.com', {:digits => 10})
|
68
|
+
expect(node.digits).to be 10
|
69
|
+
end
|
70
|
+
it 'will throw an exception if it is lower than 1' do
|
71
|
+
node = DopCommon::Node.new('mynode{i}.example.com', {:digits => -1})
|
72
|
+
expect{node.digits}.to raise_error DopCommon::PlanParsingError
|
73
|
+
end
|
74
|
+
it 'will throw an exception if is not a number' do
|
75
|
+
node = DopCommon::Node.new('mynode{i}.example.com', {:digits => 'foo'})
|
76
|
+
expect{node.digits}.to raise_error DopCommon::PlanParsingError
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe '#inflatable?' do
|
81
|
+
it 'will return true when the node inflatable' do
|
82
|
+
node = DopCommon::Node.new('mynode{i}.example.com', {})
|
83
|
+
expect(node.inflatable?).to be true
|
84
|
+
end
|
85
|
+
it 'will return false when the node is not inflatable' do
|
86
|
+
node = DopCommon::Node.new('mynode.example.com', {})
|
87
|
+
expect(node.inflatable?).to be false
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe '#inflate' do
|
92
|
+
it 'will return a new array of nodes' do
|
93
|
+
node = DopCommon::Node.new('mynode{i}.example.com', {:range => '1..10', :digits => 3})
|
94
|
+
nodes = node.inflate
|
95
|
+
expect(nodes.length).to be 10
|
96
|
+
expect(nodes[0].name).to eq 'mynode001.example.com'
|
97
|
+
expect(nodes[9].name).to eq 'mynode010.example.com'
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe '#fqdn' do
|
102
|
+
it 'will return FQDN is it is syntactically correct' do
|
103
|
+
node = DopCommon::Node.new('dummy', {})
|
104
|
+
expect(node.fqdn).to eq 'dummy'
|
105
|
+
node = DopCommon::Node.new('dummy', { 'fqdn' => 'f.q.dn.' })
|
106
|
+
expect(node.fqdn).to eq 'f.q.dn'
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'will raise an error if it is not a string' do
|
110
|
+
node = DopCommon::Node.new('dummy', { 'fqdn' => :invalid })
|
111
|
+
expect{node.fqdn}.to raise_error DopCommon::PlanParsingError
|
112
|
+
end
|
113
|
+
it 'will raise an error if FQDN is too long' do
|
114
|
+
node = DopCommon::Node.new('dummy', { 'fqdn' => "#{'long'*300}.f.q.dn" })
|
115
|
+
expect{node.fqdn}.to raise_error DopCommon::PlanParsingError
|
116
|
+
end
|
117
|
+
it 'will raise an error if FQDN is syntactically invalid' do
|
118
|
+
node = DopCommon::Node.new('dummy', { 'fqdn' => 'invalid.f!.q.dn' })
|
119
|
+
expect{node.fqdn}.to raise_error DopCommon::PlanParsingError
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
describe '#infrastructure_properties' do
|
124
|
+
it 'will return infrastructure properties' do
|
125
|
+
node = DopCommon::Node.new(
|
126
|
+
'dummy',
|
127
|
+
{
|
128
|
+
'infrastructure' => 'rhev',
|
129
|
+
'infrastructure_properties' => { 'datacenter' => 'foo', 'cluster' => 'bar' }
|
130
|
+
},
|
131
|
+
{:parsed_infrastructures => @infrastructures}
|
132
|
+
)
|
133
|
+
expect(node.infrastructure_properties).to be_an_instance_of DopCommon::InfrastructureProperties
|
134
|
+
end
|
135
|
+
it 'will raise an error if infrastructure properties is not hash' do
|
136
|
+
node = DopCommon::Node.new(
|
137
|
+
'dummy',
|
138
|
+
{
|
139
|
+
'infrastructure' => 'rhev',
|
140
|
+
'infrastructure_properties' => 'foo'
|
141
|
+
},
|
142
|
+
{:parsed_infrastructures => @infrastructures}
|
143
|
+
)
|
144
|
+
expect{node.infrastructure_properties}.to raise_error DopCommon::PlanParsingError
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
describe '#image' do
|
149
|
+
it 'will return an image of a node' do
|
150
|
+
node = DopCommon::Node.new(
|
151
|
+
'dummy',
|
152
|
+
{'infrastructure' => 'rhev', 'image' => 'dummy'},
|
153
|
+
{:parsed_infrastructures => @infrastructures}
|
154
|
+
)
|
155
|
+
expect(node.image).to eq 'dummy'
|
156
|
+
node = DopCommon::Node.new(
|
157
|
+
'dummy',
|
158
|
+
{'infrastructure' => 'baremetal'},
|
159
|
+
{:parsed_infrastructures => @infrastructures}
|
160
|
+
)
|
161
|
+
expect(node.image).to eq nil
|
162
|
+
end
|
163
|
+
|
164
|
+
it 'will raise an error if image is not a string' do
|
165
|
+
node = DopCommon::Node.new(
|
166
|
+
'dummy',
|
167
|
+
{'infrastructure' => 'rhev', 'image' => :invalid},
|
168
|
+
{:parsed_infrastructures => @infrastructures}
|
169
|
+
)
|
170
|
+
expect{node.image}.to raise_error DopCommon::PlanParsingError
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
describe '#full_clone' do
|
175
|
+
it 'will return "true" for OVirt/RHEVm-like provider if unspecified' do
|
176
|
+
node = DopCommon::Node.new(
|
177
|
+
'dummy',
|
178
|
+
{'infrastructure' => 'rhev'},
|
179
|
+
{:parsed_infrastructures => @infrastructures}
|
180
|
+
)
|
181
|
+
expect(node.full_clone).to be true
|
182
|
+
end
|
183
|
+
it 'will return a boolean value if specified properly' do
|
184
|
+
node = DopCommon::Node.new(
|
185
|
+
'dummy',
|
186
|
+
{'infrastructure' => 'rhev', 'full_clone' => true},
|
187
|
+
{:parsed_infrastructures => @infrastructures}
|
188
|
+
)
|
189
|
+
expect(node.full_clone).to be true
|
190
|
+
node = DopCommon::Node.new(
|
191
|
+
'dummy',
|
192
|
+
{'infrastructure' => 'rhev', 'full_clone' => false},
|
193
|
+
{:parsed_infrastructures => @infrastructures}
|
194
|
+
)
|
195
|
+
expect(node.full_clone).to be false
|
196
|
+
end
|
197
|
+
|
198
|
+
it 'will return the default value in case of invalid provider type' do
|
199
|
+
node = DopCommon::Node.new(
|
200
|
+
'dummy',
|
201
|
+
{'infrastructure' => 'baremetal'},
|
202
|
+
{:parsed_infrastructures => @infrastructures}
|
203
|
+
)
|
204
|
+
expect(node.full_clone).to be true
|
205
|
+
end
|
206
|
+
it 'will raise an error if "full_clone" is of invalid type' do
|
207
|
+
node = DopCommon::Node.new(
|
208
|
+
'dummy',
|
209
|
+
{'infrastructure' => 'rhev', 'full_clone' => :invalid},
|
210
|
+
{:parsed_infrastructures => @infrastructures}
|
211
|
+
)
|
212
|
+
expect{node.full_clone}.to raise_error DopCommon::PlanParsingError
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
describe '#interfaces' do
|
217
|
+
it 'will return an array of interfaces if specified correctly' do
|
218
|
+
node = DopCommon::Node.new(
|
219
|
+
'foo',
|
220
|
+
{
|
221
|
+
'infrastructure' => 'rhev',
|
222
|
+
'interfaces' => {'eth0' => {'network' => 'net0'}, 'eth1' => {'network' => 'net1'}}
|
223
|
+
},
|
224
|
+
{:parsed_infrastructures => @infrastructures}
|
225
|
+
)
|
226
|
+
expect(node.interfaces.length).to eq 2
|
227
|
+
expect(node.interfaces.all?{|i| i.kind_of?(DopCommon::Interface)}).to be true
|
228
|
+
end
|
229
|
+
it 'will return an empty array if interfaces is not specified' do
|
230
|
+
node = DopCommon::Node.new('foo', {})
|
231
|
+
expect(node.interfaces).to eq([])
|
232
|
+
end
|
233
|
+
it 'will raise an error if interfaces is not a hash' do
|
234
|
+
node = DopCommon::Node.new('foo', {:interfaces => 2})
|
235
|
+
expect{node.interfaces}.to raise_error DopCommon::PlanParsingError
|
236
|
+
end
|
237
|
+
it 'will raise an error if a key in interfaces is not a string' do
|
238
|
+
node = DopCommon::Node.new('foo', {:interfaces => {2 => {}}})
|
239
|
+
expect{node.interfaces}.to raise_error DopCommon::PlanParsingError
|
240
|
+
end
|
241
|
+
it 'will raise an error if a value in interfaces is not a hash' do
|
242
|
+
node = DopCommon::Node.new('foo', {:interfaces => {'eth0' => 2}})
|
243
|
+
expect{node.interfaces}.to raise_error DopCommon::PlanParsingError
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
describe '#flavor' do
|
248
|
+
it "will return nil if not specified and the provider isn't openstack" do
|
249
|
+
node = DopCommon::Node.new(
|
250
|
+
'dummy',
|
251
|
+
{'infrastructure' => 'rhev'},
|
252
|
+
{:parsed_infrastructures => @infrastructures}
|
253
|
+
)
|
254
|
+
expect(node.flavor).to be_nil
|
255
|
+
end
|
256
|
+
it 'will return DEFAULT_OPENSTACK_FLAVOR if not specified and the provider is openstack' do
|
257
|
+
node = DopCommon::Node.new(
|
258
|
+
'dummy',
|
259
|
+
{'infrastructure' => 'rhos'},
|
260
|
+
{:parsed_infrastructures => @infrastructures}
|
261
|
+
)
|
262
|
+
expect(node.flavor).to eq DopCommon::Node::DEFAULT_OPENSTACK_FLAVOR
|
263
|
+
end
|
264
|
+
it 'will return the flavor as-is if it is specified and the provider is openstack' do
|
265
|
+
node = DopCommon::Node.new(
|
266
|
+
'dummy',
|
267
|
+
{'infrastructure' => 'rhos', 'flavor' => 'anyflavor'},
|
268
|
+
{:parsed_infrastructures => @infrastructures}
|
269
|
+
)
|
270
|
+
expect(node.flavor).to eq 'anyflavor'
|
271
|
+
end
|
272
|
+
it 'will return nil if it exists in VALID_FLAVIR_TYPES and the provider is not openstack' do
|
273
|
+
node = DopCommon::Node.new(
|
274
|
+
'dummy',
|
275
|
+
{'infrastructure' => 'rhev', 'flavor' => 'tiny'},
|
276
|
+
{:parsed_infrastructures => @infrastructures}
|
277
|
+
)
|
278
|
+
expect(node.flavor).to be_nil
|
279
|
+
end
|
280
|
+
it 'will raise an error if flavor is defined together with one of cores, memory or storage' do
|
281
|
+
{'cores' => 2, 'memory' => '15G', 'storage' => '100GB'}.each do |k, v|
|
282
|
+
node = DopCommon::Node.new(
|
283
|
+
'dummy',
|
284
|
+
{'infrastructure' => 'rhev', 'flavor' => 'medium', k => v},
|
285
|
+
{:parsed_infrastructures => @infrastructures}
|
286
|
+
)
|
287
|
+
expect{node.flavor}.to raise_error DopCommon::PlanParsingError
|
288
|
+
end
|
289
|
+
end
|
290
|
+
it "will raise an error if flavor is specified but it isn't a string" do
|
291
|
+
[1, [], {}, :sym].each do |flavor|
|
292
|
+
node = DopCommon::Node.new(
|
293
|
+
'dummy',
|
294
|
+
{'infrastructure' => 'rhev', 'flavor' => flavor},
|
295
|
+
{:parsed_infrastructures => @infrastructures}
|
296
|
+
)
|
297
|
+
expect{node.flavor}.to raise_error DopCommon::PlanParsingError
|
298
|
+
end
|
299
|
+
end
|
300
|
+
it 'will raise an error if infrastructure is not openstack and the flavor is invalid' do
|
301
|
+
node = DopCommon::Node.new(
|
302
|
+
'dummy',
|
303
|
+
{'infrastructure' => 'rhev', 'flavor' => 'invalid'},
|
304
|
+
{:parsed_infrastructures => @infrastructures}
|
305
|
+
)
|
306
|
+
expect{node.flavor}.to raise_error DopCommon::PlanParsingError
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
describe '#cores' do
|
311
|
+
it 'will return number of cores if specified properly' do
|
312
|
+
[1, 10].each do |cores|
|
313
|
+
node = DopCommon::Node.new(
|
314
|
+
'dummy',
|
315
|
+
{'infrastructure' => 'rhev', 'cores' => cores},
|
316
|
+
{:parsed_infrastructures => @infrastructures}
|
317
|
+
)
|
318
|
+
expect(node.cores).to eq cores
|
319
|
+
end
|
320
|
+
end
|
321
|
+
it 'will raise an exception if specified for openstack provider' do
|
322
|
+
node = DopCommon::Node.new(
|
323
|
+
'dummy',
|
324
|
+
{'infrastructure' => 'rhos', 'cores' => 2},
|
325
|
+
{:parsed_infrastructures => @infrastructures}
|
326
|
+
)
|
327
|
+
expect{node.cores}.to raise_error DopCommon::PlanParsingError
|
328
|
+
end
|
329
|
+
it 'will raise an exception in case of invalid input' do
|
330
|
+
[:invalid, 'four', '4'].each do |cores|
|
331
|
+
node = DopCommon::Node.new(
|
332
|
+
'dummy',
|
333
|
+
{'infrastructure' => 'rhev', 'cores' => cores},
|
334
|
+
{:parsed_infrastructures => @infrastructures}
|
335
|
+
)
|
336
|
+
expect{node.cores}.to raise_error DopCommon::PlanParsingError
|
337
|
+
end
|
338
|
+
end
|
339
|
+
end
|
340
|
+
|
341
|
+
describe '#memory' do
|
342
|
+
it 'will return an instance of DopCommon::Utils::DataSize if specified correctly' do
|
343
|
+
[nil, '500K', '500M', '10G', '500KB', '500MB', '10GB'].each do |memory|
|
344
|
+
node = DopCommon::Node.new(
|
345
|
+
'dummy',
|
346
|
+
{'infrastructure' => 'rhev', 'memory' => memory},
|
347
|
+
{:parsed_infrastructures => @infrastructures}
|
348
|
+
)
|
349
|
+
expect(node.memory).to be_an_instance_of(DopCommon::Utils::DataSize)
|
350
|
+
end
|
351
|
+
end
|
352
|
+
it "will return an instance of DopCommon::Utils::DataSize if not specified and the provider isn't openstack" do
|
353
|
+
node = DopCommon::Node.new(
|
354
|
+
'dummy',
|
355
|
+
{'infrastructure' => 'rhev'},
|
356
|
+
{:parsed_infrastructures => @infrastructures}
|
357
|
+
)
|
358
|
+
expect(node.memory).to be_an_instance_of(DopCommon::Utils::DataSize)
|
359
|
+
expect(node.memory.bytes).to eq DopCommon::Node::DEFAULT_MEMORY
|
360
|
+
end
|
361
|
+
it 'will return an instance of DopCommon::Utils::DataSize if appropriate flavor is specified' do
|
362
|
+
flavor = 'tiny'
|
363
|
+
node = DopCommon::Node.new(
|
364
|
+
'dummy',
|
365
|
+
{'infrastructure' => 'rhev', 'flavor' => flavor},
|
366
|
+
{:parsed_infrastructures => @infrastructures}
|
367
|
+
)
|
368
|
+
expect(node.memory).to be_an_instance_of(DopCommon::Utils::DataSize)
|
369
|
+
expect(node.memory.bytes).to eq DopCommon::Node::VALID_FLAVOR_TYPES[flavor.to_sym][:memory]
|
370
|
+
end
|
371
|
+
it 'will raise an exception if specified for openstack provider' do
|
372
|
+
node = DopCommon::Node.new(
|
373
|
+
'dummy',
|
374
|
+
{'infrastructure' => 'rhos', 'memory' => '1G'},
|
375
|
+
{:parsed_infrastructures => @infrastructures}
|
376
|
+
)
|
377
|
+
expect{node.memory}.to raise_error DopCommon::PlanParsingError
|
378
|
+
end
|
379
|
+
it 'will raise an exception in case of invalid input' do
|
380
|
+
[:invalid, 'invalid', '500g'].each do |memory|
|
381
|
+
node = DopCommon::Node.new(
|
382
|
+
'dummy',
|
383
|
+
{'infrastructure' => 'rhev', 'memory' => memory},
|
384
|
+
{:parsed_infrastructures => @infrastructures}
|
385
|
+
)
|
386
|
+
expect{node.memory.bytes}.to raise_error DopCommon::PlanParsingError
|
387
|
+
end
|
388
|
+
end
|
389
|
+
end
|
390
|
+
|
391
|
+
describe '#storage' do
|
392
|
+
it 'will return an instance of DopCommon::Utils::DataSize if specified correctly' do
|
393
|
+
[nil, '500K', '500M', '10G', '500KB', '500MB', '10GB'].each do |storage|
|
394
|
+
node = DopCommon::Node.new(
|
395
|
+
'dummy',
|
396
|
+
{'infrastructure' => 'rhev', 'storage' => storage},
|
397
|
+
{:parsed_infrastructures => @infrastructures}
|
398
|
+
)
|
399
|
+
expect(node.storage).to be_an_instance_of(DopCommon::Utils::DataSize)
|
400
|
+
end
|
401
|
+
end
|
402
|
+
it "will return an instance of DopCommon::Utils::DataSize if not specified and the provider isn't openstack" do
|
403
|
+
node = DopCommon::Node.new(
|
404
|
+
'dummy',
|
405
|
+
{'infrastructure' => 'rhev'},
|
406
|
+
{:parsed_infrastructures => @infrastructures}
|
407
|
+
)
|
408
|
+
expect(node.storage).to be_an_instance_of(DopCommon::Utils::DataSize)
|
409
|
+
expect(node.storage.bytes).to eq DopCommon::Node::DEFAULT_STORAGE
|
410
|
+
end
|
411
|
+
it 'will return an instance of DopCommon::Utils::DataSize if appropriate flavor is specified' do
|
412
|
+
flavor = 'tiny'
|
413
|
+
node = DopCommon::Node.new(
|
414
|
+
'dummy',
|
415
|
+
{'infrastructure' => 'rhev', 'flavor' => flavor},
|
416
|
+
{:parsed_infrastructures => @infrastructures}
|
417
|
+
)
|
418
|
+
expect(node.storage).to be_an_instance_of(DopCommon::Utils::DataSize)
|
419
|
+
expect(node.storage.bytes).to eq DopCommon::Node::VALID_FLAVOR_TYPES[flavor.to_sym][:storage]
|
420
|
+
end
|
421
|
+
it 'will raise an exception if specified for openstack provider' do
|
422
|
+
node = DopCommon::Node.new(
|
423
|
+
'dummy',
|
424
|
+
{'infrastructure' => 'rhos', 'storage' => '1G'},
|
425
|
+
{:parsed_infrastructures => @infrastructures}
|
426
|
+
)
|
427
|
+
expect{node.storage}.to raise_error DopCommon::PlanParsingError
|
428
|
+
end
|
429
|
+
it 'will raise an exception in case of invalid input' do
|
430
|
+
[:invalid, 'invalid', '500g'].each do |storage|
|
431
|
+
node = DopCommon::Node.new(
|
432
|
+
'dummy',
|
433
|
+
{'infrastructure' => 'rhev', 'storage' => storage},
|
434
|
+
{:parsed_infrastructures => @infrastructures}
|
435
|
+
)
|
436
|
+
expect{node.storage.bytes}.to raise_error DopCommon::PlanParsingError
|
437
|
+
end
|
438
|
+
end
|
439
|
+
end
|
440
|
+
|
441
|
+
describe '#timezone' do
|
442
|
+
it "will return a parsed 'timezone' property" do
|
443
|
+
{'rhev' => nil, 'vsphere' => '095'}.each do |infrastructure, property_val|
|
444
|
+
node = DopCommon::Node.new(
|
445
|
+
'dummy',
|
446
|
+
{'infrastructure' => infrastructure, 'timezone' => property_val },
|
447
|
+
{:parsed_infrastructures => @infrastructures}
|
448
|
+
)
|
449
|
+
expect(node.timezone).to eq property_val
|
450
|
+
end
|
451
|
+
end
|
452
|
+
|
453
|
+
it 'will trow an error if input timezone is invalid' do
|
454
|
+
[nil, "", :invalid, []].each do |property_val|
|
455
|
+
node = DopCommon::Node.new(
|
456
|
+
'dummy',
|
457
|
+
{'infrastructure' => 'vsphere', 'timezone' => property_val},
|
458
|
+
{:parsed_infrastructures => @infrastructures}
|
459
|
+
)
|
460
|
+
expect{node.timezone}.to raise_error DopCommon::PlanParsingError
|
461
|
+
end
|
462
|
+
end
|
463
|
+
end
|
464
|
+
|
465
|
+
%w(product_id organization_name).each do |property_name|
|
466
|
+
describe "##{property_name}" do
|
467
|
+
it "will return a parsed '#{property_name}' property" do
|
468
|
+
["", nil, "a74230-f3485-84"].each do |property_val|
|
469
|
+
next if property_name == "organization_name" && property_val == ""
|
470
|
+
node = DopCommon::Node.new(
|
471
|
+
'dummy',
|
472
|
+
{'infrastructure' => 'vsphere', property_name => property_val }
|
473
|
+
)
|
474
|
+
expect(node.send(property_name.to_sym)).to eq property_val
|
475
|
+
end
|
476
|
+
end
|
477
|
+
|
478
|
+
it "will trow an error if #{property_name} format is invalid" do
|
479
|
+
["", :invalid, []].each do |property_val|
|
480
|
+
next if property_name == "product_id" && property_val == ""
|
481
|
+
node = DopCommon::Node.new(
|
482
|
+
'dummy',
|
483
|
+
{'infrastructure' => 'vsphere', property_name => property_val}
|
484
|
+
)
|
485
|
+
expect{node.send(property_name.to_sym)}.to raise_error DopCommon::PlanParsingError
|
486
|
+
end
|
487
|
+
end
|
488
|
+
end
|
489
|
+
end
|
490
|
+
|
491
|
+
describe '#credentials' do
|
492
|
+
before :all do
|
493
|
+
@credentials = {
|
494
|
+
'test_up' => DopCommon::Credential.new('test_up', {
|
495
|
+
:type => 'username_password',
|
496
|
+
:username => 'alice',
|
497
|
+
:password => 'abc123',
|
498
|
+
}),
|
499
|
+
'test_ssh' => DopCommon::Credential.new('test_ssh', {
|
500
|
+
:type => 'ssh_key',
|
501
|
+
:username => 'bob',
|
502
|
+
:public_key => 'spec/fixtures/example_ssh_key.pub',
|
503
|
+
}),
|
504
|
+
'test_ssh2' => DopCommon::Credential.new('test_ssh2', {
|
505
|
+
:type => 'ssh_key',
|
506
|
+
:username => 'bob',
|
507
|
+
:private_key => 'spec/fixtures/example_ssh_key',
|
508
|
+
}),
|
509
|
+
}
|
510
|
+
end
|
511
|
+
|
512
|
+
it 'returns an empty array if nothing is defined' do
|
513
|
+
node = DopCommon::Node.new('dummy',{:parsed_credentials => @credentials })
|
514
|
+
expect(node.credentials).to be_an Array
|
515
|
+
expect(node.credentials.empty?).to be true
|
516
|
+
end
|
517
|
+
|
518
|
+
it 'returns an array if a credential if properly defined as a string' do
|
519
|
+
node = DopCommon::Node.new('dummy',
|
520
|
+
{:credentials => 'test_up'},
|
521
|
+
{:parsed_credentials => @credentials }
|
522
|
+
)
|
523
|
+
expect(node).to have_exactly(1).credentials
|
524
|
+
expect(node.credentials.all?{|c| c.kind_of?(DopCommon::Credential)}).to be true
|
525
|
+
end
|
526
|
+
|
527
|
+
it 'returns an array if an array of credentials if properly defined' do
|
528
|
+
node = DopCommon::Node.new('dummy',
|
529
|
+
{:credentials => ['test_up', 'test_ssh']},
|
530
|
+
{:parsed_credentials => @credentials }
|
531
|
+
)
|
532
|
+
expect(node).to have_exactly(2).credentials
|
533
|
+
expect(node.credentials.all?{|c| c.kind_of?(DopCommon::Credential)}).to be true
|
534
|
+
end
|
535
|
+
|
536
|
+
it 'will throw an error if credentials is not an array or string' do
|
537
|
+
node = DopCommon::Node.new('dummy',
|
538
|
+
{:credentials => 1},
|
539
|
+
{:parsed_credentials => @credentials }
|
540
|
+
)
|
541
|
+
expect{node.credentials}.to raise_error DopCommon::PlanParsingError
|
542
|
+
node = DopCommon::Node.new('dummy',
|
543
|
+
{:credentials => ['test_up', 1]},
|
544
|
+
{:parsed_credentials => @credentials }
|
545
|
+
)
|
546
|
+
expect{node.credentials}.to raise_error DopCommon::PlanParsingError
|
547
|
+
end
|
548
|
+
|
549
|
+
it 'will throw an error if a node includes a ssh_key credential without public_key' do
|
550
|
+
node = DopCommon::Node.new('dummy',
|
551
|
+
{:credentials => ['test_up', 'test_ssh2']},
|
552
|
+
{:parsed_credentials => @credentials }
|
553
|
+
)
|
554
|
+
expect{node.credentials}.to raise_error DopCommon::PlanParsingError
|
555
|
+
end
|
556
|
+
|
557
|
+
end
|
558
|
+
|
559
|
+
describe '#dns' do
|
560
|
+
#before :all do
|
561
|
+
# @dns = {
|
562
|
+
# 'valid_name_server' => { 'name_servers' => ['10.0.2.1'] }
|
563
|
+
# 'valid_search_domain' => { 'search_domains' => ['foo.bar'] }
|
564
|
+
# 'valid_dns' => { 'name_servers' => ['10.0.2.1', '172.16.0.1']
|
565
|
+
# }
|
566
|
+
#end
|
567
|
+
it 'returns a dns object if properly defined' do
|
568
|
+
[{}, {:dns => {:name_servers => ['10.0.1.1'], :search_domains => ['foo.bar']}}].each do |dns|
|
569
|
+
node = DopCommon::Node.new('dummy', dns)
|
570
|
+
expect(node.dns).to be_an_instance_of DopCommon::DNS
|
571
|
+
end
|
572
|
+
end
|
573
|
+
|
574
|
+
it "will throw an exception if dns object isn't properly defined" do
|
575
|
+
[{:dns => 'invalid'}, {:dns => nil}, {:dns => []}].each do |dns|
|
576
|
+
node = DopCommon::Node.new('dummy', dns)
|
577
|
+
expect{node.dns}.to raise_error DopCommon::PlanParsingError
|
578
|
+
end
|
579
|
+
end
|
580
|
+
end
|
581
|
+
|
582
|
+
describe '#data_disks' do
|
583
|
+
it 'returns an empty array if nothing is defined' do
|
584
|
+
node = DopCommon::Node.new('dummy', {:parsed_infrastructures => @infrastructures})
|
585
|
+
expect(node.data_disks).to be_an Array
|
586
|
+
expect(node.data_disks.empty?).to be true
|
587
|
+
end
|
588
|
+
|
589
|
+
it 'returns a list of data disk objects if properly defined' do
|
590
|
+
node = DopCommon::Node.new(
|
591
|
+
'dummy',
|
592
|
+
{
|
593
|
+
'infrastructure' => 'rhev',
|
594
|
+
'infrastructure_properties' => {'default_pool' => 'test4'},
|
595
|
+
'disks' => {
|
596
|
+
'd1' => {'pool' => 'test1', 'size' => '1024M', 'thin' => true},
|
597
|
+
'd2' => {'pool' => 'test2', 'size' => '1024G', 'thin' => false},
|
598
|
+
'd3' => {'pool' => 'test3', 'size' => '1024K'},
|
599
|
+
'd4' => {'size' => '1024K'}
|
600
|
+
}
|
601
|
+
},
|
602
|
+
{:parsed_infrastructures => @infrastructures}
|
603
|
+
)
|
604
|
+
expect(node).to have_exactly(4).data_disks
|
605
|
+
expect(node.data_disks.all?{|d| d.kind_of?(DopCommon::DataDisk)}).to be true
|
606
|
+
end
|
607
|
+
|
608
|
+
it 'will throw an error if a data disk specification is invalid' do
|
609
|
+
[nil, :invalid, [], {'d1' => nil}, {'d1' => :invalid}].each do |disks|
|
610
|
+
node = DopCommon::Node.new(
|
611
|
+
'dummy',
|
612
|
+
{
|
613
|
+
:infrastructure => 'rhev',
|
614
|
+
:infrastructure_properties => {'datacenter' => 'test'},
|
615
|
+
:disks => disks
|
616
|
+
},
|
617
|
+
{:parsed_infrastructures => @infrastructures}
|
618
|
+
)
|
619
|
+
expect{node.data_disks}.to raise_error DopCommon::PlanParsingError
|
620
|
+
end
|
621
|
+
end
|
622
|
+
end
|
623
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DopCommon::PlanCache do
|
4
|
+
|
5
|
+
before :each do
|
6
|
+
@tmpdir = Dir.mktmpdir
|
7
|
+
@plan_store = DopCommon::PlanStore.new(@tmpdir)
|
8
|
+
@plan_cache = DopCommon::PlanCache.new(@plan_store)
|
9
|
+
@plan_store.add(plan)
|
10
|
+
end
|
11
|
+
|
12
|
+
after :each do
|
13
|
+
FileUtils.remove_entry_secure(@tmpdir)
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:plan) { 'spec/fixtures/simple_plan.yaml' }
|
17
|
+
let(:plan_name) { 'simple_plan' }
|
18
|
+
let(:plan_dir) { File.join(@tmpdir, plan_name) }
|
19
|
+
let(:versions_dir) { File.join(plan_dir, 'versions') }
|
20
|
+
let(:node_name) { 'linux01.example.com' }
|
21
|
+
|
22
|
+
describe '#plan_by_node' do
|
23
|
+
before :each do
|
24
|
+
@original_plan = @plan_cache.plan_by_node(node_name)
|
25
|
+
end
|
26
|
+
subject { @plan_cache.plan_by_node(node_name) }
|
27
|
+
|
28
|
+
context 'The plan in the store is unchanged' do
|
29
|
+
it { is_expected.to be_a(DopCommon::Plan) }
|
30
|
+
it { is_expected.to equal(@original_plan) }
|
31
|
+
end
|
32
|
+
context 'The plan in the store was updated' do
|
33
|
+
before do
|
34
|
+
@plan_store.update(plan)
|
35
|
+
end
|
36
|
+
it { is_expected.to be_a(DopCommon::Plan) }
|
37
|
+
it { is_expected.to_not equal(@original_plan) }
|
38
|
+
end
|
39
|
+
context 'There is no plan with this node' do
|
40
|
+
let(:node_name) { 'nonexisting.example.com' }
|
41
|
+
it { is_expected.to be(nil) }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|