rbvmomi 1.3.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.3.0
1
+ 1.4.0
data/bin/rbvmomish CHANGED
@@ -17,6 +17,7 @@ Usage:
17
17
  rbvmomish [options]
18
18
 
19
19
  Predefined methods:
20
+ conn: Returns the VIM connection
20
21
  si: Returns the ServiceInstance
21
22
  help: Displays this text.
22
23
 
@@ -92,6 +93,10 @@ def cookie str
92
93
  $vim.cookie = str
93
94
  end
94
95
 
96
+ def conn
97
+ $vim
98
+ end
99
+
95
100
  def si
96
101
  $vim.serviceInstance
97
102
  end
@@ -0,0 +1,52 @@
1
+ #!/usr/bin/env ruby
2
+ # These types are not public and so may change between releases. Do not
3
+ # use them directly.
4
+
5
+ public_vmodl_filename = ARGV[0] or abort "public vmodl filename required"
6
+ internal_vmodl_filename = ARGV[1] or abort "internal vmodl filename required"
7
+ output_vmodl_filename = ARGV[2] or abort "output vmodl filename required"
8
+
9
+ TYPES = %w(
10
+ DynamicTypeEnumTypeInfo
11
+ DynamicTypeMgrAllTypeInfo
12
+ DynamicTypeMgrAnnotation
13
+ DynamicTypeMgrDataTypeInfo
14
+ DynamicTypeMgrFilterSpec
15
+ DynamicTypeMgrManagedTypeInfo
16
+ DynamicTypeMgrMethodTypeInfo
17
+ DynamicTypeMgrMethodTypeInfoAnnotationType
18
+ DynamicTypeMgrMoFilterSpec
19
+ DynamicTypeMgrMoInstance
20
+ DynamicTypeMgrParamTypeInfo
21
+ DynamicTypeMgrParamTypeInfoAnnotationType
22
+ DynamicTypeMgrPropertyTypeInfo
23
+ DynamicTypeMgrPropertyTypeInfoAnnotationType
24
+ DynamicTypeMgrTypeFilterSpec
25
+ InternalDynamicTypeManager
26
+ ReflectManagedMethodExecuter
27
+ ReflectManagedMethodExecuterSoapArgument
28
+ ReflectManagedMethodExecuterSoapFault
29
+ ReflectManagedMethodExecuterSoapResult
30
+ )
31
+
32
+ METHODS = %w(
33
+ HostSystem.RetrieveDynamicTypeManager
34
+ HostSystem.RetrieveManagedMethodExecuter
35
+ )
36
+
37
+ public_vmodl = File.open(public_vmodl_filename, 'r') { |io| Marshal.load io }
38
+ internal_vmodl = File.open(internal_vmodl_filename, 'r') { |io| Marshal.load io }
39
+
40
+ TYPES.each do |k|
41
+ puts "Merging in #{k}"
42
+ fail unless internal_vmodl.member? k
43
+ public_vmodl[k] = internal_vmodl[k]
44
+ end
45
+
46
+ METHODS.each do |x|
47
+ puts "Merging in #{x}"
48
+ type, method = x.split '.'
49
+ public_vmodl[type]['methods'][method] = internal_vmodl[type]['methods'][method] or fail
50
+ end
51
+
52
+ File.open(output_vmodl_filename, 'w') { |io| Marshal.dump public_vmodl, io }
@@ -4,7 +4,7 @@ require 'pp'
4
4
  module RbVmomi
5
5
  module BasicTypes
6
6
 
7
- BUILTIN = %w(ManagedObject DataObject TypeName PropertyPath ManagedObjectReference MethodName MethodFault LocalizedMethodFault)
7
+ BUILTIN = %w(ManagedObject DataObject TypeName PropertyPath ManagedObjectReference MethodName MethodFault LocalizedMethodFault KeyValue)
8
8
 
9
9
  class Base
10
10
  class << self
@@ -36,9 +36,8 @@ class ObjectWithProperties < Base
36
36
  end
37
37
  end
38
38
 
39
- # XXX cache
40
39
  def full_props_desc
41
- (self == ObjectWithProperties ? [] : superclass.full_props_desc) + props_desc
40
+ @full_props_desc ||= (self == ObjectWithProperties ? [] : superclass.full_props_desc) + props_desc
42
41
  end
43
42
 
44
43
  def find_prop_desc name
