fog-kubevirt 0.1.6 → 0.1.7

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.
@@ -0,0 +1,163 @@
1
+ module Fog
2
+ module Compute
3
+ class Kubevirt
4
+ module VmData
5
+
6
+ #
7
+ # Returns an array of parsed network interfaces
8
+ #
9
+ # @param object [Hash] A hash with raw interfaces data.
10
+ #
11
+ def parse_interfaces(object)
12
+ return {} if object.nil?
13
+ nics = []
14
+ object.each do |iface|
15
+ nic = VmNic.new
16
+ nic.name = iface[:name]
17
+ nic.mac_address = iface[:macAddress]
18
+ nic.type = 'bridge' if iface.keys.include?(:bridge)
19
+ nic.type = 'slirp' if iface.keys.include?(:slirp)
20
+ nics << nic
21
+ end
22
+
23
+ nics
24
+ end
25
+
26
+ #
27
+ # Returns an array of parsed networks
28
+ #
29
+ # @param object [Hash] A hash with raw networks data.
30
+ #
31
+ def parse_networks(object)
32
+ return {} if object.nil?
33
+ networks = []
34
+ object.each do |net|
35
+ network = VmNetwork.new
36
+ network.name = net[:name]
37
+ network.type = 'pod' if net.keys.include?(:pod)
38
+ network.type = 'multus' if net.keys.include?(:multus)
39
+ network.type = 'genie' if net.keys.include?(:genie)
40
+ networks << network
41
+ end
42
+
43
+ networks
44
+ end
45
+
46
+ #
47
+ # Returns an array of parsed disks
48
+ #
49
+ # @param object [Hash] A hash with raw disks data.
50
+ #
51
+ def parse_disks(object)
52
+ return {} if object.nil?
53
+ disks = []
54
+ object.each do |d|
55
+ disk = VmDisk.new
56
+ disk.name = d[:name]
57
+ disk.boot_order = d[:bootOrder]
58
+ disk.volume_name = d[:volumeName]
59
+
60
+ if d.keys.include?(:cdrom)
61
+ disk.type = 'cdrom'
62
+ disk.bus = d.dig(:cdrom, :bus)
63
+ disk.readonly = d.dig(:cdrom, :readonly)
64
+ elsif d.keys.include?(:disk)
65
+ disk.type = 'disk'
66
+ disk.bus = d.dig(:disk, :bus)
67
+ disk.readonly = d.dig(:disk, :readonly)
68
+ elsif d.keys.include?(:floppy)
69
+ disk.type = 'floppy'
70
+ disk.readonly = d.dig(:floppy, :readonly)
71
+ elsif d.keys.include?(:lun)
72
+ disk.type = 'lun'
73
+ disk.readonly = d.dig(:lun, :readonly)
74
+ end
75
+ disks << disk
76
+ end
77
+
78
+ disks
79
+ end
80
+
81
+ #
82
+ # Returns an array of parsed volumes
83
+ #
84
+ # @param object [Hash] A hash with raw volumes data.
85
+ #
86
+ def parse_volumes(object)
87
+ return {} if object.nil?
88
+ volumes = []
89
+ object.each do |v|
90
+ volume = VmVolume.new
91
+ volume.name = v[:name]
92
+ if v.keys.include?(:registryDisk)
93
+ volume.type = 'registryDisk'
94
+ volume.info = v.dig(:registryDisk, :image)
95
+ elsif v.keys.include?(:persistentVolumeClaim)
96
+ volume.type = 'persistentVolumeClaim'
97
+ volume.info = v.dig(:persistentVolumeClaim, :claimName)
98
+ elsif v.keys.include?(:emptyDisk)
99
+ volume.type = 'emptyDisk'
100
+ volume.info = v.dig(:emptyDisk, :capacity)
101
+ elsif v.keys.include?(:ephemeral)
102
+ volume.type = 'ephemeral'
103
+ volume.info = v.dig(:ephemeral, :persistentVolumeClaim, :claimName)
104
+ elsif v.keys.include?(:cloudInitNoCloud)
105
+ volume.type = 'cloudInitNoCloud'
106
+ volume.info = v.dig(:cloudInitNoCloud, :userDataBase64)
107
+ elsif v.keys.include?(:hostDisk)
108
+ volume.type = 'hostDisk'
109
+ volume.info = v.dig(:hostDisk, :path)
110
+ elsif v.keys.include?(:secret)
111
+ volume.type = 'secret'
112
+ volume.info = v.dig(:secret, :secretName)
113
+ elsif v.keys.include?(:dataVolume)
114
+ volume.type = 'dataVolume'
115
+ volume.info = v.dig(:dataVolume, :name)
116
+ elsif v.keys.include?(:serviceAccount)
117
+ volume.type = 'serviceAccount'
118
+ volume.info = v.dig(:serviceAccount, :serviceAccountName)
119
+ elsif v.keys.include?(:configMap)
120
+ volume.type = 'configMap'
121
+ volume.info = v.dig(:configMap, :name)
122
+ end
123
+ volumes << volume
124
+ end
125
+
126
+ volumes
127
+ end
128
+
129
+ class VmNic
130
+ attr_accessor :name,
131
+ :mac_address,
132
+ :type, # values: bridge, slirp
133
+ :model,
134
+ :ports,
135
+ :boot_order
136
+ end
137
+
138
+ class VmNetwork
139
+ attr_accessor :name,
140
+ :type # values: multus, pod, genie
141
+ end
142
+
143
+ class VmDisk
144
+ attr_accessor :name,
145
+ :volume_name,
146
+ :boot_order,
147
+ :type, # values: cdrom, disk, floppy, lun
148
+ :bus,
149
+ :readonly
150
+ end
151
+
152
+ class VmVolume
153
+ attr_accessor :name,
154
+ # values: registryDisk, persistentVolumeClaim, emptyDisk,
155
+ # ephemeral, cloudInitNoCloud, hostDisk, secret,
156
+ # dataVolume, serviceAccount, configMap
157
+ :type,
158
+ :info # specific piece of information per volume type
159
+ end
160
+ end
161
+ end
162
+ end
163
+ end
@@ -1,7 +1,11 @@
1
+ require 'fog/compute/kubevirt/models/vm_data'
2
+
1
3
  module Fog
