Skip to content

Commit 742b32a

Browse files
authored
Merge pull request #9 from LoH-lu/beta
Beta merge with main
2 parents 82dcf3e + 6d8e49e commit 742b32a

12 files changed

+1395
-499
lines changed

README.md

Lines changed: 57 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,69 @@
11
# netbox-nmap-scan
22

3-
This is a simple Python scripts that achieve the purpose of keeping an updated list of IP Address which are active/responding in your network.
4-
To achieve that we are using nmap.
3+
Automatically maintain an up-to-date inventory of active IP addresses in your network using Netbox and nmap. This Python-based tool scans your network prefixes and keeps your Netbox instance synchronized with the current state of your network.
54

6-
By default the scripts is scanning all prefixes with the active status inside your Netbox instance.
7-
If you don't want a prefix to get scan, create a new tag 'Disable Automatic Scanning'
5+
## Features
86

9-
![image](https://github.com/henrionlo/netbox-nmap-scan/assets/139378145/b7a223ae-3a55-42cb-8f28-87d282e103c8)
7+
- Automatic scanning of all active prefixes in Netbox
8+
- Custom tag support for excluding prefixes from scanning
9+
- Tracking of last scan time for each IP address
10+
- DNS resolution support
11+
- Tested with Python 3.12.6 - 3.13.1 and Netbox 4.1.10
1012

11-
Create the tag 'autoscan', this will allow you to quickly know which IP Addresses has been added by the script.
13+
## Prerequisites
1214

13-
![image](https://github.com/henrionlo/netbox-nmap-scan/assets/139378145/435cec58-1f92-42f2-b4eb-1448a4d22161)
15+
- Python 3.12.6 or later
16+
- Netbox 4.1.10 or later
17+
- nmap installed on your system
18+
- Required Python packages (listed in requirements.txt)
1419

15-
And create the following custom field in Customization, this way you can see when was the last time an ip address has been pinged by the scanning engine.
20+
## Setup
1621

17-
![image](https://github.com/LoH-lu/netbox-nmap-scan/assets/139378145/c812ee55-71d0-4d8e-9b14-f337a5d867a5)
22+
1. Create the following Netbox configurations:
1823

19-
The more prefixes you want to scan, the more time it will require to finish.
24+
### Tags
25+
- `autoscan`: Identifies IP addresses added by this script
26+
- `Disable Automatic Scanning`: Add this tag to prefixes you want to exclude from scanning
27+
28+
![Disable Scanning Tag Configuration](https://github.com/henrionlo/netbox-nmap-scan/assets/139378145/b7a223ae-3a55-42cb-8f28-87d282e103c8)
29+
30+
![Autoscan Tag Configuration](https://github.com/henrionlo/netbox-nmap-scan/assets/139378145/435cec58-1f92-42f2-b4eb-1448a4d22161)
2031

21-
Tested and working with Python 3.12.2 - 3.12.4 and Netbox 3.6.x - 4.0.x
32+
### Custom Fields
33+
Add a custom field to track the last scan time for each IP address:
34+
35+
![Last Scan Time Custom Field](https://github.com/LoH-lu/netbox-nmap-scan/assets/139378145/c812ee55-71d0-4d8e-9b14-f337a5d867a5)
2236

23-
The How-To are located in https://github.com/henrionlo/netbox-nmap-scan/wiki
37+
2. Follow the detailed installation guide in our [Wiki](https://github.com/henrionlo/netbox-nmap-scan/wiki)
2438

25-
TODO
26-
- Add DNS server selection for the nmap command in the ini file (if required to have a different one from the system DNS running the script)
27-
- Allow users to disable the DNS part of the script and only run the regular nmap command
28-
- Cleanup of code and import
29-
- Adding more description
30-
- Better logging of errors and debug output
31-
- All-in-One script for easier setup
39+
## Usage
40+
41+
The script will scan all prefixes with active status in your Netbox instance by default. Scanning time increases with the number of prefixes being scanned.
42+
43+
For detailed usage instructions and examples, please refer to our [Wiki](https://github.com/henrionlo/netbox-nmap-scan/wiki).
44+
45+
## Performance Considerations
46+
47+
- Scanning time scales with the number of prefixes
48+
- Consider scheduling scans during off-peak hours for large networks
49+
- Use the `Disable Automatic Scanning` tag strategically to optimize scan times
50+
51+
## Roadmap
52+
53+
- [ ] DNS server configuration in INI file for custom DNS resolution
54+
- [X] Option to disable DNS resolution functionality
55+
- [X] Toggle for last scan time tracking
56+
- [X] Toggle for the progress bar display while importing
57+
- [ ] Toggle for the logger in the Python console
58+
- [X] All-in-One setup script for easier deployment
59+
60+
## Contributing
61+
62+
Contributions are welcome! Please feel free to submit a Pull Request.
63+
64+
## Support
65+
66+
For issues, questions, or contributions, please:
67+
1. Check our [Wiki](https://github.com/henrionlo/netbox-nmap-scan/wiki)
68+
2. Open an issue in this repository
69+
3. Submit a pull request with your proposed changes

main.py

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Script runner that executes multiple Python scripts in sequence.
4+
This module provides functionality to run multiple Python scripts in order,
5+
with comprehensive logging of execution results.
6+
"""
7+
8+
import subprocess
9+
import sys
10+
import os
11+
import logging
12+
from datetime import datetime
13+
from typing import List
14+
15+
# Define the directory for logs and scripts
16+
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
17+
LOG_DIR = os.path.join(SCRIPT_DIR, 'logs')
18+
19+
# Ensure the log directory exists
20+
os.makedirs(LOG_DIR, exist_ok=True)
21+
22+
def setup_logging() -> logging.Logger:
23+
"""
24+
Configure logging with both file and console handlers.
25+
26+
Returns:
27+
logging.Logger: Configured logger instance
28+
"""
29+
# Create logger
30+
logger = logging.getLogger(__name__)
31+
logger.setLevel(logging.DEBUG)
32+
33+
# Create formatters
34+
file_formatter = logging.Formatter(
35+
'%(asctime)s - %(levelname)s - [%(filename)s:%(lineno)d] - %(message)s'
36+
)
37+
console_formatter = logging.Formatter(
38+
'%(asctime)s - %(levelname)s - %(message)s'
39+
)
40+
41+
# Create file handlers
42+
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
43+
debug_handler = logging.FileHandler(
44+
os.path.join(LOG_DIR, f'script_execution_debug_{timestamp}.log')
45+
)
46+
debug_handler.setLevel(logging.DEBUG)
47+
debug_handler.setFormatter(file_formatter)
48+
49+
error_handler = logging.FileHandler(
50+
os.path.join(LOG_DIR, f'script_execution_error_{timestamp}.log')
51+
)
52+
error_handler.setLevel(logging.ERROR)
53+
error_handler.setFormatter(file_formatter)
54+
55+
# Create console handler
56+
console_handler = logging.StreamHandler()
57+
console_handler.setLevel(logging.INFO)
58+
console_handler.setFormatter(console_formatter)
59+
60+
# Add handlers to logger
61+
logger.addHandler(debug_handler)
62+
logger.addHandler(error_handler)
63+
logger.addHandler(console_handler)
64+
65+
return logger
66+
67+
def run_script(script_name: str, logger: logging.Logger) -> bool:
68+
"""
69+
Executes a Python script using the current Python interpreter.
70+
71+
Args:
72+
script_name (str): The name of the script to run.
73+
logger (logging.Logger): The logger instance for logging messages.
74+
75+
Returns:
76+
bool: True if the script runs successfully, False otherwise.
77+
"""
78+
logger.info(f"Running {script_name}...")
79+
80+
try:
81+
# Run the script using the current Python interpreter
82+
result = subprocess.run(
83+
[sys.executable, script_name],
84+
capture_output=True,
85+
text=True,
86+
check=True
87+
)
88+
logger.info(f"{script_name} completed successfully.")
89+
logger.debug(f"Output:\n{result.stdout}")
90+
return True
91+
except subprocess.CalledProcessError as e:
92+
logger.error(f"Error running {script_name}:")
93+
logger.error(e.stderr) # Log the error message if the script fails
94+
return False
95+
96+
def main():
97+
"""
98+
Main function to run a list of Python scripts sequentially.
99+
100+
The function will stop execution if any script fails, preventing subsequent
101+
scripts from running if an error is encountered.
102+
"""
103+
logger = setup_logging()
104+
105+
# List of scripts to execute in order
106+
scripts: List[str] = [
107+
"netbox_export.py",
108+
"network_scan.py",
109+
"scan_processor.py",
110+
"netbox_import.py"
111+
]
112+
113+
# Iterate over the list of scripts and run each one
114+
for script in scripts:
115+
if not run_script(script, logger):
116+
logger.error(f"Execution stopped due to an error in {script}")
117+
break # Stop execution if a script fails
118+
else:
119+
logger.info("All scripts executed successfully.")
120+
121+
if __name__ == "__main__":
122+
# Run the main function if the script is executed directly
123+
main()

0 commit comments

Comments
 (0)