rbvmomi2 3.2.0 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []