rbvmomi2 3.2.0 → 3.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ee70c9cbf14069109282bc0dc3b3fbfc192a75c2dfc7169e20ece8c17de30fd9
4
- data.tar.gz: 34749740fe0bbfaf0d098eea7081dc09d527e1ff08b868126c61cde22bc1740e
3
+ metadata.gz: 3cd7c8f7c07cfc8e042bc125747b279ff88430ab531068b3bb56aeb937ec5009
4
+ data.tar.gz: 1c76cde83a228ac728cdd747b3367a32d19a2a98c7c07eb796a2a73fd414fd2b
5
5
  SHA512:
6
- metadata.gz: ac0c4954c87993b43020edadfe1d142cff52041a655dc48039cb5f462d6e8ad5eaf14cef7f719f512179d00e8ec9f29b1ebfe99341ec3e1ec4659c715f19da24
7
- data.tar.gz: 3388115b0783d73c42ad20eeb99422e90601568c7140fae69e28366c0209065df07cf2c8dc535769802792d661f86f655bf542d690f34bbec46720ea3e9220b9
6
+ metadata.gz: d9779867969725d9d0eeb72fda7193e5a6e8725cc53a5d4c41518089203657ca7eb30ed8bbcf1f5e17f7a48aec52accbb975fb32e6d19a9a63c1c01d2796d560
7
+ data.tar.gz: 88421663c3b937da0fe46cb021c3f17830670738cb5297851db5ee3a0a605b994c5c12d3402b835d6418481f5348d4a6e3cb8a354d6cc67192597527bc8bcfad
@@ -195,8 +195,7 @@ module RbVmomi
195
195
  end
196
196
  xml
197
197
  rescue
198
- $stderr.puts "#{$!.class} while serializing #{name} (#{type}):"
199
- PP.pp o, $stderr
198
+ RbVmomi.logger.error("#{$!.class} while serializing #{name} (#{type})\n#{o.pretty_inspect}")
200
199
  raise
201
200
  end
202
201
 
@@ -221,8 +221,7 @@ module RbVmomi
221
221
  else raise "unexpected type #{t.inspect} (#{t.ancestors * '/'})"
222
222
  end
223
223
  rescue
224
- $stderr.puts "#{$!.class} while deserializing #{xml.name} (#{typename}):"
225
- $stderr.puts xml.to_s
224
+ RbVmomi.logger.error("#{$!.class} while deserializing #{xml.name} (#{typename}):\n#{xml.to_s}")
226
225
  raise
227
226
  end
228
227
 
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RbVmomi
4
+ class << self
5
+ attr_writer :logger
6
+ end
7
+
8
+ def self.logger
9
+ @logger ||= begin
10
+ require 'logger'
11
+ Logger.new($stderr)
12
+ end
13
+ end
14
+ end
data/lib/rbvmomi/pbm.rb CHANGED
@@ -18,7 +18,7 @@ module RbVmomi
18
18
  # @option opts [Boolean] :ssl (true) Whether to use SSL.
19
19
  # @option opts [Boolean] :insecure (false) If true, ignore SSL certificate errors.
20
20
  # @option opts [String] :path (/pbm/sdk) SDK endpoint path.
21
- # @option opts [Boolean] :debug (false) If true, print SOAP traffic to stderr.
21
+ # @option opts [Boolean] :debug (false) If true, print SOAP traffic to RbVmomi.logger.debug.
22
22
  def self.connect vim, opts = {}
23
23
  raise unless opts.is_a? Hash
24
24
 
data/lib/rbvmomi/sms.rb CHANGED
@@ -17,7 +17,7 @@ module RbVmomi
17
17
  # @option opts [Boolean] :ssl (true) Whether to use SSL.
18
18
  # @option opts [Boolean] :insecure (false) If true, ignore SSL certificate errors.
19
19
  # @option opts [String] :path (/sms/sdk) SDK endpoint path.
20
- # @option opts [Boolean] :debug (false) If true, print SOAP traffic to stderr.
20
+ # @option opts [Boolean] :debug (false) If true, print SOAP traffic to RbVmomi.logger.debug.
21
21
  def self.connect vim, opts = {}
22
22
  raise unless opts.is_a? Hash
23
23
 
@@ -84,11 +84,7 @@ class RbVmomi::TrivialSoap
84
84
  headers = { 'content-type' => 'text/xml; charset=utf-8', 'SOAPAction' => action }
85
85
  headers['cookie'] = @cookie if @cookie
86
86
 
