diff --git a/netbox-scanner/config.py b/netbox-scanner/config.py deleted file mode 100644 index 060fe8e..0000000 --- a/netbox-scanner/config.py +++ /dev/null @@ -1,26 +0,0 @@ -# netbox-scanner configuration file. - -TAG = 'auto' -UNKNOWN = 'UNKNOWN HOST' -LOG = '.' # path to logfile -NMAP_ARGS = '-T4 -O -F --host-timeout 30s' - -NETBOX = { - 'ADDRESS': 'https://', - 'TOKEN': '', - 'TLS_VERIFY': True -} - -DEVICE_AUTH = { - # 'CISCO': { - # 'USER': 'netbox', - # 'PASSWORD': '', - # 'COMMAND': 'show run | inc hostname', - # 'REGEX': r'hostname ([A-Z|a-z|0-9|\-|_]+)', - # 'REGROUP': 1 - # } -} - -# These are the networks to be scanned. -# Example: ['192.168.40.0/20', '10.2.50.0/24'] -NETWORKS = [] diff --git a/netbox-scanner/nbscan.py b/netbox-scanner/nbscan.py index 5fa7596..5548f98 100644 --- a/netbox-scanner/nbscan.py +++ b/netbox-scanner/nbscan.py @@ -5,6 +5,7 @@ from ipaddress import IPv4Network from nmap import PortScanner from cpe import CPE +from csv import reader from pynetbox import api from paramiko import SSHClient, AutoAddPolicy from paramiko.ssh_exception import AuthenticationException @@ -169,6 +170,40 @@ class NetBoxScanner(object): except (AttributeError, ValueError): pass return True + + def sync_csv(self, csvfile): + '''Imports a CSV file to NetBox. + + :param csvfile: a CSV file with the following format: + IP addr,Description + 10.0.0.1,Gateway + 10.0.0.2,Server + ... + Note that this CSV file doesn't expect mask on + IP addresses, because all of them are processed + as /32. + :return: True if syncing is ok or False in other case. + ''' + hosts = [] + with open(csvfile,'r') as f: + next(f) + hosts = [(f'{data[0]}/32',data[1]) for data in + reader(f,delimiter=',')] + + for s in self.stats: + self.stats[s] = 0 + parsing = self.parser([h[0] for h in hosts]) + if parsing: + self.logger('mistyped', badnets=parsing) + return False + + logging.info('started: {} hosts via CSV'.format(len(hosts))) + for host in hosts: + self.sync_host(host) + logging.info('finished: +{} ~{} -{} ?{} !{}'.format( + self.stats['created'], self.stats['updated'], + self.stats['deleted'], self.stats['undiscovered'], + self.stats['duplicated'])) def sync(self, networks): '''Scan some networks and sync them to NetBox. @@ -182,7 +217,7 @@ class NetBoxScanner(object): if parsing: self.logger('mistyped', badnets=parsing) return False - + logging.info('started: {} networks'.format(len(networks))) for network in networks: self.sync_network(network) diff --git a/netbox-scanner/netbox-scanner.py b/netbox-scanner/netbox-scanner.py index 6417a34..109567d 100644 --- a/netbox-scanner/netbox-scanner.py +++ b/netbox-scanner/netbox-scanner.py @@ -3,6 +3,7 @@ import logging from configparser import ConfigParser +from argparse import ArgumentParser from os import fsync from os.path import expanduser from datetime import datetime @@ -54,6 +55,11 @@ except KeyError: print('Fill all fields before run the script again.') exit(1) +argp = ArgumentParser() +argp.add_argument('-c', '--csv', + help='import CSV file instead of scan network', default=None) +args = argp.parse_args() + logfile = '{}/netbox-scanner-{}.log'.format(general_conf['log'], datetime.now().strftime('%Y%m%dT%H%M%SZ')) logging.basicConfig(filename=logfile, level=logging.INFO, @@ -65,5 +71,8 @@ if __name__ == '__main__': nbs = NetBoxScanner(netbox_conf['address'], netbox_conf['token'], netbox_conf.getboolean('tls_verify'), general_conf['nmap_args'], tacacs_conf, general_conf['tag'], general_conf['unknown']) - nbs.sync(networks) + if not args.csv: + nbs.sync(networks) + else: + nbs.sync_csv(args.csv) exit(0) diff --git a/setup.py b/setup.py index 6c816d2..a9a5840 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ with open('README.md', 'r') as fh: setuptools.setup( name='netbox-scanner', - version='0.6.1', + version='0.7.0', author='José Lopes de Oliveira Jr.', author_email='jlojunior@gmail.com', description='A scanner util for NetBox',