Files
insight-updater/PROMPT.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.2 KiB

Insight Updater - Project Prompt

Overview

Build a self-hosted update orchestration tool for Windows (CAU/WSUS) and Linux servers via WinRM/SSH. Web UI to manage servers, trigger updates, monitor progress live via WebSocket.

Target Stack

  • Backend: FastAPI + Python 3.11+, SQLAlchemy + SQLite/PostgreSQL, structlog, python-winrm, paramiko
  • Frontend: Vue 3 + TypeScript + Vite, Pinia, VueUse, Tailwind CSS, Socket.io client
  • Infra: Docker Compose (backend, frontend, db, redis), Traefik labels for reverse proxy
  • CI/CD: Gitea Actions / Woodpecker CI for build & deploy to monitoring (10.0.2.105)

Core Features

  1. Server Inventory - Add/edit/delete servers (Windows/WinRM, Linux/SSH, CAU-Cluster)
  2. Live Update Streaming - WebSocket log stream with progress, status per node
  3. CAU Cluster Orchestration - Trigger Invoke-CauRun, show per-node phases
  4. Linux Patch Management - apt/dnf/yum update via SSH with sudo
  5. Audit Log - Structured JSON logs: who, when, what server, outcome
  6. Health Checks - /health endpoint, WinRM/SSH connectivity test
  7. LDAP-ready Auth - JWT tokens, LDAP config schema prepared, local admin fallback

Non-Goals

  • No WSUS/SCCM replacement, no approval workflows
  • No agent deployment (agentless WinRM/SSH only)
  • No multi-tenancy / RBAC beyond admin/user

Success Criteria

  • Add server → see "Online/Offline", last patch date
  • Click "Update" → live WebSocket log stream → final status Success/Failed
  • CAU: Trigger cluster update, see per-node Pre/Post/Reboot phases
  • Linux: Add SSH creds, trigger update, see apt/dnf output
  • docker compose up -d → all healthy in <5 min on fresh VM
  • Deploy to monitoring (10.0.2.105) via git push + CI works
  • LDAP config schema exists, service stub wired, functional later

Verification Commands

curl -f http://localhost:8000/health
curl -f http://localhost:3000/    # frontend
docker compose ps  # all healthy

Deployment Target

  • Host: monitoring.insight.local (10.0.2.105)
  • User: b0rbor4d (sudo via Vaultwarden)
  • Docker: Podman/Docker Compose v2
  • Reverse Proxy: Traefik (labels on compose services)
  • Git Remote: ssh://git@gitea.insight-it.de:2222/b0rbor4d/insight-updater.git

Security

  • Credentials encrypted at rest (Fernet/AES-GCM, key from env)
  • WinRM: NTLM/Kerberos, HTTPS preferred, Cert validation configurable
  • SSH: Key-based auth preferred, password fallback encrypted
  • JWT: RS256, short expiry, refresh token rotation
  • Audit log: immutable append-only (SQLite WAL / PG)

Project Structure

~/projects/insight-updater/
├── backend/
│   ├── app/
│   │   ├── api/          # FastAPI routes
│   │   ├── core/         # config, security, db
│   │   ├── models/       # SQLAlchemy models
│   │   ├── schemas/      # Pydantic schemas
│   │   ├── services/     # business logic (winrm, ssh, cau, audit)
│   │   ├── websocket/    # Socket.io / FastAPI WS handlers
│   │   └── main.py
│   ├── tests/
│   ├── Dockerfile
│   ├── requirements.txt
│   └── pyproject.toml
├── frontend/
│   ├── src/
│   │   ├── components/
│   │   ├── views/
│   │   ├── stores/
│   │   ├── api/
│   │   └── main.ts
│   ├── Dockerfile
│   ├── package.json
│   └── vite.config.ts
├── docker-compose.yml
├── docker-compose.prod.yml
├── .env.example
├── .gitignore
├── README.md
├── AGENTS.md
└── PROMPT.md

Key Libraries

  • fastapi, uvicorn, sqlalchemy[asyncio], alembic
  • python-winrm[kerberos], paramiko, asyncssh
  • python-socketio[asyncio], redis, structlog
  • cryptography, python-jose[cryptography], passlib[bcrypt]
  • pydantic-settings, pydantic[email]
  • pytest, pytest-asyncio, httpx

Environment Variables (.env.example)

# Core
APP_ENV=development
SECRET_KEY=change-me-32-chars-min
ENCRYPTION_KEY=change-me-32-chars-base64
JWT_ALGORITHM=RS256
JWT_PRIVATE_KEY_PATH=/app/keys/private.pem
JWT_PUBLIC_KEY_PATH=/app/keys/public.pem

# Database
DATABASE_URL=sqlite+aiosqlite:///./data/app.db
# DATABASE_URL=postgresql+asyncpg://user:pass@db:5432/updater

# Redis
REDIS_URL=redis://redis:6379/0

# WinRM
WINRM_TRANSPORT=ntlm
WINRM_CERT_VALIDATION=ignore

# LDAP (stub)
LDAP_ENABLED=false
LDAP_URI=ldaps://dc.insight.local:636
LDAP_BIND_DN=CN=svc_updater,OU=Services,DC=insight,DC=local
LDAP_BIND_PASSWORD=
LDAP_USER_SEARCH_BASE=OU=Users,DC=insight,DC=local
LDAP_USER_FILTER=(sAMAccountName={username})

# Frontend
VITE_API_URL=http://localhost:8000
VITE_WS_URL=ws://localhost:8000

Development Workflow

# Local dev
cd backend && pip install -e . && uvicorn app.main:app --reload
cd frontend && npm install && npm run dev

# Docker dev
docker compose up -d --build

# Tests
cd backend && pytest
cd frontend && npm run test

Remote Deploy (monitoring)

# 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