fix(plugins): complete steward rename across bundled plugins; clear lint debt
The fabledscryer->steward rename had only ever reached host_agent. The other five bundled plugins (http, snmp, traefik, unifi, docker) still imported `from fabledscryer.*` (package no longer exists) and read FABLEDSCRYER_* env vars — so every one of them was broken at import since the original rebrand. CI stayed green only because none are enabled by default and migrations don't import plugin modules. Now that they version in-tree, complete the rename: - fabledscryer.* -> steward.* imports across all five plugins - FABLEDSCRYER_* -> STEWARD_* in plugin migration env.py files - author/repository/homepage + user-facing 'Fabled Scryer' strings -> Steward - snmp/scheduler.py: also drop dead `now`/datetime; record_metric from steward Adds tests/test_no_legacy_names.py — fails if 'scryer'/'roundtable' ever reappear in shipped code (the drift bit twice; this stops a third time). Also clears pre-existing ruff lint debt (unused imports, semicolon statements, mid-file import) surfaced by the new lint lane. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -13,8 +13,8 @@ from alembic import context
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent.parent.parent))
|
||||
|
||||
from fabledscryer.models.base import Base
|
||||
import fabledscryer.models # noqa: F401
|
||||
from steward.models.base import Base
|
||||
import steward.models # noqa: F401
|
||||
from plugins.docker.models import DockerContainer, DockerMetric # noqa: F401
|
||||
|
||||
config = context.config
|
||||
@@ -26,14 +26,14 @@ target_metadata = Base.metadata
|
||||
|
||||
def _get_url() -> str:
|
||||
import yaml
|
||||
cfg_path = os.environ.get("FABLEDSCRYER_CONFIG", "config.yaml")
|
||||
cfg_path = os.environ.get("STEWARD_CONFIG", "config.yaml")
|
||||
try:
|
||||
with open(cfg_path) as f:
|
||||
cfg = yaml.safe_load(f) or {}
|
||||
url = cfg.get("database", {}).get("url", "")
|
||||
except FileNotFoundError:
|
||||
url = ""
|
||||
return os.environ.get("FABLEDSCRYER_DATABASE__URL", url)
|
||||
return os.environ.get("STEWARD_DATABASE__URL", url)
|
||||
|
||||
|
||||
def run_migrations_offline() -> None:
|
||||
|
||||
@@ -4,7 +4,7 @@ import uuid
|
||||
from datetime import datetime, timezone
|
||||
from sqlalchemy import DateTime, Float, Integer, String, Text
|
||||
from sqlalchemy.orm import Mapped, mapped_column
|
||||
from fabledscryer.models.base import Base
|
||||
from steward.models.base import Base
|
||||
|
||||
|
||||
class DockerContainer(Base):
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
name: docker
|
||||
version: "1.0.0"
|
||||
description: "Docker container status, resource usage, restart tracking via Docker socket"
|
||||
author: "FabledScryer"
|
||||
author: "Steward"
|
||||
license: "MIT"
|
||||
min_app_version: "0.1.0"
|
||||
repository_url: "https://git.fabledsword.com/bvandeusen/FabledScryer-plugins"
|
||||
homepage: "https://git.fabledsword.com/bvandeusen/FabledScryer-plugins/src/branch/main/docker"
|
||||
repository_url: "https://git.fabledsword.com/bvandeusen/Steward-plugins"
|
||||
homepage: "https://git.fabledsword.com/bvandeusen/Steward-plugins/src/branch/main/docker"
|
||||
tags:
|
||||
- containers
|
||||
- docker
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
# plugins/docker/routes.py
|
||||
from __future__ import annotations
|
||||
import json
|
||||
from datetime import datetime, timezone
|
||||
from quart import Blueprint, current_app, render_template, request
|
||||
from sqlalchemy import Integer, cast, func, select
|
||||
|
||||
from fabledscryer.auth.middleware import require_role
|
||||
from fabledscryer.models.users import UserRole
|
||||
from fabledscryer.core.time_range import parse_range, DEFAULT_RANGE, bucket_seconds
|
||||
from steward.auth.middleware import require_role
|
||||
from steward.models.users import UserRole
|
||||
from steward.core.time_range import parse_range, DEFAULT_RANGE, bucket_seconds
|
||||
from .models import DockerContainer, DockerMetric
|
||||
|
||||
docker_bp = Blueprint("docker", __name__, template_folder="templates")
|
||||
|
||||
@@ -4,8 +4,8 @@ import json
|
||||
import logging
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from fabledscryer.core.scheduler import ScheduledTask
|
||||
from fabledscryer.core.alerts import record_metric
|
||||
from steward.core.scheduler import ScheduledTask
|
||||
from steward.core.alerts import record_metric
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -106,7 +106,6 @@ async def scrape_docker(socket_path: str, include_stopped: bool) -> list[dict]:
|
||||
) from exc
|
||||
|
||||
results = []
|
||||
now = datetime.now(timezone.utc)
|
||||
for container, stats in pairs:
|
||||
names = container.get("Names") or []
|
||||
name = names[0].lstrip("/") if names else _short_id(container.get("Id", ""))
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Docker — Fabled Scryer{% endblock %}
|
||||
{% block title %}Docker — Steward{% endblock %}
|
||||
{% block content %}
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:1.5rem;gap:1rem;flex-wrap:wrap;">
|
||||
<h1 class="page-title" style="margin-bottom:0;">Docker</h1>
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
"""Core HTTP check logic — runs a single monitor check and returns a result dict."""
|
||||
from __future__ import annotations
|
||||
import asyncio
|
||||
import json
|
||||
import logging
|
||||
import ssl
|
||||
import time
|
||||
|
||||
@@ -13,8 +13,8 @@ from alembic import context
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent.parent.parent))
|
||||
|
||||
from fabledscryer.models.base import Base
|
||||
import fabledscryer.models # noqa: F401
|
||||
from steward.models.base import Base
|
||||
import steward.models # noqa: F401
|
||||
from plugins.http.models import HttpMonitor, HttpResult # noqa: F401
|
||||
|
||||
config = context.config
|
||||
@@ -26,14 +26,14 @@ target_metadata = Base.metadata
|
||||
|
||||
def _get_url() -> str:
|
||||
import yaml
|
||||
cfg_path = os.environ.get("FABLEDSCRYER_CONFIG", "config.yaml")
|
||||
cfg_path = os.environ.get("STEWARD_CONFIG", "config.yaml")
|
||||
try:
|
||||
with open(cfg_path) as f:
|
||||
cfg = yaml.safe_load(f) or {}
|
||||
url = cfg.get("database", {}).get("url", "")
|
||||
except FileNotFoundError:
|
||||
url = ""
|
||||
return os.environ.get("FABLEDSCRYER_DATABASE__URL", url)
|
||||
return os.environ.get("STEWARD_DATABASE__URL", url)
|
||||
|
||||
|
||||
def run_migrations_offline() -> None:
|
||||
|
||||
@@ -4,7 +4,7 @@ import uuid
|
||||
from datetime import datetime, timezone
|
||||
from sqlalchemy import Boolean, DateTime, Float, Integer, String, Text
|
||||
from sqlalchemy.orm import Mapped, mapped_column
|
||||
from fabledscryer.models.base import Base
|
||||
from steward.models.base import Base
|
||||
|
||||
|
||||
class HttpMonitor(Base):
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
name: http
|
||||
version: "1.0.0"
|
||||
description: "Synthetic HTTP endpoint monitoring — status code, response time, content match, TLS expiry"
|
||||
author: "FabledScryer"
|
||||
author: "Steward"
|
||||
license: "MIT"
|
||||
min_app_version: "0.1.0"
|
||||
repository_url: "https://git.fabledsword.com/bvandeusen/FabledScryer-plugins"
|
||||
homepage: "https://git.fabledsword.com/bvandeusen/FabledScryer-plugins/src/branch/main/http"
|
||||
repository_url: "https://git.fabledsword.com/bvandeusen/Steward-plugins"
|
||||
homepage: "https://git.fabledsword.com/bvandeusen/Steward-plugins/src/branch/main/http"
|
||||
tags:
|
||||
- monitoring
|
||||
- http
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
# plugins/http/routes.py
|
||||
from __future__ import annotations
|
||||
import json
|
||||
import uuid
|
||||
from datetime import datetime, timezone
|
||||
from quart import Blueprint, current_app, render_template, request, redirect, url_for
|
||||
from sqlalchemy import Integer, cast, func, select
|
||||
|
||||
from fabledscryer.auth.middleware import require_role
|
||||
from fabledscryer.models.users import UserRole
|
||||
from fabledscryer.core.time_range import parse_range, DEFAULT_RANGE, bucket_seconds
|
||||
from steward.auth.middleware import require_role
|
||||
from steward.models.users import UserRole
|
||||
from steward.core.time_range import parse_range, DEFAULT_RANGE, bucket_seconds
|
||||
from .models import HttpMonitor, HttpResult
|
||||
|
||||
http_bp = Blueprint("http", __name__, template_folder="templates")
|
||||
|
||||
@@ -3,10 +3,10 @@ from __future__ import annotations
|
||||
import asyncio
|
||||
import json
|
||||
import logging
|
||||
from datetime import datetime, timezone, timedelta
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from fabledscryer.core.scheduler import ScheduledTask
|
||||
from fabledscryer.core.alerts import record_metric
|
||||
from steward.core.scheduler import ScheduledTask
|
||||
from steward.core.alerts import record_metric
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}HTTP Monitors — Fabled Scryer{% endblock %}
|
||||
{% block title %}HTTP Monitors — Steward{% endblock %}
|
||||
{% block content %}
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:1.5rem;gap:1rem;flex-wrap:wrap;">
|
||||
<h1 class="page-title" style="margin-bottom:0;">HTTP Monitors</h1>
|
||||
|
||||
+22
-22
@@ -1,6 +1,6 @@
|
||||
# fabledscryer-plugins / index.yaml
|
||||
# steward-plugins / index.yaml
|
||||
#
|
||||
# Plugin catalog for Fabled Scryer.
|
||||
# Plugin catalog for Steward.
|
||||
# Fetched by the app at: Settings → Plugins → Plugin Catalog
|
||||
#
|
||||
# After updating an entry, commit and push — changes are live within 5 minutes
|
||||
@@ -16,12 +16,12 @@ plugins:
|
||||
- name: http
|
||||
version: "1.0.0"
|
||||
description: "Synthetic HTTP endpoint monitoring — status code, response time, content match, TLS expiry"
|
||||
author: "FabledScryer"
|
||||
author: "Steward"
|
||||
license: "MIT"
|
||||
min_app_version: "0.1.0"
|
||||
repository_url: "https://git.fabledsword.com/bvandeusen/FabledScryer-plugins"
|
||||
homepage: "https://git.fabledsword.com/bvandeusen/FabledScryer-plugins/src/branch/main/http"
|
||||
download_url: "https://git.fabledsword.com/bvandeusen/FabledScryer-plugins/releases/download/http-v1.0.0/http.zip"
|
||||
repository_url: "https://git.fabledsword.com/bvandeusen/Steward-plugins"
|
||||
homepage: "https://git.fabledsword.com/bvandeusen/Steward-plugins/src/branch/main/http"
|
||||
download_url: "https://git.fabledsword.com/bvandeusen/Steward-plugins/releases/download/http-v1.0.0/http.zip"
|
||||
checksum_sha256: ""
|
||||
tags:
|
||||
- monitoring
|
||||
@@ -32,12 +32,12 @@ plugins:
|
||||
- name: docker
|
||||
version: "1.0.0"
|
||||
description: "Docker container status, resource usage, and restart tracking via Docker socket"
|
||||
author: "FabledScryer"
|
||||
author: "Steward"
|
||||
license: "MIT"
|
||||
min_app_version: "0.1.0"
|
||||
repository_url: "https://git.fabledsword.com/bvandeusen/FabledScryer-plugins"
|
||||
homepage: "https://git.fabledsword.com/bvandeusen/FabledScryer-plugins/src/branch/main/docker"
|
||||
download_url: "https://git.fabledsword.com/bvandeusen/FabledScryer-plugins/releases/download/docker-v1.0.0/docker.zip"
|
||||
repository_url: "https://git.fabledsword.com/bvandeusen/Steward-plugins"
|
||||
homepage: "https://git.fabledsword.com/bvandeusen/Steward-plugins/src/branch/main/docker"
|
||||
download_url: "https://git.fabledsword.com/bvandeusen/Steward-plugins/releases/download/docker-v1.0.0/docker.zip"
|
||||
checksum_sha256: ""
|
||||
tags:
|
||||
- containers
|
||||
@@ -47,12 +47,12 @@ plugins:
|
||||
- name: traefik
|
||||
version: "1.0.0"
|
||||
description: "Traefik reverse proxy metrics and access log integration"
|
||||
author: "FabledScryer"
|
||||
author: "Steward"
|
||||
license: "MIT"
|
||||
min_app_version: "0.1.0"
|
||||
repository_url: "https://git.fabledsword.com/bvandeusen/FabledScryer-plugins"
|
||||
homepage: "https://git.fabledsword.com/bvandeusen/FabledScryer-plugins/src/branch/main/traefik"
|
||||
download_url: "https://git.fabledsword.com/bvandeusen/FabledScryer-plugins/releases/download/traefik-v1.0.0/traefik.zip"
|
||||
repository_url: "https://git.fabledsword.com/bvandeusen/Steward-plugins"
|
||||
homepage: "https://git.fabledsword.com/bvandeusen/Steward-plugins/src/branch/main/traefik"
|
||||
download_url: "https://git.fabledsword.com/bvandeusen/Steward-plugins/releases/download/traefik-v1.0.0/traefik.zip"
|
||||
checksum_sha256: ""
|
||||
tags:
|
||||
- proxy
|
||||
@@ -62,12 +62,12 @@ plugins:
|
||||
- name: unifi
|
||||
version: "1.0.0"
|
||||
description: "UniFi Network controller integration — WAN health, devices, clients, DPI"
|
||||
author: "FabledScryer"
|
||||
author: "Steward"
|
||||
license: "MIT"
|
||||
min_app_version: "0.1.0"
|
||||
repository_url: "https://git.fabledsword.com/bvandeusen/FabledScryer-plugins"
|
||||
homepage: "https://git.fabledsword.com/bvandeusen/FabledScryer-plugins/src/branch/main/unifi"
|
||||
download_url: "https://git.fabledsword.com/bvandeusen/FabledScryer-plugins/releases/download/unifi-v1.0.0/unifi.zip"
|
||||
repository_url: "https://git.fabledsword.com/bvandeusen/Steward-plugins"
|
||||
homepage: "https://git.fabledsword.com/bvandeusen/Steward-plugins/src/branch/main/unifi"
|
||||
download_url: "https://git.fabledsword.com/bvandeusen/Steward-plugins/releases/download/unifi-v1.0.0/unifi.zip"
|
||||
checksum_sha256: ""
|
||||
tags:
|
||||
- network
|
||||
@@ -77,12 +77,12 @@ plugins:
|
||||
- name: ups
|
||||
version: "1.0.0"
|
||||
description: "UPS monitoring via NUT (Network UPS Tools) with Ansible shutdown automation"
|
||||
author: "FabledScryer"
|
||||
author: "Steward"
|
||||
license: "MIT"
|
||||
min_app_version: "0.1.0"
|
||||
repository_url: "https://git.fabledsword.com/bvandeusen/FabledScryer-plugins"
|
||||
homepage: "https://git.fabledsword.com/bvandeusen/FabledScryer-plugins/src/branch/main/ups"
|
||||
download_url: "https://git.fabledsword.com/bvandeusen/FabledScryer-plugins/releases/download/ups-v1.0.0/ups.zip"
|
||||
repository_url: "https://git.fabledsword.com/bvandeusen/Steward-plugins"
|
||||
homepage: "https://git.fabledsword.com/bvandeusen/Steward-plugins/src/branch/main/ups"
|
||||
download_url: "https://git.fabledsword.com/bvandeusen/Steward-plugins/releases/download/ups-v1.0.0/ups.zip"
|
||||
checksum_sha256: ""
|
||||
tags:
|
||||
- ups
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
name: snmp
|
||||
version: "1.0.0"
|
||||
description: "SNMP polling for network devices — switches, routers, printers, UPSes, etc."
|
||||
author: "FabledScryer"
|
||||
author: "Steward"
|
||||
license: "MIT"
|
||||
min_app_version: "0.1.0"
|
||||
repository_url: "https://git.fabledsword.com/bvandeusen/FabledScryer-plugins"
|
||||
homepage: "https://git.fabledsword.com/bvandeusen/FabledScryer-plugins/src/branch/main/snmp"
|
||||
repository_url: "https://git.fabledsword.com/bvandeusen/Steward-plugins"
|
||||
homepage: "https://git.fabledsword.com/bvandeusen/Steward-plugins/src/branch/main/snmp"
|
||||
tags:
|
||||
- snmp
|
||||
- network
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
Synchronous SNMP GET helper, run via executor.
|
||||
|
||||
Requires pysnmp-lextudio (maintained pysnmp fork):
|
||||
pip install 'fabledscryer[snmp]'
|
||||
pip install 'steward[snmp]'
|
||||
|
||||
If pysnmp is not installed, poll_device() returns an empty dict and logs a warning.
|
||||
"""
|
||||
@@ -40,7 +40,7 @@ def poll_device_sync(
|
||||
"""
|
||||
if not _pysnmp_available():
|
||||
logger.warning("pysnmp not installed — SNMP polling disabled. "
|
||||
"Install with: pip install 'fabledscryer[snmp]'")
|
||||
"Install with: pip install 'steward[snmp]'")
|
||||
return {}
|
||||
|
||||
from pysnmp.hlapi import (
|
||||
|
||||
@@ -5,9 +5,9 @@ from datetime import datetime, timedelta, timezone
|
||||
from quart import Blueprint, current_app, render_template, request
|
||||
from sqlalchemy import func, select
|
||||
|
||||
from fabledscryer.auth.middleware import require_role
|
||||
from fabledscryer.models.users import UserRole
|
||||
from fabledscryer.models.metrics import PluginMetric
|
||||
from steward.auth.middleware import require_role
|
||||
from steward.models.users import UserRole
|
||||
from steward.models.metrics import PluginMetric
|
||||
|
||||
snmp_bp = Blueprint("snmp", __name__, template_folder="templates")
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ from typing import TYPE_CHECKING
|
||||
if TYPE_CHECKING:
|
||||
from quart import Quart
|
||||
|
||||
from fabledscryer.core.scheduler import ScheduledTask
|
||||
from steward.core.scheduler import ScheduledTask
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -27,16 +27,14 @@ def make_poll_task(app: "Quart") -> ScheduledTask:
|
||||
|
||||
|
||||
async def _do_poll(app: "Quart") -> None:
|
||||
from datetime import datetime, timezone
|
||||
from .poller import poll_device_sync
|
||||
from fabledscryer.core.alerts import record_metric
|
||||
from steward.core.alerts import record_metric
|
||||
|
||||
devices: list[dict] = app.config["PLUGINS"]["snmp"].get("devices", [])
|
||||
if not devices:
|
||||
return
|
||||
|
||||
loop = asyncio.get_event_loop()
|
||||
now = datetime.now(timezone.utc)
|
||||
|
||||
async with app.db_sessionmaker() as session:
|
||||
async with session.begin():
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{# plugins/snmp/templates/snmp/device.html #}
|
||||
{% extends "base.html" %}
|
||||
{% block title %}SNMP — {{ device_name }} — Fabled Scryer{% endblock %}
|
||||
{% block title %}SNMP — {{ device_name }} — Steward{% endblock %}
|
||||
{% block content %}
|
||||
<div style="display:flex;align-items:center;gap:1rem;margin-bottom:1.5rem;flex-wrap:wrap;">
|
||||
<a href="/plugins/snmp/" style="color:var(--text-muted);font-size:0.85rem;">← SNMP</a>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{# plugins/snmp/templates/snmp/index.html #}
|
||||
{% extends "base.html" %}
|
||||
{% block title %}SNMP — Fabled Scryer{% endblock %}
|
||||
{% block title %}SNMP — Steward{% endblock %}
|
||||
{% block content %}
|
||||
<div style="display:flex;align-items:center;gap:1rem;margin-bottom:1.5rem;">
|
||||
<h1 class="page-title" style="margin:0;">SNMP Devices</h1>
|
||||
|
||||
@@ -15,11 +15,11 @@ from sqlalchemy.engine import Connection
|
||||
from sqlalchemy.ext.asyncio import async_engine_from_config
|
||||
from alembic import context
|
||||
|
||||
# Make fabledscryer importable
|
||||
# Make steward importable
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent.parent.parent))
|
||||
|
||||
from fabledscryer.models.base import Base
|
||||
import fabledscryer.models # noqa: F401 — core models
|
||||
from steward.models.base import Base
|
||||
import steward.models # noqa: F401 — core models
|
||||
from plugins.traefik.models import TraefikMetric # noqa: F401 — plugin model
|
||||
|
||||
config = context.config
|
||||
@@ -31,14 +31,14 @@ target_metadata = Base.metadata
|
||||
|
||||
def _get_url() -> str:
|
||||
import yaml
|
||||
cfg_path = os.environ.get("FABLEDSCRYER_CONFIG", "config.yaml")
|
||||
cfg_path = os.environ.get("STEWARD_CONFIG", "config.yaml")
|
||||
try:
|
||||
with open(cfg_path) as f:
|
||||
cfg = yaml.safe_load(f) or {}
|
||||
url = cfg.get("database", {}).get("url", "")
|
||||
except FileNotFoundError:
|
||||
url = ""
|
||||
return os.environ.get("FABLEDSCRYER_DATABASE__URL", url)
|
||||
return os.environ.get("STEWARD_DATABASE__URL", url)
|
||||
|
||||
|
||||
def run_migrations_offline() -> None:
|
||||
|
||||
@@ -4,7 +4,7 @@ import uuid
|
||||
from datetime import datetime, timezone
|
||||
from sqlalchemy import DateTime, Float, Integer, String, Text
|
||||
from sqlalchemy.orm import Mapped, mapped_column
|
||||
from fabledscryer.models.base import Base
|
||||
from steward.models.base import Base
|
||||
|
||||
|
||||
class TraefikMetric(Base):
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
name: traefik
|
||||
version: "1.0.0"
|
||||
description: "Traefik reverse proxy metrics and access log integration"
|
||||
author: "FabledScryer"
|
||||
author: "Steward"
|
||||
license: "MIT"
|
||||
min_app_version: "0.1.0"
|
||||
repository_url: "https://git.fabledsword.com/bvandeusen/FabledScryer-plugins"
|
||||
homepage: "https://git.fabledsword.com/bvandeusen/FabledScryer-plugins/src/branch/main/traefik"
|
||||
repository_url: "https://git.fabledsword.com/bvandeusen/Steward-plugins"
|
||||
homepage: "https://git.fabledsword.com/bvandeusen/Steward-plugins/src/branch/main/traefik"
|
||||
tags:
|
||||
- proxy
|
||||
- metrics
|
||||
|
||||
@@ -6,9 +6,9 @@ from quart import Blueprint, current_app, render_template, request
|
||||
from sqlalchemy import Integer, cast, func, select
|
||||
import json
|
||||
|
||||
from fabledscryer.auth.middleware import require_role
|
||||
from fabledscryer.models.users import UserRole
|
||||
from fabledscryer.core.time_range import parse_range, DEFAULT_RANGE, bucket_seconds, subsample
|
||||
from steward.auth.middleware import require_role
|
||||
from steward.models.users import UserRole
|
||||
from steward.core.time_range import parse_range, DEFAULT_RANGE, bucket_seconds, subsample
|
||||
from .models import TraefikAccessSummary, TraefikCert, TraefikGlobalStat, TraefikMetric
|
||||
|
||||
traefik_bp = Blueprint("traefik", __name__, template_folder="templates")
|
||||
|
||||
@@ -5,7 +5,7 @@ import time
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from datetime import datetime
|
||||
from fabledscryer.core.scheduler import ScheduledTask
|
||||
from steward.core.scheduler import ScheduledTask
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from quart import Quart
|
||||
@@ -41,7 +41,6 @@ async def _do_scrape(app: "Quart") -> None:
|
||||
global _prev_metrics, _prev_time
|
||||
|
||||
from datetime import datetime, timezone
|
||||
from sqlalchemy import select
|
||||
from .models import TraefikCert, TraefikGlobalStat, TraefikMetric
|
||||
from .scraper import (
|
||||
compute_global_stats,
|
||||
@@ -49,7 +48,7 @@ async def _do_scrape(app: "Quart") -> None:
|
||||
extract_certs,
|
||||
fetch_metrics,
|
||||
)
|
||||
from fabledscryer.core.alerts import record_metric
|
||||
from steward.core.alerts import record_metric
|
||||
|
||||
metrics_url: str = app.config["PLUGINS"]["traefik"]["metrics_url"]
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{# plugins/traefik/templates/traefik/index.html #}
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Traefik — Fabled Scryer{% endblock %}
|
||||
{% block title %}Traefik — Steward{% endblock %}
|
||||
{% block content %}
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:0.75rem;margin-bottom:1.5rem;">
|
||||
<div style="display:flex;align-items:baseline;gap:1rem;">
|
||||
|
||||
@@ -15,8 +15,8 @@ from alembic import context
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent.parent.parent))
|
||||
|
||||
from fabledscryer.models.base import Base
|
||||
import fabledscryer.models # noqa: F401
|
||||
from steward.models.base import Base
|
||||
import steward.models # noqa: F401
|
||||
from plugins.unifi.models import UnifiWanStat, UnifiClientSnapshot, UnifiDevice # noqa: F401
|
||||
|
||||
config = context.config
|
||||
@@ -28,14 +28,14 @@ target_metadata = Base.metadata
|
||||
|
||||
def _get_url() -> str:
|
||||
import yaml
|
||||
cfg_path = os.environ.get("FABLEDSCRYER_CONFIG", "config.yaml")
|
||||
cfg_path = os.environ.get("STEWARD_CONFIG", "config.yaml")
|
||||
try:
|
||||
with open(cfg_path) as f:
|
||||
cfg = yaml.safe_load(f) or {}
|
||||
url = cfg.get("database", {}).get("url", "")
|
||||
except FileNotFoundError:
|
||||
url = ""
|
||||
return os.environ.get("FABLEDSCRYER_DATABASE__URL", url)
|
||||
return os.environ.get("STEWARD_DATABASE__URL", url)
|
||||
|
||||
|
||||
def run_migrations_offline() -> None:
|
||||
|
||||
@@ -4,7 +4,7 @@ import uuid
|
||||
from datetime import datetime, timezone
|
||||
from sqlalchemy import Boolean, DateTime, Float, Integer, String, Text
|
||||
from sqlalchemy.orm import Mapped, mapped_column
|
||||
from fabledscryer.models.base import Base
|
||||
from steward.models.base import Base
|
||||
|
||||
|
||||
# ── Time-series (one row per scrape) ──────────────────────────────────────────
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
name: unifi
|
||||
version: "1.0.0"
|
||||
description: "UniFi Network controller integration — WAN health, devices, clients, DPI"
|
||||
author: "FabledScryer"
|
||||
author: "Steward"
|
||||
license: "MIT"
|
||||
min_app_version: "0.1.0"
|
||||
repository_url: "https://git.fabledsword.com/bvandeusen/FabledScryer-plugins"
|
||||
homepage: "https://git.fabledsword.com/bvandeusen/FabledScryer-plugins/src/branch/main/unifi"
|
||||
repository_url: "https://git.fabledsword.com/bvandeusen/Steward-plugins"
|
||||
homepage: "https://git.fabledsword.com/bvandeusen/Steward-plugins/src/branch/main/unifi"
|
||||
tags:
|
||||
- network
|
||||
- unifi
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
# plugins/unifi/routes.py
|
||||
from __future__ import annotations
|
||||
import json
|
||||
from datetime import datetime, timezone
|
||||
from quart import Blueprint, current_app, render_template, request
|
||||
from sqlalchemy import Integer, cast, func, select
|
||||
|
||||
from fabledscryer.auth.middleware import require_role
|
||||
from fabledscryer.models.users import UserRole
|
||||
from fabledscryer.core.time_range import parse_range, DEFAULT_RANGE, bucket_seconds, subsample
|
||||
from steward.auth.middleware import require_role
|
||||
from steward.models.users import UserRole
|
||||
from steward.core.time_range import parse_range, DEFAULT_RANGE, bucket_seconds
|
||||
from .models import (
|
||||
UnifiAlarm, UnifiClientSnapshot, UnifiDevice, UnifiDpiSnapshot,
|
||||
UnifiEvent, UnifiFwRule, UnifiKnownClient, UnifiNetwork,
|
||||
|
||||
@@ -5,7 +5,7 @@ import logging
|
||||
from datetime import datetime, timezone
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from fabledscryer.core.scheduler import ScheduledTask
|
||||
from steward.core.scheduler import ScheduledTask
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from quart import Quart
|
||||
@@ -35,7 +35,7 @@ async def _do_poll(app: "Quart") -> None:
|
||||
|
||||
from .client import UnifiClient
|
||||
from .models import UnifiClientSnapshot, UnifiDevice, UnifiWanStat
|
||||
from fabledscryer.core.alerts import record_metric
|
||||
from steward.core.alerts import record_metric
|
||||
|
||||
cfg = app.config["PLUGINS"]["unifi"]
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{# plugins/unifi/templates/unifi/index.html #}
|
||||
{% extends "base.html" %}
|
||||
{% block title %}UniFi — Fabled Scryer{% endblock %}
|
||||
{% block title %}UniFi — Steward{% endblock %}
|
||||
{% block content %}
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:0.75rem;margin-bottom:1.25rem;">
|
||||
<div style="display:flex;align-items:baseline;gap:1rem;">
|
||||
|
||||
@@ -3,13 +3,12 @@ from __future__ import annotations
|
||||
import asyncio
|
||||
import uuid
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
|
||||
from quart import (
|
||||
Blueprint, Response, current_app, redirect, render_template,
|
||||
request, session, url_for,
|
||||
Blueprint, Response, current_app, render_template,
|
||||
request, session,
|
||||
)
|
||||
from sqlalchemy import select, update
|
||||
from sqlalchemy import select
|
||||
|
||||
from steward.ansible import executor, sources as src_module
|
||||
from steward.auth.middleware import require_role
|
||||
|
||||
@@ -8,7 +8,6 @@ we trust the HTTPS connection to the discovery-documented token/userinfo endpoin
|
||||
"""
|
||||
from __future__ import annotations
|
||||
import base64
|
||||
import hashlib
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
# steward/core/plugin_manager.py
|
||||
from __future__ import annotations
|
||||
import hashlib
|
||||
import importlib
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
|
||||
@@ -6,8 +6,6 @@ Called by the scheduler (hourly check) or triggered manually from Settings.
|
||||
from __future__ import annotations
|
||||
import asyncio
|
||||
import logging
|
||||
import smtplib
|
||||
import ssl
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from email.message import EmailMessage
|
||||
|
||||
|
||||
@@ -15,7 +15,8 @@ target_metadata = Base.metadata
|
||||
|
||||
|
||||
def get_url() -> str:
|
||||
import os, yaml
|
||||
import os
|
||||
import yaml
|
||||
|
||||
def _env(suffix: str) -> str | None:
|
||||
return os.environ.get(f"STEWARD_{suffix}")
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
# steward/settings/routes.py
|
||||
from __future__ import annotations
|
||||
import json
|
||||
import logging
|
||||
from pathlib import Path
|
||||
from quart import Blueprint, current_app, render_template, request, redirect, url_for, session
|
||||
@@ -9,7 +8,7 @@ from steward.auth.middleware import require_role
|
||||
from steward.core.audit import log_audit
|
||||
from steward.models.users import UserRole
|
||||
from steward.core.settings import (
|
||||
DEFAULTS, get_all_settings, set_setting,
|
||||
get_all_settings, set_setting,
|
||||
to_smtp_cfg, to_webhook_cfg, to_ansible_cfg, to_plugins_cfg,
|
||||
to_oidc_cfg, to_ldap_cfg,
|
||||
)
|
||||
|
||||
@@ -144,12 +144,12 @@
|
||||
<div class="form-group">
|
||||
<label>Admin group DN</label>
|
||||
<input type="text" name="ldap.admin_group_dn" value="{{ settings['ldap.admin_group_dn'] }}"
|
||||
placeholder="cn=scryer-admins,ou=groups,dc=example,dc=com">
|
||||
placeholder="cn=steward-admins,ou=groups,dc=example,dc=com">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Operator group DN</label>
|
||||
<input type="text" name="ldap.operator_group_dn" value="{{ settings['ldap.operator_group_dn'] }}"
|
||||
placeholder="cn=scryer-operators,ou=groups,dc=example,dc=com">
|
||||
placeholder="cn=steward-operators,ou=groups,dc=example,dc=com">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
<div style="margin-bottom:2rem;max-width:720px;">
|
||||
<div class="section-title" style="margin-bottom:0.75rem;">Plugin Repositories</div>
|
||||
<p style="color:var(--text-muted);font-size:0.84rem;margin-bottom:0.75rem;">
|
||||
Repositories are remote <code>index.yaml</code> files that Scryer checks for available
|
||||
Repositories are remote <code>index.yaml</code> files that Steward checks for available
|
||||
and updated plugins. Add repos from other developers to expand the plugin catalog.
|
||||
</p>
|
||||
{% include "settings/_plugin_repos.html" %}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import pytest
|
||||
import pytest_asyncio
|
||||
from pathlib import Path
|
||||
import textwrap
|
||||
from steward.app import create_app
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import urllib.error
|
||||
from unittest.mock import patch
|
||||
from plugins.host_agent import agent as a
|
||||
|
||||
@@ -55,10 +56,6 @@ def test_build_payload_wraps_samples():
|
||||
assert payload["samples"][0]["cpu_pct"] == 5.0
|
||||
|
||||
|
||||
import urllib.error
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
|
||||
def test_post_payload_success():
|
||||
from plugins.host_agent import agent as a
|
||||
captured = {}
|
||||
|
||||
@@ -3,7 +3,9 @@ from plugins.host_agent.agent import RingBuffer
|
||||
|
||||
def test_ring_buffer_preserves_order():
|
||||
rb = RingBuffer(maxlen=3)
|
||||
rb.push(1); rb.push(2); rb.push(3)
|
||||
rb.push(1)
|
||||
rb.push(2)
|
||||
rb.push(3)
|
||||
assert list(rb.drain()) == [1, 2, 3]
|
||||
assert len(rb) == 0
|
||||
|
||||
@@ -17,7 +19,8 @@ def test_ring_buffer_drops_oldest_when_full():
|
||||
|
||||
def test_ring_buffer_drain_clears_and_is_atomic():
|
||||
rb = RingBuffer(maxlen=5)
|
||||
rb.push("a"); rb.push("b")
|
||||
rb.push("a")
|
||||
rb.push("b")
|
||||
out = list(rb.drain())
|
||||
rb.push("c")
|
||||
assert out == ["a", "b"]
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
|
||||
from plugins.host_agent.routes import _agent_version, AGENT_SOURCE_PATH
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import os
|
||||
import textwrap
|
||||
import pytest
|
||||
from steward.config import load_bootstrap
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import pytest
|
||||
from steward.models.users import User, UserRole
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
"""Regression guard: shipped code must not reference old project names.
|
||||
|
||||
The FabledScryer -> Roundtable -> Steward renames repeatedly left stale package
|
||||
imports behind in the (then separate) plugins (e.g. `from fabledscryer.models...`),
|
||||
silently breaking every non-host_agent plugin. Now that plugins are folded in-tree
|
||||
and version with core, this test fails loudly if either legacy name reappears in
|
||||
the shipped Python / templates / plugin manifests.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
_ROOT = Path(__file__).resolve().parent.parent
|
||||
_TREES = [_ROOT / "steward", _ROOT / "plugins"]
|
||||
_EXTENSIONS = {".py", ".yaml", ".yml", ".html", ".j2"}
|
||||
_FORBIDDEN = ("scryer", "roundtable") # case-insensitive; old project names
|
||||
|
||||
|
||||
def _shipped_files():
|
||||
for tree in _TREES:
|
||||
for path in tree.rglob("*"):
|
||||
if path.suffix in _EXTENSIONS and "__pycache__" not in path.parts:
|
||||
yield path
|
||||
|
||||
|
||||
@pytest.mark.parametrize("name", _FORBIDDEN)
|
||||
def test_no_legacy_project_name(name):
|
||||
offenders = [
|
||||
str(p.relative_to(_ROOT))
|
||||
for p in _shipped_files()
|
||||
if name in p.read_text(encoding="utf-8", errors="ignore").lower()
|
||||
]
|
||||
assert not offenders, f"legacy name {name!r} found in shipped code: {offenders}"
|
||||
Reference in New Issue
Block a user