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.
- checksums.yaml +4 -4
- data/lib/fog/compute/kubevirt.rb +60 -14
- data/lib/fog/compute/kubevirt/models/server.rb +42 -0
- data/lib/fog/compute/kubevirt/models/servers.rb +32 -0
- data/lib/fog/compute/kubevirt/models/service.rb +36 -0
- data/lib/fog/compute/kubevirt/models/services.rb +83 -0
- data/lib/fog/compute/kubevirt/models/vm.rb +6 -53
- data/lib/fog/compute/kubevirt/models/vm_base.rb +83 -0
- data/lib/fog/compute/kubevirt/models/vm_data.rb +163 -0
- data/lib/fog/compute/kubevirt/models/vminstance.rb +10 -2
- data/lib/fog/compute/kubevirt/models/vms.rb +110 -0
- data/lib/fog/compute/kubevirt/requests/create_service.rb +18 -0
- data/lib/fog/compute/kubevirt/requests/delete_service.rb +16 -0
- data/lib/fog/compute/kubevirt/requests/get_server.rb +32 -0
- data/lib/fog/compute/kubevirt/requests/get_service.rb +16 -0
- data/lib/fog/compute/kubevirt/requests/get_vm.rb +1 -1
- data/lib/fog/compute/kubevirt/requests/list_servers.rb +25 -0
- data/lib/fog/compute/kubevirt/requests/list_services.rb +22 -0
- data/lib/fog/kubevirt.rb +1 -0
- data/lib/fog/kubevirt/version.rb +1 -1
- data/spec/compute_v1alpha2_spec.rb +30 -0
- data/spec/fixtures/kubevirt/service/v1alpha2/services_crud.yml +172 -0
- data/spec/shared_context.rb +54 -0
- data/spec/spec_helper.rb +10 -0
- metadata +67 -5
@@ -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,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,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
|