fog-kubevirt 1.2.5 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. checksums.yaml +4 -4
  2. data/lib/fog/kubevirt.rb +3 -2
  3. data/lib/fog/kubevirt/compute/compute.rb +5 -148
  4. data/lib/fog/kubevirt/compute/models/persistentvolume.rb +9 -9
  5. data/lib/fog/kubevirt/compute/models/persistentvolumes.rb +6 -1
  6. data/lib/fog/kubevirt/compute/models/pvcs.rb +3 -1
  7. data/lib/fog/kubevirt/compute/models/storageclass.rb +8 -2
  8. data/lib/fog/kubevirt/compute/models/template.rb +6 -0
  9. data/lib/fog/kubevirt/compute/models/vm.rb +1 -0
  10. data/lib/fog/kubevirt/compute/models/vminstances.rb +1 -1
  11. data/lib/fog/kubevirt/compute/models/vms.rb +12 -3
  12. data/lib/fog/kubevirt/compute/requests/create_networkattachmentdef.rb +0 -3
  13. data/lib/fog/kubevirt/compute/requests/create_persistentvolume.rb +0 -3
  14. data/lib/fog/kubevirt/compute/requests/create_pvc.rb +0 -3
  15. data/lib/fog/kubevirt/compute/requests/create_service.rb +0 -3
  16. data/lib/fog/kubevirt/compute/requests/create_storageclass.rb +0 -3
  17. data/lib/fog/kubevirt/compute/requests/create_vm.rb +0 -3
  18. data/lib/fog/kubevirt/compute/requests/create_vminstance.rb +0 -3
  19. data/lib/fog/kubevirt/compute/utils/exception_wrapper.rb +43 -0
  20. data/lib/fog/kubevirt/compute/utils/unit_converter.rb +115 -0
  21. data/lib/fog/kubevirt/version.rb +1 -1
  22. data/spec/integration/mac_vmi_spec.rb +135 -0
  23. data/spec/integration/net-attach-def_spec.rb +43 -0
  24. data/spec/integration/pvcs_spec.rb +3 -2
  25. data/spec/integration/shared_context.rb +11 -4
  26. data/spec/integration/volumes_spec.rb +45 -0
  27. data/spec/unit/create_vm_spec.rb +4 -3
  28. data/spec/unit/unit_converter_spec.rb +4 -2
  29. metadata +10 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a757bb97341858b22dcbce97ae84899d67851f64
4
- data.tar.gz: 2d92ed31781d8c7331a76dbb6111875222baf5ce
3
+ metadata.gz: b8646bec0df5d890b6c7aca5738a39596c982146
4
+ data.tar.gz: aa9d02efd6cd353248becb936f2365b25765ea03
5
5
  SHA512:
6
- metadata.gz: dc6973eb073d9abfa2bb8016820d7e62a51ed5a08725b9238dcd86fd847ddc0873196c05536433133581c732cfdd63df2414dc034c30c48e0313d4bbf907ba05
7
- data.tar.gz: 2262f37fe3e69f0c66856c17722dbd4ff88160ee32c11d736eddb29ebd29b53948fc71312e473e28c3c3be6d01ca32db2f4c95da2a016c9c73ce9cbf4fc3be1d
6
+ metadata.gz: 8bbe31efac532a38857e420fd847d878c0653eb64b75266506b03c7bd5b8fe918a908d99a71a391bf44e8b16d2ca3d5f157bc7a9787170fadb8bde99751eae3c
7
+ data.tar.gz: d72fa662e0dbf84869a8e66e7f30ea96062bc8365415733c4eef0fb7ea6c55851440b27cd94b27e1482cbea5f25a8b8b10fe4d0662f45ac0bd72c7445dcbdd69
@@ -7,9 +7,10 @@ module Fog
7
7
 
8
8
  module Errors
9
9
  class ServiceError < Fog::Errors::Error; end
10
- class AlreadyExistsError < Fog::Errors::Error; end
11
10
  class ClientError < Fog::Errors::Error; end
12
- class ValidationError < Fog::Errors::Error; end
11
+ class AlreadyExistsError < ClientError; end
12
+ class NotFoundError < ClientError; end
13
+ class ValidationError < ClientError; end
13
14
  end
14
15
 
15
16
  service(:compute, 'Compute')
@@ -2,7 +2,8 @@ require 'delegate'
2
2
  require 'json'
3
3
  require 'rest-client'
4
4
 
5
- require "fog/core"
5
+ require 'fog/core'
6
+ require 'fog/kubevirt/compute/utils/exception_wrapper'
6
7
 
7
8
  module Fog
8
9
  module Kubevirt
@@ -84,150 +85,6 @@ module Fog
84
85
  end
85
86
  end
86
87
 
