idrac 0.1.29 → 0.1.30

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.
@@ -6,6 +6,7 @@ require 'nokogiri'
6
6
  require 'fileutils'
7
7
  require 'securerandom'
8
8
  require 'set'
9
+ require 'colorize'
9
10
  require_relative 'firmware_catalog'
10
11
 
11
12
  module IDRAC
@@ -126,30 +127,30 @@ module IDRAC
126
127
  system_model = inventory[:system][:model]
127
128
  service_tag = inventory[:system][:service_tag]
128
129
 
129
- puts "Checking updates for system with service tag: #{service_tag}"
130
- puts "Searching for updates for model: #{system_model}"
130
+ puts "Checking updates for system with service tag: #{service_tag}".light_cyan
131
+ puts "Searching for updates for model: #{system_model}".light_cyan
131
132
 
132
133
  # Find system models in the catalog
133
134
  models = catalog.find_system_models(system_model)
134
135
 
135
136
  if models.empty?
136
- puts "No matching system model found in catalog"
137
+ puts "No matching system model found in catalog".yellow
137
138
  return []
138
139
  end
139
140
 
140
141
  # Use the first matching model
141
142
  model = models.first
142
- puts "Found system IDs for #{model[:name]}: #{model[:id]}"
143
+ puts "Found system IDs for #{model[:name]}: #{model[:id]}".green
143
144
 
144
145
  # Find updates for this system
145
146
  catalog_updates = catalog.find_updates_for_system(model[:id])
146
- puts "Found #{catalog_updates.size} firmware updates for #{model[:name]}"
147
+ puts "Found #{catalog_updates.size} firmware updates for #{model[:name]}".green
147
148
 
148
149
  # Compare current firmware with available updates
149
150
  updates = []
150
151
 
151
152
  # Print header for firmware comparison table
152
- puts "\nFirmware Version Comparison:"
153
+ puts "\nFirmware Version Comparison:".green.bold
153
154
  puts "=" * 100
154
155
  puts "%-30s %-20s %-20s %-10s %-15s %s" % ["Component", "Current Version", "Available Version", "Updateable", "Category", "Status"]
155
156
  puts "-" * 100
@@ -205,25 +206,25 @@ module IDRAC
205
206
  fw[:name].to_s[0..29],
206
207
  fw[:version],
207
208
  update[:version],
208
- fw[:updateable] ? "Yes" : "No",
209
+ fw[:updateable] ? "Yes".light_green : "No".light_red,
209
210
  update[:category] || "N/A",
210
- "UPDATE AVAILABLE"
211
+ "UPDATE AVAILABLE".light_green.bold
211
212
  ]
212
213
  else
213
214
  # Print row with no update needed
214
215
  status = if !needs_update
215
- "Current"
216
+ "Current".light_blue
216
217
  elsif !fw[:updateable]
217
- "Not updateable"
218
+ "Not updateable".light_red
218
219
  else
219
- "No update needed"
220
+ "No update needed".light_yellow
220
221
  end
221
222
 
222
223
  puts "%-30s %-20s %-20s %-10s %-15s %s" % [
223
224
  fw[:name].to_s[0..29],
224
225
  fw[:version],
225
226
  update[:version] || "N/A",
226
- fw[:updateable] ? "Yes" : "No",
227
+ fw[:updateable] ? "Yes".light_green : "No".light_red,
227
228
  update[:category] || "N/A",
228
229
  status
229
230
  ]
@@ -234,9 +235,9 @@ module IDRAC
234
235
  fw[:name].to_s[0..29],
235
236
  fw[:version],
236
237
  "N/A",
237
- fw[:updateable] ? "Yes" : "No",
238
+ fw[:updateable] ? "Yes".light_green : "No".light_red,
238
239
  "N/A",
239
- "No update available"
240
+ "No update available".light_yellow
240
241
  ]
241
242
  end
242
243
  end
@@ -261,11 +262,11 @@ module IDRAC
261
262
 
262
263
  puts "%-30s %-20s %-20s %-10s %-15s %s" % [
263
264
  update_name.to_s[0..29],
264
- "Not Installed",
265
+ "Not Installed".light_red,
265
266
  update[:version] || "Unknown",
266
267
  "N/A",
267
268
  update[:category] || "N/A",
268
- "NEW COMPONENT"
269
+ "NEW COMPONENT".light_blue
269
270
  ]
