wbem 0.3.0 → 0.5.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
  SHA1:
3
- metadata.gz: 87b68ff6a2d000a5a3d48ca45b80457b2e09510e
4
- data.tar.gz: 485f24baa3f7b857f23a41c6d083ae335207f6ea
3
+ metadata.gz: a9c0a1ba0bac70d9aa7e910153bf46837a6dd305
4
+ data.tar.gz: 232a5e958d2e5456ba907379228e0304a32ae82c
5
5
  SHA512:
6
- metadata.gz: c0d17fee71e8379c960add9b3d250afa20ff15b06588b701a6a386396d5fa6f263bacb233f531c70955b02e2ce3bdc57025bdbde36cac9db495e85b5bd5c18e6
7
- data.tar.gz: 4d5d1ba803e1a93d2b3802dd1ae44e4fdf5c35788507e5e30d0f06b6042fb5d1569c63fab10784b0d589e86f091e75a40b5dcf90482d4a9ae61f88afa71ed9f1
6
+ metadata.gz: 364d2f6af56cfc32aecf396f546aaa85461d0dbb1f123a5db9d9e2f6c2dfc722da657df5db9378d3f52e8b7ef092b71a8ebbe7406d90113f3739bce5d63539ff
7
+ data.tar.gz: c4d5401ac945660197fa4cb0340da43086a638236d0828be2e3cb61010db996a793fc7d62604d59d678ab0f544437917d33e3d6a1bd7819768dbb0d17c55d332
@@ -1,3 +1,23 @@
1
+ == 0.5.0
2
+
3
+ * Add client.get for fetching instances with keys in Cimxml
4
+
5
+ == 0.4.0
6
+
7
+ * Add bin/genclassinfo to generate Ruby classes from MOF
8
+ * Add client.get for fetching instances with keys in Wsman
9
+ * Properly handle EndpointReferences
10
+ * Add Instance#invoke, based on type information from generated Ruby
11
+ class
12
+
13
+ == 0.3.2
14
+
15
+ * Add Client#get to get an instance by ObjectPath
16
+
17
+ == 0.3.1
18
+
19
+ * Add Client#get to get an instance by EndPointReference
20
+
1
21
  == 0.3.0
2
22
 