@@ -121,6 +120,8 @@ class DataObject < ObjectWithProperties
121
120
  keys.all? { |k| props[k] == o.props[k] }
122
121
  end
123
122
 
123
+ alias eql? ==
124
+
124
125
  def hash
125
126
  props.hash
126
127
  end
@@ -318,5 +319,23 @@ class ::Float
318
319
  def self.wsdl_name; 'xsd:float' end
319
320
  end
320
321
 
322
+ class KeyValue
323
+ def self.wsdl_name; 'xsd:float' end
324
+ attr_accessor :key, :value
325
+
326
+ def initialize k, v
327
+ @key = k
328
+ @value = v
329
+ end
330
+
331
+ def [] i
332
+ if i == 0 then @key
333
+ elsif i == 1 then @value
334
+ else fail "invalid index #{i.inspect}"
335
+ end
336
+ end
337
+ end
338
+
339
+
321
340
  end
322
341
  end
@@ -118,6 +118,13 @@ class Connection < TrivialSoap
118
118
  type(xml['type'] || t.wsdl_name).new self, xml.text
119
119
  elsif t <= BasicTypes::Enum
120
120
  xml.text
121
+ elsif t <= BasicTypes::KeyValue
122
+ h = {}
123
+ xml.children.each do |c|
124
+ next unless c.element?
125
+ h[c.name] = c.text
126
+ end
127
+ [h['key'], h['value']]
121
128
  elsif t <= String
122
129
  xml.text
123
130
  elsif t <= Symbol
@@ -136,6 +143,10 @@ class Connection < TrivialSoap
136
143
  fail "attempted to deserialize an AnyType"
137
144
  else fail "unexpected type #{t.inspect}"
138
145
  end
146
+ rescue
147
+ $stderr.puts "#{$!.class} while deserializing #{xml.name} (#{typename}):"
148
+ $stderr.puts xml.to_s
149
+ raise
139
150
  end
140
151
 
141
152
  # hic sunt dracones
@@ -143,10 +154,19 @@ class Connection < TrivialSoap
143
154
  expected = type(type)
144
155
  fail "expected array, got #{o.class.wsdl_name}" if is_array and not o.is_a? Array
145
156
  case o
146
- when Array
147
- fail "expected #{expected.wsdl_name}, got array" unless is_array
148
- o.each do |e|
149
- obj2xml xml, name, expected.wsdl_name, false, e, attrs
157
+ when Array, BasicTypes::KeyValue
158
+ if o.is_a? BasicTypes::KeyValue and expected != BasicTypes::KeyValue
159
+ fail "expected #{expected.wsdl_name}, got KeyValue"
160
+ elsif expected == BasicTypes::KeyValue
161
+ xml.tag! name, attrs do
162
+ xml.tag! 'key', o[0]
163
+ xml.tag! 'value', o[1]
164
+ end
165
+ else
166
+ fail "expected #{expected.wsdl_name}, got array" unless is_array
167
+ o.each do |e|
168
+ obj2xml xml, name, expected.wsdl_name, false, e, attrs
169
+ end
150
170
  end
151
171
  when BasicTypes::ManagedObject
152
172
  fail "expected #{expected.wsdl_name}, got #{o.class.wsdl_name} for field #{name.inspect}" if expected and not expected >= o.class
@@ -168,7 +188,7 @@ class Connection < TrivialSoap
168
188
  fail "expected #{expected.wsdl_name}, got a hash" unless expected <= BasicTypes::DataObject
169
189
  obj2xml xml, name, type, false, expected.new(o), attrs
170
190
  when true, false
171
- fail "expected #{expected.wsdl_name}, got a boolean" unless expected == BasicTypes::Boolean
191
+ fail "expected #{expected.wsdl_name}, got a boolean" unless [BasicTypes::Boolean, BasicTypes::AnyType].member? expected
172
192
  attrs['xsi:type'] = 'xsd:boolean' if expected == BasicTypes::AnyType
173
193
  xml.tag! name, (o ? '1' : '0'), attrs
174
194
  when Symbol, String
@@ -191,6 +211,10 @@ class Connection < TrivialSoap
191
211
  else fail "unexpected object class #{o.class}"
192
212
  end
193
213
  xml
214
+ rescue
215
+ $stderr.puts "#{$!.class} while serializing #{name} (#{type}):"
216
+ PP.pp o, $stderr
217
+ raise
194
218
  end
