fog-kubevirt 0.1.8 → 0.2.0
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 +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
|