Class: Wbem::WsmanClient

Inherits:
WbemClient show all
Defined in:
lib/wbem/wbem.rb,
lib/wbem/wsman.rb

Instance Attribute Summary collapse

Attributes inherited from WbemClient

#auth_scheme, #product, #response, #url

Instance Method Summary collapse

Methods inherited from WbemClient

#enumerate, #factory, #fault_string, #network_class_name, #networks, #processes, #profile_class_name, #profiles, #response_code, #service_class_name, #services, #storage_class_name, #storages, #system_class_name, #systems, #to_s

Constructor Details

#initialize(uri, auth_scheme = nil) ⇒ WsmanClient

Returns a new instance of WsmanClient



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/wbem/wsman.rb', line 97

def initialize uri, auth_scheme = nil
  super uri, auth_scheme
  @url.path = "/wsman" if @url.path.nil? || @url.path.empty?
  Openwsman::debug = -1 if Wbem.debug
  STDERR.puts "WsmanClient connecting to #{uri}, auth #{@auth_scheme.inspect}" if Wbem.debug

  @client = Openwsman::Client.new @url.to_s
  raise "Cannot create Openwsman client" unless @client
  @client.transport.timeout = 5
  @client.transport.verify_peer = 0
  @client.transport.verify_host = 0
  case @auth_scheme.to_s
  when nil, ""
    @client.transport.auth_method = nil # negotiate
  when /none/i
    @client.transport.auth_method = Openwsman::NO_AUTH_STR
  when /basic/i
    @client.transport.auth_method = Openwsman::BASIC_AUTH_STR
  when /digest/i
    @client.transport.auth_method = Openwsman::DIGEST_AUTH_STR
  when /pass/i
    @client.transport.auth_method = Openwsman::PASS_AUTH_STR
  when /ntlm/i
    @client.transport.auth_method = Openwsman::NTLM_AUTH_STR
  when /gss/i
    @client.transport.auth_method = Openwsman::GSSNEGOTIATE_AUTH_STR
  else
    raise "Unknown auth_scheme #{@auth_scheme.inspect}"
  end
  @options = Openwsman::ClientOptions.new

#    STDERR.puts "auth #{@auth_scheme.inspect} -> #{@client.transport.auth_method}"

  doc = _identify
#    STDERR.puts doc.to_xml
  @protocol_version = doc.ProtocolVersion.text
  @product_vendor = doc.ProductVendor.text
  @product_version = doc.ProductVersion.text
  if Wbem.debug
    STDERR.puts "Protocol_version '#{@protocol_version}'"
    STDERR.puts "Product vendor '#{@product_vendor}'"
    STDERR.puts "Product version '#{@product_version}'"
  end
  #
  # Windows winrm 2.0
  # Protocol "http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd"
  # Vendor "Microsoft Corporation"
  # Version "OS: 5.2.3790 SP: 2.0 Stack: 2.0"
  #
  # Windows winrm 1.1
  # Protocol "http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd"
  # Vendor "Microsoft Corporation"
  # Version "OS: 5.1.2600 SP: 3.0 Stack: 1.1"
  #
  # Openwsman 2.2
  # Protocol "http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd"
  # Vendor "Openwsman Project"
  # Version "2.2"
  #

  unless @protocol_version == Openwsman::XML_NS_WS_MAN
    raise "Unsupported WS-Management protocol '#{@protocol_version}'"
  end

  case @product_vendor
  when /Microsoft/i
    @prefix = "http://schemas.microsoft.com/wbem/wsman/1/wmi/"
    if @product_version =~ /^OS:\s([\d\.]+)\sSP:\s([\d\.]+)\sStack:\s([\d\.]+)$/
      @product_version = $3
    else
      STDERR.puts "Unrecognized product version #{@product_version}"
    end
    @product = :winrm
  when /Openwsman/i
    @prefix = "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/"
    @product = :openwsman
  when /Intel/i
    @prefix = "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/"
    @product = :iamt
    if @product_version =~ /^AMT\s(\d\.\d)$/
      @product_version = $1
    end
  else
    STDERR.puts "Unsupported WS-Management vendor #{@product_vendor}"
    @prefix = "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/"
    @product = :unknown
  end
  STDERR.puts "Connected to vendor '#{@product_vendor}', Version #{@product_version}" if Wbem.debug

end