195
219
 
196
220
  def self.type name
@@ -204,6 +228,7 @@ class Connection < TrivialSoap
204
228
  when :float, :double then Float
205
229
  when :dateTime then Time
206
230
  when :base64Binary then BasicTypes::Binary
231
+ when :KeyValue then BasicTypes::KeyValue
207
232
  else
208
233
  if @loader.has_type? name
209
234
  const_get(name)
@@ -4,29 +4,19 @@ require 'monitor'
4
4
 
5
5
  module RbVmomi
6
6
 
7
- class TypeStore
8
- def initialize fn
9
- File.open(fn, 'r') do |io|
10
- @db = Marshal.load io
11
- end
12
- end
13
-
14
- def [](k)
15
- @db[k]
16
- end
17
- end
18
-
19
7
  class TypeLoader
20
- attr_reader :typenames
21
-
22
8
  def initialize target, fn
23
9
  @target = target
24
- @db = TypeStore.new fn
25
10
  @lock = Monitor.new
11
+ @db = {}
12
+ @id2wsdl = {}
13
+ add_types Hash[BasicTypes::BUILTIN.map { |k| [k,nil] }]
14
+ vmodl_database = File.open(fn, 'r') { |io| Marshal.load io }
15
+ vmodl_database.reject! { |k,v| k =~ /^_/ }
16
+ add_types vmodl_database
26
17
  end
27
18
 
28
19
  def init
29
- @typenames = Set.new(@db['_typenames'] + BasicTypes::BUILTIN)
30
20
  @target.constants.select { |x| has_type? x.to_s }.each { |x| load_type x.to_s }
31
21
  BasicTypes::BUILTIN.each do |x|
32
22
  @target.const_set x, BasicTypes.const_get(x)
@@ -39,7 +29,7 @@ class TypeLoader
39
29
 
40
30
  def has_type? name
41
31
  fail unless name.is_a? String
42
- @typenames.member? name
32
+ @db.member? name
43
33
  end
44
34
 
45
35
  def load_type name
@@ -51,6 +41,16 @@ class TypeLoader
51
41
  nil
52
42
  end
53
43
 
44
+ def add_types types
45
+ @lock.synchronize do
46
+ @db.merge! types
47
+ end
48
+ end
49
+
50
+ def typenames
51
+ @db.keys
52
+ end
53
+
54
54
  private
55
55
 
56
56
  def load_extension name