270
271
  end
271
272
 
@@ -278,13 +279,13 @@ module IDRAC
278
279
  updates = selected_updates || check_updates(catalog_path)
279
280
 
280
281
  if updates.empty?
281
- puts "No updates available for your system."
282
+ puts "No updates available for your system.".yellow
282
283
  return
283
284
  end
284
285
 
285
- puts "\nAvailable updates:"
286
+ puts "\nAvailable Updates:".green.bold
286
287
  updates.each_with_index do |update, index|
287
- puts "#{index + 1}. #{update[:name]}: #{update[:current_version]} -> #{update[:available_version]}"
288
+ puts "#{index + 1}. #{update[:name]}: #{update[:current_version]} -> #{update[:available_version]}".light_cyan
288
289
  end
289
290
 
290
291
  # If selected_updates is provided, use those directly
@@ -292,7 +293,7 @@ module IDRAC
292
293
  selected = selected_updates
293
294
  else
294
295
  # Otherwise prompt the user for selection
295
- puts "\nEnter the number of the update to install (or 'all' for all updates, 'q' to quit):"
296
+ puts "\nEnter the number of the update to install (or 'all' for all updates, 'q' to quit):".light_yellow
296
297
  choice = STDIN.gets.chomp
297
298
 
298
299
  return if choice.downcase == 'q'
@@ -304,14 +305,14 @@ module IDRAC
304
305
  if index >= 0 && index < updates.size
305
306
  [updates[index]]
306
307
  else
307
- puts "Invalid selection."
308
+ puts "Invalid selection.".red
308
309
  return
309
310
  end
310
311
  end
311
312
  end
312
313
 
313
314
  selected.each do |update|
314
- puts "Downloading #{update[:name]} version #{update[:available_version]}..."
315
+ puts "Downloading #{update[:name]} version #{update[:available_version]}...".light_cyan.bold
315
316
 
316
317
  # Create temp directory
317
318
  temp_dir = Dir.mktmpdir
@@ -332,33 +333,33 @@ module IDRAC
332
333
  end
333
334
  end
334
335
  else
335
- puts "Failed to download update: #{response.code} #{response.message}"
336
+ puts "Failed to download update: #{response.code} #{response.message}".red
336
337
  next
337
338
  end
338
339
  end
339
340
  end
340
341
 
341
- puts "Installing #{update[:name]} version #{update[:available_version]}..."
342
+ puts "Installing #{update[:name]} version #{update[:available_version]}...".light_cyan.bold
342
343
 
343
344
  begin
344
345
  job_id = update(update_path, wait: true)
345
- puts "Update completed with job ID: #{job_id}"
346
+ puts "Update completed with job ID: #{job_id}".green.bold
346
347
  rescue IDRAC::Error => e
347
348
  if e.message.include?("already in progress")
348
- puts "Error: #{e.message}"
349
- puts "\nTips for resolving this issue:"
350
- puts "1. Wait for any existing firmware updates to complete (check iDRAC web interface)"
351
- puts "2. Restart the iDRAC if no updates appear to be in progress (Settings > iDRAC Settings > Reset iDRAC)"
352
- puts "3. Try again after a few minutes"
349
+ puts "Error: #{e.message}".red.bold
350
+ puts "\nTips for resolving this issue:".yellow.bold
351
+ puts "1. Wait for any existing firmware updates to complete (check iDRAC web interface)".light_yellow
352
+ puts "2. Restart the iDRAC if no updates appear to be in progress (Settings > iDRAC Settings > Reset iDRAC)".light_yellow
353
+ puts "3. Try again after a few minutes".light_yellow
353
354
  elsif e.message.include?("job ID") || e.message.include?("job not found")
354
- puts "Error: #{e.message}"
355
- puts "\nThe job ID could not be found or monitored. This could be because:"
356
- puts "1. The iDRAC is busy processing other requests"
357
- puts "2. The job was created but not properly tracked"
358
- puts "3. The iDRAC firmware may need to be updated first"
359
- puts "\nCheck the iDRAC web interface to see if the update was actually initiated."
355
+ puts "Error: #{e.message}".red.bold
356
+ puts "\nThe job ID could not be found or monitored. This could be because:".yellow
357
+ puts "1. The iDRAC is busy processing other requests".light_yellow
358
+ puts "2. The job was created but not properly tracked".light_yellow
359
+ puts "3. The iDRAC firmware may need to be updated first".light_yellow
360
+ puts "\nCheck the iDRAC web interface to see if the update was actually initiated.".light_cyan
360
361
  else
