- S4: bump jinja2>=3.1.4, python-multipart>=0.0.18, httpx>=0.28.0
- S5: _detect_ecosystem — DEFAULT_ECOSYSTEM для неизвестных форматов
- S6: harvester — log.exception() вместо log.error()
- S8: _scan_component — urlencode параметров
- P1: scanner — proc.kill() при таймауте
- P3: api_packages — selectinload(Scan.findings), убран N+1
- P4+P5: утечка _url_locks и _llm_locks при early return
- P6: DB reaper — сброс {'status':'analyzing'} при старте
- UI: htmx-пагинация, фильтры не теряют flagged, 404 с layout
- UI: мобильные таблицы overflow-x, полная стата на дашборде
- UI: i18n статусов в _status_badge, urlencode package_name
- 16 новых тестов: analyze endpoint (6), scanner errors (4),
webhook signature (2), llm client (4)
69 lines
2.3 KiB
Python
69 lines
2.3 KiB
Python
"""Configuration via environment variables."""
|
|
|
|
import os
|
|
from dataclasses import dataclass
|
|
|
|
from guarddog_nexus.constants import (
|
|
DEFAULT_MAX_CONCURRENT_SCANS,
|
|
GUARDDOG_BINARY_FALLBACK,
|
|
HTTP_TIMEOUT_API,
|
|
HTTP_TIMEOUT_DOWNLOAD,
|
|
LLM_DEFAULT_API_BASE,
|
|
LLM_DEFAULT_MODEL,
|
|
LLM_DEFAULT_TIMEOUT,
|
|
)
|
|
|
|
|
|
def _env_int(name: str, default: int) -> int:
|
|
val = os.getenv(name)
|
|
if val is None:
|
|
return default
|
|
try:
|
|
return int(val)
|
|
except ValueError:
|
|
return default
|
|
|
|
|
|
@dataclass
|
|
class Config:
|
|
# Nexus connection
|
|
nexus_url: str = os.getenv("NEXUS_URL", "http://localhost:8081")
|
|
nexus_username: str = os.getenv("NEXUS_USERNAME", "admin")
|
|
nexus_password: str = os.getenv("NEXUS_PASSWORD", "admin123")
|
|
nexus_download_timeout: int = _env_int("NEXUS_DOWNLOAD_TIMEOUT_SECONDS", HTTP_TIMEOUT_DOWNLOAD)
|
|
nexus_api_timeout: int = _env_int("NEXUS_API_TIMEOUT_SECONDS", HTTP_TIMEOUT_API)
|
|
|
|
# Database
|
|
database_path: str = os.getenv("DATABASE_PATH", "data/guarddog.db")
|
|
|
|
# Server
|
|
host: str = os.getenv("HOST", "0.0.0.0")
|
|
port: int = _env_int("PORT", 8080)
|
|
|
|
# Logging
|
|
log_level: str = os.getenv("LOG_LEVEL", "INFO")
|
|
log_syslog_host: str = os.getenv("LOG_SYSLOG_HOST", "")
|
|
log_syslog_port: int = _env_int("LOG_SYSLOG_PORT", 514)
|
|
log_syslog_facility: str = os.getenv("LOG_SYSLOG_FACILITY", "")
|
|
|
|
# Webhooks
|
|
webhook_secret: str = os.getenv("WEBHOOK_SECRET", "")
|
|
|
|
# Scanner
|
|
scan_timeout_seconds: int = _env_int("SCAN_TIMEOUT_SECONDS", 300)
|
|
temp_dir: str = os.getenv("TEMP_DIR", "/tmp/guarddog-nexus")
|
|
guarddog_binary: str = os.getenv("GUARDDOG_BINARY", GUARDDOG_BINARY_FALLBACK)
|
|
max_concurrent_scans: int = _env_int("MAX_CONCURRENT_SCANS", DEFAULT_MAX_CONCURRENT_SCANS)
|
|
|
|
# LLM analysis
|
|
llm_enabled: bool = os.getenv("LLM_ENABLED", "").lower() in ("1", "true", "yes")
|
|
llm_auto_analyze: bool = os.getenv("LLM_AUTO_ANALYZE", "").lower() in ("1", "true", "yes")
|
|
llm_api_base: str = os.getenv("LLM_API_BASE", LLM_DEFAULT_API_BASE)
|
|
llm_api_key: str = os.getenv("LLM_API_KEY", "")
|
|
llm_model: str = os.getenv("LLM_MODEL", LLM_DEFAULT_MODEL)
|
|
llm_timeout: int = _env_int("LLM_TIMEOUT_SECONDS", LLM_DEFAULT_TIMEOUT)
|
|
llm_max_concurrent: int = _env_int("LLM_MAX_CONCURRENT_ANALYSES", 2)
|
|
|
|
|
|
config = Config()
|