ilorb 0.0.1 → 0.0.2
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 +7 -0
- data/Gemfile.lock +4 -4
- data/README.md +4 -2
- data/lib/ilorb/ribcl.rb +1 -1
- data/lib/ilorb/version.rb +2 -2
- data/lib/ilorb.rb +203 -2
- data/spec/ilo_spec.rb +2 -2
- metadata +19 -34
- data/lib/ilorb/ilo.rb +0 -207
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4dda8bc7feb3994e4cfbd360716f380af125b2e0
|
4
|
+
data.tar.gz: 9c2b8b3d6f61d440df5039feaf2f94769b9c2ec9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 423966543881ffd1e3720fdc0d44bd2858dd4f4cbd2681c72d2ed7d7b9b64b92b4b796d733df0e0d2120c4f8adf1e2e698350e1a24e0377e6a6c3c90e81a76f2
|
7
|
+
data.tar.gz: d43910027cb1dc97efe24c9f81c743d49fc56731d744a73f7f508b9b3755998949b64a2ae9361599b61af2cbf4348e636d83e61f632a3305e7623b08e78b3a57
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
ilorb (0.0.
|
4
|
+
ilorb (0.0.2)
|
5
5
|
nokogiri
|
6
6
|
nori
|
7
7
|
|
@@ -14,10 +14,10 @@ GEM
|
|
14
14
|
safe_yaml (~> 0.9.0)
|
15
15
|
diff-lcs (1.2.4)
|
16
16
|
method_source (0.8.1)
|
17
|
-
mini_portile (0.5.
|
18
|
-
nokogiri (1.6.
|
17
|
+
mini_portile (0.5.3)
|
18
|
+
nokogiri (1.6.1)
|
19
19
|
mini_portile (~> 0.5.0)
|
20
|
-
nori (2.
|
20
|
+
nori (2.4.0)
|
21
21
|
pry (0.9.12.2)
|
22
22
|
coderay (~> 1.0.5)
|
23
23
|
method_source (~> 0.8)
|
data/README.md
CHANGED
@@ -16,11 +16,13 @@ HP, Integrated Lights Out and iLO are trademarks of HP, with whom the author of
|
|
16
16
|
|
17
17
|
## Examples
|
18
18
|
|
19
|
+
WARNING: as of 0.0.2, `ILORb::ILO` content has been moved to `ILORb`. Just use `ILORb#new`
|
20
|
+
|
19
21
|
```ruby
|
20
22
|
require 'json'
|
21
23
|
require 'ilorb'
|
22
24
|
|
23
|
-
ilo = ILORb
|
25
|
+
ilo = ILORb.new(
|
24
26
|
:hostname => "10.200.0.1",
|
25
27
|
:login => "Admin",
|
26
28
|
:password => "SECRET",
|
@@ -91,7 +93,7 @@ Dependencies:
|
|
91
93
|
Install:
|
92
94
|
* git clone https://github.com/josqu4red/ilorb
|
93
95
|
OR
|
94
|
-
* gem install ilorb
|
96
|
+
* gem install ilorb
|
95
97
|
|
96
98
|
## Credits
|
97
99
|
|
data/lib/ilorb/ribcl.rb
CHANGED
data/lib/ilorb/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
|
2
|
-
VERSION = "0.0.
|
1
|
+
class ILORb
|
2
|
+
VERSION = "0.0.2"
|
3
3
|
end
|
data/lib/ilorb.rb
CHANGED
@@ -1,5 +1,206 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'socket'
|
3
|
+
require 'openssl'
|
4
|
+
require 'net/https'
|
5
|
+
require 'nokogiri'
|
6
|
+
require 'nori'
|
1
7
|
require 'ilorb/ribcl'
|
2
|
-
require 'ilorb/ilo'
|
3
8
|
|
4
|
-
|
9
|
+
class ILORb
|
10
|
+
|
11
|
+
class NotImplemented < StandardError; end
|
12
|
+
|
13
|
+
def initialize(config = {})
|
14
|
+
@hostname = config[:hostname]
|
15
|
+
@login = config[:login] || "Administrator"
|
16
|
+
@password = config[:password]
|
17
|
+
@port = config[:port] || 443
|
18
|
+
@protocol = config[:protocol] || :http
|
19
|
+
@verify_ssl = config[:verify_ssl] || false
|
20
|
+
@ribcl_path = "/ribcl"
|
21
|
+
|
22
|
+
@log = Logger.new(STDOUT)
|
23
|
+
@log.level = config[:debug] ? Logger::DEBUG : Logger::WARN
|
24
|
+
|
25
|
+
@nori = Nori.new(:convert_tags_to => lambda{|tag| tag.downcase.to_sym})
|
26
|
+
|
27
|
+
setup_commands
|
28
|
+
end
|
29
|
+
|
30
|
+
# args should be empty or contain a hash anytime
|
31
|
+
def method_missing(name, *args, &block)
|
32
|
+
if @ribcl.has_command?(name)
|
33
|
+
command = @ribcl.command(name)
|
34
|
+
|
35
|
+
raise NotImplemented, "#{name} is not supported" unless command.supported?
|
36
|
+
|
37
|
+
params = args.first || {}
|
38
|
+
attributes = {}
|
39
|
+
element_map = nil
|
40
|
+
|
41
|
+
#TODO check for text
|
42
|
+
|
43
|
+
command.get_attributes.each do |attr|
|
44
|
+
# Attributes are mandatory
|
45
|
+
error("Attribute #{attr} missing in #{name} call") unless params.has_key?(attr)
|
46
|
+
attributes.store(attr, @ribcl.encode(params.delete(attr)))
|
47
|
+
end
|
48
|
+
|
49
|
+
element_map = command.map_elements
|
50
|
+
|
51
|
+
elements_array = []
|
52
|
+
|
53
|
+
[ params ].flatten.each do |params_hash|
|
54
|
+
elements = {}
|
55
|
+
params_hash.each do |key, value|
|
56
|
+
# Elements are not mandatory for now
|
57
|
+
elements.store(key, @ribcl.encode(params_hash.delete(key))) if element_map.has_key?(key)
|
58
|
+
end
|
59
|
+
elements_array << elements
|
60
|
+
end
|
61
|
+
|
62
|
+
#TODO check for CDATA
|
63
|
+
|
64
|
+
@log.info("Calling method #{name}")
|
65
|
+
request = ribcl_request(command, attributes) do |xml|
|
66
|
+
elements_array.each do |elements_hash|
|
67
|
+
elements_hash.each do |key, value|
|
68
|
+
elt = command.get_elements[element_map[key].first]
|
69
|
+
if elt.is_a?(Array)
|
70
|
+
attrs = Hash[elt.map{|x| [x, elements_hash.delete(element_map.invert[[element_map[key].first, x]])]}]
|
71
|
+
else
|
72
|
+
attrs = {element_map[key].last => value}
|
73
|
+
end
|
74
|
+
xml.send(element_map[key].first, attrs)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
response = send_request(request)
|
80
|
+
parse_response(response, name)
|
81
|
+
else
|
82
|
+
super
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def respond_to(name)
|
87
|
+
@ribcl.has_command?(name) ? true : super
|
88
|
+
end
|
89
|
+
|
90
|
+
def supported_commands
|
91
|
+
@ribcl.select{|name, command| command.supported?}.keys
|
92
|
+
end
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
def send_request(xml)
|
97
|
+
case @protocol
|
98
|
+
when :http
|
99
|
+
send_http_request(xml)
|
100
|
+
when :raw
|
101
|
+
send_raw_request(xml)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# ILO >= 3 speak HTTP
|
106
|
+
# Send XML request with HTTP POST and get back XML messages
|
107
|
+
def send_http_request(xml)
|
108
|
+
http = Net::HTTP.new(@hostname, @port)
|
109
|
+
http.use_ssl = true
|
110
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE unless @verify_ssl
|
111
|
+
|
112
|
+
@log.info("Sending POST request to #{@hostname}:#{@port}#{@ribcl_path}")
|
113
|
+
@log.debug("Request:\n#{xml}")
|
114
|
+
response = http.post(@ribcl_path, xml)
|
115
|
+
if response.is_a?(Net::HTTPNotFound)
|
116
|
+
@protocol = :raw
|
117
|
+
@log.info("Got 404, switching to RAW protocol")
|
118
|
+
send_raw_request(xml)
|
119
|
+
else
|
120
|
+
response.body
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# Older ILO just eat raw XML
|
125
|
+
# Send XML over raw SSL-wrapped TCP socket and read XML stream
|
126
|
+
def send_raw_request(xml)
|
127
|
+
sock = TCPSocket.new(@hostname, @port)
|
128
|
+
|
129
|
+
ctx = OpenSSL::SSL::SSLContext.new(:TLSv1)
|
130
|
+
ctx.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
131
|
+
ssl_sock = OpenSSL::SSL::SSLSocket.new(sock, ctx)
|
132
|
+
ssl_sock.sync_close = true
|
133
|
+
|
134
|
+
@log.info("Connecting to #{@hostname}:#{@port}")
|
135
|
+
ssl_sock.connect
|
136
|
+
@log.debug("Request:\n#{xml}")
|
137
|
+
ssl_sock.puts("#{xml}\r\n")
|
138
|
+
response = ""
|
139
|
+
while line = ssl_sock.gets
|
140
|
+
response += line
|
141
|
+
end
|
142
|
+
ssl_sock.close
|
143
|
+
|
144
|
+
response
|
145
|
+
end
|
146
|
+
|
147
|
+
def parse_response(xml, command)
|
148
|
+
@log.debug("Response:\n#{xml}")
|
149
|
+
|
150
|
+
# ILO sends back multiple XML documents, split by XML header and remove first (empty)
|
151
|
+
messages = xml.split(/<\?xml.*?\?>\r?\n/).drop(1)
|
152
|
+
|
153
|
+
output = {}
|
154
|
+
|
155
|
+
messages.each do |doc|
|
156
|
+
xml_doc = Nokogiri::XML(doc){|cfg| cfg.nonet.noblanks}
|
157
|
+
|
158
|
+
xml_doc.root.children.each do |node|
|
159
|
+
case node.name
|
160
|
+
when "RESPONSE"
|
161
|
+
code = node.attr("STATUS").to_i(16)
|
162
|
+
message = node.attr("MESSAGE")
|
163
|
+
if code == 0
|
164
|
+
output[:status] = { :code => code, :message => message }
|
165
|
+
else
|
166
|
+
output[:status] = { :code => code, :message => message }
|
167
|
+
@log.error("#{message} (#{code})")
|
168
|
+
break
|
169
|
+
end
|
170
|
+
when "INFORM"
|
171
|
+
# OSEF
|
172
|
+
else # actual result
|
173
|
+
output.merge!(@nori.parse(node.to_s))
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
output
|
179
|
+
end
|
180
|
+
|
181
|
+
def ribcl_request(command, args = {}, &block)
|
182
|
+
builder = Nokogiri::XML::Builder.new do |xml|
|
183
|
+
xml.ribcl(:version => "2.0") {
|
184
|
+
xml.login(:password => @password, :user_login => @login) {
|
185
|
+
xml.send(command.context, :mode => command.mode) {
|
186
|
+
xml.send(command.name, args) {
|
187
|
+
yield xml if block_given?
|
188
|
+
}
|
189
|
+
}
|
190
|
+
}
|
191
|
+
}
|
192
|
+
end
|
193
|
+
|
194
|
+
builder.to_xml
|
195
|
+
end
|
196
|
+
|
197
|
+
def setup_commands
|
198
|
+
@ribcl = ILORb::RIBCL.load(File.join(File.dirname(__FILE__), "ilorb/definitions", "*.rb"))
|
199
|
+
nil
|
200
|
+
end
|
201
|
+
|
202
|
+
def error(message)
|
203
|
+
@log.error(message)
|
204
|
+
raise message
|
205
|
+
end
|
5
206
|
end
|
data/spec/ilo_spec.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe ILORb
|
3
|
+
describe ILORb do
|
4
4
|
let(:hostname) { "10.200.0.1" }
|
5
5
|
let(:login) { "Admin" }
|
6
6
|
let(:password) { "SECRET" }
|
7
|
-
let(:ilo) { ILORb
|
7
|
+
let(:ilo) { ILORb.new(hostname: hostname, login: login, password: password) }
|
8
8
|
|
9
9
|
describe "#get_network_settings" do
|
10
10
|
before do
|
metadata
CHANGED
@@ -1,110 +1,97 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ilorb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.0.2
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Jonathan Amiez
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2014-05-02 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: bundler
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- - ~>
|
17
|
+
- - "~>"
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '1.2'
|
22
20
|
type: :development
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- - ~>
|
24
|
+
- - "~>"
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '1.2'
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: rspec
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- - ~>
|
31
|
+
- - "~>"
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: '2.14'
|
38
34
|
type: :development
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- - ~>
|
38
|
+
- - "~>"
|
44
39
|
- !ruby/object:Gem::Version
|
45
40
|
version: '2.14'
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: webmock
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
|
-
- - ~>
|
45
|
+
- - "~>"
|
52
46
|
- !ruby/object:Gem::Version
|
53
47
|
version: '1.13'
|
54
48
|
type: :development
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
|
-
- - ~>
|
52
|
+
- - "~>"
|
60
53
|
- !ruby/object:Gem::Version
|
61
54
|
version: '1.13'
|
62
55
|
- !ruby/object:Gem::Dependency
|
63
56
|
name: pry
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
58
|
requirements:
|
67
|
-
- -
|
59
|
+
- - ">="
|
68
60
|
- !ruby/object:Gem::Version
|
69
61
|
version: '0'
|
70
62
|
type: :development
|
71
63
|
prerelease: false
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
65
|
requirements:
|
75
|
-
- -
|
66
|
+
- - ">="
|
76
67
|
- !ruby/object:Gem::Version
|
77
68
|
version: '0'
|
78
69
|
- !ruby/object:Gem::Dependency
|
79
70
|
name: nokogiri
|
80
71
|
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
72
|
requirements:
|
83
|
-
- -
|
73
|
+
- - ">="
|
84
74
|
- !ruby/object:Gem::Version
|
85
75
|
version: '0'
|
86
76
|
type: :runtime
|
87
77
|
prerelease: false
|
88
78
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
79
|
requirements:
|
91
|
-
- -
|
80
|
+
- - ">="
|
92
81
|
- !ruby/object:Gem::Version
|
93
82
|
version: '0'
|
94
83
|
- !ruby/object:Gem::Dependency
|
95
84
|
name: nori
|
96
85
|
requirement: !ruby/object:Gem::Requirement
|
97
|
-
none: false
|
98
86
|
requirements:
|
99
|
-
- -
|
87
|
+
- - ">="
|
100
88
|
- !ruby/object:Gem::Version
|
101
89
|
version: '0'
|
102
90
|
type: :runtime
|
103
91
|
prerelease: false
|
104
92
|
version_requirements: !ruby/object:Gem::Requirement
|
105
|
-
none: false
|
106
93
|
requirements:
|
107
|
-
- -
|
94
|
+
- - ">="
|
108
95
|
- !ruby/object:Gem::Version
|
109
96
|
version: '0'
|
110
97
|
description: HP ILO Ruby interface
|
@@ -122,7 +109,6 @@ files:
|
|
122
109
|
- lib/ilorb/definitions/rib.rb
|
123
110
|
- lib/ilorb/definitions/server.rb
|
124
111
|
- lib/ilorb/definitions/user.rb
|
125
|
-
- lib/ilorb/ilo.rb
|
126
112
|
- lib/ilorb/ribcl.rb
|
127
113
|
- lib/ilorb/version.rb
|
128
114
|
- spec/assets/basic_response.xml
|
@@ -132,27 +118,26 @@ files:
|
|
132
118
|
homepage: https://github.com/josqu4red/ilorb
|
133
119
|
licenses:
|
134
120
|
- MIT
|
121
|
+
metadata: {}
|
135
122
|
post_install_message:
|
136
123
|
rdoc_options: []
|
137
124
|
require_paths:
|
138
125
|
- lib
|
139
126
|
required_ruby_version: !ruby/object:Gem::Requirement
|
140
|
-
none: false
|
141
127
|
requirements:
|
142
|
-
- -
|
128
|
+
- - ">="
|
143
129
|
- !ruby/object:Gem::Version
|
144
130
|
version: '0'
|
145
131
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
146
|
-
none: false
|
147
132
|
requirements:
|
148
|
-
- -
|
133
|
+
- - ">="
|
149
134
|
- !ruby/object:Gem::Version
|
150
135
|
version: '0'
|
151
136
|
requirements: []
|
152
137
|
rubyforge_project:
|
153
|
-
rubygems_version:
|
138
|
+
rubygems_version: 2.2.0
|
154
139
|
signing_key:
|
155
|
-
specification_version:
|
140
|
+
specification_version: 4
|
156
141
|
summary: Configure and retrieve data from server's ILO management card
|
157
142
|
test_files:
|
158
143
|
- spec/assets/basic_response.xml
|
data/lib/ilorb/ilo.rb
DELETED
@@ -1,207 +0,0 @@
|
|
1
|
-
require 'logger'
|
2
|
-
require 'socket'
|
3
|
-
require 'openssl'
|
4
|
-
require 'net/https'
|
5
|
-
require 'nokogiri'
|
6
|
-
require 'nori'
|
7
|
-
|
8
|
-
module ILORb
|
9
|
-
|
10
|
-
class NotImplemented < StandardError; end
|
11
|
-
|
12
|
-
class ILO
|
13
|
-
def initialize(config = {})
|
14
|
-
@hostname = config[:hostname]
|
15
|
-
@login = config[:login] || "Administrator"
|
16
|
-
@password = config[:password]
|
17
|
-
@port = config[:port] || 443
|
18
|
-
@protocol = config[:protocol] || :http
|
19
|
-
@verify_ssl = config[:verify_ssl] || false
|
20
|
-
@ribcl_path = "/ribcl"
|
21
|
-
|
22
|
-
@log = Logger.new(STDOUT)
|
23
|
-
@log.level = config[:debug] ? Logger::DEBUG : Logger::WARN
|
24
|
-
|
25
|
-
@nori = Nori.new(:convert_tags_to => lambda{|tag| tag.downcase.to_sym})
|
26
|
-
|
27
|
-
setup_commands
|
28
|
-
end
|
29
|
-
|
30
|
-
# args should be empty or contain a hash anytime
|
31
|
-
def method_missing(name, *args, &block)
|
32
|
-
if @ribcl.has_command?(name)
|
33
|
-
command = @ribcl.command(name)
|
34
|
-
|
35
|
-
raise NotImplemented, "#{name} is not supported" unless command.supported?
|
36
|
-
|
37
|
-
params = args.first || {}
|
38
|
-
attributes = {}
|
39
|
-
element_map = nil
|
40
|
-
|
41
|
-
#TODO check for text
|
42
|
-
|
43
|
-
command.get_attributes.each do |attr|
|
44
|
-
# Attributes are mandatory
|
45
|
-
error("Attribute #{attr} missing in #{name} call") unless params.has_key?(attr)
|
46
|
-
attributes.store(attr, @ribcl.encode(params.delete(attr)))
|
47
|
-
end
|
48
|
-
|
49
|
-
element_map = command.map_elements
|
50
|
-
|
51
|
-
elements_array = []
|
52
|
-
|
53
|
-
[ params ].flatten.each do |params_hash|
|
54
|
-
elements = {}
|
55
|
-
params_hash.each do |key, value|
|
56
|
-
# Elements are not mandatory for now
|
57
|
-
elements.store(key, @ribcl.encode(params_hash.delete(key))) if element_map.has_key?(key)
|
58
|
-
end
|
59
|
-
elements_array << elements
|
60
|
-
end
|
61
|
-
|
62
|
-
#TODO check for CDATA
|
63
|
-
|
64
|
-
@log.info("Calling method #{name}")
|
65
|
-
request = ribcl_request(command, attributes) do |xml|
|
66
|
-
elements_array.each do |elements_hash|
|
67
|
-
elements_hash.each do |key, value|
|
68
|
-
elt = command.get_elements[element_map[key].first]
|
69
|
-
if elt.is_a?(Array)
|
70
|
-
attrs = Hash[elt.map{|x| [x, elements_hash.delete(element_map.invert[[element_map[key].first, x]])]}]
|
71
|
-
else
|
72
|
-
attrs = {element_map[key].last => value}
|
73
|
-
end
|
74
|
-
xml.send(element_map[key].first, attrs)
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
response = send_request(request)
|
80
|
-
parse_response(response, name)
|
81
|
-
else
|
82
|
-
super
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
def respond_to(name)
|
87
|
-
@ribcl.has_command?(name) ? true : super
|
88
|
-
end
|
89
|
-
|
90
|
-
def supported_commands
|
91
|
-
@ribcl.select{|name, command| command.supported?}.keys
|
92
|
-
end
|
93
|
-
|
94
|
-
private
|
95
|
-
|
96
|
-
def send_request(xml)
|
97
|
-
case @protocol
|
98
|
-
when :http
|
99
|
-
send_http_request(xml)
|
100
|
-
when :raw
|
101
|
-
send_raw_request(xml)
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
# ILO >= 3 speak HTTP
|
106
|
-
# Send XML request with HTTP POST and get back XML messages
|
107
|
-
def send_http_request(xml)
|
108
|
-
http = Net::HTTP.new(@hostname, @port)
|
109
|
-
http.use_ssl = true
|
110
|
-
http.verify_mode = OpenSSL::SSL::VERIFY_NONE unless @verify_ssl
|
111
|
-
|
112
|
-
@log.info("Sending POST request to #{@hostname}:#{@port}#{@ribcl_path}")
|
113
|
-
@log.debug("Request:\n#{xml}")
|
114
|
-
response = http.post(@ribcl_path, xml)
|
115
|
-
if response.is_a?(Net::HTTPNotFound)
|
116
|
-
@protocol = :raw
|
117
|
-
@log.info("Got 404, switching to RAW protocol")
|
118
|
-
send_raw_request(xml)
|
119
|
-
else
|
120
|
-
response.body
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
# Older ILO just eat raw XML
|
125
|
-
# Send XML over raw SSL-wrapped TCP socket and read XML stream
|
126
|
-
def send_raw_request(xml)
|
127
|
-
sock = TCPSocket.new(@hostname, @port)
|
128
|
-
|
129
|
-
ctx = OpenSSL::SSL::SSLContext.new(:TLSv1)
|
130
|
-
ctx.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
131
|
-
ssl_sock = OpenSSL::SSL::SSLSocket.new(sock, ctx)
|
132
|
-
ssl_sock.sync_close = true
|
133
|
-
|
134
|
-
@log.info("Connecting to #{@hostname}:#{@port}")
|
135
|
-
ssl_sock.connect
|
136
|
-
@log.debug("Request:\n#{xml}")
|
137
|
-
ssl_sock.puts("#{xml}\r\n")
|
138
|
-
response = ""
|
139
|
-
while line = ssl_sock.gets
|
140
|
-
response += line
|
141
|
-
end
|
142
|
-
ssl_sock.close
|
143
|
-
|
144
|
-
response
|
145
|
-
end
|
146
|
-
|
147
|
-
def parse_response(xml, command)
|
148
|
-
@log.debug("Response:\n#{xml}")
|
149
|
-
|
150
|
-
# ILO sends back multiple XML documents, split by XML header and remove first (empty)
|
151
|
-
messages = xml.split(/<\?xml.*?\?>\r?\n/).drop(1)
|
152
|
-
|
153
|
-
output = {}
|
154
|
-
|
155
|
-
messages.each do |doc|
|
156
|
-
xml_doc = Nokogiri::XML(doc){|cfg| cfg.nonet.noblanks}
|
157
|
-
|
158
|
-
xml_doc.root.children.each do |node|
|
159
|
-
case node.name
|
160
|
-
when "RESPONSE"
|
161
|
-
code = node.attr("STATUS").to_i(16)
|
162
|
-
message = node.attr("MESSAGE")
|
163
|
-
if code == 0
|
164
|
-
output[:status] = { :code => code, :message => message }
|
165
|
-
else
|
166
|
-
output[:status] = { :code => code, :message => message }
|
167
|
-
@log.error("#{message} (#{code})")
|
168
|
-
break
|
169
|
-
end
|
170
|
-
when "INFORM"
|
171
|
-
# OSEF
|
172
|
-
else # actual result
|
173
|
-
output.merge!(@nori.parse(node.to_s))
|
174
|
-
end
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
output
|
179
|
-
end
|
180
|
-
|
181
|
-
def ribcl_request(command, args = {}, &block)
|
182
|
-
builder = Nokogiri::XML::Builder.new do |xml|
|
183
|
-
xml.ribcl(:version => "2.0") {
|
184
|
-
xml.login(:password => @password, :user_login => @login) {
|
185
|
-
xml.send(command.context, :mode => command.mode) {
|
186
|
-
xml.send(command.name, args) {
|
187
|
-
yield xml if block_given?
|
188
|
-
}
|
189
|
-
}
|
190
|
-
}
|
191
|
-
}
|
192
|
-
end
|
193
|
-
|
194
|
-
builder.to_xml
|
195
|
-
end
|
196
|
-
|
197
|
-
def setup_commands
|
198
|
-
@ribcl = ILORb::RIBCL.load(File.join(File.dirname(__FILE__), "definitions", "*.rb"))
|
199
|
-
nil
|
200
|
-
end
|
201
|
-
|
202
|
-
def error(message)
|
203
|
-
@log.error(message)
|
204
|
-
raise message
|
205
|
-
end
|
206
|
-
end
|
207
|
-
end
|