361
- puts "Error during firmware update: #{e.message}"
362
+ puts "Error during firmware update: #{e.message}".red.bold
362
363
  end
363
364
  end
364
365
 
@@ -2,10 +2,13 @@ require 'net/http'
2
2
  require 'uri'
3
3
  require 'fileutils'
4
4
  require 'nokogiri'
5
+ require 'open-uri'
6
+ require 'colorize'
5
7
 
6
8
  module IDRAC
7
9
  class FirmwareCatalog
8
- CATALOG_URL = "https://downloads.dell.com/catalog/Catalog.xml.gz"
10
+ DELL_CATALOG_BASE = 'https://downloads.dell.com'
11
+ DELL_CATALOG_URL = "#{DELL_CATALOG_BASE}/catalog/Catalog.xml.gz"
9
12
 
10
13
  attr_reader :catalog_path
11
14
 
@@ -14,40 +17,38 @@ module IDRAC
14
17
  end
15
18
 
16
19
  def download(output_dir = nil)
17
- # Use ~/.idrac as the default directory
18
- output_dir ||= File.expand_path("~/.idrac")
20
+ # Default to ~/.idrac directory
21
+ output_dir ||= File.expand_path('~/.idrac')
19
22
  FileUtils.mkdir_p(output_dir) unless Dir.exist?(output_dir)
20
23
 
21
- catalog_gz_path = File.join(output_dir, "Catalog.xml.gz")
22
- catalog_path = File.join(output_dir, "Catalog.xml")
23
-
24
- puts "Downloading Dell catalog from #{CATALOG_URL}..."
25
-
26
- uri = URI.parse(CATALOG_URL)
27
- Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
28
- request = Net::HTTP::Get.new(uri)
29
- http.request(request) do |response|
30
- if response.code == "200"
31
- File.open(catalog_gz_path, 'wb') do |file|
32
- response.read_body do |chunk|
33
- file.write(chunk)
34
- end
35
- end
36
- else
37
- raise Error, "Failed to download catalog: #{response.code} #{response.message}"
38
- end
39
- end
40
- end
24
+ catalog_gz = File.join(output_dir, 'Catalog.xml.gz')
25
+ catalog_xml = File.join(output_dir, 'Catalog.xml')
41
26
 
42
- puts "Extracting catalog..."
43
- system("gunzip -f #{catalog_gz_path}")
27
+ puts "Downloading Dell catalog from #{DELL_CATALOG_URL}...".light_cyan
44
28
 
45
- if File.exist?(catalog_path)
46
- puts "Catalog downloaded and extracted to #{catalog_path}"
47
- @catalog_path = catalog_path
48
- return catalog_path
49
- else
50
- raise Error, "Failed to extract catalog"
29
+ begin
30
+ # Download the catalog
31
+ URI.open(DELL_CATALOG_URL) do |remote_file|
32
+ File.open(catalog_gz, 'wb') do |local_file|
33
+ local_file.write(remote_file.read)
34
+ end
35
+ end
36
+
37
+ puts "Extracting catalog...".light_cyan
38
+
39
+ # Extract the catalog
40
+ system("gunzip -f #{catalog_gz}")
41
+
42
+ if File.exist?(catalog_xml)
43
+ puts "Catalog downloaded and extracted to #{catalog_xml}".green
44
+ @catalog_path = catalog_xml
45
+ return catalog_xml
46
+ else
47
+ raise Error, "Failed to extract catalog"
48
+ end
49
+ rescue => e
50
+ puts "Error downloading catalog: #{e.message}".red.bold
51
+ raise Error, "Failed to download Dell catalog: #{e.message}"
51
52
  end
52
53
  end
53
54
 
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.29"
4
+ VERSION = "0.1.30"
5
5
  end
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require_relative 'lib/idrac'
3
+ require 'lib/idrac'
4
+ require 'colorize'
4
5
 
5
6
  # Create a client
