idrac 0.1.20 → 0.1.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 87d81ae109224d8bfee1a4513bb10d307c703b74ab0d540a78aed849f16e26c4
4
- data.tar.gz: 210a4e787490a16f76994090dc908248b97efec8f7bdb3c8a8136e6aee63ec5d
3
+ metadata.gz: a32506a7e00919c067cf111bdb2cd7f2e3422302a93f2678512ffa8e17b46758
4
+ data.tar.gz: 7271bbbfcdca8616c4cb9c742c46a49213f314eaa0774e4dd2e31e189402ac49
5
5
  SHA512:
6
- metadata.gz: ea89b9514218b74a2393bc5eb46cc121a60ce9c6c9e0726f6c9df38b40dbb2cb5196bbc20350e56662729af77ef278dbabf6c4b61d162ac1a97467e3ef4fb548
7
- data.tar.gz: a4213988f3a7ad827b20f90b8cdb4be43ffed7b20bc58f6dce3b9570b6504d73dfc34f67285f6cdd94515e0ec0a52651b27360c75464e297d0e0a448fbbf6774
6
+ metadata.gz: 3918c78519d1d10062a9efe2bf69988a038e6d82dc433478448901b12eeb55bdd1ba371ea1843309f6a2eba40c2eb80f8feb88dfa25f01e3e6811bca70039de8
7
+ data.tar.gz: a96828348048c1b281ed075f23d3baed1446206806085a87d4699a14879d186cc44dfc552bd1950c07517eb05fe0b6591b80f75822a4f44d778099e1cdfb8ca5
data/README.md CHANGED
@@ -105,6 +105,14 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
105
105
 
106
106
  ## Changelog
107
107
 
108
+ ### Version 0.1.21
109
+ - **Improved Authentication Flow**: Completely restructured the login process
110
+ - Renamed `legacy_login` to `webui_login` and limited its use to screenshot functionality only
111
+ - Implemented proper Redfish authentication flow: start with direct login to get a session
112
+ - Enhanced session management: when max sessions are encountered, delete sessions using direct login
113
+ - Simplified code by removing redundant authentication methods and focusing on Redfish standards
114
+ - Improved error handling and logging for better troubleshooting
115
+
108
116
  ### Version 0.1.20
109
117
  - **Simplified CLI Interface**: Removed the direct-mode CLI option
110
118
  - Maintained internal direct mode functionality as an automatic fallback mechanism
data/lib/idrac/client.rb CHANGED
@@ -34,58 +34,18 @@ module IDRAC
34
34
  end
35
35
  end
36
36
 
37
- # Force clear all sessions by attempting multiple login/logout cycles
37
+ # Force clear all sessions by directly using Basic Auth
38
38
  def force_clear_sessions
39
39
  puts "Attempting to force clear all sessions..."
40
40
 
41
- # First try to delete sessions directly using Basic Auth
41
+ # Try to delete sessions directly using Basic Auth
42
42
  if delete_all_sessions_with_basic_auth
43
43
  puts "Successfully cleared sessions using Basic Auth"
44
44
  return true
45
+ else
46
+ puts "Failed to clear sessions using Basic Auth"
47
+ return false
45
48
  end
46
-
47
- # If direct deletion fails, try the login/logout cycle approach
48
- puts "Falling back to login/logout cycle approach for clearing sessions..."
49
-
50
- # Try multiple login/logout cycles with both methods
51
- 3.times do |i|
52
- begin
53
- # Try Redfish session first
54
- begin
55
- if create_redfish_session
56
- puts "Successfully created Redfish session (attempt #{i+1})"
57
- delete_redfish_session
58
- puts "Deleted Redfish session (attempt #{i+1})"
59
- sleep(2)
60
- end
61
- rescue => e
62
- puts "Error during Redfish session cycle: #{e.message}"
63
- end
64
-
65
- # Then try legacy session
66
- begin
67
- legacy_login(i)
68
- puts "Successfully created legacy session (attempt #{i+1})"
69
- legacy_logout
70
- puts "Deleted legacy session (attempt #{i+1})"
71
- sleep(2)
72
- rescue => e
73
- # If we get "maximum sessions" error, that's expected
74
- if e.message.include?("maximum number of user sessions")
75
- puts "Maximum sessions error during legacy login (expected during clearing)"
76
- else
77
- puts "Error during legacy session cycle: #{e.message}"
78
- end
79
- end
80
-
81
- # Add a longer delay between cycles
82
- sleep(3) if i < 2
83
- rescue => e
84
- puts "Error during session clearing cycle #{i+1}: #{e.message}"
85
- end
86
- end
87
-
88
- puts "Completed session clearing attempts"
89
49
  end
