rbvmomi 1.8.2 → 2.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. checksums.yaml +5 -13
  2. data/LICENSE +1 -1
  3. data/README.md +114 -0
  4. data/{bin → exe}/rbvmomish +5 -5
  5. data/lib/rbvmomi.rb +11 -7
  6. data/lib/rbvmomi/basic_types.rb +9 -1
  7. data/lib/rbvmomi/connection.rb +11 -9
  8. data/lib/rbvmomi/deserialization.rb +4 -3
  9. data/lib/rbvmomi/fault.rb +3 -1
  10. data/lib/rbvmomi/{trollop.rb → optimist.rb} +10 -8
  11. data/lib/rbvmomi/pbm.rb +3 -1
  12. data/lib/rbvmomi/sms.rb +3 -1
  13. data/lib/rbvmomi/sms/SmsStorageManager.rb +3 -0
  14. data/lib/rbvmomi/sso.rb +313 -0
  15. data/lib/rbvmomi/trivial_soap.rb +19 -11
  16. data/lib/rbvmomi/type_loader.rb +4 -2
  17. data/lib/rbvmomi/utils/admission_control.rb +22 -19
  18. data/lib/rbvmomi/utils/deploy.rb +18 -14
  19. data/lib/rbvmomi/utils/leases.rb +4 -1
  20. data/lib/rbvmomi/utils/perfdump.rb +4 -1
  21. data/lib/rbvmomi/version.rb +6 -0
  22. data/lib/rbvmomi/vim.rb +41 -12
  23. data/lib/rbvmomi/vim/ComputeResource.rb +3 -0
  24. data/lib/rbvmomi/vim/Datacenter.rb +8 -0
  25. data/lib/rbvmomi/vim/Datastore.rb +5 -1
  26. data/lib/rbvmomi/vim/DynamicTypeMgrAllTypeInfo.rb +3 -0
  27. data/lib/rbvmomi/vim/DynamicTypeMgrDataTypeInfo.rb +4 -1
  28. data/lib/rbvmomi/vim/DynamicTypeMgrManagedTypeInfo.rb +15 -7
  29. data/lib/rbvmomi/vim/Folder.rb +19 -12
  30. data/lib/rbvmomi/vim/HostSystem.rb +5 -2
  31. data/lib/rbvmomi/vim/ManagedEntity.rb +3 -0
  32. data/lib/rbvmomi/vim/ManagedObject.rb +4 -1
  33. data/lib/rbvmomi/vim/ObjectContent.rb +3 -0
  34. data/lib/rbvmomi/vim/ObjectUpdate.rb +3 -0
  35. data/lib/rbvmomi/vim/OvfManager.rb +6 -2
  36. data/lib/rbvmomi/vim/PerfCounterInfo.rb +3 -1
  37. data/lib/rbvmomi/vim/PerformanceManager.rb +3 -0
  38. data/lib/rbvmomi/vim/PropertyCollector.rb +3 -0
  39. data/lib/rbvmomi/vim/ReflectManagedMethodExecuter.rb +5 -2
  40. data/lib/rbvmomi/vim/ResourcePool.rb +3 -0
  41. data/lib/rbvmomi/vim/ServiceInstance.rb +3 -0
  42. data/lib/rbvmomi/vim/Task.rb +3 -0
  43. data/lib/rbvmomi/vim/VirtualMachine.rb +13 -12
  44. data/vmodl.db +0 -0
  45. metadata +100 -63
  46. data/.yardopts +0 -6
  47. data/README.rdoc +0 -78
  48. data/Rakefile +0 -45
  49. data/VERSION +0 -1
  50. data/devel/analyze-vim-declarations.rb +0 -213
  51. data/devel/analyze-xml.rb +0 -46
  52. data/devel/benchmark.rb +0 -117
  53. data/devel/collisions.rb +0 -18
  54. data/devel/merge-internal-vmodl.rb +0 -59
  55. data/devel/merge-manual-vmodl.rb +0 -32
  56. data/examples/annotate.rb +0 -54
  57. data/examples/cached_ovf_deploy.rb +0 -120
  58. data/examples/clone_vm.rb +0 -84
  59. data/examples/create_vm-1.9.rb +0 -93
  60. data/examples/create_vm.rb +0 -93
  61. data/examples/extraConfig.rb +0 -54
  62. data/examples/lease_tool.rb +0 -102
  63. data/examples/logbundle.rb +0 -63
  64. data/examples/logtail.rb +0 -60
  65. data/examples/nfs_datastore.rb +0 -95
  66. data/examples/power.rb +0 -59
  67. data/examples/readme-1.rb +0 -35
  68. data/examples/readme-2.rb +0 -51
  69. data/examples/run.sh +0 -41
  70. data/examples/screenshot.rb +0 -48
  71. data/examples/vdf.rb +0 -81
  72. data/examples/vm_drs_behavior.rb +0 -76
  73. data/test/test_deserialization.rb +0 -383
  74. data/test/test_emit_request.rb +0 -128
  75. data/test/test_exceptions.rb +0 -14
  76. data/test/test_helper.rb +0 -14
  77. data/test/test_misc.rb +0 -24
  78. data/test/test_parse_response.rb +0 -69
  79. data/test/test_serialization.rb +0 -311
