fog-kubevirt 0.1.0 → 0.1.1

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