90
50
 
91
51
  # Delete all sessions using Basic Authentication
@@ -158,19 +118,25 @@ module IDRAC
158
118
  end
159
119
  end
160
120
 
161
- # Create a Redfish session (preferred method for all Redfish API calls)
121
+ # Create a Redfish session
162
122
  def create_redfish_session
163
- # Skip if we're in direct mode or we know sessions are maxed out
164
- if @direct_mode || @sessions_maxed
165
- puts "Skipping Redfish session creation (direct mode or sessions maxed)"
123
+ # Skip if we're in direct mode
124
+ if @direct_mode
125
+ puts "Skipping Redfish session creation (direct mode)"
166
126
  return false
167
127
  end
168
128
 
169
129
  url = '/redfish/v1/SessionService/Sessions'
170
130
  payload = { "UserName" => username, "Password" => password }
171
131
 
132
+ # Use Basic Auth for the initial session creation
133
+ basic_auth_headers = {
134
+ 'Authorization' => "Basic #{Base64.strict_encode64("#{username}:#{password}")}",
135
+ 'Content-Type' => 'application/json'
136
+ }
137
+
172
138
  response = connection.post(url) do |req|
173
- req.headers['Content-Type'] = 'application/json'
139
+ req.headers.merge!(basic_auth_headers)
174
140
  req.body = payload.to_json
175
141
  end
176
142
 
@@ -188,14 +154,13 @@ module IDRAC
188
154
  puts "Maximum sessions reached during Redfish session creation"
189
155
  @sessions_maxed = true
190
156
 
191
- # Only try to clear sessions if we haven't tried too many times
192
- if !@tried_clearing_sessions
193
- @tried_clearing_sessions = true
194
- force_clear_sessions
157
+ # Try to clear sessions
158
+ if force_clear_sessions
159
+ puts "Successfully cleared sessions, trying to create a new session"
195
160
 
196
161
  # Try one more time after clearing
197
162
  response = connection.post(url) do |req|
198
- req.headers['Content-Type'] = 'application/json'
163
+ req.headers.merge!(basic_auth_headers)
199
164
  req.body = payload.to_json
200
165
  end
201
166
 
@@ -212,7 +177,7 @@ module IDRAC
212
177
  return false
213
178
  end
214
179
  else
215
- # If we've already tried clearing sessions, switch to direct mode
180
+ puts "Failed to clear sessions, switching to direct mode"
216
181
  @direct_mode = true
217
182
  return false
218
183
  end
@@ -244,24 +209,13 @@ module IDRAC
244
209
  end
245
210
  end
246
211
 
247
- # Legacy login method for screenshot functionality
248
- def legacy_login(retry_count = 0)
249
- # Skip if we're in direct mode
250
- if @direct_mode
251
- puts "Skipping legacy login (direct mode)"
252
- return false
253
- end
254
-
212
+ # WebUI login method for screenshot functionality only
213
+ def webui_login(retry_count = 0)
255
214
  # Limit retries to prevent infinite loops
256
215
  if retry_count >= 3
257
- # If we've tried too many times, switch to direct mode
258
- @direct_mode = true
259
- raise Error, "Failed to login after multiple attempts due to maximum sessions limit"
216
+ raise Error, "Failed to login to WebUI after multiple attempts"
260
217
  end
261
218
 
262
- # Always try to logout first to clear any existing sessions
263
- legacy_logout if retry_count > 0
264
-
265
219
  response = connection.post('/data/login') do |req|
266
220
  req.headers['Content-Type'] = 'application/x-www-form-urlencoded'
267
221
  req.body = "user=#{username}&password=#{password}"
@@ -282,13 +236,13 @@ module IDRAC
282
236
  if error_message && !error_message.empty?
283
237
  # Check for maximum sessions error
284
238
  if error_message.include?("maximum number of user sessions")
