bosh_vsphere_cpi 2.1.1 → 2.2.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.
- checksums.yaml +4 -4
- data/lib/cloud/vsphere/client.rb +82 -3
- data/lib/cloud/vsphere/cloud.rb +20 -21
- data/lib/cloud/vsphere/disk_provider.rb +25 -3
- data/lib/cloud/vsphere/ip_conflict_detector.rb +41 -0
- data/lib/cloud/vsphere/resources/cluster.rb +1 -1
- data/lib/cloud/vsphere/resources/datacenter.rb +10 -6
- data/lib/cloud/vsphere/vm_creator.rb +5 -0
- data/lib/cloud/vsphere/vm_provider.rb +2 -2
- data/lib/cloud/vsphere.rb +1 -0
- metadata +6 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 20484247b0bb76cefc40f2f28054428a6680991b
|
4
|
+
data.tar.gz: 1d48fb046acb02cf0417b6b803c28e6883291b0a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0ca9d5f7600ad20b84ce67c8ddeab6381c7d77ffa2baaff0323f492bfb267e57570385249b91f0c49970ddbb75b98c453b6422e02e5abd5c443f0e7f42d91627
|
7
|
+
data.tar.gz: 17673951c1c87149dc4e32ba21627f1d139a96af603d81cdd4deace7791dbcdf7a4cf341f9ec7ba0f5b825bb300e33ce3bd147beb60b2bc2cd387da756938bb1
|
data/lib/cloud/vsphere/client.rb
CHANGED
@@ -13,7 +13,7 @@ module VSphereCloud
|
|
13
13
|
def initialize(host, options={})
|
14
14
|
@soap_stub = SoapStub.new(host, options[:soap_log]).create
|
15
15
|
|
16
|
-
@service_instance =Vim::ServiceInstance.new('ServiceInstance', @soap_stub)
|
16
|
+
@service_instance = Vim::ServiceInstance.new('ServiceInstance', @soap_stub)
|
17
17
|
@service_content = @service_instance.content
|
18
18
|
|
19
19
|
@metrics_cache = {}
|
@@ -130,6 +130,31 @@ module VSphereCloud
|
|
130
130
|
@service_content.search_index.find_by_inventory_path(full_path)
|
131
131
|
end
|
132
132
|
|
133
|
+
def find_vm_by_ip(ip)
|
134
|
+
@service_content.search_index.find_by_ip(nil, ip, true)
|
135
|
+
end
|
136
|
+
|
137
|
+
def find_vm_by_name(datacenter, vm_name)
|
138
|
+
yield_all_resources_by_name(datacenter, 'VirtualMachine') do |vm_mob, name|
|
139
|
+
if name == vm_name
|
140
|
+
return vm_mob
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
nil
|
145
|
+
end
|
146
|
+
|
147
|
+
def find_all_stemcell_replicas(datacenter, stemcell_id)
|
148
|
+
matches = []
|
149
|
+
yield_all_resources_by_name(datacenter, 'VirtualMachine') do |vm_mob, name|
|
150
|
+
if name =~ Regexp.new(stemcell_id)
|
151
|
+
matches << vm_mob
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
matches
|
156
|
+
end
|
157
|
+
|
133
158
|
def wait_for_task(task)
|
134
159
|
interval = 1.0
|
135
160
|
started = Time.now
|
@@ -208,13 +233,17 @@ module VSphereCloud
|
|
208
233
|
disk_size_in_mb.nil? ? nil : Resources::Disk.new(disk_cid, disk_size_in_mb, datastore, disk_path)
|
209
234
|
end
|
210
235
|
|
211
|
-
def create_disk(datacenter, datastore, disk_cid, disk_folder, disk_size_in_mb)
|
236
|
+
def create_disk(datacenter, datastore, disk_cid, disk_folder, disk_size_in_mb, disk_type)
|
237
|
+
if disk_type.nil?
|
238
|
+
raise 'no disk type specified'
|
239
|
+
end
|
240
|
+
|
212
241
|
disk_path = "[#{datastore.name}] #{disk_folder}/#{disk_cid}.vmdk"
|
213
242
|
|
214
243
|
create_parent_folder(datacenter, disk_path)
|
215
244
|
|
216
245
|
disk_spec = VimSdk::Vim::VirtualDiskManager::FileBackedVirtualDiskSpec.new
|
217
|
-
disk_spec.disk_type =
|
246
|
+
disk_spec.disk_type = disk_type
|
218
247
|
disk_spec.capacity_kb = disk_size_in_mb * 1024
|
219
248
|
disk_spec.adapter_type = 'lsiLogic'
|
220
249
|
|
@@ -296,5 +325,55 @@ module VSphereCloud
|
|
296
325
|
metrics.each { |metric| result[metric_names[metric.counter_id]] = metric }
|
297
326
|
result
|
298
327
|
end
|
328
|
+
|
329
|
+
def create_filter_spec(datacenter, resource_type, property_names)
|
330
|
+
# Create a view to list all the resources in the root folder
|
331
|
+
container_view = @service_content.view_manager.create_container_view(datacenter.mob, [resource_type], true)
|
332
|
+
|
333
|
+
# Create an object spec to define the beginning of the traversal
|
334
|
+
object_spec = VimSdk::Vmodl::Query::PropertyCollector::ObjectSpec.new
|
335
|
+
object_spec.obj = container_view
|
336
|
+
object_spec.skip = false
|
337
|
+
|
338
|
+
# Create a traversal spec to select all objects in the 'view' of the ContainerView
|
339
|
+
vm_traversal_spec = VimSdk::Vmodl::Query::PropertyCollector::TraversalSpec.new
|
340
|
+
vm_traversal_spec.name = 'searchTraversalSpec'
|
341
|
+
vm_traversal_spec.path = 'view'
|
342
|
+
vm_traversal_spec.type = 'ContainerView'
|
343
|
+
object_spec.select_set << vm_traversal_spec
|
344
|
+
|
345
|
+
# Specify the properties for retrieval
|
346
|
+
property_spec = VimSdk::Vmodl::Query::PropertyCollector::PropertySpec.new
|
347
|
+
property_spec.type = resource_type
|
348
|
+
property_spec.path_set.concat(property_names)
|
349
|
+
property_spec.all = false
|
350
|
+
|
351
|
+
filter_spec = VimSdk::Vmodl::Query::PropertyCollector::FilterSpec.new
|
352
|
+
filter_spec.object_set << object_spec
|
353
|
+
filter_spec.prop_set << property_spec
|
354
|
+
filter_spec
|
355
|
+
end
|
356
|
+
|
357
|
+
def yield_all_resources_by_name(datacenter, type)
|
358
|
+
raise 'Requires a vSphere object type' if type.nil?
|
359
|
+
# Collect all the 'name' attributes of all VMs in the datacenter
|
360
|
+
vm_filter_spec = create_filter_spec(datacenter, type, ['name'])
|
361
|
+
ro = VimSdk::Vmodl::Query::PropertyCollector::RetrieveOptions.new
|
362
|
+
result = @service_content.property_collector.retrieve_properties_ex([vm_filter_spec], ro)
|
363
|
+
|
364
|
+
# Retrieve Properties Ex returns paginated results, so we continue retrieving
|
365
|
+
# more pages if the token indicates there are more pages.
|
366
|
+
token = "not nil"
|
367
|
+
until token.nil?
|
368
|
+
result.objects.each do |object_content|
|
369
|
+
# Yield the object MOB and its name
|
370
|
+
yield object_content.obj, object_content.prop_set.first.val
|
371
|
+
end
|
372
|
+
token = result.token
|
373
|
+
unless token.nil?
|
374
|
+
result = @service_content.property_collector.continue_retrieve_properties_ex(token)
|
375
|
+
end
|
376
|
+
end
|
377
|
+
end
|
299
378
|
end
|
300
379
|
end
|
data/lib/cloud/vsphere/cloud.rb
CHANGED
@@ -133,25 +133,24 @@ module VSphereCloud
|
|
133
133
|
with_thread_name("delete_stemcell(#{stemcell})") do
|
134
134
|
Bosh::ThreadPool.new(max_threads: 32, logger: @logger).wrap do |pool|
|
135
135
|
@logger.info("Looking for stemcell replicas in: #{@datacenter.name}")
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
@logger.info("Deleted: #{template_name}")
|
146
|
-
end
|
136
|
+
matches = client.find_all_stemcell_replicas(@datacenter, stemcell)
|
137
|
+
|
138
|
+
matches.each do |sc|
|
139
|
+
sc_name = sc.name
|
140
|
+
@logger.info("Found: #{sc_name}")
|
141
|
+
pool.process do
|
142
|
+
@logger.info("Deleting: #{sc_name}")
|
143
|
+
client.delete_vm(sc)
|
144
|
+
@logger.info("Deleted: #{sc_name}")
|
147
145
|
end
|
148
146
|
end
|
147
|
+
|
149
148
|
end
|
150
149
|
end
|
151
150
|
end
|
152
151
|
|
153
152
|
def stemcell_vm(name)
|
154
|
-
client.
|
153
|
+
client.find_vm_by_name(@datacenter, name)
|
155
154
|
end
|
156
155
|
|
157
156
|
def create_vm(agent_id, stemcell, cloud_properties, networks, disk_locality = nil, environment = nil)
|
@@ -381,7 +380,8 @@ module VSphereCloud
|
|
381
380
|
cluster = @datacenter.clusters[vm.cluster]
|
382
381
|
end
|
383
382
|
|
384
|
-
|
383
|
+
disk_type = cloud_properties['type']
|
384
|
+
disk = disk_provider.create(size_in_mb, disk_type, cluster)
|
385
385
|
@logger.info("Created disk: #{disk.inspect}")
|
386
386
|
disk.cid
|
387
387
|
end
|
@@ -398,21 +398,18 @@ module VSphereCloud
|
|
398
398
|
end
|
399
399
|
|
400
400
|
def replicate_stemcell(cluster, datastore, stemcell)
|
401
|
-
|
402
|
-
|
403
|
-
raise "Could not find VM for stemcell '#{stemcell}' at path '#{stemcell_vm_path_components.join("/")}'" if stemcell_vm.nil?
|
401
|
+
stemcell_vm = client.find_vm_by_name(@datacenter, stemcell)
|
402
|
+
raise "Could not find VM for stemcell '#{stemcell}'" if stemcell_vm.nil?
|
404
403
|
stemcell_datastore = @cloud_searcher.get_property(stemcell_vm, Vim::VirtualMachine, 'datastore', ensure_all: true)
|
405
404
|
|
406
405
|
if stemcell_datastore != datastore.mob
|
407
406
|
@logger.info("Stemcell lives on a different datastore, looking for a local copy of: #{stemcell}.")
|
408
407
|
local_stemcell_name = "#{stemcell} %2f #{datastore.mob.__mo_id__}"
|
409
|
-
local_stemcell_path =
|
410
|
-
[cluster.datacenter.name, 'vm', cluster.datacenter.template_folder.path_components, local_stemcell_name]
|
411
|
-
replicated_stemcell_vm = client.find_by_inventory_path(local_stemcell_path)
|
412
408
|
|
409
|
+
replicated_stemcell_vm = client.find_vm_by_name(@datacenter, local_stemcell_name)
|
413
410
|
if replicated_stemcell_vm.nil?
|
414
411
|
@logger.info("Cluster doesn't have stemcell #{stemcell}, replicating")
|
415
|
-
|
412
|
+
replicated_stemcell_vm = replicate_stemcell_helper(stemcell, stemcell_vm, local_stemcell_name, cluster, datastore, replicated_stemcell_vm)
|
416
413
|
else
|
417
414
|
@logger.info("Found local stemcell replica: #{replicated_stemcell_vm}")
|
418
415
|
end
|
@@ -704,7 +701,7 @@ module VSphereCloud
|
|
704
701
|
placer.nil? ? @resources : placer
|
705
702
|
end
|
706
703
|
|
707
|
-
def replicate_stemcell_helper(stemcell, stemcell_vm, local_stemcell_name, cluster, datastore, replicated_stemcell_vm
|
704
|
+
def replicate_stemcell_helper(stemcell, stemcell_vm, local_stemcell_name, cluster, datastore, replicated_stemcell_vm)
|
708
705
|
@logger.info("Replicating #{stemcell} (#{stemcell_vm}) to #{local_stemcell_name}")
|
709
706
|
task = clone_vm(stemcell_vm,
|
710
707
|
local_stemcell_name,
|
@@ -716,6 +713,8 @@ module VSphereCloud
|
|
716
713
|
@logger.info("Replicated #{stemcell} (#{stemcell_vm}) to #{local_stemcell_name} (#{replicated_stemcell_vm})")
|
717
714
|
rescue VSphereCloud::Client::DuplicateName => ex
|
718
715
|
@logger.info("Stemcell is being replicated by another thread, waiting for #{local_stemcell_name} to be ready")
|
716
|
+
local_stemcell_path =
|
717
|
+
[cluster.datacenter.name, 'vm', cluster.datacenter.template_folder.path_components, local_stemcell_name]
|
719
718
|
replicated_stemcell_vm = client.find_by_inventory_path(local_stemcell_path)
|
720
719
|
# get_properties will ensure the existence of the snapshot by retrying.
|
721
720
|
# This forces us to wait for a valid snapshot before returning with the
|
@@ -3,6 +3,16 @@ require 'cloud/vsphere/resources/disk'
|
|
3
3
|
|
4
4
|
module VSphereCloud
|
5
5
|
class DiskProvider
|
6
|
+
# https://pubs.vmware.com/vsphere-55/index.jsp?topic=%2Fcom.vmware.wssdk.apiref.doc%2Fvim.VirtualDiskManager.VirtualDiskType.html
|
7
|
+
SUPPORTED_DISK_TYPES = %w{
|
8
|
+
eagerZeroedThick
|
9
|
+
preallocated
|
10
|
+
thick
|
11
|
+
thin
|
12
|
+
}
|
13
|
+
|
14
|
+
DEFAULT_DISK_TYPE = 'preallocated'
|
15
|
+
|
6
16
|
def initialize(virtual_disk_manager, datacenter, resources, disk_path, client, logger)
|
7
17
|
@virtual_disk_manager = virtual_disk_manager
|
8
18
|
@datacenter = datacenter
|
@@ -12,7 +22,16 @@ module VSphereCloud
|
|
12
22
|
@logger = logger
|
13
23
|
end
|
14
24
|
|
15
|
-
def create(disk_size_in_mb, cluster)
|
25
|
+
def create(disk_size_in_mb, disk_type, cluster)
|
26
|
+
type = disk_type
|
27
|
+
if type.nil?
|
28
|
+
type = DEFAULT_DISK_TYPE
|
29
|
+
end
|
30
|
+
|
31
|
+
unless SUPPORTED_DISK_TYPES.include?(type)
|
32
|
+
raise "Disk type: '#{disk_type}' is not supported"
|
33
|
+
end
|
34
|
+
|
16
35
|
if cluster
|
17
36
|
datastore = @resources.pick_persistent_datastore_in_cluster(cluster.name, disk_size_in_mb)
|
18
37
|
else
|
@@ -21,14 +40,17 @@ module VSphereCloud
|
|
21
40
|
disk_cid = "disk-#{SecureRandom.uuid}"
|
22
41
|
@logger.debug("Creating disk '#{disk_cid}' in datastore '#{datastore.name}'")
|
23
42
|
|
24
|
-
@client.create_disk(@datacenter, datastore, disk_cid, @disk_path, disk_size_in_mb)
|
43
|
+
@client.create_disk(@datacenter, datastore, disk_cid, @disk_path, disk_size_in_mb, type)
|
25
44
|
end
|
26
45
|
|
27
46
|
def find_and_move(disk_cid, cluster, datacenter, accessible_datastores)
|
28
47
|
disk = find(disk_cid)
|
29
48
|
disk_in_persistent_datastore = @datacenter.persistent_datastores.include?(disk.datastore.name)
|
30
49
|
disk_in_accessible_datastore = accessible_datastores.include?(disk.datastore.name)
|
31
|
-
|
50
|
+
if disk_in_persistent_datastore && disk_in_accessible_datastore
|
51
|
+
@logger.info("Disk #{disk_cid} found in an accessible, persistent datastore '#{disk.datastore.name}'")
|
52
|
+
return disk
|
53
|
+
end
|
32
54
|
|
33
55
|
destination_datastore = @resources.pick_persistent_datastore_in_cluster(cluster.name, disk.size_in_mb)
|
34
56
|
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module VSphereCloud
|
2
|
+
class IPConflictDetector
|
3
|
+
|
4
|
+
def initialize(logger, client, networks)
|
5
|
+
@logger = logger
|
6
|
+
@client = client
|
7
|
+
@networks = networks
|
8
|
+
@desired_ip_mapping = []
|
9
|
+
|
10
|
+
@networks.map do |_, network_spec|
|
11
|
+
ip = network_spec['ip']
|
12
|
+
network_name = network_spec.fetch('cloud_properties', [])['name']
|
13
|
+
|
14
|
+
if ip && network_name
|
15
|
+
@desired_ip_mapping << {ip: ip, name: network_name}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def conflicts
|
21
|
+
conflicts = []
|
22
|
+
@desired_ip_mapping.each do |mapping|
|
23
|
+
@logger.info("Checking if ip '#{mapping[:ip]}' is in use")
|
24
|
+
vm = @client.find_vm_by_ip(mapping[:ip])
|
25
|
+
if vm.nil?
|
26
|
+
next
|
27
|
+
end
|
28
|
+
|
29
|
+
vm.guest.net.each do |nic|
|
30
|
+
if nic.ip_address.include?(mapping[:ip]) && nic.network == mapping[:name]
|
31
|
+
@logger.info("found conflicting vm: #{vm.name}, on network: #{mapping[:name]} with ip: #{mapping[:ip]}")
|
32
|
+
conflicts << {vm_name: vm.name, network_name: mapping[:name], ip: mapping[:ip]}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
conflicts
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
@@ -139,7 +139,7 @@ module VSphereCloud
|
|
139
139
|
available_datastores = datastores.reject { |datastore| datastore.free_space - size < DISK_HEADROOM }
|
140
140
|
|
141
141
|
@logger.debug("Looking for a #{type} datastore in #{self.name} with #{size}MB free space.")
|
142
|
-
@logger.debug("All datastores: #{datastores.map(&:debug_info)}")
|
142
|
+
@logger.debug("All datastores within cluster #{self.name}: #{datastores.map(&:debug_info)}")
|
143
143
|
@logger.debug("Datastores with enough space: #{available_datastores.map(&:debug_info)}")
|
144
144
|
|
145
145
|
selected_datastore = Util.weighted_random(available_datastores.map { |datastore| [datastore, datastore.free_space] })
|
@@ -68,12 +68,16 @@ module VSphereCloud
|
|
68
68
|
end
|
69
69
|
|
70
70
|
def clusters
|
71
|
-
clusters = {}
|
72
|
-
@clusters.each do |cluster_name, cluster_config|
|
73
|
-
clusters[cluster_name] = @cluster_provider.find(cluster_name, cluster_config)
|
74
|
-
end
|
75
71
|
@logger.debug("All clusters provided: #{@clusters}")
|
76
|
-
clusters
|
72
|
+
@clusters.keys.inject({}) do |acc, cluster_name|
|
73
|
+
acc[cluster_name] = find_cluster(cluster_name)
|
74
|
+
acc
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def find_cluster(cluster_name)
|
79
|
+
cluster_config = @clusters[cluster_name]
|
80
|
+
@cluster_provider.find(cluster_name, cluster_config)
|
77
81
|
end
|
78
82
|
|
79
83
|
def persistent_datastores
|
@@ -103,7 +107,7 @@ module VSphereCloud
|
|
103
107
|
available_datastores = datastores.reject { |datastore| datastore.free_space - size < DISK_HEADROOM }
|
104
108
|
|
105
109
|
@logger.debug("Looking for a '#{type}' datastore with #{size}MB free space.")
|
106
|
-
@logger.debug("All datastores: #{datastores.map(&:debug_info)}")
|
110
|
+
@logger.debug("All datastores within datacenter #{self.name}: #{datastores.map(&:debug_info)}")
|
107
111
|
@logger.debug("Datastores with enough space: #{available_datastores.map(&:debug_info)}")
|
108
112
|
|
109
113
|
selected_datastore = Util.weighted_random(available_datastores.map { |datastore| [datastore, datastore.free_space] })
|
@@ -18,6 +18,11 @@ module VSphereCloud
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def create(agent_id, stemcell_cid, networks, persistent_disk_cids, environment)
|
21
|
+
ip_conflicts = IPConflictDetector.new(@logger, @client, networks).conflicts
|
22
|
+
unless ip_conflicts.empty?
|
23
|
+
raise "Cannot create new VM because of IP conflicts with other VMs on the same networks: #{ip_conflicts}"
|
24
|
+
end
|
25
|
+
|
21
26
|
stemcell_vm = @cpi.stemcell_vm(stemcell_cid)
|
22
27
|
raise "Could not find VM for stemcell '#{stemcell_cid}'" if stemcell_vm.nil?
|
23
28
|
|
@@ -7,8 +7,8 @@ module VSphereCloud
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def find(vm_cid)
|
10
|
-
vm_mob = @client.
|
11
|
-
raise Bosh::Clouds::VMNotFound, "VM '#{vm_cid}' not found
|
10
|
+
vm_mob = @client.find_vm_by_name(@datacenter, vm_cid)
|
11
|
+
raise Bosh::Clouds::VMNotFound, "VM '#{vm_cid}' not found in datacenter '#{@datacenter.name}'" if vm_mob.nil?
|
12
12
|
|
13
13
|
Resources::VM.new(vm_cid, vm_mob, @client, @logger)
|
14
14
|
end
|
data/lib/cloud/vsphere.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bosh_vsphere_cpi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- VMware
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-11-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bosh_common
|
@@ -86,14 +86,14 @@ dependencies:
|
|
86
86
|
requirements:
|
87
87
|
- - '='
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: 2.
|
89
|
+
version: 2.4.0
|
90
90
|
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - '='
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: 2.
|
96
|
+
version: 2.4.0
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: mono_logger
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -131,6 +131,7 @@ files:
|
|
131
131
|
- lib/cloud/vsphere/drs_rules/vm_attribute_manager.rb
|
132
132
|
- lib/cloud/vsphere/file_provider.rb
|
133
133
|
- lib/cloud/vsphere/fixed_cluster_placer.rb
|
134
|
+
- lib/cloud/vsphere/ip_conflict_detector.rb
|
134
135
|
- lib/cloud/vsphere/lease_obtainer.rb
|
135
136
|
- lib/cloud/vsphere/lease_updater.rb
|
136
137
|
- lib/cloud/vsphere/object_stringifier.rb
|
@@ -198,7 +199,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
198
199
|
version: '0'
|
199
200
|
requirements: []
|
200
201
|
rubyforge_project:
|
201
|
-
rubygems_version: 2.2.
|
202
|
+
rubygems_version: 2.2.2
|
202
203
|
signing_key:
|
203
204
|
specification_version: 4
|
204
205
|
summary: BOSH VSphere CPI
|