@@ -1,4 +1,6 @@
1
- # Copyright (c) 2010 VMware, Inc. All Rights Reserved.
1
+ # Copyright (c) 2011-2017 VMware, Inc. All Rights Reserved.
2
+ # SPDX-License-Identifier: MIT
3
+
2
4
  require 'rubygems'
3
5
  require 'builder'
4
6
  require 'nokogiri'
@@ -6,7 +8,7 @@ require 'net/http'
6
8
  require 'pp'
7
9
 
8
10
  class RbVmomi::TrivialSoap
9
- attr_accessor :debug, :cookie
11
+ attr_accessor :debug, :cookie, :operation_id
10
12
  attr_reader :http
11
13
 
12
14
  def initialize opts
@@ -15,6 +17,8 @@ class RbVmomi::TrivialSoap
15
17
  return unless @opts[:host] # for testcases
16
18
  @debug = @opts[:debug]
17
19
  @cookie = @opts[:cookie]
20
+ @sso = @opts[:sso]
21
+ @operation_id = @opts[:operation_id]
18
22
  @lock = Mutex.new
19
23
  @http = nil
20
24
  restart_http
@@ -39,17 +43,14 @@ class RbVmomi::TrivialSoap
39
43
  if @opts[:ssl]
40
44
  require 'net/https'
41
45
  @http.use_ssl = true
42
- if @opts[:insecure]
43
- @http.verify_mode = OpenSSL::SSL::VERIFY_NONE
44
- else
45
- @http.verify_mode = OpenSSL::SSL::VERIFY_PEER
46
- end
46
+ @http.verify_mode = OpenSSL::SSL::VERIFY_NONE if @opts[:insecure]
47
+ @http.ca_file = @opts[:ca_file] if @opts[:ca_file]
47
48
  @http.cert = OpenSSL::X509::Certificate.new(@opts[:cert]) if @opts[:cert]
48
49
  @http.key = OpenSSL::PKey::RSA.new(@opts[:key]) if @opts[:key]
49
50
  end
50
51
  @http.set_debug_output(STDERR) if $DEBUG
51
- @http.read_timeout = 1000000
52
- @http.open_timeout = 60
52
+ @http.read_timeout = @opts[:read_timeout] || 1000000
53
+ @http.open_timeout = @opts[:open_timeout] || 60
53
54
  def @http.on_connect
54
55
  @socket.io.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
55
56
  end
@@ -62,11 +63,13 @@ class RbVmomi::TrivialSoap
62
63
  xsi = 'http://www.w3.org/2001/XMLSchema-instance'
63
64
  xml = Builder::XmlMarkup.new :indent => 0
64
65
  xml.tag!('env:Envelope', 'xmlns:xsd' => xsd, 'xmlns:env' => env, 'xmlns:xsi' => xsi) do
65
- if @vcSessionCookie
66
+ if @vcSessionCookie || @operation_id
66
67
  xml.tag!('env:Header') do
