rbvmomi 1.0.2 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.yardopts +5 -0
- data/README.rdoc +71 -0
- data/Rakefile +11 -0
- data/VERSION +1 -1
- data/devel/analyze-xml.rb +29 -29
- data/{test/test.rb → examples/create_vm.rb} +40 -15
- data/examples/extraConfig.rb +54 -0
- data/examples/power.rb +57 -0
- data/examples/readme-1.rb +35 -0
- data/examples/readme-2.rb +51 -0
- data/lib/rbvmomi.rb +3 -282
- data/lib/rbvmomi/{types.rb → basic_types.rb} +37 -97
- data/lib/rbvmomi/connection.rb +239 -0
- data/lib/rbvmomi/fault.rb +17 -0
- data/lib/{trivial_soap.rb → rbvmomi/trivial_soap.rb} +31 -13
- data/lib/rbvmomi/trollop.rb +6 -2
- data/lib/rbvmomi/type_loader.rb +72 -0
- data/lib/rbvmomi/vim.rb +76 -0
- data/lib/rbvmomi/vim/ComputeResource.rb +51 -0
- data/lib/rbvmomi/vim/Datacenter.rb +17 -0
- data/lib/rbvmomi/vim/Datastore.rb +68 -0
- data/lib/rbvmomi/vim/Folder.rb +112 -0
- data/lib/rbvmomi/vim/ManagedEntity.rb +46 -0
- data/lib/rbvmomi/vim/ManagedObject.rb +55 -0
- data/lib/rbvmomi/vim/ObjectContent.rb +23 -0
- data/lib/rbvmomi/vim/ObjectUpdate.rb +23 -0
- data/lib/rbvmomi/vim/OvfManager.rb +93 -0
- data/lib/rbvmomi/vim/ResourcePool.rb +18 -0
- data/lib/rbvmomi/vim/ServiceInstance.rb +53 -0
- data/lib/rbvmomi/vim/Task.rb +31 -0
- data/lib/rbvmomi/vim/VirtualMachine.rb +7 -0
- data/test/test_deserialization.rb +11 -55
- data/test/test_emit_request.rb +13 -10
- data/test/test_exceptions.rb +16 -0
- data/test/test_parse_response.rb +2 -10
- data/test/test_serialization.rb +14 -11
- metadata +41 -25
- data/.gitignore +0 -4
- data/README.md +0 -12
- data/lib/rbvmomi/extensions.rb +0 -491
- data/lib/rbvmomi/profile.rb +0 -22
- data/test/runner.rb +0 -3
@@ -0,0 +1,239 @@
|
|
1
|
+
# Copyright (c) 2010 VMware, Inc. All Rights Reserved.
|
2
|
+
require 'time'
|
3
|
+
require 'rbvmomi/trivial_soap'
|
4
|
+
require 'rbvmomi/basic_types'
|
5
|
+
require 'rbvmomi/fault'
|
6
|
+
require 'rbvmomi/type_loader'
|
7
|
+
|
8
|
+
module RbVmomi
|
9
|
+
|
10
|
+
class DeserializationFailed < Exception; end
|
11
|
+
|
12
|
+
class Connection < TrivialSoap
|
13
|
+
NS_XSI = 'http://www.w3.org/2001/XMLSchema-instance'
|
14
|
+
|
15
|
+
attr_accessor :rev
|
16
|
+
|
17
|
+
def initialize opts
|
18
|
+
@ns = opts[:ns] or fail "no namespace specified"
|
19
|
+
@rev = opts[:rev] or fail "no revision specified"
|
20
|
+
super opts
|
21
|
+
end
|
22
|
+
|
23
|
+
def emit_request xml, method, descs, this, params
|
24
|
+
xml.tag! method, :xmlns => @ns do
|
25
|
+
obj2xml xml, '_this', 'ManagedObject', false, this
|
26
|
+
descs.each do |d|
|
27
|
+
k = d['name'].to_sym
|
28
|
+
if params.member? k or params.member? k.to_s
|
29
|
+
v = params.member?(k) ? params[k] : params[k.to_s]
|
30
|
+
obj2xml xml, d['name'], d['wsdl_type'], d['is-array'], v
|
31
|
+
else
|
32
|
+
fail "missing required parameter #{d['name']}" unless d['is-optional']
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def parse_response resp, desc
|
39
|
+
if resp.at('faultcode')
|
40
|
+
detail = resp.at('detail')
|
41
|
+
fault = detail && xml2obj(detail.children.first, 'MethodFault')
|
42
|
+
msg = resp.at('faultstring').text
|
43
|
+
if fault
|
44
|
+
raise RbVmomi::Fault.new(msg, fault)
|
45
|
+
else
|
46
|
+
fail "#{resp.at('faultcode').text}: #{msg}"
|
47
|
+
end
|
48
|
+
else
|
49
|
+
if desc
|
50
|
+
type = desc['is-task'] ? 'Task' : desc['wsdl_type']
|
51
|
+
returnvals = resp.children.select(&:element?).map { |c| xml2obj c, type }
|
52
|
+
desc['is-array'] ? returnvals : returnvals.first
|
53
|
+
else
|
54
|
+
nil
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def call method, desc, this, params
|
60
|
+
fail "this is not a managed object" unless this.is_a? BasicTypes::ManagedObject
|
61
|
+
fail "parameters must be passed as a hash" unless params.is_a? Hash
|
62
|
+
fail unless desc.is_a? Hash
|
63
|
+
|
64
|
+
resp = request "#{@ns}/#{@rev}" do |xml|
|
65
|
+
emit_request xml, method, desc['params'], this, params
|
66
|
+
end
|
67
|
+
|
68
|
+
parse_response resp, desc['result']
|
69
|
+
end
|
70
|
+
|
71
|
+
def demangle_array_type x
|
72
|
+
case x
|
73
|
+
when 'AnyType' then 'anyType'
|
74
|
+
when 'DateTime' then 'dateTime'
|
75
|
+
when 'Boolean', 'String', 'Byte', 'Short', 'Int', 'Long', 'Float', 'Double' then x.downcase
|
76
|
+
else x
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def xml2obj xml, typename
|
81
|
+
typename = (xml.attribute_with_ns('type', NS_XSI) || typename).to_s
|
82
|
+
|
83
|
+
if typename =~ /^ArrayOf/
|
84
|
+
typename = demangle_array_type $'
|
85
|
+
return xml.children.select(&:element?).map { |c| xml2obj c, typename }
|
86
|
+
end
|
87
|
+
|
88
|
+
t = type typename
|
89
|
+
if t <= BasicTypes::DataObject
|
90
|
+
props_desc = t.full_props_desc
|
91
|
+
h = {}
|
92
|
+
props_desc.select { |d| d['is-array'] }.each { |d| h[d['name'].to_sym] = [] }
|
93
|
+
xml.children.each do |c|
|
94
|
+
next unless c.element?
|
95
|
+
field = c.name.to_sym
|
96
|
+
d = t.find_prop_desc(field.to_s) or next
|
97
|
+
o = xml2obj c, d['wsdl_type']
|
98
|
+
if h[field].is_a? Array
|
99
|
+
h[field] << o
|
100
|
+
else
|
101
|
+
h[field] = o
|
102
|
+
end
|
103
|
+
end
|
104
|
+
t.new h
|
105
|
+
elsif t == BasicTypes::ManagedObjectReference
|
106
|
+
type(xml['type']).new self, xml.text
|
107
|
+
elsif t <= BasicTypes::ManagedObject
|
108
|
+
type(xml['type'] || t.wsdl_name).new self, xml.text
|
109
|
+
elsif t <= BasicTypes::Enum
|
110
|
+
xml.text
|
111
|
+
elsif t <= String
|
112
|
+
xml.text
|
113
|
+
elsif t <= Symbol
|
114
|
+
xml.text.to_sym
|
115
|
+
elsif t <= Integer
|
116
|
+
xml.text.to_i
|
117
|
+
elsif t <= Float
|
118
|
+
xml.text.to_f
|
119
|
+
elsif t <= Time
|
120
|
+
Time.parse xml.text
|
121
|
+
elsif t == BasicTypes::Boolean
|
122
|
+
xml.text == 'true' || xml.text == '1'
|
123
|
+
elsif t == BasicTypes::Binary
|
124
|
+
xml.text.unpack('m')[0]
|
125
|
+
elsif t == BasicTypes::AnyType
|
126
|
+
fail "attempted to deserialize an AnyType"
|
127
|
+
else fail "unexpected type #{t.inspect}"
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# hic sunt dracones
|
132
|
+
def obj2xml xml, name, type, is_array, o, attrs={}
|
133
|
+
expected = type(type)
|
134
|
+
fail "expected array, got #{o.class.wsdl_name}" if is_array and not o.is_a? Array
|
135
|
+
case o
|
136
|
+
when Array
|
137
|
+
fail "expected #{expected.wsdl_name}, got array" unless is_array
|
138
|
+
o.each do |e|
|
139
|
+
obj2xml xml, name, expected.wsdl_name, false, e, attrs
|
140
|
+
end
|
141
|
+
when BasicTypes::ManagedObject
|
142
|
+
fail "expected #{expected.wsdl_name}, got #{o.class.wsdl_name} for field #{name.inspect}" if expected and not expected >= o.class
|
143
|
+
xml.tag! name, o._ref, :type => o.class.wsdl_name
|
144
|
+
when BasicTypes::DataObject
|
145
|
+
fail "expected #{expected.wsdl_name}, got #{o.class.wsdl_name} for field #{name.inspect}" if expected and not expected >= o.class
|
146
|
+
xml.tag! name, attrs.merge("xsi:type" => o.class.wsdl_name) do
|
147
|
+
o.class.full_props_desc.each do |desc|
|
148
|
+
if o.props.member? desc['name'].to_sym
|
149
|
+
v = o.props[desc['name'].to_sym]
|
150
|
+
next if v.nil?
|
151
|
+
obj2xml xml, desc['name'], desc['wsdl_type'], desc['is-array'], v
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
when BasicTypes::Enum
|
156
|
+
xml.tag! name, o.value.to_s, attrs
|
157
|
+
when Hash
|
158
|
+
fail "expected #{expected.wsdl_name}, got a hash" unless expected <= BasicTypes::DataObject
|
159
|
+
obj2xml xml, name, type, false, expected.new(o), attrs
|
160
|
+
when true, false
|
161
|
+
fail "expected #{expected.wsdl_name}, got a boolean" unless expected == BasicTypes::Boolean
|
162
|
+
attrs['xsi:type'] = 'xsd:boolean' if expected == BasicTypes::AnyType
|
163
|
+
xml.tag! name, (o ? '1' : '0'), attrs
|
164
|
+
when Symbol, String
|
165
|
+
if expected == BasicTypes::Binary
|
166
|
+
attrs['xsi:type'] = 'xsd:base64Binary' if expected == BasicTypes::AnyType
|
167
|
+
xml.tag! name, [o].pack('m').chomp, attrs
|
168
|
+
else
|
169
|
+
attrs['xsi:type'] = 'xsd:string' if expected == BasicTypes::AnyType
|
170
|
+
xml.tag! name, o.to_s, attrs
|
171
|
+
end
|
172
|
+
when Integer
|
173
|
+
attrs['xsi:type'] = 'xsd:long' if expected == BasicTypes::AnyType
|
174
|
+
xml.tag! name, o.to_s, attrs
|
175
|
+
when Float
|
176
|
+
attrs['xsi:type'] = 'xsd:double' if expected == BasicTypes::AnyType
|
177
|
+
xml.tag! name, o.to_s, attrs
|
178
|
+
when DateTime
|
179
|
+
attrs['xsi:type'] = 'xsd:dateTime' if expected == BasicTypes::AnyType
|
180
|
+
xml.tag! name, o.to_s, attrs
|
181
|
+
else fail "unexpected object class #{o.class}"
|
182
|
+
end
|
183
|
+
xml
|
184
|
+
end
|
185
|
+
|
186
|
+
def self.type name
|
187
|
+
fail unless name and (name.is_a? String or name.is_a? Symbol)
|
188
|
+
name = $' if name.to_s =~ /^xsd:/
|
189
|
+
case name.to_sym
|
190
|
+
when :anyType then BasicTypes::AnyType
|
191
|
+
when :boolean then BasicTypes::Boolean
|
192
|
+
when :string then String
|
193
|
+
when :int, :long, :short, :byte then Integer
|
194
|
+
when :float, :double then Float
|
195
|
+
when :dateTime then Time
|
196
|
+
when :base64Binary then BasicTypes::Binary
|
197
|
+
else
|
198
|
+
if @loader.has_type? name
|
199
|
+
const_get(name)
|
200
|
+
else
|
201
|
+
fail "no such type #{name.inspect}"
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
def type name
|
207
|
+
self.class.type name
|
208
|
+
end
|
209
|
+
|
210
|
+
def self.extension_path
|
211
|
+
fail "must be implemented in subclass"
|
212
|
+
end
|
213
|
+
|
214
|
+
protected
|
215
|
+
|
216
|
+
def self.const_missing sym
|
217
|
+
name = sym.to_s
|
218
|
+
if @loader and @loader.has_type? name
|
219
|
+
@loader.load_type name
|
220
|
+
const_get sym
|
221
|
+
else
|
222
|
+
super
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
def self.method_missing sym, *a
|
227
|
+
if @loader and @loader.has_type? sym.to_s
|
228
|
+
const_get(sym).new(*a)
|
229
|
+
else
|
230
|
+
super
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
def self.load_vmodl fn
|
235
|
+
@loader = RbVmomi::TypeLoader.new self, fn
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# Copyright (c) 2010 VMware, Inc. All Rights Reserved.
|
2
|
+
module RbVmomi
|
3
|
+
|
4
|
+
class Fault < StandardError
|
5
|
+
attr_reader :fault
|
6
|
+
|
7
|
+
def initialize msg, fault
|
8
|
+
super "#{fault.class.wsdl_name}: #{msg}"
|
9
|
+
@fault = fault
|
10
|
+
end
|
11
|
+
|
12
|
+
def method_missing *a
|
13
|
+
@fault.send(*a)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -4,18 +4,19 @@ require 'builder'
|
|
4
4
|
require 'nokogiri'
|
5
5
|
require 'net/http'
|
6
6
|
require 'pp'
|
7
|
-
require 'rbvmomi/profile'
|
8
7
|
|
9
|
-
|
10
|
-
|
8
|
+
module Net
|
9
|
+
class HTTPGenericRequest
|
10
|
+
alias old_exec exec
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
def exec sock, ver, path
|
13
|
+
old_exec sock, ver, path
|
14
|
+
sock.io.flush
|
15
|
+
end
|
15
16
|
end
|
16
17
|
end
|
17
18
|
|
18
|
-
class TrivialSoap
|
19
|
+
class RbVmomi::TrivialSoap
|
19
20
|
attr_accessor :debug, :cookie
|
20
21
|
attr_reader :http
|
21
22
|
|
@@ -23,21 +24,31 @@ class TrivialSoap
|
|
23
24
|
fail unless opts.is_a? Hash
|
24
25
|
@opts = opts
|
25
26
|
return unless @opts[:host] # for testcases
|
27
|
+
@debug = @opts[:debug]
|
28
|
+
@cookie = nil
|
29
|
+
@lock = Mutex.new
|
30
|
+
@http = nil
|
31
|
+
restart_http
|
32
|
+
end
|
33
|
+
|
34
|
+
def restart_http
|
35
|
+
@http.finish if @http
|
26
36
|
@http = Net::HTTP.new(@opts[:host], @opts[:port], @opts[:proxyHost], @opts[:proxyPort])
|
27
37
|
if @opts[:ssl]
|
28
38
|
require 'net/https'
|
29
39
|
@http.use_ssl = true
|
30
|
-
@
|
40
|
+
if @opts[:insecure]
|
41
|
+
@http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
42
|
+
else
|
43
|
+
@http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
44
|
+
end
|
31
45
|
@http.cert = OpenSSL::X509::Certificate.new(@opts[:cert]) if @opts[:cert]
|
32
46
|
@http.key = OpenSSL::PKey::RSA.new(@opts[:key]) if @opts[:key]
|
33
47
|
end
|
34
48
|
@http.set_debug_output(STDERR) if $DEBUG
|
35
|
-
@http.read_timeout =
|
49
|
+
@http.read_timeout = 1000000000
|
36
50
|
@http.open_timeout = 5
|
37
51
|
@http.start
|
38
|
-
@debug = @opts[:debug]
|
39
|
-
@cookie = nil
|
40
|
-
@lock = Mutex.new
|
41
52
|
end
|
42
53
|
|
43
54
|
def soap_envelope
|
@@ -65,7 +76,14 @@ class TrivialSoap
|
|
65
76
|
end
|
66
77
|
|
67
78
|
start_time = Time.now
|
68
|
-
response = @lock.synchronize
|
79
|
+
response = @lock.synchronize do
|
80
|
+
begin
|
81
|
+
@http.request_post(@opts[:path], body, headers)
|
82
|
+
rescue Exception
|
83
|
+
restart_http
|
84
|
+
raise
|
85
|
+
end
|
86
|
+
end
|
69
87
|
end_time = Time.now
|
70
88
|
|
71
89
|
@cookie = response['set-cookie'] if response.key? 'set-cookie'
|
data/lib/rbvmomi/trollop.rb
CHANGED
@@ -1,10 +1,13 @@
|
|
1
|
+
# Copyright (c) 2011 VMware, Inc. All Rights Reserved.
|
1
2
|
require 'trollop'
|
2
3
|
|
3
|
-
|
4
|
+
module Trollop
|
5
|
+
class Parser
|
4
6
|
def rbvmomi_connection_opts
|
5
7
|
opt :host, "host", type: :string, short: 'o', default: ENV['RBVMOMI_HOST']
|
6
8
|
opt :port, "port", type: :int, short: :none, default: (ENV.member?('RBVMOMI_PORT') ? ENV['RBVMOMI_PORT'].to_i : 443)
|
7
9
|
opt :"no-ssl", "don't use ssl", short: :none, default: (ENV['RBVMOMI_SSL'] == '0')
|
10
|
+
opt :insecure, "don't verify ssl certificate", short: 'k', default: (ENV['RBVMOMI_INSECURE'] == '1')
|
8
11
|
opt :user, "username", short: 'u', default: (ENV['RBVMOMI_USER'] || 'root')
|
9
12
|
opt :password, "password", short: 'p', default: (ENV['RBVMOMI_PASSWORD'] || '')
|
10
13
|
opt :path, "SOAP endpoint path", short: :none, default: (ENV['RBVMOMI_PATH'] || '/sdk')
|
@@ -12,7 +15,7 @@ class Trollop::Parser
|
|
12
15
|
end
|
13
16
|
|
14
17
|
def rbvmomi_datacenter_opt
|
15
|
-
opt :datacenter, "datacenter", type: :string, short: "D", default: (ENV['RBVMOMI_DATACENTER'])
|
18
|
+
opt :datacenter, "datacenter", type: :string, short: "D", default: (ENV['RBVMOMI_DATACENTER'] || 'ha-datacenter')
|
16
19
|
end
|
17
20
|
|
18
21
|
def rbvmomi_folder_opt
|
@@ -27,3 +30,4 @@ class Trollop::Parser
|
|
27
30
|
opt :datastore, "Datastore", short: 's', default: (ENV['RBVMOMI_DATASTORE'] || 'datastore1')
|
28
31
|
end
|
29
32
|
end
|
33
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# Copyright (c) 2010 VMware, Inc. All Rights Reserved.
|
2
|
+
require 'cdb'
|
3
|
+
require 'set'
|
4
|
+
|
5
|
+
module RbVmomi
|
6
|
+
|
7
|
+
class TypeLoader
|
8
|
+
def initialize target, fn
|
9
|
+
@target = target
|
10
|
+
@db = CDB.new fn
|
11
|
+
@vmodl = Hash.new { |h,k| if e = @db[k] then h[k] = Marshal.load(e) end }
|
12
|
+
@typenames = Set.new(Marshal.load(@db['_typenames']) + BasicTypes::BUILTIN)
|
13
|
+
@target.constants.select { |x| has_type? x.to_s }.each { |x| load_type x.to_s }
|
14
|
+
BasicTypes::BUILTIN.each do |x|
|
15
|
+
target.const_set x, BasicTypes.const_get(x)
|
16
|
+
load_extension x
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def has_type? name
|
21
|
+
fail unless name.is_a? String
|
22
|
+
@typenames.member? name
|
23
|
+
end
|
24
|
+
|
25
|
+
def load_type name
|
26
|
+
fail unless name.is_a? String
|
27
|
+
@target.const_set name, make_type(name)
|
28
|
+
load_extension name
|
29
|
+
nil
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def load_extension name
|
35
|
+
path = @target.extension_path name
|
36
|
+
load path if File.exists? path
|
37
|
+
end
|
38
|
+
|
39
|
+
def make_type name
|
40
|
+
name = name.to_s
|
41
|
+
fail if BasicTypes::BUILTIN.member? name
|
42
|
+
desc = @vmodl[name] or fail "unknown VMODL type #{name}"
|
43
|
+
case desc['kind']
|
44
|
+
when 'data' then make_data_type name, desc
|
45
|
+
when 'managed' then make_managed_type name, desc
|
46
|
+
when 'enum' then make_enum_type name, desc
|
47
|
+
else fail desc.inspect
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def make_data_type name, desc
|
52
|
+
superclass = @target.const_get desc['wsdl_base']
|
53
|
+
Class.new(superclass).tap do |klass|
|
54
|
+
klass.init name, desc['props']
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def make_managed_type name, desc
|
59
|
+
superclass = @target.const_get desc['wsdl_base']
|
60
|
+
Class.new(superclass).tap do |klass|
|
61
|
+
klass.init name, desc['props'], desc['methods']
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def make_enum_type name, desc
|
66
|
+
Class.new(BasicTypes::Enum).tap do |klass|
|
67
|
+
klass.init name, desc['values']
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
data/lib/rbvmomi/vim.rb
ADDED
@@ -0,0 +1,76 @@
|
|
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] :user (root) Username.
|
17
|
+
# @option opts [String] :password Password.
|
18
|
+
# @option opts [String] :path (/sdk) SDK endpoint path.
|
19
|
+
# @option opts [Boolean] :debug (false) If true, print SOAP traffic to stderr.
|
20
|
+
def self.connect opts
|
21
|
+
fail unless opts.is_a? Hash
|
22
|
+
fail "host option required" unless opts[:host]
|
23
|
+
opts[:user] ||= 'root'
|
24
|
+
opts[:password] ||= ''
|
25
|
+
opts[:ssl] = true unless opts.member? :ssl
|
26
|
+
opts[:insecure] ||= false
|
27
|
+
opts[:port] ||= (opts[:ssl] ? 443 : 80)
|
28
|
+
opts[:path] ||= '/sdk'
|
29
|
+
opts[:ns] ||= 'urn:vim25'
|
30
|
+
opts[:rev] = '4.1'
|
31
|
+
opts[:debug] = (!ENV['RBVMOMI_DEBUG'].empty? rescue false) unless opts.member? :debug
|
32
|
+
|
33
|
+
new(opts).tap do |vim|
|
34
|
+
vim.serviceContent.sessionManager.Login :userName => opts[:user], :password => opts[:password]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Return the ServiceInstance
|
39
|
+
#
|
40
|
+
# The ServiceInstance is the root of the vSphere inventory.
|
41
|
+
# @see http://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/vim.ServiceInstance.html
|
42
|
+
def serviceInstance
|
43
|
+
VIM::ServiceInstance self, 'ServiceInstance'
|
44
|
+
end
|
45
|
+
|
46
|
+
# Alias to serviceInstance.RetrieveServiceContent
|
47
|
+
def serviceContent
|
48
|
+
@serviceContent ||= serviceInstance.RetrieveServiceContent
|
49
|
+
end
|
50
|
+
|
51
|
+
# Alias to serviceContent.rootFolder
|
52
|
+
def rootFolder
|
53
|
+
serviceContent.rootFolder
|
54
|
+
end
|
55
|
+
|
56
|
+
alias root rootFolder
|
57
|
+
|
58
|
+
# Alias to serviceContent.propertyCollector
|
59
|
+
def propertyCollector
|
60
|
+
serviceContent.propertyCollector
|
61
|
+
end
|
62
|
+
|
63
|
+
# Alias to serviceContent.searchIndex
|
64
|
+
def searchIndex
|
65
|
+
serviceContent.searchIndex
|
66
|
+
end
|
67
|
+
|
68
|
+
# @private
|
69
|
+
def self.extension_path name
|
70
|
+
File.join(File.dirname(__FILE__), "vim", "#{name}.rb")
|
71
|
+
end
|
72
|
+
|
73
|
+
load_vmodl(ENV['VMODL'] || File.join(File.dirname(__FILE__), "../../vmodl.cdb"))
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|