87
- class ExceptionWrapper
88
- def initialize(client, version)
89
- @client = client
90
- @version = version
91
- end
92
-
93
- def method_missing(symbol, *args)
94
- super unless @client.respond_to?(symbol)
95
-
96
- if block_given?
97
- @client.__send__(symbol, *args) do |*block_args|
98
- yield(*block_args)
99
- end
100
- else
101
- @client.__send__(symbol, *args)
102
- end
103
- rescue KubeException => e
104
- raise ::Fog::Kubevirt::Errors::ClientError, e
105
- end
106
-
107
- def respond_to_missing?(method_name, include_private = false)
108
- @client.respond_to?(symbol, include_all) || super
109
- end
110
-
111
- def version
112
- @version
113
- end
114
- end
115
-
116
- #
117
- # This class contains functions performing unit calculations.
118
- # Originally implemented for manageiq-providers-kubevirt project
119
- #
120
- class UnitConverter
121
- #
122
- # Converts a value containing an optional unit to another unit. For example, if the value is
123
- # `2 MiB` and the unit is `KiB` the result will be 2048.
124
- #
125
- # @param value [String] The value to convert, with an optional unit suffix.
126
- # @param to [Symbol] (:b) The name of the unit to convert to, for example `:gib`.
127
- # @return [BigDecimal] The converted value.
128
- #
129
- def self.convert(value, to)
130
- # Return nil if no value is given:
131
- return nil unless value
132
-
133
- match = validate(value)
134
- value = match[:value]
135
- from = match[:suffix]
136
-
137
- # Convert the value from string to big decimal to make sure that we don't loose precission:
138
- value = BigDecimal(value)
139
-
140
- # Do the conversion:
141
- from_factor = scale_factor(from)
142
- to_factor = scale_factor(to)
143
- value * from_factor / to_factor
144
- end
145
-
146
- #
147
- # Validates and extracts the numeric value and the unit
148
- #
149
- # @param value [String] The value to validate with optional unit suffix.
150
- # @return [MatchData] describing the match, or ValidationError is raised if no match.
151
- #
152
- def self.validate(value)
153
- match = VALUE_RE.match(value)
154
- raise ::Fog::Kubevirt::Errors::ValidationError, "The value '#{value}' isn't a valid unit" unless match
155
-
156
- match
157
- end
158
-
159
- #
160
- # Regular expression used to match values and to separate them into the numeric value and the
161
- # optional unit suffix.
162
- #
163
- VALUE_RE = /^\s*(?<value>[[:digit:]]+)\s*(?<suffix>[[:alpha:]]+)?\s*$/i
164
- private_constant :VALUE_RE
165
-
166
- #
167
- # Scale factors associated to the different unit suffixes.
168
- #
169
- SCALE_FACTORS = {
170
- :b => 1,
171
-
172
- :k => 10**3,
173
- :m => 10**6,
174
- :g => 10**9,
175
- :t => 10**12,
176
- :p => 10**15,
177
- :e => 10**18,
178
- :z => 10**21,
179
- :y => 10**24,
180
-
181
- :kb => 10**3,
182
- :mb => 10**6,
183
- :gb => 10**9,
184
- :tb => 10**12,
185
- :pb => 10**15,
186
- :eb => 10**18,
187
- :zb => 10**21,
188
- :yb => 10**24,
189
-
190
- :ki => 2**10,
191
- :mi => 2**20,
192
- :gi => 2**30,
193
- :ti => 2**40,
194
- :pi => 2**50,
195
- :ei => 2**60,
196
- :zi => 2**70,
197
- :yi => 2**80,
198
-
199
- :kib => 2**10,
200
- :mib => 2**20,
201
- :gib => 2**30,
202
- :tib => 2**40,
203
- :pib => 2**50,
204
- :eib => 2**60,
205
- :zib => 2**70,
206
- :yib => 2**80
207
- }.freeze
208
- private_constant :SCALE_FACTORS
209
-
210
- #
211
- # Finds the scale factor that matches the given unit suffix.
212
- #
213
- # @param sufix [Symbol, String] The unit suffix, as symbol or string. For example `MiB` or `:mib`.
214
- # @return [Integer] The scale factor corresponding to that unit.
215
- #
216
- def self.scale_factor(suffix)
217
- suffix = suffix.downcase.to_sym if suffix.kind_of?(String)
218
- factor = SCALE_FACTORS[suffix]
219
- raise ::Fog::Kubevirt::Errors::ValidationError, "The value '#{suffix}' isn't a valid unit suffix" unless factor
220
- factor
221
- end
222
- private_class_method :scale_factor
223
- end
224
-
225
- #
226
- # Label name which identifies operation system information
227
- #
228
- OS_LABEL = 'kubevirt.io/os'.freeze
229
- OS_LABEL_SYMBOL = :'kubevirt.io/os'
230
-
231
88
  # converts kubeclient objects into hash for fog to consume
232
89
  def object_to_hash(object)
233
90
  result = object
@@ -382,7 +239,7 @@ module Fog
382
239
  #
383
240
  def watch_vms(opts = {})
384
241
  mapper = Proc.new do |notice|
385
- vm = OpenStruct.new(Vm.parse(notice.object)) if notice.object.kind == 'VirtualMachine'
242
+ vm = OpenStruct.new(Vm.parse(object_to_hash(notice.object))) if notice.object.kind == 'VirtualMachine'
386
243
  vm ||= OpenStruct.new
387
244
 
388
245
  populate_notice_attributes(vm, notice)
@@ -401,7 +258,7 @@ module Fog
401
258
  #
402
259
  def watch_vminstances(opts = {})
403
260
  mapper = Proc.new do |notice|
404
- vminstance = OpenStruct.new(Vminstance.parse(notice.object)) if notice.object.kind == 'VirtualMachineInstance'
261
+ vminstance = OpenStruct.new(Vminstance.parse(object_to_hash(notice.object))) if notice.object.kind == 'VirtualMachineInstance'
405
262
  vminstance ||= OpenStruct.new
406
263
 
407
264
  populate_notice_attributes(vminstance, notice)
@@ -538,7 +395,7 @@ module Fog
538
395
  end
539
396
 
540
397
  def wrap_client(client, version, key)
