From 4f4eeefddb20fc85ea61c5cd8a2f3c20e6c407f1 Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Fri, 11 Sep 2026 14:06:16 -0400 Subject: [PATCH] Have rescan -a find generic-ssh, generic-https, and generic-redfish Going from generic-redfish as most specific, then generic-https, and generic-ssh being for ssh-only targets. For generic-https and generic-ssh, the available ports are specified so code can know if https *also* has port 22 available. --- confluent_server/confluent/discovery/core.py | 38 ++++++++++++++++--- .../confluent/discovery/protocols/ssdp.py | 2 +- confluent_server/confluent/netutil.py | 8 +++- 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/confluent_server/confluent/discovery/core.py b/confluent_server/confluent/discovery/core.py index f6cd6d8a..693aa0f8 100644 --- a/confluent_server/confluent/discovery/core.py +++ b/confluent_server/confluent/discovery/core.py @@ -130,6 +130,9 @@ nodehandlers = { 'onie-switch': None, 'cumulus-switch': None, 'affluent-switch': None, + 'generic-redfish': None, + 'generic-https': None, + 'generic-ssh': None, #'openbmc': None, 'service:io-device.Lenovo:management-module': None, 'service:thinkagile-storage': cpstorage, @@ -148,6 +151,9 @@ servicenames = { 'lenovo-xcc3': 'lenovo-xcc3', 'megarac-bmc': 'megarac-bmc', 'megware-chassis': 'megware-chassis', + 'generic-redfish': 'generic-redfish', + 'generic-https': 'generic-https', + 'generic-ssh': 'generic-ssh', #'openbmc': 'openbmc', 'service:management-hardware.IBM:integrated-management-module2': 'lenovo-imm2', 'service:io-device.Lenovo:management-module': 'lenovo-switch', @@ -166,6 +172,9 @@ servicebyname = { 'lenovo-xcc': 'lenovo-xcc', 'lenovo-xcc3': 'lenovo-xcc3', 'megarac-bmc': 'megarac-bmc', + 'generic-redfish': 'generic-redfish', + 'generic-https': 'generic-https', + 'generic-ssh': 'generic-ssh', 'megware-chassis': 'megware-chassis', 'lenovo-imm2': 'service:management-hardware.IBM:integrated-management-module2', 'lenovo-switch': 'service:io-device.Lenovo:management-module', @@ -1714,18 +1723,35 @@ async def blocking_scan(aggressive=False): continue if hwaddr in known_info: continue - gencheckers.append(generic_eval(ipa)) + gencheckers.append(generic_eval(ipa, hwaddr)) if gencheckers: await asyncio.gather(*gencheckers, return_exceptions=True) scanner = None -async def generic_eval(address): - peerdata = {'addresses': [(address, 443)]} - resdata = await ssdp.check_fish(('/redfish/v1/', peerdata)) - if not resdata: +async def generic_eval(address, hwaddr): + ports = await netutil.peer_reachable(address) + if not ports: return None - safe_detected(resdata) + cloop = asyncio.get_running_loop() + addrinfo = await cloop.getaddrinfo( + address, 443, family=socket.AF_INET6, type=socket.SOCK_STREAM) + + if not addrinfo: + return None + sockaddr = addrinfo[0][4] + peerdata = {'addresses': [sockaddr], 'hwaddr': hwaddr, 'openports': ports} + if 443 in ports: + resdata = await ssdp.check_fish(('/redfish/v1/', peerdata)) + if resdata: + return safe_detected(resdata) + peerdata['services'] = ['generic-https'] + if 'services' not in peerdata and 22 in ports: + sockaddr = (sockaddr[0], 22) + tuple(sockaddr[2:]) + peerdata['addresses'] = [sockaddr] + peerdata['services'] = ['generic-ssh'] + if 'services' in peerdata: + safe_detected(peerdata) def start_detection(): diff --git a/confluent_server/confluent/discovery/protocols/ssdp.py b/confluent_server/confluent/discovery/protocols/ssdp.py index 77dc8eea..a6eb0b8a 100644 --- a/confluent_server/confluent/discovery/protocols/ssdp.py +++ b/confluent_server/confluent/discovery/protocols/ssdp.py @@ -534,7 +534,7 @@ async def check_fish(urldata, port=443, verifycallback=None): url, data, targtype = urldata except ValueError: url, data = urldata - targtype = 'service:redfish-bmc' + targtype = 'generic-redfish' try: wc = webclient.WebConnection(_get_svrip(data), port, verifycallback=verifycallback, timeout=3) peerinfo = await wc.grab_json_response(url, headers={'Accept': 'application/json', 'Host': 'credible-bmc'}) diff --git a/confluent_server/confluent/netutil.py b/confluent_server/confluent/netutil.py index e221e0fd..ccd80b27 100644 --- a/confluent_server/confluent/netutil.py +++ b/confluent_server/confluent/netutil.py @@ -92,7 +92,7 @@ async def peer_reachable(address): try: conn = await asyncio.wait_for( asyncio.open_connection(address, port), timeout=0.5) - return True + return port except Exception: return False finally: @@ -101,7 +101,11 @@ async def peer_reachable(address): await conn[1].wait_closed() testtasks.append(check_port(port)) results = await asyncio.gather(*testtasks, return_exceptions=True) - return any(not isinstance(r, Exception) and r for r in results) + reachable_ports = [] + for res in results: + if not isinstance(res, Exception) and res: + reachable_ports.append(res) + return reachable_ports async def add_zone(lla):