fog-kubevirt 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: db04da9d9e8117993d2eb4fc4630d6e670e19906
4
- data.tar.gz: 7dd7992382563c3ce868a8e694c743295c329595
3
+ metadata.gz: 503961b1ff1942c2afe14fb611d555cbe7f3020d
4
+ data.tar.gz: 63e5dd9843c6d843394a830d2aa725cc6511b605
5
5
  SHA512:
6
- metadata.gz: 68653cae72af67f1d417718b95f89bcdc8fa96606fffbd0dd0035ead0a89b713ea801bd0e038f8ed5e49c7ee0bd14b56e1adb2cbdccda21f954d0d1b000b0533
7
- data.tar.gz: c6b2b9f6d0bdeb9eb5e4a62962aa90fc8c654e81b8a182737935258b2fdfaa7003ca090e9d5b0c0b47819feabbbdf25b24c59877549e40fdba18c606ed85f607
6
+ metadata.gz: 646e2fcf922326488c8e98885624f0315ab876b9c2beed165783b4bcaeae12f8ca8ed8bfb69c98de8cb4b6a0ed6d3397d2f6e80b57a816c30baf88998ff539ec
7
+ data.tar.gz: 572ac0f6197416be7f96a5c2d5054d5788ef337d809a1e84dca69ecba87ac82a4de35a49091320730622a42b363fc316d3756231a4f3789cb2fa62238ef3487e
@@ -1,12 +1,19 @@
1
+ require 'delegate'
2
+ require 'logger'
3
+
4
+ require "fog/core"
5
+
1
6
  module Fog
2
7
  module Compute
3
8
  class Kubevirt < Fog::Service
4
9
  requires :kubevirt_token
5
- recognizes :kubevirt_hostname, :kubevirt_port
10
+ recognizes :kubevirt_hostname, :kubevirt_port, :kubevirt_namespace, :kubevirt_log
6
11
 
7
12
  model_path 'fog/compute/kubevirt/models'
8
13
  model :livevm
9
14
  collection :livevms
15
+ model :node
16
+ collection :nodes
10
17
  model :offlinevm
11
18
  collection :offlinevms
12
19
  model :template
@@ -19,16 +26,38 @@ module Fog
19
26
  request :create_vm
20
27
  request :create_offlinevm
21
28
  request :create_pvc
22
- request :destroy_vm
29
+ request :delete_livevm
30
+ request :delete_offlinevm
23
31
  request :get_livevm
32
+ request :get_node
24
33
  request :get_offlinevm
25
34
  request :get_template
26
35
  request :list_livevms
36
+ request :list_nodes
27
37
  request :list_offlinevms
28
38
  request :list_templates
29
39
  request :update_offlinevm
30
40
 
31
41
  module Shared
42
+
43
+ class EntityCollection < DelegateClass(Array)
44
+ attr_reader :kind, :resource_version, :uid, :type
45
+
46
+ def initialize(kind, resource_version, uid, type, entities)
47
+ @kind = kind
48
+ @resource_version = resource_version
49
+ @uid = uid
50
+ @type = type
51
+ super(entities)
52
+ end
53
+ end
54
+
55
+ #
56
+ # Label name which identifies operation system information
57
+ #
58
+ OS_LABEL = 'kubevirt.io/os'.freeze
59
+ OS_LABEL_SYMBOL = :'kubevirt.io/os'
60
+
32
61
  # converts kubeclient objects into hash for fog to consume
33
62
  def object_to_hash(object)
34
63
  result = object
@@ -44,9 +73,31 @@ module Fog
44
73
 
45
74
  result
46
75
  end
76
+
77
+ # Copied from rails:
78
+ # File activesupport/lib/active_support/core_ext/hash/deep_merge.rb, line 21
79
+ # The method was changed to look like this in v4.0.0 of rails
80
+ def deep_merge!(source_hash, other_hash, &block)
81
+ other_hash.each_pair do |current_key, other_value|
82
+ this_value = source_hash[current_key]
83
+
84
+ source_hash[current_key] = if this_value.is_a?(Hash) && other_value.is_a?(Hash)
85
+ this_value = deep_merge!(this_value, other_value, &block)
86
+ else
87
+ if block_given? && key?(current_key)
88
+ block.call(current_key, this_value, other_value)
89
+ else
90
+ other_value
91
+ end
92
+ end
93
+ end
94
+
95
+ source_hash
96
+ end
47
97
  end
48
98
 
49
99
  class Real
100
+ require "ostruct"
50
101
  include Shared
51
102
 
52
103
  #
@@ -65,8 +116,11 @@ module Fog
65
116
  require 'kubeclient'
66
117
 
67
118
  @kubevirt_token = options[:kubevirt_token]
68
- @host = options[:kubevirt_hostname]
69
- @port = options[:kubevirt_port]
119
+ @host = options[:kubevirt_hostname]
120
+ @port = options[:kubevirt_port]
121
+
122
+ @log = options[:kubevirt_log]
123
+ @log ||= Logger.new(STDOUT)
70
124
 
71
125
  @namespace = options[:kubevirt_namespace] || 'default'
72
126
 
@@ -84,26 +138,149 @@ module Fog
84
138
  # Kubeclient needs different client objects for different API groups. We will keep in this hash the
