foreman_ovirt 2.0.2 → 2.0.4
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 +4 -4
- data/Rakefile +2 -17
- data/app/assets/javascripts/foreman_ovirt/ovirt.js +37 -8
- data/app/controllers/concerns/foreman_ovirt/api_compute_resources_controller_extension.rb +42 -0
- data/app/controllers/concerns/foreman_ovirt/compute_resources_vms_controller.rb +3 -1
- data/app/controllers/concerns/foreman_ovirt/parameters_extension.rb +5 -5
- data/app/controllers/foreman_ovirt/concerns/compute_resources_controller_extensions.rb +12 -3
- data/app/helpers/ovirt_compute_resource_helper.rb +18 -4
- data/app/models/concerns/fog_extensions/ovirt/server.rb +13 -4
- data/app/models/concerns/fog_extensions/ovirt/template.rb +3 -1
- data/app/models/concerns/fog_extensions/ovirt/volume.rb +3 -1
- data/app/models/foreman_ovirt/ovirt.rb +167 -142
- data/app/views/api/v2/compute_resources/ovirt.json.rabl +2 -0
- data/config/routes.rb +8 -5
- data/db/migrate/20250810212811_update_legacy_ovirt_compute_resource_type.rb +5 -3
- data/lib/foreman_ovirt/engine.rb +8 -5
- data/lib/foreman_ovirt/version.rb +3 -1
- data/lib/foreman_ovirt.rb +2 -0
- data/lib/tasks/foreman_ovirt_tasks.rake +37 -22
- data/locale/gemspec.rb +3 -1
- data/package.json +1 -0
- data/test/controllers/api/v2/compute_resources_controller_test.rb +186 -0
- data/test/controllers/hosts_controller_test.rb +46 -0
- data/test/factories/foreman_ovirt_factories.rb +27 -2
- data/test/fixtures/ovirt_operating_systems.xml +243 -0
- data/test/graphql/types/provider_enum_test.rb +12 -0
- data/test/integration/compute_profile_js_test.rb +49 -0
- data/test/models/compute_resources/compute_resource_test_helpers.rb +143 -0
- data/test/models/compute_resources/ovirt_test.rb +687 -0
- data/test/models/ovirt_volume_test.rb +104 -0
- data/test/test_plugin_helper.rb +2 -0
- data/test/unit/compute_resource_host_importer_test.rb +48 -0
- data/test/unit/ovirt_connection_test.rb +123 -0
- data/webpack/components/__tests__/ovirt.test.js +17 -0
- data/webpack/components/extensions/HostDetails/DetailsTabCards/OvirtCard.js +40 -38
- data/webpack/global_index.js +0 -2
- data/webpack/global_test_setup.js +3 -3
- data/webpack/index.js +0 -1
- metadata +26 -8
- data/test/unit/foreman_ovirt_test.rb +0 -11
|
@@ -0,0 +1,687 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'test_plugin_helper'
|
|
4
|
+
require 'models/compute_resources/compute_resource_test_helpers'
|
|
5
|
+
|
|
6
|
+
module ForemanOvirt
|
|
7
|
+
class OvirtTest < ActiveSupport::TestCase
|
|
8
|
+
def setup
|
|
9
|
+
@klass = ForemanOvirt::Ovirt
|
|
10
|
+
end
|
|
11
|
+
include ComputeResourceTestHelpers
|
|
12
|
+
|
|
13
|
+
should validate_presence_of(:url)
|
|
14
|
+
should validate_presence_of(:user)
|
|
15
|
+
should validate_presence_of(:password)
|
|
16
|
+
should allow_values(
|
|
17
|
+
'http://foo.com', 'http://bar.com/baz'
|
|
18
|
+
).for(:url)
|
|
19
|
+
should_not allow_values(
|
|
20
|
+
'ftp://foo.com', 'buz'
|
|
21
|
+
).for(:url)
|
|
22
|
+
|
|
23
|
+
test '#associated_host matches any NIC' do
|
|
24
|
+
host = FactoryBot.create(
|
|
25
|
+
:host, mac: 'ca:d0:e6:32:16:97'
|
|
26
|
+
)
|
|
27
|
+
cr = FactoryBot.build_stubbed(:ovirt_cr)
|
|
28
|
+
iface1 = mock(
|
|
29
|
+
'iface1', mac: '36:48:c5:c9:86:f2'
|
|
30
|
+
)
|
|
31
|
+
iface2 = mock(
|
|
32
|
+
'iface2', mac: 'ca:d0:e6:32:16:97'
|
|
33
|
+
)
|
|
34
|
+
vm = mock(
|
|
35
|
+
'vm', interfaces: [
|
|
36
|
+
iface1, iface2
|
|
37
|
+
]
|
|
38
|
+
)
|
|
39
|
+
assert_equal(host, as_admin do
|
|
40
|
+
cr.associated_host(vm)
|
|
41
|
+
end)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
test '#associated_host matches NIC mac with uppercase letters' do
|
|
45
|
+
host = FactoryBot.create(
|
|
46
|
+
:host, mac: 'ca:d0:e6:32:16:97'
|
|
47
|
+
)
|
|
48
|
+
cr = FactoryBot.build_stubbed(:ovirt_cr)
|
|
49
|
+
iface1 = mock(
|
|
50
|
+
'iface1', mac: '36:48:c5:c9:86:f2'
|
|
51
|
+
)
|
|
52
|
+
iface2 = mock(
|
|
53
|
+
'iface2', mac: 'CA:D0:E6:32:16:97'
|
|
54
|
+
)
|
|
55
|
+
vm = mock(
|
|
56
|
+
'vm', interfaces: [
|
|
57
|
+
iface1, iface2
|
|
58
|
+
]
|
|
59
|
+
)
|
|
60
|
+
assert_equal(host, as_admin do
|
|
61
|
+
cr.associated_host(vm)
|
|
62
|
+
end)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
describe 'destroy_vm' do
|
|
66
|
+
it 'handles situation when vm is not present' do
|
|
67
|
+
cr = mock_cr_servers(
|
|
68
|
+
ForemanOvirt::Ovirt.new, empty_servers
|
|
69
|
+
)
|
|
70
|
+
cr.expects(:find_vm_by_uuid).raises(ActiveRecord::RecordNotFound)
|
|
71
|
+
assert cr.destroy_vm('abc')
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
describe 'find_vm_by_uuid' do
|
|
76
|
+
it 'raises RecordNotFound when the vm does not exist' do
|
|
77
|
+
cr = mock_cr_servers(
|
|
78
|
+
ForemanOvirt::Ovirt.new, empty_servers
|
|
79
|
+
)
|
|
80
|
+
assert_find_by_uuid_raises(
|
|
81
|
+
ActiveRecord::RecordNotFound, cr
|
|
82
|
+
)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
it 'raises RecordNotFound when the compute raises retrieve error' do
|
|
86
|
+
exception = Fog::Ovirt::Errors::OvirtEngineError.new(StandardError.new('VM not found'))
|
|
87
|
+
cr = mock_cr_servers(
|
|
88
|
+
ForemanOvirt::Ovirt.new, servers_raising_exception(exception)
|
|
89
|
+
)
|
|
90
|
+
assert_find_by_uuid_raises(
|
|
91
|
+
ActiveRecord::RecordNotFound, cr
|
|
92
|
+
)
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
describe 'associating operating system' do
|
|
97
|
+
require 'fog/ovirt/models/compute/operating_system'
|
|
98
|
+
|
|
99
|
+
setup do
|
|
100
|
+
# This calculates the path relative to this file, so it works everywhere (CI, local, etc.)
|
|
101
|
+
fixtures_path = ForemanOvirt::Engine.root.join('test', 'fixtures', 'ovirt_operating_systems.xml')
|
|
102
|
+
operating_systems_xml = Nokogiri::XML(File.read(fixtures_path))
|
|
103
|
+
@ovirt_oses = operating_systems_xml.xpath('/operating_systems/operating_system').map do |os|
|
|
104
|
+
Fog::Ovirt::Compute::OperatingSystem.new({
|
|
105
|
+
id: os[:id], name: (os / 'name').text, href: os[:href]
|
|
106
|
+
})
|
|
107
|
+
end
|
|
108
|
+
@os_hashes = @ovirt_oses.map do |ovirt_os|
|
|
109
|
+
{
|
|
110
|
+
id: ovirt_os.id, name: ovirt_os.name, href: ovirt_os.href
|
|
111
|
+
}
|
|
112
|
+
end
|
|
113
|
+
@compute_resource = FactoryBot.build(:ovirt_cr)
|
|
114
|
+
@compute_resource.attrs[:available_operating_systems] =
|
|
115
|
+
@os_hashes
|
|
116
|
+
@host = FactoryBot.build(
|
|
117
|
+
:host, mac: 'ca:d0:e6:32:16:97'
|
|
118
|
+
)
|
|
119
|
+
@quota = Fog::Ovirt::Compute::Quota.new({
|
|
120
|
+
id: '1', name: 'Default'
|
|
121
|
+
})
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
it 'maps operating system to ovirt operating systems' do
|
|
125
|
+
@compute_resource.stubs(:available_operating_systems).returns(@os_hashes)
|
|
126
|
+
assert_equal 'other_linux',
|
|
127
|
+
@compute_resource.determine_os_type(@host)
|
|
128
|
+
|
|
129
|
+
@host.operatingsystem = operatingsystems(:redhat)
|
|
130
|
+
assert_equal 'rhel_6',
|
|
131
|
+
@compute_resource.determine_os_type(@host)
|
|
132
|
+
|
|
133
|
+
@host.architecture = architectures(:x86_64) # rubocop:disable Naming/VariableNumber
|
|
134
|
+
assert_equal 'rhel_6x64',
|
|
135
|
+
@compute_resource.determine_os_type(@host)
|
|
136
|
+
|
|
137
|
+
@host.operatingsystem = operatingsystems(:ubuntu1210)
|
|
138
|
+
assert_equal 'ubuntu_12_10',
|
|
139
|
+
@compute_resource.determine_os_type(@host)
|
|
140
|
+
|
|
141
|
+
@host.operatingsystem = FactoryBot.create(:operatingsystem)
|
|
142
|
+
assert_equal 'other',
|
|
143
|
+
@compute_resource.determine_os_type(@host)
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
it 'respects host param ovirt_ostype' do
|
|
147
|
+
@compute_resource.stubs(:available_operating_systems).returns(@os_hashes)
|
|
148
|
+
@host.stubs(:params).returns({ 'ovirt_ostype' => 'some_os' })
|
|
149
|
+
assert_equal 'some_os',
|
|
150
|
+
@compute_resource.determine_os_type(@host)
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
it 'caches the operating systems in the compute resource' do
|
|
154
|
+
client_mock = mock.tap do |m|
|
|
155
|
+
m.stubs(:operating_systems).returns(@ovirt_oses)
|
|
156
|
+
end
|
|
157
|
+
@compute_resource.stubs(:client).returns(client_mock)
|
|
158
|
+
client_mock.stubs(:quotas).returns([@quota])
|
|
159
|
+
assert @compute_resource.supports_operating_systems?
|
|
160
|
+
assert_equal @os_hashes,
|
|
161
|
+
@compute_resource.available_operating_systems
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
it 'handles a case when the operating systems endpoint is missing' do
|
|
165
|
+
@compute_resource.attrs.delete(:available_operating_systems)
|
|
166
|
+
client_mock = mock.tap do |m|
|
|
167
|
+
m.stubs(:operating_systems).raises(
|
|
168
|
+
Fog::Ovirt::Errors::OvirtEngineError, StandardError.new('404')
|
|
169
|
+
)
|
|
170
|
+
end
|
|
171
|
+
@compute_resource.stubs(:client).returns(client_mock)
|
|
172
|
+
client_mock.stubs(:quotas).returns([@quota])
|
|
173
|
+
assert_not @compute_resource.supports_operating_systems?
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
describe 'APIv4 support' do
|
|
178
|
+
require 'fog/ovirt/models/compute/quota'
|
|
179
|
+
|
|
180
|
+
before do
|
|
181
|
+
@compute_resource = FactoryBot.build(:ovirt_cr)
|
|
182
|
+
@quota = Fog::Ovirt::Compute::Quota.new({
|
|
183
|
+
id: '1', name: 'Default'
|
|
184
|
+
})
|
|
185
|
+
@client_mock = mock.tap do |m|
|
|
186
|
+
m.stubs(
|
|
187
|
+
datacenters: [], quotas: [@quota]
|
|
188
|
+
)
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
it 'passes api_version v4 by default' do
|
|
193
|
+
Fog::Compute.expects(:new).with do |options|
|
|
194
|
+
assert_equal 'v4',
|
|
195
|
+
options[:api_version]
|
|
196
|
+
end.returns(@client_mock)
|
|
197
|
+
@compute_resource.send(:client)
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
describe 'quota validation and name-id substitution' do
|
|
202
|
+
require 'fog/ovirt/models/compute/quota'
|
|
203
|
+
|
|
204
|
+
before do
|
|
205
|
+
@compute_resource = FactoryBot.build(:ovirt_cr)
|
|
206
|
+
@quota = Fog::Ovirt::Compute::Quota.new({
|
|
207
|
+
id: '1', name: 'Default'
|
|
208
|
+
})
|
|
209
|
+
@client_mock = mock.tap do |m|
|
|
210
|
+
m.stubs(
|
|
211
|
+
datacenters: [], quotas: [@quota]
|
|
212
|
+
)
|
|
213
|
+
end
|
|
214
|
+
@compute_resource.stubs(:client).returns(@client_mock)
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
test 'quota validation - id entered' do
|
|
218
|
+
@compute_resource.ovirt_quota = '1'
|
|
219
|
+
assert_equal(
|
|
220
|
+
'1', @compute_resource.validate_quota
|
|
221
|
+
)
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
test 'quota validation - name entered' do
|
|
225
|
+
@compute_resource.ovirt_quota = 'Default'
|
|
226
|
+
assert_equal(
|
|
227
|
+
'1', @compute_resource.validate_quota
|
|
228
|
+
)
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
test 'quota validation - nothing entered' do
|
|
232
|
+
assert_equal(
|
|
233
|
+
'1', @compute_resource.validate_quota
|
|
234
|
+
)
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
test 'quota validation - name entered' do
|
|
238
|
+
@compute_resource.ovirt_quota = 'Default2'
|
|
239
|
+
assert_raise Foreman::Exception do
|
|
240
|
+
@compute_resource.validate_quota
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
describe 'name-id substitution for attributes: network, storage_domain and cluster' do
|
|
246
|
+
let(:cr) do
|
|
247
|
+
mock_cr(FactoryBot.build(:ovirt_cr),
|
|
248
|
+
clusters: [
|
|
249
|
+
stub(
|
|
250
|
+
id: 'c1', name: 'cluster 1'
|
|
251
|
+
),
|
|
252
|
+
stub(
|
|
253
|
+
id: 'c2', name: 'cluster 2'
|
|
254
|
+
),
|
|
255
|
+
],
|
|
256
|
+
networks: [
|
|
257
|
+
stub(
|
|
258
|
+
id: 'net1', name: 'network 1'
|
|
259
|
+
),
|
|
260
|
+
stub(
|
|
261
|
+
id: 'net2', name: 'network 2'
|
|
262
|
+
),
|
|
263
|
+
],
|
|
264
|
+
storage_domains: [
|
|
265
|
+
stub(
|
|
266
|
+
id: '312f6', name: 'domain 1'
|
|
267
|
+
),
|
|
268
|
+
stub(
|
|
269
|
+
id: '382ec', name: 'domain 2'
|
|
270
|
+
),
|
|
271
|
+
])
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
test 'cluster validation - id entered' do
|
|
275
|
+
assert_equal(
|
|
276
|
+
'c2', cr.get_ovirt_id(
|
|
277
|
+
cr.clusters, 'cluster', 'c2'
|
|
278
|
+
)
|
|
279
|
+
)
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
test 'cluster validation - name entered' do
|
|
283
|
+
assert_equal(
|
|
284
|
+
'c2', cr.get_ovirt_id(
|
|
285
|
+
cr.clusters, 'cluster', 'cluster 2'
|
|
286
|
+
)
|
|
287
|
+
)
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
test 'cluster validation - not valid' do
|
|
291
|
+
assert_raise Foreman::Exception do
|
|
292
|
+
cr.get_ovirt_id(
|
|
293
|
+
cr.clusters, 'cluster', 'c3'
|
|
294
|
+
)
|
|
295
|
+
end
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
test 'storage domain validation - id entered' do
|
|
299
|
+
assert_equal(
|
|
300
|
+
'312f6', cr.get_ovirt_id(
|
|
301
|
+
cr.storage_domains, 'storage domain', '312f6'
|
|
302
|
+
)
|
|
303
|
+
)
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
test 'storage domain validation - name entered' do
|
|
307
|
+
assert_equal(
|
|
308
|
+
'382ec', cr.get_ovirt_id(
|
|
309
|
+
cr.storage_domains, 'storage domain', 'domain 2'
|
|
310
|
+
)
|
|
311
|
+
)
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
test 'storage domain validation - not valid' do
|
|
315
|
+
assert_raise Foreman::Exception do
|
|
316
|
+
cr.get_ovirt_id(
|
|
317
|
+
cr.storage_domains, 'storage domain', 'domain 3'
|
|
318
|
+
)
|
|
319
|
+
end
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
test 'network validation - id entered' do
|
|
323
|
+
assert_equal(
|
|
324
|
+
'net1', cr.get_ovirt_id(
|
|
325
|
+
cr.networks, 'network', 'net1'
|
|
326
|
+
)
|
|
327
|
+
)
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
test 'network validation - name entered' do
|
|
331
|
+
assert_equal(
|
|
332
|
+
'net2', cr.get_ovirt_id(
|
|
333
|
+
cr.networks, 'network', 'network 2'
|
|
334
|
+
)
|
|
335
|
+
)
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
test 'network validation - not valid' do
|
|
339
|
+
assert_raise Foreman::Exception do
|
|
340
|
+
cr.get_ovirt_id(
|
|
341
|
+
cr.networks, 'network', 'network 3'
|
|
342
|
+
)
|
|
343
|
+
end
|
|
344
|
+
end
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
describe '#normalize_vm_attrs' do
|
|
348
|
+
let(:cr) do
|
|
349
|
+
mock_cr(FactoryBot.build(:ovirt_cr),
|
|
350
|
+
clusters: [
|
|
351
|
+
stub(
|
|
352
|
+
id: 'c1', name: 'cluster 1'
|
|
353
|
+
),
|
|
354
|
+
stub(
|
|
355
|
+
id: 'c2', name: 'cluster 2'
|
|
356
|
+
),
|
|
357
|
+
],
|
|
358
|
+
templates: [
|
|
359
|
+
stub(
|
|
360
|
+
id: 'tpl1', name: 'template 1'
|
|
361
|
+
),
|
|
362
|
+
stub(
|
|
363
|
+
id: 'tpl2', name: 'template 2'
|
|
364
|
+
),
|
|
365
|
+
],
|
|
366
|
+
networks: [
|
|
367
|
+
stub(
|
|
368
|
+
id: 'net1', name: 'network 1'
|
|
369
|
+
),
|
|
370
|
+
stub(
|
|
371
|
+
id: 'net2', name: 'network 2'
|
|
372
|
+
),
|
|
373
|
+
],
|
|
374
|
+
storage_domains: [
|
|
375
|
+
stub(
|
|
376
|
+
id: '312f6', name: 'domain 1'
|
|
377
|
+
),
|
|
378
|
+
stub(
|
|
379
|
+
id: '382ec', name: 'domain 2'
|
|
380
|
+
),
|
|
381
|
+
stub(
|
|
382
|
+
id: '3ea4f', name: 'domain 3'
|
|
383
|
+
),
|
|
384
|
+
])
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
test 'maps cluster to cluster_id' do
|
|
388
|
+
vm_attrs = {
|
|
389
|
+
'cluster' => 'cluster 1',
|
|
390
|
+
}
|
|
391
|
+
normalized = cr.normalize_vm_attrs(vm_attrs)
|
|
392
|
+
|
|
393
|
+
assert_not(normalized.key?('cluster'))
|
|
394
|
+
assert_equal(
|
|
395
|
+
'c1', normalized['cluster_id']
|
|
396
|
+
)
|
|
397
|
+
end
|
|
398
|
+
|
|
399
|
+
test 'finds cluster_name' do
|
|
400
|
+
vm_attrs = {
|
|
401
|
+
'cluster' => 'c2',
|
|
402
|
+
}
|
|
403
|
+
normalized = cr.normalize_vm_attrs(vm_attrs)
|
|
404
|
+
|
|
405
|
+
assert_equal(
|
|
406
|
+
'cluster 2', normalized['cluster_name']
|
|
407
|
+
)
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
test 'maps template to template_id' do
|
|
411
|
+
vm_attrs = {
|
|
412
|
+
'template' => 'template 1',
|
|
413
|
+
}
|
|
414
|
+
normalized = cr.normalize_vm_attrs(vm_attrs)
|
|
415
|
+
|
|
416
|
+
assert_not(normalized.key?('template'))
|
|
417
|
+
assert_equal(
|
|
418
|
+
'tpl1', normalized['template_id']
|
|
419
|
+
)
|
|
420
|
+
end
|
|
421
|
+
|
|
422
|
+
test 'finds template_name' do
|
|
423
|
+
vm_attrs = {
|
|
424
|
+
'template' => 'tpl2',
|
|
425
|
+
}
|
|
426
|
+
normalized = cr.normalize_vm_attrs(vm_attrs)
|
|
427
|
+
|
|
428
|
+
assert_equal(
|
|
429
|
+
'template 2', normalized['template_name']
|
|
430
|
+
)
|
|
431
|
+
end
|
|
432
|
+
|
|
433
|
+
test 'normalizes interfaces_attributes' do
|
|
434
|
+
vm_attrs = {
|
|
435
|
+
'interfaces_attributes' => {
|
|
436
|
+
'0' => {
|
|
437
|
+
'name' => 'eth0',
|
|
438
|
+
'network' => 'net1',
|
|
439
|
+
},
|
|
440
|
+
'1' => {
|
|
441
|
+
'name' => 'eth1',
|
|
442
|
+
'network' => 'net2',
|
|
443
|
+
},
|
|
444
|
+
},
|
|
445
|
+
}
|
|
446
|
+
expected_attrs = {
|
|
447
|
+
'0' => {
|
|
448
|
+
'network_id' => 'net1',
|
|
449
|
+
'network_name' => 'network 1',
|
|
450
|
+
'name' => 'eth0',
|
|
451
|
+
},
|
|
452
|
+
'1' => {
|
|
453
|
+
'network_id' => 'net2',
|
|
454
|
+
'network_name' => 'network 2',
|
|
455
|
+
'name' => 'eth1',
|
|
456
|
+
},
|
|
457
|
+
}
|
|
458
|
+
normalized = cr.normalize_vm_attrs(vm_attrs)
|
|
459
|
+
|
|
460
|
+
assert_equal(
|
|
461
|
+
expected_attrs, normalized['interfaces_attributes']
|
|
462
|
+
)
|
|
463
|
+
end
|
|
464
|
+
|
|
465
|
+
test 'normalizes volumes_attributes' do
|
|
466
|
+
vm_attrs = {
|
|
467
|
+
'volumes_attributes' => {
|
|
468
|
+
'0' => {
|
|
469
|
+
'size_gb' => '15',
|
|
470
|
+
'storage_domain' => '312f6',
|
|
471
|
+
'id' => '',
|
|
472
|
+
'preallocate' => '0',
|
|
473
|
+
},
|
|
474
|
+
'1' => {
|
|
475
|
+
'size_gb' => '5',
|
|
476
|
+
'storage_domain' => '382ec',
|
|
477
|
+
'id' => '',
|
|
478
|
+
'preallocate' => '1',
|
|
479
|
+
'bootable' => 'true',
|
|
480
|
+
},
|
|
481
|
+
},
|
|
482
|
+
}
|
|
483
|
+
expected_attrs = {
|
|
484
|
+
'0' => {
|
|
485
|
+
'size' => 15.gigabyte.to_s,
|
|
486
|
+
'storage_domain_id' => '312f6',
|
|
487
|
+
'storage_domain_name' => 'domain 1',
|
|
488
|
+
'preallocate' => false,
|
|
489
|
+
'bootable' => nil,
|
|
490
|
+
},
|
|
491
|
+
'1' => {
|
|
492
|
+
'size' => 5.gigabyte.to_s,
|
|
493
|
+
'storage_domain_id' => '382ec',
|
|
494
|
+
'storage_domain_name' => 'domain 2',
|
|
495
|
+
'preallocate' => true,
|
|
496
|
+
'bootable' => true,
|
|
497
|
+
},
|
|
498
|
+
}
|
|
499
|
+
normalized = cr.normalize_vm_attrs(vm_attrs)
|
|
500
|
+
|
|
501
|
+
assert_equal(
|
|
502
|
+
expected_attrs, normalized['volumes_attributes']
|
|
503
|
+
)
|
|
504
|
+
end
|
|
505
|
+
|
|
506
|
+
test 'correctly fills empty attributes' do
|
|
507
|
+
normalized = cr.normalize_vm_attrs({})
|
|
508
|
+
expected_attrs = {
|
|
509
|
+
'cores' => nil,
|
|
510
|
+
'memory' => nil,
|
|
511
|
+
'cluster_id' => nil,
|
|
512
|
+
'cluster_name' => nil,
|
|
513
|
+
'template_id' => nil,
|
|
514
|
+
'template_name' => nil,
|
|
515
|
+
'interfaces_attributes' => {},
|
|
516
|
+
'volumes_attributes' => {},
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
assert_equal(
|
|
520
|
+
expected_attrs.keys.sort, normalized.keys.sort
|
|
521
|
+
)
|
|
522
|
+
assert_equal(
|
|
523
|
+
expected_attrs, normalized
|
|
524
|
+
)
|
|
525
|
+
end
|
|
526
|
+
|
|
527
|
+
test 'attribute names' do
|
|
528
|
+
check_vm_attribute_names(cr)
|
|
529
|
+
end
|
|
530
|
+
end
|
|
531
|
+
|
|
532
|
+
describe '#display_type' do
|
|
533
|
+
let(:cr) do
|
|
534
|
+
FactoryBot.build_stubbed(:ovirt_cr)
|
|
535
|
+
end
|
|
536
|
+
|
|
537
|
+
test "default display type is 'vnc'" do
|
|
538
|
+
assert_nil cr.attrs[:display]
|
|
539
|
+
assert_equal 'vnc',
|
|
540
|
+
cr.display_type
|
|
541
|
+
end
|
|
542
|
+
|
|
543
|
+
test 'display type can be set' do
|
|
544
|
+
expected = 'spice'
|
|
545
|
+
cr.display_type = 'Spice'
|
|
546
|
+
assert_equal expected,
|
|
547
|
+
cr.attrs[:display]
|
|
548
|
+
assert_equal expected,
|
|
549
|
+
cr.display_type
|
|
550
|
+
assert cr.valid?
|
|
551
|
+
end
|
|
552
|
+
|
|
553
|
+
test "don't allow wrong display type to be set" do
|
|
554
|
+
cr.display_type = 'teletype'
|
|
555
|
+
assert_not cr.valid?
|
|
556
|
+
end
|
|
557
|
+
end
|
|
558
|
+
|
|
559
|
+
describe '#keyboard_layout' do
|
|
560
|
+
let(:cr) do
|
|
561
|
+
FactoryBot.build_stubbed(:ovirt_cr)
|
|
562
|
+
end
|
|
563
|
+
|
|
564
|
+
test "default keyboard layout is 'en-us'" do
|
|
565
|
+
assert_nil cr.attrs[:keyboard_layout]
|
|
566
|
+
assert_equal 'en-us',
|
|
567
|
+
cr.keyboard_layout
|
|
568
|
+
end
|
|
569
|
+
|
|
570
|
+
test 'keyboard layout can be set' do
|
|
571
|
+
expected = 'hu'
|
|
572
|
+
cr.keyboard_layout = 'hu'
|
|
573
|
+
assert_equal expected,
|
|
574
|
+
cr.attrs[:keyboard_layout]
|
|
575
|
+
assert_equal expected,
|
|
576
|
+
cr.keyboard_layout
|
|
577
|
+
assert cr.valid?
|
|
578
|
+
end
|
|
579
|
+
|
|
580
|
+
test "don't allow wrong keyboard layout to be set" do
|
|
581
|
+
cr.keyboard_layout = 'fake-layout'
|
|
582
|
+
assert_not cr.valid?
|
|
583
|
+
end
|
|
584
|
+
end
|
|
585
|
+
|
|
586
|
+
describe '#vm_compute_attributes_for' do
|
|
587
|
+
require 'fog/ovirt/models/compute/volume'
|
|
588
|
+
|
|
589
|
+
before do
|
|
590
|
+
@plain_attrs = {
|
|
591
|
+
id: 'abc',
|
|
592
|
+
cpus: 5,
|
|
593
|
+
}
|
|
594
|
+
@vm = mock
|
|
595
|
+
@vm.stubs(:attributes).returns(@plain_attrs)
|
|
596
|
+
|
|
597
|
+
@cr = FactoryBot.build(:ovirt_cr)
|
|
598
|
+
@cr.stubs(:find_vm_by_uuid).returns(@vm)
|
|
599
|
+
end
|
|
600
|
+
|
|
601
|
+
test 'returns vm attributes with oVirt-specific volume attributes' do
|
|
602
|
+
# oVirt uses different volume attributes than libvirt
|
|
603
|
+
volume1 = Fog::Ovirt::Compute::Volume.new(
|
|
604
|
+
storage_domain: 'storage1',
|
|
605
|
+
size_gb: '1',
|
|
606
|
+
bootable: 'false',
|
|
607
|
+
sparse: 'true',
|
|
608
|
+
wipe_after_delete: 'true',
|
|
609
|
+
name: 'disk1'
|
|
610
|
+
)
|
|
611
|
+
volume2 = Fog::Ovirt::Compute::Volume.new(
|
|
612
|
+
storage_domain: 'storage2',
|
|
613
|
+
size_gb: '2',
|
|
614
|
+
bootable: 'false',
|
|
615
|
+
sparse: 'true',
|
|
616
|
+
wipe_after_delete: 'true',
|
|
617
|
+
name: 'disk2'
|
|
618
|
+
)
|
|
619
|
+
|
|
620
|
+
@vm.stubs(:volumes).returns([volume1, volume2])
|
|
621
|
+
|
|
622
|
+
expected_attrs = {
|
|
623
|
+
cpus: 5,
|
|
624
|
+
volumes_attributes: {
|
|
625
|
+
'0' => {
|
|
626
|
+
size_gb: '1',
|
|
627
|
+
storage_domain: 'storage1',
|
|
628
|
+
preallocate: '0',
|
|
629
|
+
wipe_after_delete: 'true',
|
|
630
|
+
interface: nil,
|
|
631
|
+
bootable: 'false',
|
|
632
|
+
id: nil,
|
|
633
|
+
},
|
|
634
|
+
'1' => {
|
|
635
|
+
size_gb: '2',
|
|
636
|
+
storage_domain: 'storage2',
|
|
637
|
+
preallocate: '0',
|
|
638
|
+
wipe_after_delete: 'true',
|
|
639
|
+
interface: nil,
|
|
640
|
+
bootable: 'false',
|
|
641
|
+
id: nil,
|
|
642
|
+
},
|
|
643
|
+
},
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
attrs = @cr.vm_compute_attributes_for('abc')
|
|
647
|
+
assert_equal expected_attrs, attrs
|
|
648
|
+
end
|
|
649
|
+
|
|
650
|
+
test 'handles oVirt volumes with bootable flag' do
|
|
651
|
+
volume1 = Fog::Ovirt::Compute::Volume.new(
|
|
652
|
+
storage_domain: 'storage1',
|
|
653
|
+
size_gb: '1',
|
|
654
|
+
bootable: 'true',
|
|
655
|
+
sparse: 'true',
|
|
656
|
+
wipe_after_delete: 'false',
|
|
657
|
+
name: 'boot_disk'
|
|
658
|
+
)
|
|
659
|
+
|
|
660
|
+
@vm.stubs(:volumes).returns([volume1])
|
|
661
|
+
|
|
662
|
+
attrs = @cr.vm_compute_attributes_for('abc')
|
|
663
|
+
assert_equal 'true', attrs[:volumes_attributes]['0'][:bootable]
|
|
664
|
+
assert_equal 'false', attrs[:volumes_attributes]['0'][:wipe_after_delete]
|
|
665
|
+
end
|
|
666
|
+
end
|
|
667
|
+
|
|
668
|
+
describe '#get_datacenter_uuid' do
|
|
669
|
+
test 'resolves datacenter name from datacenters list' do
|
|
670
|
+
uuid = Foreman.uuid
|
|
671
|
+
cr = FactoryBot.build(:ovirt_cr)
|
|
672
|
+
cr.stubs(:datacenters).returns([
|
|
673
|
+
['prod', uuid],
|
|
674
|
+
['dev', Foreman.uuid],
|
|
675
|
+
])
|
|
676
|
+
assert_equal uuid, cr.get_datacenter_uuid('prod')
|
|
677
|
+
end
|
|
678
|
+
|
|
679
|
+
test 'raises when datacenter is unknown' do
|
|
680
|
+
cr = FactoryBot.build(:ovirt_cr)
|
|
681
|
+
cr.stubs(:datacenters).returns([['dev', Foreman.uuid]])
|
|
682
|
+
error = assert_raise(Foreman::Exception) { cr.get_datacenter_uuid('prod') }
|
|
683
|
+
assert_match(/Datacenter was not found/, error.message)
|
|
684
|
+
end
|
|
685
|
+
end
|
|
686
|
+
end
|
|
687
|
+
end
|