idrac 0.3.1 → 0.3.2

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: 03ccc12c3ebfe533e453933a630bc43624da934519341ac269babc529d47f19d
4
- data.tar.gz: d143150b5233763300314b462ad01a8716725e46a884b1739e76566e38a9233a
3
+ metadata.gz: 0563eaa5f82230341766606c73b15cf2e850b45b1ef3859f2aaa9e49b9c65df9
4
+ data.tar.gz: 29ee247993cb532d71447b5fa5fff1406a91a2d553923cedd8e207eb5a0c9c4a
5
5
  SHA512:
6
- metadata.gz: 1f23b2fe0d6ed9c150c60643b87ae046e4f67bca4bc249ed4a1761082c2793f11ac88998c33552951b3cebb35afae0826baff804463ed35c79a47f35d0174ed9
7
- data.tar.gz: a4bada808af965d7b371be12e5758a5b2c220b66333505a7166ab9dceb048cc30907ef05c2da4a23cb821bf770fb145516998e6447898c4e91e44af486281193
6
+ metadata.gz: 351a3b5d3c973d7a7c4ec1767fbd73f46eea0149e713c29bea930974efae1a9c4eeda008ce964fcb307bca02d12571734cc96429fd5901fa4e4021f84bbab391
7
+ data.tar.gz: db4363923ae2e7581e55ff7622b75b889622f9e5aa04b8cfaf33b957c5015495cdbffb787dec8c56d28c86cd956fac4e24bd54331b7854a907cf75ad9e6008e0
data/bin/idrac CHANGED
@@ -456,6 +456,145 @@ module IDRAC
456
456
  end
457
457
  end
458
458
 
