idrac 0.5.6 → 0.5.8

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: 7c4df0e2ba5dc5fb8bed2bfd514d2ee6ce8587cad0bf8f138021bff201c14887
4
- data.tar.gz: b1cad50c169305b1369345c5bf1ee0d18d4b4c6c1f3e46c97b413e3009b295d0
3
+ metadata.gz: 79416daa6f4f5be25b467367ebd64f8a662672788920f4606a1dc53bf50b31b8
4
+ data.tar.gz: e0718909bc9ac02a148fab4f2b00c9a4497b5cdf2afaad035ced830f50cae04d
5
5
  SHA512:
6
- metadata.gz: c1dd008ed19fb33410d9ccc564bba643b2000f2a5de701568ff2ddb2cd34605a80736745745d56286e8940d37a7d06a348b9cb33227529430d7a26757a2f05a7
7
- data.tar.gz: b1037ced078ac07b9629c76d00694d887b5979686fc942d105904d0c96279bc9d2d33c0cc2e863e25f5d6df1fdaa277cffb8159b18019e7303692dc431a09461
6
+ metadata.gz: 272c0628748940cdbaa79ca7de738306ad85a226bcef8dcb21cd95a0c7116da9b780d159ebf7e8c47d99d96d4f6f0696156afbf88defe8f9d2dedf963fc3a44c
7
+ data.tar.gz: d63796c20679a6f1e63c1ed8da4fba7efd263a5f0027432d647dcdf1627ab76e2b161d22e0dc62a412e53591cbe30d7c187f049275ee29fe76e8eb0aba2be16f
data/bin/idrac CHANGED
@@ -581,17 +581,17 @@ module IDRAC
581
581
  puts "-" * 80
582
582
 
583
583
  controllers.each do |controller|
584
- puts "Controller: #{controller.name}".cyan.bold
585
- puts " Model: #{controller.model}"
586
- puts " Status: #{controller.status}"
587
- puts " Drives: #{controller.drives_count}"
588
- puts " Firmware: #{controller.firmware_version}"
589
- puts " Type: #{controller.controller_type}"
590
- puts " PCI Slot: #{controller.pci_slot}"
584
+ puts "Controller: #{controller[:name]}".cyan.bold
585
+ puts " Model: #{controller[:model]}"
586
+ puts " Status: #{controller[:status]}"
587
+ puts " Drives: #{controller[:drives_count]}"
588
+ puts " Firmware: #{controller[:firmware_version]}"
589
+ puts " Type: #{controller[:controller_type]}"
590
+ puts " PCI Slot: #{controller[:pci_slot]}"
591
591
 
592
- if controller.encryption_capability
593
- puts " Encryption: #{controller.encryption_capability}"
594
- puts " Encryption Mode: #{controller.encryption_mode || 'Disabled'}"
592
+ if controller[:encryption_capability]
593
+ puts " Encryption: #{controller[:encryption_capability]}"
594
+ puts " Encryption Mode: #{controller[:encryption_mode] || 'Disabled'}"
595
595
  end
596
596
 
597
597
  puts
@@ -675,7 +675,7 @@ module IDRAC
675
675
  confirmation = $stdin.gets.chomp.downcase
676
676
 
677
677
  if confirmation == 'y'
678
- client.create_virtual_disk(controller.odata_id, drives, name: options[:name], raid_type: options[:raid])
678
+ client.create_virtual_disk(controller.odata_Id, drives, name: options[:name], raid_type: options[:raid])
679
679
  puts "Volume created successfully".green
680
680
  else
681
681
  puts "Operation cancelled".yellow
data/idrac.gemspec CHANGED
@@ -42,6 +42,7 @@ Gem::Specification.new do |spec|
42
42
  spec.add_dependency "base64", "~> 0.1", ">= 0.1.0"
43
43
  spec.add_dependency "colorize", "~> 1.1"
44
44
  spec.add_dependency "recursive-open-struct", "~> 1.1"