87
- if @debug
88
- $stderr.puts 'Request:'
89
- $stderr.puts body
90
- $stderr.puts
91
- end
87
+ RbVmomi.logger.debug("Request:\n#{body}") if @debug
92
88
 
93
89
  if @cookie.nil? && @sso
94
90
  @sso.request_token unless @sso.assertion_id
@@ -112,11 +108,7 @@ class RbVmomi::TrivialSoap
112
108
 
113
109
  nk = Nokogiri(response.body)
114
110
 
115
- if @debug
116
- $stderr.puts "Response (in #{'%.3f' % (end_time - start_time)} s)"
117
- $stderr.puts nk
118
- $stderr.puts
119
- end
111
+ RbVmomi.logger.debug("Response (in #{'%.3f' % (end_time - start_time)} s)\n#{nk}") if @debug
120
112
 
121
113
  [nk.xpath('//soapenv:Body/*').select(&:element?).first, response.body.size]
122
114
  end
@@ -3,5 +3,5 @@
3
3
  # SPDX-License-Identifier: MIT
4
4
 
5
5
  module RbVmomi
6
- VERSION = '3.2.0'.freeze
6
+ VERSION = '3.3.0'.freeze
7
7
  end
data/lib/rbvmomi/vim.rb CHANGED
@@ -18,7 +18,7 @@ module RbVmomi
18
18
  # @option opts [String] :user (root) Username.
19
19
  # @option opts [String] :password Password.
20
20
  # @option opts [String] :path (/sdk) SDK endpoint path.
21
- # @option opts [Boolean] :debug (false) If true, print SOAP traffic to stderr.
21
+ # @option opts [Boolean] :debug (false) If true, print SOAP traffic to RbVmomi.logger.debug.
22
22
  # @option opts [String] :operation_id If set, use for operationID
23
23
  # @option opts [Boolean] :close_on_exit (true) If true, will close connection with at_exit
24
24
  # @option opts [RbVmomi::SSO] :sso (nil) Use SSO token to login if set
@@ -56,7 +56,7 @@ module RbVmomi
56
56
  def close
57
57
  serviceContent.sessionManager.Logout
58
58
  rescue RbVmomi::Fault => e
59
- $stderr.puts(e.message) if debug
59
+ RbVmomi.logger.error(e.message) if debug
60
60
  ensure
61
61
  self.cookie = nil
62
62
  super
data/lib/rbvmomi.rb CHANGED
@@ -12,6 +12,7 @@ module RbVmomi
12
12
  end
13
13
 
14
14
  require_relative 'rbvmomi/connection'
15
+ require_relative 'rbvmomi/logging'
15
16
  require_relative 'rbvmomi/sso'
16
17
  require_relative 'rbvmomi/version'
