rbvmomi2 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +19 -0
- data/README.md +114 -0
- data/exe/rbvmomish +138 -0
- data/lib/rbvmomi/basic_types.rb +383 -0
- data/lib/rbvmomi/connection.rb +272 -0
- data/lib/rbvmomi/deserialization.rb +249 -0
- data/lib/rbvmomi/fault.rb +19 -0
- data/lib/rbvmomi/optimist.rb +72 -0
- data/lib/rbvmomi/pbm.rb +68 -0
- data/lib/rbvmomi/sms/SmsStorageManager.rb +10 -0
- data/lib/rbvmomi/sms.rb +63 -0
- data/lib/rbvmomi/sso.rb +313 -0
- data/lib/rbvmomi/trivial_soap.rb +122 -0
- data/lib/rbvmomi/type_loader.rb +138 -0
- data/lib/rbvmomi/utils/admission_control.rb +401 -0
- data/lib/rbvmomi/utils/deploy.rb +318 -0
- data/lib/rbvmomi/utils/leases.rb +145 -0
- data/lib/rbvmomi/utils/perfdump.rb +631 -0
- data/lib/rbvmomi/version.rb +6 -0
- data/lib/rbvmomi/vim/ComputeResource.rb +54 -0
- data/lib/rbvmomi/vim/Datacenter.rb +25 -0
- data/lib/rbvmomi/vim/Datastore.rb +72 -0
- data/lib/rbvmomi/vim/DynamicTypeMgrAllTypeInfo.rb +78 -0
- data/lib/rbvmomi/vim/DynamicTypeMgrDataTypeInfo.rb +23 -0
- data/lib/rbvmomi/vim/DynamicTypeMgrManagedTypeInfo.rb +54 -0
- data/lib/rbvmomi/vim/Folder.rb +214 -0
- data/lib/rbvmomi/vim/HostSystem.rb +177 -0
- data/lib/rbvmomi/vim/ManagedEntity.rb +60 -0
- data/lib/rbvmomi/vim/ManagedObject.rb +63 -0
- data/lib/rbvmomi/vim/ObjectContent.rb +26 -0
- data/lib/rbvmomi/vim/ObjectUpdate.rb +26 -0
- data/lib/rbvmomi/vim/OvfManager.rb +204 -0
- data/lib/rbvmomi/vim/PerfCounterInfo.rb +28 -0
- data/lib/rbvmomi/vim/PerformanceManager.rb +113 -0
- data/lib/rbvmomi/vim/PropertyCollector.rb +28 -0
- data/lib/rbvmomi/vim/ReflectManagedMethodExecuter.rb +33 -0
- data/lib/rbvmomi/vim/ResourcePool.rb +58 -0
- data/lib/rbvmomi/vim/ServiceInstance.rb +58 -0
- data/lib/rbvmomi/vim/Task.rb +68 -0
- data/lib/rbvmomi/vim/VirtualMachine.rb +75 -0
- data/lib/rbvmomi/vim.rb +157 -0
- data/lib/rbvmomi.rb +16 -0
- data/lib/rbvmomi2.rb +3 -0
- data/vmodl.db +0 -0
- metadata +214 -0
@@ -0,0 +1,25 @@
|
|
1
|
+
# Copyright (c) 2011-2017 VMware, Inc. All Rights Reserved.
|
2
|
+
# SPDX-License-Identifier: MIT
|
3
|
+
|
4
|
+
class RbVmomi::VIM::Datacenter
|
5
|
+
# Traverse the given inventory +path+ to find a ComputeResource.
|
6
|
+
def find_compute_resource path
|
7
|
+
hostFolder.traverse path, RbVmomi::VIM::ComputeResource
|
8
|
+
end
|
9
|
+
|
10
|
+
# Find the Datastore with the given +name+.
|
11
|
+
def find_datastore name
|
12
|
+
datastore.find { |x| x.name == name }
|
13
|
+
end
|
14
|
+
|
15
|
+
# Traverse the given inventory +path+ to find a VirtualMachine.
|
16
|
+
def find_vm path
|
17
|
+
vmFolder.traverse path, RbVmomi::VIM::VirtualMachine
|
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
|
24
|
+
end
|
25
|
+
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# Copyright (c) 2011-2017 VMware, Inc. All Rights Reserved.
|
2
|
+
# SPDX-License-Identifier: MIT
|
3
|
+
|
4
|
+
# @note +download+ and +upload+ require +curl+. If +curl+ is not in your +PATH+
|
5
|
+
# then set the +CURL+ environment variable to point to it.
|
6
|
+
# @todo Use an HTTP library instead of executing +curl+.
|
7
|
+
class RbVmomi::VIM::Datastore
|
8
|
+
CURLBIN = ENV['CURL'] || "curl" #@private
|
9
|
+
|
10
|
+
# Check whether a file exists on this datastore.
|
11
|
+
# @param path [String] Path on the datastore.
|
12
|
+
def exists? path
|
13
|
+
req = Net::HTTP::Head.new mkuripath(path)
|
14
|
+
req.initialize_http_header 'cookie' => _connection.cookie
|
15
|
+
resp = _connection.http.request req
|
16
|
+
case resp
|
17
|
+
when Net::HTTPSuccess
|
18
|
+
true
|
19
|
+
when Net::HTTPNotFound
|
20
|
+
false
|
21
|
+
else
|
22
|
+
fail resp.inspect
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Download a file from this datastore.
|
27
|
+
# @param remote_path [String] Source path on the datastore.
|
28
|
+
# @param local_path [String] Destination path on the local machine.
|
29
|
+
# @return [void]
|
30
|
+
def download remote_path, local_path
|
31
|
+
url = "http#{_connection.http.use_ssl? ? 's' : ''}://#{_connection.http.address}:#{_connection.http.port}#{mkuripath(remote_path)}"
|
32
|
+
pid = spawn CURLBIN, "-k", '--noproxy', '*', '-f',
|
33
|
+
"-o", local_path,
|
34
|
+
"-b", _connection.cookie,
|
35
|
+
url,
|
36
|
+
:out => '/dev/null'
|
37
|
+
Process.waitpid(pid, 0)
|
38
|
+
fail "download failed" unless $?.success?
|
39
|
+
end
|
40
|
+
|
41
|
+
# Upload a file to this datastore.
|
42
|
+
# @param remote_path [String] Destination path on the datastore.
|
43
|
+
# @param local_path [String] Source path on the local machine.
|
44
|
+
# @return [void]
|
45
|
+
def upload remote_path, local_path
|
46
|
+
url = "http#{_connection.http.use_ssl? ? 's' : ''}://#{_connection.http.address}:#{_connection.http.port}#{mkuripath(remote_path)}"
|
47
|
+
pid = spawn CURLBIN, "-k", '--noproxy', '*', '-f',
|
48
|
+
"-T", local_path,
|
49
|
+
"-b", _connection.cookie,
|
50
|
+
url,
|
51
|
+
:out => '/dev/null'
|
52
|
+
Process.waitpid(pid, 0)
|
53
|
+
fail "upload failed" unless $?.success?
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def datacenter
|
59
|
+
return @datacenter if @datacenter
|
60
|
+
x = parent
|
61
|
+
while not x.is_a? RbVmomi::VIM::Datacenter
|
62
|
+
x = x.parent
|
63
|
+
end
|
64
|
+
fail unless x.is_a? RbVmomi::VIM::Datacenter
|
65
|
+
@datacenter = x
|
66
|
+
end
|
67
|
+
|
68
|
+
def mkuripath path
|
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}"
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# Copyright (c) 2011-2017 VMware, Inc. All Rights Reserved.
|
2
|
+
# SPDX-License-Identifier: MIT
|
3
|
+
|
4
|
+
class RbVmomi::VIM::DynamicTypeMgrAllTypeInfo
|
5
|
+
def toRbvmomiTypeHash
|
6
|
+
id2name = {}
|
7
|
+
id2name.merge!({
|
8
|
+
'string' => 'xsd:string',
|
9
|
+
'java.lang.String' => 'xsd:string',
|
10
|
+
'BOOLEAN' => 'xsd:boolean',
|
11
|
+
'BYTE' => 'xsd:byte',
|
12
|
+
'SHORT' => 'xsd:short',
|
13
|
+
'INT' => 'xsd:int',
|
14
|
+
'LONG' => 'xsd:long',
|
15
|
+
'FLOAT' => 'xsd:float',
|
16
|
+
'DOUBLE' => 'xsd:double',
|
17
|
+
'boolean' => 'xsd:boolean',
|
18
|
+
'byte' => 'xsd:byte',
|
19
|
+
'short' => 'xsd:short',
|
20
|
+
'int' => 'xsd:int',
|
21
|
+
'long' => 'xsd:long',
|
22
|
+
'float' => 'xsd:float',
|
23
|
+
'double' => 'xsd:double',
|
24
|
+
'vmodl.DateTime' => 'xsd:dateTime',
|
25
|
+
'vmodl.Binary' => 'xsd:base64Binary',
|
26
|
+
'vmodl.Any' => 'xsd:anyType',
|
27
|
+
'vim.KeyValue' => 'KeyValue',
|
28
|
+
'void' => nil,
|
29
|
+
})
|
30
|
+
|
31
|
+
%w(DataObject ManagedObject MethodFault MethodName DynamicData
|
32
|
+
PropertyPath RuntimeFault TypeName).each do |x|
|
33
|
+
id2name['vmodl.' + x] = x
|
34
|
+
end
|
35
|
+
|
36
|
+
types = {}
|
37
|
+
self.managedTypeInfo.each{|x| types.merge!(x.toRbvmomiTypeHash) }
|
38
|
+
self.dataTypeInfo.each{|x| types.merge!(x.toRbvmomiTypeHash) }
|
39
|
+
|
40
|
+
types.each do |k,t|
|
41
|
+
id2name[t['type-id']] = k
|
42
|
+
end
|
43
|
+
|
44
|
+
types = Hash[types.map do |k,t|
|
45
|
+
case t['kind']
|
46
|
+
when 'data'
|
47
|
+
t['wsdl_base'] = t['base-type-id'] ? id2name[t['base-type-id']] : 'DataObject'
|
48
|
+
#t.delete 'base-type-id'
|
49
|
+
t['props'].each do |x|
|
50
|
+
x['wsdl_type'] = id2name[x['type-id-ref']]
|
51
|
+
x.delete 'type-id-ref'
|
52
|
+
end
|
53
|
+
when 'managed'
|
54
|
+
t['wsdl_base'] = t['base-type-id'] ? id2name[t['base-type-id']] : 'ManagedObject'
|
55
|
+
#t.delete 'base-type-id'
|
56
|
+
t['props'].each do |x|
|
57
|
+
x['wsdl_type'] = id2name[x['type-id-ref']]
|
58
|
+
x.delete 'type-id-ref'
|
59
|
+
end
|
60
|
+
t['methods'].each do |mName,x|
|
61
|
+
if y = x['result']
|
62
|
+
y['wsdl_type'] = id2name[y['type-id-ref']]
|
63
|
+
#y.delete 'type-id-ref'
|
64
|
+
end
|
65
|
+
x['params'].each do |r|
|
66
|
+
r['wsdl_type'] = id2name[r['type-id-ref']]
|
67
|
+
r.delete 'type-id-ref'
|
68
|
+
end
|
69
|
+
end
|
70
|
+
when 'enum'
|
71
|
+
else fail
|
72
|
+
end
|
73
|
+
[k, t]
|
74
|
+
end]
|
75
|
+
|
76
|
+
types
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# Copyright (c) 2011-2017 VMware, Inc. All Rights Reserved.
|
2
|
+
# SPDX-License-Identifier: MIT
|
3
|
+
|
4
|
+
class RbVmomi::VIM::DynamicTypeMgrDataTypeInfo
|
5
|
+
def toRbvmomiTypeHash
|
6
|
+
{
|
7
|
+
self.wsdlName => {
|
8
|
+
'kind' => 'data',
|
9
|
+
'type-id' => self.name,
|
10
|
+
'base-type-id' => self.base.first,
|
11
|
+
'props' => self.property.map do |prop|
|
12
|
+
{
|
13
|
+
'name' => prop.name,
|
14
|
+
'type-id-ref' => prop.type.gsub("[]", ""),
|
15
|
+
'is-array' => (prop.type =~ /\[\]$/) ? true : false,
|
16
|
+
'is-optional' => prop.annotation.find{|a| a.name == "optional"} ? true : false,
|
17
|
+
'version-id-ref' => prop.version,
|
18
|
+
}
|
19
|
+
end,
|
20
|
+
}
|
21
|
+
}
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# Copyright (c) 2011-2017 VMware, Inc. All Rights Reserved.
|
2
|
+
# SPDX-License-Identifier: MIT
|
3
|
+
|
4
|
+
class RbVmomi::VIM::DynamicTypeMgrManagedTypeInfo
|
5
|
+
def toRbvmomiTypeHash
|
6
|
+
{
|
7
|
+
self.wsdlName => {
|
8
|
+
'kind' => 'managed',
|
9
|
+
'type-id' => self.name,
|
10
|
+
'base-type-id' => self.base.first,
|
11
|
+
'props' => self.property.map do |prop|
|
12
|
+
{
|
13
|
+
'name' => prop.name,
|
14
|
+
'type-id-ref' => prop.type.gsub("[]", ""),
|
15
|
+
'is-array' => (prop.type =~ /\[\]$/) ? true : false,
|
16
|
+
'is-optional' => prop.annotation.find{|a| a.name == "optional"} ? true : false,
|
17
|
+
'version-id-ref' => prop.version,
|
18
|
+
}
|
19
|
+
end,
|
20
|
+
'methods' => Hash[
|
21
|
+
self.method.map do |method|
|
22
|
+
result = method.returnTypeInfo
|
23
|
+
|
24
|
+
[method.wsdlName,
|
25
|
+
{
|
26
|
+
'params' => method.paramTypeInfo.map do |param|
|
27
|
+
{
|
28
|
+
'name' => param.name,
|
29
|
+
'type-id-ref' => param.type.gsub("[]", ""),
|
30
|
+
'is-array' => (param.type =~ /\[\]$/) ? true : false,
|
31
|
+
'is-optional' => param.annotation.find{|a| a.name == "optional"} ? true : false,
|
32
|
+
'version-id-ref' => param.version,
|
33
|
+
}
|
34
|
+
end,
|
35
|
+
'result' => (
|
36
|
+
if result.nil? then
|
37
|
+
nil
|
38
|
+
else
|
39
|
+
{
|
40
|
+
'name' => result.name,
|
41
|
+
'type-id-ref' => result.type.gsub("[]", ""),
|
42
|
+
'is-array' => (result.type =~ /\[\]$/) ? true : false,
|
43
|
+
'is-optional' => result.annotation.find{|a| a.name == "optional"} ? true : false,
|
44
|
+
'version-id-ref' => result.version,
|
45
|
+
}
|
46
|
+
end)
|
47
|
+
}
|
48
|
+
]
|
49
|
+
end
|
50
|
+
]
|
51
|
+
}
|
52
|
+
}
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,214 @@
|
|
1
|
+
# Copyright (c) 2011-2017 VMware, Inc. All Rights Reserved.
|
2
|
+
# SPDX-License-Identifier: MIT
|
3
|
+
|
4
|
+
class RbVmomi::VIM::Folder
|
5
|
+
# Retrieve a child entity
|
6
|
+
# @param name [String] Name of the child.
|
7
|
+
# @param type [Class] Return nil unless the found entity <tt>is_a? type</tt>.
|
8
|
+
# @return [VIM::ManagedEntity]
|
9
|
+
def find name, type=Object
|
10
|
+
x = _connection.searchIndex.FindChild(:entity => self, :name => name)
|
11
|
+
x if x.is_a? type
|
12
|
+
end
|
13
|
+
|
14
|
+
# Retrieve a virtual machine or host by DNS name
|
15
|
+
# @param name [String] The fully qualified domain name to find.
|
16
|
+
# @param type [Class] Return nil unless the found entity <tt>is_a? type</tt>.
|
17
|
+
# @param dc [RbVmomi::VIM::Datacenter] Restricts the query to entities in the given Datacenter.
|
18
|
+
# @return [VIM::ManagedEntity]
|
19
|
+
def findByDnsName name, type=RbVmomi::VIM::VirtualMachine, dc=nil
|
20
|
+
propSpecs = {
|
21
|
+
:entity => self, :dnsName => name,
|
22
|
+
:vmSearch => type == RbVmomi::VIM::VirtualMachine
|
23
|
+
}
|
24
|
+
propSpecs[:datacenter] = dc if dc
|
25
|
+
x = _connection.searchIndex.FindByDnsName(propSpecs)
|
26
|
+
x if x.is_a? type
|
27
|
+
end
|
28
|
+
|
29
|
+
# Retrieve a virtual machine or host by IP address
|
30
|
+
# @param ip [String] The IP address is in dot-decimal notation.
|
31
|
+
# @param type [Class] Return nil unless the found entity <tt>is_a? type</tt>.
|
32
|
+
# @param dc [RbVmomi::VIM::Datacenter] Restricts the query to entities in the given Datacenter.
|
33
|
+
# @return [VIM::ManagedEntity]
|
34
|
+
def findByIp ip, type=RbVmomi::VIM::VirtualMachine, dc=nil
|
35
|
+
propSpecs = {
|
36
|
+
:entity => self, :ip => ip,
|
37
|
+
:vmSearch => type == RbVmomi::VIM::VirtualMachine
|
38
|
+
}
|
39
|
+
propSpecs[:datacenter] = dc if dc
|
40
|
+
x = _connection.searchIndex.FindByIp(propSpecs)
|
41
|
+
x if x.is_a? type
|
42
|
+
end
|
43
|
+
|
44
|
+
# Finds a virtual machine or host by BIOS or instance UUID
|
45
|
+
#
|
46
|
+
# @param uuid [String] UUID to find
|
47
|
+
# @param type [Class] return nil unless found entity <tt>is_a?(type)</tt>
|
48
|
+
# @param dc [RbVmomi::VIM::Datacenter] restricts query to specified datacenter
|
49
|
+
#
|
50
|
+
# @return [VIM::ManagedEntity]
|
51
|
+
def findByUuid(uuid, type = RbVmomi::VIM::VirtualMachine, dc = nil, instance_uuid = false)
|
52
|
+
prop_specs = {
|
53
|
+
:entity => self,
|
54
|
+
:instanceUuid => instance_uuid,
|
55
|
+
:uuid => uuid,
|
56
|
+
:vmSearch => type == RbVmomi::VIM::VirtualMachine
|
57
|
+
}
|
58
|
+
prop_specs[:datacenter] = dc if dc
|
59
|
+
x = _connection.searchIndex.FindByUuid(prop_specs)
|
60
|
+
x if x.is_a?(type)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Retrieve a managed entity by inventory path.
|
64
|
+
# @param path [String] A path of the form "My Folder/My Datacenter/vm/Discovered VM/VM1"
|
65
|
+
# @return [VIM::ManagedEntity]
|
66
|
+
def findByInventoryPath path
|
67
|
+
propSpecs = {
|
68
|
+
:entity => self, :inventoryPath => path
|
69
|
+
}
|
70
|
+
_connection.searchIndex.FindByInventoryPath(propSpecs)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Alias to <tt>traverse path, type, true</tt>
|
74
|
+
# @see #traverse
|
75
|
+
def traverse! path, type=Object
|
76
|
+
traverse path, type, true
|
77
|
+
end
|
78
|
+
|
79
|
+
# Retrieve a descendant of this Folder.
|
80
|
+
# @param path [String] Path delimited by '/', or an array of path elements.
|
81
|
+
# @param type (see Folder#find)
|
82
|
+
# @param create [Boolean] If set, create folders that don't exist.
|
83
|
+
# @return (see Folder#find)
|
84
|
+
# @todo Move +create+ functionality into another method.
|
85
|
+
def traverse path, type=Object, create=false
|
86
|
+
if path.is_a? String
|
87
|
+
es = path.split('/').reject(&:empty?)
|
88
|
+
elsif path.is_a? Enumerable
|
89
|
+
es = path
|
90
|
+
else
|
91
|
+
fail "unexpected path class #{path.class}"
|
92
|
+
end
|
93
|
+
return self if es.empty?
|
94
|
+
final = es.pop
|
95
|
+
|
96
|
+
p = es.inject(self) do |f,e|
|
97
|
+
f.find(e, RbVmomi::VIM::Folder) || (create && f.CreateFolder(:name => e)) || return
|
98
|
+
end
|
99
|
+
|
100
|
+
if x = p.find(final, type)
|
101
|
+
x
|
102
|
+
elsif create and type == RbVmomi::VIM::Folder
|
103
|
+
p.CreateFolder(:name => final)
|
104
|
+
elsif create and type == RbVmomi::VIM::Datacenter
|
105
|
+
p.CreateDatacenter(:name => final)
|
106
|
+
else
|
107
|
+
nil
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
# Alias to +childEntity+.
|
112
|
+
def children
|
113
|
+
childEntity
|
114
|
+
end
|
115
|
+
|
116
|
+
# Efficiently retrieve properties from descendants of this folder.
|
117
|
+
#
|
118
|
+
# @param propSpecs [Hash] Specification of which properties to retrieve from
|
119
|
+
# which entities. Keys may be symbols, strings, or
|
120
|
+
# classes identifying ManagedEntity subtypes to be
|
121
|
+
# included in the results. Values are an array of
|
122
|
+
# property paths (strings) or the symbol :all.
|
123
|
+
#
|
124
|
+
# @return [Hash] Hash of ManagedObjects to properties.
|
125
|
+
def inventory_flat propSpecs={}
|
126
|
+
propSet = [{ :type => 'Folder', :pathSet => ['name', 'parent', 'childEntity'] }]
|
127
|
+
propSpecs.each do |k,v|
|
128
|
+
case k
|
129
|
+
when Class
|
130
|
+
fail "key must be a subclass of ManagedEntity" unless k < RbVmomi::VIM::ManagedEntity
|
131
|
+
k = k.wsdl_name
|
132
|
+
when Symbol, String
|
133
|
+
k = k.to_s
|
134
|
+
else
|
135
|
+
fail "invalid key"
|
136
|
+
end
|
137
|
+
|
138
|
+
h = { :type => k }
|
139
|
+
if v == :all
|
140
|
+
h[:all] = true
|
141
|
+
elsif v.is_a? Array
|
142
|
+
h[:pathSet] = v + %w(parent)
|
143
|
+
else
|
144
|
+
fail "value must be an array of property paths or :all"
|
145
|
+
end
|
146
|
+
propSet << h
|
147
|
+
end
|
148
|
+
|
149
|
+
filterSpec = RbVmomi::VIM.PropertyFilterSpec(
|
150
|
+
:objectSet => [
|
151
|
+
:obj => self,
|
152
|
+
:selectSet => [
|
153
|
+
RbVmomi::VIM.TraversalSpec(
|
154
|
+
:name => 'tsFolder',
|
155
|
+
:type => 'Folder',
|
156
|
+
:path => 'childEntity',
|
157
|
+
:skip => false,
|
158
|
+
:selectSet => [
|
159
|
+
RbVmomi::VIM.SelectionSpec(:name => 'tsFolder')
|
160
|
+
]
|
161
|
+
)
|
162
|
+
]
|
163
|
+
],
|
164
|
+
:propSet => propSet
|
165
|
+
)
|
166
|
+
|
167
|
+
result = _connection.propertyCollector.RetrieveProperties(:specSet => [filterSpec])
|
168
|
+
{}.tap do |h|
|
169
|
+
result.each { |r| h[r.obj] = r }
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
# Efficiently retrieve properties from descendants of this folder.
|
174
|
+
#
|
175
|
+
# @param propSpecs [Hash] Specification of which properties to retrieve from
|
176
|
+
# which entities. Keys may be symbols, strings, or
|
177
|
+
# classes identifying ManagedEntity subtypes to be
|
178
|
+
# included in the results. Values are an array of
|
179
|
+
# property paths (strings) or the symbol :all.
|
180
|
+
#
|
181
|
+
# @return [Hash] Tree of inventory items. Each node is a hash from
|
182
|
+
# VIM::ObjectContent to children.
|
183
|
+
def inventory_tree propSpecs={}
|
184
|
+
inv = inventory_flat propSpecs
|
185
|
+
children = inv.values.group_by { |v| v['parent'] }
|
186
|
+
rec = lambda { |parent| Hash[(children[parent]||[]).map { |x| [x, rec[x.obj]] }] }
|
187
|
+
rec[self]
|
188
|
+
end
|
189
|
+
|
190
|
+
# Efficiently retrieve properties from descendants of this folder.
|
191
|
+
#
|
192
|
+
# @param propSpecs [Hash] Specification of which properties to retrieve from
|
193
|
+
# which entities. Keys may be symbols, strings, or
|
194
|
+
# classes identifying ManagedEntity subtypes to be
|
195
|
+
# included in the results. Values are an array of
|
196
|
+
# property paths (strings) or the symbol :all.
|
197
|
+
#
|
198
|
+
# @return [Hash] Tree of inventory items. Folders are hashes from child name
|
199
|
+
# to child result. Objects are hashes from property path to
|
200
|
+
# value.
|
201
|
+
#
|
202
|
+
# @deprecated
|
203
|
+
def inventory propSpecs={}
|
204
|
+
inv = inventory_flat propSpecs
|
205
|
+
tree = { self => {} }
|
206
|
+
inv.each do |obj,x|
|
207
|
+
next if obj == self
|
208
|
+
h = Hash[x.propSet.map { |y| [y.name, y.val] }]
|
209
|
+
tree[h['parent']][h['name']] = [obj, h]
|
210
|
+
tree[obj] = {} if obj.is_a? RbVmomi::VIM::Folder
|
211
|
+
end
|
212
|
+
tree
|
213
|
+
end
|
214
|
+
end
|
@@ -0,0 +1,177 @@
|
|
1
|
+
# Copyright (c) 2011-2017 VMware, Inc. All Rights Reserved.
|
2
|
+
# SPDX-License-Identifier: MIT
|
3
|
+
|
4
|
+
module RbVmomi
|
5
|
+
|
6
|
+
class VIM::HostSystem
|
7
|
+
def esxcli
|
8
|
+
@cached_esxcli ||= VIM::EsxcliNamespace.root(self)
|
9
|
+
end
|
10
|
+
|
11
|
+
def dtm
|
12
|
+
@cached_dtm ||= begin
|
13
|
+
RetrieveDynamicTypeManager()
|
14
|
+
rescue VIM::MethodNotFound
|
15
|
+
if summary.config.product.version >= '4.1.0'
|
16
|
+
if summary.config.product.version < '5.0.0' and direct?
|
17
|
+
VIM::InternalDynamicTypeManager(_connection, 'ha-dynamic-type-manager')
|
18
|
+
else
|
19
|
+
raise "esxcli not supported through VC before 5.0.0"
|
20
|
+
end
|
21
|
+
else
|
22
|
+
raise "esxcli not supported before 4.1.0"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def dti
|
28
|
+
@cached_dti ||= dtm.DynamicTypeMgrQueryTypeInfo
|
29
|
+
end
|
30
|
+
|
31
|
+
def create_dynamic_managed_object inst
|
32
|
+
wsdlName = dti.managedTypeInfo.find { |x| x.name == inst.moType }.wsdlName
|
33
|
+
_connection.type(wsdlName).new(_connection, inst.id)
|
34
|
+
end
|
35
|
+
|
36
|
+
def cli_info_fetcher
|
37
|
+
# XXX there can be more than one
|
38
|
+
return @cached_cli_info_fetcher if @cached_cli_info_fetcher
|
39
|
+
inst = dtm.DynamicTypeMgrQueryMoInstances.find { |x| x.moType == 'vim.CLIInfo' }
|
40
|
+
@cached_cli_info_fetcher = create_dynamic_managed_object inst
|
41
|
+
end
|
42
|
+
|
43
|
+
def mme
|
44
|
+
@cached_mme ||= RetrieveManagedMethodExecuter()
|
45
|
+
end
|
46
|
+
|
47
|
+
def direct?
|
48
|
+
@ref == 'ha-host'
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
class VIM::EsxcliNamespace
|
53
|
+
ESXCLI_PREFIX = 'vim.EsxCLI.'
|
54
|
+
|
55
|
+
attr_reader :name, :parent, :host, :type, :instance, :type_info, :namespaces, :commands
|
56
|
+
|
57
|
+
def self.root host
|
58
|
+
type_hash = host.dti.toRbvmomiTypeHash
|
59
|
+
VIM.loader.add_types type_hash
|
60
|
+
all_instances = host.dtm.DynamicTypeMgrQueryMoInstances
|
61
|
+
instances = Hash[all_instances.select { |x| x.moType.start_with? ESXCLI_PREFIX }.
|
62
|
+
map { |x| [x.moType,x.id] }]
|
63
|
+
type_infos = Hash[host.dti.managedTypeInfo.map { |x| [x.name,x] }]
|
64
|
+
new('root', nil, host).tap do |root|
|
65
|
+
instances.each do |type,instance|
|
66
|
+
path = type.split('.')[2..-1]
|
67
|
+
ns = path.inject(root) { |b,v| b.namespaces[v] }
|
68
|
+
ns.realize type, instance, type_infos[type]
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def initialize name, parent, host
|
74
|
+
@name = name
|
75
|
+
@parent = parent
|
76
|
+
@host = host
|
77
|
+
@type = nil
|
78
|
+
@instance = nil
|
79
|
+
@type_info = nil
|
80
|
+
@namespaces = Hash.new { |h,k| h[k] = self.class.new k, self, host }
|
81
|
+
@commands = {}
|
82
|
+
@cached_cli_info = nil
|
83
|
+
end
|
84
|
+
|
85
|
+
def realize type, instance, type_info
|
86
|
+
fail if @type or @instance
|
87
|
+
@type = type
|
88
|
+
@instance = instance
|
89
|
+
@type_info = type_info
|
90
|
+
@type_info.method.each do |method_type_info|
|
91
|
+
name = method_type_info.name
|
92
|
+
@commands[name] = VIM::EsxcliCommand.new self, method_type_info
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def type_name
|
97
|
+
if @type then @type
|
98
|
+
elsif @parent then "#{@parent.type_name}.#{@name}"
|
99
|
+
else 'vim.EsxCLI'
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def cli_info
|
104
|
+
@cached_cli_info ||=
|
105
|
+
if @host.direct?
|
106
|
+
@host.cli_info_fetcher.VimCLIInfoFetchCLIInfo(:typeName => type_name)
|
107
|
+
else
|
108
|
+
@host.mme.execute(@host.cli_info_fetcher._ref,
|
109
|
+
"vim.CLIInfo.FetchCLIInfo", :typeName => type_name)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def obj
|
114
|
+
conn = @host._connection
|
115
|
+
conn.type(@type_info.wsdlName).new(conn, @instance)
|
116
|
+
end
|
117
|
+
|
118
|
+
def method_missing(name, *args)
|
119
|
+
name = name.to_s
|
120
|
+
if @namespaces.member? name and args.empty?
|
121
|
+
@namespaces[name]
|
122
|
+
elsif @commands.member? name
|
123
|
+
@commands[name].call(*args)
|
124
|
+
else
|
125
|
+
raise NoMethodError
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def pretty_print q
|
130
|
+
q.text @name
|
131
|
+
q.text ' '
|
132
|
+
q.group 2 do
|
133
|
+
q.text '{'
|
134
|
+
q.breakable
|
135
|
+
items = (@namespaces.values+@commands.values).sort_by(&:name)
|
136
|
+
q.seplist items, nil, :each do |v|
|
137
|
+
if v.is_a? VIM::EsxcliNamespace
|
138
|
+
q.pp v
|
139
|
+
else
|
140
|
+
q.text v.name
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
q.breakable
|
145
|
+
q.text '}'
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
class VIM::EsxcliCommand
|
150
|
+
attr_reader :ns, :type_info, :cli_info
|
151
|
+
|
152
|
+
def initialize ns, type_info
|
153
|
+
@ns = ns
|
154
|
+
@type_info = type_info
|
155
|
+
@cached_cli_info = nil
|
156
|
+
end
|
157
|
+
|
158
|
+
def name
|
159
|
+
@type_info.name
|
160
|
+
end
|
161
|
+
|
162
|
+
def cli_info
|
163
|
+
@cached_cli_info ||= @ns.cli_info.method.find { |x| x.name == @type_info.name }
|
164
|
+
end
|
165
|
+
|
166
|
+
def call args={}
|
167
|
+
if @ns.host.direct?
|
168
|
+
@ns.obj._call @type_info.wsdlName, args
|
169
|
+
else
|
170
|
+
real_args = Set.new(type_info.paramTypeInfo.map(&:name))
|
171
|
+
args = args.reject { |k,v| !real_args.member?(k.to_s) }
|
172
|
+
@ns.host.mme.execute(@ns.obj._ref, "#{@ns.type_name}.#{@type_info.name}", args)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
end
|