541
- wrapped_client = ExceptionWrapper.new(client, version)
398
+ wrapped_client = ::Fog::Kubevirt::Utils::ExceptionWrapper.new(client, version, @log)
542
399
  @clients[key] = wrapped_client
543
400
 
544
401
  wrapped_client
@@ -8,17 +8,17 @@ module Fog
8
8
  attribute :uid, :aliases => 'metadata_uid'
9
9
  attribute :annotations, :aliases => 'metadata_annotations'
10
10
  attribute :labels, :aliases => 'metadata_labels'
11
- attribute :access_modes, :aliases => 'spec_access_modes'
12
- attribute :mount_options, :aliases => 'spec_mount_options'
13
- attribute :reclaim_policy, :aliases => 'spec_reclaim_policy'
14
- attribute :storage_class, :aliases => 'spec_storage_class'
11
+ attribute :access_modes, :aliases => 'spec_access_modes'
12
+ attribute :mount_options, :aliases => 'spec_mount_options'
13
+ attribute :reclaim_policy, :aliases => 'spec_reclaim_policy'
14
+ attribute :storage_class, :aliases => 'spec_storage_class'
15
15
  attribute :capacity, :aliases => 'spec_capacity'
16
16
  attribute :claim_ref, :aliases => 'spec_claim_ref'
17
- attribute :type, :aliases => 'spec_type'
18
- attribute :config, :aliases => 'spec_config'
17
+ attribute :type, :aliases => 'spec_type'
18
+ attribute :config, :aliases => 'spec_config'
19
19
  attribute :phase, :aliases => 'status_phase'
20
- attribute :reason, :aliases => 'status_reason'
21
- attribute :message, :aliases => 'status_message'
20
+ attribute :reason, :aliases => 'status_reason'
21
+ attribute :message, :aliases => 'status_message'
22
22
 
23
23
  def self.parse(object)
24
24
  metadata = object[:metadata]
@@ -35,7 +35,7 @@ module Fog
35
35
  :access_modes => spec[:accessModes],
36
36
  :mount_options => spec[:mountOptions],
37
37
  :reclaim_policy => spec[:persistentVolumeReclaimPolicy],
38
- :storage_class => spec[:storageClassName],
38
+ :storage_class => spec[:storageClassName],
39
39
  :capacity => spec.dig(:capacity, :storage),
40
40
  :claim_ref => spec[:claimRef],
41
41
  :type => type,
@@ -35,6 +35,11 @@ module Fog
35
35
  name = args[:name]
36
36
  labels = args[:labels]
37
37
 
38
+ # type is required
39
+ if args[:type].nil? || args[:type].empty?
40
+ raise ::Fog::Kubevirt::Errors::ValidationError "Type of storage can not be empty"
41
+ end
42
+
38
43
  volume = {
39
44
  :apiVersion => "v1",
40
45
  :kind => "PersistentVolume",
@@ -52,7 +57,7 @@ module Fog
52
57
  } if args[:capacity]
53
58
 
54
59
  volume[:spec][:accessModes] = args[:access_modes] if args[:access_modes]
55
- volume[:spec][args[:type].to_sym] = args[:config] if args[:type]
60
+ volume[:spec][args[:type].to_sym] = args[:config]
56
61
 
57
62
  service.create_persistentvolume(volume)
58
63
  end
@@ -1,10 +1,12 @@
1
1
  require 'fog/core/collection'
2
2
  require 'fog/kubevirt/compute/models/pvc'
3
+ require 'fog/kubevirt/compute/utils/unit_converter'
3
4
 
4
5
  module Fog
5
6
  module Kubevirt
6
7
  class Compute
7
8
  class Pvcs < Fog::Collection
9
+
8
10
  attr_reader :kind, :resource_version
9
11
 
10
12
  model Fog::Kubevirt::Compute::Pvc
@@ -82,7 +84,7 @@ module Fog
82
84
  private
83
85
 
84
86
  def check_size(value)
85
- ::Fog::Kubevirt::Compute::Shared::UnitConverter.validate(value[:storage])
87
+ ::Fog::Kubevirt::Utils::UnitConverter.validate(value[:storage])
86
88
  end
87
89
  end
88
90
  end
@@ -2,10 +2,13 @@ module Fog
2
2
  module Kubevirt
3
3
  class Compute
4
4
  class Storageclass < Fog::Model
5
+ IS_DEFAULT = 'storageclass.kubernetes.io/is-default-class'.freeze
6
+
5
7
  # Metadata
6
8
  identity :name
7
9
  attribute :resource_version, :aliases => 'metadata_resource_version'
8
10
  attribute :uid, :aliases => 'metadata_uid'
11
+ attribute :default
9
12
 
10
13
  attribute :mount_options
11
14
  attribute :parameters
@@ -15,17 +18,20 @@ module Fog
15
18
 
16
19
  def self.parse(object)
17
20
  metadata = object[:metadata]