459
+ desc "test:all", "Run tests for all major functionality areas"
460
+ map "test" => :test_all
461
+ option :quiet, type: :boolean, default: false, desc: "Minimize output, just show pass/fail"
462
+ option :skip_destructive, type: :boolean, default: true, desc: "Skip tests that could modify the system"
463
+ def test_all
464
+ quiet = options[:quiet]
465
+ skip_destructive = options[:skip_destructive]
466
+
467
+ passed = []
468
+ failed = []
469
+ skipped = []
470
+
471
+ tests = [
472
+ # Basic information
473
+ { name: "System Summary", method: -> (c) { c.summary } },
474
+ { name: "Redfish Version", method: -> (c) { c.redfish_version } },
475
+
476
+ # Power methods
477
+ { name: "Power State", method: -> (c) { c.get_power_state } },
478
+ { name: "Power Usage", method: -> (c) { c.get_power_usage_watts } },
479
+
480
+ # Jobs and lifecycle
481
+ { name: "Jobs List", method: -> (c) { c.jobs } },
482
+ { name: "Lifecycle Status", method: -> (c) { c.lifecycle_status } },
483
+
484
+ # Storage
485
+ { name: "Storage Controller", method: -> (c) { c.controller } },
486
+ { name: "Physical Drives", method: -> (c) { controller = c.controller; c.drives(controller) } },
487
+ { name: "Virtual Disks", method: -> (c) { controller = c.controller; c.volumes(controller) } },
488
+
489
+ # System components
490
+ { name: "Memory Info", method: -> (c) { c.memory } },
491
+ { name: "PSU Info", method: -> (c) { c.psus } },
492
+ { name: "Fan Info", method: -> (c) { c.fans } },
493
+ { name: "NIC Info", method: -> (c) { c.nics } },
494
+ { name: "PCI Devices", method: -> (c) { c.pci_devices } },
495
+ { name: "iDRAC Network", method: -> (c) { c.idrac_network } },
496
+ { name: "System Events", method: -> (c) { c.system_event_logs } },
497
+
498
+ # Virtual media
499
+ { name: "Virtual Media Status", method: -> (c) { c.virtual_media } },
500
+ { name: "Boot Source", method: -> (c) { c.get_boot_source_override } },
501
+
502
+ # Boot/BIOS
503
+ { name: "Boot Options", method: -> (c) { c.get_bios_boot_options } }
504
+ ]
505
+
506
+ # Destructive tests - only run if explicitly enabled
507
+ destructive_tests = [
508
+ # Virtual media operations
509
+ { name: "Eject Virtual Media", method: -> (c) { c.eject_virtual_media } },
510
+
511
+ # BIOS settings check (read-only but could affect future operations)
512
+ { name: "BIOS OS Power Control", method: -> (c) { c.set_bios_os_power_control } },
513
+ ]
514
+
515
+ puts "======= iDRAC Functionality Test =======" unless quiet
516
+ puts "Testing #{tests.length} non-destructive operations" unless quiet
517
+
518
+ with_idrac_client do |client|
519
+ begin
520
+ # Get firmware version first to help with diagnostics
521
+ firmware = client.get_firmware_version
522
+ puts "iDRAC Firmware: #{firmware}" unless quiet
523
+
524
+ # Run all the standard tests
525
+ tests.each do |test|
526
+ test_name = test[:name]
527
+
528
+ begin
529
+ puts "\nTesting: #{test_name}..." unless quiet
530
+ result = test[:method].call(client)
531
+
532
+ if result || result.nil? # nil is fine for commands that just print
533
+ passed << test_name
534
+ puts "✅ #{test_name} - PASSED" unless quiet
535
+ else
536
+ failed << test_name
537
+ puts "❌ #{test_name} - FAILED" unless quiet
538
+ end
539
+ rescue => e
540
+ failed << test_name
541
+ puts "❌ #{test_name} - ERROR: #{e.message}" unless quiet
542
+ puts e.backtrace.join("\n") if options[:verbose]
543
+ end
544
+ end
545
+
546
+ # Run destructive tests if enabled
547
+ unless skip_destructive
548
+ puts "\nTesting #{destructive_tests.length} potentially destructive operations" unless quiet
549
+
550
+ destructive_tests.each do |test|
551
+ test_name = test[:name]
552
+
553
+ begin
554
+ puts "\nTesting: #{test_name}..." unless quiet
555
+ result = test[:method].call(client)
556
+
557
+ if result || result.nil?
558
+ passed << test_name
559
+ puts "✅ #{test_name} - PASSED" unless quiet
560
+ else
561
+ failed << test_name
562
+ puts "❌ #{test_name} - FAILED" unless quiet
563
+ end
564
+ rescue => e
565
+ failed << test_name
566
+ puts "❌ #{test_name} - ERROR: #{e.message}" unless quiet
567
+ puts e.backtrace.join("\n") if options[:verbose]
568
+ end
569
+ end
570
+ else
571
+ skipped = destructive_tests.map { |t| t[:name] }
572
+ puts "\nSkipped #{skipped.length} destructive tests" unless quiet
573
+ end
574
+ rescue => e
575
+ puts "Failed to initialize client: #{e.message}".red
576
+ puts e.backtrace.join("\n") if options[:verbose]
577
+ exit 1
578
+ end
579
+ end
580
+
581
+ # Print summary
582
+ puts "\n======= Test Summary ======="
583
+ puts "✅ PASSED: #{passed.length} tests"
584
+
585
+ if failed.any?
586
+ puts "❌ FAILED: #{failed.length} tests"
587
+ puts failed.map { |name| " - #{name}" }.join("\n")
588
+ end
589
+
590
+ if skipped.any?
591
+ puts "⏭ SKIPPED: #{skipped.length} tests"
592
+ puts skipped.map { |name| " - #{name}" }.join("\n") unless quiet
593
+ end
594
+
595
+ exit(failed.empty? ? 0 : 1)
596
+ end
597
+
459
598
  # Storage commands
460
599
  desc "storage_controller", "Get storage controller information"
461
600
  map "storage:controller" => :storage_controller
@@ -477,6 +616,36 @@ module IDRAC
477
616
  end
478
617
  end
479
618
 
619
+ desc "storage_controllers", "Get all storage controllers information"
620
+ map "storage:controllers" => :storage_controllers
621
+ def storage_controllers
622
+ with_idrac_client do |client|
623
+ controllers = client.controllers
624
+
625
+ puts "\nStorage Controllers Summary:".green.bold
626
+ puts "-" * 80
627
+
628
+ controllers.each do |controller|
629
+ puts "Controller: #{controller[:name]}".cyan.bold
630
+ puts " Model: #{controller[:model]}"
631
+ puts " Status: #{controller[:status]}"
632
+ puts " Drives: #{controller[:drives_count]}"
633
+ puts " Firmware: #{controller[:firmware_version]}"
634
+ puts " Type: #{controller[:controller_type]}"
635
+ puts " PCI Slot: #{controller[:pci_slot]}"
636
+
637
+ if controller[:encryption_capability]
638
+ puts " Encryption: #{controller[:encryption_capability]}"
639
+ puts " Encryption Mode: #{controller[:encryption_mode] || 'Disabled'}"
640
+ end
641
+
642
+ puts
643
+ end
644
+
645
+ puts "Total controllers: #{controllers.size}".green
646
+ end
647
+ end
648
+
480
649
  desc "storage_drives", "Get physical drive information"