6
7
  client = IDRAC::Client.new(
@@ -12,59 +13,56 @@ client = IDRAC::Client.new(
12
13
 
13
14
  begin
14
15
  # Login to iDRAC
16
+ puts "Logging in to iDRAC...".light_cyan
15
17
  client.login
16
- puts "Logged in successfully"
18
+ puts "Logged in successfully".green
17
19
 
18
20
  # Create a firmware instance
19
21
  firmware = IDRAC::Firmware.new(client)
20
22
 
21
23
  # Get system inventory
22
- puts "Getting system inventory..."
24
+ puts "Getting system inventory...".light_cyan
23
25
  inventory = firmware.get_system_inventory
24
26
 
25
- puts "System Information:"
26
- puts " Model: #{inventory[:system][:model]}"
27
- puts " Manufacturer: #{inventory[:system][:manufacturer]}"
28
- puts " Service Tag: #{inventory[:system][:service_tag]}"
29
- puts " BIOS Version: #{inventory[:system][:bios_version]}"
27
+ puts "System Information:".green.bold
28
+ puts " Model: #{inventory[:system][:model]}".light_cyan
29
+ puts " Manufacturer: #{inventory[:system][:manufacturer]}".light_cyan
30
+ puts " Service Tag: #{inventory[:system][:service_tag]}".light_cyan
31
+ puts " BIOS Version: #{inventory[:system][:bios_version]}".light_cyan
30
32
 
31
- puts "\nInstalled Firmware:"
33
+ puts "\nInstalled Firmware:".green.bold
32
34
  inventory[:firmware].each do |fw|
33
- puts " #{fw[:name]}: #{fw[:version]} (#{fw[:updateable] ? 'Updateable' : 'Not Updateable'})"
35
+ puts " #{fw[:name]}: #{fw[:version]} (#{fw[:updateable] ? 'Updateable'.light_green : 'Not Updateable'.light_red})".light_cyan
34
36
  end
35
37
 
36
38
  # Check for updates
37
39
  catalog_path = File.expand_path("~/.idrac/Catalog.xml")
38
40
  if File.exist?(catalog_path)
39
- puts "\nChecking for updates using catalog: #{catalog_path}"
41
+ puts "\nChecking for updates using catalog: #{catalog_path}".light_cyan
40
42
  updates = firmware.check_updates(catalog_path)
41
43
 
42
- if updates.empty?
43
- puts "No updates available."
44
- else
45
- puts "\nAvailable Updates:"
44
+ if updates.any?
45
+ puts "\nAvailable Updates:".green.bold
46
46
  updates.each_with_index do |update, index|
47
- puts "#{index + 1}. #{update[:name]}: #{update[:current_version]} -> #{update[:available_version]}"
47
+ puts "#{index + 1}. #{update[:name]}: #{update[:current_version]} -> #{update[:available_version]}".light_cyan
48
48
  end
49
49
 
50
- # For testing, select the first update
51
- if updates.any?
52
- selected_update = updates.first
53
- puts "\nSelected update: #{selected_update[:name]}: #{selected_update[:current_version]} -> #{selected_update[:available_version]}"
54
-
55
- # Download and install the update
56
- puts "Starting interactive update for selected component..."
57
- firmware.interactive_update(catalog_path, [selected_update])
58
- end
50
+ # Interactive update for the first update
51
+ puts "\nSelected update: #{updates.first[:name]}".light_yellow
52
+ puts "Starting interactive update for selected component...".light_cyan.bold
53
+
54
+ firmware.interactive_update(catalog_path, [updates.first])
55
+ else
56
+ puts "No updates available for your system.".yellow
59
57
  end
60
58
  else
61
- puts "\nCatalog file not found at #{catalog_path}. Please download the catalog first."
59
+ puts "\nCatalog not found at #{catalog_path}. Run 'idrac firmware:catalog' to download it.".yellow
62
60
  end
63
61
 
64
62
  rescue IDRAC::Error => e
65
- puts "Error: #{e.message}"
63
+ puts "Error: #{e.message}".red.bold
66
64
  ensure
67
65
  # Logout
68
- client.logout if client.instance_variable_get(:@session_id)
69
- puts "Logged out"
66
+ client.logout if client
67
+ puts "Logged out".light_cyan
70
68
  end