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.
- 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
|