ilo-sdk 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 39068db4621e387c98482d7dc545fd8cb7ccf503
4
- data.tar.gz: a05c6dec3838c31dfd7a706940c9adfa4e9f9c65
3
+ metadata.gz: 6ab6bf099aad85914a4e0a9b4c9399d9f263e722
4
+ data.tar.gz: ec8b5d88be00336190a2ee51f9f2e279c9fe75a9
5
5
  SHA512:
6
- metadata.gz: 8d3e5c1ddc3d61d76d30dd920abc50c9c4f587e1b30c0671a6d3c68f84c5b5ac4dfb94aebbeb9d9f0f7a3e4961ac0efece73a369a13952b0a7df2baa2e66681b
7
- data.tar.gz: 358cb51d0ab7746d292e6cf40dc4c66381440838effffa6817da7b0ef5a4fe4698c506c88747cb00ea7507b5537890ed0a5577af6b43e7cbc8b52e17842ff47b
6
+ metadata.gz: cacb3f0f39fc3bba895f1b1d7d2d8297c5ea9e850b3e967856fd965332f09168ee39e09e3d6467d4fa97e708bcf604a4cb22c819b477bba0e19e0bb7ba1efc13
7
+ data.tar.gz: 3e4a180967d557b4581d36c56042a39cf8cc945729db1ea4d0715da9d6ad9f7919f67e9a6886810edfeecf793be421f8e17ea3e3efabb450f316f9a3a512c693
@@ -12,16 +12,20 @@ Metrics/ModuleLength:
12
12
  Metrics/ParameterLists:
13
13
  Max: 6
14
14
 
15
- Style/FileName:
16
- Exclude:
17
- - 'lib/ilo-sdk.rb'
18
-
19
15
  Style/IndentationWidth:
20
16
  Width: 2
21
17
 
22
18
  Style/VariableName:
23
19
  EnforcedStyle: snake_case
24
20
 
21
+ Style/FileName:
22
+ Exclude:
23
+ - 'lib/ilo-sdk.rb'
24
+
25
+ Style/AlignParameters:
26
+ Exclude:
27
+ - 'lib/ilo-sdk/cli.rb'
28
+
25
29
 
26
30
  Style/AccessorMethodName:
27
31
  Enabled: false
@@ -1,5 +1,18 @@
1
- ## v1.0.0
2
- Initial release
1
+ ### New (Unreleased)
2
+ - Added custom exception classes
3
+ - Added disable_proxy client option
4
+ - Added CLI
5
+ - Support environment variables
6
+
7
+ ### v1.1.0
8
+ - Added ManagerAccountHelper (to allow setting user permissions)
9
+
10
+ ### v1.0.2
11
+ - Make client.get_certificate return the full X509 object
3
12
 
4
13
  ### v1.0.1
14
+ - Added SSL certificate helper methods
5
15
  - Make `pry` a development dependency, not a runtime dependency.
16
+
17
+ ## v1.0.0
18
+ Initial release
data/README.md CHANGED
@@ -1,8 +1,13 @@
1
1
  # Ruby SDK for HPE iLO