85
139
  # client objects, indexed by API path/version.
86
140
  @clients = {}
141
+ end
87
142
 
88
- @client = kubevirt_client()
143
+ def virt_supported?
144
+ virt_enabled = false
145
+
146
+ begin
147
+ virt_enabled = kubevirt_client.api["versions"].any? { |ver| ver["groupVersion"]&.start_with?(KUBEVIRT_GROUP) }
148
+ rescue => err
149
+ # we failed to communicate or to evaluate the version format
150
+ @log.warn("Failed to detect kubevirt on provider with error: #{err.message}")
151
+ end
89
152
 
90
- # TODO expect a specific token
91
- @oc_client = openshift_client()
92
- @kube_client = kube_client()
153
+ virt_enabled
93
154
  end
94
155
 
95
- private
156
+ def valid?
157
+ kube_client.api_valid?
158
+ end
96
159
 
97
- def client
98
- @client
160
+ class WatchWrapper
161
+
162
+ def initialize(watch, mapper)
163
+ @watch = watch
164
+ @mapper = mapper
165
+ end
166
+
167
+ def each
168
+ @watch.each do |notice|
169
+ yield @mapper.call(notice)
170
+ end
171
+ end
172
+
173
+ def finish
174
+ @watch.finish
175
+ end
99
176
  end
100
177
 
101
- def oc_client
102
- @oc_client
178
+ #
179
+ # Returns a watcher for nodes.
180
+ #
181
+ # @param opts [Hash] A hash with options for the watcher.
182
+ # @return [WatchWrapper] The watcher.
183
+ #
184
+ def watch_nodes(opts = {})
185
+ mapper = Proc.new do |notice|
186
+ node = OpenStruct.new(Node.parse(notice.object)) if notice.object.kind == 'Node'
187
+ node ||= OpenStruct.new
188
+
189
+ populate_notice_attributes(node, notice)
190
+ node
191
+ end
192
+ watch = kube_client.watch_nodes(opts)
193
+
194
+ WatchWrapper.new(watch, mapper)
103
195
  end
104
196
 
105
- def kube_client
106
- @kubeclient
197
+ #
198
+ # Returns a watcher for offline virtual machines.
199
+ #
200
+ # @param opts [Hash] A hash with options for the watcher.
201
+ # @return [WatchWrapper] The watcher.
202
+ #
203
+ def watch_offline_vms(opts = {})
204
+ mapper = Proc.new do |notice|
205
+ offlinevm = OpenStruct.new(Offlinevm.parse(notice.object)) if notice.object.kind == 'OfflineVirtualMachine'
206
+ offlinevm ||= OpenStruct.new
207
+
208
+ populate_notice_attributes(offlinevm, notice)
209
+ offlinevm
210
+ end
211
+ watch = kubevirt_client.watch_offline_virtual_machines(opts)
212
+
213
+ WatchWrapper.new(watch, mapper)
214
+ end
215
+
216
+ #
217
+ # Returns a watcher for live virtual machines.
218
+ #
219
+ # @param opts [Hash] A hash with options for the watcher.
220
+ # @return [WatchWrapper] The watcher.
221
+ #
222
+ def watch_live_vms(opts = {})
223
+ mapper = Proc.new do |notice|
224
+ livevm = OpenStruct.new(Livevm.parse(notice.object)) if notice.object.kind == 'VirtualMachine'
225
+ livevm ||= OpenStruct.new
226
+
227
+ populate_notice_attributes(livevm, notice)
228
+ livevm
229
+ end
230
+ watch = kubevirt_client.watch_virtual_machines(opts)
231
+
232
+ WatchWrapper.new(watch, mapper)
233
+ end
234
+
235
+ #
236
+ # Returns a watcher for templates.
237
+ #
238
+ # @param opts [Hash] A hash with options for the watcher.
239
+ # @return [WatchWrapper] The watcher.
240
+ #
241
+ def watch_templates(opts = {})
242
+ mapper = Proc.new do |notice|
243
+ template = OpenStruct.new(Template.parse(notice.object)) if notice.object.kind == 'Template'
244
+ template ||= OpenStruct.new
245
+
246
+ populate_notice_attributes(template, notice)
247
+ template
248
+ end
249
+ watch = openshift_client.watch_templates(opts)
250
+
251
+ WatchWrapper.new(watch, mapper)
252
+ end
253
+
254
+ #
255
+ # Calculates the URL of the SPICE proxy server.
256
+ #
257
+ # @return [String] The URL of the spice proxy server.
258
+ #
259
+ def spice_proxy_url
260
+ service = kube_client.get_service('spice-proxy', @namespace)
261
+ host = service.spec.externalIPs.first
262
+ port = service.spec.ports.first.port
263
+ url = URI::Generic.build(
264
+ :scheme => 'http',
265
+ :host => host,
266
+ :port => port,
267
+ )
268
+ url.to_s
269
+ end
270
+
271
+ private
272
+
273
+
274
+ #
275
+ # Populates required notice attributes
276
+ #
277
+ # @param object entity to populate
278
+ # @param notice the source of the data to populate from
279
+ def populate_notice_attributes(object, notice)
280
+ object.metadata = notice.object.metadata
281
+ object.type = notice.type
282
+ object.code = notice.object.code
283
+ object.kind = notice.object.kind
107
284
  end