@@ -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,162 @@
1
+ module RbVmomi
2
+
3
+ class VIM::HostSystem
4
+ def esxcli
5
+ @cached_esxcli ||= VIM::EsxcliNamespace.root(self)
6
+ end
7
+
8
+ def dtm
9
+ @cached_dtm ||= RetrieveDynamicTypeManager()
10
+ end
11
+
12
+ def dti
13
+ @cached_dti ||= dtm.DynamicTypeMgrQueryTypeInfo
14
+ end
15
+
16
+ def create_dynamic_managed_object inst
17
+ wsdlName = dti.managedTypeInfo.find { |x| x.name == inst.moType }.wsdlName
18
+ _connection.type(wsdlName).new(_connection, inst.id)
19
+ end
20
+
21
+ def cli_info_fetcher
22
+ # XXX there can be more than one
23
+ return @cached_cli_info_fetcher if @cached_cli_info_fetcher
24
+ inst = dtm.DynamicTypeMgrQueryMoInstances.find { |x| x.moType == 'vim.CLIInfo' }
25
+ @cached_cli_info_fetcher = create_dynamic_managed_object inst
26
+ end
27
+
28
+ def mme
29
+ @cached_mme ||= RetrieveManagedMethodExecuter()
30
+ end
31
+
32
+ def direct?
33
+ @ref == 'ha-host'
34
+ end
35
+ end
36
+
37
+ class VIM::EsxcliNamespace
38
+ ESXCLI_PREFIX = 'vim.EsxCLI.'
39
+
40
+ attr_reader :name, :parent, :host, :type, :instance, :type_info, :namespaces, :commands
41
+
42
+ def self.root host
43
+ type_hash = host.dti.toRbvmomiTypeHash
44
+ VIM.loader.add_types type_hash
45
+ all_instances = host.dtm.DynamicTypeMgrQueryMoInstances
46
+ instances = Hash[all_instances.select { |x| x.moType.start_with? ESXCLI_PREFIX }.
47
+ map { |x| [x.moType,x.id] }]
48
+ type_infos = Hash[host.dti.managedTypeInfo.map { |x| [x.name,x] }]
49
+ new('root', nil, host).tap do |root|
50
+ instances.each do |type,instance|
51
+ path = type.split('.')[2..-1]
52
+ ns = path.inject(root) { |b,v| b.namespaces[v] }
53
+ ns.realize type, instance, type_infos[type]
54
+ end
55
+ end
56
+ end
57
+
58
+ def initialize name, parent, host
59
+ @name = name
60
+ @parent = parent
61
+ @host = host
62
+ @type = nil
63
+ @instance = nil
64
+ @type_info = nil
65
+ @namespaces = Hash.new { |h,k| h[k] = self.class.new k, self, host }
66
+ @commands = {}
67
+ @cached_cli_info = nil
68
+ end
69
+
70
+ def realize type, instance, type_info
71
+ fail if @type or @instance
72
+ @type = type
73
+ @instance = instance
74
+ @type_info = type_info
75
+ @type_info.method.each do |method_type_info|
76
+ name = method_type_info.name
77
+ @commands[name] = VIM::EsxcliCommand.new self, method_type_info
78
+ end
79
+ end
80
+
81
+ def type_name
82
+ if @type then @type
83
+ elsif @parent then "#{@parent.type_name}.#{@name}"
84
+ else 'vim.EsxCLI'
85
+ end
86
+ end
87
+
88
+ def cli_info
89
+ @cached_cli_info ||=
90
+ if @host.direct?
91
+ @host.cli_info_fetcher.VimCLIInfoFetchCLIInfo(:typeName => type_name)
92
+ else
93
+ @host.mme.execute(@host.cli_info_fetcher._ref,
94
+ "vim.CLIInfo.FetchCLIInfo", :typeName => type_name)
95
+ end
96
+ end
97
+
98
+ def obj
99
+ conn = @host._connection
100
+ conn.type(@type_info.wsdlName).new(conn, @instance)
101
+ end
102
+
103
+ def method_missing name, *args
104
+ name = name.to_s
105
+ if @namespaces.member? name and args.empty?
106
+ @namespaces[name]
107
+ elsif @commands.member? name
108
+ @commands[name].call *args
109
+ else
110
+ raise NoMethodError
111
+ end
112
+ end
113
+
114
+ def pretty_print q
115
+ q.text @name
116
+ q.text ' '
117
+ q.group 2 do
118
+ q.text '{'
119
+ q.breakable
120
+ items = (@namespaces.values+@commands.values).sort_by(&:name)
121
+ q.seplist items, nil, :each do |v|
122
+ if v.is_a? VIM::EsxcliNamespace
123
+ q.pp v
124
+ else
125
+ q.text v.name
126
+ end
127
+ end
128
+ end
129
+ q.breakable
130
+ q.text '}'
131
+ end
132
+ end
133
+
134
+ class VIM::EsxcliCommand
135
+ attr_reader :ns, :type_info, :cli_info
136
+
137
+ def initialize ns, type_info
138
+ @ns = ns
139
+ @type_info = type_info
140
+ @cached_cli_info = nil
141
+ end
142
+
143
+ def name
144
+ @type_info.name
145
+ end
146
+
147
+ def cli_info
148
+ @cached_cli_info ||= @ns.cli_info.method.find { |x| x.name == @type_info.name }
149
+ end
150
+
151
+ def call args={}
152
+ if @ns.host.direct?
153
+ @ns.obj._call @type_info.wsdlName, args
154
+ else
155
+ real_args = Set.new(type_info.paramTypeInfo.map(&:name))
156
+ args = args.reject { |k,v| !real_args.member?(k.to_s) }
157
+ @ns.host.mme.execute(@ns.obj._ref, "#{@ns.type_name}.#{@type_info.name}", args)
158
+ end
159
+ end
160
+ end
161
+
162
+ end
@@ -0,0 +1,26 @@
1
+ module RbVmomi
2
+
3
+ class VIM::ReflectManagedMethodExecuter
4
+ def fetch moid, prop
5
+ result = FetchSoap(:moid => moid, :version => 'urn:vim25/5.0', :prop => prop)
6
+ xml = Nokogiri(result.response)
7
+ _connection.xml2obj xml.root, nil
8
+ end
9
+
10
+ def execute moid, method, args
11
+ soap_args = args.map do |k,v|
12
+ VIM::ReflectManagedMethodExecuterSoapArgument.new.tap do |soap_arg|
13
+ soap_arg.name = k
14
+ xml = Builder::XmlMarkup.new :indent => 0
15
+ _connection.obj2xml xml, k, :anyType, false, v
16
+ soap_arg.val = xml.target!
17
+ end
18
+ end
19
+ result = ExecuteSoap(:moid => moid, :version => 'urn:vim25/5.0',
20
+ :method => method, :argument => soap_args)
21
+ _connection.xml2obj Nokogiri(result.response).root, nil
22
+ end
23
+ end
24
+
25
+ end
26
+
@@ -282,4 +282,14 @@ end
282
282
  </val>
