rbvmomi2 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +19 -0
  3. data/README.md +114 -0
  4. data/exe/rbvmomish +138 -0
  5. data/lib/rbvmomi/basic_types.rb +383 -0
  6. data/lib/rbvmomi/connection.rb +272 -0
  7. data/lib/rbvmomi/deserialization.rb +249 -0
  8. data/lib/rbvmomi/fault.rb +19 -0
  9. data/lib/rbvmomi/optimist.rb +72 -0
  10. data/lib/rbvmomi/pbm.rb +68 -0
  11. data/lib/rbvmomi/sms/SmsStorageManager.rb +10 -0
  12. data/lib/rbvmomi/sms.rb +63 -0
  13. data/lib/rbvmomi/sso.rb +313 -0
  14. data/lib/rbvmomi/trivial_soap.rb +122 -0
  15. data/lib/rbvmomi/type_loader.rb +138 -0
  16. data/lib/rbvmomi/utils/admission_control.rb +401 -0
  17. data/lib/rbvmomi/utils/deploy.rb +318 -0
  18. data/lib/rbvmomi/utils/leases.rb +145 -0
  19. data/lib/rbvmomi/utils/perfdump.rb +631 -0
  20. data/lib/rbvmomi/version.rb +6 -0
  21. data/lib/rbvmomi/vim/ComputeResource.rb +54 -0
  22. data/lib/rbvmomi/vim/Datacenter.rb +25 -0
  23. data/lib/rbvmomi/vim/Datastore.rb +72 -0
  24. data/lib/rbvmomi/vim/DynamicTypeMgrAllTypeInfo.rb +78 -0
  25. data/lib/rbvmomi/vim/DynamicTypeMgrDataTypeInfo.rb +23 -0
  26. data/lib/rbvmomi/vim/DynamicTypeMgrManagedTypeInfo.rb +54 -0
  27. data/lib/rbvmomi/vim/Folder.rb +214 -0
  28. data/lib/rbvmomi/vim/HostSystem.rb +177 -0
  29. data/lib/rbvmomi/vim/ManagedEntity.rb +60 -0
  30. data/lib/rbvmomi/vim/ManagedObject.rb +63 -0
  31. data/lib/rbvmomi/vim/ObjectContent.rb +26 -0
  32. data/lib/rbvmomi/vim/ObjectUpdate.rb +26 -0
  33. data/lib/rbvmomi/vim/OvfManager.rb +204 -0
  34. data/lib/rbvmomi/vim/PerfCounterInfo.rb +28 -0
  35. data/lib/rbvmomi/vim/PerformanceManager.rb +113 -0
  36. data/lib/rbvmomi/vim/PropertyCollector.rb +28 -0
  37. data/lib/rbvmomi/vim/ReflectManagedMethodExecuter.rb +33 -0
  38. data/lib/rbvmomi/vim/ResourcePool.rb +58 -0
  39. data/lib/rbvmomi/vim/ServiceInstance.rb +58 -0
  40. data/lib/rbvmomi/vim/Task.rb +68 -0
  41. data/lib/rbvmomi/vim/VirtualMachine.rb +75 -0
  42. data/lib/rbvmomi/vim.rb +157 -0
  43. data/lib/rbvmomi.rb +16 -0
  44. data/lib/rbvmomi2.rb +3 -0
  45. data/vmodl.db +0 -0
  46. metadata +214 -0
