idrac 0.1.24 → 0.1.26
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 +4 -4
- data/README.md +14 -0
- data/lib/idrac/client.rb +93 -40
- data/lib/idrac/firmware.rb +89 -21
- data/lib/idrac/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4d751ffb6e590b80a6a5dc72457d8a4be11213224a13ebeae50698ae9f6cafff
|
4
|
+
data.tar.gz: 5a3f826850bf9aee8e40287ff7f8ab7c5bd71944ddce2b183dbe88dabed9c3fa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 553bef804c000680be8ecadb15c19f2b4a335db5a7a44b5071ccb230f168880268e906f5a296a70c8659a5bbbb14a0ffb3a6f56cfc4c9ca216e0a1f8a6024a0f
|
7
|
+
data.tar.gz: ff4d0ce0967de6fbddd425844e0c86165276c44d508a2b8de41a20ec54e3998f7d2f1d5aa7cadf34201dd26113bd0abafb1e01d13439edbcb1d22f273e31a1f5
|
data/README.md
CHANGED
@@ -127,6 +127,20 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
127
127
|
|
128
128
|
## Changelog
|
129
129
|
|
130
|
+
### Version 0.1.26
|
131
|
+
- **Improved Redfish Session Creation**: Fixed issues with the Redfish session creation process
|
132
|
+
- Added multiple fallback methods for creating sessions with different iDRAC versions
|
133
|
+
- Fixed 415 Unsupported Media Type error by trying different content types
|
134
|
+
- Added support for form-urlencoded requests when JSON requests fail
|
135
|
+
- Enhanced error handling and logging during session creation
|
136
|
+
|
137
|
+
### Version 0.1.25
|
138
|
+
- **Enhanced Component Matching**: Improved firmware component matching with catalog entries
|
139
|
+
- Added extraction of model numbers and identifiers from component names (X520, H730, etc.)
|
140
|
+
- Implemented multiple matching strategies for better accuracy
|
141
|
+
- Added special handling for different component types (NIC, PERC, BIOS, iDRAC, etc.)
|
142
|
+
- Improved matching for components with different naming conventions
|
143
|
+
|
130
144
|
### Version 0.1.24
|
131
145
|
- **Improved Firmware Update Check**: Fixed issues with firmware version comparison
|
132
146
|
- Eliminated duplicate entries in firmware update results
|
data/lib/idrac/client.rb
CHANGED
@@ -130,67 +130,120 @@ module IDRAC
|
|
130
130
|
url = '/redfish/v1/SessionService/Sessions'
|
131
131
|
payload = { "UserName" => username, "Password" => password }
|
132
132
|
|
133
|
-
#
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
133
|
+
# Try first with just Content-Type header (no Basic Auth)
|
134
|
+
begin
|
135
|
+
response = connection.post(url) do |req|
|
136
|
+
req.headers['Content-Type'] = 'application/json'
|
137
|
+
req.body = payload.to_json
|
138
|
+
end
|
139
|
+
|
140
|
+
if response.status == 201 || response.status == 200
|
141
|
+
# Extract X-Auth-Token from response headers
|
142
|
+
@x_auth_token = response.headers['X-Auth-Token']
|
143
|
+
|
144
|
+
# Extract session location from response headers
|
145
|
+
@session_location = response.headers['Location']
|
146
|
+
|
147
|
+
puts "Redfish session created successfully"
|
148
|
+
@sessions_maxed = false
|
149
|
+
return true
|
150
|
+
end
|
151
|
+
rescue => e
|
152
|
+
puts "First session creation attempt failed: #{e.message}"
|
142
153
|
end
|
143
154
|
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
155
|
+
# If that fails, try with Basic Auth
|
156
|
+
begin
|
157
|
+
# Use Basic Auth for the session creation
|
158
|
+
basic_auth_headers = {
|
159
|
+
'Authorization' => "Basic #{Base64.strict_encode64("#{username}:#{password}")}",
|
160
|
+
'Content-Type' => 'application/json'
|
161
|
+
}
|
150
162
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
puts "Maximum sessions reached during Redfish session creation"
|
156
|
-
@sessions_maxed = true
|
163
|
+
response = connection.post(url) do |req|
|
164
|
+
req.headers.merge!(basic_auth_headers)
|
165
|
+
req.body = payload.to_json
|
166
|
+
end
|
157
167
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
168
|
+
if response.status == 201 || response.status == 200
|
169
|
+
# Extract X-Auth-Token from response headers
|
170
|
+
@x_auth_token = response.headers['X-Auth-Token']
|
171
|
+
|
172
|
+
# Extract session location from response headers
|
173
|
+
@session_location = response.headers['Location']
|
174
|
+
|
175
|
+
puts "Redfish session created successfully with Basic Auth"
|
176
|
+
@sessions_maxed = false
|
177
|
+
return true
|
178
|
+
elsif response.status == 400 && response.body.include?("maximum number of user sessions")
|
179
|
+
puts "Maximum sessions reached during Redfish session creation"
|
180
|
+
@sessions_maxed = true
|
181
|
+
|
182
|
+
# Try to clear sessions if auto_delete_sessions is enabled
|
183
|
+
if @auto_delete_sessions
|
184
|
+
puts "Auto-delete sessions is enabled, attempting to clear sessions"
|
185
|
+
if force_clear_sessions
|
186
|
+
puts "Successfully cleared sessions, trying to create a new session"
|
187
|
+
|
188
|
+
# Try one more time after clearing
|
189
|
+
response = connection.post(url) do |req|
|
190
|
+
req.headers.merge!(basic_auth_headers)
|
191
|
+
req.body = payload.to_json
|
192
|
+
end
|
193
|
+
|
194
|
+
if response.status == 201 || response.status == 200
|
195
|
+
@x_auth_token = response.headers['X-Auth-Token']
|
196
|
+
@session_location = response.headers['Location']
|
197
|
+
puts "Redfish session created successfully after clearing sessions"
|
198
|
+
@sessions_maxed = false
|
199
|
+
return true
|
200
|
+
else
|
201
|
+
puts "Failed to create Redfish session after clearing: #{response.status} - #{response.body}"
|
202
|
+
# If we still can't create a session, switch to direct mode
|
203
|
+
@direct_mode = true
|
204
|
+
return false
|
205
|
+
end
|
206
|
+
else
|
207
|
+
puts "Failed to clear sessions, switching to direct mode"
|
208
|
+
@direct_mode = true
|
209
|
+
return false
|
210
|
+
end
|
211
|
+
else
|
212
|
+
puts "Auto-delete sessions is disabled, switching to direct mode"
|
213
|
+
@direct_mode = true
|
214
|
+
return false
|
215
|
+
end
|
216
|
+
else
|
217
|
+
puts "Failed to create Redfish session: #{response.status} - #{response.body}"
|
218
|
+
|
219
|
+
# If we get a 415 error, try with form-urlencoded
|
220
|
+
if response.status == 415
|
221
|
+
puts "Trying with form-urlencoded content type"
|
165
222
|
response = connection.post(url) do |req|
|
166
|
-
req.headers
|
167
|
-
req.
|
223
|
+
req.headers['Content-Type'] = 'application/x-www-form-urlencoded'
|
224
|
+
req.headers['Authorization'] = "Basic #{Base64.strict_encode64("#{username}:#{password}")}"
|
225
|
+
req.body = "UserName=#{URI.encode_www_form_component(username)}&Password=#{URI.encode_www_form_component(password)}"
|
168
226
|
end
|
169
227
|
|
170
228
|
if response.status == 201 || response.status == 200
|
171
229
|
@x_auth_token = response.headers['X-Auth-Token']
|
172
230
|
@session_location = response.headers['Location']
|
173
|
-
puts "Redfish session created successfully
|
231
|
+
puts "Redfish session created successfully with form-urlencoded"
|
174
232
|
@sessions_maxed = false
|
175
233
|
return true
|
176
234
|
else
|
177
|
-
puts "Failed
|
178
|
-
# If we still can't create a session, switch to direct mode
|
235
|
+
puts "Failed with form-urlencoded too: #{response.status} - #{response.body}"
|
179
236
|
@direct_mode = true
|
180
237
|
return false
|
181
238
|
end
|
182
239
|
else
|
183
|
-
puts "Failed to clear sessions, switching to direct mode"
|
184
240
|
@direct_mode = true
|
185
241
|
return false
|
186
242
|
end
|
187
|
-
else
|
188
|
-
puts "Auto-delete sessions is disabled, switching to direct mode"
|
189
|
-
@direct_mode = true
|
190
|
-
return false
|
191
243
|
end
|
192
|
-
|
193
|
-
puts "
|
244
|
+
rescue => e
|
245
|
+
puts "Error during Redfish session creation: #{e.message}"
|
246
|
+
@direct_mode = true
|
194
247
|
return false
|
195
248
|
end
|
196
249
|
end
|
data/lib/idrac/firmware.rb
CHANGED
@@ -157,7 +157,8 @@ module IDRAC
|
|
157
157
|
current_versions[fw[:id]] = {
|
158
158
|
name: fw[:name],
|
159
159
|
version: fw[:version],
|
160
|
-
updateable: fw[:updateable]
|
160
|
+
updateable: fw[:updateable],
|
161
|
+
identifiers: extract_identifiers(fw[:name]) # Extract identifiers for better matching
|
161
162
|
}
|
162
163
|
end
|
163
164
|
|
@@ -170,43 +171,110 @@ module IDRAC
|
|
170
171
|
|
171
172
|
next unless name && version && path # Skip if missing essential data
|
172
173
|
|
174
|
+
# Extract identifiers from catalog component name for better matching
|
175
|
+
catalog_identifiers = extract_identifiers(name)
|
176
|
+
|
173
177
|
# Check if this component matches any of our firmware
|
174
178
|
# We'll track if we found a match to avoid duplicates
|
175
179
|
matched = false
|
176
180
|
|
177
181
|
current_versions.each do |id, fw_info|
|
182
|
+
# Skip if not updateable
|
183
|
+
next unless fw_info[:updateable]
|
184
|
+
|
178
185
|
# Normalize names for comparison
|
179
186
|
catalog_name = name.downcase.strip
|
180
187
|
firmware_name = fw_info[:name].downcase.strip
|
181
188
|
|
182
|
-
# Check
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
# Mark as matched to avoid duplicates
|
201
|
-
matched = true
|
189
|
+
# Check for matches using multiple strategies
|
190
|
+
match_found = false
|
191
|
+
|
192
|
+
# 1. Check if names contain each other
|
193
|
+
if catalog_name.include?(firmware_name) || firmware_name.include?(catalog_name)
|
194
|
+
match_found = true
|
195
|
+
end
|
196
|
+
|
197
|
+
# 2. Check if BIOS components match
|
198
|
+
if (catalog_name.include?("bios") && firmware_name.include?("bios"))
|
199
|
+
match_found = true
|
200
|
+
end
|
201
|
+
|
202
|
+
# 3. Check if identifiers match
|
203
|
+
if !match_found && !fw_info[:identifiers].empty? && !catalog_identifiers.empty?
|
204
|
+
# Check if any identifier from firmware matches any identifier from catalog
|
205
|
+
if (fw_info[:identifiers] & catalog_identifiers).any?
|
206
|
+
match_found = true
|
202
207
|
end
|
203
208
|
end
|
209
|
+
|
210
|
+
# If we found a match and versions differ, add to updates
|
211
|
+
if match_found && !matched && version != fw_info[:version]
|
212
|
+
updates << {
|
213
|
+
name: name,
|
214
|
+
current_version: fw_info[:version],
|
215
|
+
available_version: version,
|
216
|
+
path: path,
|
217
|
+
component_type: component_type,
|
218
|
+
download_url: "https://downloads.dell.com/#{path}"
|
219
|
+
}
|
220
|
+
|
221
|
+
# Mark as matched to avoid duplicates
|
222
|
+
matched = true
|
223
|
+
end
|
204
224
|
end
|
205
225
|
end
|
206
226
|
|
207
227
|
updates
|
208
228
|
end
|
209
229
|
|
230
|
+
def extract_identifiers(name)
|
231
|
+
return [] unless name
|
232
|
+
|
233
|
+
identifiers = []
|
234
|
+
|
235
|
+
# Extract model numbers like X520, I350, etc.
|
236
|
+
model_matches = name.scan(/[IX]\d{3,4}/)
|
237
|
+
identifiers.concat(model_matches)
|
238
|
+
|
239
|
+
# Extract PERC model like H730
|
240
|
+
perc_matches = name.scan(/[HP]\d{3,4}/)
|
241
|
+
identifiers.concat(perc_matches)
|
242
|
+
|
243
|
+
# Extract other common identifiers
|
244
|
+
if name.include?("NIC") || name.include?("Ethernet") || name.include?("Network")
|
245
|
+
identifiers << "NIC"
|
246
|
+
end
|
247
|
+
|
248
|
+
if name.include?("PERC") || name.include?("RAID")
|
249
|
+
identifiers << "PERC"
|
250
|
+
# Extract PERC model like H730
|
251
|
+
perc_match = name.match(/PERC\s+([A-Z]\d{3})/)
|
252
|
+
identifiers << perc_match[1] if perc_match
|
253
|
+
end
|
254
|
+
|
255
|
+
if name.include?("BIOS")
|
256
|
+
identifiers << "BIOS"
|
257
|
+
end
|
258
|
+
|
259
|
+
if name.include?("iDRAC") || name.include?("IDRAC") || name.include?("Remote Access Controller")
|
260
|
+
identifiers << "iDRAC"
|
261
|
+
end
|
262
|
+
|
263
|
+
if name.include?("Power Supply") || name.include?("PSU")
|
264
|
+
identifiers << "PSU"
|
265
|
+
end
|
266
|
+
|
267
|
+
if name.include?("Lifecycle Controller")
|
268
|
+
identifiers << "LC"
|
269
|
+
end
|
270
|
+
|
271
|
+
if name.include?("CPLD")
|
272
|
+
identifiers << "CPLD"
|
273
|
+
end
|
274
|
+
|
275
|
+
identifiers
|
276
|
+
end
|
277
|
+
|
210
278
|
def interactive_update(catalog_path = nil)
|
211
279
|
updates = check_updates(catalog_path)
|
212
280
|
|
data/lib/idrac/version.rb
CHANGED