108
285
 
109
286
  #
@@ -148,6 +325,10 @@ module Fog
148
325
  def kubevirt_client
149
326
  create_client('/apis/' + KUBEVIRT_GROUP, KUBEVIRT_VERSION)
150
327
  end
328
+
329
+ def log
330
+ @log
331
+ end
151
332
  end
152
333
 
153
334
  class Mock
@@ -13,9 +13,12 @@ module Fog
13
13
  attribute :memory, :aliases => 'spec_memory'
14
14
  attribute :disks, :aliases => 'spec_disks'
15
15
  attribute :volumes, :aliases => 'spec_volumes'
16
+ attribute :ip_address, :aliases => 'status_interfaces_ip'
17
+ attribute :node_name, :aliases => 'status_node_name'
16
18
 
17
19
  def self.parse(object)
18
20
  metadata = object[:metadata]
21
+ status = object[:status]
19
22
  owner = metadata[:ownerReferences][0]
20
23
  spec = object[:spec]
21
24
  domain = spec[:domain]
@@ -29,7 +32,9 @@ module Fog
29
32
  :cpu_cores => domain[:cpu][:cores],
30
33
  :memory => domain[:resources][:requests][:memory],
31
34
  :disks => domain[:devices][:disks],
32
- :volumes => spec[:volumes]
35
+ :volumes => spec[:volumes],
36
+ :ip_address => status.dig(:interfaces, 0, :ipAddress),
37
+ :node_name => status[:nodeName]
33
38
  }
34
39
  end
35
40
  end
@@ -5,15 +5,35 @@ module Fog
5
5
  module Compute
6
6
  class Kubevirt
7
7
  class Livevms < Fog::Collection
8
+ attr_reader :kind, :resourceVersion
9
+
8
10
  model Fog::Compute::Kubevirt::Livevm
9
11
 
10
12
  def all(filters = {})
11
- load service.list_livevms(filters)
13
+ vms = service.list_livevms(filters)
14
+ kind = vms.kind
15
+ resourceVersion = vms.resourceVersion
16
+ load vms
12
17
  end
13
18
 
14
19
  def get(name)
15
20
  new service.get_livevm(name)
16
21
  end
22
+
23
+ def destroy(name, namespace)
24
+ begin
25
+ live_vm = get(name)
26
+ rescue KubeException
27
+ # the live virtual machine doesn't exist
28
+ live_vm = nil
29
+ end
30
+
31
+ # delete offline vm
32
+ service.delete_offlinevm(name, namespace)
33
+
34
+ # delete live vm
35
+ service.delete_livevm(name, namespace) unless live_vm.nil?
36
+ end
17
37
  end
18
38
  end
19
39
  end
@@ -0,0 +1,39 @@
1
+ module Fog
2
+ module Compute
3
+ class Kubevirt
4
+ class Node < 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 :os_image, :aliases => 'status_node_info_os_image'
11
+ attribute :operating_system, :aliases => 'status_node_info_operating_system'
12
+ attribute :kernel_version, :aliases => 'status_node_info_kernel_version'
13
+ attribute :hostname, :aliases => 'status_addresses_hostname'
14
+ attribute :ip_address, :aliases => 'status_addresses_ip'
15
+
16
+ def self.parse(object)
17
+ metadata = object[:metadata]
18
+ status = object[:status]
19
+ info = status[:nodeInfo]
20
+
21
+ addresses = status[:addresses]
22
+ hostname = addresses.detect { |address| address[:type] == 'Hostname' }[:address]
23
+ ip = addresses.detect { |address| address[:type] == 'InternalIP' }[:address]
24
+ {
25
+ :namespace => metadata[:namespace],
26
+ :name => metadata[:name],
27
+ :resource_version => metadata[:resourceVersion],
28
+ :uid => metadata[:uid],
29
+ :os_image => info[:osImage],
30
+ :operating_system => info[:operatingSystem],
31
+ :kernel_version => info[:kernelVersion],
32
+ :hostname => hostname,
33
+ :ip_address => ip
34
+ }
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,25 @@
1
+ require 'fog/core/collection'
2
+ require 'fog/compute/kubevirt/models/node'
3
+
4
+ module Fog
5
+ module Compute
6
+ class Kubevirt
7
+ class Nodes < Fog::Collection
8
+ attr_reader :kind, :resourceVersion
9
+
10
+ model Fog::Compute::Kubevirt::Node
11
+
12
+ def all(filters = {})
13
+ nodes = service.list_nodes(filters)
14
+ kind = nodes.kind
15
+ resourceVersion = nodes.resourceVersion
16
+ load nodes
17
+ end
18
+
19
+ def get(name)
20
+ new service.get_node(name)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -2,11 +2,16 @@ module Fog
2
2
  module Compute
3
3
  class Kubevirt
4
4
  class Offlinevm < Fog::Model
5
+ include Shared
6
+
5
7
  identity :name
6
8
 
7
9
  attribute :namespace, :aliases => 'metadata_namespace'
8
10
  attribute :resource_version, :aliases => 'metadata_resource_version'
9
11
  attribute :uid, :aliases => 'metadata_uid'
