wbem 0.3.0 → 0.5.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 +4 -4
- data/CHANGELOG.rdoc +20 -0
- data/Gemfile +2 -0
- data/MIT-LICENSE +22 -0
- data/Rakefile +6 -0
- data/bin/genclassinfo +59 -0
- data/lib/wbem.rb +8 -4
- data/lib/wbem/cimxml.rb +73 -1
- data/lib/wbem/class_factory.rb +163 -0
- data/lib/wbem/class_template.erb +48 -0
- data/lib/wbem/conversion.rb +173 -0
- data/lib/wbem/openwsman.rb +51 -0
- data/lib/wbem/version.rb +1 -1
- data/lib/wbem/wbem.rb +108 -4
- data/lib/wbem/wsman.rb +58 -168
- data/lib/wbem/wsman_instance.rb +148 -0
- data/samples/amt.rb +129 -0
- data/samples/enum.rb +34 -0
- data/samples/get.rb +47 -0
- data/tasks/clean.rake +2 -0
- data/tasks/doc.rake +15 -0
- data/tasks/test.rake +6 -0
- data/test/helper.rb +3 -0
- data/test/test_class_factory.rb +25 -0
- data/test/test_classnames.rb +68 -0
- data/test/test_connect.rb +91 -0
- data/test/test_epr.rb +27 -0
- data/test/test_loading.rb +13 -0
- data/test/test_namespaces.rb +28 -0
- data/test/test_product.rb +56 -0
- data/test/test_profiles.rb +33 -0
- data/test/test_services.rb +33 -0
- data/test/test_systems.rb +34 -0
- data/wbem.gemspec +37 -0
- metadata +76 -7
@@ -0,0 +1,148 @@
|
|
1
|
+
|
2
|
+
module WsmanInstance
|
3
|
+
|
4
|
+
require "wbem/wbem"
|
5
|
+
require "openwsman"
|
6
|
+
require "cim"
|
7
|
+
#
|
8
|
+
# Class constructor
|
9
|
+
# client - client instance, used for method invocation
|
10
|
+
# either a Wbem::CimxmlClient
|
11
|
+
# or a Wbem::WsmanClient
|
12
|
+
#
|
13
|
+
# instance_ref - instance reference
|
14
|
+
# either ObjectPath (Wbem::CimxmlClient) or
|
15
|
+
# EndPointReference (Wbem::WsmanClient)
|
16
|
+
#
|
17
|
+
# instance_data - instance data
|
18
|
+
# Wbem::WsmanClient: Openwsman::XmlNode
|
19
|
+
# Wbem::CimxmlClient: nil (instance_ref has all information)
|
20
|
+
#
|
21
|
+
def wsman_initialize client, epr_or_uri, node
|
22
|
+
# STDERR.puts "Wbem::WsmanInstance.new epr_or_uri #{epr_or_uri}"
|
23
|
+
@node = node.body.child rescue node
|
24
|
+
# STDERR.puts "Wsman::Instance.new @node #{@node.class}"
|
25
|
+
@epr = (epr_or_uri.is_a? Openwsman::EndPointReference) ? epr_or_uri : Openwsman::EndPointReference.new(epr_or_uri) if epr_or_uri
|
26
|
+
@client = client
|
27
|
+
end
|
28
|
+
def classname
|
29
|
+
@epr.classname
|
30
|
+
end
|
31
|
+
#
|
32
|
+
# attribute iterator
|
33
|
+
#
|
34
|
+
def attributes
|
35
|
+
@node.each do |node|
|
36
|
+
# STDERR.puts "Wsman::Instance #{node}"
|
37
|
+
yield [ node.name, node.text ]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
#
|
41
|
+
# access attribute by name
|
42
|
+
#
|
43
|
+
def [] name
|
44
|
+
name = name.to_s
|
45
|
+
node = @node.find(nil, name) rescue nil
|
46
|
+
return nil unless node
|
47
|
+
begin
|
48
|
+
type = _typemap()[name]
|
49
|
+
rescue
|
50
|
+
raise "Property #{name} of #{self.class} has unknown type"
|
51
|
+
end
|
52
|
+
# puts "#{self.class}[#{name}]: #{node.name}<#{type.inspect}>"
|
53
|
+
Wbem::Conversion.to_ruby type, node
|
54
|
+
end
|
55
|
+
#
|
56
|
+
# to_s - stringify
|
57
|
+
#
|
58
|
+
def to_s
|
59
|
+
s = "#{@epr.classname}\n"
|
60
|
+
@node.each do |child|
|
61
|
+
s << "\t" << child.name << ": "
|
62
|
+
v = self[child.name]
|
63
|
+
s << v.to_s if v
|
64
|
+
s << "\n"
|
65
|
+
end
|
66
|
+
s
|
67
|
+
end
|
68
|
+
#
|
69
|
+
# Instance#invoke
|
70
|
+
# name => String
|
71
|
+
# type => [ :uint32,
|
72
|
+
# [ "RequestedState", :uint16, :in ],
|
73
|
+
# [ "Job", :class, :out ],
|
74
|
+
# [ "TimeoutPeriod", :dateTime, :in ],
|
75
|
+
# ]
|
76
|
+
# args => Array
|
77
|
+
#
|
78
|
+
def invoke name, type, args
|
79
|
+
# STDERR.puts "#{__FILE__}: #{self.class}#invoke #{name}<#{type}>(#{args.inspect})"
|
80
|
+
result_type = type.shift
|
81
|
+
argsin = {}
|
82
|
+
argsout = {}
|
83
|
+
loop do
|
84
|
+
break if args.empty?
|
85
|
+
if type.empty?
|
86
|
+
raise "Excess argument '#{args.shift}' at pos #{argsin.size + argsout.size + 1} in call to #{self.class}.#{name}"
|
87
|
+
end
|
88
|
+
argname, argtype, direction = type.shift
|
89
|
+
value = args.shift
|
90
|
+
case direction
|
91
|
+
when :in
|
92
|
+
argsin[argname] = Wbem::Conversion.from_ruby( argtype, value )
|
93
|
+
when :out
|
94
|
+
unless value.nil? || value.is_a?(:symbol)
|
95
|
+
raise "Argument '#{argname}' of #{self.class}.#{name} is 'out', pass nil to symbol instead of value"
|
96
|
+
end
|
97
|
+
argsout[argname] = value
|
98
|
+
else
|
99
|
+
raise "Arg #{argname} of #{self.class}.#{name} has bad direction #{direction.inspect}"
|
100
|
+
end
|
101
|
+
end
|
102
|
+
STDERR.puts "\tproperties #{argsin.inspect}" if Wbem.debug
|
103
|
+
STDERR.puts "\targsout #{argsout.inspect}" if Wbem.debug
|
104
|
+
options = Openwsman::ClientOptions.new
|
105
|
+
options.set_dump_request if Wbem.debug
|
106
|
+
options.properties = argsin
|
107
|
+
@epr.each do |k,v|
|
108
|
+
options.add_selector( k, v )
|
109
|
+
end
|
110
|
+
STDERR.puts "\tinvoke" if Wbem.debug
|
111
|
+
res = @client.client.invoke(options, @epr.resource_uri, name.to_s)
|
112
|
+
raise "Invoke failed with: #{@client.fault_string}" unless res
|
113
|
+
raise Openwsman::Exception.new(res) if res.fault?
|
114
|
+
STDERR.puts "\n\tresult #{res.to_xml}\n" if Wbem.debug
|
115
|
+
result = res.find(uri, "#{name}_OUTPUT").find(uri, "ReturnValue").text
|
116
|
+
Wbem::Conversion.to_ruby result_type, result
|
117
|
+
end
|
118
|
+
|
119
|
+
#
|
120
|
+
# method_missing
|
121
|
+
# needs to be here to access TYPEMAP
|
122
|
+
#
|
123
|
+
def method_missing name, *args
|
124
|
+
# STDERR.puts "Wbem::WsmanInstance.method_missing #{name}"
|
125
|
+
# http://stackoverflow.com/questions/8960685/ruby-why-does-puts-call-to-ary
|
126
|
+
raise NoMethodError if name == :to_ary
|
127
|
+
name = name.to_s
|
128
|
+
assign = false
|
129
|
+
if name[-1,1] == '=' # assignment
|
130
|
+
name = name[0...-1]
|
131
|
+
assign = true
|
132
|
+
end
|
133
|
+
type = _typemap[name]
|
134
|
+
if type.is_a? Array
|
135
|
+
invoke(name, type, args)
|
136
|
+
else
|
137
|
+
return nil unless type # unknown property
|
138
|
+
if assign
|
139
|
+
# property assignment
|
140
|
+
self[name] = Wbem::Conversion.from_ruby type, args[0]
|
141
|
+
else
|
142
|
+
# property read
|
143
|
+
value = self[name]
|
144
|
+
Wbem::Conversion.to_ruby type, value
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end # method_missing
|
148
|
+
end # module WsmanInstance
|
data/samples/amt.rb
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
#
|
2
|
+
# Managed iAMT
|
3
|
+
# SOL (serial-over-lan)
|
4
|
+
# https://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide/WordDocuments/enablingthesolinterface.htm
|
5
|
+
# KVM (keyboard-video-moust)
|
6
|
+
# https://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide/WordDocuments/kvmconfiguration.htm
|
7
|
+
#
|
8
|
+
# Written by Klaus Kämpf 2015
|
9
|
+
#
|
10
|
+
$:.unshift File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
|
11
|
+
|
12
|
+
require 'wbem'
|
13
|
+
|
14
|
+
def usage msg = nil
|
15
|
+
if msg
|
16
|
+
STDERR.puts "** Err: #{msg}"
|
17
|
+
STDERR.puts "amt [-d] {sol|kvm} {start|stop} <uri>"
|
18
|
+
exit 1
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def connect url
|
23
|
+
usage "<url> missing" unless url
|
24
|
+
return Wbem::Client.connect url, :wsman
|
25
|
+
end
|
26
|
+
|
27
|
+
def enable_listener instance
|
28
|
+
unless instance.ListenerEnabled
|
29
|
+
instance.ListenerEnabled = true
|
30
|
+
instance.put
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def sol_start client
|
35
|
+
instance = client.get "AMT_RedirectionService", "Name" => "Intel(r) AMT Redirection Service"
|
36
|
+
case instance.EnabledState
|
37
|
+
when 32770
|
38
|
+
puts "SOL is enabled and IDE-R is disabled"
|
39
|
+
when 32771
|
40
|
+
puts "SOL and IDE-R are enabled"
|
41
|
+
when 32768
|
42
|
+
# SOL and IDE-R are disabled
|
43
|
+
puts "Enabling SOL"
|
44
|
+
instance.RequestStateChange(32770)
|
45
|
+
when 32769
|
46
|
+
# SOL is disabled and IDE-R is enabled
|
47
|
+
puts "Enabling SOL"
|
48
|
+
instance.RequestStateChange(32771)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def sol_stop client
|
53
|
+
instance = client.get "AMT_RedirectionService", "Name" => "Intel(r) AMT Redirection Service"
|
54
|
+
case instance.EnabledState
|
55
|
+
when 32770
|
56
|
+
# SOL is enabled and IDE-R is disabled
|
57
|
+
puts "Disabling SOL"
|
58
|
+
instance.RequestStateChange(32768)
|
59
|
+
when 32771
|
60
|
+
# SOL and IDE-R are enabled
|
61
|
+
puts "Disabling SOL"
|
62
|
+
instance.RequestStateChange(32769)
|
63
|
+
when 32768
|
64
|
+
puts "SOL and IDE-R are disabled"
|
65
|
+
when 32769
|
66
|
+
puts "SOL is disabled and IDE-R is enabled"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def kvm_start client
|
71
|
+
sap = client.get "CIM_KVMRedirectionSAP", "Name" => "KVM Redirection Service Access Point"
|
72
|
+
unless sap.EnabledState
|
73
|
+
data = client.get "IPS_KVMRedirectionSettingData", "InstanceID" => "Intel(r) KVM Redirection Settings"
|
74
|
+
if data.EnabledByMEBx
|
75
|
+
result = sap.RequestStateChange(2)
|
76
|
+
if result == 0
|
77
|
+
# enable listener
|
78
|
+
else
|
79
|
+
end
|
80
|
+
end
|
81
|
+
else
|
82
|
+
puts "KVM already enabled"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def kvm_stop client
|
87
|
+
sap = client.get "CIM_KVMRedirectionSAP", "Name" => "KVM Redirection Service Access Point"
|
88
|
+
if sap.EnabledState
|
89
|
+
data = client.get "IPS_KVMRedirectionSettingData", "InstanceID" => "Intel(r) KVM Redirection Settings"
|
90
|
+
if data.EnabledByMEBx
|
91
|
+
result = sap.RequestStateChange(3)
|
92
|
+
if result == 0
|
93
|
+
# disable listener
|
94
|
+
else
|
95
|
+
end
|
96
|
+
end
|
97
|
+
else
|
98
|
+
puts "KVM already disabled"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# ---------------------------------------------------------
|
103
|
+
target = nil
|
104
|
+
loop do
|
105
|
+
target = ARGV.shift
|
106
|
+
break unless target && target[0,1] == '-'
|
107
|
+
case target[1..-1]
|
108
|
+
when 'd'
|
109
|
+
Wbem.debug = 99
|
110
|
+
else
|
111
|
+
usage "Unknown option '#{target}'"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
cmd = ARGV.shift
|
116
|
+
url = ARGV.shift
|
117
|
+
|
118
|
+
case [target, cmd]
|
119
|
+
when ["sol", "start"]
|
120
|
+
sol_start( connect(url) )
|
121
|
+
when ["sol", "stop"]
|
122
|
+
sol_stop( connect(url) )
|
123
|
+
when ["kvm", "start"]
|
124
|
+
kvm_start( connect(url) )
|
125
|
+
when ["kvm", "stop"]
|
126
|
+
kvm_stop( connect(url) )
|
127
|
+
else
|
128
|
+
usage "Unknown command: #{target.inspect} #{cmd.inspect}"
|
129
|
+
end
|
data/samples/enum.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
#
|
2
|
+
# ruby-wbem sample code
|
3
|
+
#
|
4
|
+
# Enumerate instances
|
5
|
+
#
|
6
|
+
# Written by Klaus Kämpf 2015
|
7
|
+
#
|
8
|
+
$:.unshift File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
|
9
|
+
|
10
|
+
require 'wbem'
|
11
|
+
|
12
|
+
def usage msg = nil
|
13
|
+
if msg
|
14
|
+
STDERR.puts "** Err: #{msg}"
|
15
|
+
exit 1
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def connect url
|
20
|
+
usage "<url> missing" unless url
|
21
|
+
return Wbem::Client.connect url
|
22
|
+
end
|
23
|
+
|
24
|
+
url = ARGV.shift
|
25
|
+
if url == "-d"
|
26
|
+
Wbem.debug = -1
|
27
|
+
url = ARGV.shift
|
28
|
+
end
|
29
|
+
client = connect url
|
30
|
+
eprs = client.instance_names nil, ARGV.shift
|
31
|
+
eprs.each do |epr|
|
32
|
+
instance = client.get(epr)
|
33
|
+
puts "#{instance.class}: #{instance}\n"
|
34
|
+
end
|
data/samples/get.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
#
|
2
|
+
# ruby-wbem sample code
|
3
|
+
#
|
4
|
+
# Get instance
|
5
|
+
#
|
6
|
+
# Written by Klaus Kämpf 2015
|
7
|
+
#
|
8
|
+
$:.unshift File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
|
9
|
+
|
10
|
+
require 'wbem'
|
11
|
+
|
12
|
+
def usage msg = nil
|
13
|
+
if msg
|
14
|
+
STDERR.puts "** Err: #{msg}"
|
15
|
+
STDERR.puts "Usage:"
|
16
|
+
STDERR.puts "get [-d] <url> <class> <key>=<value> [<key>=<value> ...]"
|
17
|
+
exit 1
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def connect url
|
22
|
+
usage "<url> missing" unless url
|
23
|
+
return Wbem::Client.connect url
|
24
|
+
end
|
25
|
+
|
26
|
+
url = ARGV.shift
|
27
|
+
if url == "-d"
|
28
|
+
Wbem.debug = -1
|
29
|
+
url = ARGV.shift
|
30
|
+
end
|
31
|
+
usage "<url> missing" unless url
|
32
|
+
klass = ARGV.shift
|
33
|
+
usage "<class> missing" unless klass
|
34
|
+
args = {}
|
35
|
+
while arg = ARGV.shift
|
36
|
+
k,v = arg.split("=")
|
37
|
+
usage "Bad <key>=<value> pair" unless k && v
|
38
|
+
args[k] = v
|
39
|
+
end
|
40
|
+
usage "needs at least one <key>=<value> pair" if args.empty?
|
41
|
+
client = connect url
|
42
|
+
instance = client.get klass, args
|
43
|
+
if instance
|
44
|
+
puts "#{instance.class}: #{instance}\n"
|
45
|
+
else
|
46
|
+
puts "Not found"
|
47
|
+
end
|
data/tasks/clean.rake
ADDED
data/tasks/doc.rake
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
begin
|
2
|
+
require 'yard'
|
3
|
+
YARD::Rake::YardocTask.new(:doc) do |t|
|
4
|
+
t.files = ['lib/**/*.rb']
|
5
|
+
t.options = ['--no-private']
|
6
|
+
end
|
7
|
+
rescue LoadError
|
8
|
+
STDERR.puts "Install yard if you want prettier docs"
|
9
|
+
require 'rdoc/task'
|
10
|
+
require 'wbem/version'
|
11
|
+
Rake::RDocTask.new(:doc) do |rdoc|
|
12
|
+
rdoc.rdoc_dir = "doc"
|
13
|
+
rdoc.title = "wbem #{Wbem::VERSION}"
|
14
|
+
end
|
15
|
+
end
|
data/tasks/test.rake
ADDED
data/test/helper.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
DIR = File.dirname(__FILE__)
|
2
|
+
$: << DIR
|
3
|
+
require 'helper'
|
4
|
+
require 'wbem'
|
5
|
+
|
6
|
+
class TestClassFactory < Test::Unit::TestCase
|
7
|
+
def setup
|
8
|
+
@factory = Wbem::ClassFactory.new File.join(DIR, "wbem")
|
9
|
+
end
|
10
|
+
#def teardown
|
11
|
+
#end
|
12
|
+
def test_initialize
|
13
|
+
assert @factory
|
14
|
+
end
|
15
|
+
def test_create_cim
|
16
|
+
klass = @factory.gen_class "CIM_ManagedElement"
|
17
|
+
assert klass
|
18
|
+
assert klass.new(nil,nil).is_a? Wbem::CIM_ManagedElement
|
19
|
+
end
|
20
|
+
def test_create_ips
|
21
|
+
klass = @factory.gen_class "IPS_KVMRedirectionSettingData"
|
22
|
+
assert klass
|
23
|
+
assert klass.new(nil,nil).is_a? Wbem::IPS_KVMRedirectionSettingData
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
$: << File.dirname(__FILE__)
|
2
|
+
require 'helper'
|
3
|
+
require 'wbem'
|
4
|
+
|
5
|
+
class TestClassnames < Test::Unit::TestCase
|
6
|
+
#def setup
|
7
|
+
#end
|
8
|
+
#def teardown
|
9
|
+
#end
|
10
|
+
def test_classnames_cimxml
|
11
|
+
c = Wbem::Client.connect("https://wsman:secret@localhost:5989", :cimxml)
|
12
|
+
assert c
|
13
|
+
names = c.class_names "root/cimv2"
|
14
|
+
assert names
|
15
|
+
assert names.size > 0
|
16
|
+
assert !names.include?("CIM_ManagedSystemElement")
|
17
|
+
puts "test_classnames_cimxml: #{names.size} classes"
|
18
|
+
end
|
19
|
+
def test_classnames_cimxml_partial
|
20
|
+
c = Wbem::Client.connect("https://wsman:secret@localhost:5989", :cimxml)
|
21
|
+
assert c
|
22
|
+
names = c.class_names "root/cimv2", "CIM_ManagedElement"
|
23
|
+
assert names
|
24
|
+
assert names.size > 0
|
25
|
+
assert names.include?("CIM_ManagedSystemElement")
|
26
|
+
puts "test_classnames_cimxml: #{names.size} classes"
|
27
|
+
end
|
28
|
+
def test_classnames_cimxml_deep
|
29
|
+
c = Wbem::Client.connect("https://wsman:secret@localhost:5989", :cimxml)
|
30
|
+
assert c
|
31
|
+
names = c.class_names "root/cimv2", true
|
32
|
+
assert names
|
33
|
+
assert names.size > 0
|
34
|
+
puts "test_classnames_cimxml: #{names.size} classes"
|
35
|
+
end
|
36
|
+
def test_classnames_openwsman
|
37
|
+
c = Wbem::Client.connect("http://wsman:secret@localhost:5985", :wsman)
|
38
|
+
assert c
|
39
|
+
names = c.class_names "root/cimv2"
|
40
|
+
assert names
|
41
|
+
assert names.size > 0
|
42
|
+
puts "test_classnames_openwsman: #{names.size} classes"
|
43
|
+
end
|
44
|
+
def test_classnames_openwsman_deep
|
45
|
+
c = Wbem::Client.connect("http://wsman:secret@localhost:5985", :wsman)
|
46
|
+
assert c
|
47
|
+
names = c.class_names "root/cimv2", true
|
48
|
+
assert names
|
49
|
+
assert names.size > 0
|
50
|
+
puts "test_classnames_openwsman_deep: #{names.size} classes"
|
51
|
+
end
|
52
|
+
def test_classnames_winrm
|
53
|
+
c = Wbem::Client.connect("http://wsman:secret@wsman2003sp2.suse.de:5985", :wsman, :basic)
|
54
|
+
assert c
|
55
|
+
names = c.class_names "root/cimv2"
|
56
|
+
assert names
|
57
|
+
assert names.size > 0
|
58
|
+
puts "test_classnames_winrm: #{names.size} classes"
|
59
|
+
end
|
60
|
+
def test_classnames_winrm_deep
|
61
|
+
c = Wbem::Client.connect("http://wsman:secret@wsman2003sp2.suse.de:5985", :wsman, :basic)
|
62
|
+
assert c
|
63
|
+
names = c.class_names "root/cimv2", true
|
64
|
+
assert names
|
65
|
+
assert names.size > 0
|
66
|
+
puts "test_classnames_winrm_deep: #{names.size} classes"
|
67
|
+
end
|
68
|
+
end
|