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:
@@ -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`:
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user