ilorb 0.0.1
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.
- data/Gemfile +2 -0
- data/Gemfile.lock +47 -0
- data/README.md +98 -0
- data/ilorb.gemspec +28 -0
- data/lib/ilorb/definitions/rib.rb +102 -0
- data/lib/ilorb/definitions/server.rb +51 -0
- data/lib/ilorb/definitions/user.rb +19 -0
- data/lib/ilorb/ilo.rb +207 -0
- data/lib/ilorb/ribcl.rb +135 -0
- data/lib/ilorb/version.rb +3 -0
- data/lib/ilorb.rb +5 -0
- data/spec/assets/basic_response.xml +7 -0
- data/spec/assets/get_network_settings_response.xml +87 -0
- data/spec/ilo_spec.rb +79 -0
- data/spec/spec_helper.rb +9 -0
- metadata +161 -0
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
ilorb (0.0.1)
|
|
5
|
+
nokogiri
|
|
6
|
+
nori
|
|
7
|
+
|
|
8
|
+
GEM
|
|
9
|
+
remote: https://rubygems.org/
|
|
10
|
+
specs:
|
|
11
|
+
addressable (2.3.5)
|
|
12
|
+
coderay (1.0.9)
|
|
13
|
+
crack (0.4.1)
|
|
14
|
+
safe_yaml (~> 0.9.0)
|
|
15
|
+
diff-lcs (1.2.4)
|
|
16
|
+
method_source (0.8.1)
|
|
17
|
+
mini_portile (0.5.0)
|
|
18
|
+
nokogiri (1.6.0)
|
|
19
|
+
mini_portile (~> 0.5.0)
|
|
20
|
+
nori (2.2.0)
|
|
21
|
+
pry (0.9.12.2)
|
|
22
|
+
coderay (~> 1.0.5)
|
|
23
|
+
method_source (~> 0.8)
|
|
24
|
+
slop (~> 3.4)
|
|
25
|
+
rspec (2.14.1)
|
|
26
|
+
rspec-core (~> 2.14.0)
|
|
27
|
+
rspec-expectations (~> 2.14.0)
|
|
28
|
+
rspec-mocks (~> 2.14.0)
|
|
29
|
+
rspec-core (2.14.3)
|
|
30
|
+
rspec-expectations (2.14.0)
|
|
31
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
|
32
|
+
rspec-mocks (2.14.1)
|
|
33
|
+
safe_yaml (0.9.4)
|
|
34
|
+
slop (3.4.5)
|
|
35
|
+
webmock (1.13.0)
|
|
36
|
+
addressable (>= 2.2.7)
|
|
37
|
+
crack (>= 0.3.2)
|
|
38
|
+
|
|
39
|
+
PLATFORMS
|
|
40
|
+
ruby
|
|
41
|
+
|
|
42
|
+
DEPENDENCIES
|
|
43
|
+
bundler (~> 1.2)
|
|
44
|
+
ilorb!
|
|
45
|
+
pry
|
|
46
|
+
rspec (~> 2.14)
|
|
47
|
+
webmock (~> 1.13)
|
data/README.md
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# ILORb
|
|
2
|
+
|
|
3
|
+
ILORb is a library created to ease interaction with HP servers baseboard management cards (ILO), using their XML interface.
|
|
4
|
+
|
|
5
|
+
It is primarily meant to integrate with Chef config management system, but it can of course be used standalone.
|
|
6
|
+
|
|
7
|
+
It supports RIB, SERVER and USER commands for ILO 2, 3 and 4 (no other hardware to test on).
|
|
8
|
+
|
|
9
|
+
* By default, it will try to query the BMC through HTTP POST (available from ILO version 3)
|
|
10
|
+
* It will fall back to raw XML through TCP socket (SSL-wrapped) for earlier ILO versions
|
|
11
|
+
|
|
12
|
+
Supported commands and parameters are defined using a little DSL, under [definitions](lib/ilorb/definitions), sorted by "context".
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
HP, Integrated Lights Out and iLO are trademarks of HP, with whom the author of this software is not affiliated in any way other than using some of their hardware.
|
|
16
|
+
|
|
17
|
+
## Examples
|
|
18
|
+
|
|
19
|
+
```ruby
|
|
20
|
+
require 'json'
|
|
21
|
+
require 'ilorb'
|
|
22
|
+
|
|
23
|
+
ilo = ILORb::ILO.new(
|
|
24
|
+
:hostname => "10.200.0.1",
|
|
25
|
+
:login => "Admin",
|
|
26
|
+
:password => "SECRET",
|
|
27
|
+
# :protocol => :raw, # for old ILOs, defaults to :http
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
result = ilo.get_network_settings
|
|
31
|
+
puts JSON.pretty_generate(result)
|
|
32
|
+
```
|
|
33
|
+
generates and sends :
|
|
34
|
+
|
|
35
|
+
```xml
|
|
36
|
+
<?xml version="1.0"?>
|
|
37
|
+
<ribcl version="2.0">
|
|
38
|
+
<login password="SECRET" user_login="Admin">
|
|
39
|
+
<rib_info mode="read">
|
|
40
|
+
<get_network_settings/>
|
|
41
|
+
</rib_info>
|
|
42
|
+
</login>
|
|
43
|
+
</ribcl>
|
|
44
|
+
```
|
|
45
|
+
result:
|
|
46
|
+
```json
|
|
47
|
+
{
|
|
48
|
+
"status": {
|
|
49
|
+
"code": 0,
|
|
50
|
+
"message": "No error"
|
|
51
|
+
},
|
|
52
|
+
"get_network_settings": {
|
|
53
|
+
"enable_nic": {
|
|
54
|
+
"@value": "Y"
|
|
55
|
+
},
|
|
56
|
+
"shared_network_port": {
|
|
57
|
+
"@value": "N"
|
|
58
|
+
},
|
|
59
|
+
"vlan_enabled": {
|
|
60
|
+
"@value": "N"
|
|
61
|
+
},
|
|
62
|
+
"vlan_id": {
|
|
63
|
+
"@value": "0"
|
|
64
|
+
},
|
|
65
|
+
"speed_autoselect": {
|
|
66
|
+
"@value": "Y"
|
|
67
|
+
},
|
|
68
|
+
"dhcp_enable": {
|
|
69
|
+
"@value": "N"
|
|
70
|
+
},
|
|
71
|
+
{ ... }
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## TODO
|
|
77
|
+
|
|
78
|
+
* Tests
|
|
79
|
+
* Use a custom parser instead of Nori, to avoid one-element-hashes and cast responses to actual objects (e.g Y/N to true/false)
|
|
80
|
+
* See for mandatory parameters
|
|
81
|
+
* Add a CLI tool
|
|
82
|
+
|
|
83
|
+
## Setup
|
|
84
|
+
|
|
85
|
+
Only tested with MRI >= 1.9.3
|
|
86
|
+
|
|
87
|
+
Dependencies:
|
|
88
|
+
* nokogiri
|
|
89
|
+
* nori
|
|
90
|
+
|
|
91
|
+
Install:
|
|
92
|
+
* git clone https://github.com/josqu4red/ilorb
|
|
93
|
+
OR
|
|
94
|
+
* gem install ilorb (soon)
|
|
95
|
+
|
|
96
|
+
## Credits
|
|
97
|
+
|
|
98
|
+
ilorb is inspired by [python-hpilo](https://github.com/seveas/python-hpilo)
|
data/ilorb.gemspec
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
|
|
5
|
+
require 'ilorb/version'
|
|
6
|
+
|
|
7
|
+
Gem::Specification.new do |spec|
|
|
8
|
+
spec.name = "ilorb"
|
|
9
|
+
spec.version = ILORb::VERSION
|
|
10
|
+
spec.authors = ["Jonathan Amiez"]
|
|
11
|
+
spec.email = ["jonathan.amiez@gmail.com"]
|
|
12
|
+
spec.description = "HP ILO Ruby interface"
|
|
13
|
+
spec.summary = "Configure and retrieve data from server's ILO management card"
|
|
14
|
+
spec.homepage = "https://github.com/josqu4red/ilorb"
|
|
15
|
+
spec.license = "MIT"
|
|
16
|
+
|
|
17
|
+
spec.files = `git ls-files`.split($/)
|
|
18
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
|
19
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
20
|
+
spec.require_paths = ["lib"]
|
|
21
|
+
|
|
22
|
+
spec.add_development_dependency "bundler", "~> 1.2"
|
|
23
|
+
spec.add_development_dependency "rspec", "~> 2.14"
|
|
24
|
+
spec.add_development_dependency "webmock", "~> 1.13"
|
|
25
|
+
spec.add_development_dependency "pry"
|
|
26
|
+
spec.add_dependency "nokogiri"
|
|
27
|
+
spec.add_dependency "nori"
|
|
28
|
+
end
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
context :rib_info do
|
|
2
|
+
read_cmd :get_ahs_status
|
|
3
|
+
read_cmd :get_all_languages
|
|
4
|
+
read_cmd :get_all_licenses
|
|
5
|
+
read_cmd :get_asset_tag
|
|
6
|
+
read_cmd :get_ers_settings
|
|
7
|
+
read_cmd :get_event_log
|
|
8
|
+
read_cmd :get_fips_status
|
|
9
|
+
read_cmd :get_fw_version
|
|
10
|
+
read_cmd :get_global_settings
|
|
11
|
+
read_cmd :get_hotkey_config
|
|
12
|
+
read_cmd :get_language
|
|
13
|
+
read_cmd :get_all_languages
|
|
14
|
+
read_cmd :get_network_settings
|
|
15
|
+
read_cmd :get_security_msg
|
|
16
|
+
read_cmd :get_snmp_im_settings
|
|
17
|
+
read_cmd :get_spatial
|
|
18
|
+
read_cmd :get_vm_status do
|
|
19
|
+
attributes :device
|
|
20
|
+
end
|
|
21
|
+
read_cmd :profile_apply_get_results do
|
|
22
|
+
not_implemented
|
|
23
|
+
end
|
|
24
|
+
read_cmd :profile_list do
|
|
25
|
+
not_implemented
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
write_cmd :ahs_clear_data
|
|
29
|
+
write_cmd :brownout_recovery # > mod_global_settings
|
|
30
|
+
write_cmd :certificate_signing_request
|
|
31
|
+
write_cmd :clear_eventlog
|
|
32
|
+
write_cmd :computer_lock do
|
|
33
|
+
not_implemented
|
|
34
|
+
end
|
|
35
|
+
write_cmd :disable_ers
|
|
36
|
+
write_cmd :eject_virtual_media do
|
|
37
|
+
attributes :device
|
|
38
|
+
end
|
|
39
|
+
write_cmd :factory_defaults
|
|
40
|
+
write_cmd :fips_enable
|
|
41
|
+
write_cmd :hotkey_config do
|
|
42
|
+
not_implemented
|
|
43
|
+
end
|
|
44
|
+
write_cmd :import_certificate do #TODO
|
|
45
|
+
not_implemented
|
|
46
|
+
text :certificate
|
|
47
|
+
end
|
|
48
|
+
write_cmd :insert_virtual_media do
|
|
49
|
+
attributes :device, :image_url
|
|
50
|
+
end
|
|
51
|
+
write_cmd :license do
|
|
52
|
+
elements :activate => :key
|
|
53
|
+
end
|
|
54
|
+
write_cmd :mod_global_settings do #TODO
|
|
55
|
+
not_implemented
|
|
56
|
+
end
|
|
57
|
+
write_cmd :mod_network_settings do #TODO
|
|
58
|
+
not_implemented
|
|
59
|
+
end
|
|
60
|
+
write_cmd :mod_snmp_im_settings do #TODO
|
|
61
|
+
not_implemented
|
|
62
|
+
end
|
|
63
|
+
write_cmd :profile_apply do
|
|
64
|
+
not_implemented
|
|
65
|
+
end
|
|
66
|
+
write_cmd :profile_delete do
|
|
67
|
+
not_implemented
|
|
68
|
+
end
|
|
69
|
+
write_cmd :profile_desc_download do
|
|
70
|
+
not_implemented
|
|
71
|
+
end
|
|
72
|
+
write_cmd :reset_rib
|
|
73
|
+
write_cmd :set_ahs_status do
|
|
74
|
+
attributes :value
|
|
75
|
+
end
|
|
76
|
+
write_cmd :set_asset_tag do
|
|
77
|
+
attributes :value
|
|
78
|
+
end
|
|
79
|
+
write_cmd :set_ers_irs_connect do
|
|
80
|
+
elements :ers_destination_url, :ers_destination_port
|
|
81
|
+
end
|
|
82
|
+
write_cmd :set_language do
|
|
83
|
+
attributes :lang_id
|
|
84
|
+
end
|
|
85
|
+
write_cmd :set_security_msg do
|
|
86
|
+
not_implemented
|
|
87
|
+
elements :security_msg, :security_msg_text => :cdata
|
|
88
|
+
end
|
|
89
|
+
write_cmd :set_vm_status do
|
|
90
|
+
attributes :device
|
|
91
|
+
elements :vm_boot_option, :vm_write_protect
|
|
92
|
+
end
|
|
93
|
+
write_cmd :trigger_l2_collection do
|
|
94
|
+
not_implemented
|
|
95
|
+
end
|
|
96
|
+
write_cmd :trigger_test_event do
|
|
97
|
+
not_implemented
|
|
98
|
+
end
|
|
99
|
+
write_cmd :update_firmware do #TODO
|
|
100
|
+
not_implemented
|
|
101
|
+
end
|
|
102
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
context :server_info do
|
|
2
|
+
read_cmd :get_embedded_health
|
|
3
|
+
read_cmd :get_host_power_saver_status
|
|
4
|
+
read_cmd :get_host_power_status
|
|
5
|
+
read_cmd :get_host_pwr_micro_ver
|
|
6
|
+
read_cmd :get_one_time_boot
|
|
7
|
+
read_cmd :get_persistent_boot
|
|
8
|
+
read_cmd :get_power_cap
|
|
9
|
+
read_cmd :get_power_readings
|
|
10
|
+
read_cmd :get_pwreg
|
|
11
|
+
read_cmd :get_server_auto_pwr
|
|
12
|
+
read_cmd :get_server_name
|
|
13
|
+
read_cmd :get_server_power_on_time
|
|
14
|
+
read_cmd :get_uid_status
|
|
15
|
+
|
|
16
|
+
write_cmd :clear_server_power_on_time
|
|
17
|
+
write_cmd :cold_boot_server
|
|
18
|
+
write_cmd :hold_pwr_btn do
|
|
19
|
+
attributes :toggle
|
|
20
|
+
end
|
|
21
|
+
write_cmd :press_power_btn
|
|
22
|
+
write_cmd :reset_server
|
|
23
|
+
write_cmd :server_auto_pwr do
|
|
24
|
+
attributes :value
|
|
25
|
+
end
|
|
26
|
+
write_cmd :server_name do
|
|
27
|
+
attributes :value
|
|
28
|
+
end
|
|
29
|
+
write_cmd :set_host_power do
|
|
30
|
+
attributes :host_power
|
|
31
|
+
end
|
|
32
|
+
write_cmd :set_host_power_saver do
|
|
33
|
+
attributes :host_power_saver
|
|
34
|
+
end
|
|
35
|
+
write_cmd :set_one_time_boot do
|
|
36
|
+
attributes :value
|
|
37
|
+
end
|
|
38
|
+
write_cmd :set_persistent_boot do
|
|
39
|
+
elements :device => [ :value ]
|
|
40
|
+
end
|
|
41
|
+
write_cmd :set_power_cap do
|
|
42
|
+
attributes :power_cap
|
|
43
|
+
end
|
|
44
|
+
write_cmd :set_pwreg do
|
|
45
|
+
elements :pwralert => :type, :pwralert_settings => [:threshold, :duration]
|
|
46
|
+
end
|
|
47
|
+
write_cmd :uid_control do
|
|
48
|
+
attributes :uid
|
|
49
|
+
end
|
|
50
|
+
write_cmd :warm_boot_server
|
|
51
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
context :user_info do
|
|
2
|
+
read_cmd :get_user do
|
|
3
|
+
attributes :user_login
|
|
4
|
+
end
|
|
5
|
+
read_cmd :get_all_users
|
|
6
|
+
read_cmd :get_all_user_info
|
|
7
|
+
|
|
8
|
+
write_cmd :add_user do
|
|
9
|
+
attributes :user_name, :user_login, :password
|
|
10
|
+
elements :admin_priv, :remote_cons_priv, :reset_server_priv, :virtual_media_priv, :config_ilo_priv
|
|
11
|
+
end
|
|
12
|
+
write_cmd :delete_user do
|
|
13
|
+
attributes :user_login
|
|
14
|
+
end
|
|
15
|
+
write_cmd :mod_user do
|
|
16
|
+
attributes :user_login
|
|
17
|
+
elements :user_name, :user_login, :password, :admin_priv, :remote_cons_priv, :reset_server_priv, :virtual_media_priv, :config_ilo_priv, :del_users_ssh_key
|
|
18
|
+
end
|
|
19
|
+
end
|
data/lib/ilorb/ilo.rb
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
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
|
data/lib/ilorb/ribcl.rb
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
module ILORb
|
|
2
|
+
class RIBCL < Hash
|
|
3
|
+
def initialize
|
|
4
|
+
super
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
# meaningful aliases
|
|
8
|
+
alias_method :has_command?, :has_key?
|
|
9
|
+
alias_method :command, :fetch
|
|
10
|
+
|
|
11
|
+
# mapping between Ruby objects and api format
|
|
12
|
+
VALUES = {
|
|
13
|
+
true => "yes",
|
|
14
|
+
false => "no",
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
def self.load(path)
|
|
18
|
+
obj = new
|
|
19
|
+
Dir.glob(path).each do |file|
|
|
20
|
+
obj.instance_eval(File.read(file), file)
|
|
21
|
+
end
|
|
22
|
+
obj
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def encode(value)
|
|
26
|
+
VALUES[value] ? VALUES[value] : value
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
# private methods are used by DSL
|
|
31
|
+
|
|
32
|
+
def context(name, &block)
|
|
33
|
+
context = Context.new(name)
|
|
34
|
+
context.instance_eval(&block)
|
|
35
|
+
merge!(context.commands)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
class Context
|
|
39
|
+
attr_reader :commands
|
|
40
|
+
|
|
41
|
+
def initialize(name)
|
|
42
|
+
@name = name.to_sym
|
|
43
|
+
@commands = {}
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
# private methods are used by DSL
|
|
48
|
+
|
|
49
|
+
[:read, :write].each do |mode|
|
|
50
|
+
define_method "#{mode}_cmd" do |name, &block|
|
|
51
|
+
command = Command.new(name, @name, mode)
|
|
52
|
+
command.instance_eval(&block) if block
|
|
53
|
+
@commands[name] = command
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
class Command
|
|
59
|
+
attr_reader :name, :context, :mode
|
|
60
|
+
|
|
61
|
+
def initialize(name, context, mode)
|
|
62
|
+
@name, @context, @mode = name.to_sym, context, mode
|
|
63
|
+
@attributes = []
|
|
64
|
+
@elements = {}
|
|
65
|
+
@text = nil
|
|
66
|
+
@supported = true
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
[:attributes, :elements, :text].each do |key|
|
|
70
|
+
define_method "get_#{key}" do
|
|
71
|
+
instance_variable_get("@#{key}")
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def supported?
|
|
76
|
+
@supported
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def map_elements
|
|
80
|
+
map = {}
|
|
81
|
+
@elements.each do |name, type|
|
|
82
|
+
if type == :value
|
|
83
|
+
map.store(name, [name, type])
|
|
84
|
+
elsif type.is_a?(Array)
|
|
85
|
+
type.each do |elt|
|
|
86
|
+
map.store("#{name}_#{elt}".to_sym, [name, elt])
|
|
87
|
+
end
|
|
88
|
+
else
|
|
89
|
+
map.store("#{name}_#{type}".to_sym, [name, type])
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
map
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def get_params
|
|
96
|
+
params = []
|
|
97
|
+
params += @attributes
|
|
98
|
+
params << @text if @text
|
|
99
|
+
params += map_elements.keys
|
|
100
|
+
params
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
private
|
|
104
|
+
# private methods are used by DSL
|
|
105
|
+
|
|
106
|
+
def attributes(*params)
|
|
107
|
+
@attributes += params
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def elements(*params)
|
|
111
|
+
if @text.nil?
|
|
112
|
+
hash = {}
|
|
113
|
+
params.each do |param|
|
|
114
|
+
if param.is_a?(Hash)
|
|
115
|
+
hash.merge!(param)
|
|
116
|
+
else
|
|
117
|
+
hash.store(param, :value)
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
@elements.merge!(hash)
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def text(param)
|
|
125
|
+
if @elements.empty?
|
|
126
|
+
@text = param
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def not_implemented
|
|
131
|
+
@supported = false
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
data/lib/ilorb.rb
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
<?xml version="1.0"?>
|
|
2
|
+
<RIBCL VERSION="2.22">
|
|
3
|
+
<RESPONSE
|
|
4
|
+
STATUS="0x0000"
|
|
5
|
+
MESSAGE='No error'
|
|
6
|
+
/>
|
|
7
|
+
<GET_NETWORK_SETTINGS>
|
|
8
|
+
<ENABLE_NIC VALUE="Y"/>
|
|
9
|
+
<SHARED_NETWORK_PORT VALUE="N"/>
|
|
10
|
+
<VLAN_ENABLED VALUE="N"/>
|
|
11
|
+
<VLAN_ID VALUE="0"/>
|
|
12
|
+
<SPEED_AUTOSELECT VALUE="Y"/>
|
|
13
|
+
<NIC_SPEED VALUE="Automatic"/>
|
|
14
|
+
<FULL_DUPLEX VALUE="Automatic"/>
|
|
15
|
+
<DHCP_ENABLE VALUE="Y"/>
|
|
16
|
+
<DHCP_GATEWAY VALUE="N"/>
|
|
17
|
+
<DHCP_DNS_SERVER VALUE="Y"/>
|
|
18
|
+
<DHCP_WINS_SERVER VALUE="N"/>
|
|
19
|
+
<DHCP_STATIC_ROUTE VALUE="N"/>
|
|
20
|
+
<DHCP_DOMAIN_NAME VALUE="N"/>
|
|
21
|
+
<DHCP_SNTP_SETTINGS VALUE="Y"/>
|
|
22
|
+
<REG_WINS_SERVER VALUE="N"/>
|
|
23
|
+
<REG_DDNS_SERVER VALUE="N"/>
|
|
24
|
+
<PING_GATEWAY VALUE="N"/>
|
|
25
|
+
<MAC_ADDRESS VALUE="1c:c1:de:17:b3:90"/>
|
|
26
|
+
<IP_ADDRESS VALUE="192.168.1.13"/>
|
|
27
|
+
<SUBNET_MASK VALUE="255.255.255.0"/>
|
|
28
|
+
<GATEWAY_IP_ADDRESS VALUE="0.0.0.0"/>
|
|
29
|
+
<DNS_NAME VALUE="weezer"/>
|
|
30
|
+
<DOMAIN_NAME VALUE="ilotest.com."/>
|
|
31
|
+
<PRIM_DNS_SERVER VALUE="0.0.0.0"/>
|
|
32
|
+
<SEC_DNS_SERVER VALUE="0.0.0.0"/>
|
|
33
|
+
<TER_DNS_SERVER VALUE="0.0.0.0"/>
|
|
34
|
+
<PRIM_WINS_SERVER VALUE="0.0.0.0"/>
|
|
35
|
+
<SEC_WINS_SERVER VALUE="0.0.0.0"/>
|
|
36
|
+
<SNTP_SERVER1 VALUE="192.168.1.5"/>
|
|
37
|
+
<SNTP_SERVER2 VALUE=""/>
|
|
38
|
+
<TIMEZONE VALUE="CST6CDT"/>
|
|
39
|
+
<STATIC_ROUTE_1 DEST="0.0.0.0"
|
|
40
|
+
MASK="0.0.0.0"
|
|
41
|
+
GATEWAY="0.0.0.0"/>
|
|
42
|
+
<STATIC_ROUTE_2 DEST="0.0.0.0"
|
|
43
|
+
MASK="0.0.0.0"
|
|
44
|
+
GATEWAY="0.0.0.0"/>
|
|
45
|
+
<STATIC_ROUTE_3 DEST="0.0.0.0"
|
|
46
|
+
MASK="0.0.0.0"
|
|
47
|
+
GATEWAY="0.0.0.0"/>
|
|
48
|
+
<IPV6_ADDRESS VALUE="2001:2:1::15"
|
|
49
|
+
PREFIXLEN="64"
|
|
50
|
+
ADDR_SOURCE="STATIC"
|
|
51
|
+
ADDR_STATUS="ACTIVE"/>
|
|
52
|
+
<IPV6_ADDRESS VALUE="2001:db8:1::50"
|
|
53
|
+
PREFIXLEN="64"
|
|
54
|
+
ADDR_SOURCE="STATIC"
|
|
55
|
+
ADDR_STATUS="ACTIVE"/>
|
|
56
|
+
<IPV6_ADDRESS VALUE="fe80::1ec1:deff:fe17:b390"
|
|
57
|
+
PREFIXLEN="64"
|
|
58
|
+
ADDR_SOURCE="SLAAC"
|
|
59
|
+
ADDR_STATUS="ACTIVE"/>
|
|
60
|
+
<IPV6_ADDRESS VALUE="2001:2:1:0:1ec1:deff:fe17:b390"
|
|
61
|
+
PREFIXLEN="64"
|
|
62
|
+
ADDR_SOURCE="SLAAC"
|
|
63
|
+
ADDR_STATUS="ACTIVE"/>
|
|
64
|
+
<IPV6_STATIC_ROUTE_1
|
|
65
|
+
IPV6_DEST="2001:2:2::20"
|
|
66
|
+
PREFIXLEN="64"
|
|
67
|
+
IPV6_GATEWAY="fe80::1:2:3"
|
|
68
|
+
ADDR_STATUS="ACTIVE"/>
|
|
69
|
+
<IPV6_STATIC_ROUTE_2
|
|
70
|
+
IPV6_DEST="::"
|
|
71
|
+
PREFIXLEN="0"
|
|
72
|
+
IPV6_GATEWAY="::"
|
|
73
|
+
ADDR_STATUS="INACTIVE"/>
|
|
74
|
+
<IPV6_STATIC_ROUTE_3
|
|
75
|
+
IPV6_DEST="2001:1001:2002:3003::"
|
|
76
|
+
PREFIXLEN="64"
|
|
77
|
+
IPV6_GATEWAY="2001:db8:1::40"
|
|
78
|
+
ADDR_STATUS="ACTIVE"/>
|
|
79
|
+
<IPV6_PRIM_DNS_SERVER VALUE="2001:1:2::5"/>
|
|
80
|
+
<IPV6_SEC_DNS_SERVER VALUE="2001:1:2::6"/>
|
|
81
|
+
<IPV6_TER_DNS_SERVER VALUE="::"/>
|
|
82
|
+
<IPV6_DEFAULT_GATEWAY VALUE="fe80::21c:c4ff:fe18:9cbd"/>
|
|
83
|
+
<IPV6_PREFERRED_PROTOCOL VALUE="Y"/>
|
|
84
|
+
<IPV6_ADDR_AUTOCFG VALUE="Y"/>
|
|
85
|
+
<IPV6_REG_DDNS_SERVER VALUE="Y"/>
|
|
86
|
+
</GET_NETWORK_SETTINGS>
|
|
87
|
+
</RIBCL>
|
data/spec/ilo_spec.rb
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe ILORb::ILO do
|
|
4
|
+
let(:hostname) { "10.200.0.1" }
|
|
5
|
+
let(:login) { "Admin" }
|
|
6
|
+
let(:password) { "SECRET" }
|
|
7
|
+
let(:ilo) { ILORb::ILO.new(hostname: hostname, login: login, password: password) }
|
|
8
|
+
|
|
9
|
+
describe "#get_network_settings" do
|
|
10
|
+
before do
|
|
11
|
+
stub_request(:post, "https://10.200.0.1/ribcl").
|
|
12
|
+
with(:body => "<?xml version=\"1.0\"?>\n<ribcl version=\"2.0\">\n <login password=\"SECRET\" user_login=\"Admin\">\n <rib_info mode=\"read\">\n <get_network_settings/>\n </rib_info>\n </login>\n</ribcl>\n").
|
|
13
|
+
to_return(:status => 200, :body => asset_file('get_network_settings_response.xml'))
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
subject { ilo.get_network_settings }
|
|
17
|
+
|
|
18
|
+
its([:status]) { should include(code: 0, message: 'No error') }
|
|
19
|
+
its([:get_network_settings]) { should_not be_empty }
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
describe "#set_one_time_boot" do
|
|
23
|
+
before do
|
|
24
|
+
stub_request(:post, "https://10.200.0.1/ribcl").
|
|
25
|
+
with(:body => "<?xml version=\"1.0\"?>\n<ribcl version=\"2.0\">\n <login password=\"SECRET\" user_login=\"Admin\">\n <server_info mode=\"write\">\n <set_one_time_boot value=\"FLOPPY\"/>\n </server_info>\n </login>\n</ribcl>\n").
|
|
26
|
+
to_return(:status => 200, :body => asset_file('basic_response.xml'))
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
subject { ilo.set_one_time_boot(value: "FLOPPY") }
|
|
30
|
+
|
|
31
|
+
its([:status]) { should include(code: 0, message: 'No error') }
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
describe "#set_pwreg" do
|
|
35
|
+
before do
|
|
36
|
+
stub_request(:post, "https://10.200.0.1/ribcl").
|
|
37
|
+
with(:body => "<?xml version=\"1.0\"?>\n<ribcl version=\"2.0\">\n <login password=\"SECRET\" user_login=\"Admin\">\n <server_info mode=\"write\">\n <set_pwreg>\n <pwralert type=\"PEAK\"/>\n <pwralert_settings threshold=\"200\" duration=\"35\"/>\n </set_pwreg>\n </server_info>\n </login>\n</ribcl>\n").
|
|
38
|
+
to_return(:status => 200, :body => asset_file('basic_response.xml'))
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
subject { ilo.set_pwreg pwralert_type: "PEAK",
|
|
42
|
+
pwralert_settings_threshold: 200,
|
|
43
|
+
pwralert_settings_duration: 35 }
|
|
44
|
+
|
|
45
|
+
its([:status]) { should include(code: 0, message: 'No error') }
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
describe "#set_one_time_boot" do
|
|
49
|
+
before do
|
|
50
|
+
stub_request(:post, "https://10.200.0.1/ribcl").
|
|
51
|
+
with(:body => "<?xml version=\"1.0\"?>\n<ribcl version=\"2.0\">\n <login password=\"SECRET\" user_login=\"Admin\">\n <server_info mode=\"write\">\n <set_one_time_boot value=\"FLOPPY\"/>\n </server_info>\n </login>\n</ribcl>\n").
|
|
52
|
+
to_return(:status => 200, :body => asset_file('basic_response.xml'))
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
subject { ilo.set_one_time_boot(value: "FLOPPY") }
|
|
56
|
+
|
|
57
|
+
its([:status]) { should include(code: 0, message: 'No error') }
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
describe "#set_persistent_boot" do
|
|
61
|
+
before do
|
|
62
|
+
stub_request(:post, "https://10.200.0.1/ribcl").
|
|
63
|
+
with(:body => "<?xml version=\"1.0\"?>\n<ribcl version=\"2.0\">\n <login password=\"SECRET\" user_login=\"Admin\">\n <server_info mode=\"write\">\n <set_persistent_boot>\n <device value=\"FLOPPY\"/>\n <device value=\"CDROM\"/>\n </set_persistent_boot>\n </server_info>\n </login>\n</ribcl>\n").
|
|
64
|
+
to_return(:status => 200, :body => asset_file('basic_response.xml'))
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
subject { ilo.set_persistent_boot([{ device_value: "FLOPPY" },
|
|
68
|
+
{ device_value: "CDROM" }]) }
|
|
69
|
+
|
|
70
|
+
its([:status]) { should include(code: 0, message: 'No error') }
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
private
|
|
74
|
+
|
|
75
|
+
def asset_file(asset)
|
|
76
|
+
path = File.join(File.dirname(__FILE__), 'assets', asset)
|
|
77
|
+
File.new(path)
|
|
78
|
+
end
|
|
79
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: ilorb
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
prerelease:
|
|
6
|
+
platform: ruby
|
|
7
|
+
authors:
|
|
8
|
+
- Jonathan Amiez
|
|
9
|
+
autorequire:
|
|
10
|
+
bindir: bin
|
|
11
|
+
cert_chain: []
|
|
12
|
+
date: 2013-07-25 00:00:00.000000000 Z
|
|
13
|
+
dependencies:
|
|
14
|
+
- !ruby/object:Gem::Dependency
|
|
15
|
+
name: bundler
|
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
|
17
|
+
none: false
|
|
18
|
+
requirements:
|
|
19
|
+
- - ~>
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '1.2'
|
|
22
|
+
type: :development
|
|
23
|
+
prerelease: false
|
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
+
none: false
|
|
26
|
+
requirements:
|
|
27
|
+
- - ~>
|
|
28
|
+
- !ruby/object:Gem::Version
|
|
29
|
+
version: '1.2'
|
|
30
|
+
- !ruby/object:Gem::Dependency
|
|
31
|
+
name: rspec
|
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
|
33
|
+
none: false
|
|
34
|
+
requirements:
|
|
35
|
+
- - ~>
|
|
36
|
+
- !ruby/object:Gem::Version
|
|
37
|
+
version: '2.14'
|
|
38
|
+
type: :development
|
|
39
|
+
prerelease: false
|
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
41
|
+
none: false
|
|
42
|
+
requirements:
|
|
43
|
+
- - ~>
|
|
44
|
+
- !ruby/object:Gem::Version
|
|
45
|
+
version: '2.14'
|
|
46
|
+
- !ruby/object:Gem::Dependency
|
|
47
|
+
name: webmock
|
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
|
49
|
+
none: false
|
|
50
|
+
requirements:
|
|
51
|
+
- - ~>
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '1.13'
|
|
54
|
+
type: :development
|
|
55
|
+
prerelease: false
|
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
57
|
+
none: false
|
|
58
|
+
requirements:
|
|
59
|
+
- - ~>
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '1.13'
|
|
62
|
+
- !ruby/object:Gem::Dependency
|
|
63
|
+
name: pry
|
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
|
65
|
+
none: false
|
|
66
|
+
requirements:
|
|
67
|
+
- - ! '>='
|
|
68
|
+
- !ruby/object:Gem::Version
|
|
69
|
+
version: '0'
|
|
70
|
+
type: :development
|
|
71
|
+
prerelease: false
|
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
73
|
+
none: false
|
|
74
|
+
requirements:
|
|
75
|
+
- - ! '>='
|
|
76
|
+
- !ruby/object:Gem::Version
|
|
77
|
+
version: '0'
|
|
78
|
+
- !ruby/object:Gem::Dependency
|
|
79
|
+
name: nokogiri
|
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
|
81
|
+
none: false
|
|
82
|
+
requirements:
|
|
83
|
+
- - ! '>='
|
|
84
|
+
- !ruby/object:Gem::Version
|
|
85
|
+
version: '0'
|
|
86
|
+
type: :runtime
|
|
87
|
+
prerelease: false
|
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
89
|
+
none: false
|
|
90
|
+
requirements:
|
|
91
|
+
- - ! '>='
|
|
92
|
+
- !ruby/object:Gem::Version
|
|
93
|
+
version: '0'
|
|
94
|
+
- !ruby/object:Gem::Dependency
|
|
95
|
+
name: nori
|
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
|
97
|
+
none: false
|
|
98
|
+
requirements:
|
|
99
|
+
- - ! '>='
|
|
100
|
+
- !ruby/object:Gem::Version
|
|
101
|
+
version: '0'
|
|
102
|
+
type: :runtime
|
|
103
|
+
prerelease: false
|
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
105
|
+
none: false
|
|
106
|
+
requirements:
|
|
107
|
+
- - ! '>='
|
|
108
|
+
- !ruby/object:Gem::Version
|
|
109
|
+
version: '0'
|
|
110
|
+
description: HP ILO Ruby interface
|
|
111
|
+
email:
|
|
112
|
+
- jonathan.amiez@gmail.com
|
|
113
|
+
executables: []
|
|
114
|
+
extensions: []
|
|
115
|
+
extra_rdoc_files: []
|
|
116
|
+
files:
|
|
117
|
+
- Gemfile
|
|
118
|
+
- Gemfile.lock
|
|
119
|
+
- README.md
|
|
120
|
+
- ilorb.gemspec
|
|
121
|
+
- lib/ilorb.rb
|
|
122
|
+
- lib/ilorb/definitions/rib.rb
|
|
123
|
+
- lib/ilorb/definitions/server.rb
|
|
124
|
+
- lib/ilorb/definitions/user.rb
|
|
125
|
+
- lib/ilorb/ilo.rb
|
|
126
|
+
- lib/ilorb/ribcl.rb
|
|
127
|
+
- lib/ilorb/version.rb
|
|
128
|
+
- spec/assets/basic_response.xml
|
|
129
|
+
- spec/assets/get_network_settings_response.xml
|
|
130
|
+
- spec/ilo_spec.rb
|
|
131
|
+
- spec/spec_helper.rb
|
|
132
|
+
homepage: https://github.com/josqu4red/ilorb
|
|
133
|
+
licenses:
|
|
134
|
+
- MIT
|
|
135
|
+
post_install_message:
|
|
136
|
+
rdoc_options: []
|
|
137
|
+
require_paths:
|
|
138
|
+
- lib
|
|
139
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
140
|
+
none: false
|
|
141
|
+
requirements:
|
|
142
|
+
- - ! '>='
|
|
143
|
+
- !ruby/object:Gem::Version
|
|
144
|
+
version: '0'
|
|
145
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
146
|
+
none: false
|
|
147
|
+
requirements:
|
|
148
|
+
- - ! '>='
|
|
149
|
+
- !ruby/object:Gem::Version
|
|
150
|
+
version: '0'
|
|
151
|
+
requirements: []
|
|
152
|
+
rubyforge_project:
|
|
153
|
+
rubygems_version: 1.8.25
|
|
154
|
+
signing_key:
|
|
155
|
+
specification_version: 3
|
|
156
|
+
summary: Configure and retrieve data from server's ILO management card
|
|
157
|
+
test_files:
|
|
158
|
+
- spec/assets/basic_response.xml
|
|
159
|
+
- spec/assets/get_network_settings_response.xml
|
|
160
|
+
- spec/ilo_spec.rb
|
|
161
|
+
- spec/spec_helper.rb
|