ilorb 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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