17
18
  require_relative 'rbvmomi/vim'
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './vmodl_helper'
4
+
5
+ namespace :vmodl do
6
+ desc 'Verify vmodl.db'
7
+ task :verify do
8
+ VmodlHelper.verify!
9
+ end
10
+
11
+ desc 'Generate vmodl.db'
12
+ task :generate do
13
+ VmodlHelper.generate!
14
+ end
15
+ end
@@ -0,0 +1,206 @@
1
+ # frozen_string_literal: true
2
+ require 'active_support/core_ext/enumerable'
3
+ require 'active_support/inflector'
4
+ require 'optimist'
5
+ require 'pathname'
6
+ require 'wsdl/parser'
7
+ require 'rbvmomi'
8
+ require 'rbvmomi/pbm'
9
+ require 'rbvmomi/sms'
10
+
11
+ class VmodlHelper
12
+ class << self
13
+ def verify!
14
+ run!('verify')
15
+ end
16
+
17
+ def generate!
18
+ run!('generate')
19
+ end
20
+
21
+ private
22
+
23
+ def run!(mode)
24
+ vmodl, wsdl = options(mode).values_at(:vmodl, :wsdl)
25
+ new(vmodl_path: vmodl, wsdl_path: wsdl).send("#{mode}!")
26
+ end
27
+
28
+ def options(rake_task)
29
+ argv = ARGV.slice_after('--').to_a.last
30
+ Optimist.options(argv) do
31
+ educate_on_error
32
+ opt :wsdl, 'Path to the vsphere-ws wsdl file', type: :string, required: true
33
+ opt :vmodl, 'Path to the vmodl.db', type: :string, default: 'vmodl.db'
34
+ banner <<~EOS
35
+ Usage:
36
+ rake vmodl:#{rake_task} -- --wsdl=path/to/wsdl
37
+ EOS
38
+ end
39
+ end
40
+ end
41
+
42
+ def initialize(vmodl_path:, wsdl_path:)
43
+ @vmodl_path = Pathname.new(vmodl_path)
44
+ @wsdl_path = Pathname.new(wsdl_path)
45
+
46
+ @vmodl = load_vmodl(@vmodl_path)
47
+ @wsdl = load_wsdl(@wsdl_path)
48
+ end
49
+
50
+ def verify!
51
+ # Loop through the ComplexTypes in the WSDL and compare their types
52
+ # to the types which are defined in the vmodl.db
53
+ wsdl_types_by_name.each_value do |type|
54
+ type_name = type.name.name
55
+ vmodl_data = @vmodl[type_name]
56
+
57
+ # If a type exists in the WSDL but not in the vmodl.db this usually
58
+ # indicates that it was added in a newer version than the current
59
+ # vmodl.db supports.
60
+ #
61
+ # Print a warning that the type is missing and skip it.
62
+ if vmodl_data.nil?
63
+ puts " #{type_name} is missing"
64
+ next
65
+ end
66
+
67
+ # Index the properties by name to make it simpler to find later
68
+ elements_by_name = type.elements.index_by { |e| e.name.name }
69
+
70
+ # Loop through the properties defined in the vmodl.db for this type and
71
+ # compare the type to that property as defined in the wsdl.
72
+ vmodl_data['props'].each do |vmodl_prop|
73
+ wsdl_prop = elements_by_name[vmodl_prop['name']]
74
+ next if wsdl_prop.nil?
75
+
76
+ vmodl_klass = wsdl_constantize(vmodl_prop['wsdl_type'])
77
+ wsdl_klass = wsdl_constantize(wsdl_prop.type.source)
78
+
79
+ # The vmodl class should be equal to or a subclass of the one in the wsdl.
80
+ # Example of a subclass is e.g. VirtualMachine.host is defined as a HostSystem
81
+ # in the vmodl.db but it is a ManagedObjectReference in the wsdl.
82
+ puts "#{type_name}.#{vmodl_prop["name"]} #{wsdl_klass.wsdl_name} doesn't match #{vmodl_klass.wsdl_name}" unless vmodl_klass <= wsdl_klass
83
+ end
84
+ end
85
+ end
86
+
87
+ def generate!
88
+ wsdl_types_by_name.each_value do |type|
89
+ type_name = type.name.name
90
+ vmodl_data = @vmodl[type_name]
91
+
92
+ if vmodl_data.nil?
93
+ base_class = wsdl_types_by_name[type.complexcontent.extension.base.name]
94
+ inherited_properties = base_class.elements.map { |element| element.name.name }
95
+ properties = type.elements.reject { |e| inherited_properties.include?(e.name.name) }
96
+
97
+ vmodl_data = {
98
+ 'kind' => 'data',
99
+ 'props' => properties.map do |element|
100
+ {
101
+ 'name' => element.name.name,
102
+ 'is-optional' => element.minoccurs == 0,
103
+ 'is-array' => element.maxoccurs != 1,
104
+ 'version-id-ref' => nil,
105
+ 'wsdl_type' => wsdl_to_vmodl_type(element.type)
106
+ }
107
+ end,
108
+ 'wsdl_base' => type.complexcontent.extension.base.name
109
+ }
110
+
111
+ @vmodl[type_name] = vmodl_data
112
+ @vmodl['_typenames']['_typenames'] << type_name
113
+
114
+ puts "Adding #{type_name} to vmodl"
115
+
116
+ wsdl_to_rbvmomi_namespace(type).loader.add_types type_name => vmodl_data
117
+ end
118
+ end
119
+
120
+ wsdl_types_by_name.each_value do |type|
121
+ type_name = type.name.name
122
+ vmodl_data = @vmodl[type_name]
123
+
124
+ elements_by_name = type.elements.index_by { |e| e.name.name }
125
+
126
+ # Loop through the properties defined in the vmodl.db for this type and
127
+ # compare the type to that property as defined in the wsdl.
128
+ vmodl_data['props'].each do |vmodl_prop|
129
+ wsdl_prop = elements_by_name[vmodl_prop['name']]
130
+ next if wsdl_prop.nil?
131
+
132
+ vmodl_klass = wsdl_constantize(vmodl_prop['wsdl_type'])
133
+ wsdl_klass = wsdl_constantize(wsdl_prop.type.source)
134
+
135
+ vmodl_prop['wsdl_type'] = wsdl_klass.wsdl_name unless vmodl_klass <= wsdl_klass
136
+ end
137
+ end
138
+
139
+ dump_vmodl!
140
+ end
141
+
142
+ protected
143
+
144
+ def load_wsdl(path)
145
+ # WSDL includes have to resolve in the local directory so we have to
146
+ # change working directories to where the wsdl is
147
+ Dir.chdir(path.dirname) do
148
+ WSDL::Parser.new.parse(path.read)
149
+ end
150
+ end
151
+
152
+ def load_vmodl(path)
153
+ Marshal.load(path.read)
154
+ end
155
+
156
+ def dump_vmodl!
157
+ File.write(@vmodl_path, Marshal.dump(@vmodl))
158
+ end
159
+
160
+ private
161
+
162
+ def wsdl_types_by_name
163
+ @wsdl_types_by_name ||= @wsdl.collect_complextypes
164
+ .reject { |type| type.name.name.match?(/^ArrayOf|RequestType$/) }
165
+ .index_by { |type| type.name.name }
166
+ end
167
+
168
+ def wsdl_to_vmodl_type(type)
169
+ case type.source
170
+ when /vim25:/, /pbm:/, /sms:/
171
+ vmodl_type = type.name == 'ManagedObjectReference' ? 'ManagedObject' : type.name
172
+ when /xsd:/
173
+ vmodl_type = type.source
174
+ else
175
+ raise ArgumentError, "Unrecognized wsdl type: [#{type}]"
176
+ end
177
+
178
+ vmodl_type
179
+ end
180
+
181
+ def wsdl_to_rbvmomi_namespace(type)
182
+ case type.targetnamespace
183
+ when 'urb:vim25'
184
+ RbVmomi::VIM
185
+ when 'urn:pbm'
186
+ RbVmomi::PBM
187
+ when 'urn:sms'
188
+ RbVmomi::SMS
189
+ else
190
+ raise ArgumentError, "Unrecognized namespace [#{type}]"
191
+ end
192
+ end
193
+
194
+ # Normalize the type, some of these don't have RbVmomi equivalents such as xsd:long
195
+ # and RbVmomi uses ManagedObjects not ManagedObjectReferences as parameters
196
+ def wsdl_constantize(type)
197
+ type = type.split(':').last
198
+ type = 'int' if %w[long short byte].include?(type)
199
+ type = 'float' if type == 'double'
200
+ type = 'binary' if type == 'base64Binary'
201
+ type = 'ManagedObject' if type == 'ManagedObjectReference'
202
+
203
+ type = type.camelcase
204
+ type.safe_constantize || "RbVmomi::BasicTypes::#{type}".safe_constantize || "RbVmomi::VIM::#{type}".safe_constantize
205
+ end
206
+ end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rbvmomi2
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.0
4
+ version: 3.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Grare
8
8
  - Jason Frey