Instance Attribute Details

#clientObject (readonly)

Returns the value of attribute client



95
96
97
# File 'lib/wbem/wsman.rb', line 95

def client
  @client
end

#product_vendorObject (readonly)

Returns the value of attribute product_vendor



19
20
21
# File 'lib/wbem/wsman.rb', line 19

def product_vendor
  @product_vendor
end

#product_versionObject (readonly)

Returns the value of attribute product_version



19
20
21
# File 'lib/wbem/wsman.rb', line 19

def product_version
  @product_version
end

#protocol_versionObject (readonly)

Returns the value of attribute protocol_version



19
20
21
# File 'lib/wbem/wsman.rb', line 19

def protocol_version
  @protocol_version
end

Instance Method Details

#class_names(op, deep_inheritance = false) ⇒ Object

Enumerate class names



241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
# File 'lib/wbem/wsman.rb', line 241

def class_names op, deep_inheritance = false
  @options.flags = Openwsman::FLAG_ENUMERATION_OPTIMIZATION
  @options.max_elements = 999
  namespace = (op.is_a? Sfcc::Cim::ObjectPath) ? op.namespace : op
  classname = (op.is_a? Sfcc::Cim::ObjectPath) ? op.classname : nil
  case @product
  when :openwsman
    if @product_version < "2.2"
      STDERR.puts "ENUMERATE_CLASS_NAMES unsupported for #{@product_vendor} #{@product_version}, please upgrade"
      return []
    end
    method = Openwsman::CIM_ACTION_ENUMERATE_CLASS_NAMES
    uri = Openwsman::XML_NS_CIM_INTRINSIC
    @options.cim_namespace = namespace
    @options.add_selector("DeepInheritance", "True") if deep_inheritance
    result = @client.invoke( @options, uri, method )
  when :winrm
    # see https://github.com/kkaempf/openwsman/blob/master/bindings/ruby/tests/winenum.rb
    filter = Openwsman::Filter.new
    query = "select * from meta_class"
    query << " where __SuperClass is #{classname?classname:'null'}" unless deep_inheritance
    filter.wql query
    uri = "#{@prefix}#{namespace}/*"
    result = @client.enumerate( @options, filter, uri )
  else
    raise "Unsupported for WSMAN product #{@product}"
  end
  
  if _handle_fault @client, result
    return []
  end
  
  classes = []
  
  case @product
  when :openwsman
    # extract invoke result
    output = result.body[method]
    output.each do |c|
      classes << c.to_s
    end
  when :winrm
    # extract enumerate/pull result
    loop do
      output = result.Items
      output.each do |node|
        classes << node.name.to_s
      end if output
      context = result.context
      break unless context
      # get the next chunk
      result = @client.pull( @options, nil, uri, context)
      break if _handle_fault @client, result
    end
  end
  return classes
end

#each_instance(namespace_or_objectpath, classname = nil) ⇒ Object

Enumerate instances



212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
# File 'lib/wbem/wsman.rb', line 212

def each_instance( namespace_or_objectpath, classname = nil )
  op = if namespace_or_objectpath.is_a? Openwsman::ObjectPath
    namespace_or_objectpath
  else
    objectpath namespace_or_objectpath, classname
  end
  @options.flags = Openwsman::FLAG_ENUMERATION_OPTIMIZATION
  @options.max_elements = 999
  uri = epr_uri_for op.namespace, op.classname
  result = @client.enumerate( @options, nil, uri )
  loop do
    if _handle_fault @client, result
      break
    end
    items = result.Items rescue nil
    if items
      items.each do |inst|
        yield Wbem::Instance.new(self, uri, inst)
      end
    end
    context = result.context
    break unless context
    result = @client.pull( @options, nil, uri, context )
  end
end

#get(instance_reference, keys = nil) ⇒ Object

get instance by reference

call-seq

get Openwsman::EndPointReference -> Wbem::Instance
get EndPointReference-as-String -> Wbem::Instance
get "ClassName", "key" => "value", :namespace => "root/interop"


359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
# File 'lib/wbem/wsman.rb', line 359

def get instance_reference, keys = nil
  if keys
    uri = Openwsman.epr_uri_for "", instance_reference
    instance_reference = Openwsman::EndPointReference.new(uri, nil, keys)
  end
  puts "@client.get #{instance_reference.class}..." if Wbem.debug
  case instance_reference
  when Openwsman::EndPointReference
    get_by_epr instance_reference
  when String
    get_by_epr Openwsman::EndPointReference.new(instance_reference)
  else
    raise "Unsupported Wbem::get #{instance_reference.class}"
  end
