fog-kubevirt 0.1.6 → 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -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