67
- xml.tag!('vcSessionCookie', @vcSessionCookie)
68
+ xml.tag!('vcSessionCookie', @vcSessionCookie) if @vcSessionCookie
69
+ xml.tag!('operationID', @operation_id) if @operation_id
68
70
  end
69
71
  end
72
+
70
73
  xml.tag!('env:Body') do
71
74
  yield xml if block_given?
72
75
  end
@@ -84,6 +87,11 @@ class RbVmomi::TrivialSoap
84
87
  $stderr.puts
85
88
  end
86
89
 
90
+ if @cookie.nil? && @sso
91
+ @sso.request_token unless @sso.assertion_id
92
+ body = @sso.sign_request(body)
93
+ end
94
+
87
95
  start_time = Time.now
88
96
  response = @lock.synchronize do
89
97
  begin
@@ -1,4 +1,6 @@
1
- # Copyright (c) 2010 VMware, Inc. All Rights Reserved.
1
+ # Copyright (c) 2011-2017 VMware, Inc. All Rights Reserved.
2
+ # SPDX-License-Identifier: MIT
3
+
2
4
  require 'set'
3
5
  require 'monitor'
4
6
 
@@ -93,7 +95,7 @@ class TypeLoader
93
95
 
94
96
  def load_extension name
95
97
  @extension_dirs.map { |x| File.join(x, "#{name}.rb") }.
96
- select { |x| File.exists? x }.
98
+ select { |x| File.exist? x }.
97
99
  each { |x| load x }
98
100
  end
99
101
 
@@ -1,3 +1,6 @@
1
+ # Copyright (c) 2012-2017 VMware, Inc. All Rights Reserved.
2
+ # SPDX-License-Identifier: MIT
3
+
1
4
 
2
5
  # An admission controlled resource scheduler for large scale vSphere deployments
3
6
  #
@@ -77,11 +80,11 @@ class AdmissionControlledResourceScheduler
77
80
  # Returns the used VM folder. If not set yet, uses the vm_folder_path to
78
81
  # lookup the folder. If it doesn't exist, it is created. Collisions between
79
82
  # multiple clients concurrently creating the same folder are handled.
80
- # @return [VIM::Folder] The VM folder
83
+ # @return [RbVmomi::VIM::Folder] The VM folder
81
84
  def vm_folder
82
85
  retries = 1
83
86
  begin
84
- @vm_folder ||= datacenter.vmFolder.traverse!(@vm_folder_path, VIM::Folder)
87
+ @vm_folder ||= datacenter.vmFolder.traverse!(@vm_folder_path, RbVmomi::VIM::Folder)
85
88
  if !@vm_folder
86
89
  fail "VM folder #{@vm_folder_path} not found"
87
90
  end
@@ -98,10 +101,10 @@ class AdmissionControlledResourceScheduler
98
101
 
99
102
  # Returns the used Datacenter. If not set yet, uses the datacenter_path to
100
103
  # lookup the datacenter.
101
- # @return [VIM::Datacenter] The datacenter
104
+ # @return [RbVmomi::VIM::Datacenter] The datacenter
102
105
  def datacenter
103
106
  if !@datacenter
104
- @datacenter = @root_folder.traverse(@datacenter_path, VIM::Datacenter)
107
+ @datacenter = @root_folder.traverse(@datacenter_path, RbVmomi::VIM::Datacenter)
105
108
  if !@datacenter
106
109
  fail "datacenter #{@datacenter_path} not found"
107
110
  end
@@ -112,11 +115,11 @@ class AdmissionControlledResourceScheduler
112
115
  # Returns the candidate datastores. If not set yet, uses the datastore_paths
113
116
  # to lookup the datastores under the datacenter.
114
117
  # As a side effect, also looks up properties about all the datastores
115
- # @return [Array] List of VIM::Datastore
118
+ # @return [Array] List of RbVmomi::VIM::Datastore
116
119
  def datastores
117
120
  if !@datastores
118
121
  @datastores = @datastore_paths.map do |path|
119
- ds = datacenter.datastoreFolder.traverse(path, VIM::Datastore)
122
+ ds = datacenter.datastoreFolder.traverse(path, RbVmomi::VIM::Datastore)
120
123
  if !ds