2
4
  module Compute
3
5
  class Kubevirt
4
6
  class Vminstance < Fog::Model
7
+ extend VmData
8
+
5
9
  identity :name
6
10
 
7
11
  attribute :namespace, :aliases => 'metadata_namespace'
@@ -14,6 +18,8 @@ module Fog
14
18
  attribute :disks, :aliases => 'spec_disks'
15
19
  attribute :volumes, :aliases => 'spec_volumes'
16
20
  attribute :ip_address, :aliases => 'status_interfaces_ip'
21
+ attribute :interfaces, :aliases => 'spec_interfaces'
22
+ attribute :networks, :aliases => 'spec_networks'
17
23
  attribute :node_name, :aliases => 'status_node_name'
18
24
  attribute :status, :aliases => 'status_phase'
19
25
 
@@ -31,8 +37,10 @@ module Fog
31
37
  :owner_uid => metadata.dig(:ownerReferences, 0, :uid),
32
38
  :cpu_cores => domain.dig(:cpu, :cores),
33
39
  :memory => domain[:resources][:requests][:memory],
34
- :disks => domain[:devices][:disks],
35
- :volumes => spec[:volumes],
40
+ :disks => parse_disks(domain[:devices][:disks]),
41
+ :volumes => parse_volumes(spec[:volumes]),
42
+ :interfaces => parse_interfaces(domain[:devices][:interfaces]),
43
+ :networks => parse_networks(spec[:networks]),
36
44
  :ip_address => status.dig(:interfaces, 0, :ipAddress),
37
45
  :node_name => status[:nodeName],
38
46
  :status => status[:phase]
@@ -5,6 +5,8 @@ module Fog
5
5
  module Compute
6
6
  class Kubevirt
7
7
  class Vms < Fog::Collection
8
+ include Shared
9
+
8
10
  attr_reader :kind, :resource_version
9
11
 
10
12
  model Fog::Compute::Kubevirt::Vm
@@ -24,6 +26,114 @@ module Fog
24
26
  def get(name)
25
27
  new service.get_vm(name)
26
28
  end
