Thread-safe SQLite database manager for Ragnar host/network data. ACTION_STATUS_COLUMNS = { 'ssh_connector', 'rdp_connector', 'ftp_connector', 'smb_connector', 'telnet_connector', 'sql_connector', 'steal_files_ssh', 'steal_file
| 54 | logger = Logger(name="db_manager.py", level=logging.INFO) |
| 55 | |
| 56 | class DatabaseManager: |
| 57 | """ |
| 58 | Thread-safe SQLite database manager for Ragnar host/network data. |
| 59 | ACTION_STATUS_COLUMNS = { |
| 60 | 'ssh_connector', |
| 61 | 'rdp_connector', |
| 62 | 'ftp_connector', |
| 63 | 'smb_connector', |
| 64 | 'telnet_connector', |
| 65 | 'sql_connector', |
| 66 | 'steal_files_ssh', |
| 67 | 'steal_files_rdp', |
| 68 | 'steal_files_ftp', |
| 69 | 'steal_files_smb', |
| 70 | 'steal_files_telnet', |
| 71 | 'steal_data_sql', |
| 72 | 'nmap_vuln_scanner', |
| 73 | 'scanner_status' |
| 74 | } |
| 75 | |
| 76 | This class handles all database operations including: |
| 77 | - Schema creation and migrations |
| 78 | - CRUD operations for hosts |
| 79 | - Ping failure tracking |
| 80 | - Status management (alive/degraded/dead) |
| 81 | - CSV migration and backward compatibility |
| 82 | """ |
| 83 | |
| 84 | def __init__(self, db_path: str = None, currentdir: str = None, data_root: str = None): |
| 85 | """ |
| 86 | Initialize the database manager. |
| 87 | |
| 88 | Args: |
| 89 | db_path: Path to SQLite database file (default: data/ragnar.db) |
| 90 | currentdir: Root directory of Ragnar installation |
| 91 | """ |
| 92 | self.currentdir = currentdir or os.path.dirname(os.path.abspath(__file__)) |
| 93 | self.datadir = data_root or os.path.join(self.currentdir, 'data') |
| 94 | |
| 95 | # Database file location |
| 96 | if db_path is None: |
| 97 | db_path = os.path.join(self.datadir, 'ragnar.db') |
| 98 | |
| 99 | self.db_path = db_path |
| 100 | self.lock = threading.RLock() # Reentrant lock for nested calls |
| 101 | |
| 102 | # Legacy CSV paths for migration |
| 103 | self.netkb_csv = os.path.join(self.datadir, 'netkb.csv') |
| 104 | |
| 105 | # Initialize database |
| 106 | self._init_database() |
| 107 | |
| 108 | logger.info(f"DatabaseManager initialized: {self.db_path}") |
| 109 | |
| 110 | def configure_storage(self, data_root: Optional[str], db_path: Optional[str]): |
| 111 | """Update the storage root and database path when network context changes.""" |
| 112 | updated = False |
| 113 | with self.lock: |
no outgoing calls
no test coverage detected