121
124
  fail "datastore #{path} not found"
122
125
  end
@@ -131,7 +134,7 @@ class AdmissionControlledResourceScheduler
131
134
 
132
135
  # Returns the candidate computers (aka clusters). If not set yet, uses the
133
136
  # computer_names to look them up.
134
- # @return [Array] List of [VIM::ClusterComputeResource, Hash] tuples, where
137
+ # @return [Array] List of [RbVmomi::VIM::ClusterComputeResource, Hash] tuples, where
135
138
  # the Hash is a list of stats about the computer
136
139
  def computers
137
140
  if !@computers
@@ -145,7 +148,7 @@ class AdmissionControlledResourceScheduler
145
148
 
146
149
  # Returns the candidate pods. If not set, automatically computes the pods
147
150
  # based on the list of computers (aka clusters) and datastores.
148
- # @return [Array] List of pods, where a pod is a list of VIM::ClusterComputeResource
151
+ # @return [Array] List of pods, where a pod is a list of RbVmomi::VIM::ClusterComputeResource
149
152
  def pods
150
153
  if !@pods
151
154
  # A pod is defined as a set of clusters (aka computers) that share the same
@@ -168,22 +171,22 @@ class AdmissionControlledResourceScheduler
168
171
  # @return [Hash] Hash of VMs as keys and their properties as values.
169
172
  def pod_vms pod
170
173
  # This function retrieves all VMs residing inside a pod
