adding phase 5 init framework, added deployment ease scripts
This commit is contained in:
118
app/init_db.py
118
app/init_db.py
@@ -23,11 +23,112 @@ from alembic import command
|
||||
from alembic.config import Config
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from web.models import Base
|
||||
from web.models import Base, AlertRule
|
||||
from web.utils.settings import PasswordManager, SettingsManager
|
||||
|
||||
|
||||
def init_default_alert_rules(session):
|
||||
"""
|
||||
Create default alert rules for Phase 5.
|
||||
|
||||
Args:
|
||||
session: Database session
|
||||
"""
|
||||
print("Initializing default alert rules...")
|
||||
|
||||
# Check if alert rules already exist
|
||||
existing_rules = session.query(AlertRule).count()
|
||||
if existing_rules > 0:
|
||||
print(f" Alert rules already exist ({existing_rules} rules), skipping...")
|
||||
return
|
||||
|
||||
default_rules = [
|
||||
{
|
||||
'name': 'Unexpected Port Detection',
|
||||
'rule_type': 'unexpected_port',
|
||||
'enabled': True,
|
||||
'threshold': None,
|
||||
'email_enabled': False,
|
||||
'webhook_enabled': False,
|
||||
'severity': 'warning',
|
||||
'filter_conditions': None,
|
||||
'config_file': None
|
||||
},
|
||||
{
|
||||
'name': 'Drift Detection',
|
||||
'rule_type': 'drift_detection',
|
||||
'enabled': True,
|
||||
'threshold': None, # No threshold means alert on any drift
|
||||
'email_enabled': False,
|
||||
'webhook_enabled': False,
|
||||
'severity': 'info',
|
||||
'filter_conditions': None,
|
||||
'config_file': None
|
||||
},
|
||||
{
|
||||
'name': 'Certificate Expiry Warning',
|
||||
'rule_type': 'cert_expiry',
|
||||
'enabled': True,
|
||||
'threshold': 30, # Alert when certs expire in 30 days
|
||||
'email_enabled': False,
|
||||
'webhook_enabled': False,
|
||||
'severity': 'warning',
|
||||
'filter_conditions': None,
|
||||
'config_file': None
|
||||
},
|
||||
{
|
||||
'name': 'Weak TLS Detection',
|
||||
'rule_type': 'weak_tls',
|
||||
'enabled': True,
|
||||
'threshold': None,
|
||||
'email_enabled': False,
|
||||
'webhook_enabled': False,
|
||||
'severity': 'warning',
|
||||
'filter_conditions': None,
|
||||
'config_file': None
|
||||
},
|
||||
{
|
||||
'name': 'Host Down Detection',
|
||||
'rule_type': 'ping_failed',
|
||||
'enabled': True,
|
||||
'threshold': None,
|
||||
'email_enabled': False,
|
||||
'webhook_enabled': False,
|
||||
'severity': 'critical',
|
||||
'filter_conditions': None,
|
||||
'config_file': None
|
||||
}
|
||||
]
|
||||
|
||||
try:
|
||||
for rule_data in default_rules:
|
||||
rule = AlertRule(
|
||||
name=rule_data['name'],
|
||||
rule_type=rule_data['rule_type'],
|
||||
enabled=rule_data['enabled'],
|
||||
threshold=rule_data['threshold'],
|
||||
email_enabled=rule_data['email_enabled'],
|
||||
webhook_enabled=rule_data['webhook_enabled'],
|
||||
severity=rule_data['severity'],
|
||||
filter_conditions=rule_data['filter_conditions'],
|
||||
config_file=rule_data['config_file'],
|
||||
created_at=datetime.now(timezone.utc),
|
||||
updated_at=datetime.now(timezone.utc)
|
||||
)
|
||||
session.add(rule)
|
||||
print(f" ✓ Created rule: {rule.name}")
|
||||
|
||||
session.commit()
|
||||
print(f"✓ Created {len(default_rules)} default alert rules")
|
||||
|
||||
except Exception as e:
|
||||
print(f"✗ Failed to create default alert rules: {e}")
|
||||
session.rollback()
|
||||
raise
|
||||
|
||||
|
||||
def init_database(db_url: str = "sqlite:///./sneakyscanner.db", run_migrations: bool = True):
|
||||
"""
|
||||
Initialize the database schema and settings.
|
||||
@@ -78,6 +179,10 @@ def init_database(db_url: str = "sqlite:///./sneakyscanner.db", run_migrations:
|
||||
settings_manager = SettingsManager(session)
|
||||
settings_manager.init_defaults()
|
||||
print("✓ Default settings initialized")
|
||||
|
||||
# Initialize default alert rules
|
||||
init_default_alert_rules(session)
|
||||
|
||||
except Exception as e:
|
||||
print(f"✗ Failed to initialize settings: {e}")
|
||||
session.rollback()
|
||||
@@ -164,6 +269,9 @@ Examples:
|
||||
# Use custom database URL
|
||||
python3 init_db.py --db-url postgresql://user:pass@localhost/sneakyscanner
|
||||
|
||||
# Force initialization without prompting (for Docker/scripts)
|
||||
python3 init_db.py --force --password mysecret
|
||||
|
||||
# Verify existing database
|
||||
python3 init_db.py --verify-only
|
||||
"""
|
||||
@@ -192,6 +300,12 @@ Examples:
|
||||
help='Create tables directly instead of using migrations'
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--force',
|
||||
action='store_true',
|
||||
help='Force initialization without prompting (for non-interactive environments)'
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# Check if database already exists
|
||||
@@ -200,7 +314,7 @@ Examples:
|
||||
db_path = args.db_url.replace('sqlite:///', '')
|
||||
db_exists = Path(db_path).exists()
|
||||
|
||||
if db_exists and not args.verify_only:
|
||||
if db_exists and not args.verify_only and not args.force:
|
||||
response = input(f"\nDatabase already exists at {db_path}. Reinitialize? (y/N): ")
|
||||
if response.lower() != 'y':
|
||||
print("Aborting.")
|
||||
|
||||
Reference in New Issue
Block a user