vagrant-rbvmomi 1.8.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +6 -0
  3. data/LICENSE +19 -0
  4. data/README.rdoc +78 -0
  5. data/Rakefile +31 -0
  6. data/VERSION +1 -0
  7. data/bin/rbvmomish +138 -0
  8. data/devel/analyze-vim-declarations.rb +213 -0
  9. data/devel/analyze-xml.rb +46 -0
  10. data/devel/benchmark.rb +117 -0
  11. data/devel/collisions.rb +18 -0
  12. data/devel/merge-internal-vmodl.rb +59 -0
  13. data/devel/merge-manual-vmodl.rb +32 -0
  14. data/examples/annotate.rb +54 -0
  15. data/examples/cached_ovf_deploy.rb +120 -0
  16. data/examples/clone_vm.rb +84 -0
  17. data/examples/create_vm-1.9.rb +93 -0
  18. data/examples/create_vm.rb +93 -0
  19. data/examples/extraConfig.rb +54 -0
  20. data/examples/lease_tool.rb +102 -0
  21. data/examples/logbundle.rb +63 -0
  22. data/examples/logtail.rb +60 -0
  23. data/examples/nfs_datastore.rb +95 -0
  24. data/examples/power.rb +59 -0
  25. data/examples/readme-1.rb +35 -0
  26. data/examples/readme-2.rb +51 -0
  27. data/examples/run.sh +41 -0
  28. data/examples/screenshot.rb +48 -0
  29. data/examples/vdf.rb +81 -0
  30. data/examples/vm_drs_behavior.rb +76 -0
  31. data/lib/rbvmomi.rb +12 -0
  32. data/lib/rbvmomi/basic_types.rb +375 -0
  33. data/lib/rbvmomi/connection.rb +270 -0
  34. data/lib/rbvmomi/deserialization.rb +248 -0
  35. data/lib/rbvmomi/fault.rb +17 -0
  36. data/lib/rbvmomi/pbm.rb +66 -0
  37. data/lib/rbvmomi/sms.rb +61 -0
  38. data/lib/rbvmomi/sms/SmsStorageManager.rb +7 -0
  39. data/lib/rbvmomi/trivial_soap.rb +114 -0
  40. data/lib/rbvmomi/trollop.rb +70 -0
  41. data/lib/rbvmomi/type_loader.rb +136 -0
  42. data/lib/rbvmomi/utils/admission_control.rb +398 -0
  43. data/lib/rbvmomi/utils/deploy.rb +336 -0
  44. data/lib/rbvmomi/utils/leases.rb +142 -0
  45. data/lib/rbvmomi/utils/perfdump.rb +628 -0
  46. data/lib/rbvmomi/vim.rb +128 -0
  47. data/lib/rbvmomi/vim/ComputeResource.rb +51 -0
  48. data/lib/rbvmomi/vim/Datacenter.rb +17 -0
  49. data/lib/rbvmomi/vim/Datastore.rb +68 -0
  50. data/lib/rbvmomi/vim/DynamicTypeMgrAllTypeInfo.rb +75 -0
  51. data/lib/rbvmomi/vim/DynamicTypeMgrDataTypeInfo.rb +20 -0
  52. data/lib/rbvmomi/vim/DynamicTypeMgrManagedTypeInfo.rb +46 -0
  53. data/lib/rbvmomi/vim/Folder.rb +207 -0
  54. data/lib/rbvmomi/vim/HostSystem.rb +174 -0
  55. data/lib/rbvmomi/vim/ManagedEntity.rb +57 -0
  56. data/lib/rbvmomi/vim/ManagedObject.rb +60 -0
  57. data/lib/rbvmomi/vim/ObjectContent.rb +23 -0
  58. data/lib/rbvmomi/vim/ObjectUpdate.rb +23 -0
  59. data/lib/rbvmomi/vim/OvfManager.rb +200 -0
  60. data/lib/rbvmomi/vim/PerfCounterInfo.rb +26 -0
  61. data/lib/rbvmomi/vim/PerformanceManager.rb +110 -0
  62. data/lib/rbvmomi/vim/PropertyCollector.rb +25 -0
  63. data/lib/rbvmomi/vim/ReflectManagedMethodExecuter.rb +30 -0
  64. data/lib/rbvmomi/vim/ResourcePool.rb +55 -0
  65. data/lib/rbvmomi/vim/ServiceInstance.rb +55 -0
  66. data/lib/rbvmomi/vim/Task.rb +65 -0
  67. data/lib/rbvmomi/vim/VirtualMachine.rb +74 -0
  68. data/test/test_deserialization.rb +383 -0
  69. data/test/test_emit_request.rb +128 -0
  70. data/test/test_exceptions.rb +14 -0
  71. data/test/test_helper.rb +14 -0
  72. data/test/test_misc.rb +24 -0
  73. data/test/test_parse_response.rb +69 -0
  74. data/test/test_serialization.rb +311 -0
  75. data/vmodl.db +0 -0
  76. metadata +163 -0
