From 8bdabdc962dda7406d18feae8ea00717280ec924 Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Tue, 3 Dec 2024 14:34:11 -0500 Subject: [PATCH] SMMv3 discovery support The SMMv3 doesn't respond to the correct SSDP service, add the odd service. Have SMMv3 use the standard redfish handler. Augment the standard redfish handler to deal with non-error password change required message. --- confluent_server/confluent/discovery/core.py | 4 ++++ .../confluent/discovery/handlers/redfishbmc.py | 9 ++++++++- .../confluent/discovery/protocols/ssdp.py | 12 +++++++++--- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/confluent_server/confluent/discovery/core.py b/confluent_server/confluent/discovery/core.py index fd302f8b..41767a77 100644 --- a/confluent_server/confluent/discovery/core.py +++ b/confluent_server/confluent/discovery/core.py @@ -75,6 +75,7 @@ import confluent.discovery.handlers.pxe as pxeh import confluent.discovery.handlers.smm as smm import confluent.discovery.handlers.xcc as xcc import confluent.discovery.handlers.xcc3 as xcc3 +import confluent.discovery.handlers.smm3 as smm3 import confluent.discovery.handlers.megarac as megarac import confluent.exceptions as exc import confluent.log as log @@ -114,6 +115,7 @@ class nesteddict(dict): nodehandlers = { 'service:lenovo-smm': smm, 'service:lenovo-smm2': smm, + 'lenovo-smm3': smm3, 'lenovo-xcc': xcc, 'lenovo-xcc3': xcc3, 'megarac-bmc': megarac, @@ -134,6 +136,7 @@ servicenames = { 'cumulus-switch': 'cumulus-switch', 'service:lenovo-smm': 'lenovo-smm', 'service:lenovo-smm2': 'lenovo-smm2', + 'lenovo-smm3': 'lenovo-smm3', 'affluent-switch': 'affluent-switch', 'lenovo-xcc': 'lenovo-xcc', 'lenovo-xcc3': 'lenovo-xcc3', @@ -151,6 +154,7 @@ servicebyname = { 'cumulus-switch': 'cumulus-switch', 'lenovo-smm': 'service:lenovo-smm', 'lenovo-smm2': 'service:lenovo-smm2', + 'lenovo-smm3': 'lenovo-smm3', 'affluent-switch': 'affluent-switch', 'lenovo-xcc': 'lenovo-xcc', 'lenovo-xcc3': 'lenovo-xcc3', diff --git a/confluent_server/confluent/discovery/handlers/redfishbmc.py b/confluent_server/confluent/discovery/handlers/redfishbmc.py index 7cf3f3d1..a14530d3 100644 --- a/confluent_server/confluent/discovery/handlers/redfishbmc.py +++ b/confluent_server/confluent/discovery/handlers/redfishbmc.py @@ -134,7 +134,14 @@ class NodeHandler(generic.NodeHandler): rsp = json.loads(rsp) currerr = rsp.get('error', {}) ecode = currerr.get('code', None) - if ecode.endswith('PasswordChangeRequired'): + if not ecode: + for msg in rsp['@Message.ExtendedInfo']: + if 'PasswordChangeRequired' in msg['MessageId']: + chgurl = msg['MessageArgs'][0] + break + else: + raise Exception("Failed to ascertain login failure reason") + elif ecode.endswith('PasswordChangeRequired'): for einfo in currerr.get('@Message.ExtendedInfo', []): if einfo.get('MessageId', None).endswith('PasswordChangeRequired'): for msgarg in einfo.get('MessageArgs'): diff --git a/confluent_server/confluent/discovery/protocols/ssdp.py b/confluent_server/confluent/discovery/protocols/ssdp.py index 5c27473b..8a9ab396 100644 --- a/confluent_server/confluent/discovery/protocols/ssdp.py +++ b/confluent_server/confluent/discovery/protocols/ssdp.py @@ -58,7 +58,7 @@ smsg = ('M-SEARCH * HTTP/1.1\r\n' def active_scan(handler, protocol=None): known_peers = set([]) - for scanned in scan(['urn:dmtf-org:service:redfish-rest:1', 'urn::service:affluent']): + for scanned in scan(['urn:dmtf-org:service:redfish-rest:1', 'urn::dmtf-org:service:redfish-rest:', 'urn::service:affluent']): for addr in scanned['addresses']: addr = addr[0:1] + addr[2:] if addr in known_peers: @@ -429,10 +429,10 @@ def _find_service(service, target): mya['enclosure-machinetype-model'] = [val] yield peerdata[nid] continue - if '/redfish/v1/' not in peerdata[nid].get('urls', ()) and '/redfish/v1' not in peerdata[nid].get('urls', ()): - continue if '/DeviceDescription.json' in peerdata[nid]['urls']: pooltargs.append(('/DeviceDescription.json', peerdata[nid], 'lenovo-xcc')) + elif '/redfish/v1/' not in peerdata[nid].get('urls', ()) and '/redfish/v1' not in peerdata[nid].get('urls', ()): + continue else: for targurl in peerdata[nid]['urls']: if '/eth' in targurl and targurl.endswith('.xml'): @@ -463,6 +463,12 @@ def check_fish(urldata, port=443, verifycallback=None): return None if url == '/DeviceDescription.json': if not peerinfo: + if data['services'] == ['urn::dmtf-org:service:redfish-rest:']: + peerinfo = wc.grab_json_response('/redfish/v1/') + if peerinfo: + data['services'] = ['lenovo-smm3'] + data['uuid'] = peerinfo['UUID'].lower() + return data return None try: peerinfo = peerinfo[0]