end

#get_instance(namespace, classname = nil, properties = {}) ⇒ Object

Return matching Wbem::Instance for first instance

matching namespace, classname, properties

Parameters:

  • namespace

    : String or Sfcc::Cim::ObjectPath

  • classname (defaults to: nil)

    : String (optional)

  • properties (defaults to: {})

    : Hash (optional)



381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
# File 'lib/wbem/wsman.rb', line 381

def get_instance namespace, classname=nil, properties={}
  case namespace
  when Openwsman::ObjectPath
    classname = namespace.classname
    properties = namespace.properties
    namespace = namespace.namespace
    uri = epr_uri_for(namespace, classname)
  when Openwsman::EndPointReference
    namespace.each do |k,v|
      properties[k] = v
    end
    classname = namespace.classname
    uri = namespace.resource_uri
    namespace = namespace.namespace
  else
    uri = epr_uri_for(namespace, classname)
  end
  @options.set_dump_request if Wbem.debug
  @options.cim_namespace = namespace if @product == :openwsman
  @options.selectors = properties unless properties.empty?
  STDERR.puts "@client.get(namepace '#{@options.cim_namespace}', props #{properties.inspect}, uri #{uri}" if Wbem.debug
  res = @client.get(@options, uri)
  raise Openwsman::Exception.new res if res.fault?
  Wbem::Instance.new self, Openwsman::EndPointReference.new(uri, "", properties), res
end

#instance_names(namespace, classname = nil, properties = {}) ⇒ Object

Return list of Wbem::EndpointReference (object pathes) for instances

of namespace, classname

Parameters:

  • namespace

    : String or Sfcc::Cim::ObjectPath

  • classname (defaults to: nil)

    : String (optional)

  • properties (defaults to: {})

    : Hash (optional)



306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
# File 'lib/wbem/wsman.rb', line 306

def instance_names namespace, classname=nil, properties = {}
  case namespace
  when Openwsman::ObjectPath
    classname = namespace.classname
    properties = namespace.properties
    namespace = namespace.namespace
    uri = epr_uri_for(namespace,classname)
  when Openwsman::EndPointReference
    namespace.each do |k,v|
      properties[k] = v
    end
    classname = namespace.classname
    uri = namespace.resource_uri
    namespace = namespace.namespace
  else
    uri = epr_uri_for(namespace, classname)
  end
  @options.flags = Openwsman::FLAG_ENUMERATION_ENUM_EPR | Openwsman::FLAG_ENUMERATION_OPTIMIZATION
  @options.max_elements = 999
  @options.cim_namespace = namespace if @product == :openwsman
  @options.set_dump_request if Wbem.debug
  @options.selectors = properties unless properties.empty?
  start = Time.now
  STDERR.puts "instance_names enumerate (#{uri})" if Wbem.debug
  result = @client.enumerate( @options, nil, uri )
  names = []
  loop do
    if _handle_fault @client, result
      break
    end
    items = result.Items
    if items
      # expect <n:Item><a:EndpointReference>...
      items.each do |epr|
        names << Openwsman::EndPointReference.new(epr)
      end
    end
    context = result.context
    break unless context
    result = @client.pull( @options, nil, uri, context )
  end
  STDERR.puts "Enumerated #{names.size} items in #{Time.now-start} seconds" if Wbem.debug
  return names
end

#namespaces(ns = "root", cn = "__Namespace") ⇒ Object

return list of namespaces



192
193
194
195
196
197
198
199
200
# File 'lib/wbem/wsman.rb', line 192

def namespaces ns = "root", cn = "__Namespace"
  result = []
  each_instance( ns, cn ) do |inst|
    name = "#{ns}/#{inst.Name}"
    result << name
    result.concat namespaces name, cn
  end
  result.uniq
end

#objectpath(namespace, classname = nil, properties = {}) ⇒ Object

Create ObjectPath from namespace, classname, and properties



205
206
207
# File 'lib/wbem/wsman.rb', line 205

def objectpath namespace, classname = nil, properties = {}
  Openwsman::ObjectPath.new namespace, classname, properties
end