2
0
mirror of https://github.com/xcat2/confluent.git synced 2026-09-11 03:56:26 +00:00

Begin work on aggressive discovery rescan

This begins to ping everywhere and start evaluating everything.
This commit is contained in:
Jarrod Johnson
2026-09-10 16:00:46 -04:00
parent c7d2e17545
commit 65960df93e
4 changed files with 53 additions and 11 deletions
+6 -3
View File
@@ -371,8 +371,8 @@ async def assign_discovery(options, session, needid=True):
if exitcode:
sys.exit(exitcode)
async def blocking_scan(session):
list([x async for x in session.update('/discovery/rescan', {'rescan': 'start'})])
async def blocking_scan(session, aggressive=False):
list([x async for x in session.update('/discovery/rescan', {'rescan': 'aggressive' if aggressive else 'start'})])
while(list([x async for x in session.read('/discovery/rescan')])[0].get('scanning', False)):
await asyncio.sleep(0.5)
list([x async for x in session.update('/networking/macs/rescan', {'rescan': 'start'})])
@@ -388,6 +388,9 @@ async def main():
# flush to clear old data out? (e.g. no good way to age pxe data)
# also delete discovery datum... more targeted
# defect: -t lenovo-imm returns all
parser.add_option('-a', '--aggresive', dest='aggressive',
help='Use aggressive scanning and fingerprinting that is slower and more intrusive',
action='store_true')
parser.add_option('-m', '--model', dest='model',
help='Operate with nodes matching the specified model '
'number', metavar='MODEL')
@@ -443,7 +446,7 @@ async def main():
if args[0] == 'unsubscribe':
await subscribe_discovery(options, session, False, args[1])
if args[0] == 'rescan':
await blocking_scan(session)
await blocking_scan(session, aggressive=options.aggressive)
print("Rescan complete")
@@ -75,6 +75,9 @@ the nodes.
## OPTIONS
* `-a`, `--aggressive`:
Perform more aggressive scanning and fingerprinting. This will probe as many addresses as it can find with ssh and https connections. By default more targeted measures are used
that will only tend to probe things that are easily detectable as devices implementing explicit mechanisms for detection and identification.
* `-m MODEL`, `--model=MODEL`:
Operate with nodes matching the specified model number
* `-s SERIAL`, `--serial=SERIAL`:
+37 -6
View File
@@ -95,6 +95,8 @@ import socket
import socket as nsocket
import aiohmi.util.webclient as webclient
from confluent import netutil, neighutil
autosensors = set()
scanner = None
@@ -574,9 +576,13 @@ async def handle_api_request(configmanager, inputdata, operation, pathcomponents
return handle_read_api_request(pathcomponents)
elif (operation in ('update', 'create') and
pathcomponents == ['discovery', 'rescan']):
if inputdata != {'rescan': 'start'}:
rescanmode = inputdata.get('rescan', None)
if rescanmode == 'aggressive':
await rescan(aggressive=True)
elif rescanmode == 'start':
await rescan()
else:
raise exc.InvalidArgumentException()
await rescan()
return (msg.KeyValueData({'rescan': 'started'}),)
elif operation in ('update', 'create') and pathcomponents[:2] == ['discovery', 'subscriptions']:
target = pathcomponents[2]
@@ -1669,13 +1675,13 @@ async def _periodic_recheck(configmanager):
configmanager)
async def rescan():
async def rescan(aggressive=False):
_map_unique_ids()
global scanner
if scanner:
return
else:
scanner = tasks.spawn_task(blocking_scan())
scanner = tasks.spawn_task(blocking_scan(aggressive))
await remotescan()
async def remotescan():
@@ -1688,15 +1694,40 @@ async def remotescan():
log.log({'error': 'Unexpected problem asking {} for discovery notifications'.format(remagent)})
async def blocking_scan():
async def blocking_scan(aggressive=False):
global scanner
if aggressive:
pingscan = tasks.spawn_task(netutil.ping_everywhere())
slpscan = tasks.spawn_task(slp.active_scan(safe_detected, slp))
ssdpscan = tasks.spawn_task(ssdp.active_scan(safe_detected, ssdp))
await slpscan
await ssdpscan
#ssdpscan.wait()
if aggressive:
pingscan_result = await pingscan
else:
pingscan_result = {}
gencheckers = []
for iface in pingscan_result:
for ipa in pingscan_result[iface]:
hwaddr = await neighutil.get_hwaddr(ipa)
if not hwaddr:
continue
if hwaddr in known_info:
continue
gencheckers.append(generic_eval(ipa))
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:
return None
safe_detected(resdata)
def start_detection():
global attribwatcher
global rechecker
@@ -127,7 +127,10 @@ 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((targurl, peerdata, targtype))
try:
retdata = await check_fish((targurl, peerdata, targtype))
except Exception:
return
if retdata:
known_peers.add(peer)
newmacs.add(mac)
@@ -533,7 +536,7 @@ async def check_fish(urldata, port=443, verifycallback=None):
url, data = urldata
targtype = 'service:redfish-bmc'
try:
wc = webclient.WebConnection(_get_svrip(data), port, verifycallback=verifycallback)
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'})
except socket.error:
return None
@@ -588,6 +591,8 @@ async def check_fish(urldata, port=443, verifycallback=None):
else:
data['services'] = [targtype]
data['uuid'] = peerinfo['UUID'].lower()
if len(data['uuid']) == 32: # add hyphens to match standard UUID format
data['uuid'] = '-'.join([data['uuid'][:8], data['uuid'][8:12], data['uuid'][12:16], data['uuid'][16:20], data['uuid'][20:]])
return data
return None