From 149ecad90e256061c14e0df996cc92ffe0092c8f Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Thu, 9 Jul 2026 14:12:23 -0400 Subject: [PATCH] Improvements for MegaRAC discovery Some Megarac fail with Host header looking like link local. Systems with nVidia architecture have multiple bmcs, select the actual bmc. --- .../confluent/discovery/handlers/megarac.py | 19 +++++++++++++++++++ .../confluent/discovery/protocols/ssdp.py | 9 ++++----- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/confluent_server/confluent/discovery/handlers/megarac.py b/confluent_server/confluent/discovery/handlers/megarac.py index 71866bac..3f3030b5 100644 --- a/confluent_server/confluent/discovery/handlers/megarac.py +++ b/confluent_server/confluent/discovery/handlers/megarac.py @@ -21,6 +21,25 @@ class NodeHandler(redfishbmc.NodeHandler): def get_firmware_default_account_info(self): return ('admin', 'admin') + async def get_manager_url(self, wc): + mgrs = (await self.srvroot(wc)).get('Managers', {}).get('@odata.id', None) + if not mgrs: + raise Exception("No Managers resource on BMC") + rsp = await wc.grab_json_response(mgrs) + if len(rsp.get('Members', [])) != 1: + urls = [] + for member in rsp.get('Members', []): + url = member.get('@odata.id', 'Unknown') + if 'HGX_BMC' in url: + continue + urls.append(url) + if len(urls) == 1: + return urls[0] + raise Exception("Can not handle multiple Managers") + mgrurl = rsp['Members'][0]['@odata.id'] + return mgrurl + + async def remote_nodecfg(nodename, cfm): cfg = cfm.get_node_attributes( diff --git a/confluent_server/confluent/discovery/protocols/ssdp.py b/confluent_server/confluent/discovery/protocols/ssdp.py index a6e77b8e..c71000bc 100644 --- a/confluent_server/confluent/discovery/protocols/ssdp.py +++ b/confluent_server/confluent/discovery/protocols/ssdp.py @@ -57,7 +57,7 @@ smsg = ('M-SEARCH * HTTP/1.1\r\n' async def active_scan(handler, protocol=None): known_peers = set([]) - async for scanned in scan(['urn:dmtf-org:service:redfish-rest:1', 'urn::dmtf-org:service:redfish-rest:', 'urn::service:affluent']): + async for scanned in scan(['urn:dmtf-org:service:redfish-rest:1', 'urn::service:affluent']): for addr in scanned['addresses']: addr = addr[0:1] + addr[2:] if addr in known_peers: @@ -115,7 +115,6 @@ def _process_snoop(peer, rsp, mac, known_peers, newmacs, peerbymacaddress, byeha if '/eth' in value and value.endswith('.xml'): targurl = '/redfish/v1/' targtype = 'megarac-bmc' - continue # MegaRAC redfish elif value.endswith('/DeviceDescription.json'): targurl = '/DeviceDescription.json' targtype = 'lenovo-xcc' @@ -128,7 +127,7 @@ def _process_snoop(peer, rsp, mac, known_peers, newmacs, peerbymacaddress, byeha tasks.spawn(check_fish_handler(handler, peerdata, known_peers, newmacs, peerbymacaddress, machandlers, mac, peer, targurl, targtype)) async def check_fish_handler(handler, peerdata, known_peers, newmacs, peerbymacaddress, machandlers, mac, peer, targurl, targtype): - retdata = await check_fish(('/DeviceDescription.json', peerdata, targtype)) + retdata = await check_fish((targurl, peerdata, targtype)) if retdata: known_peers.add(peer) newmacs.add(mac) @@ -497,7 +496,7 @@ async def check_fish(urldata, port=443, verifycallback=None): targtype = 'service:redfish-bmc' try: wc = webclient.WebConnection(_get_svrip(data), port, verifycallback=verifycallback) - peerinfo = await wc.grab_json_response(url, headers={'Accept': 'application/json'}) + peerinfo = await wc.grab_json_response(url, headers={'Accept': 'application/json', 'Host': 'credible-bmc'}) except socket.error: return None if url == '/DeviceDescription.json': @@ -609,6 +608,6 @@ async def _parse_ssdp(peer, rsp, peerdata): if __name__ == '__main__': def printit(rsp): pass # print(repr(rsp)) - active_scan(printit) + asyncio.run(active_scan(printit))