vagrant-rbvmomi 1.8.1

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 (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