9
- autorequire:
9
+ autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2021-10-08 00:00:00.000000000 Z
12
+ date: 2022-03-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: builder
@@ -185,7 +185,7 @@ dependencies:
185
185
  - - "~>"
186
186
  - !ruby/object:Gem::Version
187
187
  version: 0.9.25
188
- description:
188
+ description:
189
189
  email:
190
190
  - adam@grare.com
191
191
  - fryguy9@gmail.com
@@ -202,6 +202,7 @@ files:
202
202
  - lib/rbvmomi/connection.rb
203
203
  - lib/rbvmomi/deserialization.rb
204
204
  - lib/rbvmomi/fault.rb
205
+ - lib/rbvmomi/logging.rb
205
206
  - lib/rbvmomi/optimist.rb
206
207
  - lib/rbvmomi/pbm.rb
207
208
  - lib/rbvmomi/sms.rb
@@ -237,12 +238,14 @@ files:
237
238
  - lib/rbvmomi/vim/Task.rb
238
239
  - lib/rbvmomi/vim/VirtualMachine.rb
239
240
  - lib/rbvmomi2.rb
241
+ - lib/tasks/vmodl.rake
242
+ - lib/tasks/vmodl_helper.rb
240
243
  - vmodl.db
241
244
  homepage: https://github.com/ManageIQ/rbvmomi2
242
245
  licenses:
243
246
  - MIT
244
247
  metadata: {}
245
- post_install_message:
248
+ post_install_message:
246
249
  rdoc_options: []
247
250
  require_paths:
248
251
  - lib
@@ -257,8 +260,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
257
260
  - !ruby/object:Gem::Version
258
261
  version: '0'
259
262
  requirements: []
260
- rubygems_version: 3.2.27
261
- signing_key:
263
+ rubygems_version: 3.3.5
264
+ signing_key:
262
265
  specification_version: 4
263
266
  summary: Ruby interface to the VMware vSphere API
264
267
  test_files: []