12
+ attribute :labels, :aliases => 'metadata_labels'
13
+ attribute :owner_reference, :aliases => 'metadata_owner_reference'
14
+ attribute :annotations, :aliases => 'metadata_annotations'
10
15
  attribute :cpu_cores, :aliases => 'spec_cpu_cores'
11
16
  attribute :memory, :aliases => 'spec_memory'
12
17
  attribute :disks, :aliases => 'spec_disks'
@@ -14,10 +19,10 @@ module Fog
14
19
 
15
20
 
16
21
  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.
22
+ # Change the `running` attribute to `true` so that the offline virtual machine controller will take it and
23
+ # create the live virtual machine.
19
24
  offline_vm = service.get_raw_offlinevm(name)
20
- offline_vm = offline_vm.deep_merge(
25
+ offline_vm = deep_merge!(offline_vm,
21
26
  :spec => {
22
27
  :running => true
23
28
  }
@@ -26,6 +31,13 @@ module Fog
26
31
  end
27
32
 
28
33
  def stop(options = {})
34
+ offline_vm = service.get_raw_offlinevm(name)
35
+ offline_vm = deep_merge!(offline_vm,
36
+ :spec => {
37
+ :running => false
38
+ }
39
+ )
40
+ service.update_offline_vm(offline_vm)
29
41
  end
30
42
 
31
43
  def self.parse(object)
@@ -37,6 +49,9 @@ module Fog
37
49
  :name => metadata[:name],
38
50
  :resource_version => metadata[:resourceVersion],
39
51
  :uid => metadata[:uid],
52
+ :labels => metadata[:labels],
53
+ :annotations => metadata[:annotations],
54
+ :owner_reference => metadata[:ownerReferences],
40
55
  :cpu_cores => domain[:cpu][:cores],
41
56
  :memory => domain[:resources][:requests][:memory],
42
57
  :disks => domain[:devices][:disks],
@@ -5,10 +5,15 @@ module Fog
5
5
  module Compute
6
6
  class Kubevirt
7
7
  class Offlinevms < Fog::Collection
8
+ attr_reader :kind, :resourceVersion
9
+
8
10
  model Fog::Compute::Kubevirt::Offlinevm
9
11
 
10
12
  def all(filters = {})
11
- load service.list_offlinevms(filters)
13
+ ovms = service.list_offlinevms(filters)
14
+ kind = ovms.kind
15
+ resourceVersion = ovms.resourceVersion
16
+ load ovms
12
17
  end
13
18
 
14
19
  def get(name)
@@ -2,14 +2,16 @@ module Fog
2
2
  module Compute
3
3
  class Kubevirt
4
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'
5
+ include Shared
6
+ identity :name, :aliases => 'metadata_name'
7
+
8
+ attribute :namespace, :aliases => 'metadata_namespace'
9
+ attribute :description, :aliases => 'metadata_description'
10
+ attribute :tags, :aliases => 'metadata_tags'
11
+ attribute :labels, :aliases => 'metadata_labels'
12
+ attribute :resource_version, :aliases => 'metadata_resource_version'
13
+ attribute :uid, :aliases => 'metadata_uid'
14
+ attribute :annotations, :aliases => 'metadata_annotations'
13
15
  attribute :objects
14
16
  attribute :parameters
15
17
 
@@ -27,16 +29,17 @@ module Fog
27
29
  metadata = object[:metadata]
28
30
  annotations = metadata[:annotations]
29
31
  {
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
- }
32
+ :namespace => metadata[:namespace],
33
+ :annotations => metadata[:annotations],
34
+ :name => metadata[:name],
35
+ :labels => metadata[:labels],
36
+ :resource_version => metadata[:resourceVersion],
37
+ :uid => metadata[:uid],
38
+ :objects => object[:objects],
39
+ :parameters => object[:parameters],
40
+ :description => annotations && annotations[:description],
41
+ :tags => annotations && annotations[:tags]
42
+ }.compact
40
43
  end
41
44
 
42
45
  private
@@ -70,13 +73,24 @@ module Fog
70
73
  #
71
74
  def create_offline_vm(offline_vm, params, namespace)
72
75
  offline_vm = param_substitution!(offline_vm, params)
73
-
74
- offline_vm = offline_vm.deep_merge(
76
+ os_labels = labels || {}
77
+ offline_vm = deep_merge!(offline_vm,
78
+ :spec => {
79
+ :running => false
80
+ },
75
81
  :metadata => {
76
82
  :namespace => namespace
77
83
  }
78
84
  )
79
85
 
86
+ offline_vm = deep_merge!(offline_vm,
87
+ :metadata => {
88
+ :labels => {
89
+ OS_LABEL => os_labels[OS_LABEL_SYMBOL]
90
+ }
91
+ }
92
+ ) if os_labels[OS_LABEL_SYMBOL]
93
+
80
94
  # Send the request to create the offline virtual machine:
81
95
  offline_vm = service.create_offlinevm(offline_vm)
82
96
  end
@@ -92,7 +106,7 @@ module Fog
92
106
  pvcs.each do |pvc|
93
107
  pvc = param_substitution!(pvc, params)
94
108
 
95
- pvc = pvc.deep_merge(
109
+ pvc = deep_merge!(pvc,
96
110
  :metadata => {
97
111
  :namespace => namespace
98
112
  }
@@ -182,4 +196,4 @@ module Fog
182
196
  end
183
197
  end
184
198
  end
185
- end
199
+ end
@@ -5,10 +5,15 @@ module Fog
5
5
  module Compute
6
6
  class Kubevirt
7
7
  class Templates < Fog::Collection
8
+ attr_reader :kind, :resourceVersion
9
+
8
10
  model Fog::Compute::Kubevirt::Template
9
11
 
10
12
  def all(filters = {})
11
- load service.list_templates(filters)
13
+ temps = service.list_templates(filters)
14
+ kind = temps.kind
15
+ resourceVersion = temps.resourceVersion
16
+ load temps
12
17
  end
13
18
 
14
19
  def get(name)
@@ -4,7 +4,8 @@ module Fog
4
4
  class Real
5
5
  def create_offlinevm(vm)
6
6
  kubevirt_client.create_offline_virtual_machine(vm)
7
- rescue KubeException
7
+ rescue KubeException => err
8
+ log.warn(err)
8
9
  raise ::Fog::Kubevirt::Errors::AlreadyExistsError
9
10
  end
10
11
  end
@@ -5,6 +5,7 @@ module Fog
5
5
  def create_pvc(pvc)
6
6
  kube_client.create_persistent_volume_claim(pvc)
7
7
  rescue Kubeclient::HttpError
8
+ log.warn(err)
8
9
  raise ::Fog::Kubevirt::Errors::AlreadyExistsError
9
10
  end
10
11
  end
@@ -5,6 +5,7 @@ module Fog
5
5
  def create_vm(vm)
6
6
  kubevirt_client.create_virtual_machine(vm)
7
7
  rescue Kubeclient::HttpError
8
+ log.warn(err)
8
9
  raise ::Fog::Kubevirt::Errors::AlreadyExistsError
9
10
  end
10
11
  end
@@ -0,0 +1,16 @@
1
+ module Fog
2
+ module Compute
3
+ class Kubevirt
4
+ class Real
5
+ def delete_livevm(name, namespace)
6
+ kubevirt_client.delete_virtual_machine(name, namespace)
7
+ end
8
+ end
9
+
10
+ class Mock
11
+ def delete_livevm(name, namespace = nil)
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 delete_offlinevm(name, namespace)
6
+ kubevirt_client.delete_offline_virtual_machine(name, namespace)
7
+ end
8
+ end
9
+
10
+ class Mock
11
+ def delete_offlinevm(name)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -5,37 +5,56 @@ module Fog
5
5
  class Kubevirt
6
6
  class Real
7
7
  def get_livevm(name)
8
- Livevm.parse object_to_hash( kubevirt_client.get_virtual_machine(name, 'default') )
8
+ # namespace is defined on the Real object
9
+ Livevm.parse object_to_hash( kubevirt_client.get_virtual_machine(name, @namespace) )
9
10
  end
10
11
  end
11
12
 
12
13
  class Mock
13
14
  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"}]}}
15
+ vm = { :apiVersion => "kubevirt.io/v1alpha1",
16
+ :kind => "VirtualMachine",
17
+ :metadata => { :clusterName => "",
18
+ :creationTimestamp => "2018-02-23T10:12:47Z",
19
+ :name => "demo",
20
+ :namespace => "default",
21
+ :ownerReferences => [{ :apiVersion => "kubevirt.io/v1alpha1",
22
+ :kind => "OfflineVirtualMachine",
23
+ :name => "demo",
24
+ :uid => "57e279c1-17ee-11e8-a9f9-525400a7f647"
25
+ }
26
+ ],
27
+ :resourceVersion => "84873",
28
+ :selfLink => "/apis/kubevirt.io/v1alpha1/namespaces/default/virtualmachines/demo",
29
+ :uid => "1906421f-1882-11e8-b539-525400a7f647"
30
+ },
31
+ :spec => { :domain => { :cpu => { :cores => "4" },
32
+ :devices => { :disks => [{ :disk => { :dev => "vda" },
33
+ :name => "registrydisk",
34
+ :volumeName => "registryvolume"
35
+ },
36
+ { :disk => { :dev => "vdb" },
37
+ :name => "cloudinitdisk",
38
+ :volumeName => "cloudinitvolume"
39
+ }
40
+ ]
41
+ },
42
+ :machine => { :type => "q35" },
43
+ :resources => { :requests => { :memory => "512Mi" }}
44
+ },
45
+ :volumes => [ { :name => "registryvolume",
46
+ :registryDisk => { :image => "kubevirt/fedora-cloud-registry-disk-demo:latest" }
47
+ },
48
+ { :cloudInitNoCloud => { :userDataBase64 => "I2Nsb3VkLWNvbmZpZwpwYXNzd29yZDogYXRvbWljCnNzaF9wd2F1dGg6IFRydWUKY2hwYXNzd2Q6IHsgZXhwaXJlOiBGYWxzZSB9Cg==" },
49
+ :name => "cloudinitvolume"
50
+ }
51
+ ]
52
+ }
53
+ }
35
54
  object = RecursiveOpenStruct.new(vm, recurse_over_arrays: true)
36
55
  Livevm.parse object_to_hash(object)
37
56
  end
38
57
  end
39
58
  end
40
59
  end
41
- end
60
+ end
@@ -0,0 +1,112 @@
1
+ require 'recursive_open_struct'
2
+
3
+ module Fog
4
+ module Compute
5
+ class Kubevirt
6
+ class Real
7
+ def get_node(name)
8
+ Node.parse object_to_hash( kube_client.get_node(name) )
9
+ end
10
+ end
11
+
12
+ class Mock
13
+ def get_livevm(name)
14
+ node = {:apiVersion => "v1",
15
+ :kind => "Node",
16
+ :metadata => {
17
+ :annotations => {
18
+ :volumes.kubernetes.io/controller-managed-attach-detach => "true"
19
+ },
20
+ :creationTimestamp => "2018-04-09T15:34:26Z",
21
+ :labels => {
22
+ :beta.kubernetes.io/arch => "amd64", :beta.kubernetes.io/os => "linux",
23
+ :kubernetes.io/hostname => "master", :node-role.kubernetes.io/master => "true",
24
+ :openshift-infra => "apiserver", :region => "infra", :zone => "default"
25
+ },
26
+ :name => "master",
27
+ :resourceVersion => "1514501",
28
+ :selfLink => "/api/v1/nodes/master",
29
+ :uid => "7c4102a6-3c0b-11e8-ad43-525400a36119"
30
+ },
31
+ :spec => {
32
+ :externalID => "master"
33
+ },
34
+ :status => {
35
+ :addresses => [
36
+ {:address => "192.168.200.2", :type => "InternalIP"},
37
+ {:address => "master", :type => "Hostname"}
38
+ ],
39
+ :allocatable => {:cpu => "2", :memory => "2739328Ki", :pods => "20"},
40
+ :capacity => {:cpu => "2", :memory => "2841728Ki", :pods => "20"},
41
+ :conditions => [
42
+ {
43
+ :lastHeartbeatTime => "2018-04-20T09:37:45Z", :lastTransitionTime => "2018-04-09T15:34:26Z",
44
+ :message => "kubelet has sufficient disk space available", :reason => "KubeletHasSufficientDisk",
45
+ :status => "False", :type => "OutOfDisk"
46
+ },
47
+ {
48
+ :lastHeartbeatTime => "2018-04-20T09:37:45Z", :lastTransitionTime => "2018-04-09T15:34:26Z",
49
+ :message => "kubelet has sufficient memory available", :reason => "KubeletHasSufficientMemory",
50
+ :status => "False", :type => "MemoryPressure"
51
+ },
52
+ {
53
+ :lastHeartbeatTime => "2018-04-20T09:37:45Z", :lastTransitionTime => "2018-04-19T12:56:17Z",
54
+ :message => "kubelet has disk pressure", :reason => "KubeletHasDiskPressure",
55
+ :status => "True", :type => "DiskPressure"
56
+ },
57
+ {
58
+ :lastHeartbeatTime => "2018-04-20T09:37:45Z", :lastTransitionTime => "2018-04-20T07:08:18Z",
59
+ :message => "kubelet is posting ready status", :reason => "KubeletReady",
60
+ :status => "True", :type => "Ready"
61
+ }
62
+ ],
63
+ :daemonEndpoints => {
64
+ :kubeletEndpoint => {
65
+ :Port => 10250
66
+ }
67
+ },
68
+ :images => [
69
+ {
70
+ :names => ["docker.io/openshift/openvswitch@sha256:2783e9bc552ea8c4ea725a9f88e353330243b010925c274561ba045974ce4000",
71
+ "docker.io/openshift/openvswitch:v3.9.0-alpha.4"], :sizeBytes => 1474465582
72
+ },
73
+ {
74
+ :names => ["docker.io/openshift/node@sha256:e092f1267535714070761844a62cdd38ce05e63a836ee55196953b8ac69527ba",
75
+ "docker.io/openshift/node:v3.9.0-alpha.4"], :sizeBytes => 1472685816
76
+ },
77
+ {
78
+ :names => ["docker.io/openshift/origin@sha256:4a3d8819499307c57dbb7d244b719c0e45068ca54727ef30b53a361cbe7d9430",
79
+ "docker.io/openshift/origin:v3.9.0-alpha.4"], :sizeBytes => 1257103966
80
+ },
81
+ {
82
+ :names => ["docker.io/ansibleplaybookbundle/apb-base@sha256:639d623b8185dd1471d38d2cc554efe7e2440a69d9a44cefa6b5565e8cc0d89c",
83
+ "docker.io/ansibleplaybookbundle/apb-base:latest"], :sizeBytes => 658504560
84
+ },
85
+ {
86
+ :names => ["registry.fedoraproject.org/latest/etcd@sha256:0656877d3888ca8b385bfc720fede845de185f0b5d29a0bbc7a2fb8c6fc8137a",
87
+ "registry.fedoraproject.org/latest/etcd:latest"], :sizeBytes => 308700638
88
+ },
89
+ {
90
+ :names => ["docker.io/fedora@sha256:7e2fc11763119c0cc0781400bb571bf2033c45469ebe286f1f090ba0dcffc32e",
91
+ "docker.io/fedora:26"], :sizeBytes => 231669643
92
+ },
93
+ {
94
+ :names => ["docker.io/openshift/origin-pod@sha256:ba180ba987ad1f07187c35e2369923b04fb8969a4344064feb38de508d65c385",
95
+ "docker.io/openshift/origin-pod:v3.9.0-alpha.4"], :sizeBytes => 228576414
96
+ }
97
+ ],
98
+ :nodeInfo => {
99
+ :architecture => "amd64", :bootID => "c2c59d3a-79d4-4661-acff-daf685ae4edc", :containerRuntimeVersion => "docker://1.13.1",
100
+ :kernelVersion => "3.10.0-693.21.1.el7.x86_64", :kubeProxyVersion => "v1.9.1+a0ce1bc657", :kubeletVersion => "v1.9.1+a0ce1bc657",
101
+ :machineID => "52c01ad890e84b15a1be4be18bd64ecd", :operatingSystem => "linux", :osImage => "CentOS Linux 7 (Core)",
102
+ :systemUUID => "52C01AD8-90E8-4B15-A1BE-4BE18BD64ECD"
103
+ }
104
+ }
105
+ }
106
+ object = RecursiveOpenStruct.new(node, recurse_over_arrays: true)
107
+ Node.parse object_to_hash(object)
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
@@ -7,11 +7,12 @@ module Fog
7
7
  end
8
8
 
9
9
  def get_raw_offlinevm(name)
10
- object_to_hash( kubevirt_client.get_offline_virtual_machine(name, 'default') )
10
+ object_to_hash( kubevirt_client.get_offline_virtual_machine(name, @namespace) )
11
11
  end
12
12
  end
13
13
 
14
14
  class Mock
15
+ # TODO provide implementation
15
16
  def get_offlinevm(name)
16
17
  end
17
18
 
@@ -3,11 +3,12 @@ module Fog
3
3
  class Kubevirt
4
4
  class Real
5
5
  def get_template(name)
6
- Template.parse object_to_hash( oc_client.get_template(name, 'default') )
6
+ Template.parse object_to_hash( openshift_client.get_template(name, @namespace) )
7
7
  end
8
8
  end
9
9
 
10
10
  class Mock
11
+ # TODO provide implementation
11
12
  def get_template(name)
12
13
  end
13
14
  end
@@ -3,14 +3,19 @@ module Fog
3
3
  class Kubevirt
4
4
  class Real
5
5
  def list_livevms(_filters = {})
6
- kubevirt_client.get_virtual_machines(namespace: 'default').map { |kubevirt_obj| Livevm.parse object_to_hash(kubevirt_obj) }
6
+ vms = kubevirt_client.get_virtual_machines(namespace: @namespace)
7
+ entities = vms.map do |kubevirt_obj|
8
+ Livevm.parse object_to_hash(kubevirt_obj)
9
+ end
10
+ EntityCollection.new(vms.kind, vms.resourceVersion, vms.metadata.uid, vms.metadata.type, entities)
7
11
  end
8
12
  end
9
13
 
10
14
  class Mock
15
+ # TODO provide implementation
11
16
  def list_livevms(_filters = {})
12
17
  end
13
18
  end
14
19
  end
15
20
  end
16
- end
21
+ end
@@ -0,0 +1,19 @@
1
+ module Fog
2
+ module Compute
3
+ class Kubevirt
4
+ class Real
5
+ def list_nodes(_filters = {})
6
+ nodes = kube_client.get_nodes
7
+ entities = nodes.map { |kubevirt_obj| Node.parse object_to_hash(kubevirt_obj) }
8
+ EntityCollection.new(nodes.kind, nodes.resourceVersion, vms.metadata.uid, vms.metadata.type, entities)
9
+ end
10
+ end
11
+
12
+ class Mock
13
+ # TODO provide implementation
14
+ def list_nodes(_filters = {})
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -5,7 +5,11 @@ module Fog
5
5
  class Kubevirt
6
6
  class Real
7
7
  def list_offlinevms(_filters = {})
8
- kubevirt_client.get_offline_virtual_machines(namespace: 'default').map { |kubevirt_obj| Offlinevm.parse object_to_hash(kubevirt_obj) }
8
+ ovms = kubevirt_client.get_offline_virtual_machines(namespace: @namespace)
9
+ entities = ovms.map do |kubevirt_obj|
10
+ Offlinevm.parse object_to_hash(kubevirt_obj)
11
+ end
12
+ EntityCollection.new(ovms.kind, ovms.resourceVersion, ovms.metadata.uid, ovms.metadata.type, entities)
9
13
  end
10
14
  end
11
15
 
@@ -28,15 +32,15 @@ module Fog
28
32
  devices: { disks: [{ disk: { dev: 'vda' },
29
33
  name: 'registrydisk',
30
34
  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' }] }
35
+ { disk: { dev: 'vdb' },
36
+ name: 'cloudinitdisk',
37
+ volumeName: 'cloudinitvolume' }] },
38
+ machine: { type: 'q35' },
39
+ resources: { requests: { memory: '512Mi' } } },
40
+ volumes: [{ name: 'registryvolume',
41
+ registryDisk: { image: 'kubevirt/fedora-cloud-registry-disk-demo:latest' } },
42
+ { cloudInitNoCloud: { userDataBase64: 'I2Nsb3VkLWNvbmZpZwpwYXNzd29yZDogYXRvbWljCnNzaF9wd2F1dGg6IFRydWUKY2hwYXNzd2Q6IHsgZXhwaXJlOiBGYWxzZSB9Cg==' },
43
+ name: 'cloudinitvolume' }] }
40
44
  }
41
45
  } }]
