new module: netxms
This commit is contained in:
parent
03a90b6239
commit
9bca20b010
22
README.md
22
README.md
|
@ -56,26 +56,24 @@ This script accesses [Prime](https://www.cisco.com/c/en/us/products/cloud-system
|
||||||
It is important to note everything was tested on Cisco Prime v3.4.0, using API v4. It was noticed that when trying to retrieve access points data, Prime requires more privileges, so you must explicitly inform that you wish this by using `Prime().run(access_points=True)`.
|
It is important to note everything was tested on Cisco Prime v3.4.0, using API v4. It was noticed that when trying to retrieve access points data, Prime requires more privileges, so you must explicitly inform that you wish this by using `Prime().run(access_points=True)`.
|
||||||
|
|
||||||
|
|
||||||
|
## NetXMS Module
|
||||||
|
This module reads the full list of NetXMS' objects and searches for IPv4 addresses discarding loopback addresses. Unfortunately, NetXMS API is not well documented and it is quite different from other APIs, since it doesn't paginate and uses cookies for authentication. This way, querying NetXMS can take a couple of minutes depending on the number of records and it can downgrade the system.
|
||||||
|
|
||||||
|
|
||||||
## Tests
|
## Tests
|
||||||
Some basic tests are implemented under `tests`. This directory comes with a shell script to run all the tests at once, but before running it, remember to setup some environment variables required by them, such as `NETBOX_ADDRESS` and `NMAP_PATH`.
|
Some basic tests are implemented under `tests`. This directory comes with a shell script to run all the tests at once, but before running it, remember to setup some environment variables required by them, such as `NETBOX_ADDRESS` and `NMAP_PATH`.
|
||||||
|
|
||||||
Here's the list of all variables:
|
The script contains a list of all variables, but if you do not want to hardcode passwords, just make sure to export such variables in your shell and properly comment those lines.
|
||||||
|
|
||||||
```bash
|
|
||||||
NETBOX_ADDRESS
|
|
||||||
NETBOX_TOKEN
|
|
||||||
|
|
||||||
NMAP_PATH
|
|
||||||
|
|
||||||
PRIME_ADDRESS
|
|
||||||
PRIME_USER
|
|
||||||
PRIME_PASS
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
## New Modules
|
## New Modules
|
||||||
New modules should be implemented as a new file with the name of the module, for instance `nbs/netxms.py`. In this case, a class `NetXMS` should be created in this file with a method `run`. Finally, in `netbox-scanner.py`, a function `cmd_netxms` should be created to execute the just created class, and another option should be created both in the argument parsing section and in the if structure inside the main block.
|
New modules should be implemented as a new file with the name of the module, for instance `nbs/netxms.py`. In this case, a class `NetXMS` should be created in this file with a method `run`. Finally, in `netbox-scanner.py`, a function `cmd_netxms` should be created to execute the just created class, and another option should be created both in the argument parsing section and in the if structure inside the main block.
|
||||||
|
|
||||||
|
|
||||||
|
## Contributors
|
||||||
|
|
||||||
|
- [Jarder Gonzalez](https://github.com/jfjunior) for the great NetXMS' API tips.
|
||||||
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
netbox-scanner is licensed under an MIT license --read `LICENSE` file for more information.
|
netbox-scanner is licensed under an MIT license --read `LICENSE` file for more information.
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
from re import compile
|
||||||
|
from json import loads
|
||||||
|
|
||||||
|
from requests import session, post
|
||||||
|
|
||||||
|
|
||||||
|
re_ipv4 = compile(r'(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)')
|
||||||
|
|
||||||
|
|
||||||
|
class NetXMS(object):
|
||||||
|
def __init__(self, address, username, password, tls_verify, unknown):
|
||||||
|
self.netxms = Api(address, username, password, tls_verify)
|
||||||
|
self.unknown = unknown
|
||||||
|
self.hosts = list()
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
objects = self.netxms.all()
|
||||||
|
|
||||||
|
for obj in objects['objects']:
|
||||||
|
address = description = ''
|
||||||
|
try:
|
||||||
|
if obj['ipAddressList']:
|
||||||
|
for ip in obj['ipAddressList']:
|
||||||
|
if re_ipv4.match(ip) and not ip.startswith('127.'):
|
||||||
|
address = ip
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
except KeyError:
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
description = obj['objectName']
|
||||||
|
except KeyError:
|
||||||
|
description = self.unknown
|
||||||
|
|
||||||
|
if address:
|
||||||
|
self.hosts.append((address, description))
|
||||||
|
|
||||||
|
|
||||||
|
class Api(object):
|
||||||
|
def __init__(self, base_url, username, password, tls_verify=False):
|
||||||
|
self.base_url = base_url
|
||||||
|
self.session = session()
|
||||||
|
self.session.post(
|
||||||
|
f'{self.base_url}/sessions',
|
||||||
|
json={'login':username, 'password':password}
|
||||||
|
)
|
||||||
|
|
||||||
|
def all(self):
|
||||||
|
return loads(self.session.get(f'{self.base_url}/objects').text)
|
|
@ -10,6 +10,15 @@ unknown = autodiscovered:netbox-scanner
|
||||||
tag = nmap
|
tag = nmap
|
||||||
cleanup = yes
|
cleanup = yes
|
||||||
|
|
||||||
|
[NETXMS]
|
||||||
|
address = https://netxms.domain
|
||||||
|
username =
|
||||||
|
password =
|
||||||
|
tls_verify = no
|
||||||
|
unknown = autodiscovered:netbox-scanner
|
||||||
|
tag = netxms
|
||||||
|
cleanup = yes
|
||||||
|
|
||||||
[PRIME]
|
[PRIME]
|
||||||
address = https://prime.domain/webacs/api/v4
|
address = https://prime.domain/webacs/api/v4
|
||||||
username =
|
username =
|
||||||
|
|
|
@ -11,6 +11,7 @@ from urllib3.exceptions import InsecureRequestWarning
|
||||||
|
|
||||||
from nbs import NetBoxScanner
|
from nbs import NetBoxScanner
|
||||||
from nbs.nmap import Nmap
|
from nbs.nmap import Nmap
|
||||||
|
from nbs.netxms import NetXMS
|
||||||
from nbs.prime import Prime
|
from nbs.prime import Prime
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,12 +28,14 @@ else:
|
||||||
|
|
||||||
netbox = config['NETBOX']
|
netbox = config['NETBOX']
|
||||||
nmap = config['NMAP']
|
nmap = config['NMAP']
|
||||||
|
netxms = config['NETXMS']
|
||||||
prime = config['PRIME']
|
prime = config['PRIME']
|
||||||
|
|
||||||
parser = ArgumentParser(description='netbox-scanner')
|
parser = ArgumentParser(description='netbox-scanner')
|
||||||
subparsers = parser.add_subparsers(title='Commands', dest='command')
|
subparsers = parser.add_subparsers(title='Commands', dest='command')
|
||||||
subparsers.required = True
|
subparsers.required = True
|
||||||
argsp = subparsers.add_parser('nmap', help='Nmap module')
|
argsp = subparsers.add_parser('nmap', help='Nmap module')
|
||||||
|
argsp = subparsers.add_parser('netxms', help='NetXMS module')
|
||||||
argsp = subparsers.add_parser('prime', help='Cisco Prime module')
|
argsp = subparsers.add_parser('prime', help='Cisco Prime module')
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
@ -55,6 +58,17 @@ def cmd_nmap(s): # nmap handler
|
||||||
h.run()
|
h.run()
|
||||||
s.sync(h.hosts)
|
s.sync(h.hosts)
|
||||||
|
|
||||||
|
def cmd_netxms(s): # netxms handler
|
||||||
|
h = NetXMS(
|
||||||
|
netxms['address'],
|
||||||
|
netxms['username'],
|
||||||
|
netxms['password'],
|
||||||
|
netxms.getboolean('tls_verify'),
|
||||||
|
netxms['unknown']
|
||||||
|
)
|
||||||
|
h.run()
|
||||||
|
s.sync(h.hosts)
|
||||||
|
|
||||||
def cmd_prime(s): # prime handler
|
def cmd_prime(s): # prime handler
|
||||||
h = Prime(
|
h = Prime(
|
||||||
prime['address'],
|
prime['address'],
|
||||||
|
@ -78,6 +92,10 @@ if __name__ == '__main__':
|
||||||
|
|
||||||
if args.command == 'nmap':
|
if args.command == 'nmap':
|
||||||
cmd_nmap(scanner)
|
cmd_nmap(scanner)
|
||||||
|
elif args.command == 'netxms':
|
||||||
|
scanner.tag = 'netxms'
|
||||||
|
scanner.cleanup = netxms.getboolean('cleanup')
|
||||||
|
cmd_netxms(scanner)
|
||||||
elif args.command == 'prime':
|
elif args.command == 'prime':
|
||||||
scanner.tag = prime['tag']
|
scanner.tag = prime['tag']
|
||||||
scanner.cleanup = prime.getboolean('cleanup')
|
scanner.cleanup = prime.getboolean('cleanup')
|
||||||
|
|
|
@ -1,13 +1,26 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
#
|
#
|
||||||
# Before running these tests, you must define some
|
# Before running these tests, fill the environment variables
|
||||||
# environment variables, such as:
|
# below according to your setup. If you don't want to
|
||||||
#
|
# hardcode this data, just be sure to exporting them in
|
||||||
# $ export NETBOX_ADDRESS="https..."
|
# your shell.
|
||||||
# $ export NETBOX_TOKEN="..."
|
|
||||||
# $ export NMAP_PATH="..."
|
|
||||||
##
|
##
|
||||||
|
|
||||||
|
export NETBOX_ADDRESS=""
|
||||||
|
export NETBOX_TOKEN=""
|
||||||
|
|
||||||
|
export NMAP_PATH=""
|
||||||
|
|
||||||
|
export PRIME_ADDRESS=""
|
||||||
|
export PRIME_USER=""
|
||||||
|
export PRIME_PASS=""
|
||||||
|
|
||||||
|
export NETXMS_ADDRESS=""
|
||||||
|
export NETXMS_USER=""
|
||||||
|
export NETXMS_PASS=""
|
||||||
|
|
||||||
|
|
||||||
python -m unittest tests.test_netbox
|
python -m unittest tests.test_netbox
|
||||||
python -m unittest tests.test_nmap
|
python -m unittest tests.test_nmap
|
||||||
python -m unittest tests.test_prime
|
python -m unittest tests.test_prime
|
||||||
|
python -m unittest tests.test_netxms
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
import unittest
|
||||||
|
from os import environ
|
||||||
|
from nbs.netxms import NetXMS
|
||||||
|
|
||||||
|
|
||||||
|
class TestRequest(unittest.TestCase):
|
||||||
|
def test_api(self):
|
||||||
|
address = environ.get('NETXMS_ADDRESS')
|
||||||
|
username = environ.get('NETXMS_USER')
|
||||||
|
password = environ.get('NETXMS_PASS')
|
||||||
|
|
||||||
|
netxms = NetXMS(address, username, password, False, 'unknown')
|
||||||
|
self.assertIsInstance(netxms, NetXMS)
|
||||||
|
netxms.run()
|
||||||
|
self.assertIsInstance(netxms.hosts, list)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
Loading…
Reference in New Issue