45
+ spec.add_dependency "activesupport", ">= 6.0", "< 8.0"
45
46
 
46
47
  # Development dependencies
47
48
  spec.add_development_dependency "bundler", "~> 2.4", ">= 2.4.0"
data/lib/idrac/storage.rb CHANGED
@@ -82,8 +82,7 @@ module IDRAC
82
82
  def drives(controller)
83
83
  raise Error, "Controller not provided" unless controller
84
84
 
85
- odata_id_path = controller["@odata.id"] || controller["odata_id"]
86
- controller_path = odata_id_path.split("v1/").last
85
+ controller_path = controller["@odata.id"].split("v1/").last
87
86
  response = authenticated_request(:get, "/redfish/v1/#{controller_path}?$expand=*($levels=1)")
88
87
 
89
88
  if response.status == 200
@@ -108,7 +107,7 @@ module IDRAC
108
107
  operation_name: body.dig("Oem", "Dell", "DellPhysicalDisk", "OperationName"),
109
108
  operation_progress: body.dig("Oem", "Dell", "DellPhysicalDisk", "OperationPercentCompletePercent"),
110
109
  encryption_ability: body["EncryptionAbility"],
111
- odata_id: body["@odata.id"]
110
+ "@odata.id": body["@odata.id"]
112
111
  }
113
112
 
114
113
  RecursiveOpenStruct.new(drive_data, recurse_over_arrays: true)
@@ -129,8 +128,8 @@ module IDRAC
129
128
 
130
129
  puts "Volumes (e.g. Arrays)".green
131
130
 
132
- odata_id_path = controller.dig("Volumes", "odata_id") || controller.volumes.odata_id
133
- path = odata_id_path.split("v1/").last
131
+ v = controller["Volumes"]
132
+ path = v["@odata.id"].split("v1/").last
134
133
  response = authenticated_request(:get, "/redfish/v1/#{path}?$expand=*($levels=1)")
135
134
 
136
135
  if response.status == 200
@@ -404,278 +403,4 @@ module IDRAC
404
403
  end
405
404
  end
406
405
  end
