feat: initial itpp-docs setup with MkDocs Material
Publish Docs Site / build (push) Failing after 5s
Publish Docs Site / build (push) Failing after 5s
- mkdocs.yml with dark slate theme, nav for 12 ITPP projects - build-docs.sh aggregates docs from all project repos - .gitea/workflows/docs-publish.yml for nightly rebuild+deploy - README and CHANGELOG for the itpp-docs repo itself - docs-source/ populated from all 12 repos - site/ ready for deployment to docs.itpropartner.com
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
# Ops Portal — Architecture
|
||||
|
||||
## Topology
|
||||
|
||||
```
|
||||
INTERNET
|
||||
|
|
||||
[Caddy :443]
|
||||
|
|
||||
Core (152.53.192.33)
|
||||
|
|
||||
+---------------+---------------+
|
||||
| | |
|
||||
/api/* :8090 /data/* :files /static/*
|
||||
| | |
|
||||
[FastAPI app] ops-status.json [HTML/CSS/JS]
|
||||
server.py /var/www/ops/ /opt/ops-portal/
|
||||
| /data/ static/
|
||||
|
|
||||
+-------+-------+-------+-------+
|
||||
| | | | |
|
||||
S3 API UISP Wazuh Bitdef systemd
|
||||
(Wasabi) (FFW) (app1) (Cloud) (Core)
|
||||
```
|
||||
|
||||
## Data Flow
|
||||
|
||||
```
|
||||
[Collector] [Dashboard]
|
||||
| |
|
||||
|-- python3 ops-data- |
|
||||
| collector.py |
|
||||
| |
|
||||
v |
|
||||
S3 buckets ----+ |
|
||||
UISP API ------+---> ops-status |
|
||||
Wazuh API -----+ .json ------> GET /api/status
|
||||
Bitdefender ---+ |
|
||||
systemd -------+ |
|
||||
cron jobs -----+ |
|
||||
v
|
||||
[Browser renders
|
||||
health grid,
|
||||
widgets, alerts]
|
||||
```
|
||||
|
||||
## Components
|
||||
|
||||
### 1. Collector (`/root/.hermes/scripts/ops-data-collector.py`)
|
||||
- Runs every 5 min via cron
|
||||
- Gathers: S3 backup status (6 buckets), UISP devices (90), Wazuh agents/alerts, Bitdefender endpoints, systemd services, cron jobs, server health, disk/memory/CPU
|
||||
- Timeout: 90s (was 20s — too short for 94K-file S3 bucket)
|
||||
- Output: `/var/www/ops/data/ops-status.json`
|
||||
|
||||
### 2. Backend (`/opt/ops-portal/server.py`)
|
||||
- FastAPI on port 8090
|
||||
- 7 API endpoints (health, status, servers, servers/health, audit-log, ft360/status)
|
||||
- JWT auth from `/root/.hermes/.env` (ADMIN_USERNAME, ADMIN_PASSWORD, JWT_SECRET)
|
||||
- Critical service restart protection (hermes, caddy, ops-portal blocked)
|
||||
- Systemd: `ops-portal.service`
|
||||
|
||||
### 3. Frontend (`/opt/ops-portal/static/`)
|
||||
- 11 HTML pages with shared ops.css, app.js, utils.js
|
||||
- Auth: login overlay → localStorage JWT → all API calls Bearer
|
||||
- Auto-refresh: 60s interval + tab visibility API
|
||||
- Mobile: hamburger toggle with .nav-links.open CSS
|
||||
- Cache-busting: all assets versioned with timestamps
|
||||
|
||||
### 4. Proxy (Caddy on Core)
|
||||
- `/` and `/*.html` → static file server from `/opt/ops-portal/static/`
|
||||
- `/api/*` → reverse_proxy to 127.0.0.1:8090
|
||||
- `/data/*` → file server from `/var/www/ops/data/`
|
||||
- Domain: ops.itpropartner.com
|
||||
|
||||
## Cross-Service Dependencies
|
||||
|
||||
| Dependency | Server | Purpose | Fallback |
|
||||
|---|---|---|---|
|
||||
| Wasabi S3 | External | Backup bucket status | Shows "Issues" |
|
||||
| UISP API | unms.forefrontwireless.com | Device/site count | Shows 0 devices |
|
||||
| Wazuh | app1 (152.53.36.131) | Agent count, alerts | Shows "Offline" |
|
||||
| Bitdefender | External API | Endpoint monitoring | Shows "Offline" |
|
||||
| Traccar | app2 (152.53.39.202) | FleetTracker data | Dedicated endpoint |
|
||||
| Core systemd | Local | Service health, disk, memory | N/A (local) |
|
||||
|
||||
## Auth Flow
|
||||
|
||||
```
|
||||
Browser Server
|
||||
| |
|
||||
|-- POST /api/auth/login ->|
|
||||
| {username, password} |
|
||||
| |-- Validate against ADMIN_USERNAME/ADMIN_PASSWORD
|
||||
| |-- Generate JWT with JWT_SECRET
|
||||
|<- {access_token} --------|
|
||||
| |
|
||||
|-- GET /api/status ------->|
|
||||
| Authorization: Bearer |
|
||||
| |-- Verify JWT
|
||||
| |-- Read ops-status.json
|
||||
|<- {full dashboard} ------|
|
||||
```
|
||||
|
||||
## Key Design Decisions
|
||||
|
||||
1. **Collector pattern over direct API calls:** Dashboard fetches one JSON blob rather than 6 separate APIs. Single point of failure but fast rendering and offline-capable (shows last-cached data).
|
||||
|
||||
2. **Python/FastAPI over Node:** Already have Python toolchain on Core. FastAPI is lightweight, async-native, and the ops portal is read-heavy with minimal write paths.
|
||||
|
||||
3. **Static HTML + vanilla JS over React/Vue:** 11-page dashboard with no SPA routing. Auth via localStorage JWT. Zero build step, zero dependencies beyond ops.css.
|
||||
|
||||
4. **JWT over session cookies:** Cross-page auth without server-side session state. Token survives page navigations and ops-portal restarts (persistent JWT_SECRET in .env).
|
||||
@@ -0,0 +1,39 @@
|
||||
# Ops Portal Changelog
|
||||
|
||||
## 2026-07-20 — Major audit and fix session
|
||||
|
||||
### Fixed
|
||||
- **`/api/health` returning 404:** Caddy `handle_path` was stripping the path → changed to `handle`, port corrected to 8090
|
||||
- **`/api/servers` returning null:** Server list now returns all 5 servers with live ping health
|
||||
- **Server IPs stale:** app1-bu updated to 5.161.225.131, legacy entries removed
|
||||
- **Page titles inconsistent:** All 11 pages standardized to "X — IT Pro Partner Ops" format
|
||||
- **Missing nav icons:** All 11 nav items now have SVG icons
|
||||
- **FleetTracker360 missing from nav:** Added to navigation with car icon
|
||||
- **Backups page no data:** `s3_buckets` → `s3_backups` key fix
|
||||
- **FleetTracker360 page no nav:** Added ops.css, app.js, utils.js includes
|
||||
- **Network page dark sidebar:** Replaced with standard top nav bar
|
||||
- **Cache-busting broken:** All JS/CSS references now versioned with timestamps
|
||||
- **Mobile nav broken:** `.nav-links.open` CSS rule missing → hamburger menu now toggles properly on iOS/Android
|
||||
- **Auth guard race condition:** IIFE scripts replaced with DOMContentLoaded event listeners — pages now load data when user is authenticated
|
||||
- **Cost page broken:** Missing `loadData` function → defined and wired
|
||||
- **Dependency diagram 404:** File copied to static dir, link corrected
|
||||
- **Logs page mangled title:** Triple-nested `<title>` tags from sed accident → cleaned
|
||||
- **Config page scripts directory:** Now populates directory listing when clicked
|
||||
- **Services page:** Server column added showing "Core (152.53.192.33)"
|
||||
- **Dashboard auto-refresh on tab focus:** Visibility API handler added
|
||||
- **Critical service protection:** hermes, caddy, ops-portal restarts blocked via API
|
||||
|
||||
### Removed
|
||||
- Duplicate server entries: "app1 (AI Stack)" and "Docker Box (legacy)"
|
||||
- Server count: 7 → 5 clean entries
|
||||
|
||||
### Changed
|
||||
- Admin credentials: germaine/itpp2026! → ippadmin (password → Vaultwarden)
|
||||
- JWT_SECRET made persistent in /root/.hermes/.env to survive restarts
|
||||
- Collector timeout: 20s → 90s to handle 94K-file S3 bucket scanning
|
||||
|
||||
## Jul 17, 2026 — Initial deployment
|
||||
- Ops portal deployed on Core as FastAPI app
|
||||
- Caddy reverse proxy configured
|
||||
- 10 HTML pages created
|
||||
- Ops collector built for S3, system health, server status
|
||||
@@ -0,0 +1,55 @@
|
||||
# Ops Portal — ops.itpropartner.com
|
||||
|
||||
## Architecture
|
||||
- **Server:** Core (152.53.192.33, netcup RS 2000)
|
||||
- **Backend:** FastAPI at `/opt/ops-portal/server.py` (port 8090)
|
||||
- **Proxy:** Caddy → reverse_proxy to 127.0.0.1:8090
|
||||
- **Static files:** `/opt/ops-portal/static/` — 11 HTML pages, ops.css, app.js, utils.js
|
||||
- **Auth:** JWT via `POST /api/auth/login`, token in localStorage
|
||||
- **Data:** `/var/www/ops/data/ops-status.json` (5-min collector refresh)
|
||||
- **Collector:** `/root/.hermes/scripts/ops-data-collector.py` — Wazuh, Bitdefender, S3, UISP, system health
|
||||
- **Systemd:** `ops-portal.service`, env from `/root/.hermes/.env`
|
||||
- **Credentials:** ippadmin (password → Vaultwarden / `~/.hermes/.env`)
|
||||
|
||||
## Pages (11 total)
|
||||
| Page | Path | Description |
|
||||
|------|------|-------------|
|
||||
| Dashboard | / | System health, widgets, audit log |
|
||||
| Services | /services.html | Systemd service control, audit log, server column |
|
||||
| Servers | /servers.html | 5 servers with ping health |
|
||||
| Network | /network.html | UISP data (44 sites, 90 devices), DNS zones |
|
||||
| Backups | /backups.html | S3 bucket status (6 buckets) |
|
||||
| FleetTracker | /fleettracker360.html | Traccar device tracking |
|
||||
| Cron Jobs | /cron.html | Hermes cron jobs with expandable scripts |
|
||||
| Config | /config.html | Active configs, /root/.hermes/scripts/ listing |
|
||||
| Logs | /logs.html | Aggregated log viewer |
|
||||
| Audit | /audit.html | Full audit trail |
|
||||
| Costs | /cost.html | API cost tracking by model |
|
||||
|
||||
## API Endpoints
|
||||
| Method | Path | Auth | Description |
|
||||
|--------|------|------|-------------|
|
||||
| POST | /api/auth/login | No | JWT authentication |
|
||||
| GET | /api/health | No | Health check, DB status |
|
||||
| GET | /api/status | JWT | Full dashboard data (17 sections) |
|
||||
| GET | /api/servers | JWT | Server list with IPs |
|
||||
| GET | /api/servers/health | JWT | Ping health (all 7 LIVE) |
|
||||
| GET | /api/audit-log?limit=N | JWT | Audit trail entries |
|
||||
| GET | /api/ft360/status | JWT | FleetTracker device data |
|
||||
|
||||
## Critical Services (API restart blocked)
|
||||
hermes, hermes-assistant, hermes-browser, caddy, ops-portal, mysql-tunnel
|
||||
|
||||
## Dashboard Widgets
|
||||
- System Health — Core metrics (jobs, disk, memory, S3, APIs)
|
||||
- Wazuh Security — agent count, alerts
|
||||
- Bitdefender GravityZone — 9 managed endpoints
|
||||
- Alerts and Notifications — DR issues, backup failures, cron errors
|
||||
- Quick Actions — Restart Ops Portal
|
||||
|
||||
## Recovery
|
||||
```
|
||||
systemctl restart ops-portal
|
||||
systemctl reload caddy
|
||||
python3 /root/.hermes/scripts/ops-data-collector.py
|
||||
```
|
||||
Reference in New Issue
Block a user