fog-kubevirt 0.1.8 → 0.2.0
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 +64 -20
- data/lib/fog/compute/kubevirt/models/networkattachmentdef.rb +25 -0
- data/lib/fog/compute/kubevirt/models/networkattachmentdefs.rb +59 -0
- data/lib/fog/compute/kubevirt/models/pvc.rb +59 -0
- data/lib/fog/compute/kubevirt/models/pvcs.rb +76 -0
- data/lib/fog/compute/kubevirt/models/server.rb +3 -1
- data/lib/fog/compute/kubevirt/models/vm_data.rb +5 -4
- data/lib/fog/compute/kubevirt/models/vms.rb +44 -7
- data/lib/fog/compute/kubevirt/models/volume.rb +73 -0
- data/lib/fog/compute/kubevirt/models/volumes.rb +61 -0
- data/lib/fog/compute/kubevirt/requests/create_networkattachmentdef.rb +37 -0
- data/lib/fog/compute/kubevirt/requests/create_vm.rb +1 -0
- data/lib/fog/compute/kubevirt/requests/create_volume.rb +19 -0
- data/lib/fog/compute/kubevirt/requests/delete_networkattachmentdef.rb +16 -0
- data/lib/fog/compute/kubevirt/requests/delete_pvc.rb +16 -0
- data/lib/fog/compute/kubevirt/requests/delete_volume.rb +16 -0
- data/lib/fog/compute/kubevirt/requests/get_networkattachmentdef.rb +19 -0
- data/lib/fog/compute/kubevirt/requests/get_pvc.rb +16 -0
- data/lib/fog/compute/kubevirt/requests/get_vminstance.rb +4 -4
- data/lib/fog/compute/kubevirt/requests/get_volume.rb +16 -0
- data/lib/fog/compute/kubevirt/requests/list_networkattachmentdefs.rb +21 -0
- data/lib/fog/compute/kubevirt/requests/list_pvcs.rb +22 -0
- data/lib/fog/compute/kubevirt/requests/list_vms.rb +4 -4
- data/lib/fog/compute/kubevirt/requests/list_volumes.rb +22 -0
- data/lib/fog/kubevirt/version.rb +1 -1
- data/spec/compute_v1alpha2_spec.rb +1 -1
- data/spec/fixtures/kubevirt/networkattachmentdefinition/networkattachmentdefinitions_crud.yml +320 -0
- data/spec/fixtures/kubevirt/pvc/pvcs_crud.yml +316 -0
- data/spec/fixtures/kubevirt/service/services_crud.yml +316 -0
- data/spec/fixtures/kubevirt/volume/volumes_crud.yml +316 -0
- data/spec/network_attachment_definition_v1alpha2_spec.rb +28 -0
- data/spec/pvcs_v1alpha2_spec.rb +52 -0
- data/spec/shared_context.rb +2 -2
- data/spec/volumes_v1alpha2_spec.rb +45 -0
- metadata +33 -20
- data/spec/fixtures/kubevirt/service/v1alpha2/services_crud.yml +0 -172
@@ -31,9 +31,22 @@ module Fog
|
|
31
31
|
# :vm_name [String] - name of a vm
|
32
32
|
# :cpus [String] - number of cpus
|
33
33
|
# :memory_size [String] - amount of memory
|
34
|
-
# :image [String] - name of a
|
34
|
+
# :image [String] - name of a container disk
|
35
35
|
# :pvc [String] - name of a persistent volume claim
|
36
36
|
# :cloudinit [Hash] - number of items needed to configure cloud-init
|
37
|
+
# :networks[Array] - networks to which the vm should be connected, i.e:
|
38
|
+
# [ { :name => 'default', :pod => {} } ,
|
39
|
+
# { :name => 'ovs-red', :multus => { :networkName => 'red'} }
|
40
|
+
# ]
|
41
|
+
#
|
42
|
+
# :interfaces[Array] - network interfaces for the vm, correlated to
|
43
|
+
# :networks section by network's name, i.e.:
|
44
|
+
# [ { :name => 'default', :bridge => {} },
|
45
|
+
# { :name => 'red', # correlated to networks[networkName]
|
46
|
+
# :bridge => {},
|
47
|
+
# :bootOrder => 1, # 1 to boot from network interface
|
48
|
+
# :macAddress => '12:34:56:AB:CD:EF' }
|
49
|
+
# ]
|
37
50
|
#
|
38
51
|
# One of :image or :pvc needs to be provided.
|
39
52
|
#
|
@@ -46,17 +59,19 @@ module Fog
|
|
46
59
|
image = args.fetch(:image, nil)
|
47
60
|
pvc = args.fetch(:pvc, nil)
|
48
61
|
init = args.fetch(:cloudinit, {})
|
62
|
+
networks = args.fetch(:networks)
|
63
|
+
interfaces = args.fetch(:interfaces)
|
49
64
|
|
50
65
|
if image.nil? && pvc.nil?
|
51
66
|
raise ::Fog::Kubevirt::Errors::ValidationError
|
52
67
|
end
|
53
|
-
|
54
|
-
volumes = []
|
55
68
|
|
69
|
+
volumes = []
|
70
|
+
volume_name = vm_name.gsub(/[._]+/,'-') + "-disk-01"
|
56
71
|
if !image.nil?
|
57
|
-
volumes.push(:name =>
|
72
|
+
volumes.push(:name => volume_name, :containerDisk => {:image => image})
|
58
73
|
else
|
59
|
-
volumes.push(:name =>
|
74
|
+
volumes.push(:name => volume_name, :persistentVolumeClaim => {:claimName => pvc})
|
60
75
|
end
|
61
76
|
|
62
77
|
unless init.empty?
|
@@ -64,7 +79,6 @@ module Fog
|
|
64
79
|
end
|
65
80
|
|
66
81
|
vm = {
|
67
|
-
:apiVersion => service.class::KUBEVIRT_VERSION_LABEL,
|
68
82
|
:kind => "VirtualMachine",
|
69
83
|
:metadata => {
|
70
84
|
:labels => {
|
@@ -90,7 +104,6 @@ module Fog
|
|
90
104
|
:bus => "virtio"
|
91
105
|
},
|
92
106
|
:name => vm_name,
|
93
|
-
:volumeName => vm_name
|
94
107
|
}
|
95
108
|
]
|
96
109
|
},
|
@@ -132,6 +145,30 @@ module Fog
|
|
132
145
|
:volumeName => "cloudinitvolume"
|
133
146
|
) unless init.empty?
|
134
147
|
|
148
|
+
vm = deep_merge!(vm,
|
149
|
+
:spec => {
|
150
|
+
:template => {
|
151
|
+
:spec => {
|
152
|
+
:networks => networks
|
153
|
+
}
|
154
|
+
}
|
155
|
+
}
|
156
|
+
) unless networks.nil?
|
157
|
+
|
158
|
+
vm = deep_merge!(vm,
|
159
|
+
:spec => {
|
160
|
+
:template => {
|
161
|
+
:spec => {
|
162
|
+
:domain => {
|
163
|
+
:devices => {
|
164
|
+
:interfaces => interfaces
|
165
|
+
}
|
166
|
+
}
|
167
|
+
}
|
168
|
+
}
|
169
|
+
}
|
170
|
+
) unless interfaces.nil?
|
171
|
+
|
135
172
|
service.create_vm(vm)
|
136
173
|
end
|
137
174
|
end
|
@@ -2,7 +2,80 @@ module Fog
|
|
2
2
|
module Compute
|
3
3
|
class Kubevirt
|
4
4
|
class Volume < Fog::Model
|
5
|
+
identity :name
|
5
6
|
|
7
|
+
attribute :resource_version, :aliases => 'metadata_resource_version'
|
8
|
+
attribute :uid, :aliases => 'metadata_uid'
|
9
|
+
attribute :annotations, :aliases => 'metadata_annotations'
|
10
|
+
attribute :labels, :aliases => 'metadata_labels'
|
11
|
+
attribute :access_modes, :aliases => 'spec_access_modes'
|
12
|
+
attribute :mount_options, :aliases => 'spec_mount_options'
|
13
|
+
attribute :reclaim_policy, :aliases => 'spec_reclaim_policy'
|
14
|
+
attribute :storage_class, :aliases => 'spec_storage_class'
|
15
|
+
attribute :capacity, :aliases => 'spec_capacity'
|
16
|
+
attribute :claim_ref, :aliases => 'spec_claim_ref'
|
17
|
+
attribute :type, :aliases => 'spec_type'
|
18
|
+
attribute :config, :aliases => 'spec_config'
|
19
|
+
attribute :phase, :aliases => 'status_phase'
|
20
|
+
attribute :reason, :aliases => 'status_reason'
|
21
|
+
attribute :message, :aliases => 'status_message'
|
22
|
+
|
23
|
+
def self.parse(object)
|
24
|
+
metadata = object[:metadata]
|
25
|
+
spec = object[:spec]
|
26
|
+
status = object[:status]
|
27
|
+
type = detect_type(spec)
|
28
|
+
|
29
|
+
{
|
30
|
+
:name => metadata[:name],
|
31
|
+
:resource_version => metadata[:resourceVersion],
|
32
|
+
:uid => metadata[:uid],
|
33
|
+
:annotations => metadata[:annotations],
|
34
|
+
:labels => metadata[:labels],
|
35
|
+
:access_modes => spec[:accessModes],
|
36
|
+
:mount_options => spec[:mountOptions],
|
37
|
+
:reclaim_policy => spec[:persistentVolumeReclaimPolicy],
|
38
|
+
:storage_class => spec[:storageClassName],
|
39
|
+
:capacity => spec.dig(:capacity, :storage),
|
40
|
+
:claim_ref => spec[:claimRef],
|
41
|
+
:type => type,
|
42
|
+
:config => spec[type&.to_sym],
|
43
|
+
:phase => status[:phase],
|
44
|
+
:reason => status[:reason],
|
45
|
+
:message => status[:message]
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.detect_type(spec)
|
50
|
+
type = ''
|
51
|
+
type = 'awsElasticBlockStore' if spec.keys.include?(:awsElasticBlockStore)
|
52
|
+
type = 'azureDisk' if spec.keys.include?(:azureDisk)
|
53
|
+
type = 'azureFile' if spec.keys.include?(:azureFile)
|
54
|
+
type = 'cephfs' if spec.keys.include?(:cephfs)
|
55
|
+
type = 'configMap' if spec.keys.include?(:configMap)
|
56
|
+
type = 'csi' if spec.keys.include?(:csi)
|
57
|
+
type = 'downwardAPI' if spec.keys.include?(:downwardAPI)
|
58
|
+
type = 'emptyDir' if spec.keys.include?(:emptyDir)
|
59
|
+
type = 'fc' if spec.keys.include?(:fc)
|
60
|
+
type = 'flexVolume' if spec.keys.include?(:flexVolume)
|
61
|
+
type = 'flocker' if spec.keys.include?(:flocker)
|
62
|
+
type = 'gcePersistentDisk' if spec.keys.include?(:gcePersistentDisk)
|
63
|
+
type = 'glusterfs' if spec.keys.include?(:glusterfs)
|
64
|
+
type = 'hostPath' if spec.keys.include?(:hostPath)
|
65
|
+
type = 'iscsi' if spec.keys.include?(:iscsi)
|
66
|
+
type = 'local' if spec.keys.include?(:local)
|
67
|
+
type = 'nfs' if spec.keys.include?(:nfs)
|
68
|
+
type = 'persistentVolumeClaim' if spec.keys.include?(:persistentVolumeClaim)
|
69
|
+
type = 'projected' if spec.keys.include?(:projected)
|
70
|
+
type = 'portworxVolume' if spec.keys.include?(:portworxVolume)
|
71
|
+
type = 'quobyte' if spec.keys.include?(:quobyte)
|
72
|
+
type = 'rbd' if spec.keys.include?(:rbd)
|
73
|
+
type = 'scaleIO' if spec.keys.include?(:scaleIO)
|
74
|
+
type = 'secret' if spec.keys.include?(:secret)
|
75
|
+
type = 'storageos' if spec.keys.include?(:storageos)
|
76
|
+
type = 'vsphereVolume' if spec.keys.include?(:vsphereVolume)
|
77
|
+
type
|
78
|
+
end
|
6
79
|
end
|
7
80
|
end
|
8
81
|
end
|
@@ -5,7 +5,68 @@ module Fog
|
|
5
5
|
module Compute
|
6
6
|
class Kubevirt
|
7
7
|
class Volumes < Fog::Collection
|
8
|
+
attr_reader :kind, :resource_version
|
9
|
+
|
8
10
|
model Fog::Compute::Kubevirt::Volume
|
11
|
+
|
12
|
+
def all(filters = {})
|
13
|
+
volumes = service.list_volumes(filters)
|
14
|
+
@kind = volumes.kind
|
15
|
+
@resource_version = volumes.resource_version
|
16
|
+
load volumes
|
17
|
+
end
|
18
|
+
|
19
|
+
def get(name)
|
20
|
+
new service.get_volume(name)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Creates a volume using provided paramters:
|
24
|
+
# :name [String] - name of a volume
|
25
|
+
# :labels [Hash] - a hash of key,values representing the labels
|
26
|
+
# :storage_class [String] - the storage class name of the volume
|
27
|
+
# :capacity [String] - The capacity of the storage if applied
|
28
|
+
# :accessModes [Arr] - the access modes for the volume, values are specified here:
|
29
|
+
# https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes
|
30
|
+
# :type [String] - the type of the storage
|
31
|
+
# :config [Hash] - storage specific configuration to be applied for the volume
|
32
|
+
# correlated to the args[:type]
|
33
|
+
# @param [Hash] attributes containing details about volume to be created.
|
34
|
+
def create(args = {})
|
35
|
+
name = args[:name]
|
36
|
+
labels = args[:labels]
|
37
|
+
|
38
|
+
volume = {
|
39
|
+
:apiVersion => "v1",
|
40
|
+
:kind => "PersistentVolume",
|
41
|
+
:metadata => {
|
42
|
+
:name => name
|
43
|
+
},
|
44
|
+
:spec => {
|
45
|
+
:storageClassName => args[:storage_class]
|
46
|
+
}
|
47
|
+
}
|
48
|
+
|
49
|
+
volume[:metadata][:labels] = labels if labels
|
50
|
+
volume[:spec][:capacity] = {
|
51
|
+
:storage => args[:capacity]
|
52
|
+
} if args[:capacity]
|
53
|
+
|
54
|
+
volume[:spec][:accessModes] = args[:access_modes] if args[:access_modes]
|
55
|
+
volume[:spec][args[:type].to_sym] = args[:config] if args[:type]
|
56
|
+
|
57
|
+
service.create_volume(volume)
|
58
|
+
end
|
59
|
+
|
60
|
+
def delete(name)
|
61
|
+
begin
|
62
|
+
volume = get(name)
|
63
|
+
rescue ::Fog::Kubevirt::Errors::ClientError
|
64
|
+
# the volume doesn't exist
|
65
|
+
volume = nil
|
66
|
+
end
|
67
|
+
|
68
|
+
service.delete_volume(name) unless volume.nil?
|
69
|
+
end
|
9
70
|
end
|
10
71
|
end
|
11
72
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Fog
|
2
|
+
module Compute
|
3
|
+
class Kubevirt
|
4
|
+
class Real
|
5
|
+
include Shared
|
6
|
+
|
7
|
+
# creates netwrork attachment definition object
|
8
|
+
# @param net_att[Hash] contains the following elements:
|
9
|
+
# metadata[Hash]: the net-attachment-def metadata:
|
10
|
+
# name[String]: the netwrork attachment definition definition
|
11
|
+
# spec[Hash]: the specification of the attachment, contains:config
|
12
|
+
# config[string]: the configuration of the attachment, i.e.
|
13
|
+
# '{ :cniVersion => "0.3.1", :type => "ovs", :bridge => "red" }'
|
14
|
+
# Example of net_att:
|
15
|
+
# metadata: {
|
16
|
+
# name: "ovs-red"},
|
17
|
+
# spec: {
|
18
|
+
# config: '{ cni_version: "0.3.1", type: "ovs", bridge: "red" }'
|
19
|
+
# }
|
20
|
+
def create_networkattachmentdef(net_att)
|
21
|
+
if net_att.dig(:metadata, :namespace).nil?
|
22
|
+
net_att = deep_merge!(net_att, metadata: { namespace: @namespace })
|
23
|
+
end
|
24
|
+
kube_net_client.create_network_attachment_definition(net_att)
|
25
|
+
rescue ::Fog::Kubevirt::Errors::ClientError => err
|
26
|
+
log.warn(err)
|
27
|
+
raise ::Fog::Kubevirt::Errors::AlreadyExistsError
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class Mock
|
32
|
+
def create_networkattachmentdef(_net_att_def)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Fog
|
2
|
+
module Compute
|
3
|
+
class Kubevirt
|
4
|
+
class Real
|
5
|
+
def create_volume(volume)
|
6
|
+
kube_client.create_persistent_volume(volume)
|
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_volume(volume)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Fog
|
2
|
+
module Compute
|
3
|
+
class Kubevirt
|
4
|
+
class Real
|
5
|
+
def delete_networkattachmentdef(name, namespace)
|
6
|
+
kube_net_client.delete_network_attachment_definition(name, namespace)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class Mock
|
11
|
+
def delete_networkattachmentdef(_name, _namespace)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'recursive_open_struct'
|
2
|
+
|
3
|
+
module Fog
|
4
|
+
module Compute
|
5
|
+
class Kubevirt
|
6
|
+
class Real
|
7
|
+
def get_networkattachmentdef(name)
|
8
|
+
net_attach_def = kube_net_client.get_network_attachment_definition(name, @namespace)
|
9
|
+
Networkattachmentdef.parse object_to_hash(net_attach_def)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class Mock
|
14
|
+
def get_networkattachmentdef(name)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -30,8 +30,8 @@ module Fog
|
|
30
30
|
},
|
31
31
|
:spec => { :domain => { :cpu => { :cores => "4" },
|
32
32
|
:devices => { :disks => [{ :disk => { :dev => "vda" },
|
33
|
-
:name => "
|
34
|
-
:volumeName => "
|
33
|
+
:name => "containerDisk",
|
34
|
+
:volumeName => "containervolume"
|
35
35
|
},
|
36
36
|
{ :disk => { :dev => "vdb" },
|
37
37
|
:name => "cloudinitdisk",
|
@@ -42,8 +42,8 @@ module Fog
|
|
42
42
|
:machine => { :type => "q35" },
|
43
43
|
:resources => { :requests => { :memory => "512Mi" }}
|
44
44
|
},
|
45
|
-
:volumes => [ { :name => "
|
46
|
-
:
|
45
|
+
:volumes => [ { :name => "containervolume",
|
46
|
+
:containerDisk => { :image => "kubevirt/fedora-cloud-registry-disk-demo:latest" }
|
47
47
|
},
|
48
48
|
{ :cloudInitNoCloud => { :userDataBase64 => "I2Nsb3VkLWNvbmZpZwpwYXNzd29yZDogYXRvbWljCnNzaF9wd2F1dGg6IFRydWUKY2hwYXNzd2Q6IHsgZXhwaXJlOiBGYWxzZSB9Cg==" },
|
49
49
|
:name => "cloudinitvolume"
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Fog
|
2
|
+
module Compute
|
3
|
+
class Kubevirt
|
4
|
+
class Real
|
5
|
+
def list_networkattachmentdefs(_filters = {})
|
6
|
+
netdefs = kube_net_client.get_network_attachment_definitions
|
7
|
+
entities = netdefs.map do |kubevirt_obj|
|
8
|
+
Networkattachmentdef.parse object_to_hash(kubevirt_obj)
|
9
|
+
end
|
10
|
+
EntityCollection.new(netdefs.kind, netdefs.resourceVersion, entities)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class Mock
|
15
|
+
# TODO provide implementation
|
16
|
+
def list_networkattachmentdefs(_filters = {})
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|