@@ -0,0 +1,128 @@
1
+ # Copyright (c) 2011 VMware, Inc. All Rights Reserved.
2
+ require 'rbvmomi'
3
+
4
+ module RbVmomi
5
+
6
+ # A connection to one vSphere SDK endpoint.
7
+ # @see #serviceInstance
8
+ class VIM < Connection
9
+ # Connect to a vSphere SDK endpoint
10
+ #
11
+ # @param [Hash] opts The options hash.
12
+ # @option opts [String] :host Host to connect to.
13
+ # @option opts [Numeric] :port (443) Port to connect to.
14
+ # @option opts [Boolean] :ssl (true) Whether to use SSL.
15
+ # @option opts [Boolean] :insecure (false) If true, ignore SSL certificate errors.
16
+ # @option opts [String] :cookie If set, use cookie to connect instead of user/password
17
+ # @option opts [String] :user (root) Username.
18
+ # @option opts [String] :password Password.
19
+ # @option opts [String] :path (/sdk) SDK endpoint path.
20
+ # @option opts [Boolean] :debug (false) If true, print SOAP traffic to stderr.
21
+ def self.connect opts
22
+ fail unless opts.is_a? Hash
23
+ fail "host option required" unless opts[:host]
24
+ opts[:cookie] ||= nil
25
+ opts[:user] ||= 'root'
26
+ opts[:password] ||= ''
27
+ opts[:ssl] = true unless opts.member? :ssl or opts[:"no-ssl"]
28
+ opts[:insecure] ||= false
29
+ opts[:port] ||= (opts[:ssl] ? 443 : 80)
30
+ opts[:path] ||= '/sdk'
31
+ opts[:ns] ||= 'urn:vim25'
32
+ rev_given = opts[:rev] != nil
33
+ opts[:rev] = '4.0' unless rev_given
34
+ opts[:debug] = (!ENV['RBVMOMI_DEBUG'].empty? rescue false) unless opts.member? :debug
35
+
36
+ new(opts).tap do |vim|
37
+ 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
43
+ end
44
+ end
45
+ end
46
+
47
+ def close
48
+ VIM::SessionManager(self, 'SessionManager').Logout rescue RbVmomi::Fault
49
+ self.cookie = nil
50
+ super
51
+ end
52
+
53
+ def rev= x
54
+ super
55
+ @serviceContent = nil
56
+ end
57
+
58
+ # Return the ServiceInstance
59
+ #
60
+ # The ServiceInstance is the root of the vSphere inventory.
61
+ # @see http://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/vim.ServiceInstance.html
62
+ def serviceInstance
63
+ VIM::ServiceInstance self, 'ServiceInstance'
64
+ end
65
+
66
+ # Alias to serviceInstance.RetrieveServiceContent
67
+ def serviceContent
68
+ @serviceContent ||= serviceInstance.RetrieveServiceContent
69
+ end
70
+
71
+ # Alias to serviceContent.rootFolder
72
+ def rootFolder
73
+ serviceContent.rootFolder
74
+ end
75
+
76
+ alias root rootFolder
77
+
78
+ # Alias to serviceContent.propertyCollector
79
+ def propertyCollector
80
+ serviceContent.propertyCollector
81
+ end
82
+
83
+ # Alias to serviceContent.searchIndex
84
+ def searchIndex
85
+ serviceContent.searchIndex
86
+ end
87
+
88
+ # @private
89
+ def pretty_print pp
90
+ pp.text "VIM(#{@opts[:host]})"
91
+ end
92
+
93
+ def instanceUuid
94
+ serviceContent.about.instanceUuid
95
+ end
96
+
97
+ def get_log_lines logKey, lines=5, start=nil, host=nil
98
+ diagMgr = self.serviceContent.diagnosticManager
99
+ if !start
100
+ log = diagMgr.BrowseDiagnosticLog(:host => host, :key => logKey, :start => 999999999)
101
+ lineEnd = log.lineEnd
102
+ start = lineEnd - lines
103
+ end
104
+ start = start < 0 ? 0 : start
105
+ log = diagMgr.BrowseDiagnosticLog(:host => host, :key => logKey, :start => start)
106
+ if log.lineText.size > 0
107
+ [log.lineText.slice(-lines, log.lineText.size), log.lineEnd]
108
+ else
109
+ [log.lineText, log.lineEnd]
110
+ end
111
+ end
112
+
113
+ def get_log_keys host=nil
114
+ diagMgr = self.serviceContent.diagnosticManager
115
+ keys = []
116
+ diagMgr.QueryDescriptions(:host => host).each do |desc|
117
+ keys << "#{desc.key}"
118
+ end
119
+ keys
120
+ end
121
+
122
+ add_extension_dir File.join(File.dirname(__FILE__), "vim")
123
+ (ENV['RBVMOMI_VIM_EXTENSION_PATH']||'').split(':').each { |dir| add_extension_dir dir }
124
+
125
+ load_vmodl(ENV['VMODL'] || File.join(File.dirname(__FILE__), "../../vmodl.db"))
126
+ end
127
+
128
+ end
@@ -0,0 +1,51 @@
1
+ class RbVmomi::VIM::ComputeResource
2
+ # Aggregate cluster information.
3
+ #
4
+ # @note Values are returned in a hash.
5
+ #
6
+ # @return [Mhz] totalCPU: Sum of the frequencies of each CPU in the cluster.
7
+ # @return [Mhz] usedCPU: CPU cycles used across the cluster.
8
+ # @return [MB] totalMem: Total RAM.
9
+ # @return [MB] usedMem: Used RAM.
10
+ def stats
11
+ filterSpec = RbVmomi::VIM.PropertyFilterSpec(
12
+ :objectSet => [{
13
+ :obj => self,
14
+ :selectSet => [
15
+ RbVmomi::VIM.TraversalSpec(
16
+ :name => 'tsHosts',
17
+ :type => 'ComputeResource',
18
+ :path => 'host',
19
+ :skip => false
20
+ )
21
+ ]
22
+ }],
23
+ :propSet => [{
24
+ :pathSet => %w(name overallStatus summary.hardware.cpuMhz
25
+ summary.hardware.numCpuCores summary.hardware.memorySize
26
+ summary.quickStats.overallCpuUsage
27
+ summary.quickStats.overallMemoryUsage),
28
+ :type => 'HostSystem'
29
+ }]
30
+ )
31
+
32
+ result = _connection.propertyCollector.RetrieveProperties(:specSet => [filterSpec])
33
+
34
+ stats = {
35
+ :totalCPU => 0,
36
+ :totalMem => 0,
37
+ :usedCPU => 0,
38
+ :usedMem => 0,
39
+ }
40
+
41
+ result.each do |x|
42
+ next if x['overallStatus'] == 'red'
43
+ stats[:totalCPU] += x['summary.hardware.cpuMhz'] * x['summary.hardware.numCpuCores']
44
+ stats[:totalMem] += x['summary.hardware.memorySize'] / (1024*1024)
45
+ stats[:usedCPU] += x['summary.quickStats.overallCpuUsage'] || 0
46
+ stats[:usedMem] += x['summary.quickStats.overallMemoryUsage'] || 0
47
+ end
48
+
49
+ stats
50
+ end
51
+ end
@@ -0,0 +1,17 @@
1
+ class RbVmomi::VIM::Datacenter
2
+ # Traverse the given inventory +path+ to find a ComputeResource.
3
+ def find_compute_resource path
4
+ hostFolder.traverse path, RbVmomi::VIM::ComputeResource
5
+ end
6
+
7
+ # Find the Datastore with the given +name+.
8
+ def find_datastore name
9
+ datastore.find { |x| x.name == name }
10
+ end
11
+
12
+ # Traverse the given inventory +path+ to find a VirtualMachine.
13
+ def find_vm path
14
+ vmFolder.traverse path, RbVmomi::VIM::VirtualMachine
15
+ end
16
+ end
17
+
@@ -0,0 +1,68 @@
1
+ # @note +download+ and +upload+ require +curl+. If +curl+ is not in your +PATH+
2
+ # then set the +CURL+ environment variable to point to it.
3
+ # @todo Use an HTTP library instead of executing +curl+.
4
+ class RbVmomi::VIM::Datastore
5
+ CURLBIN = ENV['CURL'] || "curl" #@private
6
+
7
+ # Check whether a file exists on this datastore.
8
+ # @param path [String] Path on the datastore.
9
+ def exists? path
10
+ req = Net::HTTP::Head.new mkuripath(path)
11
+ req.initialize_http_header 'cookie' => _connection.cookie
12
+ resp = _connection.http.request req
13
+ case resp
14
+ when Net::HTTPSuccess
15
+ true
16
+ when Net::HTTPNotFound
17
+ false
18
+ else
19
+ fail resp.inspect
20
+ end
21
+ end
22
+
23
+ # Download a file from this datastore.
24
+ # @param remote_path [String] Source path on the datastore.
25
+ # @param local_path [String] Destination path on the local machine.
26
+ # @return [void]
27
+ def download remote_path, local_path
28
+ url = "http#{_connection.http.use_ssl? ? 's' : ''}://#{_connection.http.address}:#{_connection.http.port}#{mkuripath(remote_path)}"
29
+ pid = spawn CURLBIN, "-k", '--noproxy', '*', '-f',
30
+ "-o", local_path,
31
+ "-b", _connection.cookie,
32
+ url,
33
+ :out => '/dev/null'
34
+ Process.waitpid(pid, 0)
35
+ fail "download failed" unless $?.success?
36
+ end
37
+
38
+ # Upload a file to this datastore.
39
+ # @param remote_path [String] Destination path on the datastore.
40
+ # @param local_path [String] Source path on the local machine.
41
+ # @return [void]
42
+ def upload remote_path, local_path
43
+ url = "http#{_connection.http.use_ssl? ? 's' : ''}://#{_connection.http.address}:#{_connection.http.port}#{mkuripath(remote_path)}"
44
+ pid = spawn CURLBIN, "-k", '--noproxy', '*', '-f',
45
+ "-T", local_path,
46
+ "-b", _connection.cookie,
47
+ url,
48
+ :out => '/dev/null'
49
+ Process.waitpid(pid, 0)
50
+ fail "upload failed" unless $?.success?
51
+ end
52
+
53
+ private
54
+
55
+ def datacenter
56
+ return @datacenter if @datacenter
57
+ x = parent
58
+ while not x.is_a? RbVmomi::VIM::Datacenter
59
+ x = x.parent
60
+ end
61
+ fail unless x.is_a? RbVmomi::VIM::Datacenter
62
+ @datacenter = x
63
+ end
64
+
65
+ def mkuripath path
66
+ "/folder/#{URI.escape path}?dcPath=#{URI.escape datacenter.name}&dsName=#{URI.escape name}"
67
+ end
68
+ end
@@ -0,0 +1,75 @@
1
+ class RbVmomi::VIM::DynamicTypeMgrAllTypeInfo
2
+ def toRbvmomiTypeHash
3
+ id2name = {}
4
+ id2name.merge!({
5
+ 'string' => 'xsd:string',
6
+ 'java.lang.String' => 'xsd:string',
7
+ 'BOOLEAN' => 'xsd:boolean',
8
+ 'BYTE' => 'xsd:byte',
9
+ 'SHORT' => 'xsd:short',
10
+ 'INT' => 'xsd:int',
11
+ 'LONG' => 'xsd:long',
12
+ 'FLOAT' => 'xsd:float',
13
+ 'DOUBLE' => 'xsd:double',
14
+ 'boolean' => 'xsd:boolean',
15
+ 'byte' => 'xsd:byte',
16
+ 'short' => 'xsd:short',
17
+ 'int' => 'xsd:int',
18
+ 'long' => 'xsd:long',
19
+ 'float' => 'xsd:float',
20
+ 'double' => 'xsd:double',
21
+ 'vmodl.DateTime' => 'xsd:dateTime',
22
+ 'vmodl.Binary' => 'xsd:base64Binary',
23
+ 'vmodl.Any' => 'xsd:anyType',
24
+ 'vim.KeyValue' => 'KeyValue',
25
+ 'void' => nil,
26
+ })
27
+
28
+ %w(DataObject ManagedObject MethodFault MethodName DynamicData
29
+ PropertyPath RuntimeFault TypeName).each do |x|
30
+ id2name['vmodl.' + x] = x
31
+ end
32
+
33
+ types = {}
34
+ self.managedTypeInfo.each{|x| types.merge!(x.toRbvmomiTypeHash) }
35
+ self.dataTypeInfo.each{|x| types.merge!(x.toRbvmomiTypeHash) }
36
+
37
+ types.each do |k,t|
38
+ id2name[t['type-id']] = k
39
+ end
40
+
41
+ types = Hash[types.map do |k,t|
42
+ case t['kind']
43
+ when 'data'
44
+ t['wsdl_base'] = t['base-type-id'] ? id2name[t['base-type-id']] : 'DataObject'
45
+ #t.delete 'base-type-id'
46
+ t['props'].each do |x|
47
+ x['wsdl_type'] = id2name[x['type-id-ref']]
48
+ x.delete 'type-id-ref'
49
+ end
50
+ when 'managed'
51
+ t['wsdl_base'] = t['base-type-id'] ? id2name[t['base-type-id']] : 'ManagedObject'
52
+ #t.delete 'base-type-id'
53
+ t['props'].each do |x|
54
+ x['wsdl_type'] = id2name[x['type-id-ref']]
55
+ x.delete 'type-id-ref'
56
+ end
57
+ t['methods'].each do |mName,x|
58
+ if y = x['result']
59
+ y['wsdl_type'] = id2name[y['type-id-ref']]
60
+ #y.delete 'type-id-ref'
61
+ end
62
+ x['params'].each do |r|
63
+ r['wsdl_type'] = id2name[r['type-id-ref']]
64
+ r.delete 'type-id-ref'
65
+ end
66
+ end
67
+ when 'enum'
68
+ else fail
69
+ end
70
+ [k, t]
71
+ end]
72
+
73
+ types
74
+ end
75
+ end
@@ -0,0 +1,20 @@
1
+ class RbVmomi::VIM::DynamicTypeMgrDataTypeInfo
2
+ def toRbvmomiTypeHash
3
+ {
4
+ self.wsdlName => {
5
+ 'kind' => 'data',
6
+ 'type-id' => self.name,
7
+ 'base-type-id' => self.base.first,
8
+ 'props' => self.property.map do |prop|
9
+ {
10
+ 'name' => prop.name,
11
+ 'type-id-ref' => prop.type.gsub("[]", ""),
12
+ 'is-array' => (prop.type =~ /\[\]$/) ? true : false,
13
+ 'is-optional' => prop.annotation.find{|a| a.name == "optional"} ? true : false,
14
+ 'version-id-ref' => prop.version,
15
+ }
16
+ end,
17
+ }
18
+ }
19
+ end
20
+ end
@@ -0,0 +1,46 @@
1
+ class RbVmomi::VIM::DynamicTypeMgrManagedTypeInfo
2
+ def toRbvmomiTypeHash
3
+ {
4
+ self.wsdlName => {
5
+ 'kind' => 'managed',
6
+ 'type-id' => self.name,
7
+ 'base-type-id' => self.base.first,
8
+ 'props' => self.property.map do |prop|
9
+ {
10
+ 'name' => prop.name,
11
+ 'type-id-ref' => prop.type.gsub("[]", ""),
12
+ 'is-array' => (prop.type =~ /\[\]$/) ? true : false,
13
+ 'is-optional' => prop.annotation.find{|a| a.name == "optional"} ? true : false,
14
+ 'version-id-ref' => prop.version,
15
+ }
16
+ end,
17
+ 'methods' => Hash[
18
+ self.method.map do |method|
19
+ result = method.returnTypeInfo
20
+
21
+ [method.wsdlName,
22
+ {
23
+ 'params' => method.paramTypeInfo.map do |param|
24
+ {
25
+ 'name' => param.name,
26
+ 'type-id-ref' => param.type.gsub("[]", ""),
27
+ 'is-array' => (param.type =~ /\[\]$/) ? true : false,
28
+ 'is-optional' => param.annotation.find{|a| a.name == "optional"} ? true : false,
29
+ 'version-id-ref' => param.version,
30
+ }
31
+ end,
32
+ 'result' => {
33
+ 'name' => result.name,
34
+ 'type-id-ref' => result.type.gsub("[]", ""),
35
+ 'is-array' => (result.type =~ /\[\]$/) ? true : false,
36
+ 'is-optional' => result.annotation.find{|a| a.name == "optional"} ? true : false,
37
+ 'version-id-ref' => result.version,
38
+ }
39
+ }
40
+ ]
41
+ end
42
+ ]
43
+ }
44
+ }
45
+ end
46
+ end
@@ -0,0 +1,207 @@
1
+ class RbVmomi::VIM::Folder
2
+ # Retrieve a child entity
3
+ # @param name [String] Name of the child.
4
+ # @param type [Class] Return nil unless the found entity <tt>is_a? type</tt>.
5
+ # @return [VIM::ManagedEntity]
6
+ def find name, type=Object
7
+ x = _connection.searchIndex.FindChild(:entity => self, :name => name)
8
+ x if x.is_a? type
9
+ end
10
+
11
+ # Retrieve a virtual machine or host by DNS name
12
+ # @param name [String] The fully qualified domain name to find.
13
+ # @param type [Class] Return nil unless the found entity <tt>is_a? type</tt>.
14
+ # @param dc [RbVmomi::VIM::Datacenter] Restricts the query to entities in the given Datacenter.
15
+ # @return [VIM::ManagedEntity]
16
+ def findByDnsName name, type=RbVmomi::VIM::VirtualMachine, dc=nil
17
+ propSpecs = {
18
+ :entity => self, :dnsName => name,
19
+ :vmSearch => type == RbVmomi::VIM::VirtualMachine
20
+ }
21
+ propSpecs[:datacenter] = dc if dc
22
+ x = _connection.searchIndex.FindByDnsName(propSpecs)
23
+ x if x.is_a? type
24
+ end
25
+
26
+ # Retrieve a virtual machine or host by IP address
27
+ # @param ip [String] The IP address is in dot-decimal notation.
28
+ # @param type [Class] Return nil unless the found entity <tt>is_a? type</tt>.
29
+ # @param dc [RbVmomi::VIM::Datacenter] Restricts the query to entities in the given Datacenter.
30
+ # @return [VIM::ManagedEntity]
31
+ def findByIp ip, type=RbVmomi::VIM::VirtualMachine, dc=nil
32
+ propSpecs = {
33
+ :entity => self, :ip => ip,
34
+ :vmSearch => type == RbVmomi::VIM::VirtualMachine
35
+ }
36
+ propSpecs[:datacenter] = dc if dc
37
+ x = _connection.searchIndex.FindByIp(propSpecs)
38
+ x if x.is_a? type
39
+ end
40
+
41
+ # Retrieve a virtual machine or host by BIOS UUID.
42
+ # @param uuid [String] The UUID to find.
43
+ # @param type [Class] Return nil unless the found entity <tt>is_a? type</tt>.
44
+ # @param dc [RbVmomi::VIM::Datacenter] Restricts the query to entities in the given Datacenter.
45
+ # @return [VIM::ManagedEntity]
46
+ def findByUuid uuid, type=RbVmomi::VIM::VirtualMachine, dc=nil
47
+ propSpecs = {
48
+ :entity => self, :uuid => uuid, :instanceUuid => false,
49
+ :vmSearch => type == RbVmomi::VIM::VirtualMachine
50
+ }
51
+ propSpecs[:datacenter] = dc if dc
52
+ x = _connection.searchIndex.FindByUuid(propSpecs)
53
+ x if x.is_a? type
54
+ end
55
+
56
+ # Retrieve a managed entity by inventory path.
57
+ # @param path [String] A path of the form "My Folder/My Datacenter/vm/Discovered VM/VM1"
58
+ # @return [VIM::ManagedEntity]
59
+ def findByInventoryPath path
60
+ propSpecs = {
61
+ :entity => self, :inventoryPath => path
62
+ }
63
+ x = _connection.searchIndex.FindByInventoryPath(propSpecs)
64
+ end
65
+
66
+ # Alias to <tt>traverse path, type, true</tt>
67
+ # @see #traverse
68
+ def traverse! path, type=Object
69
+ traverse path, type, true
70
+ end
71
+
72
+ # Retrieve a descendant of this Folder.
73
+ # @param path [String] Path delimited by '/', or an array of path elements.
74
+ # @param type (see Folder#find)
75
+ # @param create [Boolean] If set, create folders that don't exist.
76
+ # @return (see Folder#find)
77
+ # @todo Move +create+ functionality into another method.
78
+ def traverse path, type=Object, create=false
79
+ if path.is_a? String
80
+ es = path.split('/').reject(&:empty?)
81
+ elsif path.is_a? Enumerable
82
+ es = path
83
+ else
84
+ fail "unexpected path class #{path.class}"
85
+ end
86
+ return self if es.empty?
87
+ final = es.pop
88
+
89
+ p = es.inject(self) do |f,e|
90
+ f.find(e, RbVmomi::VIM::Folder) || (create && f.CreateFolder(:name => e)) || return
91
+ end
92
+
93
+ if x = p.find(final, type)
94
+ x
95
+ elsif create and type == RbVmomi::VIM::Folder
96
+ p.CreateFolder(:name => final)
97
+ elsif create and type == RbVmomi::VIM::Datacenter
98
+ p.CreateDatacenter(:name => final)
99
+ else
100
+ nil
101
+ end
102
+ end
103
+
104
+ # Alias to +childEntity+.
105
+ def children
106
+ childEntity
107
+ end
108
+
109
+ # Efficiently retrieve properties from descendants of this folder.
110
+ #
111
+ # @param propSpecs [Hash] Specification of which properties to retrieve from
112
+ # which entities. Keys may be symbols, strings, or
113
+ # classes identifying ManagedEntity subtypes to be
114
+ # included in the results. Values are an array of
115
+ # property paths (strings) or the symbol :all.
116
+ #
117
+ # @return [Hash] Hash of ManagedObjects to properties.
118
+ def inventory_flat propSpecs={}
119
+ propSet = [{ :type => 'Folder', :pathSet => ['name', 'parent', 'childEntity'] }]
120
+ propSpecs.each do |k,v|
121
+ case k
122
+ when Class
123
+ fail "key must be a subclass of ManagedEntity" unless k < RbVmomi::VIM::ManagedEntity
124
+ k = k.wsdl_name
125
+ when Symbol, String
126
+ k = k.to_s
127
+ else
128
+ fail "invalid key"
129
+ end
130
+
131
+ h = { :type => k }
132
+ if v == :all
133
+ h[:all] = true
134
+ elsif v.is_a? Array
135
+ h[:pathSet] = v + %w(parent)
136
+ else
137
+ fail "value must be an array of property paths or :all"
138
+ end
139
+ propSet << h
140
+ end
141
+
142
+ filterSpec = RbVmomi::VIM.PropertyFilterSpec(
143
+ :objectSet => [
144
+ :obj => self,
145
+ :selectSet => [
146
+ RbVmomi::VIM.TraversalSpec(
147
+ :name => 'tsFolder',
148
+ :type => 'Folder',
149
+ :path => 'childEntity',
150
+ :skip => false,
151
+ :selectSet => [
152
+ RbVmomi::VIM.SelectionSpec(:name => 'tsFolder')
153
+ ]
154
+ )
155
+ ]
156
+ ],
157
+ :propSet => propSet
158
+ )
159
+
160
+ result = _connection.propertyCollector.RetrieveProperties(:specSet => [filterSpec])
161
+ {}.tap do |h|
162
+ result.each { |r| h[r.obj] = r }
163
+ end
164
+ end
165
+
166
+ # Efficiently retrieve properties from descendants of this folder.
167
+ #
168
+ # @param propSpecs [Hash] Specification of which properties to retrieve from
169
+ # which entities. Keys may be symbols, strings, or
170
+ # classes identifying ManagedEntity subtypes to be
171
+ # included in the results. Values are an array of
172
+ # property paths (strings) or the symbol :all.
173
+ #
174
+ # @return [Hash] Tree of inventory items. Each node is a hash from
175
+ # VIM::ObjectContent to children.
176
+ def inventory_tree propSpecs={}
177
+ inv = inventory_flat propSpecs
178
+ children = inv.values.group_by { |v| v['parent'] }
179
+ rec = lambda { |parent| Hash[(children[parent]||[]).map { |x| [x, rec[x.obj]] }] }
180
+ rec[self]
181
+ end
182
+
183
+ # Efficiently retrieve properties from descendants of this folder.
184
+ #
185
+ # @param propSpecs [Hash] Specification of which properties to retrieve from
186
+ # which entities. Keys may be symbols, strings, or
187
+ # classes identifying ManagedEntity subtypes to be
188
+ # included in the results. Values are an array of
189
+ # property paths (strings) or the symbol :all.
190
+ #
191
+ # @return [Hash] Tree of inventory items. Folders are hashes from child name
192
+ # to child result. Objects are hashes from property path to
193
+ # value.
194
+ #
195
+ # @deprecated
196
+ def inventory propSpecs={}
197
+ inv = inventory_flat propSpecs
198
+ tree = { self => {} }
199
+ inv.each do |obj,x|
200
+ next if obj == self
201
+ h = Hash[x.propSet.map { |y| [y.name, y.val] }]
202
+ tree[h['parent']][h['name']] = [obj, h]
203
+ tree[obj] = {} if obj.is_a? RbVmomi::VIM::Folder
204
+ end
205
+ tree
206
+ end
207
+ end