285
- puts "Maximum sessions reached, attempting to clear sessions (attempt #{retry_count + 1}/3)..."
286
- # Try to clear any existing sessions by forcing a logout
287
- legacy_logout
288
- # Wait longer for the server to process the logout
289
- sleep(5)
239
+ puts "Maximum sessions reached for WebUI, attempting to clear sessions (attempt #{retry_count + 1}/3)..."
240
+ # Try to clear any existing sessions
241
+ force_clear_sessions
242
+ # Wait for the server to process the session changes
243
+ sleep(3)
290
244
  # Try logging in again with incremented retry counter
291
- return legacy_login(retry_count + 1)
245
+ return webui_login(retry_count + 1)
292
246
  end
293
247
 
294
248
  raise Error, "Error Message: #{error_message}"
@@ -297,27 +251,21 @@ module IDRAC
297
251
  forward_url = xml_doc.xpath('//forwardUrl').text
298
252
  return forward_url
299
253
  else
300
- raise Error, "Login failed with status #{response.status}: #{response.body}"
254
+ raise Error, "WebUI login failed with status #{response.status}: #{response.body}"
301
255
  end
302
256
  end
303
257
 
304
- # Legacy logout method for screenshot functionality
305
- def legacy_logout
258
+ # WebUI logout method for screenshot functionality
259
+ def webui_logout
306
260
  return unless @session_id
307
261
 
308
262
  begin
309
- # Try multiple logout attempts to ensure session is cleared
310
- 3.times do |i|
311
- response = connection.get('/data/logout') do |req|
312
- req.headers['Cookie'] = "sessionid=#{@session_id}"
313
- end
314
-
315
- break if response.status == 200
316
- sleep(1) if i < 2 # Sleep between attempts, but not after the last one
263
+ response = connection.get('/data/logout') do |req|
264
+ req.headers['Cookie'] = "sessionid=#{@session_id}"
317
265
  end
318
266
  rescue => e
319
267
  # Ignore errors during logout
320
- puts "Warning: Error during logout: #{e.message}"
268
+ puts "Warning: Error during WebUI logout: #{e.message}"
321
269
  ensure
322
270
  @session_id = nil
323
271
  @cookies = nil
@@ -326,7 +274,7 @@ module IDRAC
326
274
  true
327
275
  end
328
276
 
329
- # Main login method that decides which approach to use
277
+ # Main login method
330
278
  def login
331
279
  # If we're in direct mode, skip login attempts
332
280
  if @direct_mode
@@ -334,40 +282,29 @@ module IDRAC
334
282
  return true
335
283
  end
336
284
 
337
- # First try to create a Redfish session
285
+ # Try to create a Redfish session
338
286
  if create_redfish_session
339
287
  return true
340
288
  else
341
- # If we failed to create a Redfish session, try to clear sessions first
342
- if !@tried_clearing_sessions
343
- @tried_clearing_sessions = true
344
- force_clear_sessions
345
-
346
- # Try Redfish again
347
- if create_redfish_session
348
- return true
349
- end
350
- end
351
-
352
- # Fall back to legacy login if Redfish session creation fails
353
- if !@direct_mode
354
- puts "Falling back to legacy login method"
355
- return legacy_login
356
- else
289
+ # If we failed to create a Redfish session and direct_mode is set, just return
290
+ if @direct_mode
357
291
  puts "Operating in direct mode (no session)"
358
292
  return true
293
+ else
294
+ # If we're here, something went wrong with session creation
295
+ raise Error, "Failed to create a session and direct mode is not enabled"
359
296
  end
360
297
  end
361
298
  end
362
299
 
363
- # Main logout method that decides which approach to use
300
+ # Main logout method
364
301
  def logout
365
302
  if @x_auth_token
366
303
  delete_redfish_session
367
304
  end
368
305
 
369
306
  if @session_id
370
- legacy_logout
307
+ webui_logout
371
308
  end
372
309
 
373
310
  true
@@ -384,23 +321,15 @@ module IDRAC
384
321
  # Ensure we have a valid session (unless in direct mode)
385
322
  unless @direct_mode
386
323
  begin
387
- login unless @x_auth_token || @session_id
324
+ login unless @x_auth_token
388
325
  rescue Error => e