283
283
  EOS
284
284
  end
285
+
286
+ def test_keyvalue
287
+ obj = ['a', 'b']
288
+ check <<-EOS, obj, 'KeyValue'
289
+ <root>
290
+ <key>a</key>
291
+ <value>b</value>
292
+ </root>
293
+ EOS
294
+ end
285
295
  end
@@ -208,4 +208,22 @@ class SerializationTest < Test::Unit::TestCase
208
208
  EOS
209
209
 
210
210
  end
211
+
212
+ def test_keyvalue
213
+ obj = RbVmomi::BasicTypes::KeyValue.new('a', 'b')
214
+ check <<-EOS, obj, 'KeyValue', false
215
+ <root>
216
+ <key>a</key>
217
+ <value>b</value>
218
+ </root>
219
+ EOS
220
+
221
+ obj = ['a', 'b']
222
+ check <<-EOS, obj, 'KeyValue', false
223
+ <root>
224
+ <key>a</key>
225
+ <value>b</value>
226
+ </root>
227
+ EOS
228
+ end
211
229
  end
data/vmodl.db CHANGED
Binary file
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: rbvmomi
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 1.3.0
5
+ version: 1.4.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Rich Lane
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-09-02 00:00:00 -07:00
13
+ date: 2011-10-19 00:00:00 -07:00
14
14
  default_executable: rbvmomish
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -54,7 +54,6 @@ extensions: []
54
54
 
55
55
  extra_rdoc_files:
56
56
  - LICENSE
57
- - README.html
58
57
  - README.rdoc
59
58
  files:
60
59
  - .yardopts
@@ -65,6 +64,7 @@ files:
65
64
  - bin/rbvmomish
66
65
  - devel/analyze-vim-declarations.rb
67
66
  - devel/analyze-xml.rb
67
+ - devel/merge-internal-vmodl.rb
68
68
  - examples/annotate.rb
69
69
  - examples/clone_vm.rb
70
70
  - examples/create_vm-1.9.rb
@@ -91,13 +91,18 @@ files:
91
91
  - lib/rbvmomi/vim/ComputeResource.rb
92
92
  - lib/rbvmomi/vim/Datacenter.rb
93
93
  - lib/rbvmomi/vim/Datastore.rb
94
+ - lib/rbvmomi/vim/DynamicTypeMgrAllTypeInfo.rb
95
+ - lib/rbvmomi/vim/DynamicTypeMgrDataTypeInfo.rb
96
+ - lib/rbvmomi/vim/DynamicTypeMgrManagedTypeInfo.rb
94
97
  - lib/rbvmomi/vim/Folder.rb
98
+ - lib/rbvmomi/vim/HostSystem.rb
95
99
  - lib/rbvmomi/vim/ManagedEntity.rb
96
100
  - lib/rbvmomi/vim/ManagedObject.rb
97
101
  - lib/rbvmomi/vim/ObjectContent.rb
98
102
  - lib/rbvmomi/vim/ObjectUpdate.rb
99
103
  - lib/rbvmomi/vim/OvfManager.rb
100
104
  - lib/rbvmomi/vim/PropertyCollector.rb
105
+ - lib/rbvmomi/vim/ReflectManagedMethodExecuter.rb
101
106
  - lib/rbvmomi/vim/ResourcePool.rb
102
107
  - lib/rbvmomi/vim/ServiceInstance.rb
103
108
  - lib/rbvmomi/vim/Task.rb
@@ -109,7 +114,6 @@ files:
109
114
  - test/test_parse_response.rb