42
46
  object = RecursiveOpenStruct.new(offlinevms, recurse_over_arrays: true)
@@ -5,7 +5,11 @@ module Fog
5
5
  class Kubevirt
6
6
  class Real
7
7
  def list_templates(_filters = {})
8
- oc_client.get_templates(namespace: 'default').map { |kubevirt_obj| Template.parse object_to_hash(kubevirt_obj) }
8
+ temps = openshift_client.get_templates(namespace: @namespace)
9
+ entities = temps.map do |kubevirt_obj|
10
+ Template.parse object_to_hash(kubevirt_obj)
11
+ end
12
+ EntityCollection.new(temps.kind, temps.resourceVersion, temps.metadata.uid, temps.metadata.type, entities)
9
13
  end
10
14
  end
11
15
 
@@ -19,25 +23,26 @@ module Fog
19
23
  creationTimestamp: '2018-02-22T10:37:28Z',
20
24
  labels: { :"miq.github.io/kubevirt-is-vm-template" => 'true',
21
25
  :"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' }] }]
26
+ annotations: { description: 'OCP kubevirt linux, template',
27
+ tags: 'kubevirt,ocp,template,linux' }
28
+ },
29
+ objects: [{ apiVersion: 'kubevirt.io/v1alpha1',
30
+ kind: 'OfflineVirtualMachine',
31
+ metadata: { name: '${NAME}' },
32
+ spec: { template: { spec: { domain:
33
+ { cpu: { cores: '${CPU_CORES}' },
34
+ devices: { disks: [{ disk: { dev: 'vda' }, name: 'disk0', volumeName: 'disk0-pvc' }] },
35
+ machine: { type: 'q35' },
36
+ resources: { requests: { memory: '${MEMORY}' } } },
37
+ volumes: [{ name: 'disk0-pvc', persistentVolumeClaim: { claimName: 'linux-vm-pvc-${NAME}' } }] } } } },
38
+ { apiVersion: 'v1',
39
+ kind: 'PersistentVolumeClaim',
40
+ metadata: { name: 'linux-vm-pvc-${NAME}' },
41
+ spec: { accessModes: ['ReadWriteOnce'],
42
+ resources: { requests: { storage: '10Gi' } } } }],
43
+ parameters: [{ name: 'NAME', description: 'Name for the new VM' },
44
+ { name: 'MEMORY', description: 'Amount of memory', value: '4096Mi' },
45
+ { name: 'CPU_CORES', description: 'Amount of cores', value: '4' }] }]
41
46
  object = RecursiveOpenStruct.new(templates, recurse_over_arrays: true)