389
- # If login fails with maximum sessions error, try to handle it
390
- if e.message.include?("maximum number of user sessions") && retry_count < 2
391
- puts "Maximum sessions reached during initial login, attempting to clear sessions (attempt #{retry_count + 1}/3)..."
392
- logout
393
- sleep(5) # Longer delay
394
- return authenticated_request(method, path, options, retry_count + 1)
326
+ # If login fails and we've tried too many times, switch to direct mode
327
+ if retry_count >= 2
328
+ @direct_mode = true
329
+ puts "Switching to direct mode after multiple authentication failures"
395
330
  else
396
- # If we've tried too many times, switch to direct mode
397
- if retry_count >= 2
398
- @direct_mode = true
399
- puts "Switching to direct mode after multiple authentication failures"
400
- else
401
- # Re-raise other errors or if we've tried too many times
402
- raise
403
- end
331
+ # Re-raise other errors
332
+ raise
404
333
  end
405
334
  end
406
335
  end
@@ -410,9 +339,6 @@ module IDRAC
410
339
  # Use X-Auth-Token if available (preferred Redfish method)
411
340
  if @x_auth_token
412
341
  options[:headers]['X-Auth-Token'] = @x_auth_token
413
- elsif @session_id
414
- # Fall back to session cookie if needed
415
- options[:headers]['Cookie'] = "sessionid=#{@session_id}"
416
342
  elsif @direct_mode
417
343
  # In direct mode, use Basic Auth
418
344
  options[:headers]['Authorization'] = "Basic #{Base64.strict_encode64("#{username}:#{password}")}"
@@ -427,15 +353,13 @@ module IDRAC
427
353
  if response.status == 401 && !@direct_mode
428
354
  puts "Session expired, re-authenticating..."
429
355
  logout
430
- sleep(3)
356
+ sleep(2)
431
357
  login
432
358
 
433
359
  # Update headers with new authentication
434
360
  options[:headers] ||= {}
435
361
  if @x_auth_token
436
362
  options[:headers]['X-Auth-Token'] = @x_auth_token
437
- elsif @session_id
438
- options[:headers]['Cookie'] = "sessionid=#{@session_id}"
439
363
  elsif @direct_mode
440
364
  options[:headers]['Authorization'] = "Basic #{Base64.strict_encode64("#{username}:#{password}")}"
441
365
  end
@@ -453,31 +377,13 @@ module IDRAC
453
377
  end
454
378
  end
455
379
 
456
- # Check for maximum sessions error in the response
457
- if response.status == 200
458
- begin
459
- xml_doc = Nokogiri::XML(response.body)
460
- error_message = xml_doc.at_xpath('//errorMsg')&.text
461
-
462
- if error_message && error_message.include?("maximum number of user sessions") && retry_count < 2
463
- puts "Maximum sessions reached, clearing sessions and retrying (attempt #{retry_count + 1}/3)..."
464
- logout
465
- sleep(5)
466
- login
467
- return authenticated_request(method, path, options, retry_count + 1)
468
- end
469
- rescue => e
470
- # If we can't parse the response as XML, just continue
471
- end
472
- end
473
-
474
380
  response
475
381
  end
476
382
 
477
383
  def get(path:, headers: {})
478
- # For screenshot functionality, we need to use the legacy cookies
479
- if @cookies.nil? && !@direct_mode
480
- legacy_login unless @session_id
384
+ # For screenshot functionality, we need to use the WebUI cookies
385
+ if @cookies.nil? && path.include?('screen/screen.jpg')
386
+ webui_login unless @session_id
481
387
  end
482
388
 
483
389
  headers_to_use = {
@@ -490,6 +396,8 @@ module IDRAC
490
396
  elsif @direct_mode
491
397
  # In direct mode, use Basic Auth
492
398
  headers_to_use["Authorization"] = "Basic #{Base64.strict_encode64("#{username}:#{password}")}"
399
+ elsif @x_auth_token
400
+ headers_to_use["X-Auth-Token"] = @x_auth_token
493
401
  end
494
402
 
495
403
  response = HTTParty.get(
data/lib/idrac/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module IDRAC
4
- VERSION = "0.1.20"
4
+ VERSION = "0.1.21"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: idrac
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.20
4
+ version: 0.1.21
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonathan Siegel