fog-kubevirt 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: db04da9d9e8117993d2eb4fc4630d6e670e19906
4
+ data.tar.gz: 7dd7992382563c3ce868a8e694c743295c329595
5
+ SHA512:
6
+ metadata.gz: 68653cae72af67f1d417718b95f89bcdc8fa96606fffbd0dd0035ead0a89b713ea801bd0e038f8ed5e49c7ee0bd14b56e1adb2cbdccda21f954d0d1b000b0533
7
+ data.tar.gz: c6b2b9f6d0bdeb9eb5e4a62962aa90fc8c654e81b8a182737935258b2fdfaa7003ca090e9d5b0c0b47819feabbbdf25b24c59877549e40fdba18c606ed85f607
@@ -0,0 +1,13 @@
1
+ Copyright (c) 2018 Red Hat, Inc.
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
@@ -0,0 +1,45 @@
1
+ # Fog::Kubevirt
2
+
3
+ fog-kubevirt is an kubevirt provider for [fog](https://github.com/fog/fog).
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'fog-kubevirt'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install fog-kubevirt
20
+
21
+ ## Usage
22
+
23
+ Require the gem:
24
+ ```ruby
25
+ require 'fog/kubevirt'
26
+ ```
27
+
28
+ Connect to kubevirt instance:
29
+ ```ruby
30
+
31
+ compute = Fog::Compute.new(
32
+ :provider => "kubevirt",
33
+ :kubevirt_token => token,
34
+ :kubevirt_server => server,
35
+ :kubevirt_port => port
36
+ )
37
+ ```
38
+
39
+ ## Contributing
40
+
41
+ Please refer to [CONTRIBUTING.md](CONTRIBUTING.md).
42
+
43
+ ## License
44
+
45
+ Please refer to [LICENSE.txt](LICENSE.txt).
@@ -0,0 +1,28 @@
1
+ class Kubevirt < Fog::Bin
2
+ class << self
3
+ def class_for(key)
4
+ case key
5
+ when :compute
6
+ Fog::Compute::Kubevirt
7
+ else
8
+ raise ArgumentError, "Unrecognized service: #{key}"
9
+ end
10
+ end
11
+
12
+ def [](service)
13
+ @@connections ||= Hash.new do |hash, key|
14
+ hash[key] = case key
15
+ when :compute
16
+ Fog::Compute.new(:provider => 'Kubevirt')
17
+ else
18
+ raise ArgumentError, "Unrecognized service: #{key.inspect}"
19
+ end
20
+ end
21
+ @@connections[service]
22
+ end
23
+
24
+ def services
25
+ Fog::Kubevirt.services
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,169 @@
1
+ module Fog
2
+ module Compute
3
+ class Kubevirt < Fog::Service
4
+ requires :kubevirt_token
5
+ recognizes :kubevirt_hostname, :kubevirt_port
6
+
7
+ model_path 'fog/compute/kubevirt/models'
8
+ model :livevm
9
+ collection :livevms
10
+ model :offlinevm
11
+ collection :offlinevms
12
+ model :template
13
+ collection :templates
14
+ model :volume
15
+ collection :volumes
16
+
17
+ request_path 'fog/compute/kubevirt/requests'
18
+
19
+ request :create_vm
20
+ request :create_offlinevm
21
+ request :create_pvc
22
+ request :destroy_vm
23
+ request :get_livevm
24
+ request :get_offlinevm
25
+ request :get_template
26
+ request :list_livevms
27
+ request :list_offlinevms
28
+ request :list_templates
29
+ request :update_offlinevm
30
+
31
+ module Shared
32
+ # converts kubeclient objects into hash for fog to consume
33
+ def object_to_hash(object)
34
+ result = object
35
+ case result
36
+ when OpenStruct
37
+ result = result.marshal_dump
38
+ result.each do |k, v|
39
+ result[k] = object_to_hash(v)
40
+ end
41
+ when Array
42
+ result = result.map { |v| object_to_hash(v) }
43
+ end
44
+
45
+ result
46
+ end
47
+ end
48
+
49
+ class Real
50
+ include Shared
51
+
52
+ #
53
+ # The API version and group of the Kubernetes core:
54
+ #
55
+ CORE_GROUP = ''.freeze
56
+ CORE_VERSION = 'v1'.freeze
57
+
58
+ #
59
+ # The API version and group of KubeVirt:
60
+ #
61
+ KUBEVIRT_GROUP = 'kubevirt.io'.freeze
62
+ KUBEVIRT_VERSION = 'v1alpha1'.freeze
63
+
64
+ def initialize(options={})
65
+ require 'kubeclient'
66
+
67
+ @kubevirt_token = options[:kubevirt_token]
68
+ @host = options[:kubevirt_hostname]
69
+ @port = options[:kubevirt_port]
70
+
71
+ @namespace = options[:kubevirt_namespace] || 'default'
72
+
73
+ # Prepare the TLS and authentication options that will be used for the standard Kubernetes API
74
+ # and also for the KubeVirt extension:
75
+ @opts = {
76
+ :ssl_options => {
77
+ :verify_ssl => OpenSSL::SSL::VERIFY_NONE,
78
+ },
79
+ :auth_options => {
80
+ :bearer_token => @kubevirt_token
81
+ }
82
+ }
83
+
84
+ # Kubeclient needs different client objects for different API groups. We will keep in this hash the
85
+ # client objects, indexed by API path/version.
86
+ @clients = {}
87
+
88
+ @client = kubevirt_client()
89
+
90
+ # TODO expect a specific token
91
+ @oc_client = openshift_client()
92
+ @kube_client = kube_client()
93
+ end
94
+
95
+ private
96
+
97
+ def client
98
+ @client
99
+ end
100
+
101
+ def oc_client
102
+ @oc_client
103
+ end
104
+
105
+ def kube_client
106
+ @kubeclient
107
+ end
108
+
109
+ #
110
+ # Lazily creates the a client for the given Kubernetes API path and version.
111
+ #
112
+ # @param path [String] The Kubernetes API path.
113
+ # @param version [String] The Kubernetes API version.
114
+ # @return [Kubeclient::Client] The client for the given path and version.
115
+ #
116
+ def create_client(path, version)
117
+ # Return the client immediately if it has been created before:
118
+ key = path + '/' + version
119
+ client = @clients[key]
120
+ return client if client
121
+
122
+ # Create the client and save it:
123
+ url = URI::Generic.build(
124
+ :scheme => 'https',
125
+ :host => @host,
126
+ :port => @port,
127
+ :path => path
128
+ )
129
+ client = Kubeclient::Client.new(
130
+ url.to_s,
131
+ version,
132
+ @opts
133
+ )
134
+ @clients[key] = client
135
+
136
+ # Return the client:
137
+ client
138
+ end
139
+
140
+ def openshift_client
141
+ create_client('/oapi', CORE_VERSION)
142
+ end
143
+
144
+ def kube_client
145
+ create_client('/api', CORE_VERSION)
146
+ end
147
+
148
+ def kubevirt_client
149
+ create_client('/apis/' + KUBEVIRT_GROUP, KUBEVIRT_VERSION)
150
+ end
151
+ end
152
+
153
+ class Mock
154
+ include Shared
155
+
156
+ def initialize(options={})
157
+ end
158
+
159
+ private
160
+
161
+ def client
162
+ return @client if defined?(@client)
163
+ end
164
+
165
+ # TODO provide mocking
166
+ end
167
+ end
168
+ end
169
+ end
@@ -0,0 +1,38 @@
1
+ module Fog
2
+ module Compute
3
+ class Kubevirt
4
+ class Livevm < Fog::Model
5
+ identity :name
6
+
7
+ attribute :namespace, :aliases => 'metadata_namespace'
8
+ attribute :resource_version, :aliases => 'metadata_resource_version'
9
+ attribute :uid, :aliases => 'metadata_uid'
10
+ attribute :owner_name, :aliases => 'metadata_owner_name'
11
+ attribute :owner_uid, :aliases => 'metadata_owner_uid'
12
+ attribute :cpu_cores, :aliases => 'spec_cpu_cores'
13
+ attribute :memory, :aliases => 'spec_memory'
14
+ attribute :disks, :aliases => 'spec_disks'
15
+ attribute :volumes, :aliases => 'spec_volumes'
16
+
17
+ def self.parse(object)
18
+ metadata = object[:metadata]
19
+ owner = metadata[:ownerReferences][0]
20
+ spec = object[:spec]
21
+ domain = spec[:domain]
22
+ {
23
+ :namespace => metadata[:namespace],
24
+ :name => metadata[:name],
25
+ :resource_version => metadata[:resourceVersion],
26
+ :uid => metadata[:uid],
27
+ :owner_name => owner[:name],
28
+ :owner_uid => owner[:uid],
29
+ :cpu_cores => domain[:cpu][:cores],
30
+ :memory => domain[:resources][:requests][:memory],
31
+ :disks => domain[:devices][:disks],
32
+ :volumes => spec[:volumes]
33
+ }
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,20 @@
1
+ require 'fog/core/collection'
2
+ require 'fog/compute/kubevirt/models/livevm'
3
+
4
+ module Fog
5
+ module Compute
6
+ class Kubevirt
7
+ class Livevms < Fog::Collection
8
+ model Fog::Compute::Kubevirt::Livevm
9
+
10
+ def all(filters = {})
11
+ load service.list_livevms(filters)
12
+ end
13
+
14
+ def get(name)
15
+ new service.get_livevm(name)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,49 @@
1
+ module Fog
2
+ module Compute
3
+ class Kubevirt
4
+ class Offlinevm < Fog::Model
5
+ identity :name
6
+
7
+ attribute :namespace, :aliases => 'metadata_namespace'
8
+ attribute :resource_version, :aliases => 'metadata_resource_version'
9
+ attribute :uid, :aliases => 'metadata_uid'
10
+ attribute :cpu_cores, :aliases => 'spec_cpu_cores'
11
+ attribute :memory, :aliases => 'spec_memory'
12
+ attribute :disks, :aliases => 'spec_disks'
13
+ attribute :volumes, :aliases => 'spec_volumes'
14
+
15
+
16
+ def start(options = {})
17
+ # Change the `running` attribute to `true` so that the offline virtual machine controller will take it and create
18
+ # the live virtual machine.
19
+ offline_vm = service.get_raw_offlinevm(name)
20
+ offline_vm = offline_vm.deep_merge(
21
+ :spec => {
22
+ :running => true
23
+ }
24
+ )
25
+ service.update_offline_vm(offline_vm)
26
+ end
27
+
28
+ def stop(options = {})
29
+ end
30
+
31
+ def self.parse(object)
32
+ metadata = object[:metadata]
33
+ spec = object[:spec][:template][:spec]
34
+ domain = spec[:domain]
35
+ {
36
+ :namespace => metadata[:namespace],
37
+ :name => metadata[:name],
38
+ :resource_version => metadata[:resourceVersion],
39
+ :uid => metadata[:uid],
40
+ :cpu_cores => domain[:cpu][:cores],
41
+ :memory => domain[:resources][:requests][:memory],
42
+ :disks => domain[:devices][:disks],
43
+ :volumes => spec[:volumes]
44
+ }
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,20 @@
1
+ require 'fog/core/collection'
2
+ require 'fog/compute/kubevirt/models/offlinevm'
3
+
4
+ module Fog
5
+ module Compute
6
+ class Kubevirt
7
+ class Offlinevms < Fog::Collection
8
+ model Fog::Compute::Kubevirt::Offlinevm
9
+
10
+ def all(filters = {})
11
+ load service.list_offlinevms(filters)
12
+ end
13
+
14
+ def get(name)
15
+ new service.get_offlinevm(name)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,185 @@
1
+ module Fog
2
+ module Compute
3
+ class Kubevirt
4
+ class Template < Fog::Model
5
+ identity :name, aliases: 'metadata_name'
6
+
7
+ attribute :namespace, aliases: 'metadata_namespace'
8
+ attribute :description, aliases: 'metadata_description'
9
+ attribute :tags, aliases: 'metadata_tags'
10
+ attribute :labels, aliases: 'metadata_labels'
11
+ attribute :resource_version, aliases: 'metadata_resource_version'
12
+ attribute :uid, aliases: 'metadata_uid'
13
+ attribute :objects
14
+ attribute :parameters
15
+
16
+ def clone(options = {})
17
+ params = values(options)
18
+
19
+ # use persistent volume claims if any from a template and send
20
+ create_persistent_volume_claims(persistent_volume_claims_from_objects(objects), params, namespace)
21
+
22
+ # use offline vm definition from a template and send
23
+ create_offline_vm(offline_vm_from_objects(objects), params, namespace)
24
+ end
25
+
26
+ def self.parse(object)
27
+ metadata = object[:metadata]
28
+ annotations = metadata[:annotations]
29
+ {
30
+ namespace: metadata[:namespace],
31
+ name: metadata[:name],
32
+ description: annotations[:description],
33
+ tags: annotations[:tags],
34
+ labels: metadata[:labels],
35
+ resource_version: metadata[:resourceVersion],
36
+ uid: metadata[:uid],
37
+ objects: object[:objects],
38
+ parameters: object[:parameters],
39
+ }
40
+ end
41
+
42
+ private
43
+
44
+ #
45
+ # Combines default values of the parameters defined in a template with values
46
+ # provided by the user on the UI.
47
+ #
48
+ # @param options [Hash] Hash containing values defined by the user on the UI.
49
+ #
50
+ def values(options)
51
+ default_params = {}
52
+ parameters.each do |param|
53
+ name = param[:name].downcase
54
+ value = options[name.to_sym]
55
+ if value && name == "memory"
56
+ value = value.to_s + 'Mi'
57
+ end
58
+
59
+ default_params[name] = value || param[:value]
60
+ end
61
+ default_params
62
+ end
63
+
64
+ #
65
+ # Creates an offline virtual machine within provided namespace.
66
+ #
67
+ # @param offline_vm [Hash] Offline virtual machine hash as defined in the template.
68
+ # @param params [Hash] Containing mapping of name and value.
69
+ # @param namespace [String] Namespace used to store the object.
70
+ #
71
+ def create_offline_vm(offline_vm, params, namespace)
72
+ offline_vm = param_substitution!(offline_vm, params)
73
+
74
+ offline_vm = offline_vm.deep_merge(
75
+ :metadata => {
76
+ :namespace => namespace
77
+ }
78
+ )
79
+
80
+ # Send the request to create the offline virtual machine:
81
+ offline_vm = service.create_offlinevm(offline_vm)
82
+ end
83
+
84
+ #
85
+ # Creates an persistent volume claims within provided namespace.
86
+ #
87
+ # @param pvcs Array[Hash] An array of pvc hashes as defined in the template.
88
+ # @param params [Hash] Containing mapping of name and value.
89
+ # @param namespace [String] Namespace used to store the object.
90
+ #
91
+ def create_persistent_volume_claims(pvcs, params, namespace)
92
+ pvcs.each do |pvc|
93
+ pvc = param_substitution!(pvc, params)
94
+
95
+ pvc = pvc.deep_merge(
96
+ :metadata => {
97
+ :namespace => namespace
98
+ }
99
+ )
100
+
101
+ # Send the request to create the persistent volume claim:
102
+ service.create_pvc(pvc)
103
+ end
104
+ end
105
+
106
+ #
107
+ # Returns object of `OfflineVirtualMachine` kind from provided objects.
108
+ #
109
+ # @param objects Array[Object] Objects defined in the template.
110
+ # @return [Hash] Offline virtual machine hash
111
+ #
112
+ def offline_vm_from_objects(objects)
113
+ vm = nil
114
+ objects.each do |object|
115
+ if object[:kind] == "OfflineVirtualMachine"
116
+ vm = object
117
+ end
118
+ end
119
+ # make sure there is one
120
+ raise ::Fog::Kubevirt::Errors::ServiceError if vm.nil?
121
+ vm
122
+ end
123
+
124
+ #
125
+ # Returns object of `PersistentVolumeClaim` kind from provided objects.
126
+ #
127
+ # @param objects Array[Object] Objects defined in the template.
128
+ # @return Array[Hash] An array of pvc hashes.
129
+ #
130
+ def persistent_volume_claims_from_objects(objects)
131
+ pvcs = []
132
+ objects.each do |object|
133
+ if object[:kind] == "PersistentVolumeClaim"
134
+ pvcs << object
135
+ end
136
+ end
137
+ pvcs
138
+ end
139
+
140
+ #
141
+ # Performs parameter substitution for specific object where we
142
+ # substitute ${params.key} with params[key].
143
+ #
144
+ # @param object [Hash | Array | String] Specific object where substitution takes place.
145
+ # @param params [Hash] Hash containing parameters to be substituted.
146
+ #
147
+ def param_substitution!(object, params)
148
+ result = object
149
+ case result
150
+ when Hash
151
+ result.each do |k, v|
152
+ result[k] = param_substitution!(v, params)
153
+ end
154
+ when Array
155
+ result.map { |v| param_substitution!(v, params) }
156
+ when String
157
+ result = sub_specific_object(params, object)
158
+ end
159
+ result
160
+ end
161
+
162
+ #
163
+ # Performs substitution on specific object.
164
+ #
165
+ # @params params [Hash] Containing parameter names and values used for substitution.
166
+ # @params object [String] Object on which substitution takes place.
167
+ # @returns [String] The outcome of substitution.
168
+ #
169
+ def sub_specific_object(params, object)
170
+ result = object
171
+ params.each_key do |name|
172
+ token = "${#{name.upcase}}"
173
+ next unless object.include?(token)
174
+ result = if params[name].kind_of?(String)
175
+ object.sub!(token, params[name])
176
+ else
177
+ params[name]
178
+ end
179
+ end
180
+ result
181
+ end
182
+ end
183
+ end
184
+ end
185
+ end
@@ -0,0 +1,20 @@
1
+ require 'fog/core/collection'
2
+ require 'fog/compute/kubevirt/models/template'
3
+
4
+ module Fog
5
+ module Compute
6
+ class Kubevirt
7
+ class Templates < Fog::Collection
8
+ model Fog::Compute::Kubevirt::Template
9
+
10
+ def all(filters = {})
11
+ load service.list_templates(filters)
12
+ end
13
+
14
+ def get(name)
15
+ new service.get_template(name)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,9 @@
1
+ module Fog
2
+ module Compute
3
+ class Kubevirt
4
+ class Volume < Fog::Model
5
+
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,12 @@
1
+ require 'fog/core/collection'
2
+ require 'fog/compute/kubevirt/models/volume'
3
+
4
+ module Fog
5
+ module Compute
6
+ class Kubevirt
7
+ class Volumes < Fog::Collection
8
+ model Fog::Compute::Kubevirt::Volume
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,17 @@
1
+ module Fog
2
+ module Compute
3
+ class Kubevirt
4
+ class Real
5
+ def create_offlinevm(vm)
6
+ kubevirt_client.create_offline_virtual_machine(vm)
7
+ rescue KubeException
8
+ raise ::Fog::Kubevirt::Errors::AlreadyExistsError
9
+ end
10
+ end
11
+
12
+ class Mock
13
+ def create_offlinevm(vm); end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module Fog
2
+ module Compute
3
+ class Kubevirt
4
+ class Real
5
+ def create_pvc(pvc)
6
+ kube_client.create_persistent_volume_claim(pvc)
7
+ rescue Kubeclient::HttpError
8
+ raise ::Fog::Kubevirt::Errors::AlreadyExistsError
9
+ end
10
+ end
11
+
12
+ class Mock
13
+ def create_pvc(attrs); end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,18 @@
1
+ module Fog
2
+ module Compute
3
+ class Kubevirt
4
+ class Real
5
+ def create_vm(vm)
6
+ kubevirt_client.create_virtual_machine(vm)
7
+ rescue Kubeclient::HttpError
8
+ raise ::Fog::Kubevirt::Errors::AlreadyExistsError
9
+ end
10
+ end
11
+
12
+ class Mock
13
+ def create_vm(vm)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,15 @@
1
+ module Fog
2
+ module Compute
3
+ class Kubevirt
4
+ class Real
5
+ def destroy_vm(options = {})
6
+ end
7
+ end
8
+
9
+ class Mock
10
+ def destroy_vm(options = {})
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,41 @@
1
+ require 'recursive_open_struct'
2
+
3
+ module Fog
4
+ module Compute
5
+ class Kubevirt
6
+ class Real
7
+ def get_livevm(name)
8
+ Livevm.parse object_to_hash( kubevirt_client.get_virtual_machine(name, 'default') )
9
+ end
10
+ end
11
+
12
+ class Mock
13
+ def get_livevm(name)
14
+ vm = {:apiVersion=>"kubevirt.io/v1alpha1",
15
+ :kind=>"VirtualMachine",
16
+ :metadata=>{:clusterName=>"",
17
+ :creationTimestamp=>"2018-02-23T10:12:47Z",
18
+ :name=>"demo",
19
+ :namespace=>"default",
20
+ :ownerReferences=>[{:apiVersion=>"kubevirt.io/v1alpha1",
21
+ :kind=>"OfflineVirtualMachine",
22
+ :name=>"demo",
23
+ :uid=>"57e279c1-17ee-11e8-a9f9-525400a7f647"}],
24
+ :resourceVersion=>"84873",
25
+ :selfLink=>"/apis/kubevirt.io/v1alpha1/namespaces/default/virtualmachines/demo",
26
+ :uid=>"1906421f-1882-11e8-b539-525400a7f647"},
27
+ :spec=>{:domain=>{:cpu=>{:cores=>"4"},
28
+ :devices=>{:disks=>[{:disk=>{:dev=>"vda"}, :name=>"registrydisk", :volumeName=>"registryvolume"},
29
+ {:disk=>{:dev=>"vdb"}, :name=>"cloudinitdisk", :volumeName=>"cloudinitvolume"}]},
30
+ :machine=>{:type=>"q35"},
31
+ :resources=>{:requests=>{:memory=>"512Mi"}}},
32
+ :volumes=>[{:name=>"registryvolume", :registryDisk=>{:image=>"kubevirt/fedora-cloud-registry-disk-demo:latest"}},
33
+ {:cloudInitNoCloud=>{:userDataBase64=>"I2Nsb3VkLWNvbmZpZwpwYXNzd29yZDogYXRvbWljCnNzaF9wd2F1dGg6IFRydWUKY2hwYXNzd2Q6IHsgZXhwaXJlOiBGYWxzZSB9Cg=="},
34
+ :name=>"cloudinitvolume"}]}}
35
+ object = RecursiveOpenStruct.new(vm, recurse_over_arrays: true)
36
+ Livevm.parse object_to_hash(object)
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,23 @@
1
+ module Fog
2
+ module Compute
3
+ class Kubevirt
4
+ class Real
5
+ def get_offlinevm(name)
6
+ Offlinevm.parse get_raw_offlinevm(name)
7
+ end
8
+
9
+ def get_raw_offlinevm(name)
10
+ object_to_hash( kubevirt_client.get_offline_virtual_machine(name, 'default') )
11
+ end
12
+ end
13
+
14
+ class Mock
15
+ def get_offlinevm(name)
16
+ end
17
+
18
+ def get_raw_offlinevm(name)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,16 @@
1
+ module Fog
2
+ module Compute
3
+ class Kubevirt
4
+ class Real
5
+ def get_template(name)
6
+ Template.parse object_to_hash( oc_client.get_template(name, 'default') )
7
+ end
8
+ end
9
+
10
+ class Mock
11
+ def get_template(name)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Fog
2
+ module Compute
3
+ class Kubevirt
4
+ class Real
5
+ def list_livevms(_filters = {})
6
+ kubevirt_client.get_virtual_machines(namespace: 'default').map { |kubevirt_obj| Livevm.parse object_to_hash(kubevirt_obj) }
7
+ end
8
+ end
9
+
10
+ class Mock
11
+ def list_livevms(_filters = {})
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,48 @@
1
+ require 'recursive_open_struct'
2
+
3
+ module Fog
4
+ module Compute
5
+ class Kubevirt
6
+ class Real
7
+ def list_offlinevms(_filters = {})
8
+ kubevirt_client.get_offline_virtual_machines(namespace: 'default').map { |kubevirt_obj| Offlinevm.parse object_to_hash(kubevirt_obj) }
9
+ end
10
+ end
11
+
12
+ class Mock
13
+ def list_offlinevms(_filters = {})
14
+ offlinevms = [{ apiVersion: 'kubevirt.io/v1alpha1',
15
+ kind: 'OfflineVirtualMachine',
16
+ metadata: {
17
+ clusterName: '',
18
+ creationTimestamp: '2018-02-21T11:15:41Z',
19
+ name: 'aaa',
20
+ namespace: 'default',
21
+ resourceVersion: '967810',
22
+ selfLink: '/apis/kubevirt.io/v1alpha1/namespaces/default/offlinevirtualmachines/aaa',
23
+ uid: '8d27ad76-16f8-11e8-95dc-525400b2cba8'
24
+ },
25
+ spec: {
26
+ template: {
27
+ spec: { domain: { cpu: { cores: 4 },
28
+ devices: { disks: [{ disk: { dev: 'vda' },
29
+ name: 'registrydisk',
30
+ volumeName: 'registryvolume' },
31
+ { disk: { dev: 'vdb' },
32
+ name: 'cloudinitdisk',
33
+ volumeName: 'cloudinitvolume' }] },
34
+ machine: { type: 'q35' },
35
+ resources: { requests: { memory: '512Mi' } } },
36
+ volumes: [{ name: 'registryvolume',
37
+ registryDisk: { image: 'kubevirt/fedora-cloud-registry-disk-demo:latest' } },
38
+ { cloudInitNoCloud: { userDataBase64: 'I2Nsb3VkLWNvbmZpZwpwYXNzd29yZDogYXRvbWljCnNzaF9wd2F1dGg6IFRydWUKY2hwYXNzd2Q6IHsgZXhwaXJlOiBGYWxzZSB9Cg==' },
39
+ name: 'cloudinitvolume' }] }
40
+ }
41
+ } }]
42
+ object = RecursiveOpenStruct.new(offlinevms, recurse_over_arrays: true)
43
+ object.map { |kubevirt_obj| Offlinevm.parse object_to_hash(kubevirt_obj) }
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,47 @@
1
+ require 'recursive_open_struct'
2
+
3
+ module Fog
4
+ module Compute
5
+ class Kubevirt
6
+ class Real
7
+ def list_templates(_filters = {})
8
+ oc_client.get_templates(namespace: 'default').map { |kubevirt_obj| Template.parse object_to_hash(kubevirt_obj) }
9
+ end
10
+ end
11
+
12
+ class Mock
13
+ def list_templates(_filters = {})
14
+ templates = [{ metadata: { name: 'linux-vm-template',
15
+ namespace: 'default',
16
+ selfLink: '/oapi/v1/namespaces/default/templates/linux-vm-template',
17
+ uid: '610c434f-17bc-11e8-a9f9-525400a7f647',
18
+ resourceVersion: '9240',
19
+ creationTimestamp: '2018-02-22T10:37:28Z',
20
+ labels: { :"miq.github.io/kubevirt-is-vm-template" => 'true',
21
+ :"miq.github.io/kubevirt-os" => 'rhel-7' },
22
+ annotations: { description: 'OCP kubevirt linux, template',
23
+ tags: 'kubevirt,ocp,template,linux' } },
24
+ objects: [{ apiVersion: 'kubevirt.io/v1alpha1',
25
+ kind: 'OfflineVirtualMachine',
26
+ metadata: { name: '${NAME}' },
27
+ spec: { template: { spec: { domain:
28
+ { cpu: { cores: '${CPU_CORES}' },
29
+ devices: { disks: [{ disk: { dev: 'vda' }, name: 'disk0', volumeName: 'disk0-pvc' }] },
30
+ machine: { type: 'q35' },
31
+ resources: { requests: { memory: '${MEMORY}' } } },
32
+ volumes: [{ name: 'disk0-pvc', persistentVolumeClaim: { claimName: 'linux-vm-pvc-${NAME}' } }] } } } },
33
+ { apiVersion: 'v1',
34
+ kind: 'PersistentVolumeClaim',
35
+ metadata: { name: 'linux-vm-pvc-${NAME}' },
36
+ spec: { accessModes: ['ReadWriteOnce'],
37
+ resources: { requests: { storage: '10Gi' } } } }],
38
+ parameters: [{ name: 'NAME', description: 'Name for the new VM' },
39
+ { name: 'MEMORY', description: 'Amount of memory', value: '4096Mi' },
40
+ { name: 'CPU_CORES', description: 'Amount of cores', value: '4' }] }]
41
+ object = RecursiveOpenStruct.new(templates, recurse_over_arrays: true)
42
+ object.map { |kubevirt_obj| Template.parse object_to_hash(kubevirt_obj) }
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,16 @@
1
+ module Fog
2
+ module Compute
3
+ class Kubevirt
4
+ class Real
5
+ def update_offline_vm(update)
6
+ kubevirt_client.update_offline_virtual_machine(update)
7
+ end
8
+ end
9
+
10
+ class Mock
11
+ def update_offline_vm(update)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,18 @@
1
+ require 'fog/core'
2
+
3
+ module Fog
4
+ module Compute
5
+ autoload :Kubevirt, File.expand_path('../compute/kubevirt', __FILE__)
6
+ end
7
+
8
+ module Kubevirt
9
+ extend Fog::Provider
10
+
11
+ module Errors
12
+ class ServiceError < Fog::Errors::Error; end
13
+ class AlreadyExistsError < Fog::Errors::Error; end
14
+ end
15
+
16
+ service(:compute, 'Compute')
17
+ end
18
+ end
@@ -0,0 +1,5 @@
1
+ module Fog
2
+ module Kubevirt
3
+ VERSION = '0.1.0'
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,159 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fog-kubevirt
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Piotr Kliczewski
8
+ - Moti Asayag
9
+ - Paulo Ribeiro
10
+ - Wesley Beary
11
+ autorequire:
12
+ bindir: bin
13
+ cert_chain: []
14
+ date: 2018-04-18 00:00:00.000000000 Z
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: bundler
18
+ requirement: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - "~>"
21
+ - !ruby/object:Gem::Version
22
+ version: '1.3'
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '1.3'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: '0'
37
+ type: :development
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ - !ruby/object:Gem::Dependency
45
+ name: rspec
46
+ requirement: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - "~>"
49
+ - !ruby/object:Gem::Version
50
+ version: '3.0'
51
+ type: :development
52
+ prerelease: false
53
+ version_requirements: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - "~>"
56
+ - !ruby/object:Gem::Version
57
+ version: '3.0'
58
+ - !ruby/object:Gem::Dependency
59
+ name: rubocop
60
+ requirement: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ type: :development
66
+ prerelease: false
67
+ version_requirements: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ - !ruby/object:Gem::Dependency
73
+ name: fog-core
74
+ requirement: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - "~>"
77
+ - !ruby/object:Gem::Version
78
+ version: '1.45'
79
+ type: :runtime
80
+ prerelease: false
81
+ version_requirements: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - "~>"
84
+ - !ruby/object:Gem::Version
85
+ version: '1.45'
86
+ - !ruby/object:Gem::Dependency
87
+ name: kubeclient
88
+ requirement: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - "~>"
91
+ - !ruby/object:Gem::Version
92
+ version: 2.5.2
93
+ type: :runtime
94
+ prerelease: false
95
+ version_requirements: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - "~>"
98
+ - !ruby/object:Gem::Version
99
+ version: 2.5.2
100
+ description: This library can be used as a module for `fog`.
101
+ email:
102
+ - piotr.kliczewski@gmail.com
103
+ - masayag@redhat.com
104
+ - plribeiro3000@gmail.com
105
+ - geemus@gmail.com
106
+ executables: []
107
+ extensions: []
108
+ extra_rdoc_files: []
109
+ files:
110
+ - LICENSE.txt
111
+ - README.md
112
+ - lib/fog/bin/kubevirt.rb
113
+ - lib/fog/compute/kubevirt.rb
114
+ - lib/fog/compute/kubevirt/models/livevm.rb
115
+ - lib/fog/compute/kubevirt/models/livevms.rb
116
+ - lib/fog/compute/kubevirt/models/offlinevm.rb
117
+ - lib/fog/compute/kubevirt/models/offlinevms.rb
118
+ - lib/fog/compute/kubevirt/models/template.rb
119
+ - lib/fog/compute/kubevirt/models/templates.rb
120
+ - lib/fog/compute/kubevirt/models/volume.rb
121
+ - lib/fog/compute/kubevirt/models/volumes.rb
122
+ - lib/fog/compute/kubevirt/requests/create_offlinevm.rb
123
+ - lib/fog/compute/kubevirt/requests/create_pvc.rb
124
+ - lib/fog/compute/kubevirt/requests/create_vm.rb
125
+ - lib/fog/compute/kubevirt/requests/destroy_vm.rb
126
+ - lib/fog/compute/kubevirt/requests/get_livevm.rb
127
+ - lib/fog/compute/kubevirt/requests/get_offlinevm.rb
128
+ - lib/fog/compute/kubevirt/requests/get_template.rb
129
+ - lib/fog/compute/kubevirt/requests/list_livevms.rb
130
+ - lib/fog/compute/kubevirt/requests/list_offlinevms.rb
131
+ - lib/fog/compute/kubevirt/requests/list_templates.rb
132
+ - lib/fog/compute/kubevirt/requests/update_offlinevm.rb
133
+ - lib/fog/kubevirt.rb
134
+ - lib/fog/kubevirt/version.rb
135
+ homepage: https://github.com/pkliczewski/fog-kubevirt
136
+ licenses:
137
+ - Apache-2.0
138
+ metadata: {}
139
+ post_install_message:
140
+ rdoc_options: []
141
+ require_paths:
142
+ - lib
143
+ required_ruby_version: !ruby/object:Gem::Requirement
144
+ requirements:
145
+ - - ">="
146
+ - !ruby/object:Gem::Version
147
+ version: '0'
148
+ required_rubygems_version: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ requirements: []
154
+ rubyforge_project:
155
+ rubygems_version: 2.6.14
156
+ signing_key:
157
+ specification_version: 4
158
+ summary: Module for the 'fog' gem to support Kubevirt.
159
+ test_files: []