diff --git a/SOURCES/redfish-finder-multi-block.patch b/SOURCES/redfish-finder-multi-block.patch new file mode 100644 index 0000000..41ab1a2 --- /dev/null +++ b/SOURCES/redfish-finder-multi-block.patch @@ -0,0 +1,283 @@ +commit 44853a940a2b3c52395e26a3632e10cc6b5f2e5d +Author: Neil Horman +Date: Thu Jun 27 11:26:48 2019 -0400 + + Add support for multiple type 42 blocks in SMBIOS + + DMTF recently updated their host API specification to allow for multiple + type 42 blocks (in support of ipv4/ipv6 in the constrained space of a + single block). Enhance redfish-finder to parse and merge those blocks + + Signed-off-by: Neil Horman + +diff --git a/redfish-finder b/redfish-finder +index 45c4ea8..429cc42 100755 +--- a/redfish-finder ++++ b/redfish-finder +@@ -1,4 +1,4 @@ +-#!/usr/bin/python3 ++#!/usr/libexec/platform-python + + import sys + import os +@@ -49,6 +49,9 @@ class NetDevice(object): + def getifcname(self): + return self.name + ++ def merge(self, newdev): ++ return self ++ + def __str__(self): + return "Interface: " + self.name + +@@ -112,9 +115,9 @@ class USBNetDevice(NetDevice): + ###################################################### + class HostConfig(): + def __init__(self, cursor): +- self.address = None +- self.mask = None +- self.network = None ++ self.address = [] ++ self.mask = [] ++ self.network = [] + + try: + cursor = cursor_consume_next(cursor, "Host IP Assignment Type: ") +@@ -122,26 +125,30 @@ class HostConfig(): + printf("redfish-finder: Unable to parse SMBIOS Host IP Assignment Type") + return None + if cursor.split()[0] == "Static": +- self.assigntype = AssignType.STATIC ++ self.assigntype = [] ++ self.assigntype.append(AssignType.STATIC) + cursor = cursor_consume_next(cursor, "Host IP Address Format: ") + if cursor.split()[0] == "IPv4": + cursor = cursor_consume_next(cursor, "IPv4 Address: ") + addr = cursor.split()[0] +- self.address = ipaddress.IPv4Address(addr) ++ self.address.append(ipaddress.IPv4Address(addr)) + cursor = cursor_consume_next(cursor, "IPv4 Mask: ") + mask = cursor.split()[0] +- self.mask = ipaddress.IPv4Address(mask) +- self.network = ipaddress.IPv4Network(addr + "/" + mask, strict=False) ++ self.mask.append(ipaddress.IPv4Address(mask)) ++ self.network.append(ipaddress.IPv4Network(addr + "/" + mask, strict=False)) + elif cursor.split()[0] == "IPv6": + cursor = cursor_consume_next(cursor, "IPv6 Address: ") + addr = cursor.split()[0] +- self.address = ipaddress.IPv6Address(addr) ++ self.address.append(ipaddress.IPv6Address(addr)) + cursor = cursor_consume_next(cursor, "IPv6 Mask: ") + mask = cursor.split()[0] +- self.mask = ipaddress.IPv4Address(mask) +- self.network = ipaddress.IPv6Network(addr + "/" + mask, strict=False) ++ self.mask.append(ipaddress.IPv4Address(mask)) ++ self.network.append(ipaddress.IPv6Network(addr + "/" + mask, strict=False)) + elif cursor.split()[0] == "DHCP": +- self.assigntype = AssignType.DHCP ++ self.assigntype.append(AssignType.DHCP) ++ self.address.append(0) ++ self.mask.append(0) ++ self.network.append(0) + else: + # Support the other types later + print("redfish-finder: Unable to parse SMBIOS Host configuaration") +@@ -150,6 +157,13 @@ class HostConfig(): + print("redfish-finder: Unexpected error while parsing HostConfig!") + return None + ++ def merge(self, newconfig): ++ self.assigntype.extend(newconfig.assigntype) ++ self.address.extend(newconfig.address) ++ self.mask.extend(newconfig.mask) ++ self.network.extend(newconfig.network) ++ return self ++ + # + # Using the smbios host config info, set the appropriate + # attributes of the network manager connection object +@@ -157,20 +171,22 @@ class HostConfig(): + def generate_nm_config(self, device, nmcon): + assignmap = { AssignType.STATIC: "manual", AssignType.DHCP: "auto"} + methodp = "ipv4.method" +- if self.assigntype == AssignType.STATIC: +- if self.address.version == 4: +- methodp = "ipv4.method" +- addrp = "ipv4.addresses" +- else: +- methodp = "ipv6.method" +- addrp = "ipv6.addresses" +- try: +- nmcon.update_property(methodp, assignmap[self.assigntype]) +- if self.assigntype == AssignType.STATIC: +- nmcon.update_property(addrp, str(self.address) + "/" + str(self.network.prefixlen)) +- except: +- print("redfish-finder: Error generating nm_config") +- return False ++ for i in range(len(self.assigntype)): ++ assigntype = self.assigntype[i] ++ if assigntype == AssignType.STATIC: ++ if self.address[i].version == 4: ++ methodp = "ipv4.method" ++ addrp = "ipv4.addresses" ++ else: ++ methodp = "ipv6.method" ++ addrp = "ipv6.addresses" ++ try: ++ nmcon.update_property(methodp, assignmap[assigntype]) ++ if assigntype == AssignType.STATIC: ++ nmcon.update_property(addrp, str(self.address[i]) + "/" + str(self.network[i].prefixlen)) ++ except: ++ print("redfish-finder: Error generating nm_config") ++ return False + + return True + +@@ -188,8 +204,8 @@ class HostConfig(): + ###################################################### + class ServiceConfig(): + def __init__(self, cursor): +- self.address = None +- self.mask = None ++ self.address = [] ++ self.mask = [] + try: + cursor = cursor_consume_next(cursor, "Redfish Service IP Discovery Type: ") + if cursor == None: +@@ -200,14 +216,14 @@ class ServiceConfig(): + cursor = cursor_consume_next(cursor, "Redfish Service IP Address Format: ") + if cursor.split()[0] == "IPv4": + cursor = cursor_consume_next(cursor, "IPv4 Redfish Service Address: ") +- self.address = ipaddress.IPv4Address(cursor.split()[0]) ++ self.address.append(ipaddress.IPv4Address(cursor.split()[0])) + cursor = cursor_consume_next(cursor, "IPv4 Redfish Service Mask: ") +- self.mask = ipaddress.IPv4Address(cursor.split()[0]) ++ self.mask.append(ipaddress.IPv4Address(cursor.split()[0])) + elif cursor.split()[0] == "IPv6": + cursor = cursor_consume_next(cursor, "IPv6 Redfish Service Address: ") +- self.address = ipaddress.IPv6Address(unicode(cursor.split()[0], "utf-8")) ++ self.address.append(ipaddress.IPv6Address(unicode(cursor.split()[0], "utf-8"))) + cursor = cursor_consume_next(cursor, "IPv6 Mask: ") +- self.mask = ipaddress.IPv4Address(unicode(cursor.split()[0], "utf-8")) ++ self.mask.append(ipaddress.IPv4Address(unicode(cursor.split()[0], "utf-8"))) + elif cursor.split()[0] == "DHCP": + self.assigntype = AssignType.DHCP + else: +@@ -223,6 +239,11 @@ class ServiceConfig(): + except: + print("redfish-finder: Unexpected error parsing ServiceConfig") + ++ def merge(self, newconfig): ++ self.address.extend(newconfig.address) ++ self.mask.extend(newconfig.mask) ++ return self ++ + def __str__(self): + val = "Service Config(" + AssignType.typestring[self.assigntype] + ")" + if (self.assigntype == AssignType.STATIC): +@@ -236,42 +257,63 @@ class ServiceConfig(): + ###################################################### + class dmiobject(): + def __init__(self, dmioutput): ++ self.device = None ++ self.hostconfig = None ++ self.serviceconfig = None + cursor = dmioutput + # Find the type 42 header, if not found, nothing to do here +- cursor = cursor_consume_next(cursor, "Management Controller Host Interface\n") +- if (cursor == None): +- return None +- cursor = cursor_consume_next(cursor, "Host Interface Type: Network\n") +- if (cursor == None): +- return None ++ cursor = cursor_consume_next(cursor, "Management Controller Host Interface\n") ++ while (cursor != None): ++ if (cursor == None): ++ return None ++ cursor = cursor_consume_next(cursor, "Host Interface Type: Network\n") ++ if (cursor == None): ++ return None + +- # If we get here then we know this is a network interface device +- cursor = cursor_consume_next(cursor, "Device Type: ") +- # The next token should either be: +- # USB +- # PCI/PCIe +- # OEM +- # Unknown +- dtype = cursor.split()[0] +- if (dtype == "USB"): +- self.device = USBNetDevice(cursor) +- +- if self.device == None: +- return None ++ # If we get here then we know this is a network interface device ++ cursor = cursor_consume_next(cursor, "Device Type: ") ++ # The next token should either be: ++ # USB ++ # PCI/PCIe ++ # OEM ++ # Unknown ++ dtype = cursor.split()[0] ++ if (dtype == "USB"): ++ newdev = USBNetDevice(cursor) ++ ++ if newdev == None: ++ return None + +- # Now find the Redfish over IP section +- cursor = cursor_consume_next(cursor, "Protocol ID: 04 (Redfish over IP)\n") +- if (cursor == None): +- print("redfish-finder: Unable to find Redfish Protocol") +- return None ++ if self.device == None: ++ self.device = newdev ++ else: ++ self.device.merge(newdev) + +- self.hostconfig = HostConfig(cursor) +- if self.hostconfig == None: +- return None ++ # Now find the Redfish over IP section ++ cursor = cursor_consume_next(cursor, "Protocol ID: 04 (Redfish over IP)\n") ++ if (cursor == None): ++ print("redfish-finder: Unable to find Redfish Protocol") ++ return None + +- self.serviceconfig = ServiceConfig(cursor) +- if self.serviceconfig == None: +- return None ++ newhostconfig = HostConfig(cursor) ++ if newhostconfig == None: ++ return None ++ ++ if self.hostconfig == None: ++ self.hostconfig = newhostconfig ++ else: ++ self.hostconfig.merge(newhostconfig) ++ ++ serviceconfig = ServiceConfig(cursor) ++ if serviceconfig == None: ++ return None ++ ++ if self.serviceconfig == None: ++ self.serviceconfig = serviceconfig ++ elif self.serviceconfig == None: ++ self.serviceconfig.merge(serviceconfig) ++ ++ cursor = cursor_consume_next(cursor, "Management Controller Host Interface\n") + + + def __str__(self): +@@ -309,7 +351,10 @@ class OSServiceData(): + continue + + # Now add the new entries in +- newentry = str(self.sconf.address) + " " + self.constant_name ++ addresses="" ++ for i in self.sconf.address: ++ addresses = addresses + str(i) + " " ++ newentry = addresses + " " + self.constant_name + newentry = newentry + " " + self.sconf.hostname + self.host_entries.append(newentry) + diff --git a/SPECS/redfish-finder.spec b/SPECS/redfish-finder.spec index 8e9eb97..922357b 100644 --- a/SPECS/redfish-finder.spec +++ b/SPECS/redfish-finder.spec @@ -1,6 +1,6 @@ Name: redfish-finder Version: 0.3 -Release: 1%{?dist} +Release: 3%{?dist} Summary: Utility for parsing SMBIOS information and configuring canonical BMC access BuildArch: noarch @@ -8,6 +8,8 @@ License: GPLv2 URL: https://github.com/nhorman/redfish-finder Source0: %url/archive/V%{version}/%{name}-%{version}.tar.gz +Patch0: redfish-finder-multi-block.patch + %{?systemd_requires} BuildRequires: systemd @@ -48,8 +50,14 @@ install -D -p -m 0644 ./redfish-finder.service %{buildroot}/%{_unitdir}/redfish- %{_unitdir}/redfish-finder.service %changelog -* Thu Jul 11 2019 Neil Horman - 0.3.1 -- Update to latest upstream release +* Mon Jul 01 2019 Neil Horman - 0.3-3 +- Enhance to support multiple type 42 blocks (bz1715914) + +* Fri Apr 26 2019 Neil Horman - 0.3-2 +- Bump release number to test CI gating + +* Mon Apr 01 2019 Neil Horman - 0.3-1 +- Update to latest upstream release (bz1687111) * Fri Oct 19 2018 Neil Horman - 0.2-1 - Update to new upstream release