29
+
30
+ # Creates a virtual machine using provided paramters:
31
+ # :vm_name [String] - name of a vm
32
+ # :cpus [String] - number of cpus
33
+ # :memory_size [String] - amount of memory
34
+ # :image [String] - name of a registry disk
35
+ # :pvc [String] - name of a persistent volume claim
36
+ # :cloudinit [Hash] - number of items needed to configure cloud-init
37
+ #
38
+ # One of :image or :pvc needs to be provided.
39
+ #
40
+ # @param [Hash] attributes containing details about vm about to be
41
+ # created.
42
+ def create(args = {})
43
+ vm_name = args.fetch(:vm_name)
44
+ cpus = args.fetch(:cpus, nil)
45
+ memory_size = args.fetch(:memory_size)
46
+ image = args.fetch(:image, nil)
47
+ pvc = args.fetch(:pvc, nil)
48
+ init = args.fetch(:cloudinit, {})
49
+
50
+ if image.nil? && pvc.nil?
51
+ raise ::Fog::Kubevirt::Errors::ValidationError
52
+ end
53
+
54
+ volumes = []
55
+
56
+ if !image.nil?
57
+ volumes.push(:name => vm_name, :registryDisk => {:image => image})
58
+ else
59
+ volumes.push(:name => vm_name, :persistentVolumeClaim => {:claimName => pvc})
60
+ end
61
+
62
+ unless init.empty?
63
+ volumes.push(:cloudInitNoCloud => init, :name => "cloudinitvolume")
64
+ end
65
+
66
+ vm = {
67
+ :apiVersion => service.class::KUBEVIRT_VERSION_LABEL,
68
+ :kind => "VirtualMachine",
69
+ :metadata => {
70
+ :labels => {
71
+ :"kubevirt.io/vm" => vm_name,
72
+ },
73
+ :name => vm_name,
74
+ :namespace => service.namespace,
75
+ },
76
+ :spec => {
77
+ :running => false,
78
+ :template => {
79
+ :metadata => {
80
+ :creationTimestamp => nil,
81
+ :labels => {
82
+ :"kubevirt.io/vm" => vm_name
83
+ }
84
+ },
85
+ :spec => {
86
+ :domain => {
87
+ :devices => {
88
+ :disks => [
89
+ {:disk => {
90
+ :bus => "virtio"
91
+ },
92
+ :name => vm_name,
93
+ :volumeName => vm_name
94
+ }
95
+ ]
96
+ },
97
+ :machine => {
98
+ :type => ""
99
+ },
100
+ :resources => {
101
+ :requests => {
102
+ :memory => "#{memory_size}M"
103
+ }
104
+ }
105
+ },
106
+ :terminationGracePeriodSeconds => 0,
107
+ :volumes => volumes
108
+ }
109
+ }
110
+ }
111
+ }
112
+
113
+ vm = deep_merge!(vm,
114
+ :spec => {
115
+ :template => {
116
+ :spec => {
117
+ :domain => {
118
+ :cpu => {
119
+ :cores => cpus
120
+ }
121
+ }
122
+ }
123
+ }
124
+ }
125
+ ) unless cpus.nil?
126
+
127
+ vm[:spec][:template][:spec][:domain][:devices][:disks].push(
128
+ :disk => {
129
+ :bus => "virtio"
130
+ },
131
+ :name => "cloudinitdisk",
132
+ :volumeName => "cloudinitvolume"
133
+ ) unless init.empty?
134
+
135
+ service.create_vm(vm)
136
+ end
27
137
  end
28
138
  end
29
139
  end
@@ -0,0 +1,18 @@
1
+ module Fog
2
+ module Compute
3
+ class Kubevirt
4
+ class Real
5
+ def create_service(srv)
6
+ kube_client.create_service(srv)
7
+ rescue ::Fog::Kubevirt::Errors::ClientError => err
8
+ log.warn(err)
9
+ raise ::Fog::Kubevirt::Errors::AlreadyExistsError
10
+ end
11
+ end
12
+
13
+ class Mock
14
+ def create_service(srv); end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,16 @@
1
+ module Fog
2
+ module Compute
3
+ class Kubevirt
4
+ class Real
5
+ def delete_service(name, namespace)
6
+ kube_client.delete_service(name, namespace)
7
+ end
8
+ end
9
+
10
+ class Mock
11
+ def delete_service(name)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,32 @@
1
+ module Fog
2
+ module Compute
3
+ class Kubevirt
4
+ class Real
5
+ def get_server(name)
6
+ vm = get_raw_vm(name)
7
+ populate_runtime_info(vm)
8
+ Server.parse vm
9
+ end
10
+
11
+ # Updates a given VM raw entity with vm instance info if exists
12
+ #
13
+ # @param vm [Hash] A hash with vm raw data.
14
+ def populate_runtime_info(vm)
15
+ vmi = get_vminstance(vm[:metadata][:name])
16
+ vm[:ip_address] = vmi[:ip_address]
17
+ vm[:node_name] = vmi[:node_name]
18
+ vm[:phase] = vmi[:status]
19
+ vm
20
+ rescue
21
+ # do nothing if vmi doesn't exist
22
+ end
23
+ end
24
+
25
+ class Mock
26
+ # TODO provide implementation
27
+ def get_server(name)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,16 @@
1
+ module Fog
2
+ module Compute
3
+ class Kubevirt
4
+ class Real
5
+ def get_service(name)
6
+ Service.parse object_to_hash(kube_client.get_service(name, @namespace))
7
+ end
8
+ end
9
+
10
+ class Mock
11
+ def get_service(name)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -7,7 +7,7 @@ module Fog
7
7
  end
8
8
 
9
9
  def get_raw_vm(name)
10
- object_to_hash( kubevirt_client.get_virtual_machine(name, @namespace) )
10
+ object_to_hash(kubevirt_client.get_virtual_machine(name, @namespace))
11
11
  end
12
12
  end
13
13
 
@@ -0,0 +1,25 @@
1
+ require 'recursive_open_struct'
2
+ require 'fog/compute/kubevirt/requests/get_server'
3
+
4
+ module Fog
5
+ module Compute
6
+ class Kubevirt
7
+ class Real
8
+ def list_servers(_filters = {})
9
+ vms = kubevirt_client.get_virtual_machines(namespace: @namespace)
10
+ entities = vms.map do |kubevirt_obj|
11
+ vm_obj = object_to_hash(kubevirt_obj)
12
+ populate_runtime_info(vm_obj)
13
+ Server.parse vm_obj
14
+ end
15
+ EntityCollection.new(vms.kind, vms.resourceVersion, entities)
16
+ end
17
+ end
18
+
19
+ class Mock
20
+ def list_servers(_filters = {})
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end