171
- filterSpec = VIM.PropertyFilterSpec(
174
+ filterSpec = RbVmomi::VIM.PropertyFilterSpec(
172
175
  objectSet: pod.map do |computer, stats|
173
176
  {
174
177
  obj: computer.resourcePool,
175
178
  selectSet: [
176
- VIM.TraversalSpec(
179
+ RbVmomi::VIM.TraversalSpec(
177
180
  name: 'tsFolder',
178
181
  type: 'ResourcePool',
179
182
  path: 'resourcePool',
180
183
  skip: false,
181
184
  selectSet: [
182
- VIM.SelectionSpec(name: 'tsFolder'),
183
- VIM.SelectionSpec(name: 'tsVM'),
185
+ RbVmomi::VIM.SelectionSpec(name: 'tsFolder'),
186
+ RbVmomi::VIM.SelectionSpec(name: 'tsVM'),
184
187
  ]
185
188
  ),
186
- VIM.TraversalSpec(
189
+ RbVmomi::VIM.TraversalSpec(
187
190
  name: 'tsVM',
188
191
  type: 'ResourcePool',
189
192
  path: 'vm',
@@ -202,11 +205,11 @@ class AdmissionControlledResourceScheduler
202
205
  result = @vim.propertyCollector.RetrieveProperties(specSet: [filterSpec])
203
206
 
204
207
  out = result.map { |x| [x.obj, Hash[x.propSet.map { |y| [y.name, y.val] }]] }
205
- out.select{|obj, props| obj.is_a?(VIM::VirtualMachine)}
208
+ out.select{|obj, props| obj.is_a?(RbVmomi::VIM::VirtualMachine)}
206
209
  end
207
210
 
208
211
  # Returns all candidate datastores for a given pod.
209
- # @return [Array] List of VIM::Datastore
212
+ # @return [Array] List of RbVmomi::VIM::Datastore
210
213
  def pod_datastores pod
211
214
  pod.first.datastore & self.datastores
212
215
  end
@@ -214,7 +217,7 @@ class AdmissionControlledResourceScheduler
214
217
  # Returns the list of pods that pass admission control. If not set yet, performs
215
218
  # admission control to compute the list. If no pods passed the admission
216
219
  # control, an exception is thrown.
217
- # @return [Array] List of pods, where a pod is a list of VIM::ClusterComputeResource
220
+ # @return [Array] List of pods, where a pod is a list of RbVmomi::VIM::ClusterComputeResource
218
221
  def filtered_pods
219
222
  # This function applies admission control and returns those pods that have
220
223
  # passed admission control. An exception is thrown if access was denied to
@@ -300,7 +303,7 @@ class AdmissionControlledResourceScheduler
300
303
  # Returns the computer (aka cluster) to be used for placement. If not set yet,
301
304
  # computs the least loaded cluster (using a metric that combines CPU and Memory
302
305
  # load) that passes admission control.
303
- # @return [VIM::ClusterComputeResource] Chosen computer (aka cluster)
306
+ # @return [RbVmomi::VIM::ClusterComputeResource] Chosen computer (aka cluster)
304
307
  def pick_computer placementhint = nil
305
308
  if !@computer
306
309
  # Out of the pods to which we have been granted access, pick the cluster
@@ -330,7 +333,7 @@ class AdmissionControlledResourceScheduler
330
333
 
331
334
  # Returns the datastore to be used for placement. If not set yet, picks a
332
335
  # datastore without much intelligence, as long as it passes admission control.
333
- # @return [VIM::Datastore] Chosen datastore
336
+ # @return [RbVmomi::VIM::Datastore] Chosen datastore
334
337
  def datastore placementHint = nil
335
338
  if @datastore
336
339
  return @datastore
@@ -395,4 +398,4 @@ class AdmissionControlledResourceScheduler
395
398
  datastore = self.datastore @placement_hint
396
399
  log "Datastore: #{datastore.name}"
397
400
  end
398
- end
401
+ end
@@ -1,3 +1,6 @@
1
+ # Copyright (c) 2012-2017 VMware, Inc. All Rights Reserved.
2
+ # SPDX-License-Identifier: MIT
3
+
1
4
  require 'open-uri'
2
5
  require 'nokogiri'
3
6
  require 'rbvmomi'
@@ -78,18 +81,17 @@ class CachedOvfDeployer
78
81
  # it to be marked as a template. This way, the cost of uploading and keeping
79
82
  # the full size of the VM is only paid once.
80
83
  # @param ovf_url [String] URL to the OVF to be deployed. Currently only http
81
- # and https are supported
84
+ # and https are supported.
82
85
  # @param template_name [String] Name of the template to be used. Should be the
83
- # same name for the same URL. A cluster specific
84
- # post-fix will automatically be added.
85
- # @option opts [int] :run_without_interruptions Whether or not to disable
86
- # SIGINT and SIGTERM during
87
- # the OVF upload.
86
+ # same name for the same URL. A cluster specific post-fix will automatically
87
+ # be added.
88
+ # @option opts [int] :run_without_interruptions Whether or not to disable
89
+ # SIGINT and SIGTERM during the OVF upload.
88
90
  # @option opts [Hash] :config VM Config delta to apply after the OVF deploy is
89
- # done. Allows the template to be customized, e.g.
90
- # to set annotations.
91
+ # done. Allows the template to be customized, e.g. to set annotations.
92
+ # @option opts [Boolean] :no_delta Whether or not to add a delta disk layer.
91
93
  # @return [VIM::VirtualMachine] The template as a VIM::VirtualMachine instance
92
- def upload_ovf_as_template ovf_url, template_name, opts = {}
94
+ def upload_ovf_as_template(ovf_url, template_name, opts = {})
93
95
  # Optimization: If there happens to be a fully prepared template, then
94
96
  # there is no need to do the complicated OVF upload dance
95
97
  template = lookup_template template_name
@@ -185,10 +187,12 @@ class CachedOvfDeployer
185
187
  # prepare it for (linked) cloning and mark it as a template to signal
186
188
  # we are done.
187
189
  if !wait_for_template
188
- config = opts[:config] || {}
189
- config = vm.update_spec_add_delta_disk_layer_on_all_disks(config)
190
- # XXX: Should we add a version that does retries?
191
- vm.ReconfigVM_Task(:spec => config).wait_for_completion
190
+ if opts[:no_delta] != true
191
+ config = opts[:config] || {}
192
+ config = vm.update_spec_add_delta_disk_layer_on_all_disks(config)
193
+ # XXX: Should we add a version that does retries?
194
+ vm.ReconfigVM_Task(:spec => config).wait_for_completion
195
+ end
192
196
  vm.MarkAsTemplate
193
197
  end
194
198
  end
@@ -311,4 +315,4 @@ class CachedOvfDeployer
311
315
 
312
316
  vm
313
317
  end
314
- end
318
+ end
@@ -1,3 +1,6 @@
1
+ # Copyright (c) 2012-2017 VMware, Inc. All Rights Reserved.
2
+ # SPDX-License-Identifier: MIT
3
+
1
4
  require 'yaml'
2
5
 
3
6
  # A class to manage VM leases
@@ -139,4 +142,4 @@ class LeaseTool
139
142
  out = Hash[out]
140
143
  out
141
144
  end
142
- end
145
+ end
@@ -1,3 +1,6 @@
1
+ # Copyright (c) 2012-2017 VMware, Inc. All Rights Reserved.
2
+ # SPDX-License-Identifier: MIT
3
+
1
4
  require 'set'
2
5
  require 'yaml'
3
6
 
@@ -336,7 +339,7 @@ class PerfAggregator
336
339
  vms_props, inventory = all_inventory_flat root_folder, prop_names
337
340
  vms = vms_props.keys
338
341
 
339
- hosts_props = inventory.select{|k, v| k.is_a?(VIM::HostSystem)}
342
+ hosts_props = inventory.select{|k, v| k.is_a?(RbVmomi::VIM::HostSystem)}
340
343
 
341
344
  conn = root_folder._connection
342
345
  sc = conn.serviceContent
@@ -0,0 +1,6 @@
1
+ # Copyright (c) 2016-2019 VMware, Inc. All Rights Reserved.
2
+ # SPDX-License-Identifier: MIT
3
+
4
+ module RbVmomi
5
+ VERSION = '2.4.1'.freeze
6
+ end
data/lib/rbvmomi/vim.rb CHANGED
@@ -1,5 +1,12 @@
1
- # Copyright (c) 2011 VMware, Inc. All Rights Reserved.
2
- require 'rbvmomi'
1
+ # Copyright (c) 2011-2017 VMware, Inc. All Rights Reserved.
2
+ # SPDX-License-Identifier: MIT
3
+
4
+ # Win32::SSPI is part of core on Windows
5
+ begin
6
+ require 'win32/sspi'
7
+ rescue LoadError
8
+ end
9
+ WIN32 = (defined? Win32::SSPI)
3
10
 
4
11
  module RbVmomi
5
12
 
@@ -18,34 +25,56 @@ class VIM < Connection
18
25
  # @option opts [String] :password Password.
19
26
  # @option opts [String] :path (/sdk) SDK endpoint path.
20
27
  # @option opts [Boolean] :debug (false) If true, print SOAP traffic to stderr.
28
+ # @option opts [String] :operation_id If set, use for operationID
29
+ # @option opts [Boolean] :close_on_exit (true) If true, will close connection with at_exit
30
+ # @option opts [RbVmomi::SSO] :sso (nil) Use SSO token to login if set
21
31
  def self.connect opts
22
32
  fail unless opts.is_a? Hash
23
33
  fail "host option required" unless opts[:host]
24
34
  opts[:cookie] ||= nil
25
- opts[:user] ||= 'root'
35
+ opts[:user] ||= (WIN32 ? ENV['USERNAME'].dup : 'root')
26
36
  opts[:password] ||= ''
27
37
  opts[:ssl] = true unless opts.member? :ssl or opts[:"no-ssl"]
28
38
  opts[:insecure] ||= false
29
39
  opts[:port] ||= (opts[:ssl] ? 443 : 80)
30
40
  opts[:path] ||= '/sdk'
31
41
  opts[:ns] ||= 'urn:vim25'
32
- rev_given = opts[:rev] != nil
33
- opts[:rev] = '4.0' unless rev_given
42
+ opts[:rev] = '6.7' if opts[:rev].nil?
34
43
  opts[:debug] = (!ENV['RBVMOMI_DEBUG'].empty? rescue false) unless opts.member? :debug
35
44
 
36
- new(opts).tap do |vim|
45
+ conn = new(opts).tap do |vim|
37
46
  unless opts[:cookie]
38
- vim.serviceContent.sessionManager.Login :userName => opts[:user], :password => opts[:password]
39
- end
40
- unless rev_given
41
- rev = vim.serviceContent.about.apiVersion
42
- vim.rev = [rev, '5.5'].min
47
+ if WIN32 && opts[:password] == ''
48
+ # Attempt login by SSPI if no password specified on Windows
49
+ negotiation = Win32::SSPI::NegotiateAuth.new opts[:user], ENV['USERDOMAIN'].dup
50
+ begin
51
+ vim.serviceContent.sessionManager.LoginBySSPI :base64Token => negotiation.get_initial_token
52
+ rescue RbVmomi::Fault => fault
53
+ if !fault.fault.is_a?(RbVmomi::VIM::SSPIChallenge)
54
+ raise
55
+ else
56
+ vim.serviceContent.sessionManager.LoginBySSPI :base64Token => negotiation.complete_authentication(fault.base64Token)
57
+ end
58
+ end
59
+ elsif opts[:sso]
60
+ vim.serviceContent.sessionManager.LoginByToken
61
+ else
62
+ vim.serviceContent.sessionManager.Login :userName => opts[:user], :password => opts[:password]
63
+ end
43
64
  end
65
+ rev = vim.serviceContent.about.apiVersion
66
+ vim.rev = [rev, opts[:rev]].min { |a, b| Gem::Version.new(a) <=> Gem::Version.new(b) }
44
67
  end
68
+
69
+ at_exit { conn.close } if opts.fetch(:close_on_exit, true)
70
+ conn
45
71
  end
46
72
 
47
73
  def close
48
- VIM::SessionManager(self, 'SessionManager').Logout rescue RbVmomi::Fault
74
+ serviceContent.sessionManager.Logout
75
+ rescue RbVmomi::Fault => e
76
+ $stderr.puts(e.message) if debug
77
+ ensure
49
78
  self.cookie = nil
50
79
  super
51
80
  end
@@ -1,3 +1,6 @@
1
+ # Copyright (c) 2011-2017 VMware, Inc. All Rights Reserved.
2
+ # SPDX-License-Identifier: MIT
3
+
1
4
  class RbVmomi::VIM::ComputeResource
2
5
  # Aggregate cluster information.
3
6
  #
@@ -1,3 +1,6 @@
1
+ # Copyright (c) 2011-2017 VMware, Inc. All Rights Reserved.
2
+ # SPDX-License-Identifier: MIT
3
+
1
4
  class RbVmomi::VIM::Datacenter
2
5
  # Traverse the given inventory +path+ to find a ComputeResource.
3
6
  def find_compute_resource path
@@ -13,5 +16,10 @@ class RbVmomi::VIM::Datacenter
13
16
  def find_vm path
14
17
  vmFolder.traverse path, RbVmomi::VIM::VirtualMachine
15
18
  end
19
+
20
+ # Traverse the given inventory +path+ to find a Folder.
21
+ def find_folder path
22
+ vmFolder.traverse path, RbVmomi::VIM::Folder
23
+ end
16
24
  end
17
25
 
@@ -1,3 +1,6 @@
1
+ # Copyright (c) 2011-2017 VMware, Inc. All Rights Reserved.
2
+ # SPDX-License-Identifier: MIT
3
+
1
4
  # @note +download+ and +upload+ require +curl+. If +curl+ is not in your +PATH+
2
5
  # then set the +CURL+ environment variable to point to it.
3
6
  # @todo Use an HTTP library instead of executing +curl+.
@@ -63,6 +66,7 @@ class RbVmomi::VIM::Datastore
63
66
  end
64
67
 
65
68
  def mkuripath path
66
- "/folder/#{URI.escape path}?dcPath=#{URI.escape datacenter.name}&dsName=#{URI.escape name}"
69
+ datacenter_path_str = datacenter.path[1..-1].map{|elem| elem[1]}.join('/')
70
+ "/folder/#{URI.escape path}?dcPath=#{URI.escape datacenter_path_str }&dsName=#{URI.escape name}"
67
71
  end
68
72
  end