407
- end
408
- =begin
409
- def controller_encryption_capable?
410
- self.meta.dig("controller", "Oem", "Dell", "DellController", "EncryptionCapability") =~ /localkey/i # "LocalKeyManagementAndSecureEnterpriseKeyManagerCapable"
411
- end
412
- def controller_encryption_enabled?
413
- self.meta.dig("controller", "Oem", "Dell", "DellController", "EncryptionMode") =~ /localkey/i
414
- end
415
- def drives
416
- # Get the drives
417
- controller_path = self.controller["@odata.id"].split("v1/").last
418
- json = get(path: "#{controller_path}?$expand=*($levels=1)")["body"]["Drives"]
419
- # drives = self.controller["Drives"].collect
420
- idrac_drives = json.map do |body|
421
- # path = d["@odata.id"].split("v1/").last
422
- # body = self.get(path: path)["body"]
423
- serial = body["SerialNumber"]
424
- serial = body["Identifiers"].first["DurableName"] if serial.blank?
425
- {
426
- serial: serial,
427
- model: body["Model"],
428
- name: body["Name"],
429
- capacity_bytes: body["CapacityBytes"],
430
- # Health is nil when powered off...
431
- health: body["Status"]["Health"] ? body["Status"]["Health"] : "N/A",
432
- speed_gbp: body["CapableSpeedGbs"],
433
- manufacturer: body["Manufacturer"],
434
- media_type: body["MediaType"],
435
- failure_predicted: body["FailurePredicted"],
436
- life_left_percent: body["PredictedMediaLifeLeftPercent"],
437
- certified: body.dig("Oem", "Dell", "DellPhysicalDisk", "Certified"),
438
- raid_status: body.dig("Oem", "Dell", "DellPhysicalDisk", "RaidStatus"),
439
- operation_name: body.dig("Oem", "Dell", "DellPhysicalDisk", "OperationName"),
440
- operation_progress: body.dig("Oem", "Dell", "DellPhysicalDisk", "OperationPercentCompletePercent"),
441
- encryption_ability: body["EncryptionAbility"],
442
- "@odata.id": body["@odata.id"]
443
- }
444
- end
445
- self.meta["drives"] = idrac_drives.sort_by { |d| d[:name] }
446
- if self.save
447
- self.meta["drives"]
448
- else
449
- false
450
- end
451
- end
452
- def volumes
453
- puts "Volumes (e.g. Arrays)".green
454
- # {"@odata.id"=>"/redfish/v1/Systems/System.Embedded.1/Storage/RAID.Integrated.1-1/Volumes"}
455
-
456
- v = self.controller["Volumes"]
457
- path = v["@odata.id"].split("v1/").last
458
- vols = self.get(path: path+"?$expand=*($levels=1)")["body"]
459
- volumes = vols["Members"].collect do |vol|
460
- drives = vol["Links"]["Drives"]
461
- volume = {
462
- name: vol["Name"],
463
- capacity_bytes: vol["CapacityBytes"],
464
- volume_type: vol["VolumeType"],
465
- drives: drives,
466
- write_cache_policy: vol.dig("Oem", "Dell", "DellVirtualDisk", "WriteCachePolicy"),
467
- read_cache_policy: vol.dig("Oem", "Dell", "DellVirtualDisk", "ReadCachePolicy"),
468
- stripe_size: vol.dig("Oem", "Dell", "DellVirtualDisk", "StripeSize"),
469
- raid_level: vol["RAIDType"],
470
- encrypted: vol["Encrypted"],
471
- lock_status: vol.dig("Oem", "Dell", "DellVirtualDisk", "LockStatus"),
472
- # "Operations"=>[{"OperationName"=>"Background Initialization", "PercentageComplete"=>0}],
473
- "@odata.id": vol["@odata.id"]
474
- }
475
- if !self.modern_firmware?
476
- # Unfortunately for older idracs, to get the drive cache policies we need to do a
477
- # system_configuration_profile call AND we still don't get the right stripe size.
478
- scp ||= self.get_system_configuration_profile(target: "RAID")
479
- controller = self.meta["controller"]
480
- scp_vol = scp["SystemConfiguration"]["Components"]
481
- .find { |comp| comp["FQDD"] == controller['Id'] }["Components"]
482
- .find { |comp| comp["FQDD"] == vol["Id"] }["Attributes"]
483
- # .find { |attr| attr["Name"] == "RAIDdefaultWritePolicy" }["Value"]
484
- volume[:write_cache_policy] = scp_vol.find { |attr| attr["Name"] == "RAIDdefaultWritePolicy" }["Value"]
485
- volume[:read_cache_policy] = scp_vol.find { |attr| attr["Name"] == "RAIDdefaultReadPolicy" }["Value"]
486
- end
487
-
488
-
489
- # Dell-specific high-performance settings for PERC:
490
- # [Read more](https://www.dell.com/support/manuals/en-us/perc-h755/perc11_ug/fastpath?guid=guid-a9e90946-a41f-48ab-88f1-9ce514b4c414&lang=en-us)
491
- volume[:fastpath] = self.fastpath_good?(volume)
492
-
493
- # Not built yet:
494
- # "Status"=>{"Health"=>nil, "HealthRollup"=>nil, "State"=>"Enabled"},
495
- # Dunno
496
- # "Status"=>{"Health"=>"OK", "HealthRollup"=>"OK", "State"=>"Enabled"},
497
- # In progress:
498
- # "Operations"=>[{"OperationName"=>"Background Initialization", "PercentageComplete"=>0}],
499
- # "Status"=>{"Health"=>nil, "HealthRollup"=>nil, "State"=>"Enabled"},
500
- if vol["Operations"].any?
501
- volume[:health] = vol["Status"]["Health"] ? vol["Status"]["Health"] : "N/A"
502
- volume[:progress] = vol["Operations"].first["PercentageComplete"]
503
- volume[:message] = vol["Operations"].first["OperationName"]
504
- elsif vol["Status"]["Health"] == "OK"
505
- volume[:health] = "OK"
506
- volume[:progress] = nil
507
- volume[:message] = nil
508
- else
509
- volume[:health] = "?"
510
- volume[:progress] = nil
511
- volume[:message] = nil
512
- end
513
- volume
514
- end
515
- self.meta["volumes"] = volumes.sort_by { |d| d[:name] }
516
- self.save
517
- end
518
- def memory
519
- expected = expected_memory
520
- mem = self.get(path: "Systems/System.Embedded.1/Memory?$expand=*($levels=1)")["body"]
521
- memory = mem["Members"].map do |m|
522
- dimm_name = m["Name"] # e.g. DIMM A1
523
- bank, index = /DIMM ([A-Z])(\d+)/.match(dimm_name).captures
524
- # We expect one of our configurations:
525
- # 32GB DIMMS x 32 = 1TB # Gen III, less memory issues (we've experienced too many bad 64GB DIMMS)
526
- # 64GB DIMMS x 24 = 1.5TB # Gen II
527
- # 64GB DIMMS x 32 = 2TB # Gen I
528
- expected.delete(dimm_name) if expected[dimm_name] == m["CapacityMiB"] * 1.megabyte || expected[dimm_name] == m["CapacityMiB"] * 1.megabyte * 2
529
- puts "DIMM: #{m["Model"]} #{m["Name"]} > #{m["CapacityMiB"]}MiB > #{m["Status"]["Health"]} > #{m["OperatingSpeedMhz"]}MHz > #{m["PartNumber"]} / #{m["SerialNumber"]}"
530
- {
531
- "model" => m["Model"],
532
- "name" => m["Name"],
533
- "capacity_bytes" => m["CapacityMiB"].to_i * 1.megabyte,
534
- "health" => m["Status"]["Health"] ? m["Status"]["Health"] : "N/A",
535
- "speed_mhz" => m["OperatingSpeedMhz"],
536
- "part_number" => m["PartNumber"],
537
- "serial" => m["SerialNumber"],
538
- "bank" => bank,
539
- "index" => index.to_i
540
- }
541
- end
542
- self.meta["memory"] = memory.sort_by { |a| [a["bank"], a["index"]] }
543
- if expected.any?
544
- log("Missing DIMMs: #{expected.keys.join(", ")}".red)
545
- puts "Missing DIMMs: #{expected.keys.join(", ")}".red
546
- end
547
- self.save
548
- end
549
- def pci(force: false)
550
- # If we've already found two Mellanox cards, let's not refresh by default
551
- if !force && (2 == self.meta["pci"]&.select { |p| p['manufacturer'] =~ /Mellanox/ }&.size)
552
- puts "[PCI] 2 x Mellanox NICs already found. Skipping.".yellow
553
- return
554
- end
555
- # /redfish/v1/Chassis/System.Embedded.1/PCIeDevices/59-0/PCIeFunctions/59-0-0
556
- # Look at all the PCI slots and ideally identify the Mellanox cards
557
- # Then match them to the
558
- devices = self.get(path: "Chassis/System.Embedded.1/PCIeDevices?$expand=*($levels=1)")["body"]
559
- pci = devices["Members"].map do |stub|
560
- manufacturer = stub["Manufacturer"]
561
- pcie_function_path = stub.dig("Links", "PCIeFunctions", 0, "@odata.id")
562
- device = self.get(path: pcie_function_path)["body"]
563
-
564
- # If it's a network device, we can chcek the link to its PCIe details and then
565
- # NetworkController
566
- puts "PCI Device: #{device["Name"]} > #{manufacturer} > #{device["DeviceClass"]} > #{device["Description"]} > #{device["Id"]}"
567
- { device_class: device["DeviceClass"], # e.g. NetworkController
568
- manufacturer: manufacturer,
569
- name: device["Name"],
570
- description: device["Description"],
571
- id: device["Id"], # This is the BUS: e.g. 59-0-0 => 3b
572
- slot_type: device.dig("Oem", "Dell", "DellPCIeFunction", "SlotType"),
573
- bus_width: device.dig("Oem", "Dell", "DellPCIeFunction", "DataBusWidth"),
574
- nic: device.dig("Links", "EthernetInterfaces", 0, "@odata.id")
575
- }
576
- end
577
- self.meta['pci'] = pci
578
- self.save
579
- end
580
- # Finds Mellanox cards on the bus and their NICs.
581
- # [{:bus_id=>"59", :nic=>"NIC.Slot.1-1-1"}, {:bus_id=>"94", :nic=>"NIC.Slot.2-1-1"}]
582
- def nics_to_pci
583
- self.nics if self.meta['nics'].blank?
584
- self.pci if self.meta['pci'].blank?
585
- hsh = self.meta['pci']&.select { |n| n['device_class'] =~ /NetworkController/ && n['manufacturer'] =~ /Mellanox/ }&.inject({}) do |acc,v|
586
- nic = (v['nic'] =~ /.*\/([^\/\-]+-\d+)/; $1) # e.g. NIC.Slot.1-1 # Drop one -1 for consistency with other iDRAC
587
- pci = (v['id'] =~ /^(\d+)-\d+-\d/; $1) # e.g. 59
588
- acc[nic] = pci
589
- acc
590
- end
591
- self.meta['nics'].each do |nic|
592
- nic['ports'].each do |port|
593
- pci_bus = hsh[port['name']]
594
- if pci_bus
595
- port['pci'] = pci_bus
596
- port['linux_device'] = "enp#{pci_bus}s0np0" # e.g. enp3s0np0
597
- end
598
- end
599
- end
600
- hsh
601
- end
602
- def nics
603
- # There can be multiple NIC adapters, so first we enumerate them:
604
- adapters = self.get(path: "Systems/System.Embedded.1/NetworkAdapters?$expand=*($levels=1)")["body"]
605
- nics = adapters["Members"].map do |adapter|
606
- port_part = self.idrac_license_version.to_i == 9 ? 'Ports' : 'NetworkPorts'
607
- path = "#{adapter["@odata.id"].split("v1/").last}/#{port_part}?$expand=*($levels=1)"
608
- res = self.get(path: path)["body"]
609
- ports = res["Members"].collect do |nic|
610
- link_speed_mbps, mac_addr, link_status = nil, nil, nil
611
- if self.idrac_license_version.to_i == 9
612
- link_speed_mbps = nic['CurrentSpeedGbps'].to_i * 1000
613
- mac_addr = nic['Ethernet']['AssociatedMACAddresses'].first
614
- port_num = nic['PortId']
615
- network_technology = nic['LinkNetworkTechnology']
616
- link_status = nic['LinkStatus'] =~ /up/i ? "Up" : "Down" # Lovely, iDRAC now uses LinkUp instead of Up. :shrug:
617
- else # iDRAC 8
618
- link_speed_mbps = nic["SupportedLinkCapabilities"].first["LinkSpeedMbps"]
619
- mac_addr = nic["AssociatedNetworkAddresses"].first
620
- port_num = nic["PhysicalPortNumber"]
621
- network_technology = nic["SupportedLinkCapabilities"].first["LinkNetworkTechnology"]
622
- link_status = nic['LinkStatus']
623
- end
624
- puts "NIC: #{nic["Id"]} > #{mac_addr} > #{link_status} > #{port_num} > #{link_speed_mbps}Mbps"
625
- {
626
- "name" => nic["Id"],
627
- "status" => link_status,
628
- "mac" => mac_addr,
629
- "port" => port_num,
630
- "speed_mbps" => link_speed_mbps,
631
- "kind" => network_technology&.downcase
632
- }
633
- end
634
- {
635
- "name" => adapter["Id"], # "NIC.Integrated.1-1",
636
- "manufacturer" => adapter["Manufacturer"], # "Mellanox Technologies",
637
- "model" => adapter["Model"], # "MLNX 100GbE 2P ConnectX6 Adpt"
638
- "part_number" => adapter["PartNumber"], # "08AAAA",
639
- "serial" => adapter["SerialNumber"], # "TW78AAAAAAAAAA",
640
- "ports" => ports
641
- }
642
- end
643
- # Now let's parse the NICs and make sure we have a PORT for each one.
644
- # Note that we set the MAC address for the MANAGEMENT port by a heuristic!!!
645
- # If we ever see a 1000 Mbps port in the NIC.Integrated or NIC.Embedded, that's the Managament Port!
646
- nics.each do |nic|
647
- # puts nic.inspect
648
- nic["ports"].each do |port|
649
- # puts port.inspect
650
- if port["speed_mbps"] == 1000 &&
651
- (port["name"] =~ /NIC.Integrated/ || nic["name"] =~ /NIC.Embedded/) &&
652
- port['status'] == 'Up' &&
653
- port['kind'] == 'ethernet' &&
654
- port['mac'] =~ /([0-9a-fA-F]{2}[:-]){5}([0-9a-fA-F]{2})/
655
- Rails.logger.debug "Identified Management Port: #{port['name']} #{port['mac']}".blue
656
- self.management_port.update(mac_addr: port["mac"])
657
- end
658
- end
659
- end
660
- self.meta["nics"] = nics
661
- self.save
662
- end
663
- # Kind of like a NIC, but serves a different purpose.
664
- def idrac
665
- body = self.get(path: "Managers/iDRAC.Embedded.1/EthernetInterfaces/iDRAC.Embedded.1%23NIC.1")["body"]
666
- idrac = {
667
- "name" => body["Id"],
668
- "status" => body["Status"]["Health"] == 'OK' ? 'Up' : 'Down',
669
- "mac" => body["MACAddress"],
670
- "mask" => body["IPv4Addresses"].first["SubnetMask"],
671
- "ipv4" => body["IPv4Addresses"].first["Address"],
672
- "origin" => body["IPv4Addresses"].first["AddressOrigin"], # DHCP or Static
673
- "port" => nil,
674
- "speed_mbps" => body["SpeedMbps"],
675
- "kind" => "ethernet"
676
- }
677
- self.meta["idrac"] = idrac
678
- self.save
679
- end
680
-
681
- =end
406
+ end
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.5.6"
4
+ VERSION = "0.5.8"
5
5
  end
