feat: rename to FabledScryer, multi-dashboard system, plugin management, branding
- Rename package fablednetmon → fabledscryer throughout - Multi-dashboard: ownership, per-user defaults, HTMX edit (add/remove/reorder) - Read-only share tokens scoped to individual dashboards - Dashboard edit is HTMX-driven (no page reloads) - Plugin management system: remote catalog, download/install, hot-reload, in-app restart - plugin_index.py: fetch/cache remote index.yaml; default URL → bvandeusen/fabledscryer-plugins - plugin_manager.py: download_and_install_plugin, hot_reload_plugin, restart_app - ZIP extraction handles GitHub archive formats (name-v1.0.0/, name-main/) - Settings split into tabbed sections: General, Notifications, Ansible, Plugins - Plugins tab: catalog browser (HTMX), install/activate/update/restart actions - UI/branding: dark palette (#07071a), crystal ball SVG logo, animated star field, Libertinus Serif applied to headings, nav, labels, and section titles - Widget registry (core/widgets.py) for dashboard plugin integration - UPS widget.html (dashboard card) and settings/_tabs.html include - Migrations 0005–0008: dashboards, is_default, ownership, share tokens - docs/plugins/: writing-a-plugin.md updated with publishing guide, index.yaml.example template for fabledscryer-plugins repo Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
# Configuration
|
||||
|
||||
Fabled Scryer uses a two-layer configuration system. Only the bare minimum needed to boot lives in files or environment variables. Everything else is stored in the database and managed through the Settings UI.
|
||||
|
||||
---
|
||||
|
||||
## Bootstrap Config (File / Env Vars)
|
||||
|
||||
These three values are read at startup from `config.yaml` and/or environment variables:
|
||||
|
||||
| Key | Env var | Default | Description |
|
||||
|---|---|---|---|
|
||||
| `database.url` | `FABLEDSCRYER_DATABASE_URL` | — | PostgreSQL async URL. **Required.** |
|
||||
| `secret_key` | `FABLEDSCRYER_SECRET_KEY` | auto-generated | Flask/Quart session signing key. Auto-generated and saved to `/data/secret.key` if not set. |
|
||||
| `plugin_dir` | `FABLEDSCRYER_PLUGIN_DIR` | `plugins` | Path to the plugins directory. |
|
||||
|
||||
**Resolution order for `database_url`:** env var `FABLEDSCRYER_DATABASE_URL` → env var `FABLEDSCRYER_DATABASE__URL` (legacy double-underscore) → `database.url` in `config.yaml`.
|
||||
|
||||
**Resolution order for `secret_key`:** env var `FABLEDSCRYER_SECRET_KEY` → `secret_key` in `config.yaml` → `/data/secret.key` file → auto-generate and write to `/data/secret.key`.
|
||||
|
||||
### Minimal config.yaml
|
||||
|
||||
```yaml
|
||||
database:
|
||||
url: "postgresql+asyncpg://user:password@localhost/fabledscryer"
|
||||
```
|
||||
|
||||
### Minimal env-only setup (Docker)
|
||||
|
||||
```bash
|
||||
FABLEDSCRYER_DATABASE_URL=postgresql+asyncpg://user:password@db/fabledscryer
|
||||
```
|
||||
|
||||
A `.env` file is loaded automatically if present.
|
||||
|
||||
---
|
||||
|
||||
## App Settings (Database-backed)
|
||||
|
||||
All runtime settings are stored in the `app_settings` table and editable through the web UI at `/settings/`. They are loaded into `app.config` at startup.
|
||||
|
||||
### All Settings and Defaults
|
||||
|
||||
| Key | Default | Description |
|
||||
|---|---|---|
|
||||
| `session.lifetime_hours` | `8` | How long a login session lasts |
|
||||
| `data.retention_days` | `90` | How many days of ping/DNS/metric/ansible history to keep |
|
||||
| `monitors.poll_interval_seconds` | `60` | How often ping and DNS checks run |
|
||||
| `smtp.host` | `""` | SMTP server hostname |
|
||||
| `smtp.port` | `587` | SMTP server port |
|
||||
| `smtp.tls` | `true` | Use STARTTLS |
|
||||
| `smtp.username` | `""` | SMTP login username |
|
||||
| `smtp.password` | `""` | SMTP login password |
|
||||
| `smtp.recipients` | `[]` | List of email addresses to notify |
|
||||
| `webhook.url` | `""` | Webhook POST destination URL |
|
||||
| `webhook.template` | see below | Jinja2 JSON template for webhook body |
|
||||
| `ansible.sources` | `[]` | List of playbook source definitions |
|
||||
| `ping.threshold.good_ms` | `50` | Latency below this is shown green in the ping UI |
|
||||
| `ping.threshold.warn_ms` | `200` | Latency below this is shown yellow; above is orange |
|
||||
|
||||
Default webhook template:
|
||||
```
|
||||
{"content": "**{{ alert.state }}** — {{ alert.resource }} — {{ alert.rule_name }} ({{ alert.metric }} = {{ alert.value }})"}
|
||||
```
|
||||
|
||||
### Reading and Writing Settings in Code
|
||||
|
||||
```python
|
||||
from fabledscryer.core.settings import get_setting, set_setting
|
||||
|
||||
# Read
|
||||
async with current_app.db_sessionmaker() as session:
|
||||
host = await get_setting(session, "smtp.host")
|
||||
|
||||
# Write (must be inside a transaction)
|
||||
async with current_app.db_sessionmaker() as session:
|
||||
async with session.begin():
|
||||
await set_setting(session, "smtp.host", "mail.example.com")
|
||||
```
|
||||
|
||||
`get_setting()` returns the stored value or the default from `DEFAULTS` if the key has never been set.
|
||||
|
||||
### The DEFAULTS Dict
|
||||
|
||||
`fabledscryer/core/settings.py` contains the `DEFAULTS` dict — the canonical list of all recognised settings and their default values. Add new settings here to make them recognised by `get_all_settings()` and the settings UI.
|
||||
|
||||
---
|
||||
|
||||
## app.config Keys
|
||||
|
||||
After startup, `app.config` contains these additional keys (in addition to standard Quart keys):
|
||||
|
||||
| Key | Type | Source |
|
||||
|---|---|---|
|
||||
| `DATABASE_URL` | str | Bootstrap |
|
||||
| `PLUGIN_DIR` | str | Bootstrap |
|
||||
| `SESSION_LIFETIME_HOURS` | int | DB settings |
|
||||
| `DATA_RETENTION_DAYS` | int | DB settings |
|
||||
| `MONITORS_POLL_INTERVAL` | int | DB settings |
|
||||
| `SMTP` | dict | DB settings, via `to_smtp_cfg()` |
|
||||
| `WEBHOOK` | dict | DB settings, via `to_webhook_cfg()` |
|
||||
| `ANSIBLE` | dict | DB settings, via `to_ansible_cfg()` |
|
||||
| `PLUGINS` | dict | DB settings + plugin.yaml defaults, keyed by plugin name |
|
||||
Reference in New Issue
Block a user