Files
insight-updater/AGENTS.md
T
B0rbor4d cf7c29639c Initial scaffold: FastAPI backend + Vue 3 frontend + Docker setup
Backend: config/db/security/logging core, SQLAlchemy models (Server,
Credential, UpdateJob, UpdateLog, AuditLog, User), services (winrm, ssh,
cau, audit, job_runner), REST API (auth, servers, updates, audit),
Socket.io WebSocket layer.
Frontend: Vue 3 + TS + Pinia + Tailwind, Views (Dashboard, Servers,
Updates, Audit, Login), axios + socket.io-client, nginx prod config.
2026-07-31 23:45:31 +00:00

5.6 KiB

Insight Updater - Agent Orientation

Project Purpose

Self-hosted update orchestration for Windows (CAU/WSUS) and Linux servers via WinRM/SSH. Web UI to manage inventory, trigger updates, stream live progress via WebSocket.

Quick Start

# Local development
cd ~/projects/insight-updater
docker compose up -d --build

# Backend only
cd backend && pip install -e . && uvicorn app.main:app --reload

# Frontend only
cd frontend && npm install && npm run dev

Architecture Overview

┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│  Frontend   │────▶│   Backend   │────▶│  Database   │
│  (Vue 3)    │ WS  │  (FastAPI)  │     │  (SQLite/   │
│  Port 3000  │◀─── │  Port 8000  │     │   PostgreSQL)│
└─────────────┘     └──────┬──────┘     └─────────────┘
                           │
              ┌────────────┼────────────┐
              ▼            ▼            ▼
         ┌─────────┐  ┌─────────┐  ┌─────────┐
         │  WinRM  │  │   SSH   │  │  CAU    │
         │ Service │  │ Service │  │ Service │
         └─────────┘  └─────────┘  └─────────┘

Key Directories

Path Purpose
backend/app/api/ FastAPI route definitions (REST + WS)
backend/app/core/ Config, security, database, logging
backend/app/models/ SQLAlchemy ORM models
backend/app/schemas/ Pydantic request/response models
backend/app/services/ Business logic: winrm, ssh, cau, audit
backend/app/websocket/ Socket.io handlers for live updates
frontend/src/views/ Page components (Dashboard, Servers, Updates, Audit)
frontend/src/components/ Reusable UI components
frontend/src/stores/ Pinia stores (auth, servers, updates)
frontend/src/api/ Axios/Socket.io client setup

Core Models

Model Description
Server Inventory item: Windows/WinRM, Linux/SSH, CAU-Cluster
Credential Encrypted credentials (WinRM user/pass, SSH key/pass)
UpdateJob One update execution: server, status, started_by, started_at, finished_at
UpdateLog Streamed log lines per job (WebSocket → DB)
AuditLog Immutable audit trail: user, action, target, result
User Local admin or LDAP-mapped user

Key Services

Service File Responsibility
WinRMService services/winrm.py Connect, run PS commands, stream output
SSHService services/ssh.py Connect, run commands, sudo handling
CAUService services/cau.py Invoke-CauRun, cluster status, node phases
AuditService services/audit.py Structured logging to DB + JSON file
EncryptionService core/security.py Fernet encrypt/decrypt credentials

WebSocket Events

Event Direction Payload
job:start Server→Client {job_id, server_id, type}
job:log Server→Client {job_id, line, timestamp, level}
job:progress Server→Client {job_id, percent, phase, node?}
job:complete Server→Client {job_id, status, duration}
job:cancel Client→Server {job_id}

API Endpoints (Key)

Method Path Description
GET /api/servers List all servers
POST /api/servers Create server
GET /api/servers/{id}/health Test WinRM/SSH connectivity
POST /api/updates/trigger Start update job
GET /api/updates/{job_id}/logs Get job logs (REST fallback)
WS /ws/updates Socket.io connection
GET /api/audit Paginated audit log
POST /api/auth/login JWT login
GET /health Health check

Environment Variables

See .env.example — key ones:

  • DATABASE_URL — SQLite (dev) or PostgreSQL (prod)
  • SECRET_KEY — JWT signing (32+ chars)
  • ENCRYPTION_KEY — Fernet key for credentials (32 bytes base64)
  • WINRM_TRANSPORTntlm | kerberos | credssp
  • LDAP_ENABLEDtrue/false (stub)

Testing

# Backend
cd backend && pytest -v

# Frontend
cd frontend && npm run test

# E2E (Playwright)
cd frontend && npm run test:e2e

Deployment

Target: monitoring (10.0.2.105)
User: b0rbor4d (sudo via Vaultwarden)
Reverse Proxy: Traefik (Docker labels)
Git Remote: ssh://git@gitea.insight-it.de:2222/b0rbor4d/insight-updater.git

# On monitoring host
git clone ssh://git@gitea.insight-it.de:2222/b0rbor4d/insight-updater.git
cd insight-updater
cp .env.example .env  # fill secrets
docker compose -f docker-compose.prod.yml up -d --build

Useful Commands

# DB migrations
cd backend && alembic upgrade head

# Generate keys
openssl genrsa -out keys/private.pem 2048
openssl rsa -in keys/private.pem -pubout -out keys/public.pem

# Encrypt a test credential
python -c "from app.core.security import encrypt; print(encrypt('secret'))"

Conventions

  • Language: German for user-facing text, English for code/comments
  • Logging: structlog JSON, level from LOG_LEVEL env
  • Errors: Custom exceptions in core/exceptions.py, mapped to HTTP in main.py
  • Async: All I/O async (asyncpg, asyncssh, httpx)
  • Types: Strict mypy, Pydantic v2, SQLAlchemy 2.0