481
650
  map "storage:drives" => :storage_drives
482
651
  def storage_drives
data/lib/idrac/storage.rb CHANGED
@@ -5,35 +5,60 @@ module IDRAC
5
5
  module StorageMethods
6
6
  # Get storage controllers information
7
7
  def controller
8
+ # Use the controllers method to get all controllers
9
+ controller_list = controllers
10
+
11
+ puts "Controllers".green
12
+ controller_list.each { |c| puts "#{c[:name]} > #{c[:drives_count]}" }
13
+
14
+ puts "Drives".green
15
+ controller_list.each do |c|
16
+ puts "Storage: #{c[:name]} > #{c[:status]} > #{c[:drives_count]}"
17
+ end
18
+
19
+ # Find the controller with the most drives (usually the PERC)
20
+ controller_info = controller_list.max_by { |c| c[:drives_count] }
21
+
22
+ if controller_info[:name] =~ /PERC/
23
+ puts "Found #{controller_info[:name]}".green
24
+ else
25
+ puts "Found #{controller_info[:name]} but continuing...".yellow
26
+ end
27
+
28
+ # Return the raw controller data
29
+ controller_info[:raw]
30
+ end
31
+
32
+ # Get all storage controllers and return them as an array
33
+ def controllers
8
34
  response = authenticated_request(:get, '/redfish/v1/Systems/System.Embedded.1/Storage?$expand=*($levels=1)')
9
35
 
10
36
  if response.status == 200
11
37
  begin
12
38
  data = JSON.parse(response.body)
13
39
 
14
- puts "Controllers".green
15
- data["Members"].each { |ctrlr| puts "#{ctrlr["Name"]} > #{ctrlr["Drives@odata.count"]}" }
16
-
17
- puts "Drives".green
18
- data["Members"].each do |m|
19
- puts "Storage: #{m["Name"]} > #{m["Status"]["Health"] || "N/A"} > #{m["Drives"].size}"
20
- end
21
-
22
- # Find the controller with the most drives (usually the PERC)
23
- controller = data["Members"].sort_by { |ctrlr| ctrlr["Drives"].size }.last
24
-
25
- if controller["Name"] =~ /PERC/
26
- puts "Found #{controller["Name"]}".green
27
- else
28
- puts "Found #{controller["Name"]} but continuing...".yellow
40
+ # Transform and return all controllers as an array of hashes with consistent keys
41
+ controllers = data["Members"].map do |controller|
42
+ {
43
+ name: controller["Name"],
44
+ model: controller["Model"],
45
+ drives_count: controller["Drives"].size,
46
+ status: controller["Status"]["Health"] || "N/A",
47
+ firmware_version: controller.dig("StorageControllers", 0, "FirmwareVersion"),
48
+ encryption_mode: controller.dig("Oem", "Dell", "DellController", "EncryptionMode"),
49
+ encryption_capability: controller.dig("Oem", "Dell", "DellController", "EncryptionCapability"),
50
+ controller_type: controller.dig("Oem", "Dell", "DellController", "ControllerType"),
51
+ pci_slot: controller.dig("Oem", "Dell", "DellController", "PCISlot"),
52
+ raw: controller
53
+ }
29
54
  end
30
55
 
31
- return controller
56
+ return controllers.sort_by { |c| c[:name] }
32
57
  rescue JSON::ParserError
33
- raise Error, "Failed to parse controller response: #{response.body}"
58
+ raise Error, "Failed to parse controllers response: #{response.body}"
34
59
  end
35
60
  else
36
- raise Error, "Failed to get controller. Status code: #{response.status}"
61
+ raise Error, "Failed to get controllers. Status code: #{response.status}"
37
62
  end
38
63
  end
39
64
 
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.3.1"
4
+ VERSION = "0.3.2"
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.3.1
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonathan Siegel