110
115
  - test/test_serialization.rb
111
116
  - vmodl.db
112
- - README.html
113
117
  has_rdoc: true
114
118
  homepage: https://github.com/rlane/rbvmomi
115
119
  licenses: []
data/README.html DELETED
@@ -1,76 +0,0 @@
1
- <h1>RbVmomi</h1>
2
-
3
- <h2>Introduction</h2>
4
-
5
- <p>RbVmomi is a Ruby interface to the vSphere API. Like the Perl and Java SDKs,
6
- you can use it to manage ESX and VirtualCenter servers. The current release
7
- supports the vSphere 4.1 API.</p>
8
-
9
- <h2>Usage</h2>
10
-
11
- <p>A simple example of turning on a VM:</p>
12
-
13
- <pre><code>require 'rbvmomi'
14
- conn = RbVmomi.connect host: 'foo', user: 'bar', password: 'baz'
15
- dc = conn.serviceInstance.find_datacenter("mydatacenter") or fail "datacenter not found"
16
- vm = dc.find_vm("myvm") or fail "VM not found"
17
- vm.PowerOn_Task.wait_for_completion
18
- </code></pre>
19
-
20
- <p>This code uses several RbVmomi extensions to the VI API for concision. The
21
- expanded snippet below uses only standard API calls and should be familiar to
22
- users of the Java SDK:</p>
23
-
24
- <pre><code>require 'rbvmomi'
25
- conn = RbVmomi.connect host: 'foo', user: 'bar', password: 'baz'
26
- rootFolder = conn.serviceInstance.content.rootFolder
27
- dc = rootFolder.childEntity.grep(RbVmomi::VIM::Datacenter).find { |x| x.name == "mydatacenter" } or fail "datacenter not found"
28
- vm = dc.vmFolder.childEntity.grep(RbVmomi::VIM::VirtualMachine).find { |x| x.name == "myvm" } or fail "VM not found"
29
- task = vm.PowerOn_Task
30
- filter = conn.propertyCollector.CreateFilter(
31
- spec: {
32
- propSet: [{ type =&gt; 'Task', all: false, pathSet: ['info.state']}],
33
- objectSet: [{ obj: task }]
34
- },
35
- partialUpdates: false
36
- )
37
- ver = ''
38
- while true
39
- result = conn.propertyCollector.WaitForUpdates(version: ver)
40
- ver = result.version
41
- break if ['success', ['error'].member? task.info.state
42
- end
43
- filter.DestroyPropertyFilter
44
- raise task.info.error if task.info.state == 'error'
45
- </code></pre>
46
-
47
- <p>As you can see, the extensions RbVmomi adds can dramatically decrease the code
48
- needed to perform simple tasks while still letting you use the full power of
49
- the API when necessary. RbVmomi extensions are often more efficient than a
50
- naive implementation; for example, the find_vm method on VIM::Datacenter used
51
- in the first example uses the SearchIndex for fast lookups.</p>
52
-
53
- <p>A few important points:</p>
54
-
55
- <ul>
56
- <li>Ruby 1.9 is required.</li>
57
- <li>Properties are exposed as methods: vm.summary</li>
58
- <li>All class, method, parameter, and property names match the <a href="http://www.vmware.com/support/developer/vc-sdk/visdk41pubs/ApiReference/index.html">official documentation</a>.</li>
59
- <li>Data object types can usually be inferred from context, so you may simply use a hash instead.</li>
60
- <li>Enumeration values are simply strings.</li>
61
- <li>Example code is included in the examples/ directory.</li>
62
- <li>A set of helper methods for Trollop is included to speed up development of
63
- command line apps. See the included examples for usage.</li>
64
- <li>This is a side project of a VMware developer and is entirely unsupported by VMware.</li>
65
- </ul>
66
-
67
- <p>Built-in extensions are in lib/rbvmomi/extensions.rb. You are encouraged to
68
- reopen VIM classes in your applications and add extensions of your own. If you
69
- write something generally useful please send it to me and I'll add it in. One
70
- important point about extensions is that since VIM classes are lazily loaded,
71
- you need to trigger this loading before you can reopen the class. Putting the
72
- class name on a line by itself before reopening is enough.</p>
73
-
74
- <h2>Development</h2>
75
-
76
- <p>Send patches to rlane@vmware.com.</p>