fog-vsphere 2.3.0 → 2.4.0

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
  SHA256:
3
- metadata.gz: 2802cab39cda0d34fbf317a0ef39e79b53a7ce20fd736e2f41ac86e0d95f494b
4
- data.tar.gz: d173548894fdfed4a4c517e1e6b30b513420b2bf59be77ce1147350ba695a15f
3
+ metadata.gz: d5281df844dc5370c7eeb4aa1b6d062edc780650cfa26143ef122a9f719b1305
4
+ data.tar.gz: ddd9c2dfe8393e74aa74267406f23638047f52ae426dcb98b30d0db64666e5d2
5
5
  SHA512:
6
- metadata.gz: 62ec056eb0f333a9a80eb1d4ec523cb2e5f8893d8b0cdd9f5243210a920b2acfeeaa74dd5fe00770b5eb77bd5a255167dde730b8f89b257e1d8891133803e1e6
7
- data.tar.gz: 4ac64f5bca359eb6e6290d137e1975644929f4eee39e0ad5f48d6c7fb2f58d8f6a235d557efe5bb26f1e0bfc98f88321a199b78bbf6b195aa92c3459e7b9bfd9
6
+ metadata.gz: cf18dc5cee08a4be3919c5473237ad83ba609d95868891dd7afb43d8d0aacd4d89ff05f211e3a89e25610aa3b5ee0da75f846fbbfdd7a3d1e3b9301d860f7586
7
+ data.tar.gz: 597988c88827a950b9ff4ab4363c344f72ebca5833cae3397358ddab8fae9f4f63813c8fa54826c3c2956e0469898165e582f4ef17406c22bd95d1b9c1fd34fd
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ ## v2.4.0
2
+ * improve folder loading performance (#158)
3
+ * improve storage pod loading performance (#160)
4
+ * improve datastore loading performance (#159)
5
+ * prevent hard fail on undefined legacy networks (#157)
6
+ * add support to create vms on NSX-T networks (#153)
7
+ * set the server for fog volume objects (#152)
8
+ * add server guard to unit_number calculation (#152)
9
+
1
10
  ## v2.3.0
2
11
  * set volume unit_number when cloning a vm (#151)
3
12
  * add unclustered esxi hosts back to cluster selection (#149)
data/CONTRIBUTING.md CHANGED
@@ -1,18 +1,18 @@
1
- ## Getting Involved
1
+ # Getting Involved
2
2
 
3
3
  New contributors are always welcome, when it doubt please ask questions. We strive to be an open and welcoming community. Please be nice to one another.
4
4
 
5
- ### Coding
5
+ ## Coding
6
6
 
7
- * Pick a task:
8
- * Offer feedback on open [pull requests](https://github.com/fog/fog-vsphere/pulls).
9
- * Review open [issues](https://github.com/fog/fog-vsphere/issues) for things to help on.
10
- * [Create an issue](https://github.com/fog/fog-vsphere/issues/new) to start a discussion on additions or features.
11
- * Fork the project, add your changes and tests to cover them in a topic branch.
12
- * Commit your changes and rebase against `fog/fog-vsphere` to ensure everything is up to date.
13
- * [Submit a pull request](https://github.com/fog/fog-vsphere/compare/)
7
+ - Pick a task:
8
+ - Offer feedback on open [pull requests](https://github.com/fog/fog-vsphere/pulls).
9
+ - Review open [issues](https://github.com/fog/fog-vsphere/issues) for things to help on.
10
+ - [Create an issue](https://github.com/fog/fog-vsphere/issues/new) to start a discussion on additions or features.
11
+ - Fork the project, add your changes and tests to cover them in a topic branch.
12
+ - Commit your changes and rebase against `fog/fog-vsphere` to ensure everything is up to date.
13
+ - [Submit a pull request](https://github.com/fog/fog-vsphere/compare/)
14
14
 
15
- ### Non-Coding
15
+ ## Non-Coding
16
16
 
17
- * Offer feedback on open [issues](https://github.com/fog/fog-vsphere/issues).
18
- * Organize or volunteer at events.
17
+ - Offer feedback on open [issues](https://github.com/fog/fog-vsphere/issues).
18
+ - Organize or volunteer at events.
data/README.md CHANGED
@@ -1,11 +1,8 @@
1
1
  # Fog vSphere
2
+
2
3
  > VMware vSphere® provider for the Fog cloud services library
3
4
 
4
- [![Gem Version][gemfury-image]][gemfury-url]
5
- [![Build Status][travis-image]][travis-url]
6
- [![Dependency Status][gemnasium-image]][gemnasium-url]
7
- [![Test Coverage][coverage-image]][coverage-url]
8
- [![Code Climate][climate-image]][climate-url]
5
+ [![Gem Version][gemfury-image]][gemfury-url] [![Build Status][travis-image]][travis-url] [![Test Coverage][coverage-image]][coverage-url] [![Code Climate][climate-image]][climate-url]
9
6
 
10
7
  The VMware vSphere® provider allows you to use the abstractions of the Fog cloud services library to communicate with vSphere.
11
8
 
@@ -91,7 +88,5 @@ To contribute to this project, add an issue or pull request. For more info on wh
91
88
  [coverage-url]: https://codeclimate.com/github/fog/fog-vsphere/coverage
92
89
  [gemfury-image]: https://badge.fury.io/rb/fog-vsphere.svg
93
90
  [gemfury-url]: http://badge.fury.io/rb/fog-vsphere
94
- [gemnasium-image]: https://gemnasium.com/fog/fog-vsphere.svg
95
- [gemnasium-url]: https://gemnasium.com/fog/fog-vsphere
96
91
  [travis-image]: https://travis-ci.org/fog/fog-vsphere.svg?branch=master
97
92
  [travis-url]: https://travis-ci.org/fog/fog-vsphere
@@ -344,7 +344,14 @@ module Fog
344
344
 
345
345
  def initialize_volumes
346
346
  if attributes[:volumes] && attributes[:volumes].is_a?(Array)
347
- attributes[:volumes].map! { |vol| vol.is_a?(Hash) ? service.volumes.new({ server: self }.merge(vol)) : vol }
347
+ attributes[:volumes].map! do |vol|
348
+ if vol.is_a?(Hash)
349
+ service.volumes.new({ server: self }.merge(vol))
350
+ else
351
+ vol.server = self
352
+ vol
353
+ end
354
+ end
348
355
  end
349
356
  end
350
357
 
@@ -98,6 +98,7 @@ module Fog
98
98
  end
99
99
 
100
100
  def set_unit_number
101
+ requires :server
101
102
  # When adding volumes to vsphere, if our unit_number is 7 or higher, vsphere will increment the unit_number
102
103
  # This is due to SCSI ID 7 being reserved for the pvscsi controller
103
104
  # When referring to a volume that already added using a unit_id of 7 or higher, we must refer to the actual SCSI ID
@@ -31,7 +31,7 @@ module Fog
31
31
  get_raw_host(attributes[:host], attributes[:cluster], attributes[:datacenter])
32
32
  end
33
33
  # if any volume has a storage_pod set, we deploy the vm on a storage pod instead of the defined datastores
34
- pod = get_storage_pod(attributes)
34
+ pod = get_storage_pod_from_volumes(attributes)
35
35
  vm = if pod
36
36
  create_vm_on_storage_pod(pod, vm_cfg, vmFolder, resource_pool, attributes[:datacenter], host)
37
37
  else
@@ -73,7 +73,7 @@ module Fog
73
73
 
74
74
  # check if a storage pool is set on any of the volumes and return the first result found or nil
75
75
  # return early if vsphere revision is lower than 5 as this is not supported
76
- def get_storage_pod(attributes)
76
+ def get_storage_pod_from_volumes(attributes)
77
77
  return unless @vsphere_rev.to_f >= 5
78
78
  volume = attributes[:volumes].detect { |volume| !(volume.storage_pod.nil? || volume.storage_pod.empty?) }
79
79
  volume.storage_pod if volume
@@ -83,7 +83,7 @@ module Fog
83
83
  # by default we prefer to keep it at the same place the (first) vmdk is located
84
84
  # if we deploy the vm on a storage pool, we have to return an empty string
85
85
  def vm_path_name(attributes)
86
- return '' if get_storage_pod(attributes)
86
+ return '' if get_storage_pod_from_volumes(attributes)
87
87
  datastore = attributes[:volumes].first.datastore unless attributes[:volumes].empty?
88
88
  datastore ||= 'datastore1'
89
89
  "[#{datastore}]"
@@ -100,7 +100,7 @@ module Fog
100
100
  end
101
101
 
102
102
  if (disks = attributes[:volumes])
103
- devices << disks.map { |disk| create_disk(disk, :add, storage_pod: get_storage_pod(attributes)) }
103
+ devices << disks.map { |disk| create_disk(disk, :add, storage_pod: get_storage_pod_from_volumes(attributes)) }
104
104
  end
105
105
 
106
106
  if (cdroms = attributes[:cdroms])
@@ -171,6 +171,12 @@ module Fog
171
171
  switchUuid: raw_network.config.distributedVirtualSwitch.uuid
172
172
  )
173
173
  )
174
+ elsif raw_network.is_a? RbVmomi::VIM::OpaqueNetwork
175
+ RbVmomi::VIM.VirtualEthernetCardOpaqueNetworkBackingInfo(
176
+ opaqueNetworkType: raw_network.summary.opaqueNetworkType,
177
+ opaqueNetworkId: raw_network.summary.opaqueNetworkId
178
+ )
179
+
174
180
  else
175
181
  RbVmomi::VIM.VirtualEthernetCardNetworkBackingInfo(deviceName: nic.network)
176
182
  end
@@ -10,8 +10,12 @@ module Fog
10
10
 
11
11
  protected
12
12
 
13
- def get_raw_cluster(name, datacenter_name)
14
- dc = find_raw_datacenter(datacenter_name)
13
+ def get_raw_cluster(name, datacenter_name_or_obj)
14
+ dc = if datacenter_name_or_obj.is_a?(String)
15
+ find_raw_datacenter(datacenter_name_or_obj)
16
+ else
17
+ datacenter_name_or_obj
18
+ end
15
19
  dc.find_compute_resource(name)
16
20
  end
17
21
  end
@@ -3,9 +3,9 @@ module Fog
3
3
  class Vsphere
4
4
  class Real
5
5
  def get_datastore(name, datacenter_name)
6
- datastore = get_raw_datastore(name, datacenter_name)
6
+ datastore = list_datastores(datacenter: datacenter_name).detect { |ds| ds[:name] == name }
7
7
  raise(Fog::Compute::Vsphere::NotFound) unless datastore
8
- datastore_attributes(datastore, datacenter_name)
8
+ datastore
9
9
  end
10
10
 
11
11
  protected
@@ -52,7 +52,7 @@ module Fog
52
52
  name: folder.name,
53
53
  parent: folder.parent.name,
54
54
  datacenter: datacenter_name,
55
- type: folder_type(folder),
55
+ type: folder_type(folder.childType),
56
56
  path: folder_path(folder)
57
57
  }
58
58
  end
@@ -61,8 +61,7 @@ module Fog
61
61
  '/' + folder.path.map(&:last).join('/')
62
62
  end
63
63
 
64
- def folder_type(folder)
65
- types = folder.childType
64
+ def folder_type(types)
66
65
  return :vm if types.include?('VirtualMachine')
67
66
  return :network if types.include?('Network')
68
67
  return :datastore if types.include?('Datastore')
@@ -3,9 +3,9 @@ module Fog
3
3
  class Vsphere
4
4
  class Real
5
5
  def get_storage_pod(name, datacenter_name)
6
- storage_pod = get_raw_storage_pod(name, datacenter_name)
6
+ storage_pod = list_storage_pods(datacenter: datacenter_name).detect { |pod| pod[:name] == name }
7
7
  raise(Fog::Compute::Vsphere::NotFound) unless storage_pod
8
- storage_pod_attributes(storage_pod, datacenter_name)
8
+ storage_pod
9
9
  end
10
10
 
11
11
  protected
@@ -13,6 +13,10 @@ module Fog
13
13
  def get_raw_storage_pod(name, datacenter_name)
14
14
  raw_storage_pods(datacenter_name).detect { |pod| pod.name == name }
15
15
  end
16
+
17
+ def raw_storage_pods(datacenter_name)
18
+ list_container_view(datacenter_name, 'StoragePod')
19
+ end
16
20
  end
17
21
 
18
22
  class Mock
@@ -7,32 +7,76 @@ module Fog
7
7
  cluster_name = filters.fetch(:cluster, nil)
8
8
  # default to show all datastores
9
9
  only_active = filters[:accessible] || false
10
- raw_datastores(datacenter_name, cluster_name).map do |datastore|
11
- next if only_active && !datastore.summary.accessible
12
- datastore_attributes(datastore, datacenter_name)
10
+
11
+ dc = find_raw_datacenter(datacenter_name)
12
+
13
+ datastores = if cluster_name
14
+ cluster = get_raw_cluster(cluster_name, dc)
15
+ property_collector_results(datastore_cluster_filter_spec(cluster))
16
+ else
17
+ property_collector_results(datastore_filter_spec(dc))
18
+ end
19
+
20
+ datastores.map do |datastore|
21
+ next if only_active && !datastore['summary.accessible']
22
+ map_attrs_to_hash(datastore, datastore_attribute_mapping).merge(
23
+ datacenter: datacenter_name,
24
+ id: managed_obj_id(datastore.obj)
25
+ )
13
26
  end.compact
14
27
  end
15
28
 
16
- def raw_datastores(datacenter_name, cluster = nil)
17
- if cluster.nil?
18
- find_raw_datacenter(datacenter_name).datastore
19
- else
20
- get_raw_cluster(cluster, datacenter_name).datastore
21
- end
29
+ protected
30
+
31
+ def datastore_filter_spec(obj)
32
+ RbVmomi::VIM.PropertyFilterSpec(
33
+ objectSet: [
34
+ obj: obj.datastoreFolder,
35
+ skip: true,
36
+ selectSet: [
37
+ folder_traversal_spec
38
+ ]
39
+ ],
40
+ propSet: datastore_filter_prop_set
41
+ )
22
42
  end
23
43
 
24
- protected
44
+ def datastore_cluster_filter_spec(obj)
45
+ RbVmomi::VIM.PropertyFilterSpec(
46
+ objectSet: [
47
+ obj: obj,
48
+ skip: true,
49
+ selectSet: [
50
+ compute_resource_datastore_traversal_spec
51
+ ]
52
+ ],
53
+ propSet: datastore_filter_prop_set
54
+ )
55
+ end
56
+
57
+ def datastore_filter_prop_set
58
+ [
59
+ { type: 'Datastore', pathSet: datastore_attribute_mapping.values }
60
+ ]
61
+ end
62
+
63
+ def compute_resource_datastore_traversal_spec
64
+ RbVmomi::VIM.TraversalSpec(
65
+ name: 'computeResourceDatastoreTraversalSpec',
66
+ type: 'ComputeResource',
67
+ path: 'datastore',
68
+ skip: false
69
+ )
70
+ end
25
71
 
26
- def datastore_attributes(datastore, datacenter)
72
+ def datastore_attribute_mapping
27
73
  {
28
- id: managed_obj_id(datastore),
29
- name: datastore.name,
30
- accessible: datastore.summary.accessible,
31
- type: datastore.summary.type,
32
- freespace: datastore.summary.freeSpace,
33
- capacity: datastore.summary.capacity,
34
- uncommitted: datastore.summary.uncommitted,
35
- datacenter: datacenter
74
+ name: 'summary.name',
75
+ accessible: 'summary.accessible',
76
+ type: 'summary.type',
77
+ freespace: 'summary.freeSpace',
78
+ capacity: 'summary.capacity',
79
+ uncommitted: 'summary.uncommitted'
36
80
  }
37
81
  end
38
82
  end
@@ -23,13 +23,130 @@ module Fog
23
23
  def list_folders(filters = {})
24
24
  path = filters[:path] || filters['path'] || ''
25
25
  datacenter_name = filters[:datacenter]
26
- get_raw_vmfolders(path, datacenter_name).map do |folder|
27
- folder_attributes(folder, datacenter_name)
26
+
27
+ # if we don't need to display folders for a specific path
28
+ # we can easily use a property collector to get the
29
+ # data in an efficient manner from vsphere
30
+ # otherwise we use a much slower implementation
31
+ unless path.nil? || path.empty?
32
+ return get_raw_vmfolders(path, datacenter_name).map do |folder|
33
+ folder_attributes(folder, datacenter_name)
34
+ end
28
35
  end
36
+
37
+ root_folder = connection.serviceContent.rootFolder
38
+
39
+ results = property_collector_results(folder_filter_spec(root_folder))
40
+
41
+ folder_inventory = generate_folder_inventory(results)
42
+
43
+ folders = results.select { |result| result.obj.is_a?(RbVmomi::VIM::Folder) && result['childType'].include?('VirtualMachine') }
44
+
45
+ folders.map do |folder|
46
+ folder_id = managed_obj_id(folder.obj)
47
+ parent_id = folder['parent']._ref if folder['parent']
48
+ path = lookup_folder_path(folder_inventory, folder_id)
49
+ next unless path.include?(datacenter_name) # skip folders from another datacenter
50
+ map_attrs_to_hash(folder, folder_attribute_mapping).merge(
51
+ datacenter: datacenter_name,
52
+ parent: lookup_folder_name(folder_inventory, parent_id),
53
+ path: path.join('/'),
54
+ type: folder_type(folder['childType']),
55
+ id: folder_id
56
+ )
57
+ end.compact
29
58
  end
30
59
 
31
60
  protected
32
61
 
62
+ def folder_filter_spec(root_folder)
63
+ RbVmomi::VIM.PropertyFilterSpec(
64
+ objectSet: [
65
+ obj: root_folder,
66
+ skip: false,
67
+ selectSet: [
68
+ dc_folder_traversal_spec,
69
+ datacenter_to_vm_folder_traversal_spec
70
+ ]
71
+ ],
72
+ propSet: [
73
+ { type: 'Folder', pathSet: folder_attribute_mapping.values + %w[parent childType] },
74
+ { type: 'Datacenter', pathSet: %w[name parent] }
75
+ ]
76
+ )
77
+ end
78
+
79
+ def dc_folder_traversal_spec
80
+ RbVmomi::VIM.TraversalSpec(
81
+ name: 'dcFolderTraversalSpec',
82
+ type: 'Folder',
83
+ path: 'childEntity',
84
+ skip: false,
85
+ selectSet: [
86
+ RbVmomi::VIM.SelectionSpec(name: 'dcFolderTraversalSpec'),
87
+ RbVmomi::VIM.SelectionSpec(name: 'DatacenterToVmFolderTraversalSpec')
88
+ ]
89
+ )
90
+ end
91
+
92
+ def datacenter_to_vm_folder_traversal_spec
93
+ RbVmomi::VIM.TraversalSpec(
94
+ name: 'DatacenterToVmFolderTraversalSpec',
95
+ type: 'Datacenter',
96
+ path: 'vmFolder',
97
+ skip: false,
98
+ selectSet: [
99
+ RbVmomi::VIM.SelectionSpec(name: 'dcFolderTraversalSpec')
100
+ ]
101
+ )
102
+ end
103
+
104
+ def lookup_folder_name(inventory, folder_id)
105
+ folder = inventory[folder_id]
106
+ return '' unless folder
107
+ folder[:name]
108
+ end
109
+
110
+ def lookup_folder_path(inventory, folder_id)
111
+ folder = inventory[folder_id]
112
+ return '' unless folder
113
+ folder[:path]
114
+ end
115
+
116
+ def set_folder_paths(folder_inventory) # rubocop:disable Naming/AccessorMethodName
117
+ folder_inventory.each do |ref, props|
118
+ props[:path] = ['', lookup_parent_folders(folder_inventory, ref).reverse].flatten
119
+ end
120
+ end
121
+
122
+ def lookup_parent_folders(folder_inventory, ref)
123
+ return [] unless folder_inventory[ref]
124
+ return [folder_inventory[ref][:name]] if folder_inventory[ref][:parent].nil?
125
+ [folder_inventory[ref][:name], lookup_parent_folders(folder_inventory, folder_inventory[ref][:parent])].flatten
126
+ end
127
+
128
+ def folder_attribute_mapping
129
+ {
130
+ name: 'name'
131
+ }
132
+ end
133
+
134
+ def generate_folder_inventory(folders)
135
+ folder_inventory = folders.each_with_object({}) do |folder, inventory|
136
+ parent = if folder['parent'].nil?
137
+ nil
138
+ else
139
+ folder['parent']._ref
140
+ end
141
+ inventory[folder.obj._ref] = {
142
+ name: folder['name'],
143
+ parent: parent
144
+ }
145
+ end
146
+ set_folder_paths(folder_inventory)
147
+ folder_inventory
148
+ end
149
+
33
150
  def get_raw_vmfolders(path, datacenter_name)
34
151
  folder = get_raw_vmfolder(path, datacenter_name)
35
152
  child_folders(folder).flatten.compact
@@ -4,26 +4,45 @@ module Fog
4
4
  class Real
5
5
  def list_storage_pods(filters = {})
6
6
  datacenter_name = filters[:datacenter]
7
- raw_storage_pods(datacenter_name).map do |storage_pod|
8
- storage_pod_attributes(storage_pod, datacenter_name)
9
- end.compact
10
- end
11
7
 
12
- private
8
+ dc = find_raw_datacenter(datacenter_name)
9
+
10
+ storage_pods = property_collector_results(storage_pod_filter_spec(dc))
13
11
 
14
- def raw_storage_pods(datacenter_name)
15
- list_container_view(datacenter_name, 'StoragePod')
12
+ storage_pods.map do |storage_pod|
13
+ map_attrs_to_hash(storage_pod, storage_pod_attribute_mapping).merge(
14
+ datacenter: datacenter_name,
15
+ id: managed_obj_id(storage_pod.obj)
16
+ )
17
+ end
16
18
  end
17
19
 
18
20
  protected
19
21
 
20
- def storage_pod_attributes(storage_pod, datacenter)
22
+ def storage_pod_filter_spec(obj)
23
+ RbVmomi::VIM.PropertyFilterSpec(
24
+ objectSet: [
25
+ obj: obj.datastoreFolder,
26
+ skip: true,
27
+ selectSet: [
28
+ folder_traversal_spec
29
+ ]
30
+ ],
31
+ propSet: storage_pod_filter_prop_set
32
+ )
33
+ end
34
+
35
+ def storage_pod_filter_prop_set
36
+ [
37
+ { type: 'StoragePod', pathSet: storage_pod_attribute_mapping.values }
38
+ ]
39
+ end
40
+
41
+ def storage_pod_attribute_mapping
21
42
  {
22
- id: managed_obj_id(storage_pod),
23
- name: storage_pod.name,
24
- freespace: storage_pod.summary.freeSpace,
25
- capacity: storage_pod.summary.capacity,
26
- datacenter: datacenter
43
+ name: 'name',
44
+ freespace: 'summary.freeSpace',
45
+ capacity: 'summary.capacity'
27
46
  }
28
47
  end
29
48
  end
@@ -61,11 +61,19 @@ module Fog
61
61
 
62
62
  private
63
63
 
64
+ # rubocop:disable Style/ConditionalAssignment
64
65
  def raw_to_hash(nic)
66
+ if nic.backing.respond_to?(:network)
67
+ network = nic.backing.network.name
68
+ elsif nic.backing.respond_to?(:port)
69
+ network = nic.backing.port.portgroupKey
70
+ else
71
+ network = nil
72
+ end
65
73
  {
66
74
  name: nic.deviceInfo.label,
67
75
  mac: nic.macAddress,
68
- network: nic.backing.respond_to?('network') ? nic.backing.network.name : nic.backing.port.portgroupKey,
76
+ network: network,
69
77
  status: nic.connectable.status,
70
78
  connected: nic.connectable.connected,
71
79
  summary: nic.deviceInfo.summary,
@@ -73,6 +81,7 @@ module Fog
73
81
  key: nic.key
74
82
  }
75
83
  end
84
+ # rubocop:enable Style/ConditionalAssignment
76
85
  end
77
86
 
78
87
  class Mock
@@ -1,5 +1,5 @@
1
1
  module Fog
2
2
  module Vsphere
3
- VERSION = '2.3.0'.freeze
3
+ VERSION = '2.4.0'.freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fog-vsphere
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.0
4
+ version: 2.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - J.R. Garcia
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-07-09 00:00:00.000000000 Z
11
+ date: 2018-10-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fog-core