@@ -0,0 +1,60 @@
1
+ # Copyright (c) 2011-2017 VMware, Inc. All Rights Reserved.
2
+ # SPDX-License-Identifier: MIT
3
+
4
+ class RbVmomi::VIM::ManagedEntity
5
+ # Retrieve the ancestors of the entity.
6
+ # @return [Array] Ancestors of this entity, starting with the root.
7
+ def path
8
+ self.class.paths([self])[self]
9
+ end
10
+
11
+ # Retrieve the ancestors of a list of entries.
12
+ # @return [Hash] Object-indexed hash of ancestors of entities, starting with the root.
13
+ def self.paths objs
14
+ filterSpec = RbVmomi::VIM.PropertyFilterSpec(
15
+ :objectSet => objs.map do |obj|
16
+ RbVmomi::VIM.ObjectSpec(
17
+ :obj => obj,
18
+ :selectSet => [
19
+ RbVmomi::VIM.TraversalSpec(
20
+ :name => "tsME",
21
+ :type => 'ManagedEntity',
22
+ :path => 'parent',
23
+ :skip => false,
24
+ :selectSet => [
25
+ RbVmomi::VIM.SelectionSpec(:name => "tsME")
26
+ ]
27
+ )
28
+ ]
29
+ )
30
+ end,
31
+ :propSet => [{
32
+ :pathSet => %w(name parent),
33
+ :type => 'ManagedEntity'
34
+ }]
35
+ )
36
+
37
+ propCollector = objs.first._connection.propertyCollector
38
+ result = propCollector.RetrieveProperties(:specSet => [filterSpec])
39
+
40
+ Hash[objs.map do |obj|
41
+ tree = {}
42
+ result.each { |x| tree[x.obj] = [x['parent'], x['name']] }
43
+ a = []
44
+ cur = obj
45
+ while cur
46
+ parent, name = *tree[cur]
47
+ a << [cur, name]
48
+ cur = parent
49
+ end
50
+ [obj, a.reverse]
51
+ end]
52
+ end
53
+
54
+ # Return a string representation of +path+ suitable for display.
55
+ # @return [String]
56
+ # @see #path
57
+ def pretty_path
58
+ path[1..-1].map { |x| x[1] } * '/'
59
+ end
60
+ end
@@ -0,0 +1,63 @@
1
+ # Copyright (c) 2011-2017 VMware, Inc. All Rights Reserved.
2
+ # SPDX-License-Identifier: MIT
3
+
4
+ class RbVmomi::VIM::ManagedObject
5
+ # Wait for updates on an object until a condition becomes true.
6
+ #
7
+ # @param pathSet [Array] Property paths to wait for updates to.
8
+ # @yield Called when an update to a subscribed property occurs.
9
+ # @yieldreturn [Boolean] Whether to stop waiting.
10
+ #
11
+ # @todo Pass the current property values to the block.
12
+ def wait_until *pathSet, &b
13
+ all = pathSet.empty?
14
+ filter = _connection.propertyCollector.CreateFilter :spec => {
15
+ :propSet => [{ :type => self.class.wsdl_name, :all => all, :pathSet => pathSet }],
16
+ :objectSet => [{ :obj => self }],
17
+ }, :partialUpdates => false
18
+ ver = ''
19
+ loop do
20
+ result = _connection.propertyCollector.WaitForUpdates(:version => ver)
21
+ ver = result.version
22
+ if x = b.call
23
+ return x
24
+ end
25
+ end
26
+ ensure
27
+ filter.DestroyPropertyFilter if filter
28
+ end
29
+
30
+ # Efficiently retrieve multiple properties from an object.
31
+ # @param pathSet [Array] Properties to return.
32
+ # @return [Hash] Hash from property paths to values.
33
+ def collect! *pathSet
34
+ spec = {
35
+ :objectSet => [{ :obj => self }],
36
+ :propSet => [{
37
+ :pathSet => pathSet,
38
+ :type => self.class.wsdl_name
39
+ }]
40
+ }
41
+ ret = _connection.propertyCollector.RetrieveProperties(:specSet => [spec])
42
+ if ret && ret.length > 0
43
+ ret[0].to_hash
44
+ else
45
+ {}
46
+ end
47
+ end
48
+
49
+ # Efficiently retrieve multiple properties from an object.
50
+ # @param pathSet (see #collect!)
51
+ # @yield [*values] Property values in same order as +pathSet+.
52
+ # @return [Array] Property values in same order as +pathSet+, or the return
53
+ # value from the block if it is given.
54
+ def collect *pathSet
55
+ h = collect!(*pathSet)
56
+ a = pathSet.map { |k| h[k.to_s] }
57
+ if block_given?
58
+ yield a
59
+ else
60
+ a
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,26 @@
1
+ # Copyright (c) 2011-2017 VMware, Inc. All Rights Reserved.
2
+ # SPDX-License-Identifier: MIT
3
+
4
+ class RbVmomi::VIM::ObjectContent
5
+ # Represent this ObjectContent as a hash.
6
+ # @return [Hash] A hash from property paths to values.
7
+ def to_hash
8
+ @cached_hash ||= to_hash_uncached
9
+ end
10
+
11
+ # Alias for +to_hash[k]+.
12
+ def [](k)
13
+ to_hash[k]
14
+ end
15
+
16
+ private
17
+
18
+ def to_hash_uncached
19
+ h = {}
20
+ propSet.each do |x|
21
+ fail if h.member? x.name
22
+ h[x.name] = x.val
23
+ end
24
+ h
25
+ end
26
+ end
@@ -0,0 +1,26 @@
1
+ # Copyright (c) 2011-2017 VMware, Inc. All Rights Reserved.
2
+ # SPDX-License-Identifier: MIT
3
+
4
+ class RbVmomi::VIM::ObjectUpdate
5
+ # Represent this ObjectUpdate as a hash.
6
+ # @return [Hash] A hash from property paths to values.
7
+ def to_hash
8
+ @cached_hash ||= to_hash_uncached
9
+ end
10
+
11
+ # Alias for +to_hash[k]+.
12
+ def [](k)
13
+ to_hash[k]
14
+ end
15
+
16
+ private
17
+
18
+ def to_hash_uncached
19
+ h = {}
20
+ changeSet.each do |x|
21
+ fail if h.member? x.name
22
+ h[x.name] = x.val
23
+ end
24
+ h
25
+ end
26
+ end
@@ -0,0 +1,204 @@
1
+ # Copyright (c) 2011-2017 VMware, Inc. All Rights Reserved.
2
+ # SPDX-License-Identifier: MIT
3
+
4
+ # @note +deployOVF+ and requires +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::OvfManager
8
+ CURLBIN = ENV['CURL'] || "curl" #@private
9
+
10
+ # Deploy an OVF.
11
+ #
12
+ # @param [Hash] opts The options hash.
13
+ # @option opts [String] :uri Location of the OVF.
14
+ # @option opts [String] :vmName Name of the new VM.
15
+ # @option opts [VIM::Folder] :vmFolder Folder to place the VM in.
16
+ # @option opts [VIM::HostSystem] :host Host to use.
17
+ # @option opts [VIM::ResourcePool] :resourcePool Resource pool to use.
18
+ # @option opts [VIM::Datastore] :datastore Datastore to use.
19
+ # @option opts [String] :diskProvisioning (thin) Disk provisioning mode.
20
+ # @option opts [Hash] :networkMappings Network mappings.
21
+ # @option opts [Hash] :propertyMappings Property mappings.
22
+ # @option opts [String] :deploymentOption Deployment option key.
23
+ def deployOVF opts
24
+ opts = { :networkMappings => {},
25
+ :propertyMappings => {},
26
+ :diskProvisioning => :thin }.merge opts
27
+
28
+ %w(uri vmName vmFolder host resourcePool datastore).each do |k|
29
+ fail "parameter #{k} required" unless opts[k.to_sym]
30
+ end
31
+
32
+ ovfImportSpec = RbVmomi::VIM::OvfCreateImportSpecParams(
33
+ :hostSystem => opts[:host],
34
+ :locale => "US",
35
+ :entityName => opts[:vmName],
36
+ :deploymentOption => opts[:deploymentOption] || "",
37
+ :networkMapping => opts[:networkMappings].map{|from, to| RbVmomi::VIM::OvfNetworkMapping(:name => from, :network => to)},
38
+ :propertyMapping => opts[:propertyMappings].to_a,
39
+ :diskProvisioning => opts[:diskProvisioning]
40
+ )
41
+
42
+ result = CreateImportSpec(
43
+ :ovfDescriptor => open(opts[:uri]).read,
44
+ :resourcePool => opts[:resourcePool],
45
+ :datastore => opts[:datastore],
46
+ :cisp => ovfImportSpec
47
+ )
48
+
49
+ raise result.error[0].localizedMessage if result.error && !result.error.empty?
50
+
51
+ if result.warning
52
+ result.warning.each{|x| puts "OVF Warning: #{x.localizedMessage.chomp}" }
53
+ end
54
+
55
+ importSpec = result.importSpec
56
+ if importSpec && importSpec.instantiationOst && importSpec.instantiationOst.child
57
+ importSpec.instantiationOst.child.each do |child|
58
+ child.section.map do |section|
59
+ section.xml = _handle_ost(section.xml, opts)
60
+ end
61
+ end
62
+ end
63
+
64
+ nfcLease = opts[:resourcePool].ImportVApp(:spec => importSpec,
65
+ :folder => opts[:vmFolder],
66
+ :host => opts[:host])
67
+
68
+ nfcLease.wait_until(:state) { nfcLease.state != "initializing" }
69
+ raise nfcLease.error if nfcLease.state == "error"
70
+ begin
71
+ nfcLease.HttpNfcLeaseProgress(:percent => 5)
72
+ timeout, = nfcLease.collect 'info.leaseTimeout'
73
+ puts "DEBUG: Timeout: #{timeout}"
74
+ if timeout < 4 * 60
75
+ puts "WARNING: OVF upload NFC lease timeout less than 4 minutes"
76
+ end
77
+ progress = 5.0
78
+ result.fileItem.each do |fileItem|
79
+ leaseInfo, leaseState, leaseError = nfcLease.collect 'info', 'state', 'error'
80
+ # Retry nfcLease.collect because of PR 969599:
81
+ # If retrying property collector works, this means there is a network
82
+ # or VC overloading problem.
83
+ retrynum = 5
84
+ i = 1
85
+ while i <= retrynum && !leaseState
86
+ puts "Retrying at iteration #{i}"
87
+ sleep 1
88
+ leaseInfo, leaseState, leaseError = nfcLease.collect 'info', 'state', 'error'
89
+ i += 1
90
+ end
91
+ if leaseState != "ready"
92
+ raise "NFC lease is no longer ready: #{leaseState}: #{leaseError}"
93
+ end
94
+ if leaseInfo == nil
95
+ raise "NFC lease disappeared?"
96
+ end
97
+ deviceUrl = leaseInfo.deviceUrl.find{|x| x.importKey == fileItem.deviceId}
98
+ if !deviceUrl
99
+ raise "Couldn't find deviceURL for device '#{fileItem.deviceId}'"
100
+ end
101
+
102
+ ovfFilename = opts[:uri].to_s
103
+ tmp = ovfFilename.split(/\//)
104
+ tmp.pop
105
+ tmp << fileItem.path
106
+ filename = tmp.join("/")
107
+
108
+ # If filename doesn't have a URI scheme, we're considering it a local file
109
+ if URI(filename).scheme.nil?
110
+ filename = "file://" + filename
111
+ end
112
+
113
+ method = fileItem.create ? "PUT" : "POST"
114
+
115
+ keepAliveThread = Thread.new do
116
+ while true
117
+ nfcLease.HttpNfcLeaseProgress(:percent => progress.to_i)
118
+ sleep 1 * 60
119
+ end
120
+ end
121
+
122
+ i = 1
123
+ ip = nil
124
+ begin
125
+ begin
126
+ puts "Iteration #{i}: Trying to get host's IP address ..."
127
+ ip = opts[:host].config.network.vnic[0].spec.ip.ipAddress
128
+ rescue Exception=>e
129
+ puts "Iteration #{i}: Couldn't get host's IP address: #{e}"
130
+ end
131
+ sleep 1
132
+ i += 1
133
+ end while i <= 5 && !ip
134
+ raise "Couldn't get host's IP address" unless ip
135
+ href = deviceUrl.url.gsub("*", ip)
136
+ downloadCmd = "#{CURLBIN} -L '#{URI::escape(filename)}'"
137
+ uploadCmd = "#{CURLBIN} -Ss -X #{method} --insecure -T - -H 'Content-Type: application/x-vnd.vmware-streamVmdk' '#{URI::escape(href)}'"
138
+ # Previously we used to append "-H 'Content-Length: #{fileItem.size}'"
139
+ # to the uploadCmd. It is not clear to me why, but that leads to
140
+ # trucation of the uploaded disk. Without this option curl can't tell
141
+ # the progress, but who cares
142
+ system("#{downloadCmd} | #{uploadCmd}", :out => "/dev/null")
143
+
144
+ keepAliveThread.kill
145
+ keepAliveThread.join
146
+
147
+ progress += (90.0 / result.fileItem.length)
148
+ nfcLease.HttpNfcLeaseProgress(:percent => progress.to_i)
149
+ end
150
+
151
+ nfcLease.HttpNfcLeaseProgress(:percent => 100)
152
+ raise nfcLease.error if nfcLease.state == "error"
153
+ i = 1
154
+ vm = nil
155
+ begin
156
+ begin
157
+ puts "Iteration #{i}: Trying to access nfcLease.info.entity ..."
158
+ vm = nfcLease.info.entity
159
+ rescue Exception=>e
160
+ puts "Iteration #{i}: Couldn't access nfcLease.info.entity: #{e}"
161
+ end
162
+ sleep 1
163
+ i += 1
164
+ end while i <= 5 && !vm
165
+ raise "Couldn't access nfcLease.info.entity" unless vm
166
+
167
+ # Ignore sporadic connection errors caused by PR 1019166..
168
+ # Three attempts are made to execute HttpNfcLeaseComplete.
169
+ # Not critical if none goes through, as long as vm is obtained
170
+ #
171
+ # TODO: find the reason why HttpNfcLeaseComplete gets a wrong
172
+ # response (RetrievePropertiesResponse)
173
+ i = 0
174
+ begin
175
+ nfcLease.HttpNfcLeaseComplete
176
+ puts "HttpNfcLeaseComplete succeeded"
177
+ rescue RbVmomi::VIM::InvalidState
178
+ puts "HttpNfcLeaseComplete already finished.."
179
+ rescue Exception => e
180
+ puts "HttpNfcLeaseComplete failed at iteration #{i} with exception: #{e}"
181
+ i += 1
182
+ retry if i < 3
183
+ puts "Giving up HttpNfcLeaseComplete.."
184
+ end
185
+ vm
186
+ end
187
+ rescue Exception
188
+ (nfcLease.HttpNfcLeaseAbort rescue nil) if nfcLease
189
+ raise
190
+ end
191
+
192
+ def _handle_ost ost, opts = {}
193
+ ost = Nokogiri::XML(ost)
194
+ if opts[:vservice] == ['com.vmware.vim.vsm:extension_vservice']
195
+ ost.xpath('//vmw:Annotations/vmw:Providers/vmw:Provider').each do |x|
196
+ x['vmw:selected'] = 'selected'
197
+ end
198
+ ost.xpath('//vmw:Annotations/vmw:Providers').each do |x|
199
+ x['vmw:selected'] = 'com.vmware.vim.vsm:extension_vservice'
200
+ end
201
+ end
202
+ ost.to_s
203
+ end
204
+ end
@@ -0,0 +1,28 @@
1
+ # Copyright (c) 2012-2017 VMware, Inc. All Rights Reserved.
2
+ # SPDX-License-Identifier: MIT
3
+
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ class RbVmomi::VIM::PerfCounterInfo
24
+ def name
25
+ "#{groupInfo.key}.#{nameInfo.key}"
26
+ end
27
+ end
28
+
@@ -0,0 +1,113 @@
1
+ # Copyright (c) 2012-2017 VMware, Inc. All Rights Reserved.
2
+ # SPDX-License-Identifier: MIT
3
+
4
+ require 'date'
5
+
6
+ class Time
7
+ def to_datetime
8
+ # Convert seconds + microseconds into a fractional number of seconds
9
+ seconds = sec + Rational(usec, 10**6)
10
+
11
+ # Convert a UTC offset measured in minutes to one measured in a
12
+ # fraction of a day.
13
+ offset = Rational(utc_offset, 60 * 60 * 24)
14
+ DateTime.new(year, month, day, hour, min, seconds, offset)
15
+ end
16
+ end
17
+
18
+ RbVmomi::VIM::PerformanceManager
19
+ class RbVmomi::VIM::PerformanceManager
20
+ def perfcounter_cached
21
+ @perfcounter ||= perfCounter
22
+ end
23
+
24
+ def perfcounter_hash
25
+ @perfcounter_hash ||= Hash[perfcounter_cached.map{|x| [x.name, x]}]
26
+ end
27
+
28
+ def perfcounter_idhash
29
+ @perfcounter_idhash ||= Hash[perfcounter_cached.map{|x| [x.key, x]}]
30
+ end
31
+
32
+ def provider_summary obj
33
+ @provider_summary ||= {}
34
+ @provider_summary[obj.class] ||= QueryPerfProviderSummary(:entity => obj)
35
+ end
36
+
37
+ def retrieve_stats objects, metrics, opts = {}
38
+ opts = opts.dup
39
+ max_samples = opts[:max_samples] || 1
40
+ realtime = false
41
+ if not opts[:interval]
42
+ provider = provider_summary objects.first
43
+ opts[:interval] = provider.refreshRate
44
+ realtime = true
45
+ else
46
+ provider = provider_summary objects.first
47
+ if opts[:interval] == provider.refreshRate
48
+ realtime = true
49
+ end
50
+ end
51
+
52
+ instances = opts[:instance] || '*'
53
+ if !instances.is_a?(Array)
54
+ instances = [instances]
55
+ end
56
+ metric_ids = []
57
+ metrics.each do |x|
58
+ counter = perfcounter_hash[x]
59
+ if !counter
60
+ pp perfcounter_hash.keys
61
+ fail "Counter for #{x} couldn't be found"
62
+ end
63
+ instances.each do |instance|
64
+ metric_ids << RbVmomi::VIM::PerfMetricId(:counterId => counter.key,
65
+ :instance => instance)
66
+ end
67
+ end
68
+ query_specs = objects.map do |obj|
69
+ RbVmomi::VIM::PerfQuerySpec({
70
+ :maxSample => max_samples,
71
+ :entity => obj,
72
+ :metricId => metric_ids,
73
+ :intervalId => opts[:interval],
74
+ :startTime => (realtime == false ? opts[:start_time].to_datetime : nil),
75
+ })
76
+ end
77
+ stats = QueryPerf(:querySpec => query_specs)
78
+
79
+ if !opts[:multi_instance]
80
+ Hash[stats.map do |res|
81
+ [
82
+ res.entity,
83
+ {
84
+ :sampleInfo => res.sampleInfo,
85
+ :metrics => Hash[res.value.map do |metric|
86
+ metric_name = perfcounter_idhash[metric.id.counterId].name
87
+ [metric_name, metric.value]
88
+ end]
89
+ }
90
+ ]
91
+ end]
92
+ else
93
+ Hash[stats.map do |res|
94
+ [
95
+ res.entity,
96
+ {
97
+ :sampleInfo => res.sampleInfo,
98
+ :metrics => Hash[res.value.map do |metric|
99
+ metric_name = perfcounter_idhash[metric.id.counterId].name
100
+ [[metric_name, metric.id.instance], metric.value]
101
+ end]
102
+ }
103
+ ]
104
+ end]
105
+ end
106
+ end
107
+
108
+
109
+ def active_intervals
110
+ intervals = historicalInterval
111
+ Hash[(1..4).map { |level| [level, intervals.select { |x| x.enabled && x.level >= level }] }]
112
+ end
113
+ end
@@ -0,0 +1,28 @@
1
+ # Copyright (c) 2011-2017 VMware, Inc. All Rights Reserved.
2
+ # SPDX-License-Identifier: MIT
3
+
4
+ class RbVmomi::VIM::PropertyCollector
5
+ def collectMultiple objs, *pathSet
6
+ return {} if objs.empty?
7
+
8
+ klasses = objs.map{|x| x.class}.uniq
9
+ klass = if klasses.length > 1
10
+ # common superclass
11
+ klasses.map(&:ancestors).inject(&:&)[0]
12
+ else
13
+ klasses.first
14
+ end
15
+
16
+ spec = {
17
+ :objectSet => objs.map{|x| { :obj => x }},
18
+ :propSet => [{
19
+ :pathSet => pathSet,
20
+ :type => klass.wsdl_name
21
+ }]
22
+ }
23
+ res = RetrieveProperties(:specSet => [spec])
24
+ Hash[res.map do |x|
25
+ [x.obj, x.to_hash]
26
+ end]
27
+ end
28
+ end
@@ -0,0 +1,33 @@
1
+ # Copyright (c) 2011-2017 VMware, Inc. All Rights Reserved.
2
+ # SPDX-License-Identifier: MIT
3
+
4
+ module RbVmomi
5
+
6
+ class VIM::ReflectManagedMethodExecuter
7
+ def fetch moid, prop
8
+ result = FetchSoap(:moid => moid, :version => 'urn:vim25/6.5', :prop => prop)
9
+ xml = Nokogiri(result.response)
10
+ _connection.deserializer.deserialize xml.root, nil
11
+ end
12
+
13
+ def execute moid, method, args
14
+ soap_args = args.map do |k,v|
15
+ VIM::ReflectManagedMethodExecuterSoapArgument.new.tap do |soap_arg|
16
+ soap_arg.name = k
17
+ xml = Builder::XmlMarkup.new :indent => 0
18
+ _connection.obj2xml xml, k, :anyType, false, v
19
+ soap_arg.val = xml.target!
20
+ end
21
+ end
22
+ result = ExecuteSoap(:moid => moid, :version => 'urn:vim25/6.5',
23
+ :method => method, :argument => soap_args)
24
+ if result
25
+ _connection.deserializer.deserialize Nokogiri(result.response).root, nil
26
+ else
27
+ nil
28
+ end
29
+ end
30
+ end
31
+
32
+ end
33
+
@@ -0,0 +1,58 @@
1
+ # Copyright (c) 2011-2017 VMware, Inc. All Rights Reserved.
2
+ # SPDX-License-Identifier: MIT
3
+
4
+ class RbVmomi::VIM::ResourcePool
5
+ # Retrieve a child ResourcePool.
6
+ # @param name [String] Name of the child.
7
+ # @return [VIM::ResourcePool]
8
+ def find name
9
+ _connection.searchIndex.FindChild(:entity => self, :name => name)
10
+ end
11
+
12
+ # Retrieve a descendant of this ResourcePool.
13
+ # @param path [String] Path delimited by '/'.
14
+ # @return [VIM::ResourcePool]
15
+ def traverse path
16
+ es = path.split('/').reject(&:empty?)
17
+ es.inject(self) do |f,e|
18
+ f.find(e) || return
19
+ end
20
+ end
21
+
22
+ def resourcePoolSubTree fields = []
23
+ self.class.resourcePoolSubTree [self], fields
24
+ end
25
+
26
+ def self.resourcePoolSubTree objs, fields = []
27
+ fields = (fields + ['name', 'resourcePool']).uniq
28
+ filterSpec = RbVmomi::VIM.PropertyFilterSpec(
29
+ :objectSet => objs.map do |obj|
30
+ RbVmomi::VIM.ObjectSpec(
31
+ :obj => obj,
32
+ :selectSet => [
33
+ RbVmomi::VIM.TraversalSpec(
34
+ :name => "tsRP",
35
+ :type => 'ResourcePool',
36
+ :path => 'resourcePool',
37
+ :skip => false,
38
+ :selectSet => [
39
+ RbVmomi::VIM.SelectionSpec(:name => "tsRP")
40
+ ]
41
+ )
42
+ ]
43
+ )
44
+ end,
45
+ :propSet => [{
46
+ :pathSet => fields,
47
+ :type => 'ResourcePool'
48
+ }]
49
+ )
50
+
51
+ propCollector = objs.first._connection.propertyCollector
52
+ result = propCollector.RetrieveProperties(:specSet => [filterSpec])
53
+
54
+ Hash[result.map do |x|
55
+ [x.obj, x.to_hash]
56
+ end]
57
+ end
58
+ end