Security Dashboard
📜 Software Bill of Materials (SBOM)
Vollstaendige Liste aller Abhaengigkeiten und deren Versionen.
""" BreakPilot Developer Admin Frontend Ein separates Admin-Frontend fuer Entwickler mit DevSecOps Dashboard, SBOM-Viewer, Security-Scans und anderen Entwickler-Tools. URL: /dev-admin """ from fastapi import APIRouter from fastapi.responses import HTMLResponse # Import der Security Module from .modules.security import SecurityModule router = APIRouter() def get_dev_admin_css() -> str: """CSS fuer das Developer Admin Frontend.""" return """ /* ========================================== DEVELOPER ADMIN - CSS VARIABLES ========================================== */ :root { /* Primary Colors - Entwickler Blau */ --da-primary: #3b82f6; --da-primary-hover: #2563eb; --da-primary-soft: rgba(59, 130, 246, 0.1); /* Background */ --da-bg: #0f172a; --da-surface: #1e293b; --da-surface-elevated: #334155; /* Borders */ --da-border: #475569; --da-border-subtle: rgba(255, 255, 255, 0.1); /* Text */ --da-text: #e5e7eb; --da-text-muted: #9ca3af; /* Status Colors */ --da-danger: #ef4444; --da-warning: #f59e0b; --da-success: #22c55e; --da-info: #3b82f6; /* Sidebar */ --sidebar-width: 260px; } /* Light Theme */ [data-theme="light"] { --da-bg: #f8fafc; --da-surface: #ffffff; --da-surface-elevated: #f1f5f9; --da-border: #e2e8f0; --da-border-subtle: rgba(0, 0, 0, 0.1); --da-text: #1e293b; --da-text-muted: #64748b; } /* ========================================== RESET & BASE ========================================== */ * { box-sizing: border-box; margin: 0; padding: 0; } body { font-family: 'JetBrains Mono', 'SF Mono', 'Monaco', monospace; background: var(--da-bg); color: var(--da-text); min-height: 100vh; line-height: 1.5; } /* ========================================== LAYOUT ========================================== */ .dev-admin-root { display: flex; min-height: 100vh; } /* Sidebar */ .dev-admin-sidebar { width: var(--sidebar-width); background: var(--da-surface); border-right: 1px solid var(--da-border); position: fixed; top: 0; left: 0; height: 100vh; overflow-y: auto; z-index: 100; } .dev-admin-sidebar-header { padding: 20px; border-bottom: 1px solid var(--da-border); } .dev-admin-brand { display: flex; align-items: center; gap: 12px; } .dev-admin-logo { width: 40px; height: 40px; background: linear-gradient(135deg, #3b82f6, #8b5cf6); border-radius: 8px; display: flex; align-items: center; justify-content: center; font-size: 20px; } .dev-admin-title { font-size: 16px; font-weight: 700; color: var(--da-text); } .dev-admin-subtitle { font-size: 11px; color: var(--da-text-muted); } /* Sidebar Navigation */ .dev-admin-nav { padding: 16px 12px; } .dev-admin-nav-section { margin-bottom: 24px; } .dev-admin-nav-label { font-size: 10px; text-transform: uppercase; letter-spacing: 1px; color: var(--da-text-muted); padding: 0 8px; margin-bottom: 8px; } .dev-admin-nav-item { display: flex; align-items: center; gap: 12px; padding: 10px 12px; border-radius: 8px; color: var(--da-text-muted); cursor: pointer; transition: all 0.2s ease; font-size: 13px; } .dev-admin-nav-item:hover { background: var(--da-surface-elevated); color: var(--da-text); } .dev-admin-nav-item.active { background: var(--da-primary-soft); color: var(--da-primary); } .dev-admin-nav-icon { font-size: 18px; width: 24px; text-align: center; } .dev-admin-nav-badge { margin-left: auto; padding: 2px 8px; font-size: 10px; border-radius: 10px; background: var(--da-primary-soft); color: var(--da-primary); } /* Main Content */ .dev-admin-main { flex: 1; margin-left: var(--sidebar-width); padding: 24px; min-height: 100vh; } /* Header */ .dev-admin-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 24px; padding-bottom: 16px; border-bottom: 1px solid var(--da-border); } .dev-admin-header h1 { font-size: 24px; font-weight: 600; } .dev-admin-header-actions { display: flex; gap: 12px; align-items: center; } /* Theme Toggle */ .theme-toggle-dev { width: 40px; height: 40px; border-radius: 8px; border: 1px solid var(--da-border); background: var(--da-surface); color: var(--da-text); cursor: pointer; display: flex; align-items: center; justify-content: center; font-size: 18px; transition: all 0.2s ease; } .theme-toggle-dev:hover { background: var(--da-surface-elevated); border-color: var(--da-primary); } /* Panels */ .dev-admin-panel { display: none; } .dev-admin-panel.active { display: block; } /* Back Link */ .dev-admin-back { display: flex; align-items: center; gap: 8px; color: var(--da-text-muted); text-decoration: none; font-size: 13px; padding: 8px 12px; margin: 16px 12px; border-radius: 8px; transition: all 0.2s ease; } .dev-admin-back:hover { background: var(--da-surface-elevated); color: var(--da-text); } /* ========================================== LOGS STYLES ========================================== */ .log-controls { display: flex; gap: 12px; align-items: center; } .log-controls select { padding: 8px 12px; border-radius: 6px; border: 1px solid var(--da-border); background: var(--da-surface); color: var(--da-text); font-size: 13px; } .logs-list { font-family: 'JetBrains Mono', monospace; font-size: 12px; max-height: 500px; overflow-y: auto; } .log-entry { display: flex; gap: 12px; padding: 8px 12px; border-bottom: 1px solid var(--da-border-subtle); align-items: baseline; } .log-entry:hover { background: var(--da-surface-elevated); } .log-time { color: var(--da-text-muted); min-width: 80px; } .log-level { padding: 2px 8px; border-radius: 4px; font-size: 10px; font-weight: 600; min-width: 60px; text-align: center; } .log-error .log-level { background: rgba(239, 68, 68, 0.2); color: #ef4444; } .log-warning .log-level { background: rgba(245, 158, 11, 0.2); color: #f59e0b; } .log-info .log-level { background: rgba(59, 130, 246, 0.2); color: #3b82f6; } .log-debug .log-level { background: rgba(156, 163, 175, 0.2); color: #9ca3af; } .log-service { color: var(--da-primary); min-width: 120px; } .log-message { color: var(--da-text); flex: 1; } /* ========================================== METRICS STYLES ========================================== */ .metrics-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 16px; } .metric-card { background: var(--da-surface-elevated); border-radius: 12px; padding: 20px; position: relative; } .metric-name { font-size: 12px; color: var(--da-text-muted); margin-bottom: 8px; } .metric-value { font-size: 28px; font-weight: 700; color: var(--da-text); } .metric-unit { font-size: 14px; font-weight: 400; color: var(--da-text-muted); } .metric-trend { position: absolute; top: 16px; right: 16px; font-size: 16px; } .trend-up { color: #22c55e; } .trend-down { color: #ef4444; } .trend-stable { color: var(--da-text-muted); } /* ========================================== CONTAINERS STYLES ========================================== */ .containers-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 16px; } .container-card { background: var(--da-surface-elevated); border-radius: 12px; padding: 16px; border-left: 4px solid var(--da-success); } .container-card.status-unhealthy { border-left-color: var(--da-danger); } .container-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; } .container-name { font-weight: 600; font-size: 14px; color: var(--da-text); } .container-status { font-size: 12px; color: var(--da-success); } .status-unhealthy .container-status { color: var(--da-danger); } .container-stats { display: flex; gap: 16px; } .container-stats .stat { flex: 1; text-align: center; } .container-stats .stat-label { display: block; font-size: 10px; color: var(--da-text-muted); text-transform: uppercase; margin-bottom: 4px; } .container-stats .stat-value { font-size: 14px; font-weight: 600; color: var(--da-text); } /* ========================================== SERVICES STYLES ========================================== */ .services-list { display: flex; flex-direction: column; gap: 12px; } .service-row { display: grid; grid-template-columns: 200px 1fr 100px; gap: 16px; align-items: center; padding: 16px; background: var(--da-surface-elevated); border-radius: 8px; border-left: 4px solid var(--da-success); } .service-row.status-unhealthy { border-left-color: var(--da-danger); } .service-info { display: flex; align-items: center; gap: 12px; } .service-status { font-size: 16px; } .status-healthy .service-status { color: var(--da-success); } .status-unhealthy .service-status { color: var(--da-danger); } .service-name { font-weight: 600; color: var(--da-text); } .service-url { font-family: 'JetBrains Mono', monospace; font-size: 12px; color: var(--da-text-muted); } .service-response { font-weight: 600; text-align: right; } .response-fast { color: var(--da-success); } .response-medium { color: var(--da-warning); } .response-slow { color: var(--da-danger); } /* ========================================== SBOM EXTRAS ========================================== */ .stat-card { background: var(--da-surface-elevated); border-radius: 8px; padding: 16px; text-align: center; } .stat-card .stat-value { font-size: 24px; font-weight: 700; color: var(--da-primary); } .stat-card .stat-label { font-size: 11px; color: var(--da-text-muted); text-transform: uppercase; margin-top: 4px; } .license-badge { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 11px; background: var(--da-primary-soft); color: var(--da-primary); } """ def get_dev_admin_html() -> str: """HTML-Struktur fuer das Developer Admin Frontend.""" return """
Vollstaendige Liste aller Abhaengigkeiten und deren Versionen.
| Name | Version | Typ | Lizenz | PURL | '; html += '
|---|---|---|---|---|
| ' + (comp.name || '-') + ' | '; html += '' + (comp.version || '-') + ' | ';
html += '' + (comp.type || '-') + ' | '; html += '' + license + ' | '; html += '' + (comp.purl || '-') + ' | '; html += '
'; html += 'Zeige 100 von ' + data.components.length + ' Komponenten
'; } container.innerHTML = html; } else { container.innerHTML = 'Keine SBOM-Daten verfuegbar. Fuehren Sie "syft" aus.
'; } }) .catch(err => { container.innerHTML = 'Fehler beim Laden: ' + err.message + '
'; }); } async function runScan(scanType) { const resultsDiv = document.getElementById('scan-results'); resultsDiv.innerHTML = 'Keine Logs gefunden.
'; return; } let html = 'Fehler: ' + err.message + '
'; }); } // =================== // METRICS DASHBOARD // =================== function loadMetrics() { const container = document.getElementById('metrics-content'); container.innerHTML = 'Fehler: ' + err.message + '
'; }); } // =================== // CONTAINER STATUS // =================== function loadContainers() { const container = document.getElementById('containers-content'); container.innerHTML = 'Fehler: ' + err.message + '
'; }); } // =================== // SERVICE HEALTH // =================== function loadServices() { const container = document.getElementById('services-content'); container.innerHTML = 'Fehler: ' + err.message + '
'; }); } // Initialisierung beim Laden document.addEventListener('DOMContentLoaded', function() { // Theme aus localStorage laden const savedTheme = localStorage.getItem('dev-admin-theme'); if (savedTheme) { document.documentElement.setAttribute('data-theme', savedTheme); } // Security Dashboard initialisieren if (typeof SecurityDashboard !== 'undefined') { SecurityDashboard.init(); } }); """ @router.get("/dev-admin", response_class=HTMLResponse) def dev_admin_ui(): """ Rendert das Developer Admin Frontend. Enthaelt: - Security Dashboard (DevSecOps) - SBOM Viewer - Security Scans - Logs (geplant) - Metrics (geplant) - Container Status (geplant) - Service Health (geplant) """ # CSS zusammenfuegen all_css = get_dev_admin_css() + "\n" + SecurityModule.get_css() # Security-Modul HTML (ohne eigenen Container, wird in Panel eingebettet) security_html = SecurityModule.get_html() # JavaScript zusammenfuegen all_js = get_dev_admin_js() + "\n" + SecurityModule.get_js() # HTML Template fuellen html = get_dev_admin_html() html = html.replace("{css}", all_css) html = html.replace("{security_content}", security_html) html = html.replace("{js}", all_js) return html