require 'json'
require 'colorize'
module IDRAC
module System
# Get memory information
def memory
response = authenticated_request(:get, "/redfish/v1/Systems/System.Embedded.1/Memory?$expand=*($levels=1)")
if response.status == 200
begin
data = JSON.parse(response.body)
memory = data["Members"].map do |m|
dimm_name = m["Name"] # e.g. DIMM A1
bank, index = /DIMM ([A-Z])(\d+)/.match(dimm_name).captures
{
"model" => m["Model"],
"name" => m["Name"],
"capacity_bytes" => m["CapacityMiB"].to_i * 1024 * 1024,
"health" => m.dig("Status","Health") || "N/A",
"speed_mhz" => m["OperatingSpeedMhz"],
"part_number" => m["PartNumber"],
"serial" => m["SerialNumber"],
"bank" => bank,
"index" => index.to_i
}
end
return memory.sort_by { |m| [m["bank"] || "Z", m["index"] || 999] }
rescue JSON::ParserError
raise Error, "Failed to parse memory response: #{response.body}"
end
else
raise Error, "Failed to get memory. Status code: #{response.status}"
end
end
# Get power supply information
def psus
response = authenticated_request(:get, "/redfish/v1/Chassis/System.Embedded.1/Power")
if response.status == 200
begin
data = JSON.parse(response.body)
puts "Power Supplies".green
psus = data["PowerSupplies"].map do |psu|
puts "PSU: #{psu["Name"]} > #{psu["PowerInputWatts"]}W > #{psu.dig("Status", "Health")}"
{
"name" => psu["Name"],
"voltage" => psu["LineInputVoltage"],
"voltage_human" => psu["LineInputVoltageType"], # AC240V
"watts" => psu["PowerInputWatts"],
"part" => psu["PartNumber"],
"model" => psu["Model"],
"serial" => psu["SerialNumber"],
"status" => psu.dig("Status", "Health")
}
end
return psus
rescue JSON::ParserError
raise Error, "Failed to parse PSU response: #{response.body}"
end
else
raise Error, "Failed to get PSUs. Status code: #{response.status}"
end
end
# Get fan information
def fans
tries = 0
max_tries = 3
while tries < max_tries
begin
response = authenticated_request(:get, "/redfish/v1/Chassis/System.Embedded.1/Thermal?$expand=*($levels=1)")
if response.status == 200
data = JSON.parse(response.body)
fans = data["Fans"].map do |fan|
puts "Fan: #{fan["Name"]} > #{fan["Reading"]} > #{fan.dig("Status", "Health")}"
{
"name" => fan["Name"],
"rpm" => fan["Reading"],
"serial" => fan["SerialNumber"],
"status" => fan.dig("Status", "Health")
}
end
return fans
elsif response.status.between?(400, 499)
# Check if system is powered off
power_response = authenticated_request(:get, "/redfish/v1/Systems/System.Embedded.1?$select=PowerState")
if power_response.status == 200 && JSON.parse(power_response.body)["PowerState"] == "Off"
puts "WARN: System is off. Fans are not available.".yellow
return []
end
end
rescue => e
puts "WARN: Error getting fans: #{e.message}".yellow
end
tries += 1
puts "Failed to get fans. Retrying #{tries}/#{max_tries}.".red if tries < max_tries
sleep 10
end
puts "Failed to get fans after #{max_tries} tries".red
return []
end
# Get NIC information
def nics
response = authenticated_request(:get, "/redfish/v1/Systems/System.Embedded.1/NetworkAdapters?$expand=*($levels=1)")
if response.status == 200
begin
adapters_data = JSON.parse(response.body)
# Try to get network configuration from SCP for IP addresses
nic_ip_map = {}
# Try to get IP data from SCP
begin
scp_data = get_system_configuration_profile(target: "NIC")
if scp_data && scp_data["SystemConfiguration"] && scp_data["SystemConfiguration"]["Components"]
scp_data["SystemConfiguration"]["Components"].each do |component|
next unless component["FQDD"] =~ /NIC\.|BCM57/ # Match NIC components
# Extract IP configuration if available
ip_attrs = component["Attributes"]&.select { |attr| attr["Name"] =~ /IPAddress|IPv4Address|IPV4Address/ }
mac_attrs = component["Attributes"]&.select { |attr| attr["Name"] =~ /MACAddress/ }
if ip_attrs&.any? && mac_attrs&.any?
mac = mac_attrs.first["Value"]
ip = ip_attrs.first["Value"]
nic_ip_map[mac&.upcase] = ip unless ip.nil? || ip.empty? || ip == "0.0.0.0"
end
end
end
rescue => e
# Ignore errors, just continue
end
# Try to get static IP configuration from iDRAC
begin
idrac_net = idrac_network
if idrac_net && idrac_net["mac"] && idrac_net["ipv4"]
nic_ip_map[idrac_net["mac"].upcase] = idrac_net["ipv4"]
end
rescue => e
# Ignore errors, just continue
end
nics = []
# Process each network adapter
adapters_data["Members"].each do |adapter|
# Get basic adapter info
adapter_info = {
"name" => adapter["Id"],
"manufacturer" => adapter["Manufacturer"],
"model" => adapter["Model"],
"part_number" => adapter["PartNumber"],
"serial" => adapter["SerialNumber"],
"ports" => []
}
# Try each port type in order of preference
["NetworkPorts", "Ports"].each do |port_type|
ports_path = "#{adapter["@odata.id"].split("v1/").last}/#{port_type}?$expand=*($levels=1)"
begin
ports_response = authenticated_request(:get, "/redfish/v1/#{ports_path}")
if ports_response.status == 200
ports_data = JSON.parse(ports_response.body)
if ports_data["Members"] && ports_data["Members"].any?
# Process each port
adapter_info["ports"] = ports_data["Members"].map do |port|
# Extract port info based on port type
if port_type == "NetworkPorts"
# NetworkPorts style (usually iDRAC 8)
mac_addr = port["AssociatedNetworkAddresses"]&.first
link_speed_mbps = port.dig("SupportedLinkCapabilities", 0, "LinkSpeedMbps") || 0
port_num = port["PhysicalPortNumber"]
link_status = port["LinkStatus"]
else
# Ports style (usually iDRAC 9)
mac_addr = port.dig("Ethernet", "AssociatedMACAddresses", 0)
link_speed_mbps = port["CurrentSpeedGbps"] ? (port["CurrentSpeedGbps"].to_i * 1000) : 0
port_num = port["PortId"]
link_status = port["LinkStatus"] =~ /up/i ? "Up" : "Down"
end
# Get IP address from our mapping
ip_address = nic_ip_map[mac_addr&.upcase]
puts "NIC: #{port["Id"]} > #{mac_addr} > #{link_status} > #{port_num} > #{link_speed_mbps}Mbps > #{ip_address || 'No IP'}"
{
"name" => port["Id"],
"status" => link_status,
"mac" => mac_addr,
"ip_address" => ip_address,
"port" => port_num,
"speed_mbps" => link_speed_mbps,
"kind" => port_type == "NetworkPorts" ? "ethernet" : "port"
}
end
# If we found ports, no need to try the other endpoint
break
end
end
rescue => e
# Ignore errors and try the next port type
end
end
# Add adapter to our list
nics << adapter_info
end
return nics
rescue JSON::ParserError
raise Error, "Failed to parse NICs response: #{response.body}"
end
else
raise Error, "Failed to get NICs. Status code: #{response.status}"
end
end
# Get iDRAC network information
def idrac_network
# First try to get the EthernetInterfaces collection to get the correct path
collection_response = authenticated_request(:get, "/redfish/v1/Managers/iDRAC.Embedded.1/EthernetInterfaces")
if collection_response.status == 200
begin
collection_data = JSON.parse(collection_response.body)
if collection_data["Members"] && collection_data["Members"].any?
# Use the first interface found
interface_path = collection_data["Members"][0]["@odata.id"]
debug "Using interface path: #{interface_path}", 2
response = authenticated_request(:get, interface_path)
if response.status == 200
data = JSON.parse(response.body)
idrac = {
"name" => data["Id"],
"status" => data.dig("Status", "Health") == 'OK' ? 'Up' : 'Down',
"mac" => data["MACAddress"],
"mask" => data["IPv4Addresses"].first["SubnetMask"],
"ipv4" => data["IPv4Addresses"].first["Address"],
"origin" => data["IPv4Addresses"].first["AddressOrigin"], # DHCP or Static
"port" => nil,
"speed_mbps" => data["SpeedMbps"],
"kind" => "ethernet"
}
return idrac
else
raise Error, "Failed to get iDRAC network. Status code: #{response.status}"
end
else
raise Error, "No Ethernet interfaces found"
end
rescue JSON::ParserError
raise Error, "Failed to parse iDRAC network response: #{collection_response.body}"
end
else
# Fallback to the old hard-coded path for backwards compatibility
response = authenticated_request(:get, "/redfish/v1/Managers/iDRAC.Embedded.1/EthernetInterfaces/iDRAC.Embedded.1%23NIC.1")
if response.status == 200
begin
data = JSON.parse(response.body)
idrac = {
"name" => data["Id"],
"status" => data.dig("Status", "Health") == 'OK' ? 'Up' : 'Down',
"mac" => data["MACAddress"],
"mask" => data["IPv4Addresses"].first["SubnetMask"],
"ipv4" => data["IPv4Addresses"].first["Address"],
"origin" => data["IPv4Addresses"].first["AddressOrigin"], # DHCP or Static
"port" => nil,
"speed_mbps" => data["SpeedMbps"],
"kind" => "ethernet"
}
return idrac
rescue JSON::ParserError
raise Error, "Failed to parse iDRAC network response: #{response.body}"
end
else
raise Error, "Failed to get iDRAC network. Status code: #{response.status}"
end
end
end
# Get PCI device information
def pci_devices
# First try the standard PCIeDevices endpoint
response = authenticated_request(:get, "/redfish/v1/Chassis/System.Embedded.1/PCIeDevices?$expand=*($levels=1)")
if response.status == 200
begin
data = JSON.parse(response.body)
pci = data["Members"].map do |stub|
manufacturer = stub["Manufacturer"]
# Get PCIe function details if available
pcie_function = nil
if stub.dig("Links", "PCIeFunctions", 0, "@odata.id")
pcie_function_path = stub.dig("Links", "PCIeFunctions", 0, "@odata.id").split("v1/").last
function_response = authenticated_request(:get, "/redfish/v1/#{pcie_function_path}")
if function_response.status == 200
pcie_function = JSON.parse(function_response.body)
end
end
# Create device info with available data
device_info = {
"device_class" => pcie_function ? pcie_function["DeviceClass"] : nil,
"manufacturer" => manufacturer,
"name" => stub["Name"],
"description" => stub["Description"],
"id" => pcie_function ? pcie_function["Id"] : stub["Id"],
"slot_type" => pcie_function ? pcie_function.dig("Oem", "Dell", "DellPCIeFunction", "SlotType") : nil,
"bus_width" => pcie_function ? pcie_function.dig("Oem", "Dell", "DellPCIeFunction", "DataBusWidth") : nil,
"nic" => pcie_function ? pcie_function.dig("Links", "EthernetInterfaces", 0, "@odata.id") : nil
}
puts "PCI Device: #{device_info["name"]} > #{device_info["manufacturer"]} > #{device_info["device_class"]} > #{device_info["description"]} > #{device_info["id"]}"
device_info
end
return pci
rescue JSON::ParserError
raise Error, "Failed to parse PCI devices response: #{response.body}"
end
else
# For iDRAC 8, try Dell's recommended approach using System endpoint with PCIeDevices select option
system_pcie_response = authenticated_request(:get, "/redfish/v1/Systems/System.Embedded.1?$select=PCIeDevices")
if system_pcie_response.status == 200
begin
system_data = JSON.parse(system_pcie_response.body)
if system_data.key?("PCIeDevices") && !system_data["PCIeDevices"].empty?
pci_devices = []
# Process each PCIe device
system_data["PCIeDevices"].each do |device_link|
if device_link.is_a?(Hash) && device_link["@odata.id"]
device_path = device_link["@odata.id"]
device_response = authenticated_request(:get, device_path)
if device_response.status == 200
device_data = JSON.parse(device_response.body)
pci_devices << {
"device_class" => device_data["DeviceType"] || "Unknown",
"manufacturer" => device_data["Manufacturer"],
"name" => device_data["Name"] || device_data["Id"],
"description" => device_data["Description"],
"id" => device_data["Id"],
"slot_type" => device_data.dig("Oem", "Dell", "SlotType"),
"bus_width" => device_data.dig("Oem", "Dell", "BusWidth"),
"nic" => nil
}
end
end
end
return pci_devices unless pci_devices.empty?
end
rescue JSON::ParserError
# Continue to next approach
end
end
# Try NetworkAdapters as an alternative for finding PCIe devices (especially NICs and FC adapters)
nic_response = authenticated_request(:get, "/redfish/v1/Systems/System.Embedded.1/NetworkAdapters?$expand=*($levels=1)")
if nic_response.status == 200
begin
nic_data = JSON.parse(nic_response.body)
pci_devices = []
# Extract PCI info from network adapters
if nic_data["Members"] && !nic_data["Members"].empty?
nic_data["Members"].each do |adapter|
next unless adapter["Model"] || adapter["Manufacturer"]
# Check if this is a Fiber Channel adapter by name or model
is_fc = (adapter["Name"] =~ /FC/i || adapter["Model"] =~ /FC/i ||
adapter["Id"] =~ /FC/i || adapter["Description"] =~ /Fibre/i) ? true : false
device_class = is_fc ? "FibreChannelController" : "NetworkController"
pci_devices << {
"device_class" => device_class,
"manufacturer" => adapter["Manufacturer"],
"name" => adapter["Name"] || adapter["Id"],
"description" => adapter["Description"],
"id" => adapter["Id"],
"slot_type" => adapter.dig("Oem", "Dell", "SlotType") ||
(adapter["Id"] =~ /Slot\.(\d+)/ ? "Slot #{$1}" : nil),
"bus_width" => nil,
"nic" => adapter["@odata.id"]
}
end
return pci_devices unless pci_devices.empty?
end
rescue JSON::ParserError
# Continue to fallback
end
end
# Last resort: check if PCIeFunctions are directly available
pcie_functions_response = authenticated_request(:get, "/redfish/v1/Systems/System.Embedded.1/PCIeFunctions?$expand=*($levels=1)")
if pcie_functions_response.status == 200
begin
functions_data = JSON.parse(pcie_functions_response.body)
if functions_data["Members"] && !functions_data["Members"].empty?
pci_devices = functions_data["Members"].map do |function|
{
"device_class" => function["DeviceClass"] || "Unknown",
"manufacturer" => function["Manufacturer"] || "Unknown",
"name" => function["Name"] || function["Id"],
"description" => function["Description"],
"id" => function["Id"],
"slot_type" => function.dig("Oem", "Dell", "SlotType"),
"bus_width" => function.dig("Oem", "Dell", "DataBusWidth"),
"nic" => nil
}
end
return pci_devices
end
rescue JSON::ParserError
# Continue to fallback
end
end
# Fallback for any version when all endpoints unavailable
puts "PCI device information not available through standard or alternative endpoints" if @verbose
return []
end
end
# Map NICs to PCI bus IDs for Mellanox cards
def nics_to_pci(nics, pci_devices)
# Filter for Mellanox network controllers
mellanox_pci = pci_devices.select do |dev|
dev['device_class'] =~ /NetworkController/ && dev['manufacturer'] =~ /Mellanox/
end
# Create mapping of NIC names to PCI IDs
mapping = {}
mellanox_pci.each do |dev|
if dev['nic'] && dev['nic'] =~ /.*\/([^\/\-]+-\d+)/
nic = $1 # e.g. NIC.Slot.1-1
if dev['id'] =~ /^(\d+)-\d+-\d/
pci_bus = $1 # e.g. 59
mapping[nic] = pci_bus
end
end
end
# Add PCI bus info to each NIC port
nics_with_pci = nics.map do |nic|
nic_with_pci = nic.dup
if nic_with_pci["ports"]
nic_with_pci["ports"] = nic_with_pci["ports"].map do |port|
port_with_pci = port.dup
pci_bus = mapping[port["name"]]
if pci_bus
port_with_pci["pci"] = pci_bus
port_with_pci["linux_device"] = "enp#{pci_bus}s0np0" # e.g. enp3s0np0
end
port_with_pci
end
end
nic_with_pci
end
return nics_with_pci
end
# Kind of like a NIC, but serves a different purpose.
def idrac_interface
# First try to get the EthernetInterfaces collection to get the correct path
collection_response = authenticated_request(:get, "/redfish/v1/Managers/iDRAC.Embedded.1/EthernetInterfaces")
if collection_response.status == 200
collection_data = JSON.parse(collection_response.body)
if collection_data["Members"] && collection_data["Members"].any?
# Use the first interface found
interface_path = collection_data["Members"][0]["@odata.id"]
debug "Using interface path: #{interface_path}", 2
response = authenticated_request(:get, interface_path)
if response.status == 200
idrac_data = JSON.parse(response.body)
return {
"name" => idrac_data["Id"],
"status" => idrac_data.dig("Status", "Health") == 'OK' ? 'Up' : 'Down',
"mac" => idrac_data["MACAddress"],
"mask" => idrac_data["IPv4Addresses"].first["SubnetMask"],
"ipv4" => idrac_data["IPv4Addresses"].first["Address"],
"origin" => idrac_data["IPv4Addresses"].first["AddressOrigin"], # DHCP or Static
"port" => nil,
"speed_mbps" => idrac_data["SpeedMbps"],
"kind" => "ethernet"
}
end
end
end
# Fallback to the old hard-coded path
response = authenticated_request(:get, "/redfish/v1/Managers/iDRAC.Embedded.1/EthernetInterfaces/iDRAC.Embedded.1%23NIC.1")
idrac_data = JSON.parse(response.body)
{
"name" => idrac_data["Id"],
"status" => idrac_data.dig("Status", "Health") == 'OK' ? 'Up' : 'Down',
"mac" => idrac_data["MACAddress"],
"mask" => idrac_data["IPv4Addresses"].first["SubnetMask"],
"ipv4" => idrac_data["IPv4Addresses"].first["Address"],
"origin" => idrac_data["IPv4Addresses"].first["AddressOrigin"], # DHCP or Static
"port" => nil,
"speed_mbps" => idrac_data["SpeedMbps"],
"kind" => "ethernet"
}
end
# Get system identification information
def system_info
response = authenticated_request(:get, "/redfish/v1")
if response.status == 200
begin
data = JSON.parse(response.body)
# Initialize return hash with defaults
info = {
"is_dell" => false,
"is_ancient_dell" => false,
"product" => data["Product"] || "Unknown",
"service_tag" => nil,
"model" => nil,
"idrac_version" => data["RedfishVersion"],
"firmware_version" => nil
}
# Check if it's a Dell iDRAC
if data["Product"] == "Integrated Dell Remote Access Controller"
info["is_dell"] = true
# Get service tag from Dell OEM data
info["service_tag"] = data.dig("Oem", "Dell", "ServiceTag")
# Get firmware version - try both common locations
info["firmware_version"] = data["FirmwareVersion"] || data.dig("Oem", "Dell", "FirmwareVersion")
# Get additional system information
system_response = authenticated_request(:get, "/redfish/v1/Systems/System.Embedded.1")
if system_response.status == 200
system_data = JSON.parse(system_response.body)
info["model"] = system_data["Model"]
end
return info
else
# Try to handle ancient Dell models where Product is null or non-standard
if data["Product"].nil? || data.dig("Oem", "Dell")
info["is_ancient_dell"] = true
return info
end
end
return info
rescue JSON::ParserError
raise Error, "Failed to parse system information: #{response.body}"
end
else
raise Error, "Failed to get system information. Status code: #{response.status}"
end
end
# Get processor/CPU information
def cpus
response = authenticated_request(:get, "/redfish/v1/Systems/System.Embedded.1?$expand=*($levels=1)")
if response.status == 200
begin
data = JSON.parse(response.body)
summary = {
"count" => data.dig("ProcessorSummary", "Count"),
"model" => data.dig("ProcessorSummary", "Model"),
"cores" => data.dig("ProcessorSummary", "CoreCount"),
"threads" => data.dig("ProcessorSummary", "LogicalProcessorCount"),
"status" => data.dig("ProcessorSummary", "Status", "Health")
}
return summary
rescue JSON::ParserError
raise Error, "Failed to parse processor information: #{response.body}"
end
else
raise Error, "Failed to get processor information. Status code: #{response.status}"
end
end
# Get system health status
def system_health
response = authenticated_request(:get, "/redfish/v1/Systems/System.Embedded.1?$expand=*($levels=1)")
if response.status == 200
begin
data = JSON.parse(response.body)
health = {
"overall" => data.dig("Status", "HealthRollup"),
"system" => data.dig("Status", "Health"),
"processor" => data.dig("ProcessorSummary", "Status", "Health"),
"memory" => data.dig("MemorySummary", "Status", "Health"),
"storage" => data.dig("Storage", "Status", "Health")
}
return health
rescue JSON::ParserError
raise Error, "Failed to parse system health information: #{response.body}"
end
else
raise Error, "Failed to get system health. Status code: #{response.status}"
end
end
# Get system event logs
def system_event_logs
response = authenticated_request(:get, "/redfish/v1/Managers/iDRAC.Embedded.1/Logs/Sel?$expand=*($levels=1)")
if response.status == 200
begin
data = JSON.parse(response.body)
logs = data["Members"].map do |log|
puts "#{log['Id']} : #{log['Created']} : #{log['Message']} : #{log['Severity']}".yellow
log
end
# Sort by creation date, newest first
return logs.sort_by { |log| log['Created'] }.reverse
rescue JSON::ParserError
raise Error, "Failed to parse system event logs response: #{response.body}"
end
else
raise Error, "Failed to get system event logs. Status code: #{response.status}"
end
end
# Clear system event logs
def clear_system_event_logs
response = authenticated_request(
:post,
"/redfish/v1/Managers/iDRAC.Embedded.1/LogServices/Sel/Actions/LogService.ClearLog",
body: {}.to_json,
headers: { 'Content-Type': 'application/json' }
)
if response.status.between?(200, 299)
puts "System Event Logs cleared".green
return true
else
error_message = "Failed to clear System Event Logs. Status code: #{response.status}"
begin
error_data = JSON.parse(response.body)
error_message += ", Message: #{error_data['error']['message']}" if error_data['error'] && error_data['error']['message']
rescue
# Ignore JSON parsing errors
end
raise Error, error_message
end
end
# Get total memory in human-readable format
def total_memory_human(memory_data)
total_memory = memory_data.sum { |m| m["capacity_bytes"] }
"%0.2f GB" % (total_memory.to_f / 1.gigabyte)
end
# Get complete system configuration
def get_system_config
response = authenticated_request(:get, "/redfish/v1/Systems/System.Embedded.1?$expand=*($levels=1)")
if response.status == 200
return JSON.parse(response.body)
else
raise Error, "Failed to retrieve system configuration: #{response.status}"
end
end
# Get system summary information (used by CLI summary command)
def get_system_summary
# Get system information
system_response = authenticated_request(:get, "/redfish/v1/Systems/System.Embedded.1")
system_info = JSON.parse(system_response.body)
# Get iDRAC information
idrac_response = authenticated_request(:get, "/redfish/v1/Managers/iDRAC.Embedded.1")
idrac_info = JSON.parse(idrac_response.body)
# Initialize network info values to Unknown
ip_address = "Unknown"
mac_address = "Unknown"
# Try to get network information
begin
# First, get the EthernetInterfaces collection to find available interfaces
eth_collection_response = authenticated_request(:get, "/redfish/v1/Managers/iDRAC.Embedded.1/EthernetInterfaces")
if eth_collection_response.status == 200
eth_collection = JSON.parse(eth_collection_response.body)
if eth_collection["Members"] && eth_collection["Members"].any?
# Use the first interface found
first_eth = eth_collection["Members"][0]["@odata.id"]
debug "Found network interface: #{first_eth}", 2
first_eth_response = authenticated_request(:get, first_eth)
if first_eth_response.status == 200
first_eth_info = JSON.parse(first_eth_response.body)
ip_address = first_eth_info.dig("IPv4Addresses", 0, "Address") || "Unknown"
mac_address = first_eth_info.dig("MACAddress") || "Unknown"
debug "Network info - IP: #{ip_address}, MAC: #{mac_address}", 2
end
end
end
rescue => e
debug "Failed to get network info: #{e.message}", 1, :yellow
# Failed to get network info, leave as Unknown
end
# Initialize license_type to Unknown
license_type = "Unknown"
license_description = nil
# Try to get license information (new approach that works with iDRAC 8 too)
license_info = license_info() rescue nil
license_version = license_version() rescue nil
if license_info
license_type = license_info["LicenseType"] || "Unknown"
license_description = license_info["Description"]
end
# Format the license display string
license_display = license_type
if license_description && license_type != "Unknown"
license_display = "#{license_type} (#{license_description})"
end
# Return the system summary
{
power_state: system_info["PowerState"],
model: system_info["Model"],
host_name: system_info["HostName"],
operating_system: system_info.dig("Oem", "Dell", "OperatingSystem"),
os_version: system_info.dig("Oem", "Dell", "OperatingSystemVersion"),
service_tag: system_info["SKU"],
bios_version: system_info.dig("BiosVersion"),
idrac_firmware: idrac_info.dig("FirmwareVersion"),
ip_address: ip_address,
mac_address: mac_address,
license: license_display
}
end
# Get basic system information (used for test_live function)
def get_basic_system_info
response = authenticated_request(:get, "/redfish/v1/Systems/System.Embedded.1")
if response.status == 200
data = JSON.parse(response.body)
return {
model: data["Model"],
sku: data["SKU"]
}
else
raise Error, "Failed to get basic system information: #{response.status}"
end
end
end
end