2
+
2
3
  [![Gem Version](https://badge.fury.io/rb/ilo-sdk.svg)](https://badge.fury.io/rb/ilo-sdk)
3
4
 
4
5
  Software Development Kit for interacting with the Hewlett Packard Enterprise iLO (Integrated Lights-Out) server management technology.
5
6
 
7
+ ### Supported iLO versions:
8
+
9
+ - iLO 4
10
+
6
11
  ## Installation
7
12
 
8
13
  - Require the gem in your Gemfile:
@@ -20,8 +25,9 @@ Software Development Kit for interacting with the Hewlett Packard Enterprise iLO
20
25
 
21
26
 
22
27
  ## Client
23
- Everything you do with this API happens through a client object.
24
- Creating the client object is the first step; then you can perform actions on the client.
28
+
29
+ Everything you do with this API happens through a client object.
30
+ Creating the client object is the first step; then you can perform actions on the client.
25
31
 
26
32
  ```ruby
27
33
  require 'ilo-sdk'
@@ -31,13 +37,28 @@ client = ILO_SDK::Client.new(
31
37
  password: 'secret123',
32
38
  ssl_enabled: true, # This is the default and strongly encouraged
33
39
  logger: Logger.new(STDOUT), # This is the default
34
- log_level: :info # This is the default
40
+ log_level: :info, # This is the default
41
+ disable_proxy: true # Default is false. Set to disable, even if ENV['http_proxy'] is set
35
42
  )
36
43
  ```
37
44
 
38
- :lock: Tip: Check the file permissions because the password is stored in clear-text.
45
+ :lock: Tip: Check the file permissions when storing passwords in clear-text.
46
+
47
+ #### Environment Variables
48
+
49
+ You can also set many client options using environment variables. For bash:
50
+
51
+ ```bash
52
+ export ILO_HOST='https://oneview.example.com'
53
+ export ILO_USER='Administrator'
54
+ export ILO_PASSWORD='secret123'
55
+ export ILO_SSL_ENABLED=false # NOTE: Disabling SSL is strongly discouraged. Please see the CLI section for import instructions.
56
+ ```
57
+
58
+ :lock: Tip: Be sure nobody can access to your environment variables
39
59
 
40
60
  ### Custom logging
61
+
41
62
  The default logger is a standard logger to STDOUT, but if you want to specify your own, you can. However, your logger must implement the following methods:
42
63
 
43
64
  ```ruby
@@ -50,9 +71,11 @@ level=(Symbol, etc.) # The parameter here will be the log_level attribute
50
71
 
51
72
 
52
73
  ## Actions
74
+
53
75
  Actions are performed on the client, and defined in the [helper modules](lib/ilo-sdk/helpers).
54
76
 
55
77
  #### Account Service
78
+
56
79
  ```ruby
57
80
  # Get list of users:
58
81
  users = client.get_users
@@ -68,7 +91,19 @@ client.delete_user('user1')
68
91
  ```
69
92
 
70
93
  #### Bios
94
+
71
95
  ```ruby
96
+ # Get all BIOS settings
97
+ settings = client.get_bios_settings
98
+
99
+ # Set BIOS settings
100
+ client.set_bios_settings(
101
+ UefiShellStartup: 'Enabled',
102
+ Ipv4Gateway: '10.0.1.1',
103
+ ServiceEmail: 'admin@domain.com'
104
+ # Note: You can set many more options here. This is just an example.
105
+ )
106
+
72
107
  # Get BIOS base configuration:
73
108
  baseconfig = client.get_bios_baseconfig
74
109
 
@@ -105,11 +140,12 @@ bios_service_settings = client.get_bios_service
105
140
 
106
141
  # Set BIOS service settings:
107
142
  service_name = 'my_name'
108
- service_email = 'my_name@hpe.com'
143
+ service_email = 'my_name@domain.com'
109
144
  client.set_bios_service(service_name, service_email)
110
145
  ```
111
146
 
112
147
  #### Boot Settings
148
+
113
149
  ```ruby
114
150
  # Get boot order base configuration:
115
151
  baseconfig = client.get_boot_baseconfig
@@ -140,6 +176,7 @@ client.set_temporary_boot_order(boot_source_override_target)
140
176
  ```
141
177
 
142
178
  #### Chassis
179
+
143
180
  ```ruby
144
181
  # Get power metrics information:
145
182
  power_metrics = client.get_power_metrics
@@ -149,6 +186,7 @@ thermal_metrics = client.get_thermal_metrics
149
186
  ```
150
187
 
151
188
  #### Computer Details
189
+
152
190
  ```ruby
153
191
  # Get computer details (including general, network, and array controller details):
154
192
  computer_details = client.get_computer_details
@@ -164,21 +202,21 @@ array_controller_details = client.get_array_controller_details
164
202
  ```
165
203
 
166
204
  #### Computer System
167
- ```ruby
168
- # Get the computer system asset tag:
169
- asset_tag = client.get_asset_tag
170
-
171
- # Set the computer system asset tag:
172
- client.set_asset_tag('HP001')
173
205
 
174
- # Get the indicator led state:
175
- indicator_led = client.get_indicator_led
176
-
177
- # Set the indicator led state:
178
- client.set_indicator_led('Lit')
206
+ ```ruby
207
+ # Get computer system settings
208
+ settings = client.get_system_settings
209
+
210
+ # Set computer system settings
211
+ client.set_system_settings(
212
+ AssetTag: 'HP001',
213
+ IndicatorLED: 'Lit'
214
+ # Note: You can set more options here. This is just an example.
215
+ )
179
216
  ```
180
217
 
181
218
  #### Date Time
219
+
182
220
  ```ruby
183
221
  # Get the time zone:
184
222
  time_zone = client.get_time_zone
@@ -201,6 +239,7 @@ client.set_ntp_server(ntp_servers)
201
239
  ```
202
240
 
203
241
  #### Firmware
242
+
204
243
  ```ruby
205
244
  # Get the firmware version:
206
245
  fw_version = client.get_fw_version
@@ -210,6 +249,7 @@ client.set_fw_upgrade('www.firmwareupgrade.com')
210
249
  ```
211
250
 
212
251
  #### HTTPS Certificate
252
+
213
253
  ```ruby
214
254
  # Get the current SSL Certificate and check to see if expires within 24 hours
215
255
  expiration = client.get_certificate.not_after.to_datetime
@@ -240,6 +280,7 @@ end
240
280
  ```
241
281
 
242
282
  #### Log Entry
283
+
243
284
  ```ruby
244
285
  # Clear a specific type of logs:
245
286
  log_type = 'IEL'
@@ -254,7 +295,8 @@ duration = 10 # hours
254
295
  logs = client.get_log(severity_level, duration, log_type)
255
296
  ```
256
297
 
257
- ### Manager Account
298
+ #### Manager Account
299
+
258
300
  ```ruby
259
301
  # Get the Account Privileges for a specific user:
260
302
  username = 'Administrator'
@@ -276,6 +318,7 @@ client.set_account_privileges(username, privileges)
276
318
  ```
277
319
 
278
320
  #### Manager Network Protocol
321
+
279
322
  ```ruby
280
323
  # Get the minutes until session timeout:
281
324
  timeout = client.get_timeout
@@ -285,6 +328,7 @@ client.set_timeout(60)
285
328
  ```
286
329
 
287
330
  #### Power
331
+
288
332
  ```ruby
289
333
  # Get the power state of the system:
290
334
  power_state = client.get_power_state
@@ -297,6 +341,7 @@ client.reset_ilo
297
341
  ```
298
342
 
299
343
  #### Secure Boot
344
+
300
345
  ```ruby
301
346
  # Get whether or not UEFI secure boot is enabled:
302
347
  uefi_secure_boot = client.get_uefi_secure_boot
@@ -306,6 +351,7 @@ client.set_uefi_secure_boot(true)
306
351
  ```
307
352
 
308
353
  #### Service Root
354
+
309
355
  ```ruby
310
356
  # Get the schema information with a given prefix:
311
357
  schema_prefix = 'Account'
@@ -317,6 +363,7 @@ registry = client.get_registry(registry_prefix)
317
363
  ```
318
364
 
319
365
  #### SNMP
366
+
320
367
  ```ruby
321
368
  # Get the SNMP mode:
322
369
  snmp_mode = client.get_snmp_mode
@@ -331,6 +378,7 @@ client.set_snmp(snmp_mode, snmp_alerts_enabled)
331
378
  ```
332
379
 
333
380
  #### Virtual Media
381
+
334
382
  ```ruby
335
383
  # Get the virtual media information:
336
384
  virtual_media = client.get_virtual_media
@@ -348,6 +396,7 @@ client.eject_virtual_media(id)
348
396
  ```
349
397
 
350
398
  ## Custom requests
399
+
351
400
  In most cases, interacting with the client object is enough, but sometimes you need to make your own custom requests to the iLO.
352
401
  This project makes it extremely easy to do with some built-in methods for the client object. Here are some examples:
353
402
 
@@ -365,11 +414,36 @@ This example is about as basic as it gets, but you can make any type of iLO requ
365
414
  If a resource does not do what you need, this will allow you to do it.
366
415
  Please refer to the documentation and [code](lib/ilo-sdk/rest.rb) for complete list of methods and information about how to use them.
367
416
 
417
+
418
+ ## CLI
419
+
420
+ This gem also comes with a command-line interface to make interracting with the iLO API without needing to create a Ruby program.
421
+
422
+ Note: In order to use this, you will need to make sure your ruby bin directory is in your path. Run $ gem environment to see where the executable paths are for your Ruby installation.
423
+
424
+ To get started, run `$ ilo-ruby --help`.
425
+
426
+ To communicate with an appliance, you will need to set up a few environment variables so it knows how to communicate. Run $ ilo-ruby env to see the available environment variables.
427
+
428
+ Here are a few examples of how you might want to use the CLI:
429
+
430
+ ##### Start an interactive console session with an iLO connection:
431
+
432
+ ```bash
433
+ $ ilo-ruby console
434
+ Connected to https://ilo.example.com
435
+ HINT: The @client object is available to you
436
+ >
437
+ ```
438
+
439
+
368
440
  ## License
441
+
369
442
  This project is licensed under the Apache 2.0 license. Please see [LICENSE](LICENSE) for more info.
370
443
 
371
444
 
372
445
  ## Contributing and feature requests
446
+
373
447
  **Contributing:** You know the drill. Fork it, branch it, change it, commit it, and pull-request it.
374
448
  We are passionate about improving this project, and glad to accept help to make it better. However, keep the following in mind:
375
449
 
@@ -381,11 +455,13 @@ We are passionate about improving this project, and glad to accept help to make
381
455
  This feedback is crucial for us to deliver a useful product. Do not assume we have already thought of everything, because we assure you that is not the case.
382
456
 
383
457
  ### Building the Gem
458
+
384
459
  First run `$ bundle` (requires the bundler gem), then...
385
460
  - To build only, run `$ rake build`.
386
461
  - To build and install the gem, run `$ rake install`.
387
462
 
388
463
  ### Testing
464
+
389
465
  - RuboCop: `$ rake rubocop`
390
466
  - Unit: `$ rake spec`
391
467
  - All test: `$ rake test`
@@ -393,6 +469,7 @@ First run `$ bundle` (requires the bundler gem), then...
393
469
  Note: run `$ rake -T` to get a list of all the available rake tasks.
394
470
 
395
471
  ## Authors
472
+
396
473
  - Anirudh Gupta - [@Anirudh-Gupta](https://github.com/Anirudh-Gupta)
397
474
  - Bik Bajwa - [@bikbajwa](https://github.com/bikbajwa)
398
475
  - Jared Smartt - [@jsmartt](https://github.com/jsmartt)
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require 'ilo-sdk'
3
+ ILO_SDK::Cli::Runner.new(ARGV.dup).execute!
@@ -1,10 +1,10 @@
1
1
  # coding: utf-8
2
2
  # http://guides.rubygems.org/specification-reference
3
3
 
4
- # (C) Copyright 2016 Hewlett Packard Enterprise Development LP
4
+ # (c) Copyright 2016 Hewlett Packard Enterprise Development LP
5
5
  #
6
6
  # Licensed under the Apache License, Version 2.0 (the "License");
7
- # You may not use this file except in compliance with the License.
7
+ # you may not use this file except in compliance with the License.
8
8
  # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
9
9
  #
10
10
  # Unless required by applicable law or agreed to in writing, software distributed
@@ -29,7 +29,9 @@ Gem::Specification.new do |spec|
29
29
  spec.executables = all_files.grep(%r{^bin/}) { |f| File.basename(f) }
30
30
  spec.require_paths = ['lib']
31
31
 
32
- spec.add_development_dependency 'pry'
32
+ spec.add_runtime_dependency 'thor'
33
+ spec.add_runtime_dependency 'pry'
34
+
33
35
  spec.add_development_dependency 'bundler'
34
36
  spec.add_development_dependency 'rspec'
35
37
  spec.add_development_dependency 'rake'
@@ -1,7 +1,7 @@
1
- # (C) Copyright 2016 Hewlett Packard Enterprise Development LP
1
+ # (c) Copyright 2016 Hewlett Packard Enterprise Development LP
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
- # You may not use this file except in compliance with the License.
4
+ # you may not use this file except in compliance with the License.
5
5
  # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6
6
  #
7
7
  # Unless required by applicable law or agreed to in writing, software distributed
@@ -11,7 +11,10 @@
11
11
 
12
12
  require_relative 'ilo-sdk/version'
13
13
  require_relative 'ilo-sdk/client'
14
+ require_relative 'ilo-sdk/exceptions'
15
+ require_relative 'ilo-sdk/cli'
14
16
 
15
17
  # Module for interracting with the HPE iLO API
16
18
  module ILO_SDK
19
+ ENV_VARS = %w(ILO_HOST ILO_USER ILO_PASSWORD ILO_SSL_ENABLED).freeze
17
20
  end
@@ -0,0 +1,214 @@
1
+ # (c) Copyright 2016 Hewlett Packard Enterprise Development LP
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software distributed
8
+ # under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9
+ # CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
10
+ # language governing permissions and limitations under the License.
11
+
12
+ require 'thor'
13
+ require 'json'
14
+ require 'yaml'
15
+
16
+ module ILO_SDK
17
+ # cli for ilo-sdk
18
+ class Cli < Thor
19
+ # Runner class to enable testing
20
+ class Runner
21
+ def initialize(argv, stdin = STDIN, stdout = STDOUT, stderr = STDERR, kernel = Kernel)
22
+ @argv = argv
23
+ @stdin = stdin
24
+ @stdout = stdout
25
+ @stderr = stderr
26
+ @kernel = kernel
27
+ end
28
+
29
+ def execute!
30
+ exit_code = begin
31
+ $stderr = @stderr
32
+ $stdin = @stdin
33
+ $stdout = @stdout
34
+
35
+ ILO_SDK::Cli.start(@argv)
36
+ 0
37
+ rescue StandardError => e
38
+ b = e.backtrace
39
+ @stderr.puts("#{b.shift}: #{e.message} (#{e.class})")
40
+ @stderr.puts(b.map { |s| "\tfrom #{s}" }.join("\n"))
41
+ 1
42
+ rescue SystemExit => e
43
+ e.status
44
+ end
45
+
46
+ # Proxy our exit code back to the injected kernel.
47
+ @kernel.exit(exit_code)
48
+ end
49
+ end
50
+
51
+ class_option :ssl_verify,
52
+ type: :boolean,
53
+ desc: 'Enable/Disable SSL verification for requests. Can also use ENV[\'ILO_SSL_ENABLED\']',
54
+ default: nil
55
+
56
+ class_option :host,
57
+ desc: 'Hostname or URL of iLO. Can also use ENV[\'ILO_HOST\']'
58
+
59
+ class_option :user,
60
+ desc: 'Username. Can also use ENV[\'ILO_USER\']',
61
+ aliases: '-u'
62
+
63
+ class_option :log_level,
64
+ desc: 'Log level to use',
65
+ aliases: '-l',
66
+ enum: %w(debug info warn error),
67
+ default: 'warn'
68
+
69
+ map ['-v', '--version'] => :version
70
+
71
+
72
+ method_option :format,
73
+ desc: 'Output format',
74
+ aliases: '-f',
75
+ enum: %w(json yaml human),
76
+ default: 'human'
77
+ desc 'env', 'Show environment variables for ilo-sdk for Ruby'
78
+ def env
79
+ data = {}
80
+ ILO_SDK::ENV_VARS.each { |k| data[k] = ENV[k] }
81
+ if @options['format'] == 'human'
82
+ data.each do |key, value|
83
+ value = "'#{value}'" if value && ! %w(true false).include?(value)
84
+ printf "%-#{data.keys.max_by(&:length).length}s = %s\n", key, value || 'nil'
85
+ end
86
+ else
87
+ output(parse_hash(data, true))
88
+ end
89
+ end
90
+
91
+ desc 'console', 'Open a Ruby console with a connection to iLO'
92
+ def console
93
+ client_setup({}, true, true)
94
+ puts "Connected to #{@client.host}"
95
+ puts "HINT: The @client object is available to you\n\n"
96
+ rescue
97
+ puts "WARNING: Couldn't connect to #{@options['host'] || ENV['ILO_HOST'] || 'nil (host not set)'}\n\n"
98
+ ensure
99
+ require 'pry'
100
+ Pry.config.prompt = proc { '> ' }
101
+ Pry.plugins['stack_explorer'] && Pry.plugins['stack_explorer'].disable!
102
+ Pry.plugins['byebug'] && Pry.plugins['byebug'].disable!
103
+ Pry.start(ILO_SDK::Console.new(@client))
104
+ end
105
+
106
+ desc 'version', 'Print gem and iLO API versions'
107
+ def version
108
+ puts "Gem Version: #{ILO_SDK::VERSION}"
109
+ client_setup({ 'log_level' => :error }, true)
110
+ ver = @client.response_handler(@client.rest_get('/redfish/v1/'))['RedfishVersion']
111
+ puts "iLO Redfish API version: #{ver}"
112
+ rescue StandardError, SystemExit
113
+ puts 'iLO API version unknown'
114
+ end
115
+
116
+ desc 'login', 'Attempt loading an authenticated API endpoint'
117
+ def login
118
+ client_setup
119
+ @client.response_handler(@client.rest_get('/redfish/v1/Sessions/'))
120
+ puts 'Login Successful!'
121
+ end
122
+
123
+ private
124
+
125
+ def fail_nice(msg = nil)
126
+ puts "ERROR: #{msg}" if msg
127
+ exit 1
128
+ end
129
+
130
+ def client_setup(client_params = {}, quiet = false, throw_errors = false)
131
+ client_params['ssl_enabled'] = true if @options['ssl_verify'] == true
132
+ client_params['ssl_enabled'] = false if @options['ssl_verify'] == false
133
+ client_params['host'] ||= @options['host'] if @options['host']
134
+ client_params['user'] ||= @options['user'] if @options['user']
135
+ client_params['log_level'] ||= @options['log_level'].to_sym if @options['log_level']
136
+ @client = ILO_SDK::Client.new(client_params)
137
+ rescue StandardError => e
138
+ raise e if throw_errors
139
+ fail_nice if quiet
140
+ fail_nice "Failed to login to iLO at '#{client_params['host'] || ENV['ILO_HOST']}'. Message: #{e}"
141
+ end
142
+
143
+ # Parse options hash from input. Handles chaining and keywords such as true/false & nil
144
+ # Returns new hash with proper nesting and formatting
145
+ def parse_hash(hash, convert_types = false)
146
+ new_hash = {}
147
+ hash.each do |k, v|
148
+ if convert_types
149
+ v = v.to_i if v && v.match(/^\d+$/)
150
+ v = true if v == 'true'
151
+ v = false if v == 'false'
152
+ v = nil if v == 'nil'
153
+ end
154
+ if k =~ /\./
155
+ sub_hash = new_hash
156
+ split = k.split('.')
157
+ split.each do |sub_key|
158
+ if sub_key == split.last
159
+ sub_hash[sub_key] = v
160
+ else
161
+ sub_hash[sub_key] ||= {}
162
+ sub_hash = sub_hash[sub_key]
163
+ end
164
+ end
165
+ new_hash[split.first] ||= {}
166
+ else
167
+ new_hash[k] = v
168
+ end
169
+ end
170
+ new_hash
171
+ end
172
+
173
+ # Print output in a given format.
174
+ def output(data = {}, indent = 0)
175
+ case @options['format']
176
+ when 'json'
177
+ puts JSON.pretty_generate(data)
178
+ when 'yaml'
179
+ puts data.to_yaml
180
+ else
181
+ # rubocop:disable Metrics/BlockNesting
182
+ if data.class == Hash
183
+ data.each do |k, v|
184
+ if v.class == Hash || v.class == Array
185
+ puts "#{' ' * indent}#{k.nil? ? 'nil' : k}:"
186
+ output(v, indent + 2)
187
+ else
188
+ puts "#{' ' * indent}#{k.nil? ? 'nil' : k}: #{v.nil? ? 'nil' : v}"
189
+ end
190
+ end
191
+ elsif data.class == Array
192
+ data.each do |d|
193
+ if d.class == Hash || d.class == Array
194
+ output(d, indent + 2)
195
+ else
196
+ puts "#{' ' * indent}#{d.nil? ? 'nil' : d}"
197
+ end
198
+ end
199
+ puts "\nTotal: #{data.size}" if indent < 1
200
+ else
201
+ puts "#{' ' * indent}#{data.nil? ? 'nil' : data}"
202
+ end
203
+ # rubocop:enable Metrics/BlockNesting
204
+ end
205
+ end
206
+ end
207
+
208
+ # Console class
209
+ class Console
210
+ def initialize(client)
211
+ @client = client
212
+ end
213
+ end
214
+ end
@@ -17,32 +17,48 @@ Dir[File.join(File.dirname(__FILE__), '/helpers/*.rb')].each { |file| require fi
17
17
  module ILO_SDK
18
18
  # The client defines the connection to the iLO and handles communication with it
19
19
  class Client
20
- attr_accessor :host, :user, :password, :ssl_enabled, :logger, :log_level
20
+ attr_accessor :host, :user, :password, :ssl_enabled, :disable_proxy, :logger, :log_level
21
21
 
22
22
  # Create a client object
23
23
  # @param [Hash] options the options to configure the client
24
- # @option options [String] :host URL, hostname, or IP address of the iLO
24
+ # @option options [String] :host (ENV['ILO_HOST']) URL, hostname, or IP address of the iLO
25
25
  # @option options [String] :user ('Administrator') Username to use for authentication with the iLO
26
26
  # @option options [String] :password Password to use for authentication with the iLO
27
27
  # @option options [Logger] :logger (Logger.new(STDOUT)) Logger object to use.
28
28
  # Must implement debug(String), info(String), warn(String), error(String), & level=
29
29
  # @option options [Symbol] :log_level (:info) Log level. Logger must define a constant with this name. ie Logger::INFO
30
30
  # @option options [Boolean] :ssl_enabled (true) Use ssl for requests?
31
+ # @option options [Boolean] :disable_proxy (false) Disable usage of a proxy for requests?
31
32
  def initialize(options = {})
32
33
  options = Hash[options.map { |k, v| [k.to_sym, v] }] # Convert string hash keys to symbols
33
34
  @logger = options[:logger] || Logger.new(STDOUT)
34
35
  [:debug, :info, :warn, :error, :level=].each { |m| raise "Logger must respond to #{m} method " unless @logger.respond_to?(m) }
35
36
  @log_level = options[:log_level] || :info
36
37
  @logger.level = @logger.class.const_get(@log_level.upcase) rescue @log_level
37
- @host = options[:host]
38
- raise 'Must set the host option' unless @host
38
+ @host = options[:host] || ENV['ILO_HOST']
39
+ raise InvalidClient, 'Must set the host option' unless @host
39
40
  @host = 'https://' + @host unless @host.start_with?('http://', 'https://')
40
- @ssl_enabled = options[:ssl_enabled].nil? ? true : options[:ssl_enabled]
41
- raise 'ssl_enabled option must be either true or false' unless [true, false].include?(@ssl_enabled)
42
- @logger.warn 'User option not set. Using default (Administrator)' unless options[:user]
43
- @user = options[:user] || 'Administrator'
44
- @password = options[:password]
45
- raise 'Must set the password option' unless @password
41
+ @ssl_enabled = true # Default
42
+ if ENV.key?('ILO_SSL_ENABLED')
43
+ @ssl_enabled = case ENV['ILO_SSL_ENABLED']
44
+ when 'true', '1' then true
45
+ when 'false', '0' then false
46
+ else ENV['ILO_SSL_ENABLED']
47
+ end
48
+ end
49
+ @ssl_enabled = options[:ssl_enabled] unless options[:ssl_enabled].nil?
50
+ unless [true, false].include?(@ssl_enabled)
51
+ raise InvalidClient, "ssl_enabled option must be true or false. Got '#{@ssl_enabled}'"
52
+ end
53
+ unless @ssl_enabled
54
+ @logger.warn "SSL is disabled for all requests to #{@host}! We recommend you import the necessary certificates instead. of disabling SSL"
55
+ end
56
+ @disable_proxy = options[:disable_proxy]
57
+ raise InvalidClient, 'disable_proxy option must be true, false, or nil' unless [true, false, nil].include?(@disable_proxy)
58
+ @logger.warn 'User option not set. Using default (Administrator)' unless options[:user] || ENV['ILO_USER']
59
+ @user = options[:user] || ENV['ILO_USER'] || 'Administrator'
60
+ @password = options[:password] || ENV['ILO_PASSWORD']
61
+ raise InvalidClient, 'Must set the password option' unless @password
46
62
  end
47
63
 
48
64
  include Rest
@@ -0,0 +1,31 @@
1
+ # (c) Copyright 2016 Hewlett Packard Enterprise Development LP
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # You may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software distributed
8
+ # under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9
+ # CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
10
+ # language governing permissions and limitations under the License.
11
+
12
+ # Contains all the custom Exception classes
13
+ module ILO_SDK
14
+ class InvalidClient < StandardError # Client configuration is invalid
15
+ end
16
+
17
+ class InvalidRequest < StandardError # Could not make request
18
+ end
19
+
20
+ class BadRequest < StandardError # 400
21
+ end
22
+
23
+ class Unauthorized < StandardError # 401
24
+ end
25
+
26
+ class NotFound < StandardError # 404
27
+ end
28
+
29
+ class RequestError < StandardError # Other bad response codes
30
+ end
31
+ end
@@ -12,6 +12,25 @@
12
12
  module ILO_SDK
13
13
  # Contains helper methods for Bios actions
14
14
  module BiosHelper
15
+ # Get all the BIOS settings
16
+ # @param system_id [Integer, String] ID of the system
17
+ # @raise [RuntimeError] if the request failed
18
+ # @return [Hash] BIOS settings
19
+ def get_bios_settings(system_id = 1)
20
+ response_handler(rest_get("/redfish/v1/Systems/#{system_id}/bios/Settings/"))
21
+ end
22
+
23
+ # Set BIOS settings
24
+ # @param options [Hash] Hash of options to set
25
+ # @param system_id [Integer, String] ID of the system
26
+ # @raise [RuntimeError] if the request failed
27
+ # @return true
28
+ def set_bios_settings(options, system_id = 1)
29
+ r = response_handler(rest_patch("/redfish/v1/Systems/#{system_id}/bios/Settings/", body: options))
30
+ @logger.warn(r) if r['error']
31
+ true
32
+ end
33
+
15
34
  # Get the bios base config
16
35
  # @raise [RuntimeError] if the request failed
17
36
  # @return [Fixnum] bios_baseconfig
@@ -44,9 +63,9 @@ module ILO_SDK
44
63
  end
45
64
 
46
65
  # Set the UEFI shell start up
47
- # @param [String, Symbol] uefi_shell_startup
48
- # @param [String, Symbol] uefi_shell_startup_location
49
- # @param [String, Symbol] uefi_shell_startup_url
66
+ # @param uefi_shell_startup [String, Symbol]
67
+ # @param uefi_shell_startup_location [String, Symbol]
68
+ # @param uefi_shell_startup_url [String, Symbol]
50
69
  # @raise [RuntimeError] if the request failed
51
70
  # @return true
52
71
  def set_uefi_shell_startup(uefi_shell_startup, uefi_shell_startup_location, uefi_shell_startup_url)
@@ -77,12 +96,12 @@ module ILO_SDK
77
96
  end
78
97
 
79
98
  # Set the BIOS DHCP
80
- # @param [String, Symbol] dhcpv4
81
- # @param [String, Symbol] ipv4_address
82
- # @param [String, Symbol] ipv4_gateway
83
- # @param [String, Symbol] ipv4_primary_dns
84
- # @param [String, Symbol] ipv4_secondary_dns
85
- # @param [String, Symbol] ipv4_subnet_mask
99
+ # @param dhcpv4 [String, Symbol]
100
+ # @param ipv4_address [String, Symbol]
101
+ # @param ipv4_gateway [String, Symbol]
102
+ # @param ipv4_primary_dns [String, Symbol]
103
+ # @param ipv4_secondary_dns [String, Symbol]
104
+ # @param ipv4_subnet_mask [String, Symbol]
86
105
  # @raise [RuntimeError] if the request failed
87
106
  # @return true
88
107
  def set_bios_dhcp(dhcpv4, ipv4_address = '', ipv4_gateway = '', ipv4_primary_dns = '', ipv4_secondary_dns = '', ipv4_subnet_mask = '')
@@ -108,7 +127,7 @@ module ILO_SDK
108
127
  end
109
128
 
110
129
  # Set the URL boot file
111
- # @param [String, Symbol] url_boot_file
130
+ # @param url_boot_file [String, Symbol]
112
131
  # @raise [RuntimeError] if the request failed
113
132
  # @return true
114
133
  def set_url_boot_file(url_boot_file)
@@ -131,8 +150,8 @@ module ILO_SDK
131
150
  end
132
151
 
133
152
  # Set the BIOS service
134
- # @param [String, Symbol] name
135
- # @param [String, Symbol] email
153
+ # @param name [String, Symbol]
154
+ # @param email [String, Symbol]
136
155
  # @raise [RuntimeError] if the request failed
137
156
  # @return true
138
157
  def set_bios_service(name, email)
@@ -1,7 +1,7 @@
1
- # (C) Copyright 2016 Hewlett Packard Enterprise Development LP
1
+ # (c) Copyright 2016 Hewlett Packard Enterprise Development LP
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
- # You may not use this file except in compliance with the License.
4
+ # you may not use this file except in compliance with the License.
5
5
  # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6
6
  #
7
7
  # Unless required by applicable law or agreed to in writing, software distributed
@@ -12,19 +12,41 @@
12
12
  module ILO_SDK
13
13
  # Contains helper methods for Computer System actions
14
14
  module ComputerSystemHelper
15
+ # Get the computer system settings
16
+ # @param system_id [Integer, String] ID of the system
17
+ # @raise [RuntimeError] if the request failed
18
+ # @return [Hash] Computer system settings
19
+ def get_system_settings(system_id = 1)
20
+ response_handler(rest_get("/redfish/v1/Systems/#{system_id}/"))
21
+ end
22
+
23
+ # Set computer system settings
24
+ # @param options [Hash] Hash of options to set
25
+ # @param system_id [Integer, String] ID of the system
26
+ # @raise [RuntimeError] if the request failed
27
+ # @return true
28
+ def set_system_settings(options, system_id = 1)
29
+ response_handler(rest_patch("/redfish/v1/Systems/#{system_id}/", body: options))
30
+ true
31
+ end
32
+
15
33
  # Get the Asset Tag
34
+ # @deprecated Use {#get_system_settings} instead
16
35
  # @raise [RuntimeError] if the request failed
17
36
  # @return [String] asset_tag
18
37
  def get_asset_tag
38
+ @logger.warn '[Deprecated] `get_asset_tag` is deprecated. Please use `get_system_settings[\'AssetTag\']` instead.'
19
39
  response = rest_get('/redfish/v1/Systems/1/')
20
40
  response_handler(response)['AssetTag']
21
41
  end
22
42
 
23
43
  # Set the Asset Tag
24
- # @param [String, Symbol] asset_tag
44
+ # @deprecated Use {#set_system_settings} instead
45
+ # @param asset_tag [String, Symbol]
25
46
  # @raise [RuntimeError] if the request failed
26
47
  # @return true
27
48
  def set_asset_tag(asset_tag)
49
+ @logger.warn '[Deprecated] `set_asset_tag` is deprecated. Please use `set_system_settings(AssetTag: <tag>)` instead.'
28
50
  new_action = { 'AssetTag' => asset_tag }
29
51
  response = rest_patch('/redfish/v1/Systems/1/', body: new_action)
30
52
  response_handler(response)
@@ -32,18 +54,22 @@ module ILO_SDK
32
54
  end
33
55
 
34
56
  # Get the UID indicator LED state
57
+ # @deprecated Use {#get_system_settings} instead
35
58
  # @raise [RuntimeError] if the request failed
36
59
  # @return [String] indicator_led
37
60
  def get_indicator_led
61
+ @logger.warn '[Deprecated] `get_indicator_led` is deprecated. Please use `get_system_settings[\'IndicatorLED\']` instead.'
38
62
  response = rest_get('/redfish/v1/Systems/1/')
39
63
  response_handler(response)['IndicatorLED']
40
64
  end
41
65
 
42
66
  # Set the UID indicator LED
43
- # @param [String, Symbol] state
67
+ # @deprecated Use {#set_system_settings} instead
68
+ # @param state [String, Symbol]
44
69
  # @raise [RuntimeError] if the request failed
45
70
  # @return true
46
71
  def set_indicator_led(state)
72
+ @logger.warn '[Deprecated] `set_indicator_led` is deprecated. Please use `set_system_settings(IndicatorLED: <state>)` instead.'
47
73
  new_action = { 'IndicatorLED' => state }
48
74
  response = rest_patch('/redfish/v1/Systems/1/', body: new_action)
49
75
  response_handler(response)
@@ -1,4 +1,4 @@
1
- # (C) Copyright 2016 Hewlett Packard Enterprise Development LP
1
+ # (c) Copyright 2016 Hewlett Packard Enterprise Development LP
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # You may not use this file except in compliance with the License.
@@ -23,14 +23,17 @@ module ILO_SDK
23
23
  # @param [Hash] options the options for the request
24
24
  # @option options [String] :body Hash to be converted into json and set as the request body
25
25
  # @option options [String] :Content-Type ('application/json') Set to nil or :none to have this option removed
26
+ # @raise [InvalidRequest] if the request is invalid
27
+ # @raise [SocketError] if a connection could not be made
28
+ # @raise [OpenSSL::SSL::SSLError] if SSL validation of the iLO's certificate failed
26
29
  # @return [NetHTTPResponse] The response object
27
30
  def rest_api(type, path, options = {})
28
- raise 'Must specify path' unless path
29
- raise 'Must specify type' unless type
31
+ raise InvalidRequest, 'Must specify path' unless path
32
+ raise InvalidRequest, 'Must specify type' unless type
30
33
  @logger.debug "Making :#{type} rest call to #{@host}#{path}"
31
34
 
32
35
  uri = URI.parse(URI.escape("#{@host}#{path}"))
33
- http = Net::HTTP.new(uri.host, uri.port)
36
+ http = @disable_proxy ? Net::HTTP.new(uri.host, uri.port, nil, nil) : Net::HTTP.new(uri.host, uri.port)
34
37
  http.use_ssl = true if uri.scheme == 'https'
35
38
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE unless @ssl_enabled
36
39
 
@@ -39,12 +42,15 @@ module ILO_SDK
39
42
  @logger.debug " Response: Code=#{response.code}. Headers=#{response.to_hash}\n Body=#{response.body}"
40
43
  response
41
44
  rescue OpenSSL::SSL::SSLError => e
42
- msg = 'SSL verification failed for request. Please either:'
43
- msg += "\n 1. Install the certificate into your cert store"
45
+ msg = 'SSL verification failed for the request. Please either:'
46
+ msg += "\n 1. Install the necessary certificate(s) into your cert store"
44
47
  msg += ". Using cert store: #{ENV['SSL_CERT_FILE']}" if ENV['SSL_CERT_FILE']
45
- msg += "\n 2. Set the :ssl_enabled option to false for your ilo client"
48
+ msg += "\n 2. Set the :ssl_enabled option to false for your iLO client (not recommended)"
46
49
  @logger.error msg
47
50
  raise e
51
+ rescue SocketError => e
52
+ e.message.prepend("Failed to connect to iLO host #{@host}!\n")
53
+ raise e
48
54
  end
49
55
 
50
56
  # Make a restful GET request
@@ -88,8 +94,10 @@ module ILO_SDK
88
94
  # Handle the response for rest call.
89
95
  # If an asynchronous task was started, this waits for it to complete.
90
96
  # @param [HTTPResponse] HTTP response
91
- # @raise [RuntimeError] if the request failed
92
- # @raise [RuntimeError] if a task was returned that did not complete successfully
97
+ # @raise [ILO_SDK::BadRequest] if the request failed with a 400 status
98
+ # @raise [ILO_SDK::Unauthorized] if the request failed with a 401 status
99
+ # @raise [ILO_SDK::NotFound] if the request failed with a 404 status
100
+ # @raise [ILO_SDK::RequestError] if the request failed with any other status
93
101
  # @return [Hash] The parsed JSON body
94
102
  def response_handler(response)
95
103
  case response.code.to_i
@@ -113,19 +121,23 @@ module ILO_SDK
113
121
  when RESPONSE_CODE_NO_CONTENT # Synchronous delete
114
122
  return {}
115
123
  when RESPONSE_CODE_BAD_REQUEST
116
- raise "400 BAD REQUEST #{response.body}"
124
+ raise BadRequest, "400 BAD REQUEST #{response.body}"
117
125
  when RESPONSE_CODE_UNAUTHORIZED
118
- raise "401 UNAUTHORIZED #{response.body}"
126
+ raise Unauthorized, "401 UNAUTHORIZED #{response.body}"
119
127
  when RESPONSE_CODE_NOT_FOUND
120
- raise "404 NOT FOUND #{response.body}"
128
+ raise NotFound, "404 NOT FOUND #{response.body}"
121
129
  else
122
- raise "#{response.code} #{response.body}"
130
+ raise RequestError, "#{response.code} #{response.body}"
123
131
  end
124
132
  end
125
133
 
126
134
 
127
135
  private
128
136
 
137
+ # @param type [Symbol] The type of request object to build (get, post, put, patch, or delete)
138
+ # @param uri [URI] URI object
139
+ # @param options [Hash] Options for building the request. All options except "body" are set as headers.
140
+ # @raise [ILO_SDK::InvalidRequest] if the request type is not recognized
129
141
  def build_request(type, uri, options)
130
142
  case type.downcase
131
143
  when 'get', :get
@@ -139,7 +151,7 @@ module ILO_SDK
139
151
  when 'delete', :delete
140
152
  request = Net::HTTP::Delete.new(uri.request_uri)
141
153
  else
142
- raise "Invalid rest call: #{type}"
154
+ raise InvalidRequest, "Invalid rest call: #{type}"
143
155
  end
144
156
  options['Content-Type'] ||= 'application/json'
145
157
  options.delete('Content-Type') if [:none, 'none', nil].include?(options['Content-Type'])
@@ -1,7 +1,7 @@
1
- # (C) Copyright 2016 Hewlett Packard Enterprise Development LP
1
+ # (c) Copyright 2016 Hewlett Packard Enterprise Development LP
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
- # You may not use this file except in compliance with the License.
4
+ # you may not use this file except in compliance with the License.
5
5
  # You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
6
6
  #
7
7
  # Unless required by applicable law or agreed to in writing, software distributed
@@ -11,5 +11,5 @@
11
11
 
12
12
  # Gem version defined here
13
13
  module ILO_SDK
14
- VERSION = '1.1.0'.freeze
14
+ VERSION = '1.2.0'.freeze
15
15
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ilo-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anirudh Gupta
@@ -11,8 +11,22 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2016-08-08 00:00:00.000000000 Z
14
+ date: 2016-08-25 00:00:00.000000000 Z
15
15
  dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: thor
18
+ requirement: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
16
30
  - !ruby/object:Gem::Dependency
17
31
  name: pry
18
32
  requirement: !ruby/object:Gem::Requirement
@@ -20,7 +34,7 @@ dependencies:
20
34
  - - ">="
21
35
  - !ruby/object:Gem::Version
22
36
  version: '0'
23
- type: :development
37
+ type: :runtime
24
38
  prerelease: false
25
39
  version_requirements: !ruby/object:Gem::Requirement
26
40
  requirements:
@@ -103,7 +117,8 @@ email:
103
117
  - bik.bajwa@hpe.com
104
118
  - jared.smartt@hpe.com
105
119
  - vivek.bhatia@hpe.com
106
- executables: []
120
+ executables:
121
+ - ilo-ruby
107
122
  extensions: []
108
123
  extra_rdoc_files: []
109
124
  files:
@@ -115,9 +130,12 @@ files:
115
130
  - LICENSE
116
131
  - README.md
117
132
  - Rakefile
133
+ - bin/ilo-ruby
118
134
  - ilo-sdk.gemspec
119
135
  - lib/ilo-sdk.rb
136
+ - lib/ilo-sdk/cli.rb
120
137
  - lib/ilo-sdk/client.rb
138
+ - lib/ilo-sdk/exceptions.rb
121
139
  - lib/ilo-sdk/helpers/account_service_helper.rb
122
140
  - lib/ilo-sdk/helpers/bios_helper.rb
123
141
  - lib/ilo-sdk/helpers/boot_settings_helper.rb