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 +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
|