3
23
  * Add Client#profiles to enumerate CIM_RegisteredProfile
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source :rubygems
2
+ gemspec
@@ -0,0 +1,22 @@
1
+
2
+ Copyright (c) 2009 Novell Inc.
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining
5
+ a copy of this software and associated documentation files (the
6
+ "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish,
8
+ distribute, sublicense, and/or sell copies of the Software, and to
9
+ permit persons to whom the Software is furnished to do so, subject to
10
+ the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
+
4
+ Dir['tasks/**/*.rake'].each { |t| load t }
5
+
6
+ task :default => [:test]
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # genclassinfo
4
+ #
5
+ # Generate Ruby class templates
6
+ #
7
+ # Copyright (c) 2015 Klaus Kämpf <kkaempf@suse.de>
8
+ #
9
+ # Licensed under the Ruby license
10
+ #
11
+ # == Usage
12
+ #
13
+ # genclassinfo [-d] [-h] [-q] [-I <includedir>] [-o <output>] <moffile> [<moffile> ...]
14
+ #
15
+ # -d:
16
+ # turn on debugging
17
+ # -h:
18
+ # show (this) help
19
+ # -q:
20
+ # be quiet
21
+ # -I <includedir>
22
+ # additional include directories to search
23
+ # -o <outputdir>
24
+ # directory to write generated files, defaults to 'generated'
25
+ # <moffile>
26
+ # .mof files to read
27
+ #
28
+
29
+ require 'rubygems'
30
+
31
+ require 'mof'
32
+ require 'pathname'
33
+ require 'fileutils'
34
+
35
+ $:.push(File.join(File.dirname(__FILE__), '..', 'lib'))
36
+
37
+ require 'wbem'
38
+
39
+ def usage msg=nil
40
+ STDERR.puts "Err: #{msg}" if msg
41
+ STDERR.puts "Usage: genclassinfo [-d] <class> [ <class> ...]"
42
+ exit (msg)?1:0
43
+ end
44
+
45
+ #--------------------------------------------------------------------
46
+
47
+ @factory = Wbem::ClassFactory.new
48
+
49
+ if ARGV.empty?
50
+ usage
51
+ end
52
+
53
+ ARGV.each do |c|
54
+ if c == "-d"
55
+ Wbem::debug = 1
56
+ next
57
+ end
58
+ @factory.gen_class c
59
+ end
@@ -9,6 +9,10 @@
9
9
  # Licensed under the MIT license
10
10
  #
11
11
  module Wbem
12
+ require 'wbem/class_factory'
13
+ require 'wbem/conversion'
14
+ require 'wbem/wbem'
15
+
12
16
  @@debug = nil
13
17
  def Wbem.debug
14
18
  @@debug
@@ -19,8 +23,6 @@ module Wbem
19
23
 
20
24
  class Client
21
25
  require 'uri'
22
- require 'wbem/wsman'
23
- require 'wbem/cimxml'
24
26
 
25
27
  #
26
28
  # Wbem::Client.connect uri, protocol = nil
@@ -32,7 +34,7 @@ module Wbem
32
34
  # else - probe connection (cim/xml first)
33
35
  #
34
36
  def self.connect uri, protocol = nil, auth_scheme = nil
35
- STDERR.puts "Wbem::Client.connect(#{uri},#{protocol},#{auth_scheme})"
37
+ STDERR.puts "Wbem::Client.connect(#{uri},#{protocol},#{auth_scheme})" if Wbem.debug
36
38
  unless uri.is_a?(URI)
37
39
  u = URI.parse(uri)
38
40
  # u.port will be set in any case, so check the uri for port specification
@@ -46,16 +48,18 @@ module Wbem
46
48
  unless protocol_given
47
49
  u.port = (u.scheme == "http") ? 5985 : 5986
48
50
  end
51
+ require 'wbem/wsman'
49
52
  return WsmanClient.new u, auth_scheme
50
53
  when "cimxml"
51
54
  unless protocol_given
52
55
  u.port = (u.scheme == "http") ? 5988 : 5989
53
56
  end
57
+ require 'wbem/cimxml'
54
58
  return CimxmlClient.new u
55
59
  end
56
60
  # no connect, check known ports
57
61
  case u.port
58
- when 8888, 8889, 5985, 5986
62
+ when 8888, 8889, 5985, 5986, 16992
59
63
  return Wbem::Client.connect u, :wsman, auth_scheme
60
64
  when 5988, 5989
61
65
  return Wbem::Client.connect u, :cimxml, auth_scheme
@@ -51,6 +51,43 @@ private
51
51
 
52
52
  public
53
53
 
54
+ #
55
+ # parse ObjectPath to Sfcc::Cim::ObjectPath
56
+ # 1. root/cimv2:Linux_ComputerSystem.CreationClassName="Linux_ComputerSystem",Name="foo.bar"
57
+ # 2. localhost:5989/root/cimv2:Linux_ComputerSystem.CreationClassName="Linux_ComputerSystem",Name="heron.suse.de"
58
+ #
59
+ #
60
+ def self.parse_object_path s
61
+ op = nil
62
+ front, values = s.split(".",2)
63
+ STDERR.puts "self.parse_object_path >#{front}<(#{values})"
64
+ frontargs = front.split(":")
65
+ if frontargs.size == 2
66
+ # case 1 above
67
+ namespace, classname = frontargs
68
+ op = Sfcc::Cim::ObjectPath.new(namespace, classname)
69
+ elsif frontargs.size == 3
70
+ host, port_and_namespace, classname = frontargs
71
+ port, namespace = port_and_namespace.split("/", 2)
72
+ op = Sfcc::Cim::ObjectPath.new(namespace, classname)
73
+ else
74
+ raise "CimxmlClient.parse_object_path: Can't parse >#{frontargs.inspect}<"
75
+ end
76
+ # add values
77
+ while values && !values.empty?
78
+ puts "Values >#{values.inspect}<"
79
+ name, rest = values.split("=", 2)
80
+ arg, values = if rest[0,1] == '"' # quoted arg
81
+ rest[1..-1].split(/\",?/, 2)
82
+ else # non-quoted arg
83
+ rest.split(",", 2)
84
+ end
85
+ puts "name(#{name}), arg(#{arg})"
86
+ op.add_key(name, arg)
87
+ end
88
+ puts "Op #{op}"
89
+ op
90
+ end
54
91
  #
55
92
  # Initialize a CIMXML client connection
56
93
  #
@@ -125,10 +162,12 @@ public
125
162
  # @param properties : Hash (optional)
126
163
  #
127
164
  def instance_names namespace, classname=nil, properties={}
165
+ # if namespace is unset, sfcc will generate invalid XML
166
+ namespace ||= "root/cimv2"
128
167
  case namespace
129
168
  when Sfcc::Cim::ObjectPath
130
169
  objectpath = namespace
131
- namespace = objectpath.namespace
170
+ namespace = objectpath.namespace
132
171
  else
133
172
  objectpath = objectpath namespace.to_s, classname, properties
134
173
  end
@@ -143,6 +182,32 @@ public
143
182
  ret
144
183
  end
145
184
 
185
+ #
186
+ # get instance by reference
187
+ #
188
+ # call-seq
189
+ # get Sfcc::Cim::ObjectPath -> Wbem::Instance
190
+ # get ObjectPath-as-String -> Wbem::Instance
191
+ # get "ClassName", "key" => "value", :namespace => "root/interop"
192
+ #
193
+ def get instance_reference, keys = nil
194
+ if keys
195
+ namespace = keys.delete(:namespace) || "root/cimv2"
196
+ instance_reference = Sfcc::Cim::ObjectPath.new(namespace, instance_reference)
197
+ keys.each do |k,v|
198
+ instance_reference.add_key k, v
199
+ end
200
+ end
201
+ puts "@client.get #{instance_reference.class}..." if Wbem.debug
202
+ case instance_reference
203
+ when Sfcc::Cim::ObjectPath
204
+ get_by_objectpath instance_reference
205
+ when String
206
+ get_by_objectpath CimxmlClient.parse_object_path(instance_reference)
207
+ else
208
+ raise "Unsupported Wbem::get #{instance_reference.class}"
209
+ end
210
+ end
146
211
  #
147
212
  # Return matching Wbem::Instance for first instance
148
213
  # matching namespace, classname, properties
@@ -190,5 +255,12 @@ public
190
255
  end
191
256
  end
192
257
 
258
+ #
259
+ # get instance by objectpath
260
+ #
261
+ def get_by_objectpath objpath
262
+ STDERR.puts "#{self.class}.get_by_objectpath #{objpath}" if Wbem.debug
263
+ @client.get_instance(objpath)
264
+ end
193
265
  end # class
194
266
  end # module
@@ -0,0 +1,163 @@
1
+ #
2
+ # Class Factory
3
+ #
4
+ #
5
+ # Creates CIM class with ancestry chain
6
+ #
7
+ # Base class: Wbem::Instance
8
+ #
9
+ module Wbem
10
+ class ClassFactory
11
+ MOFBASE = "/usr/share/mof/cim-current"
12
+ AMTBASE = "/usr/share/mof/iAMT/MOF"
13
+ QUALIFIERS = "qualifiers.mof"
14
+ SCHEMATA = { MOFBASE => "CIM_Schema.mof", AMTBASE => "amt.mof" }
15
+ CLASSDIR = "wbem"
16
+ require 'cim'
17
+ require 'mof'
18
+ require 'pathname'
19
+
20
+ #
21
+ # Constructor
22
+ #
23
+ def initialize basepath = nil
24
+ @basedir = File.expand_path(File.join(basepath || Dir.getwd, CLASSDIR))
25
+ end
26
+ private
27
+
28
+ #
29
+ # parse_with_ancestors
30
+ #
31
+ # Find the superclass name of a class, parse its mof file
32
+ # returns Hash of { classname -> CIM::Class }
33
+ #
34
+
35
+ def parse_with_ancestors name
36
+ # find .mof file
37
+ mofdata = classmap()[name]
38
+ unless mofdata
39
+ raise "Can't find MOF for #{name}"
40
+ end
41
+ mofpath = mofdata[:path]
42
+ # parsed before ?
43
+ mof = mofdata[:mof] rescue nil
44
+ unless mof
45
+ # not parsed, parse now
46
+ puts "Reading mof from #{mofpath}" if Wbem.debug
47
+ begin
48
+ mofs = parser().parse [ QUALIFIERS, "qualifiers_intel.mof", mofpath ]
49
+ rescue Exception => e
50
+ parser.error_handler e
51
+ end
52
+ # puts "==> #{mofs.inspect}"
53
+ # Iterate over all parsed classes
54
+ mofs[mofpath].classes.each do |mofclass|
55
+ next unless mofclass.name == name
56
+ classmap()[name] = { :path => mofpath, :mof => mofclass }
57
+ if mofclass.superclass
58
+ parse_with_ancestors mofclass.superclass
59
+ end
60
+ end
61
+ end
62
+ end
63
+
64
+ #
65
+ # generate method parameter information
66
+ # return nil if no parameters
67
+ #
68
+ def gen_method_parameters direction, parameters, file
69
+ return if parameters.empty?
70
+ file.print "#{direction.inspect} => ["
71
+ first = true
72
+ parameters.each do |p|
73
+ if first
74
+ first = false
75
+ else
76
+ file.print ", "
77
+ end
78
+ # [ <name>, <type>, <out>? ]
79
+ file.print "#{p.name.inspect}, #{p.type.to_sym.inspect}"
80
+ end
81
+ file.print "]"
82
+ return true
83
+ end
84
+ #
85
+ # generate .rb class declaration
86
+ #
87
+ def generate name, file
88
+ require 'erb'
89
+ template = File.read(File.join(File.dirname(__FILE__), "class_template.erb"))
90
+ erb = ERB.new(template)
91
+ code = erb.result(binding)
92
+ Dir.mkdir(@basedir) unless File.directory?(@basedir)
93
+ File.open(file, "w+") do |f|
94
+ f.puts code
95
+ end
96
+ end
97
+
98
+ #
99
+ # classmap - generate map of classes and their .mof files
100
+ #
101
+ def classmap
102
+ return @classmap if @classmap
103
+ # read SCHEMA and build class index to find .mof files quickly
104
+ @classmap = Hash.new
105
+ @includes = [ Pathname.new(".") ]
106
+ SCHEMATA.each do |base, file|
107
+ @includes << base
108
+ allow_cim = (file =~ /^CIM_/) # allow CIM_ only for CIM_Schema.mof
109
+ File.open(File.join(base, file)) do |f|
110
+ f.each do |l|
111
+ if l =~ /^\#pragma\sinclude\s?\(\"(([\w\/_]+)\.mof)\"\).*/
112
+ # $1 Foo/Bar.mof
113
+ # $2 Foo/Bar
114
+ path = $1
115
+ names = $2.split("/")
116
+ name = names[1] || names[0]
117
+ next unless name =~ /_/ # class name must have underscore (rules out 'qualifiers.mof')
118
+ # puts "#{path}:#{name}"
119
+ next if !allow_cim && name =~ /^CIM_/ # skip CIM_ mofs unless allowed
120
+ if @classmap[name]
121
+ raise "Dup #{name} : #{@classmap[name]}"
122
+ else
123
+ @classmap[name] = { :path => path }
124
+ end
125
+ end
126
+ end
127
+ end
128
+ end
129
+ STDERR.puts "Found MOFs for #{@classmap.size} classes" if Wbem.debug
130
+ @classmap
131
+ end
132
+
133
+ #
134
+ # MOF parser access
135
+ #
136
+ def parser
137
+ @parser ||= MOF::Parser.new :style => :cim, :includes => @includes, :quiet => true
138
+ end
139
+ public
140
+ #
141
+ # Class Factory
142
+ #
143
+ def class_for name
144
+ begin
145
+ path = "#{@basedir}/#{name}"
146
+ require path
147
+ return Object.const_get("Wbem").const_get(name)
148
+ rescue LoadError
149
+ raise "'#{path}.rb' not found, use 'genclass' of ruby-wbem to generate class '#{name}'"
150
+ end
151
+ end
152
+ #
153
+ # gen_class
154
+ #
155
+ def gen_class name
156
+ mofname = name + ".mof"
157
+ classpath = File.join(@basedir, "#{name}.rb")
158
+ parse_with_ancestors name
159
+ generate name, classpath
160
+ class_for name
161
+ end # def create
162
+ end # class ClassFactory
163
+ end # module Wbem
@@ -0,0 +1,48 @@
1
+ <%
2
+ # @classes[name] = { :path => mofpath, :mof => mofclass }
3
+
4
+ def collect_superclasses name
5
+ classdata = @classmap[name]
6
+ raise "No such class: #{name}" unless classdata
7
+ mofclass = classdata[:mof]
8
+ superclass = mofclass.superclass
9
+ [mofclass] + ((superclass)?collect_superclasses(superclass):[])
10
+ end
11
+ %>
12
+
13
+ # Class information for <%= name %>
14
+ # Generated by 'wbem' for use with ruby-wbem
15
+
16
+ require 'rubygems'
17
+ require 'cim'
18
+ require 'wbem'
19
+
20
+ module Wbem
21
+
22
+ class <%= name %> < Wbem::Instance
23
+ <% classes = collect_superclasses name %>
24
+ <% known_features = Hash.new %>
25
+ TYPEMAP = {
26
+ <% classes.each do |mofclass|
27
+ mofclass.features.each do |f|
28
+ next if known_features[f.name]
29
+ known_features[f.name] = f
30
+ if f.method? %>
31
+ # <%= mofclass.name %>.<%= f.name %>()
32
+ <%= f.name.inspect %> => [ <%= f.type.to_sym.inspect %>, <% f.parameters.each do |p| %>
33
+ [ <%= p.name.inspect %>, <%= p.type.to_sym.inspect %>, <%= (p.includes?(:out))?":out":":in" %> ], <% end %>
34
+ ],
35
+ <% else %>
36
+ # <%= mofclass.name %>.<%= f.name %>
37
+ <%= f.name.inspect %> => <%= f.type.to_sym.inspect %>,
38
+ <% end
39
+ end
40
+ end %>
41
+ }
42
+
43
+ def _typemap
44
+ TYPEMAP
45
+ end
46
+
47
+ end # class
48
+ end # module