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 ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
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
@@ -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
@@ -0,0 +1,3 @@
1
+ module ILORb
2
+ VERSION = "0.0.1"
3
+ end
data/lib/ilorb.rb ADDED
@@ -0,0 +1,5 @@
1
+ require 'ilorb/ribcl'
2
+ require 'ilorb/ilo'
3
+
4
+ module ILORb
5
+ end
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0"?>
2
+ <RIBCL VERSION="2.22">
3
+ <RESPONSE
4
+ STATUS="0x0000"
5
+ MESSAGE='No error'
6
+ />
7
+ </RIBCL>
@@ -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
@@ -0,0 +1,9 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'ilorb'
4
+ require 'webmock/rspec'
5
+ require 'pry'
6
+
7
+ RSpec.configure do |config|
8
+ config.order = "random"
9
+ end
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