foreman_kubevirt 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: eb14b9910b51e87d3bd699260b39936ecf751d2e
4
- data.tar.gz: a2ff30c7286f23678e50f1bcafc77b27abe47ab4
3
+ metadata.gz: f2ab728beaf6449390b9686a3578738848ac1da3
4
+ data.tar.gz: dc79c8e150b8d7cb02c679c9e1ffd4cf63495e0b
5
5
  SHA512:
6
- metadata.gz: 406d06d9e17c37437d133513d44e89e6c006b99510a96145895e6584080dcc7bd3ea2f7e25d024b12351bfece8d51e2b08e6253cf52e96f9c128bc4bc54d696f
7
- data.tar.gz: d16ddc90d2ad8652a71e05840fdbe605bc9ed20dccf38242bc5d767e03c814d7ba748eece054f09dbb084e2b51624b94e9a1dc95e0d1d465d3ce8a1cad35f64d
6
+ metadata.gz: 53d8317d77b47588d0b049ae083aa4e261ac4983c6a047870f4dc4eb899c77fa3b1b32d2edbe1f4e23201bec197a6c171708b9a77710fde52bf78a5805a612f9
7
+ data.tar.gz: d961f6dff0ebf22b0e8a326b08c7c20d555b9e2ce6aed4bae7e4b39c6922c512a1c3f04c2215371f55a13b461bc0d3836d5938a47e1bd65e2cb746877ef29655
@@ -1,5 +1,5 @@
1
1
  bootableRadio = function (item) {
2
- const disabled = $('[id$=_bootable_true]:disabled:checked:visible');
2
+ disabled = $('[id$=_bootable_true]:disabled:checked:visible');
3
3
 
4
4
  $('[id$=_bootable_true]').prop('checked', false);
5
5
  if (disabled.length > 0) {
@@ -10,8 +10,8 @@ bootableRadio = function (item) {
10
10
  }
11
11
 
12
12
  cniProviderSelected = function (item) {
13
- const selected = $(item).val().toLowerCase();
14
- const networks = $(item).parentsUntil('.fields').parent().find('#networks');
13
+ selected = $(item).val().toLowerCase();
14
+ networks = $(item).parentsUntil('.fields').parent().find('#networks');
15
15
 
16
16
  if (selected == "pod") {
17
17
  disableDropdown(networks);
@@ -57,7 +57,8 @@ module ForemanKubevirt
57
57
  def networks
58
58
  client.networkattachmentdefs.all
59
59
  rescue StandardError => e
60
- logger.warn("Failed to retrieve network attachments definition from KubeVirt, make sure KubeVirt has CNI provider and NetworkAttachmentDefinition CRD deployed: #{e.message}")
60
+ logger.warn("Failed to retrieve network attachments definition from KubeVirt,
61
+ make sure KubeVirt has CNI provider and NetworkAttachmentDefinition CRD deployed: #{e.message}")
61
62
  []
62
63
  end
63
64
 
@@ -130,84 +131,16 @@ module ForemanKubevirt
130
131
  # "capacity"=>"2"
131
132
  # }
132
133
  # }
133
-
134
- def verify_booting_from_image_is_possible(volumes)
135
- raise ::Foreman::Exception.new N_('It is not possible to set a bootable volume and image based provisioning.') if
136
- volumes.any? { |_, v| v["bootable"] == "true" }
137
- end
138
-
139
134
  def create_vm(args = {})
140
135
  options = vm_instance_defaults.merge(args.to_hash.deep_symbolize_keys)
141
136
  logger.debug("creating VM with the following options: #{options.inspect}")
142
- volumes = []
143
-
144
- image = args["image_id"]
145
- volumes_attributes = args["volumes_attributes"]
146
- raise ::Foreman::Exception.new N_('VM should be created based on Persistent Volume Claim or Image') unless (volumes_attributes.present? || image)
147
-
148
- # Add image as volume to the virtual machine
149
- image_provision = args["provision_method"] == "image"
150
- if image_provision
151
- verify_booting_from_image_is_possible(volumes_attributes)
152
- volume = Fog::Kubevirt::Compute::Volume.new
153
- raise ::Foreman::Exception.new N_('VM should be created based on an image') unless image
154
-
155
- volume.info = image
156
- volume.boot_order = 1
157
- volume.type = 'containerDisk'
158
- volumes << volume
159
- end
160
137
 
161
- volumes_attributes.each { |_, v| raise ::Foreman::Exception.new N_('Capacity was not found') if v["capacity"].empty? }
162
- volumes_attributes&.each_with_index do |(_, v), index|
163
- # Add PVC as volumes to the virtual machine
164
- pvc_name = options[:name].gsub(/[._]+/, '-') + "-claim-" + (index + 1).to_s
165
- capacity = v["capacity"]
166
- storage_class = v["storage_class"]
167
- bootable = v["bootable"] && !image_provision
168
-
169
- volume = create_vm_volume(pvc_name, capacity, storage_class, bootable)
170
- volumes << volume
171
- end
138
+ volumes = create_volumes_for_vm(options)
172
139
 
173
140
  # FIXME: Add cloud-init support
174
141
  # init = { 'userData' => "#!/bin/bash\necho \"fedora\" | passwd fedora --stdin"}
175
142
 
176
- interfaces = []
177
- networks = []
178
-
179
- args["interfaces_attributes"].values.each do |iface|
180
- if iface["cni_provider"] == 'pod'
181
- nic = {
182
- :bridge => {},
183
- :name => 'pod'
184
- }
185
-
186
- net = { :name => 'pod', :pod => {} }
187
- else
188
- nic = {
189
- :bridge => {},
190
- :name => iface["network"]
191
- }
192
-
193
- cni = iface["cni_provider"].to_sym
194
- net = {
195
- :name => iface["network"],
196
- cni => { :networkName => iface["network"] }
197
- }
198
- end
199
-
200
- # TODO: Consider replacing with 'free' boot order, also verify uniqueness
201
- # there is a bug with bootOrder https://bugzilla.redhat.com/show_bug.cgi?id=1687341
202
- # therefore adding to the condition not to boot from netwotk device if already asked
203
- # to boot from disk
204
- if iface["provision"] == true && volumes.select { |v| v.boot_order == 1 }.empty?
205
- nic[:bootOrder] = 1
206
- end
207
- nic[:macAddress] = iface["mac"] if iface["mac"]
208
- interfaces << nic
209
- networks << net
210
- end
143
+ interfaces, networks = create_network_devices_for_vm(options, volumes)
211
144
 
212
145
  begin
213
146
  client.vms.create(:vm_name => options[:name],
@@ -224,34 +157,6 @@ module ForemanKubevirt
224
157
  end
225
158
  end
226
159
 
227
- def create_new_pvc(pvc_name, capacity, storage_class)
228
- client.pvcs.create(:name => pvc_name,
229
- :namespace => namespace,
230
- :storage_class => storage_class,
231
- :access_modes => ['ReadWriteOnce'],
232
- :requests => { :storage => capacity + "G" })
233
- end
234
-
235
- def delete_pvcs(volumes)
236
- volumes.each do |volume|
237
- begin
238
- client.pvcs.delete(volume.info) if volume.type == "persistentVolumeClaim"
239
- rescue StandardError => e
240
- logger.error("The PVC #{volume.info} couldn't be delete due to #{e.message}")
241
- end
242
- end
243
- end
244
-
245
- def create_vm_volume(pvc_name, capacity, storage_class, bootable)
246
- create_new_pvc(pvc_name, capacity, storage_class)
247
-
248
- volume = Fog::Kubevirt::Compute::Volume.new
249
- volume.type = 'persistentVolumeClaim'
250
- volume.info = pvc_name
251
- volume.boot_order = 1 if bootable == "true"
252
- volume
253
- end
254
-
255
160
  def destroy_vm(vm_uuid)
256
161
  vm = find_vm_by_uuid(vm_uuid)
257
162
  delete_pvcs(vm.volumes)
@@ -315,11 +220,13 @@ module ForemanKubevirt
315
220
  vm_attrs = super
316
221
  interfaces = vm.interfaces || []
317
222
  vm_attrs[:interfaces_attributes] = interfaces.each_with_index.each_with_object({}) do |(interface, index), hsh|
318
- interface_attrs = {}
319
- interface_attrs[:compute_attributes] = {}
320
- interface_attrs[:mac] = interface.mac
321
- interface_attrs[:compute_attributes][:network] = interface.network
322
- interface_attrs[:compute_attributes][:cni_provider] = interface.cni_provider
223
+ interface_attrs = {
224
+ mac: interface.mac,
225
+ compute_attributes: {
226
+ network: interface.network,
227
+ cni_provider: interface.cni_provider
228
+ }
229
+ }
323
230
  hsh[index.to_s] = interface_attrs
324
231
  end
325
232
 
@@ -385,5 +292,141 @@ module ForemanKubevirt
385
292
  ca_cert
386
293
  )
387
294
  end
295
+
296
+ private
297
+
298
+ def verify_at_least_one_volume_provided(options)
299
+ image = options[:image_id]
300
+ volumes_attributes = options[:volumes_attributes]
301
+ raise ::Foreman::Exception.new N_('VM should be created based on Persistent Volume Claim or Image') unless
302
+ (volumes_attributes.present? || image)
303
+ end
304
+
305
+ def verify_booting_from_image_is_possible(volumes)
306
+ raise ::Foreman::Exception.new N_('It is not possible to set a bootable volume and image based provisioning.') if
307
+ volumes.any? { |_, v| v[:bootable] == "true" }
308
+ end
309
+
310
+ def add_volume_for_image_provision(options)
311
+ image = options[:image_id]
312
+ raise ::Foreman::Exception.new N_('VM should be created based on an image') unless image
313
+
314
+ verify_booting_from_image_is_possible(options[:volumes_attributes])
315
+
316
+ volume = Fog::Kubevirt::Compute::Volume.new
317
+ volume.info = image
318
+ volume.boot_order = 1
319
+ volume.type = 'containerDisk'
320
+ volume
321
+ end
322
+
323
+ def validate_volume_capacity(volumes_attributes)
324
+ volumes_attributes.each { |_, v| raise ::Foreman::Exception.new N_('Capacity was not found') if v[:capacity].empty? }
325
+ end
326
+
327
+ def validate_only_single_bootable_volume(volumes_attributes)
328
+ raise ::Foreman::Exception.new N_('Only one volume can be bootable') if volumes_attributes.select { |_, v| v[:bootable] == "true" }.count > 1
329
+ end
330
+
331
+ def create_new_pvc(pvc_name, capacity, storage_class)
332
+ client.pvcs.create(:name => pvc_name,
333
+ :namespace => namespace,
334
+ :storage_class => storage_class,
335
+ :access_modes => ['ReadWriteOnce'],
336
+ :requests => { :storage => capacity + "G" })
337
+ end
338
+
339
+ def delete_pvcs(volumes)
340
+ volumes.each do |volume|
341
+ begin
342
+ client.pvcs.delete(volume.info) if volume.type == "persistentVolumeClaim"
343
+ rescue StandardError => e
344
+ logger.error("The PVC #{volume.info} couldn't be delete due to #{e.message}")
345
+ end
346
+ end
347
+ end
348
+
349
+ def create_vm_volume(pvc_name, capacity, storage_class, bootable)
350
+ create_new_pvc(pvc_name, capacity, storage_class)
351
+
352
+ volume = Fog::Kubevirt::Compute::Volume.new
353
+ volume.type = 'persistentVolumeClaim'
354
+ volume.info = pvc_name
355
+ volume.boot_order = 1 if bootable == "true"
356
+ volume
357
+ end
358
+
359
+ def add_volumes_based_on_pvcs(options, image_provision)
360
+ volumes_attributes = options[:volumes_attributes]
361
+ return [] if volumes_attributes.blank?
362
+
363
+ validate_volume_capacity(volumes_attributes)
364
+ validate_only_single_bootable_volume(volumes_attributes)
365
+
366
+ volumes = []
367
+ vm_name = options[:name].gsub(/[._]+/, '-')
368
+ volumes_attributes.each_with_index do |(_, v), index|
369
+ # Add PVC as volumes to the virtual machine
370
+ pvc_name = vm_name + "-claim-" + (index + 1).to_s
371
+ capacity = v[:capacity]
372
+ storage_class = v[:storage_class]
373
+ bootable = v[:bootable] && !image_provision
374
+
375
+ volume = create_vm_volume(pvc_name, capacity, storage_class, bootable)
376
+ volumes << volume
377
+ end
378
+
379
+ volumes
380
+ end
381
+
382
+ # Creates volume elements for the VM based on provided parameters
383
+ #
384
+ # @param options[Hash] contains VM creation parameters
385
+ #
386
+ def create_volumes_for_vm(options)
387
+ verify_at_least_one_volume_provided(options)
388
+
389
+ # Add image as volume to the virtual machine
390
+ volumes = []
391
+ image_provision = options[:provision_method] == "image"
392
+
393
+ volumes << add_volume_for_image_provision(options) if image_provision
394
+ volumes.concat(add_volumes_based_on_pvcs(options, image_provision))
395
+ end
396
+
397
+ def create_pod_network_element
398
+ nic = { bridge: {}, name: 'pod' }
399
+ net = { name: 'pod', pod: {} }
400
+ [nic, net]
401
+ end
402
+
403
+ def create_network_element(iface)
404
+ nic = { bridge: {}, name: iface[:network] }
405
+ cni = iface[:cni_provider].to_sym
406
+ net = { :name => iface[:network], cni => { :networkName => iface[:network] } }
407
+ [nic, net]
408
+ end
409
+
410
+ def create_network_devices_for_vm(options, volumes)
411
+ interfaces = []
412
+ networks = []
413
+
414
+ options[:interfaces_attributes].values.each do |iface|
415
+ if iface[:cni_provider] == 'pod'
416
+ nic, net = create_pod_network_element
417
+ else
418
+ nic, net = create_network_element(iface)
419
+ end
420
+
421
+ if iface[:provision] == true && volumes.select { |v| v.boot_order == 1 }.empty?
422
+ nic[:bootOrder] = 1
423
+ end
424
+ nic[:macAddress] = iface[:mac] if iface[:mac]
425
+ interfaces << nic
426
+ networks << net
427
+ end
428
+
429
+ [interfaces, networks]
430
+ end
388
431
  end
389
432
  end
@@ -1,3 +1,3 @@
1
1
  module ForemanKubevirt
2
- VERSION = '0.1.1'.freeze
2
+ VERSION = '0.1.2'.freeze
3
3
  end
@@ -19,11 +19,42 @@ class ForemanKubevirtTest < ActiveSupport::TestCase
19
19
 
20
20
  require 'kubeclient'
21
21
 
22
- test "create_vm network based" do
23
- vm_args = { "cpu_cores" => "1", "memory" => "1073741824", "start" => "1", "volumes_attributes" => { "1554559479978" => { "_delete" => "", "storage_class" => "local-storage", "capacity" => "1", "bootable" => "true" }, "1554559483803" => { "_delete" => "", "storage_class" => "local-storage", "capacity" => "2" } }, "name" => "robin-rykert.example.com", "provision_method" => "build", "firmware_type" => :bios, "interfaces_attributes" => { "0" => { "cni_provider" => "multus", "network" => "ovs-foreman", "ip" => "192.168.111.193", "mac" => "a2:b4:a2:b6:a2:a8", "provision" => true } } }
22
+ NETWORK_BASED_VM_ARGS = {
23
+ "cpu_cores" => "1",
24
+ "memory" => "1073741824",
25
+ "start" => "1",
26
+ "volumes_attributes" => {
27
+ "0" => { "_delete" => "", "storage_class" => "local-storage", "capacity" => "1", "bootable" => "true" },
28
+ "1" => { "_delete" => "", "storage_class" => "local-storage", "capacity" => "2" }
29
+ },
30
+ "name" => "robin-rykert.example.com",
31
+ "provision_method" => "build",
32
+ "firmware_type" => :bios,
33
+ "interfaces_attributes" => {
34
+ "0" => { "cni_provider" => "multus", "network" => "ovs-foreman", "ip" => "192.168.111.193", "mac" => "a2:b4:a2:b6:a2:a8", "provision" => true }
35
+ }
36
+ }.freeze
37
+
38
+ IMAGE_BASED_VM_ARGS = {
39
+ "cpu_cores" => "1",
40
+ "memory" => "1073741824",
41
+ "start" => "1",
42
+ "volumes_attributes" => {
43
+ "0" => { "_delete" => "", "storage_class" => "local-storage", "capacity" => "1", "bootable" => "false" }
44
+ },
45
+ "image_id" => "kubevirt/fedora-cloud-registry-disk-demo",
46
+ "name" => "olive-kempter.example.com",
47
+ "provision_method" => "image",
48
+ "firmware_type" => :bios,
49
+ "interfaces_attributes" => {
50
+ "0" => { "cni_provider" => "multus", "network" => "ovs-foreman", "ip" => "192.168.111.184", "mac" => "a2:a4:a2:b2:a2:b6", "provision" => true }
51
+ }
52
+ }.freeze
53
+
54
+ test "create_vm network based should pass" do
24
55
  Fog.mock!
25
56
  compute_resource = new_kubevirt_vcr
26
- server = compute_resource.create_vm(vm_args)
57
+ server = compute_resource.create_vm(NETWORK_BASED_VM_ARGS)
27
58
 
28
59
  assert_equal "robin-rykert.example.com", server.name
29
60
  assert_equal 2, server.volumes.count
@@ -31,11 +62,10 @@ class ForemanKubevirtTest < ActiveSupport::TestCase
31
62
  assert_equal 1, server.interfaces.count
32
63
  end
33
64
 
34
- test "create_vm image based" do
35
- vm_args = { "cpu_cores" => "1", "memory" => "1073741824", "start" => "1", "volumes_attributes" => { "1554649143334" => { "_delete" => "", "storage_class" => "local-storage", "capacity" => "1", "bootable" => "false" } }, "image_id" => "kubevirt/fedora-cloud-registry-disk-demo", "name" => "olive-kempter.example.com", "provision_method" => "image", "firmware_type" => :bios, "interfaces_attributes" => { "0" => { "cni_provider" => "multus", "network" => "ovs-foreman", "ip" => "192.168.111.184", "mac" => "a2:a4:a2:b2:a2:b6", "provision" => true } } }
65
+ test "create_vm image based should pass" do
36
66
  Fog.mock!
37
67
  compute_resource = new_kubevirt_vcr
38
- server = compute_resource.create_vm(vm_args)
68
+ server = compute_resource.create_vm(IMAGE_BASED_VM_ARGS)
39
69
 
40
70
  assert_equal "olive-kempter.example.com", server.name
41
71
  assert_equal 2, server.volumes.count
@@ -44,7 +74,18 @@ class ForemanKubevirtTest < ActiveSupport::TestCase
44
74
  end
45
75
 
46
76
  test "should fail when creating a VM with_bootable flag and image based" do
47
- vm_args = { "cpu_cores" => "1", "memory" => "1073741824", "start" => "1", "volumes_attributes" => { "1554649143334" => { "_delete" => "", "storage_class" => "local-storage", "capacity" => "1", "bootable" => "true" } }, "image_id" => "kubevirt/fedora-cloud-registry-disk-demo", "name" => "olive-kempter.example.com", "provision_method" => "image", "firmware_type" => :bios, "interfaces_attributes" => { "0" => { "cni_provider" => "multus", "network" => "ovs-foreman", "ip" => "192.168.111.184", "mac" => "a2:a4:a2:b2:a2:b6", "provision" => true } } }
77
+ vm_args = IMAGE_BASED_VM_ARGS.deep_dup
78
+ vm_args["volumes_attributes"]["0"]["bootable"] = "true"
79
+ Fog.mock!
80
+ compute_resource = new_kubevirt_vcr
81
+ assert_raise(Foreman::Exception) do
82
+ compute_resource.create_vm(vm_args)
83
+ end
84
+ end
85
+
86
+ test "should fail when creating a VM without an image or pvc" do
87
+ vm_args = IMAGE_BASED_VM_ARGS.deep_dup
88
+ vm_args["image_id"] = nil
48
89
  Fog.mock!
49
90
  compute_resource = new_kubevirt_vcr
50
91
  assert_raise(Foreman::Exception) do
@@ -52,8 +93,10 @@ class ForemanKubevirtTest < ActiveSupport::TestCase
52
93
  end
53
94
  end
54
95
 
55
- test "should fail when creating a VM without an image or pvc " do
56
- vm_args = { "cpu_cores" => "1", "memory" => "1073741824", "start" => "1", "volumes_attributes" => {}, "name" => "olive-kempter.example.com", "provision_method" => "image", "firmware_type" => :bios, "interfaces_attributes" => { "0" => { "cni_provider" => "multus", "network" => "ovs-foreman", "ip" => "192.168.111.184", "mac" => "a2:a4:a2:b2:a2:b6", "provision" => true } } }
96
+ test "should fail when creating image-based VM without an image" do
97
+ vm_args = IMAGE_BASED_VM_ARGS.deep_dup
98
+ vm_args["volumes_attributes"] = {}
99
+ vm_args["image_id"] = nil
57
100
  Fog.mock!
58
101
  compute_resource = new_kubevirt_vcr
59
102
  assert_raise(Foreman::Exception) do
@@ -62,7 +105,19 @@ class ForemanKubevirtTest < ActiveSupport::TestCase
62
105
  end
63
106
 
64
107
  test "should fail when creating a VM with PVC and not providing a capacity" do
65
- vm_args = { "cpu_cores" => "1", "memory" => "1073741824", "start" => "1", "volumes_attributes" => { "1554649143334" => { "_delete" => "", "storage_class" => "local-storage", "bootable" => "false" } }, "image_id" => "kubevirt/fedora-cloud-registry-disk-demo", "name" => "olive-kempter.example.com", "provision_method" => "image", "firmware_type" => :bios, "interfaces_attributes" => { "0" => { "cni_provider" => "multus", "network" => "ovs-foreman", "ip" => "192.168.111.184", "mac" => "a2:a4:a2:b2:a2:b6", "provision" => true } } }
108
+ vm_args = NETWORK_BASED_VM_ARGS.deep_dup
109
+ vm_args["volumes_attributes"]["0"]["capacity"] = nil
110
+ Fog.mock!
111
+ compute_resource = new_kubevirt_vcr
112
+ assert_raise(Foreman::Exception) do
113
+ compute_resource.create_vm(vm_args)
114
+ end
115
+ end
116
+
117
+ test "should fail when creating a VM with two bootable PVCs" do
118
+ vm_args = NETWORK_BASED_VM_ARGS.deep_dup
119
+ vm_args["volumes_attributes"]["0"]["bootable"] = "true"
120
+ vm_args["volumes_attributes"]["1"]["bootable"] = "true"
66
121
  Fog.mock!
67
122
  compute_resource = new_kubevirt_vcr
68
123
  assert_raise(Foreman::Exception) do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreman_kubevirt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Moti Asayag
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-04-24 00:00:00.000000000 Z
11
+ date: 2019-04-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -96,7 +96,7 @@ files:
96
96
  - test/unit/foreman_kubevirt_test.rb
97
97
  homepage: https://github.com/theforeman/foreman_kubevirt
98
98
  licenses:
99
- - GPLv3
99
+ - GPL-3.0
100
100
  metadata: {}
101
101
  post_install_message:
102
102
  rdoc_options: []