Publish curated Unraid-AppOps-Gateway source from 4f99d8f6ea4fb8ae105b83570344b25fa05c31fd

This commit is contained in:
Public Source Publisher committed 2026-10-02 18:50:59 +00:00
1 parent 27a33107a3
commit f50d6e8c2c
14 files changed
+1178 -21

No files matched your search

+23 -1
View File
@@ -15,11 +15,12 @@ from sqlmodel import Session
from ..core.security import require_operator_request
from ..db.session import get_session
from ..schemas.deployment import DeploymentPlanV1
from ..schemas.forge_bootstrap import ForgeBootstrapPreflightV1
from ..services.deployment_broker import DeploymentBrokerClient
from ..services.deployment_control_plane import (
DeploymentControlError,
DeploymentControlPlane,
)
from ..services.deployment_broker import DeploymentBrokerClient
def _require_deployment_operator(request: Request) -> str:
@@ -95,6 +96,27 @@ def preflight_workmesh_promotion(
raise HTTPException(status_code=409, detail=str(exc)) from exc
@router.post("/forge-bootstrap/preflight")
def preflight_forge_bootstrap(
payload: ForgeBootstrapPreflightV1,
session: DeploymentSession,
idempotency_key: DeploymentIdempotencyKey = None,
):
from ..services.forge_bootstrap_preflight import (
ForgeBootstrapPreflightError,
ForgeBootstrapPreflightService,
)
try:
return ForgeBootstrapPreflightService().preflight(
session,
payload,
idempotency_key=_idempotency_header(idempotency_key),
)
except ForgeBootstrapPreflightError as exc:
raise HTTPException(status_code=409, detail=str(exc)) from exc
@router.get("/workmesh/promotions/{promotion_id}")
def get_workmesh_promotion(promotion_id: str, session: DeploymentSession):
from ..services.workmesh_promotion import WorkMeshPromotionService
+20 -1
View File
@@ -27,6 +27,7 @@ from .db.models import AppSetting, AuditEvent
from .db.session import engine
from .schemas.deployment import DeploymentPlanV1
from .schemas.enrollment import EnrollmentPlanV1
from .schemas.forge_bootstrap import ForgeBootstrapPreflightV1
from .services import knowledge_service, mcp_operations, safety_center_service
from .services.action_execution import mcp_execution_supported
from .services.action_registry import ACTION_RISK, ACTIONS, action_capability
@@ -653,8 +654,26 @@ def cancel_job(jobId: str) -> dict[str, Any]:
@appops_mcp.tool(name="deployment.preflight", annotations=_READ_ONLY_TOOL)
@_tracked("deployment.preflight")
def deployment_preflight(plan: dict[str, Any], idempotencyKey: str) -> dict[str, Any]:
"""Validate one strict DeploymentPlanV1 without touching application runtime state."""
"""Validate a strict V1 plan or fixed Forge bootstrap profile read-only."""
try:
if plan.get("api_version") == "itworx.forge-bootstrap-preflight/v1":
from .services.forge_bootstrap_preflight import (
ForgeBootstrapPreflightService,
)
profile = ForgeBootstrapPreflightV1.model_validate(plan)
with Session(engine) as session:
return _json(
ForgeBootstrapPreflightService().preflight(
session, profile, idempotency_key=idempotencyKey
)
)
if "api_version" in plan:
return {
"status": "invalid",
"executed": False,
"reason": "Unsupported deployment.preflight profile discriminator.",
}
typed_plan = DeploymentPlanV1.model_validate(plan)
with Session(engine) as session:
return _json(
+34
View File
@@ -0,0 +1,34 @@
from __future__ import annotations
import re
from typing import Literal
from pydantic import BaseModel, ConfigDict, Field, field_validator
_REVISION = re.compile(r"^[0-9a-f]{40}$")
_DIGEST = re.compile(r"^sha256:[0-9a-f]{64}$")
class ForgeBootstrapPreflightV1(BaseModel):
"""Fixed read-only input for Forge production bootstrap readiness."""
model_config = ConfigDict(extra="forbid", strict=True)
api_version: Literal["itworx.forge-bootstrap-preflight/v1"]
revision: str = Field(min_length=40, max_length=40)
workspace_image_digest: str = Field(min_length=71, max_length=71)
frontdoor_image_digest: str = Field(min_length=71, max_length=71)
@field_validator("revision")
@classmethod
def full_lowercase_revision(cls, value: str) -> str:
if not _REVISION.fullmatch(value):
raise ValueError("revision must be a full lowercase Git SHA")
return value
@field_validator("workspace_image_digest", "frontdoor_image_digest")
@classmethod
def immutable_oci_digest(cls, value: str) -> str:
if not _DIGEST.fullmatch(value):
raise ValueError("image digest must be a lowercase sha256 OCI digest")
return value
@@ -60,6 +60,7 @@ git --git-dir="$repo" archive --format=tar "$revision" \
scripts/reconcile_controller_state.py \
scripts/run_repopulse_adoption.py \
scripts/prepare_controller_hub_release_volume.py \
scripts/vendor \
scripts/upgrade_deployment_controller.sh > "$work/controller.tar"
chmod 0600 "$work/controller.tar"
archive_sha="$(sha256sum "$work/controller.tar" | cut -d ' ' -f 1)"
+12
View File
@@ -26,6 +26,7 @@ import httpx
from ..core.config import settings
from ..core.redaction import redact_message
from ..schemas.deployment import DeploymentPlanV1
from ..schemas.forge_bootstrap import ForgeBootstrapPreflightV1
_REQUEST_ID = re.compile(r"^[0-9a-f]{64}$")
_MAX_DELIVERY_STATUS_BYTES = 512 * 1024
@@ -302,6 +303,17 @@ class DeploymentBrokerClient:
payload={"enrollment": enrollment},
)
def forge_bootstrap_preflight(
self, profile: ForgeBootstrapPreflightV1, *, secret: str
) -> dict[str, Any]:
"""Read fixed Forge source and host prerequisites through bootstrap HMAC."""
return self._request(
"POST",
"/v1/appops/forge/bootstrap/preflight",
secret=secret,
payload={"profile": profile.model_dump(mode="json")},
)
def enrollment_capabilities(self, *, secret: str) -> dict[str, Any]:
"""Read the bootstrap-protected enrollment controller capability."""
return self._request(
@@ -0,0 +1,329 @@
from __future__ import annotations
import hashlib
import json
import re
import uuid
from typing import Any
from sqlmodel import Session, select
from ..core.time import utc_now
from ..db.models import DeploymentJob, Policy
from ..schemas.forge_bootstrap import ForgeBootstrapPreflightV1
from .audit_logger import log_event
from .deployment_broker import DeploymentBrokerClient
from .enrollment_plane import EnrollmentPlane
from .policy_engine import evaluate_policy
from .secret_store import get_secret, has_secret
_API_VERSION = "itworx.forge-bootstrap-preflight/v1"
_APPLICATION_ID = "itworx-forge"
_REPOSITORY = "jens/itworx-forge"
_IDEMPOTENCY = re.compile(r"^[A-Za-z0-9._:-]{8,128}$")
_CONTROLLER_CHECKS = {
"exact_main", "source_manifest", "managed_appdata", "proxy_network",
"resource_collisions", "push_validation", "image_registry", "oidc",
"secret_delivery",
}
_DETAILS = {
"deployment_apply_policy": "An explicit allowed exact-target deployment policy is required before apply.",
"controller_trust": "Stored controller trust and bootstrap secret are required for host checks.",
"managed_appdata_root_selection": "The managed Docker-root backup acknowledgement and storage selection are required before setup.",
"exact_main": "Requested Forge revision must equal the current main head.",
"source_manifest": "The source manifest must match the fixed Forge six-service topology.",
"managed_appdata": "The fixed managed PostgreSQL directory must have safe owner-only metadata.",
"proxy_network": "The required external proxy network must be present.",
"resource_collisions": "Fixed Forge container names must be free for first installation.",
"push_validation": "Exact-main CI validation cannot be verified from trusted controller configuration.",
"image_registry": "Registry publication and pull authorization require external verification.",
"oidc": "Dedicated Forge Authentik provider, application, and role groups require external verification.",
"secret_delivery": "Forge database and application secret files require external verification.",
}
_STATUS_DETAILS = {
"exact_main": {
"passed": "Requested revision equals the current protected Gitea main head.",
"blocked": "Requested revision is not the current protected Gitea main head.",
"unknown": "Current protected Gitea main head could not be verified.",
},
"source_manifest": {
"passed": "Committed Forge manifest matches the pinned production topology contract.",
"blocked": "Committed Forge manifest differs from the pinned production topology contract.",
"unknown": "Committed Forge manifest could not be read from the controller mirror.",
},
"managed_appdata": {
"passed": "Selected managed root and fixed PostgreSQL directory have safe metadata.",
"blocked": "Managed root or fixed PostgreSQL directory is missing or unsafe.",
"unknown": "Managed storage metadata could not be verified.",
},
"proxy_network": {
"passed": "The required external proxy network exists.",
"blocked": "The required external proxy network is missing.",
"unknown": "Docker network inventory is unavailable.",
},
"resource_collisions": {
"passed": "No fixed Forge container-name collisions were found.",
"blocked": "One or more fixed Forge container names already exist.",
"unknown": "Docker container inventory is unavailable.",
},
"push_validation": {
"passed": "Configured required push validation contexts passed for this exact commit.",
"blocked": "A configured required push validation context rejected this exact commit.",
"unknown": "Exact-commit push validation is not configured or cannot be verified.",
},
}
class ForgeBootstrapPreflightError(ValueError):
"""A fixed-target Forge preflight request failed closed."""
def _canonical_digest(value: dict[str, Any]) -> str:
return hashlib.sha256(
json.dumps(value, sort_keys=True, separators=(",", ":")).encode("utf-8")
).hexdigest()
def _idempotency_digest(value: str) -> str:
normalized = value.strip()
if not _IDEMPOTENCY.fullmatch(normalized):
raise ForgeBootstrapPreflightError("Idempotency-Key must contain 8 to 128 safe characters.")
return hashlib.sha256(f"forge-bootstrap-preflight:{normalized}".encode()).hexdigest()
def _check(name: str, status: str) -> dict[str, str]:
detail = _STATUS_DETAILS.get(name, {}).get(status, _DETAILS[name])
return {"name": name, "status": status, "detail": detail}
def _checked_controller_result(
result: object, profile: ForgeBootstrapPreflightV1
) -> tuple[list[dict[str, str]], dict[str, Any]] | None:
if not isinstance(result, dict) or (
result.get("apiVersion") != _API_VERSION
or result.get("revision") != profile.revision
or result.get("workspaceImageDigest") != profile.workspace_image_digest
or result.get("frontdoorImageDigest") != profile.frontdoor_image_digest
):
return None
raw_checks = result.get("checks")
if not isinstance(raw_checks, dict) or set(raw_checks) != _CONTROLLER_CHECKS:
return None
checks: list[dict[str, str]] = []
for name in sorted(_CONTROLLER_CHECKS):
raw = raw_checks.get(name)
if not isinstance(raw, dict) or set(raw) != {"status"} or raw.get("status") not in {"passed", "blocked", "unknown"}:
return None
# CI, registry access, OIDC and secret delivery are intentionally
# unknown until a configured, source-authenticated proof exists.
if name in {"image_registry", "oidc", "secret_delivery"} and raw["status"] != "unknown":
return None
checks.append(_check(name, raw["status"]))
statuses = [item["status"] for item in checks]
expected_status = "preflight_blocked" if "blocked" in statuses else "preflight_unknown" if "unknown" in statuses else "preflight_ok"
if result.get("status") != expected_status:
return None
raw_evidence = result.get("evidence", {})
if not isinstance(raw_evidence, dict) or set(raw_evidence) - {
"mainRevision", "sourceManifestSha256", "resourceCollisionCount",
"workspaceImagePresent", "frontdoorImagePresent",
}:
return None
evidence: dict[str, Any] = {}
for name in ("mainRevision", "sourceManifestSha256"):
value = raw_evidence.get(name)
if value is not None:
pattern = r"^[0-9a-f]{40}$" if name == "mainRevision" else r"^[0-9a-f]{64}$"
if not isinstance(value, str) or not re.fullmatch(pattern, value):
return None
evidence[name] = value
count = raw_evidence.get("resourceCollisionCount")
if count is not None:
if isinstance(count, bool) or not isinstance(count, int) or not 0 <= count <= 1000:
return None
evidence["resourceCollisionCount"] = count
for name in ("workspaceImagePresent", "frontdoorImagePresent"):
value = raw_evidence.get(name)
if value is not None:
if not isinstance(value, bool):
return None
evidence[name] = value
return checks, evidence
class ForgeBootstrapPreflightService:
"""Read-only fixed Forge checks; this profile has no apply or rollback path."""
def __init__(self, *, broker: DeploymentBrokerClient | None = None):
self.broker = broker or DeploymentBrokerClient()
def preflight(
self,
session: Session,
profile: ForgeBootstrapPreflightV1,
*,
idempotency_key: str,
) -> dict[str, Any]:
payload = profile.model_dump(mode="json")
plan_digest = _canonical_digest(payload)
key_digest = _idempotency_digest(idempotency_key)
existing = session.exec(
select(DeploymentJob).where(DeploymentJob.idempotency_sha256 == key_digest)
).first()
if existing:
if existing.plan_sha256 != plan_digest:
raise ForgeBootstrapPreflightError(
"Idempotency-Key was already used for a different Forge profile."
)
return self.serialize_job(existing, replay=True)
exact = session.exec(
select(Policy).where(
(Policy.action == "deployment.apply") & (Policy.target == _APPLICATION_ID)
)
).all()
decision = evaluate_policy(
session, action="deployment.apply", target=_APPLICATION_ID, source="manual"
)
policy_ready = bool(
len(exact) == 1
and exact[0].manual == "allowed"
and exact[0].voice == "blocked"
and exact[0].risk == "high"
and decision.get("decision") == "allowed"
and decision.get("policy_id") == exact[0].id
)
checks = [_check("deployment_apply_policy", "passed" if policy_ready else "blocked")]
trust = EnrollmentPlane.get_trust_config(session)
expected_root = "/var/lib/docker/volumes/itworx-managed-appdata/_data"
secret = None
if trust is not None:
try:
if has_secret(session, trust.bootstrap_secret_ref):
secret = get_secret(session, trust.bootstrap_secret_ref, touch=False)
except Exception: # noqa: BLE001 - fail closed without exposing secret-store errors.
secret = None
bootstrap_ready = bool(
trust
and isinstance(secret, str)
and len(secret) >= 32
and secret.isascii()
and secret.isprintable()
)
checks.append(_check("controller_trust", "passed" if bootstrap_ready else "blocked"))
root_ready = bool(
trust
and trust.trusted_appdata_root == expected_root
and trust.managed_appdata_backup_acknowledged
)
checks.append(
_check("managed_appdata_root_selection", "passed" if root_ready else "blocked")
)
controller_result = None
if bootstrap_ready:
try:
controller_result = self.broker.forge_bootstrap_preflight(
profile, secret=secret or ""
)
except Exception: # noqa: BLE001 - transport details stay out of the preflight receipt.
controller_result = None
parsed_controller = _checked_controller_result(controller_result, profile)
if parsed_controller is None:
host_checks = [_check(name, "unknown") for name in sorted(_CONTROLLER_CHECKS)]
controller_evidence: dict[str, Any] = {}
else:
host_checks, controller_evidence = parsed_controller
checks.extend(host_checks)
blockers = [item["name"] for item in checks if item["status"] == "blocked"]
unknowns = [item["name"] for item in checks if item["status"] == "unknown"]
outcome = "blocked" if blockers else "unknown" if unknowns else "passed"
job_status = "preflight_succeeded" if outcome == "passed" else "preflight_failed"
now = utc_now()
job = DeploymentJob(
id=f"forge-preflight-{uuid.uuid4().hex[:16]}",
application_id=_APPLICATION_ID,
repository=_REPOSITORY,
revision=profile.revision,
plan_sha256=plan_digest,
idempotency_sha256=key_digest,
status=job_status,
stage="preflight_complete" if outcome == "passed" else "preflight_incomplete",
plan_json=payload,
preflight_json={
"apiVersion": _API_VERSION,
"status": outcome,
"blockers": blockers,
"unknowns": unknowns,
"checks": checks,
},
evidence_json={
"profile": "forge-production-bootstrap",
"workspaceImageDigest": profile.workspace_image_digest,
"frontdoorImageDigest": profile.frontdoor_image_digest,
"controller": controller_evidence,
},
result_summary=(
"Forge bootstrap checks passed; production apply remains separately gated."
if outcome == "passed"
else "Forge bootstrap preflight is incomplete; see blocked and unknown checks."
),
created_at=now,
updated_at=now,
completed_at=now,
)
session.add(job)
session.commit()
session.refresh(job)
log_event(
session,
source="deployment-control-plane",
identity="operator",
action_id="deployment.preflight",
target=_APPLICATION_ID,
target_type="deployment",
risk="high",
policy_decision="allowed" if policy_ready else "blocked",
reason="Fixed Forge bootstrap preflight recorded without requesting a deployment action.",
result="success" if outcome == "passed" else "blocked",
execution_plan={"planSha256": plan_digest, "profile": "forge-production-bootstrap"},
post_checks={"preflight": job.preflight_json},
)
return self.serialize_job(job)
@staticmethod
def serialize_job(job: DeploymentJob, *, replay: bool = False) -> dict[str, Any]:
return {
"id": job.id,
"applicationId": job.application_id,
"repository": job.repository,
"revision": job.revision,
"status": job.status,
"stage": job.stage,
"preflight": job.preflight_json,
"evidence": job.evidence_json,
"result": job.result_summary,
"brokerRequestId": job.broker_request_id,
"createdAt": job.created_at.isoformat(),
"updatedAt": job.updated_at.isoformat(),
"completedAt": job.completed_at.isoformat() if job.completed_at else None,
"idempotentReplay": replay,
}
@staticmethod
def refresh(session: Session, job_id: str) -> dict[str, Any] | None:
job = session.get(DeploymentJob, job_id)
if not job or not job.id.startswith("forge-preflight-"):
return None
return ForgeBootstrapPreflightService.serialize_job(job)
@staticmethod
def list_jobs(session: Session, *, limit: int = 100) -> list[dict[str, Any]]:
rows = session.exec(
select(DeploymentJob)
.where(DeploymentJob.id.startswith("forge-preflight-"))
.order_by(DeploymentJob.created_at.desc())
.limit(max(1, min(limit, 250)))
).all()
return [ForgeBootstrapPreflightService.serialize_job(row) for row in rows]