mkuzmin-rbvmomi 1.8.2.1

Sign up to get free protection for your applications and to get access to all the features.
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 +45 -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 +314 -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,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
@@ -0,0 +1,66 @@
1
+ # Copyright (c) 2012 VMware, Inc. All Rights Reserved.
2
+ require 'rbvmomi'
3
+
4
+ module RbVmomi
5
+
6
+ # A connection to one vSphere ProfileBasedManagement endpoint.
7
+ # @see #serviceInstance
8
+ class PBM < Connection
9
+ # Connect to a vSphere ProfileBasedManagement endpoint
10
+ #
11
+ # @param [VIM] Connection to main vSphere API endpoint
12
+ # @param [Hash] opts The options hash.
13
+ # @option opts [String] :host Host to connect to.
14
+ # @option opts [Numeric] :port (443) Port to connect to.
15
+ # @option opts [Boolean] :ssl (true) Whether to use SSL.
16
+ # @option opts [Boolean] :insecure (false) If true, ignore SSL certificate errors.
17
+ # @option opts [String] :path (/pbm/sdk) SDK endpoint path.
18
+ # @option opts [Boolean] :debug (false) If true, print SOAP traffic to stderr.
19
+ def self.connect vim, opts = {}
20
+ fail unless opts.is_a? Hash
21
+ opts[:host] = vim.host
22
+ opts[:ssl] = true unless opts.member? :ssl or opts[:"no-ssl"]
23
+ opts[:insecure] ||= false
24
+ opts[:port] ||= (opts[:ssl] ? 443 : 80)
25
+ opts[:path] ||= '/pbm/sdk'
26
+ opts[:ns] ||= 'urn:pbm'
27
+ rev_given = opts[:rev] != nil
28
+ opts[:rev] = '1.0' unless rev_given
29
+ opts[:debug] = (!ENV['RBVMOMI_DEBUG'].empty? rescue false) unless opts.member? :debug
30
+
31
+ new(opts).tap do |pbm|
32
+ pbm.vcSessionCookie = vim.cookie.split('"')[1]
33
+ end
34
+ end
35
+
36
+ def vcSessionCookie= cookie
37
+ @vcSessionCookie = cookie
38
+ end
39
+
40
+ def rev= x
41
+ super
42
+ @serviceContent = nil
43
+ end
44
+
45
+ # Return the ServiceInstance
46
+ #
47
+ # The ServiceInstance is the root of the vSphere inventory.
48
+ def serviceInstance
49
+ @serviceInstance ||= VIM::PbmServiceInstance self, 'ServiceInstance'
50
+ end
51
+
52
+ # Alias to serviceInstance.PbmRetrieveServiceContent
53
+ def serviceContent
54
+ @serviceContent ||= serviceInstance.PbmRetrieveServiceContent
55
+ end
56
+
57
+ # @private
58
+ def pretty_print pp
59
+ pp.text "PBM(#{@opts[:host]})"
60
+ end
61
+
62
+ add_extension_dir File.join(File.dirname(__FILE__), "pbm")
63
+ load_vmodl(ENV['VMODL'] || File.join(File.dirname(__FILE__), "../../vmodl.db"))
64
+ end
65
+
66
+ end
@@ -0,0 +1,61 @@
1
+ # Copyright (c) 2013 VMware, Inc. All Rights Reserved.
2
+ require 'rbvmomi'
3
+ module RbVmomi
4
+
5
+ # A connection to one vSphere SMS endpoint.
6
+ # @see #serviceInstance
7
+ class SMS < Connection
8
+ # Connect to a vSphere SMS endpoint
9
+ #
10
+ # @param [VIM] Connection to main vSphere API endpoint
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] :path (/sms/sdk) SDK endpoint path.
17
+ # @option opts [Boolean] :debug (false) If true, print SOAP traffic to stderr.
18
+ def self.connect vim, opts = {}
19
+ fail unless opts.is_a? Hash
20
+ opts[:host] = vim.host
21
+ opts[:ssl] = true unless opts.member? :ssl or opts[:"no-ssl"]
22
+ opts[:insecure] ||= true
23
+ opts[:port] ||= (opts[:ssl] ? 443 : 80)
24
+ opts[:path] ||= '/sms/sdk'
25
+ opts[:ns] ||= 'urn:sms'
26
+ rev_given = opts[:rev] != nil
27
+ opts[:rev] = '4.0' unless rev_given
28
+ opts[:debug] = (!ENV['RBVMOMI_DEBUG'].empty? rescue false) unless opts.member? :debug
29
+
30
+ new(opts).tap do |sms|
31
+ sms.vcSessionCookie = vim.cookie.split('"')[1]
32
+ end
33
+ end
34
+
35
+ def vcSessionCookie= cookie
36
+ @vcSessionCookie = cookie
37
+ end
38
+
39
+ def rev= x
40
+ super
41
+ @serviceContent = nil
42
+ end
43
+
44
+ # Return the ServiceInstance
45
+ #
46
+ # The ServiceInstance is the root of the vSphere inventory.
47
+ def serviceInstance
48
+ @serviceInstance ||= VIM::SmsServiceInstance self, 'ServiceInstance'
49
+ end
50
+
51
+ # @private
52
+ def pretty_print pp
53
+ pp.text "SMS(#{@opts[:host]})"
54
+ end
55
+
56
+ add_extension_dir File.join(File.dirname(__FILE__), "sms")
57
+ load_vmodl(ENV['VMODL'] || File.join(File.dirname(__FILE__), "../../vmodl.db"))
58
+ end
59
+
60
+ end
61
+
@@ -0,0 +1,7 @@
1
+ class RbVmomi::SMS::SmsStorageManager
2
+
3
+ def RegisterProvider_Task2 providerSpec
4
+ self.RegisterProvider_Task providerSpec
5
+ end
6
+
7
+ end
@@ -0,0 +1,114 @@
1
+ # Copyright (c) 2010 VMware, Inc. All Rights Reserved.
2
+ require 'rubygems'
3
+ require 'builder'
4
+ require 'nokogiri'
5
+ require 'net/http'
6
+ require 'pp'
7
+
8
+ class RbVmomi::TrivialSoap
9
+ attr_accessor :debug, :cookie
10
+ attr_reader :http
11
+
12
+ def initialize opts
13
+ fail unless opts.is_a? Hash
14
+ @opts = opts
15
+ return unless @opts[:host] # for testcases
16
+ @debug = @opts[:debug]
17
+ @cookie = @opts[:cookie]
18
+ @lock = Mutex.new
19
+ @http = nil
20
+ restart_http
21
+ end
22
+
23
+ def host
24
+ @opts[:host]
25
+ end
26
+
27
+ def close
28
+ @http.finish rescue IOError
29
+ end
30
+
31
+ def restart_http
32
+ begin
33
+ @http.finish if @http
34
+ rescue Exception => ex
35
+ puts "WARNING: Ignoring exception: #{ex.message}"
36
+ puts ex.backtrace.join("\n")
37
+ end
38
+ @http = Net::HTTP.new(@opts[:host], @opts[:port], @opts[:proxyHost], @opts[:proxyPort])
39
+ if @opts[:ssl]
40
+ require 'net/https'
41
+ @http.use_ssl = true
42
+ if @opts[:insecure]
43
+ @http.verify_mode = OpenSSL::SSL::VERIFY_NONE
44
+ else
45
+ @http.verify_mode = OpenSSL::SSL::VERIFY_PEER
46
+ end
47
+ @http.cert = OpenSSL::X509::Certificate.new(@opts[:cert]) if @opts[:cert]
48
+ @http.key = OpenSSL::PKey::RSA.new(@opts[:key]) if @opts[:key]
49
+ end
50
+ @http.set_debug_output(STDERR) if $DEBUG
51
+ @http.read_timeout = 1000000
52
+ @http.open_timeout = 60
53
+ def @http.on_connect
54
+ @socket.io.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
55
+ end
56
+ @http.start
57
+ end
58
+
59
+ def soap_envelope
60
+ xsd = 'http://www.w3.org/2001/XMLSchema'
61
+ env = 'http://schemas.xmlsoap.org/soap/envelope/'
62
+ xsi = 'http://www.w3.org/2001/XMLSchema-instance'
63
+ xml = Builder::XmlMarkup.new :indent => 0
64
+ xml.tag!('env:Envelope', 'xmlns:xsd' => xsd, 'xmlns:env' => env, 'xmlns:xsi' => xsi) do
65
+ if @vcSessionCookie
66
+ xml.tag!('env:Header') do
67
+ xml.tag!('vcSessionCookie', @vcSessionCookie)
68
+ end
69
+ end
70
+ xml.tag!('env:Body') do
71
+ yield xml if block_given?
72
+ end
73
+ end
74
+ xml
75
+ end
76
+
77
+ def request action, body
78
+ headers = { 'content-type' => 'text/xml; charset=utf-8', 'SOAPAction' => action }
79
+ headers['cookie'] = @cookie if @cookie
80
+
81
+ if @debug
82
+ $stderr.puts "Request:"
83
+ $stderr.puts body
84
+ $stderr.puts
85
+ end
86
+
87
+ start_time = Time.now
88
+ response = @lock.synchronize do
89
+ begin
90
+ @http.request_post(@opts[:path], body, headers)
91
+ rescue Exception
92
+ restart_http
93
+ raise
94
+ end
95
+ end
96
+ end_time = Time.now
97
+
98
+ if response.is_a? Net::HTTPServiceUnavailable
99
+ raise "Got HTTP 503: Service unavailable"
100
+ end
101
+
102
+ self.cookie = response['set-cookie'] if response.key? 'set-cookie'
103
+
104
+ nk = Nokogiri(response.body)
105
+
106
+ if @debug
107
+ $stderr.puts "Response (in #{'%.3f' % (end_time - start_time)} s)"
108
+ $stderr.puts nk
109
+ $stderr.puts
110
+ end
111
+
112
+ [nk.xpath('//soapenv:Body/*').select(&:element?).first, response.body.size]
113
+ end
114
+ end
@@ -0,0 +1,70 @@
1
+ # Copyright (c) 2011 VMware, Inc. All Rights Reserved.
2
+ require 'trollop'
3
+
4
+ # Convenience methods for Trollop, Ruby's premier option parser.
5
+ # @see http://trollop.rubyforge.org/
6
+ # @see Trollop::Parser
7
+ module Trollop
8
+
9
+ # Convenience methods for Trollop, Ruby's premier option parser.
10
+ #
11
+ # See the examples directory for sample code.
12
+ # Descriptions are of the form:
13
+ # <key>: <options> <environment variable> (<default>)
14
+ # @see http://trollop.rubyforge.org/
15
+ class Parser
16
+ # Options used by VIM.connect
17
+ #
18
+ # !!!plain
19
+ # host: -o --host RBVMOMI_HOST
20
+ # port: --port RBVMOMI_PORT (443)
21
+ # no-ssl: --no-ssl RBVMOMI_SSL (false)
22
+ # insecure: -k --insecure RBVMOMI_INSECURE (false)
23
+ # user: -u --user RBVMOMI_USER (root)
24
+ # password: -p --password RBVMOMI_PASSWORD ()
25
+ # path: --path RBVMOMI_PATH (/sdk)
26
+ # debug: -d --debug RBVMOMI_DEBUG (false)
27
+ def rbvmomi_connection_opts
28
+ opt :host, "host", :type => :string, :short => 'o', :default => ENV['RBVMOMI_HOST']
29
+ opt :port, "port", :type => :int, :short => :none, :default => (ENV.member?('RBVMOMI_PORT') ? ENV['RBVMOMI_PORT'].to_i : 443)
30
+ opt :"no-ssl", "don't use ssl", :short => :none, :default => (ENV['RBVMOMI_SSL'] == '0')
31
+ opt :insecure, "don't verify ssl certificate", :short => 'k', :default => (ENV['RBVMOMI_INSECURE'] == '1')
32
+ opt :user, "username", :short => 'u', :default => (ENV['RBVMOMI_USER'] || 'root')
33
+ opt :password, "password", :short => 'p', :default => (ENV['RBVMOMI_PASSWORD'] || '')
34
+ opt :path, "SOAP endpoint path", :short => :none, :default => (ENV['RBVMOMI_PATH'] || '/sdk')
35
+ opt :debug, "Log SOAP messages", :short => 'd', :default => (ENV['RBVMOMI_DEBUG'] || false)
36
+ end
37
+
38
+ # Select a datacenter
39
+ #
40
+ # !!!plain
41
+ # datacenter: -D --datacenter RBVMOMI_DATACENTER (ha-datacenter)
42
+ def rbvmomi_datacenter_opt
43
+ opt :datacenter, "datacenter", :type => :string, :short => "D", :default => (ENV['RBVMOMI_DATACENTER'] || 'ha-datacenter')
44
+ end
45
+
46
+ # Select a folder
47
+ #
48
+ # !!!plain
49
+ # folder: -F --folder RBVMOMI_FOLDER ()
50
+ def rbvmomi_folder_opt
51
+ opt :folder, "VM folder", :type => :string, :short => "F", :default => (ENV['RBVMOMI_FOLDER'] || '')
52
+ end
53
+
54
+ # Select a compute resource
55
+ #
56
+ # !!!plain
57
+ # computer: -R --computer RBVMOMI_COMPUTER
58
+ def rbvmomi_computer_opt
59
+ opt :computer, "Compute resource", :type => :string, :short => "R", :default => (ENV['RBVMOMI_COMPUTER']||'ha-compute-res')
60
+ end
61
+
62
+ # Select a datastore
63
+ #
64
+ # !!!plain
65
+ # datastore: -s --datastore RBVMOMI_DATASTORE (datastore1)
66
+ def rbvmomi_datastore_opt
67
+ opt :datastore, "Datastore", :short => 's', :default => (ENV['RBVMOMI_DATASTORE'] || 'datastore1')
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,136 @@
1
+ # Copyright (c) 2010 VMware, Inc. All Rights Reserved.
2
+ require 'set'
3
+ require 'monitor'
4
+
5
+ module RbVmomi
6
+
7
+ class TypeLoader
8
+ def initialize fn, extension_dirs, namespace
9
+ @extension_dirs = extension_dirs
10
+ @namespace = namespace
11
+ @lock = Monitor.new
12
+ @db = {}
13
+ @id2wsdl = {}
14
+ @loaded = {}
15
+ add_types Hash[BasicTypes::BUILTIN.map { |k| [k,nil] }]
16
+ vmodl_database = File.open(fn, 'r') { |io| Marshal.load io }
17
+ vmodl_database.reject! { |k,v| k =~ /^_/ }
18
+ add_types vmodl_database
19
+ preload
20
+ end
21
+
22
+ def preload
23
+ names = (@namespace.constants + Object.constants).map(&:to_s).uniq.
24
+ select { |x| has? x }
25
+ names.each { |x| get(x) }
26
+ end
27
+
28
+ # Reload all extensions for loaded VMODL types
29
+ def reload_extensions
30
+ @extension_dirs.each do |path|
31
+ reload_extensions_dir path
32
+ end
33
+ end
34
+
35
+ # Reload all extensions for loaded VMODL types from the given directory
36
+ def reload_extensions_dir path
37
+ loaded = Set.new(typenames.select { |x| @namespace.const_defined? x })
38
+ Dir.open(path) do |dir|
39
+ dir.each do |file|
40
+ next unless file =~ /\.rb$/
41
+ next unless loaded.member? $`
42
+ file_path = File.join(dir, file)
43
+ load file_path
44
+ end
45
+ end
46
+ end
47
+
48
+ def has? name
49
+ fail unless name.is_a? String
50
+
51
+ @db.member?(name) or BasicTypes::BUILTIN.member?(name)
52
+ end
53
+
54
+ def get name
55
+ fail "name '#{name}' is #{name.class} expecting String" unless name.is_a? String
56
+
57
+ first_char = name[0].chr
58
+ if first_char.downcase == first_char
59
+ name = "%s%s" % [first_char.upcase, name[1..-1]]
60
+ end
61
+
62
+ return @loaded[name] if @loaded.member? name
63
+ @lock.synchronize do
64
+ return @loaded[name] if @loaded.member? name
65
+ klass = make_type(name)
66
+ @namespace.const_set name, klass
67
+ load_extension name
68
+ @loaded[name] = klass
69
+ end
70
+ end
71
+
72
+ def add_types types
73
+ @lock.synchronize do
74
+ @db.merge! types
75
+ @db = Hash[@db.map do |name, value|
76
+ if value
77
+ value['wsdl_name'] ||= name
78
+ end
79
+ first_char = name[0].chr
80
+ if first_char.downcase == first_char
81
+ name = "%s%s" % [first_char.upcase, name[1..-1]]
82
+ end
83
+ [name, value]
84
+ end]
85
+ end
86
+ end
87
+
88
+ def typenames
89
+ @db.keys
90
+ end
91
+
92
+ private
93
+
94
+ def load_extension name
95
+ @extension_dirs.map { |x| File.join(x, "#{name}.rb") }.
96
+ select { |x| File.exists? x }.
97
+ each { |x| load x }
98
+ end
99
+
100
+ def make_type name
101
+ name = name.to_s
102
+ return BasicTypes.const_get(name) if BasicTypes::BUILTIN.member? name
103
+ desc = @db[name] or fail "unknown VMODL type #{name}"
104
+ case desc['kind']
105
+ when 'data' then make_data_type name, desc
106
+ when 'managed' then make_managed_type name, desc
107
+ when 'enum' then make_enum_type name, desc
108
+ else fail desc.inspect
109
+ end
110
+ end
111
+
112
+ def make_data_type name, desc
113
+ superclass = get desc['wsdl_base']
114
+ Class.new(superclass).tap do |klass|
115
+ klass.init name, desc['props']
116
+ klass.wsdl_name = desc['wsdl_name']
117
+ end
118
+ end
119
+
120
+ def make_managed_type name, desc
121
+ superclass = get desc['wsdl_base']
122
+ Class.new(superclass).tap do |klass|
123
+ klass.init name, desc['props'], desc['methods']
124
+ klass.wsdl_name = desc['wsdl_name']
125
+ end
126
+ end
127
+
128
+ def make_enum_type name, desc
129
+ Class.new(BasicTypes::Enum).tap do |klass|
130
+ klass.init name, desc['values']
131
+ klass.wsdl_name = desc['wsdl_name']
132
+ end
133
+ end
134
+ end
135
+
136
+ end