18
- {
21
+ annotations = metadata[:annotations]
22
+ sc = {
19
23
  :name => metadata[:name],
20
24
  :resource_version => metadata[:resourceVersion],
21
25
  :uid => metadata[:uid],
22
-
23
26
  :parameters => object[:parameters],
24
27
  :mount_options => object[:mountOptions],
25
28
  :provisioner => object[:provisioner],
26
29
  :reclaim_policy => object[:reclaimPolicy],
27
30
  :volume_binding_mode => object[:volumeBindingMode]
28
31
  }
32
+
33
+ sc[:default] = annotations[IS_DEFAULT.to_sym] unless annotations.nil?
34
+ sc
29
35
  end
30
36
  end
31
37
  end
@@ -15,6 +15,12 @@ module Fog
15
15
  attribute :objects
16
16
  attribute :parameters
17
17
 
18
+ #
19
+ # Label name which identifies operation system information
20
+ #
21
+ OS_LABEL = 'kubevirt.io/os'.freeze
22
+ OS_LABEL_SYMBOL = :'kubevirt.io/os'
23
+
18
24
  def clone(options = {})
19
25
  params = values(options)
20
26
 
@@ -6,6 +6,7 @@ module Fog
6
6
  class Compute
7
7
  class Vm < Fog::Model
8
8
  include VmAction
9
+ include Shared
9
10
  extend VmBase
10
11
  define_properties
11
12
 
@@ -37,7 +37,7 @@ module Fog
37
37
  service.delete_vm(name, namespace)
38
38
 
39
39
  # delete vm instance
40
- service.delete_vminstance(name, namespace) unless vm_instance.nil?
40
+ service.delete_vminstance(name) unless vm_instance.nil?
41
41
  end
42
42
  end
43
43
  end
@@ -44,6 +44,7 @@ module Fog
44
44
  # :vm_name [String] - name of a vm
45
45
  # :cpus [String] - number of cpus
46
46
  # :memory_size [String] - amount of memory
47
+ # :memory_unit [String] - memory unit to use, default to 'M'
47
48
  # :image [String] - name of a container disk
48
49
  # :pvc [String] - name of a persistent volume claim
49
50
  # :cloudinit [Hash] - number of items needed to configure cloud-init
@@ -71,6 +72,7 @@ module Fog
71
72
  vm_name = args.fetch(:vm_name)
72
73
  cpus = args.fetch(:cpus, nil)
73
74
  memory_size = args.fetch(:memory_size)
75
+ memory_unit = args.fetch(:memory_unit, "M")
74
76
  init = args.fetch(:cloudinit, {})
75
77
  networks = args.fetch(:networks, nil)
76
78
  interfaces = args.fetch(:interfaces, nil)
@@ -80,6 +82,8 @@ module Fog
80
82
  raise ::Fog::Kubevirt::Errors::ValidationError
81
83
  end
82
84
 
85
+ memory = "#{memory_size}#{memory_unit}"
86
+ ::Fog::Kubevirt::Utils::UnitConverter.validate(memory)
83
87
  volumes, disks = add_vm_storage(vm_name, vm_volumes)
84
88
 
85
89
  unless init.empty?
@@ -114,7 +118,7 @@ module Fog
114
118
  },
115
119
  :resources => {
116
120
  :requests => {
117
- :memory => "#{memory_size}M"
121
+ :memory => memory
118
122
  }
119
123
  }
120
124
  },
@@ -173,10 +177,9 @@ module Fog
173
177
  end
174
178
 
175
179
  def add_vm_storage(vm_name, vm_volumes)
176
- normalized_vm_name = vm_name.gsub(/[._]+/,'-')
177
180
  volumes, disks = [], []
178
181
  vm_volumes.each_with_index do |v, idx|