42
47
  object.map { |kubevirt_obj| Template.parse object_to_hash(kubevirt_obj) }
43
48
  end
@@ -1,5 +1,5 @@
1
1
  module Fog
2
2
  module Kubevirt
3
- VERSION = '0.1.0'
3
+ VERSION = '0.1.1'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fog-kubevirt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Kliczewski
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2018-04-18 00:00:00.000000000 Z
14
+ date: 2018-05-24 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: bundler
@@ -113,6 +113,8 @@ files:
113
113
  - lib/fog/compute/kubevirt.rb
114
114
  - lib/fog/compute/kubevirt/models/livevm.rb
115
115
  - lib/fog/compute/kubevirt/models/livevms.rb
116
+ - lib/fog/compute/kubevirt/models/node.rb
117
+ - lib/fog/compute/kubevirt/models/nodes.rb
116
118
  - lib/fog/compute/kubevirt/models/offlinevm.rb
117
119
  - lib/fog/compute/kubevirt/models/offlinevms.rb
118
120
  - lib/fog/compute/kubevirt/models/template.rb
@@ -122,11 +124,14 @@ files:
122
124
  - lib/fog/compute/kubevirt/requests/create_offlinevm.rb
123
125
  - lib/fog/compute/kubevirt/requests/create_pvc.rb
124
126
  - lib/fog/compute/kubevirt/requests/create_vm.rb
125
- - lib/fog/compute/kubevirt/requests/destroy_vm.rb
127
+ - lib/fog/compute/kubevirt/requests/delete_livevm.rb
128
+ - lib/fog/compute/kubevirt/requests/delete_offlinevm.rb
126
129
  - lib/fog/compute/kubevirt/requests/get_livevm.rb
130
+ - lib/fog/compute/kubevirt/requests/get_node.rb
127
131
  - lib/fog/compute/kubevirt/requests/get_offlinevm.rb
128
132
  - lib/fog/compute/kubevirt/requests/get_template.rb
129
133
  - lib/fog/compute/kubevirt/requests/list_livevms.rb
134
+ - lib/fog/compute/kubevirt/requests/list_nodes.rb
130
135
  - lib/fog/compute/kubevirt/requests/list_offlinevms.rb
131
136
  - lib/fog/compute/kubevirt/requests/list_templates.rb
132
137
  - lib/fog/compute/kubevirt/requests/update_offlinevm.rb
@@ -1,15 +0,0 @@
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