idrac 0.5.4 → 0.5.6
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/bin/idrac +11 -11
- data/lib/idrac/client.rb +27 -0
- data/lib/idrac/storage.rb +280 -5
- 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: 7c4df0e2ba5dc5fb8bed2bfd514d2ee6ce8587cad0bf8f138021bff201c14887
|
4
|
+
data.tar.gz: b1cad50c169305b1369345c5bf1ee0d18d4b4c6c1f3e46c97b413e3009b295d0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c1dd008ed19fb33410d9ccc564bba643b2000f2a5de701568ff2ddb2cd34605a80736745745d56286e8940d37a7d06a348b9cb33227529430d7a26757a2f05a7
|
7
|
+
data.tar.gz: b1037ced078ac07b9629c76d00694d887b5979686fc942d105904d0c96279bc9d2d33c0cc2e863e25f5d6df1fdaa277cffb8159b18019e7303692dc431a09461
|
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
|
585
|
-
puts " Model: #{controller
|
586
|
-
puts " Status: #{controller
|
587
|
-
puts " Drives: #{controller
|
588
|
-
puts " Firmware: #{controller
|
589
|
-
puts " Type: #{controller
|
590
|
-
puts " PCI Slot: #{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}"
|
591
591
|
|
592
|
-
if controller
|
593
|
-
puts " Encryption: #{controller
|
594
|
-
puts " Encryption Mode: #{controller
|
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.
|
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/lib/idrac/client.rb
CHANGED
@@ -302,6 +302,33 @@ module IDRAC
|
|
302
302
|
end
|
303
303
|
end
|
304
304
|
|
305
|
+
def get_firmware_version
|
306
|
+
response = authenticated_request(:get, "/redfish/v1/Managers/iDRAC.Embedded.1?$select=FirmwareVersion")
|
307
|
+
|
308
|
+
if response.status == 200
|
309
|
+
begin
|
310
|
+
data = JSON.parse(response.body)
|
311
|
+
return data["FirmwareVersion"]
|
312
|
+
rescue JSON::ParserError
|
313
|
+
raise Error, "Failed to parse firmware version response: #{response.body}"
|
314
|
+
end
|
315
|
+
else
|
316
|
+
# Try again without the $select parameter for older firmware
|
317
|
+
response = authenticated_request(:get, "/redfish/v1/Managers/iDRAC.Embedded.1")
|
318
|
+
|
319
|
+
if response.status == 200
|
320
|
+
begin
|
321
|
+
data = JSON.parse(response.body)
|
322
|
+
return data["FirmwareVersion"]
|
323
|
+
rescue JSON::ParserError
|
324
|
+
raise Error, "Failed to parse firmware version response: #{response.body}"
|
325
|
+
end
|
326
|
+
else
|
327
|
+
raise Error, "Failed to get firmware version. Status code: #{response.status}"
|
328
|
+
end
|
329
|
+
end
|
330
|
+
end
|
331
|
+
|
305
332
|
# Execute a block with automatic retries
|
306
333
|
# @param max_retries [Integer] Maximum number of retry attempts
|
307
334
|
# @param initial_delay [Integer] Initial delay in seconds between retries (increases exponentially)
|
data/lib/idrac/storage.rb
CHANGED
@@ -82,7 +82,8 @@ module IDRAC
|
|
82
82
|
def drives(controller)
|
83
83
|
raise Error, "Controller not provided" unless controller
|
84
84
|
|
85
|
-
|
85
|
+
odata_id_path = controller["@odata.id"] || controller["odata_id"]
|
86
|
+
controller_path = odata_id_path.split("v1/").last
|
86
87
|
response = authenticated_request(:get, "/redfish/v1/#{controller_path}?$expand=*($levels=1)")
|
87
88
|
|
88
89
|
if response.status == 200
|
@@ -107,7 +108,7 @@ module IDRAC
|
|
107
108
|
operation_name: body.dig("Oem", "Dell", "DellPhysicalDisk", "OperationName"),
|
108
109
|
operation_progress: body.dig("Oem", "Dell", "DellPhysicalDisk", "OperationPercentCompletePercent"),
|
109
110
|
encryption_ability: body["EncryptionAbility"],
|
110
|
-
|
111
|
+
odata_id: body["@odata.id"]
|
111
112
|
}
|
112
113
|
|
113
114
|
RecursiveOpenStruct.new(drive_data, recurse_over_arrays: true)
|
@@ -128,8 +129,8 @@ module IDRAC
|
|
128
129
|
|
129
130
|
puts "Volumes (e.g. Arrays)".green
|
130
131
|
|
131
|
-
|
132
|
-
path =
|
132
|
+
odata_id_path = controller.dig("Volumes", "odata_id") || controller.volumes.odata_id
|
133
|
+
path = odata_id_path.split("v1/").last
|
133
134
|
response = authenticated_request(:get, "/redfish/v1/#{path}?$expand=*($levels=1)")
|
134
135
|
|
135
136
|
if response.status == 200
|
@@ -403,4 +404,278 @@ module IDRAC
|
|
403
404
|
end
|
404
405
|
end
|
405
406
|
end
|
406
|
-
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
|
data/lib/idrac/version.rb
CHANGED