data/lib/idrac.rb CHANGED
@@ -8,6 +8,8 @@ require 'base64'
8
8
  require 'uri'
9
9
  require 'colorize'
10
10
  require 'recursive-open-struct'
11
+ require 'active_support'
12
+ require 'active_support/core_ext'
11
13
  # If dev, required debug
12
14
  require 'debug' if ENV['RUBY_ENV'] == 'development'
13
15
 
@@ -38,7 +40,6 @@ module IDRAC
38
40
  end
39
41
 
40
42
  require 'idrac/version'
41
- require 'idrac/core_ext'
42
43
  require 'idrac/error'
43
44
  require 'idrac/web'
44
45
  require 'idrac/firmware_catalog'
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: idrac
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.6
4
+ version: 0.5.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonathan Siegel
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2025-04-05 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: httparty
@@ -158,6 +157,26 @@ dependencies:
158
157
  - - "~>"
159
158
  - !ruby/object:Gem::Version
160
159
  version: '1.1'
160
+ - !ruby/object:Gem::Dependency
161
+ name: activesupport
162
+ requirement: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '6.0'
167
+ - - "<"
168
+ - !ruby/object:Gem::Version
169
+ version: '8.0'
170
+ type: :runtime
171
+ prerelease: false
172
+ version_requirements: !ruby/object:Gem::Requirement
173
+ requirements:
174
+ - - ">="
175
+ - !ruby/object:Gem::Version
176
+ version: '6.0'
177
+ - - "<"
178
+ - !ruby/object:Gem::Version
179
+ version: '8.0'
161
180
  - !ruby/object:Gem::Dependency