179
- volume_name = v.name || normalized_vm_name + "-disk-0" + idx.to_s
182
+ volume_name = v.name.nil? ? normalized_name(vm_name) + "-disk-0" + idx.to_s : normalized_name(v.name)
180
183
  disk = {
181
184
  :name => volume_name,
182
185
  :disk => {}
@@ -209,6 +212,12 @@ module Fog
209
212
 
210
213
  return volumes, disks
211
214
  end
215
+
216
+ private
217
+
218
+ def normalized_name(name)
219
+ name.gsub(/[._]+/,'-')
220
+ end
212
221
  end
213
222
  end
214
223
  end
@@ -22,9 +22,6 @@ module Fog
22
22
  net_att = deep_merge!(net_att, metadata: { namespace: @namespace })
23
23
  end
24
24
  kube_net_client.create_network_attachment_definition(net_att)
25
- rescue ::Fog::Kubevirt::Errors::ClientError => err
26
- log.warn(err)
27
- raise ::Fog::Kubevirt::Errors::AlreadyExistsError
28
25
  end
29
26
  end
30
27
 
@@ -4,9 +4,6 @@ module Fog
4
4
  class Real
5
5
  def create_persistentvolume(volume)
6
6
  kube_client.create_persistent_volume(volume)
7
- rescue ::Fog::Kubevirt::Errors::ClientError => err
8
- log.warn(err)
9
- raise ::Fog::Kubevirt::Errors::AlreadyExistsError
10
7
  end
11
8
  end
12
9
 
@@ -4,9 +4,6 @@ module Fog
4
4
  class Real
5
5
  def create_pvc(pvc)
6
6
  kube_client.create_persistent_volume_claim(pvc)
7
- rescue ::Fog::Kubevirt::Errors::ClientError => err
8
- log.warn(err)
9
- raise ::Fog::Kubevirt::Errors::AlreadyExistsError
10
7
  end
11
8
  end
12
9
 
@@ -4,9 +4,6 @@ module Fog
4
4
  class Real
5
5
  def create_service(srv)
6
6
  kube_client.create_service(srv)
7
- rescue ::Fog::Kubevirt::Errors::ClientError => err
8
- log.warn(err)
9
- raise ::Fog::Kubevirt::Errors::AlreadyExistsError
10
7
  end
11
8
  end
12
9
 
@@ -4,9 +4,6 @@ module Fog
4
4
  class Real
5
5
  def create_storageclass(storageclass)
6
6
  kube_storage_client.create_storage_class(storageclass)
7
- rescue ::Fog::Kubevirt::Errors::ClientError => err
8
- log.warn(err)
9
- raise ::Fog::Kubevirt::Errors::AlreadyExistsError
10
7
  end
11
8
  end
12
9
 
@@ -6,9 +6,6 @@ module Fog
6
6
  vm[:apiVersion] = kubevirt_client.version
7
7
 
8
8
  kubevirt_client.create_virtual_machine(vm)
9
- rescue ::Fog::Kubevirt::Errors::ClientError => err
10
- log.warn(err)
11
- raise ::Fog::Kubevirt::Errors::AlreadyExistsError
12
9
  end
13
10
  end
14
11
 
@@ -5,9 +5,6 @@ module Fog
5
5
 
6
6
  def create_vminstance(vm)
7
7
  kubevirt_client.create_virtual_machine_instance(vm)
8
- rescue ::Fog::Kubevirt::Errors::ClientError => err
9
- log.warn(err)
10
- raise ::Fog::Kubevirt::Errors::AlreadyExistsError
11
8
  end
12
9
  end
13
10
 
@@ -0,0 +1,43 @@
1
+ module Fog
2
+ module Kubevirt
3
+ module Utils
4
+ class ExceptionWrapper
5
+ def initialize(client, version, log)
6
+ @client = client
7
+ @version = version
8
+ @log = log
9
+ end
10
+
11
+ def method_missing(symbol, *args)
12
+ super unless @client.respond_to?(symbol)
13
+
14
+ if block_given?
15
+ @client.__send__(symbol, *args) do |*block_args|
16
+ yield(*block_args)
17
+ end
18
+ else
19
+ @client.__send__(symbol, *args)
20
+ end
21
+ rescue KubeException => e
22
+ if e.error_code == 409
23
+ @log.warn(e)
24
+ raise ::Fog::Kubevirt::Errors::AlreadyExistsError, e
25
+ elsif e.error_code == 404
26
+ raise ::Fog::Kubevirt::Errors::NotFoundError, e
27
+ else
28
+ @log.warn(e)
29
+ raise ::Fog::Kubevirt::Errors::ClientError, e
30
+ end
31
+ end
32
+
33
+ def respond_to_missing?(method_name, include_private = false)
34
+ @client.respond_to?(method_name, include_private) || super
35
+ end
36
+
37
+ def version
38
+ @version
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,115 @@
1
+ module Fog
2
+ module Kubevirt
3
+ module Utils
4
+ #
5
+ # This class contains functions performing unit calculations.
6
+ # Originally implemented for manageiq-providers-kubevirt project
7
+ #
8
+ class UnitConverter
9
+
10
+ #
11
+ # Converts a value containing an optional unit to another unit. For example, if the value is
12
+ # `2 MiB` and the unit is `KiB` the result will be 2048.
13
+ #
14
+ # @param value [String] The value to convert, with an optional unit suffix.
15
+ # @param to [Symbol] (:b) The name of the unit to convert to, for example `:gib`.
16
+ # @return [BigDecimal] The converted value.
17
+ #
18
+ def self.convert(value, to)
19
+ # Return nil if no value is given:
20
+ return nil unless value
21
+
22
+ match = validate(value)
23
+ value = match[:value]
24
+ from = match[:suffix]
25
+
26
+ # Convert the value from string to big decimal to make sure that we don't loose precission:
27
+ value = BigDecimal(value)
28
+
29
+ # Do the conversion:
30
+ from_factor = scale_factor(from)
31
+ to_factor = scale_factor(to)
32
+ value * from_factor / to_factor
33
+ end
34
+
35
+ #
36
+ # Validates and extracts the numeric value and the unit
37
+ #
38
+ # @param value [String] The value to validate with optional unit suffix.
39
+ # @return [MatchData] describing the match, or ValidationError is raised if no match.
40
+ #
41
+ def self.validate(value)
42
+ match = VALUE_RE.match(value)
43
+ raise ::Fog::Kubevirt::Errors::ValidationError, "The value '#{value}' isn't a valid unit" unless match
44
+
45
+ match
46
+ end
47
+
48
+ #
49
+ # Regular expression used to match values and to separate them into the numeric value and the
50
+ # optional unit suffix.
51
+ #
52
+ VALUE_RE = /^\s*(?<value>[[:digit:]]+)\s*(?<suffix>[[:alpha:]]+)?\s*$/i
53
+ private_constant :VALUE_RE
54
+
55
+ #
56
+ # Scale factors associated to the different unit suffixes.
57
+ #
58
+ SCALE_FACTORS = {
59
+ :b => 1,
60
+
61
+ :k => 10**3,
62
+ :m => 10**6,
63
+ :g => 10**9,
64
+ :t => 10**12,
65
+ :p => 10**15,
66
+ :e => 10**18,
67
+ :z => 10**21,
68
+ :y => 10**24,
69
+
70
+ :kb => 10**3,
71
+ :mb => 10**6,
72
+ :gb => 10**9,
73
+ :tb => 10**12,
74
+ :pb => 10**15,
75
+ :eb => 10**18,
76
+ :zb => 10**21,
77
+ :yb => 10**24,
78
+
79
+ :ki => 2**10,
80
+ :mi => 2**20,
81
+ :gi => 2**30,
82
+ :ti => 2**40,
83
+ :pi => 2**50,
84
+ :ei => 2**60,
85
+ :zi => 2**70,
86
+ :yi => 2**80,
87
+
88
+ :kib => 2**10,
89
+ :mib => 2**20,
90
+ :gib => 2**30,
91
+ :tib => 2**40,
92
+ :pib => 2**50,
93
+ :eib => 2**60,
94
+ :zib => 2**70,
95
+ :yib => 2**80
96
+ }.freeze
97
+ private_constant :SCALE_FACTORS
98
+
99
+ #
100
+ # Finds the scale factor that matches the given unit suffix.
101
+ #
102
+ # @param sufix [Symbol, String] The unit suffix, as symbol or string. For example `MiB` or `:mib`.
103
+ # @return [Integer] The scale factor corresponding to that unit.
104
+ #
105
+ def self.scale_factor(suffix)
106
+ suffix = suffix.downcase.to_sym if suffix.kind_of?(String)
107
+ factor = SCALE_FACTORS[suffix]
108
+ raise ::Fog::Kubevirt::Errors::ValidationError, "The value '#{suffix}' isn't a valid unit suffix" unless factor
109
+ factor
110
+ end
111
+ private_class_method :scale_factor
112
+ end
113
+ end
114
+ end
115
+ end
@@ -1,5 +1,5 @@
1
1
  module Fog
2
2
  module Kubevirt
3
- VERSION = '1.2.5'
3
+ VERSION = '1.3.0'
4
4
  end
5
5
  end
@@ -0,0 +1,135 @@
1
+ require_relative './shared_context'
2
+
3
+ describe Fog::Kubevirt::Compute do
4
+ before :all do
5
+ conn = KubevirtConnection.new()
6
+ @client = conn.client
7
+ @watch = nil
8
+ end
9
+
10
+ it 'creates VMI and checks MAC' do
11
+ vm_name = 'test'
12
+ cpus = 1
13
+ memory_size = 64
14
+
15
+ volume = Fog::Kubevirt::Compute::Volume.new
16
+ volume.type = 'containerDisk'
17
+ volume.name = 'test-disk-01'
18
+ volume.info = 'registry:5000/kubevirt/cirros-container-disk-demo:devel'
19
+
20
+ @client.vms.create(vm_name: vm_name, cpus: cpus, memory_size: memory_size, volumes: [volume])
21
+
22
+ vm = @client.vms.get(vm_name)
23
+ assert_equal(vm.cpu_cores, cpus)
24
+ assert_equal(vm.memory, "#{memory_size}M")
25
+
26
+ vm.start()
27
+
28
+ # check whether vmi to be created if not it will raise ClientError
29
+ @client.vminstances.get(vm_name)
30
+
31
+ vmis = @client.vminstances.all()
32
+ @watch = @client.watch_vminstances(:resource_version => vmis.resource_version)
33
+
34
+ thread = Thread.new do
35
+ @watch.each do |notice|
36
+ break if notice.type == 'MODIFIED' && notice.status == 'Running'
37
+ end
38
+ end
39
+
40
+ if thread.join(60).nil?
41
+ fail('VMI did not start')
42
+ end
43
+ @watch.finish
44
+ @watch = nil
45
+
46
+ vmi = @client.vminstances.get(vm_name)
47
+
48
+ assert_equal(vm.cpu_cores, cpus)
49
+ assert_equal(vm.memory, "#{memory_size}M")
50
+
51
+ vmi.interfaces do |iface|
52
+ assert !iface.mac_address.nil?
53
+ end
54
+
55
+ vmis = @client.vminstances.all()
56
+ @watch = @client.watch_vminstances(:resource_version => vmis.resource_version)
57
+
58
+ @client.vminstances.destroy(vm_name, @client.namespace)
59
+
60
+ thread = Thread.new do
61
+ @watch.each do |notice|
62
+ break if notice.type == 'DELETED'
63
+ end
64
+ end
65
+
66
+ if thread.join(60).nil?
67
+ fail('VMI was not removed')
68
+ end
69
+ @watch.finish
70
+ @watch = nil
71
+ end
72
+
73
+ it 'creates VMI and checks MAC using server' do
74
+ vm_name = 'test-server'
75
+ cpus = 1
76
+ memory_size = 64
77
+
78
+ volume = Fog::Kubevirt::Compute::Volume.new
79
+ volume.type = 'containerDisk'
80
+ volume.name = 'test.disk.01'
81
+ volume.info = 'registry:5000/kubevirt/cirros-container-disk-demo:devel'
82
+
83
+ @client.vms.create(vm_name: vm_name, cpus: cpus, memory_size: memory_size, volumes: [volume])
84
+
85
+ server_vm = @client.servers.get(vm_name)
86
+ assert_equal(server_vm.cpu_cores, cpus)
87
+ assert_equal(server_vm.memory, "#{memory_size}M")
88
+
89
+ server_vm.start()
90
+
91
+ # check whether vmi to be created if not it will raise ClientError
92
+ @client.servers.get(vm_name)
93
+
94
+ vmis = @client.vminstances.all()
95
+ @watch = @client.watch_vminstances(:resource_version => vmis.resource_version)
96
+
97
+ thread = Thread.new do
98
+ @watch.each do |notice|
99
+ break if notice.type == 'MODIFIED' && notice.status == 'Running'
100
+ end
101
+ end
102
+
103
+ if thread.join(60).nil?
104
+ fail('Server did not start')
105
+ end
106
+ @watch.finish
107
+ @watch = nil
108
+
109
+ server = @client.servers.get(vm_name)
110
+
111
+ assert_equal(server.cpu_cores, cpus)
112
+ assert_equal(server.memory, "#{memory_size}M")
113
+
114
+ server.interfaces do |iface|
115
+ assert !iface.mac_address.nil?
116
+ end
117
+
118
+ vmis = @client.vminstances.all()
119
+ @watch = @client.watch_vminstances(:resource_version => vmis.resource_version)
120
+
121
+ server.destroy
122
+
123
+ thread = Thread.new do
124
+ @watch.each do |notice|
125
+ break if notice.type == 'DELETED'
126
+ end
127
+ end
128
+
129
+ if thread.join(60).nil?
130
+ fail('Server was not removed')
131
+ end
132
+ @watch.finish
133
+ @watch = nil
134
+ end
135
+ end
@@ -0,0 +1,43 @@
1
+ require_relative './shared_context'
2
+
3
+ describe Fog::Kubevirt::Compute do
4
+ before :all do
5
+ conn = KubevirtConnection.new()
6
+ @client = conn.client.networkattachmentdefs
7
+ end
8
+
9
+ it 'CRD network attachements' do
10
+ name = 'ovs-red'
11
+ config = '{ cni_version: "0.3.1", type: "ovs", bridge: "red" }'
12
+
13
+ @client.create(name: name, config: config)
14
+
15
+ net_att_def = @client.get(name)
16
+ assert_equal(net_att_def.config, config)
17
+
18
+ @client.delete(name)
19
+
20
+ begin
21
+ @client.get(name)
22
+ fail "net_attach_def should not exist"
23
+ rescue ::Fog::Kubevirt::Errors::ClientError
24
+ # expected
25
+ end
26
+ end
27
+
28
+ it 'creates empty config' do
29
+ begin
30
+ @client.create(name: 'aaa')
31
+ fail "empty config can not be nil"
32
+ rescue ::Fog::Kubevirt::Errors::ClientError
33
+ # expected
34
+ end
35
+
36
+ begin
37
+ @client.create(name: 'aaa', config: '{}')
38
+ fail "empty config can not be nil"
39
+ rescue ::Fog::Kubevirt::Errors::ClientError
40
+ # expected
41
+ end
42
+ end
43
+ end
@@ -3,13 +3,14 @@ require_relative './shared_context'
3
3
  describe Fog::Kubevirt::Compute do
4
4
  before :all do
5
5
  conn = KubevirtConnection.new()
6
+ @namespace = conn.client.namespace
6
7
  @client = conn.client.pvcs
7
8
  end
8
9
 
9
10
  it 'CRD pvc' do
10
11
  pvc = {
11
12
  :name => 'test-pvc',
12
- :namespace => 'default',
13
+ :namespace => @namespace,
13
14
  :storage_class => '',
14
15
  :access_modes => ['ReadWriteOnce'],
15
16
  :requests => { storage: "1Gi" }
@@ -42,7 +43,7 @@ describe Fog::Kubevirt::Compute do
42
43
  it 'fails with wrong size format' do
43
44
  pvc = {
44
45
  :name => 'test-pvc',
45
- :namespace => 'default',
46
+ :namespace => @namespace,
46
47
  :storage_class => '',
47
48
  :access_modes => ['ReadWriteOnce'],
48
49
  :requests => { storage: "X" }
@@ -8,15 +8,22 @@ class KubevirtConnection
8
8
  @host = ENV.key?('KUBE_HOST') ? ENV['KUBE_HOST'] : options[:host]
9
9
  @port = ENV.key?('KUBE_PORT') ? ENV['KUBE_PORT'] : options[:port]
10
10
  @token = ENV.key?('KUBE_TOKEN') ? ENV['KUBE_TOKEN'] : options[:token]
11
+ @namespace = ENV.key?('KUBE_NAMESPACE') ? ENV['KUBE_NAMESPACE'] : options[:namespace]
11
12
  end
12
13
 
13
14
  def client
14
15
  if !ENV.key?('KUBECONFIG')
15
- return Fog::Kubevirt::Compute.new(:kubevirt_hostname => @host,
16
- :kubevirt_port => @port,
17
- :kubevirt_token => @token)
16
+ return Fog::Kubevirt::Compute.new(
17
+ :kubevirt_hostname => @host,
18
+ :kubevirt_port => @port,
19
+ :kubevirt_token => @token,
20
+ :kubevirt_namespace => @namespace
21
+ )
18
22
  else
19
- return Fog::Kubevirt::Compute.new(:kubevirt_token => nil)
23
+ return Fog::Kubevirt::Compute.new(
24
+ :kubevirt_token => nil,
25
+ :kubevirt_namespace => @namespace
26
+ )
20
27
  end
21
28
  end
22
29
  end
@@ -0,0 +1,45 @@
1
+ require_relative './shared_context'
2
+
3
+ require 'fileutils'
4
+
5
+ describe Fog::Kubevirt::Compute do
6
+ before :all do
7
+ conn = KubevirtConnection.new()
8
+ @client = conn.client
9
+ end
10
+
11
+ it 'creates volumes' do
12
+ scs = @client.storageclasses.all()
13
+ default_sc = scs.find { | sc | sc.default }
14
+
15
+ dir = Dir.mktmpdir
16
+
17
+ name = 'my-local-storage'
18
+ access_modes = [ 'ReadWriteOnce' ]
19
+ capacity = '1Gi'
20
+ type = 'hostPath'
21
+ config = { path: dir, type: "Directory" }
22
+
23
+ @client.persistentvolumes.create(name: name,
24
+ access_modes: access_modes,
25
+ capacity: capacity,
26
+ storage_class: default_sc.name,
27
+ type: type,
28
+ config: config)
29
+
30
+ pv = @client.persistentvolumes.get(name)
31
+ assert_equal(pv.storage_class, default_sc.name)
32
+ assert_equal(pv.capacity, capacity)
33
+ assert_equal(pv.access_modes, access_modes)
34
+
35
+ @client.persistentvolumes.delete(name)
36
+ FileUtils.remove_entry dir
37
+
38
+ begin
39
+ @client.persistentvolumes.get(name)
40
+ fail "pv should not exist"
41
+ rescue ::Fog::Kubevirt::Errors::ClientError
42
+ # expected
43
+ end
44
+ end
45
+ end
@@ -18,7 +18,7 @@ describe Fog::Compute do
18
18
  begin
19
19
  vm_name = 'test'
20
20
  cpus = 1
21
- memory_size = 64
21
+ memory_size = '64'
22
22
  pvc1 = 'mypvc1'
23
23
  pvc2 = 'mypvc2'
24
24
 
@@ -104,12 +104,13 @@ describe Fog::Compute do
104
104
  begin
105
105
  vm_name = 'test2'
106
106
  cpus = 1
107
- memory_size = 64
107
+ memory_size = '64'
108
+ memory_unit = 'M'
108
109
 
109
110
  volume = Fog::Kubevirt::Compute::Volume.new
110
111
  volume.type = 'persistentVolumeClaim'
111
112
  volume.info = 'mypvc3'
112
- @service.vms.create(vm_name: vm_name, cpus: cpus, memory_size: memory_size, volumes: [volume])
113
+ @service.vms.create(vm_name: vm_name, cpus: cpus, memory_size: memory_size, memory_unit: memory_unit, volumes: [volume])
113
114
 
114
115
  vm = @service.vms.get(vm_name)
115
116
 
@@ -1,8 +1,10 @@
1
1
  require_relative './spec_helper'
2
2
 
3
- describe Fog::Kubevirt::Compute::Shared::UnitConverter do
3
+ require 'fog/kubevirt/compute/utils/unit_converter'
4
4
 
5
- described_class = Fog::Kubevirt::Compute::Shared::UnitConverter
5
+ describe Fog::Kubevirt::Utils::UnitConverter do
6
+
7
+ described_class = Fog::Kubevirt::Utils::UnitConverter
6
8
 
7
9
  describe '.convert' do
8
10
  it 'converts correctly units that correspond to powers of 10' do
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: 1.2.5
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Kliczewski
@@ -14,7 +14,7 @@ authors:
14
14
  autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
- date: 2019-04-24 00:00:00.000000000 Z
17
+ date: 2019-05-14 00:00:00.000000000 Z
18
18
  dependencies:
19
19
  - !ruby/object:Gem::Dependency
20
20
  name: minitest
@@ -209,6 +209,8 @@ files:
209
209
  - lib/fog/kubevirt/compute/requests/list_vms.rb
210
210
  - lib/fog/kubevirt/compute/requests/list_volumes.rb
211
211
  - lib/fog/kubevirt/compute/requests/update_vm.rb
212
+ - lib/fog/kubevirt/compute/utils/exception_wrapper.rb
213
+ - lib/fog/kubevirt/compute/utils/unit_converter.rb
212
214
  - lib/fog/kubevirt/version.rb
213
215
  - spec/fixtures/kubevirt/networkattachmentdefinition/networkattachmentdefinitions_crud.yml
214
216
  - spec/fixtures/kubevirt/persistentvolume/persistent_volumes_crud.yml
@@ -219,8 +221,11 @@ files:
219
221
  - spec/fixtures/kubevirt/storageclass/storageclasses_crud.yml
220
222
  - spec/fixtures/kubevirt/vm/vm_create_multi.yml
221
223
  - spec/fixtures/kubevirt/vm/vm_create_single.yml
224
+ - spec/integration/mac_vmi_spec.rb
225
+ - spec/integration/net-attach-def_spec.rb
222
226
  - spec/integration/pvcs_spec.rb
223
227
  - spec/integration/shared_context.rb
228
+ - spec/integration/volumes_spec.rb
224
229
  - spec/unit/compute_v1alpha2_spec.rb
225
230
  - spec/unit/create_vm_spec.rb
226
231
  - spec/unit/network_attachment_definition_v1alpha2_spec.rb
@@ -266,8 +271,11 @@ test_files:
266
271
  - spec/fixtures/kubevirt/storageclass/storageclasses_crud.yml
267
272
  - spec/fixtures/kubevirt/vm/vm_create_multi.yml
268
273
  - spec/fixtures/kubevirt/vm/vm_create_single.yml
274
+ - spec/integration/mac_vmi_spec.rb
275
+ - spec/integration/net-attach-def_spec.rb
269
276
  - spec/integration/pvcs_spec.rb
270
277
  - spec/integration/shared_context.rb
278
+ - spec/integration/volumes_spec.rb
271
279
  - spec/unit/compute_v1alpha2_spec.rb
272
280
  - spec/unit/create_vm_spec.rb
273
281
  - spec/unit/network_attachment_definition_v1alpha2_spec.rb