mirror of
https://github.com/lopes/netbox-scanner.git
synced 2025-07-24 22:34:47 +02:00
added network parsing
This commit is contained in:
parent
9bea9ffa3d
commit
f9833a65ba
@ -26,6 +26,22 @@ class NetBoxScanner(object):
|
|||||||
self.stats = {'created':0, 'updated':0, 'deleted':0,
|
self.stats = {'created':0, 'updated':0, 'deleted':0,
|
||||||
'undiscovered':0, 'duplicated':0}
|
'undiscovered':0, 'duplicated':0}
|
||||||
|
|
||||||
|
def parser(self, networks):
|
||||||
|
'''Parses a list of networks in CIDR notation.
|
||||||
|
|
||||||
|
:param networks: a list of networks like ['10.0.0.0/8',...]
|
||||||
|
:return: False if parsing is OK, or a string with duplicated
|
||||||
|
or mistyped networks.
|
||||||
|
'''
|
||||||
|
ipv4 = re.compile(r'^((2([0-4][0-9]|5[0-5])|1?[0-9]?[0-9])\.){3}(2([0-4][0-9]|5[0-5])|1?[0-9]?[0-9])\/(3[012]|[12]?[0-9])$')
|
||||||
|
duplicated = set([x for x in networks if networks.count(x)>1])
|
||||||
|
if duplicated:
|
||||||
|
return ', '.join(duplicated)
|
||||||
|
for net in networks:
|
||||||
|
if not re.match(ipv4, net):
|
||||||
|
return net
|
||||||
|
return False
|
||||||
|
|
||||||
def get_description(self, address, name, cpe):
|
def get_description(self, address, name, cpe):
|
||||||
'''Define a description based on hostname and CPE'''
|
'''Define a description based on hostname and CPE'''
|
||||||
if name:
|
if name:
|
||||||
@ -73,7 +89,9 @@ class NetBoxScanner(object):
|
|||||||
|
|
||||||
def logger(self, logtype, **kwargs):
|
def logger(self, logtype, **kwargs):
|
||||||
'''Logs and updates stats for NetBox interactions.'''
|
'''Logs and updates stats for NetBox interactions.'''
|
||||||
if logtype == 'created':
|
if logtype == 'scanned':
|
||||||
|
logging.info('scanned: {} ({} hosts discovered)'.format(kwargs['net'], kwargs['hosts']))
|
||||||
|
elif logtype == 'created':
|
||||||
logging.info('created: {}/32 "{}"'.format(kwargs['address'],
|
logging.info('created: {}/32 "{}"'.format(kwargs['address'],
|
||||||
kwargs['description']))
|
kwargs['description']))
|
||||||
self.stats['created'] += 1
|
self.stats['created'] += 1
|
||||||
@ -92,7 +110,9 @@ class NetBoxScanner(object):
|
|||||||
self.stats['undiscovered'] += 1
|
self.stats['undiscovered'] += 1
|
||||||
elif logtype == 'duplicated':
|
elif logtype == 'duplicated':
|
||||||
logging.error('duplicated: {}/32'.format(kwargs['address']))
|
logging.error('duplicated: {}/32'.format(kwargs['address']))
|
||||||
self.stats['duplicated'] += 1
|
self.stats['duplicated'] += 1
|
||||||
|
elif logtype == 'mistyped':
|
||||||
|
logging.error('mistyped: {}'.format(kwargs['badnets']))
|
||||||
|
|
||||||
def sync_host(self, host):
|
def sync_host(self, host):
|
||||||
'''Syncs a single host to NetBox.
|
'''Syncs a single host to NetBox.
|
||||||
@ -122,14 +142,19 @@ class NetBoxScanner(object):
|
|||||||
'''Scan some networks and sync them to NetBox.
|
'''Scan some networks and sync them to NetBox.
|
||||||
|
|
||||||
:param networks: a list of valid networks, like ['10.0.0.0/8']
|
:param networks: a list of valid networks, like ['10.0.0.0/8']
|
||||||
:return: synching statistics are returned as a tuple
|
:return: synching statistics
|
||||||
'''
|
'''
|
||||||
for s in self.stats:
|
for s in self.stats:
|
||||||
self.stats[s] = 0
|
self.stats[s] = 0
|
||||||
|
|
||||||
|
parsing = self.parser(networks)
|
||||||
|
if parsing:
|
||||||
|
self.logger('mistyped', badnets=parsing)
|
||||||
|
return False
|
||||||
|
|
||||||
for net in networks:
|
for net in networks:
|
||||||
hosts = self.scan(net)
|
hosts = self.scan(net)
|
||||||
logging.info('scan: {} ({} hosts discovered)'.format(net,
|
self.logger('scanned', net=net, hosts=len(hosts))
|
||||||
len(hosts)))
|
|
||||||
for host in hosts:
|
for host in hosts:
|
||||||
self.sync_host(host)
|
self.sync_host(host)
|
||||||
|
|
||||||
@ -147,6 +172,5 @@ class NetBoxScanner(object):
|
|||||||
description=nbhost.description)
|
description=nbhost.description)
|
||||||
except (AttributeError, ValueError):
|
except (AttributeError, ValueError):
|
||||||
pass
|
pass
|
||||||
return (self.stats['created'], self.stats['updated'],
|
|
||||||
self.stats['deleted'], self.stats['undiscovered'],
|
return True
|
||||||
self.stats['duplicated'])
|
|
||||||
|
@ -40,8 +40,9 @@ disable_warnings(InsecureRequestWarning)
|
|||||||
nbs = NetBoxScanner(args.address, args.token, args.verify, args.nmap,
|
nbs = NetBoxScanner(args.address, args.token, args.verify, args.nmap,
|
||||||
args.devices, args.tag, args.unknown)
|
args.devices, args.tag, args.unknown)
|
||||||
logging.info('started: {} networks'.format(len(args.networks)))
|
logging.info('started: {} networks'.format(len(args.networks)))
|
||||||
stats = nbs.sync(args.networks)
|
nbs.sync(args.networks)
|
||||||
logging.info('finished: +{} ~{} -{} ?{} !{}'.format(stats[0], stats[1],
|
logging.info('finished: +{} ~{} -{} ?{} !{}'.format(nbs.stats['created'],
|
||||||
stats[2], stats[3], stats[4]))
|
nbs.stats['updated'], nbs.stats['deleted'], nbs.stats['undiscovered'],
|
||||||
|
nbs.stats['duplicated']))
|
||||||
|
|
||||||
exit(0)
|
exit(0)
|
||||||
|
2
setup.py
2
setup.py
@ -7,7 +7,7 @@ with open('README.md', 'r') as fh:
|
|||||||
|
|
||||||
setuptools.setup(
|
setuptools.setup(
|
||||||
name='netbox-scanner',
|
name='netbox-scanner',
|
||||||
version='0.5.2',
|
version='0.5.3',
|
||||||
author='José Lopes de Oliveira Jr.',
|
author='José Lopes de Oliveira Jr.',
|
||||||
author_email='jlojunior@gmail.com',
|
author_email='jlojunior@gmail.com',
|
||||||
description='A scanner util for NetBox',
|
description='A scanner util for NetBox',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user