162
181
  name: bundler
163
182
  requirement: !ruby/object:Gem::Requirement
@@ -236,7 +255,6 @@ files:
236
255
  - lib/idrac.rb
237
256
  - lib/idrac/boot.rb
238
257
  - lib/idrac/client.rb
239
- - lib/idrac/core_ext.rb
240
258
  - lib/idrac/error.rb
241
259
  - lib/idrac/firmware.rb
242
260
  - lib/idrac/firmware_catalog.rb
@@ -255,7 +273,6 @@ licenses:
255
273
  - MIT
256
274
  metadata:
257
275
  homepage_uri: http://github.com
258
- post_install_message:
259
276
  rdoc_options: []
260
277
  require_paths:
261
278
  - lib
@@ -270,8 +287,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
270
287
  - !ruby/object:Gem::Version
271
288
  version: '0'
272
289
  requirements: []
273
- rubygems_version: 3.5.16
274
- signing_key:
290
+ rubygems_version: 3.6.7
275
291
  specification_version: 4
276
292
  summary: API Client for Dell iDRAC
277
293
  test_files: []
@@ -1,100 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Add ActiveSupport-like blank? method to core Ruby classes
4
- # This allows us to use blank? without requiring Rails' ActiveSupport
5
-
6
- class NilClass
7
- # nil is always blank
8
- def blank?
9
- true
10
- end
11
- end
12
-
13
- class String
14
- # A string is blank if it's empty or contains whitespace only
15
- def blank?
16
- strip.empty?
17
- end
18
- end
19
-
20
- class Array
21
- # An array is blank if it's empty
22
- def blank?
23
- empty?
24
- end
25
- end
26
-
27
- class Hash
28
- # A hash is blank if it's empty
29
- def blank?
30
- empty?
31
- end
32
- end
33
-
34
- class Object
35
- # An object is blank if it responds to empty? and is empty
36
- # Otherwise return false
37
- def blank?
38
- respond_to?(:empty?) ? empty? : false
39
- end
40
- end
41
-
42
- # Add ActiveSupport-like numeric extensions
43
- class Integer
44
- # Byte size helpers
45
- def byte
46
- self
47
- end
48
- alias_method :bytes, :byte
49
-
50
- def kilobyte
51
- self * 1024
52
- end
53
- alias_method :kilobytes, :kilobyte
54
-
55
- def megabyte
56
- self * 1024 * 1024
57
- end
58
- alias_method :megabytes, :megabyte
59
-
60
- def gigabyte
61
- self * 1024 * 1024 * 1024
62
- end
63
- alias_method :gigabytes, :gigabyte
64
-
65
- def terabyte
66
- self * 1024 * 1024 * 1024 * 1024
67
- end
68
- alias_method :terabytes, :terabyte
69
-
70
- def petabyte
71
- self * 1024 * 1024 * 1024 * 1024 * 1024
72
- end
73
- alias_method :petabytes, :petabyte
74
-
75
- # Time duration helpers (for potential future use)
76
- def second
77
- self
78
- end
79
- alias_method :seconds, :second
80
-
81
- def minute
82
- self * 60
83
- end
84
- alias_method :minutes, :minute
85
-
86
- def hour
87
- self * 60 * 60
88
- end
89
- alias_method :hours, :hour
90
-
91
- def day
92
- self * 24 * 60 * 60
93
- end
94
- alias_method :days, :day
95
-
96
- def week
97
- self * 7 * 24 * 60 * 60
98
- end
99
- alias_method :weeks, :week
100
- end