Publish curated Unraid-AppOps-Gateway source from a506550ef83ef2d81651e37c98a89f7ee330c730
This commit is contained in:
1 parent
2facb8de34
commit
767e66921e
68 files changed
+15924
-313
No files matched your search
@@ -53,6 +53,9 @@ APPROVAL_EXECUTOR_ACTIONS = {
|
||||
"container.restart",
|
||||
"controller.artifact.promote",
|
||||
"runner.fleet.upgrade_v2",
|
||||
"runner.fleet.specialize",
|
||||
"runner.statistics.configure",
|
||||
"hub.migration.prepare_permissions",
|
||||
"deployment.targets.sync",
|
||||
"deployment.runnerless.provision",
|
||||
"deployment.target.deploy_workmesh",
|
||||
@@ -1648,18 +1651,27 @@ def _execute_runner_fleet_upgrade_v2(
|
||||
risk: str,
|
||||
reason: str,
|
||||
original_policy_decision: str,
|
||||
specialized: bool = False,
|
||||
statistics_configuration: bool = False,
|
||||
) -> dict[str, Any]:
|
||||
from .deployment_broker import DeploymentBrokerClient
|
||||
|
||||
action = "runner.fleet.upgrade_v2"
|
||||
target = "tower/runner-fleet-v2"
|
||||
action = ("runner.statistics.configure" if statistics_configuration else
|
||||
"runner.fleet.specialize" if specialized else "runner.fleet.upgrade_v2")
|
||||
target = ("tower/projectbrain-runner-statistics" if statistics_configuration else
|
||||
"tower/runner-fleet-specialized" if specialized else "tower/runner-fleet-v2")
|
||||
steps = [
|
||||
"Validate exact fixed runner-fleet target",
|
||||
"Call HMAC-signed root controller endpoint",
|
||||
"Prove protected main and successful push validation",
|
||||
"Execute exact-revision fleet-v2 migration script",
|
||||
"Execute exact-revision specialized migration script" if specialized
|
||||
else "Execute exact-revision fleet-v2 migration script",
|
||||
"Verify specialized runner topology",
|
||||
]
|
||||
if statistics_configuration:
|
||||
steps = ["Verify fixed read-only statistics target", "Prove protected controller/runtime source",
|
||||
"Lock production configuration", "Provision private independent credential with durable CAS",
|
||||
"Configure ProjectBrain for its governed delivery"]
|
||||
job = create_job(
|
||||
session,
|
||||
action_id=action,
|
||||
@@ -1670,24 +1682,31 @@ def _execute_runner_fleet_upgrade_v2(
|
||||
steps=steps,
|
||||
)
|
||||
start_job(session, job)
|
||||
set_job_progress(session, job, 25, "Requesting fixed Tower runner-fleet v2 migration.")
|
||||
set_job_progress(session, job, 25, f"Requesting {action} through the fixed controller endpoint.")
|
||||
try:
|
||||
result = DeploymentBrokerClient().runner_fleet_upgrade_v2(reason=reason)
|
||||
broker = DeploymentBrokerClient()
|
||||
result = (broker.runner_statistics_configure(reason=reason) if statistics_configuration else
|
||||
broker.runner_fleet_specialize(reason=reason) if specialized else broker.runner_fleet_upgrade_v2(reason=reason))
|
||||
status = str(result.get("status") or "error")
|
||||
success = status in {"upgraded", "already_applied"}
|
||||
success = status in ({"configured", "already_configured"} if statistics_configuration else
|
||||
{"specialized", "already_applied"} if specialized else {"upgraded", "already_applied"})
|
||||
message = str(
|
||||
result.get("reason")
|
||||
or (
|
||||
"Tower runner-fleet v2 migration verified."
|
||||
if success
|
||||
else "Tower runner-fleet v2 migration was rejected or failed."
|
||||
("ProjectBrain read-only statistics configuration verified." if statistics_configuration else
|
||||
"Tower runner specialization verified." if specialized
|
||||
else "Tower runner-fleet v2 migration verified.")
|
||||
if success else
|
||||
("ProjectBrain statistics configuration was rejected or failed." if statistics_configuration else
|
||||
"Tower runner specialization was rejected or failed." if specialized
|
||||
else "Tower runner-fleet v2 migration was rejected or failed.")
|
||||
)
|
||||
)
|
||||
except Exception as exc:
|
||||
result = {"status": "error"}
|
||||
status = "error"
|
||||
success = False
|
||||
message = f"{type(exc).__name__}: runner fleet v2 migration failed"
|
||||
message = f"{type(exc).__name__}: fixed controller operation failed"
|
||||
|
||||
completed = complete_job(
|
||||
session,
|
||||
@@ -1711,6 +1730,7 @@ def _execute_runner_fleet_upgrade_v2(
|
||||
"status": status,
|
||||
"revision": result.get("revision"),
|
||||
"verifiedRunners": result.get("verifiedRunners"),
|
||||
"projectbrainDeliveryRequired": result.get("projectbrainDeliveryRequired"),
|
||||
},
|
||||
redacted_metadata={
|
||||
"executor": action,
|
||||
@@ -1732,6 +1752,253 @@ def _execute_runner_fleet_upgrade_v2(
|
||||
"controllerStatus": status,
|
||||
"revision": result.get("revision"),
|
||||
"verifiedRunners": result.get("verifiedRunners"),
|
||||
"projectbrainDeliveryRequired": result.get("projectbrainDeliveryRequired"),
|
||||
}
|
||||
|
||||
|
||||
def _execute_hub_migration_prepare_permissions(
|
||||
session: Session,
|
||||
*,
|
||||
source: str,
|
||||
risk: str,
|
||||
reason: str,
|
||||
original_policy_decision: str,
|
||||
) -> dict[str, Any]:
|
||||
from .deployment_broker import DeploymentBrokerClient
|
||||
|
||||
action = "hub.migration.prepare_permissions"
|
||||
target = "tower/itworx-mcp-hub-permissions"
|
||||
state_file = "/mnt/cache/appdata/gitea-deploy-runners/state/itworx-mcp-hub.json"
|
||||
fixed_targets = {state_file}
|
||||
steps = [
|
||||
"Validate the exact fixed MCP Hub permission target",
|
||||
"Authenticate the fixed root-controller request with HMAC and replay protection",
|
||||
"Verify the running controller is the protected current main release with full-push validation",
|
||||
"Reinspect the fixed Hub state file and shared deployment lock",
|
||||
"Apply only the fixed state-file mode correction and verify its final metadata",
|
||||
]
|
||||
job = create_job(
|
||||
session,
|
||||
action_id=action,
|
||||
target=target,
|
||||
source=source,
|
||||
risk=risk,
|
||||
policy_decision="allowed",
|
||||
steps=steps,
|
||||
)
|
||||
start_job(session, job)
|
||||
set_job_progress(session, job, 25, "Requesting fixed MCP Hub permission preparation through the controller.")
|
||||
try:
|
||||
result = DeploymentBrokerClient().hub_migration_prepare_permissions(reason=reason)
|
||||
status = str(result.get("status") or "blocked")
|
||||
revision_value = result.get("revision")
|
||||
revision = (
|
||||
revision_value
|
||||
if isinstance(revision_value, str)
|
||||
and len(revision_value) == 40
|
||||
and all(character in "0123456789abcdef" for character in revision_value)
|
||||
else None
|
||||
)
|
||||
|
||||
changed_value = result.get("changedTargets", [])
|
||||
changed_targets = (
|
||||
changed_value
|
||||
if isinstance(changed_value, list)
|
||||
and all(isinstance(path, str) and path in fixed_targets for path in changed_value)
|
||||
and len(changed_value) == len(set(changed_value))
|
||||
else None
|
||||
)
|
||||
changed_details_value = result.get("changedTargetDetails", [])
|
||||
target_names = {
|
||||
state_file: "state_file",
|
||||
}
|
||||
changed_details = (
|
||||
changed_details_value
|
||||
if isinstance(changed_details_value, list)
|
||||
and all(
|
||||
isinstance(item, dict)
|
||||
and set(item) == {"name", "path", "observedMode", "sameIdentityAtPath"}
|
||||
and isinstance(item.get("path"), str)
|
||||
and item.get("path") in fixed_targets
|
||||
and item.get("name") == target_names.get(item.get("path"))
|
||||
and isinstance(item.get("observedMode"), str)
|
||||
and len(item["observedMode"]) == 4
|
||||
and item["observedMode"].startswith("0")
|
||||
and all(character in "01234567" for character in item["observedMode"])
|
||||
and isinstance(item.get("sameIdentityAtPath"), bool)
|
||||
and changed_targets is not None
|
||||
and item["path"] in changed_targets
|
||||
for item in changed_details_value
|
||||
)
|
||||
and len({item["path"] for item in changed_details_value}) == len(changed_details_value)
|
||||
else None
|
||||
)
|
||||
uncertain_value = result.get("uncertainTargets", [])
|
||||
uncertain_targets = (
|
||||
uncertain_value
|
||||
if isinstance(uncertain_value, list)
|
||||
and all(isinstance(path, str) and path in fixed_targets for path in uncertain_value)
|
||||
and len(uncertain_value) == len(set(uncertain_value))
|
||||
else None
|
||||
)
|
||||
expected_verified = {
|
||||
"state_file": {
|
||||
"path": state_file,
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"mode": "0600",
|
||||
"aclPresent": False,
|
||||
},
|
||||
}
|
||||
verified_value = result.get("verifiedTargets")
|
||||
verified_targets = None
|
||||
if isinstance(verified_value, list) and len(verified_value) == len(expected_verified):
|
||||
by_name = {
|
||||
item.get("name"): item
|
||||
for item in verified_value
|
||||
if isinstance(item, dict) and isinstance(item.get("name"), str)
|
||||
}
|
||||
if set(by_name) == set(expected_verified) and all(
|
||||
all(by_name[name].get(key) == value for key, value in expected.items())
|
||||
for name, expected in expected_verified.items()
|
||||
):
|
||||
verified_targets = [
|
||||
{"name": name, **expected_verified[name]}
|
||||
for name in ("state_file",)
|
||||
]
|
||||
|
||||
has_controller_projection = all(
|
||||
key in result
|
||||
for key in (
|
||||
"revision",
|
||||
"changedTargets",
|
||||
"changedTargetDetails",
|
||||
"uncertainTargets",
|
||||
)
|
||||
)
|
||||
success = (
|
||||
status in {"prepared", "already_compliant"}
|
||||
and has_controller_projection
|
||||
and revision is not None
|
||||
and changed_targets is not None
|
||||
and changed_details is not None
|
||||
and uncertain_targets == []
|
||||
and verified_targets is not None
|
||||
and (bool(changed_targets) if status == "prepared" else not changed_targets)
|
||||
)
|
||||
if success:
|
||||
message = (
|
||||
"The fixed MCP Hub state-file permission was prepared and verified."
|
||||
if status == "prepared"
|
||||
else "The fixed MCP Hub state-file permission was already compliant and verified."
|
||||
)
|
||||
elif (
|
||||
status == "partial"
|
||||
and has_controller_projection
|
||||
and revision is not None
|
||||
and changed_targets is not None
|
||||
and changed_details is not None
|
||||
and uncertain_targets is not None
|
||||
and (changed_targets or uncertain_targets)
|
||||
and len(changed_details) == len(changed_targets)
|
||||
and {item["path"] for item in changed_details} == set(changed_targets)
|
||||
):
|
||||
message = "Permission preparation stopped partway; inspect the exact changed and uncertain fixed targets before retrying."
|
||||
elif (
|
||||
status in {
|
||||
"blocked",
|
||||
"unauthorized",
|
||||
"missing_config",
|
||||
"missing_secret",
|
||||
"runtime_identity_unavailable",
|
||||
"controller_source_mismatch",
|
||||
"preflight_rejected",
|
||||
"configuration_unavailable",
|
||||
"exact_source_unavailable",
|
||||
"invalid_request",
|
||||
"invalid_body_size",
|
||||
"authentication_rejected",
|
||||
"forbidden",
|
||||
}
|
||||
and changed_targets == []
|
||||
and changed_details == []
|
||||
and uncertain_targets == []
|
||||
):
|
||||
status = "blocked"
|
||||
message = "The fixed MCP Hub permission request was rejected before any target change."
|
||||
else:
|
||||
status = "outcome_unknown"
|
||||
changed_targets = []
|
||||
changed_details = []
|
||||
uncertain_targets = sorted(fixed_targets)
|
||||
verified_targets = None
|
||||
message = (
|
||||
"The controller request outcome is unknown; the fixed Hub state file may have changed. "
|
||||
"Inspect it before retrying."
|
||||
)
|
||||
except Exception:
|
||||
result = {"status": "outcome_unknown"}
|
||||
status = "outcome_unknown"
|
||||
revision = None
|
||||
changed_targets = []
|
||||
changed_details = []
|
||||
uncertain_targets = sorted(fixed_targets)
|
||||
verified_targets = None
|
||||
success = False
|
||||
message = (
|
||||
"The controller request outcome is unknown; the fixed Hub state file may have changed. "
|
||||
"Inspect it before retrying."
|
||||
)
|
||||
|
||||
completed = complete_job(
|
||||
session,
|
||||
job,
|
||||
status="succeeded" if success else "failed",
|
||||
result_summary=message,
|
||||
)
|
||||
audit = log_event(
|
||||
session,
|
||||
source="action",
|
||||
identity=source,
|
||||
action_id=action,
|
||||
target=target,
|
||||
target_type="mcp-hub-permissions",
|
||||
risk=risk,
|
||||
policy_decision="allowed",
|
||||
reason=reason,
|
||||
result="success" if success else "outcome_unknown" if status == "outcome_unknown" else "failed",
|
||||
execution_plan={"steps": steps, "jobId": completed.id},
|
||||
after_state={
|
||||
"status": status,
|
||||
"revision": revision,
|
||||
"changedTargets": changed_targets,
|
||||
"changedTargetDetails": changed_details,
|
||||
"uncertainTargets": uncertain_targets,
|
||||
"verifiedTargets": verified_targets,
|
||||
},
|
||||
redacted_metadata={
|
||||
"executor": action,
|
||||
"integration": "mcp" if source == "chatgpt-mcp" else "operator",
|
||||
"originalPolicyDecision": original_policy_decision,
|
||||
"targetSelectionCallerSelectable": False,
|
||||
"pathOrCommandCallerSelectable": False,
|
||||
},
|
||||
)
|
||||
return {
|
||||
"success": success,
|
||||
"status": "success" if success else status,
|
||||
"result": "success" if success else "outcome_unknown" if status == "outcome_unknown" else "failed",
|
||||
"message": message,
|
||||
"jobId": completed.id,
|
||||
"auditId": audit.id,
|
||||
"policyDecision": "allowed",
|
||||
"originalPolicyDecision": original_policy_decision,
|
||||
"controllerStatus": status,
|
||||
"revision": revision,
|
||||
"changedTargets": changed_targets,
|
||||
"changedTargetDetails": changed_details,
|
||||
"uncertainTargets": uncertain_targets,
|
||||
"verifiedTargets": verified_targets,
|
||||
}
|
||||
|
||||
|
||||
@@ -1809,6 +2076,24 @@ def execute_governed_action(
|
||||
original_policy_decision=original_policy_decision,
|
||||
)
|
||||
|
||||
if action == "hub.migration.prepare_permissions":
|
||||
if target.strip().lower() != "tower/itworx-mcp-hub-permissions":
|
||||
return {
|
||||
"success": False,
|
||||
"status": "failed",
|
||||
"result": "blocked",
|
||||
"message": "MCP Hub permission preparation accepts only tower/itworx-mcp-hub-permissions.",
|
||||
"policyDecision": "blocked",
|
||||
"originalPolicyDecision": original_policy_decision,
|
||||
}
|
||||
return _execute_hub_migration_prepare_permissions(
|
||||
session,
|
||||
source=source,
|
||||
risk=risk,
|
||||
reason=reason,
|
||||
original_policy_decision=original_policy_decision,
|
||||
)
|
||||
|
||||
if action == "runner.fleet.upgrade_v2":
|
||||
if target.strip().lower() != "tower/runner-fleet-v2":
|
||||
return {
|
||||
@@ -1827,6 +2112,28 @@ def execute_governed_action(
|
||||
original_policy_decision=original_policy_decision,
|
||||
)
|
||||
|
||||
if action == "runner.statistics.configure":
|
||||
if target.strip().lower() != "tower/projectbrain-runner-statistics":
|
||||
return {"success": False, "status": "failed", "result": "blocked",
|
||||
"message": "Statistics configuration accepts only tower/projectbrain-runner-statistics.",
|
||||
"policyDecision": "blocked", "originalPolicyDecision": original_policy_decision}
|
||||
return _execute_runner_fleet_upgrade_v2(
|
||||
session, source=source, risk=risk, reason=reason,
|
||||
original_policy_decision=original_policy_decision, statistics_configuration=True,
|
||||
)
|
||||
|
||||
if action == "runner.fleet.specialize":
|
||||
if target.strip().lower() != "tower/runner-fleet-specialized":
|
||||
return {
|
||||
"success": False, "status": "failed", "result": "blocked",
|
||||
"message": "Runner specialization accepts only tower/runner-fleet-specialized.",
|
||||
"policyDecision": "blocked", "originalPolicyDecision": original_policy_decision,
|
||||
}
|
||||
return _execute_runner_fleet_upgrade_v2(
|
||||
session, source=source, risk=risk, reason=reason,
|
||||
original_policy_decision=original_policy_decision, specialized=True,
|
||||
)
|
||||
|
||||
if action == "deployment.runnerless.provision":
|
||||
return _execute_runnerless_target_provisioning(
|
||||
session,
|
||||
@@ -2287,6 +2594,44 @@ def execute_approved_action(session: Session, approval: Approval) -> dict[str, A
|
||||
original_policy_decision="approval_required",
|
||||
)
|
||||
|
||||
if approval.action == "runner.statistics.configure":
|
||||
if approval.target.strip().lower() != "tower/projectbrain-runner-statistics":
|
||||
return {"success": False, "status": "failed", "result": "blocked",
|
||||
"message": "Statistics configuration accepts only tower/projectbrain-runner-statistics."}
|
||||
return _execute_runner_fleet_upgrade_v2(
|
||||
session, source="approved_operator", risk=approval.risk,
|
||||
reason=approval.reason or f"Approved through {approval.id}.",
|
||||
original_policy_decision="approval_required", statistics_configuration=True,
|
||||
)
|
||||
|
||||
if approval.action == "runner.fleet.specialize":
|
||||
if approval.target.strip().lower() != "tower/runner-fleet-specialized":
|
||||
return {
|
||||
"success": False, "status": "failed", "result": "blocked",
|
||||
"message": "Runner specialization accepts only tower/runner-fleet-specialized.",
|
||||
}
|
||||
return _execute_runner_fleet_upgrade_v2(
|
||||
session, source="approved_operator", risk=approval.risk,
|
||||
reason=approval.reason or f"Approved through {approval.id}.",
|
||||
original_policy_decision="approval_required", specialized=True,
|
||||
)
|
||||
|
||||
if approval.action == "hub.migration.prepare_permissions":
|
||||
if approval.target.strip().lower() != "tower/itworx-mcp-hub-permissions":
|
||||
return {
|
||||
"success": False,
|
||||
"status": "failed",
|
||||
"result": "blocked",
|
||||
"message": "MCP Hub permission preparation accepts only tower/itworx-mcp-hub-permissions.",
|
||||
}
|
||||
return _execute_hub_migration_prepare_permissions(
|
||||
session,
|
||||
source="approved_operator",
|
||||
risk=approval.risk,
|
||||
reason=approval.reason or f"Approved through {approval.id}.",
|
||||
original_policy_decision="approval_required",
|
||||
)
|
||||
|
||||
if approval.action in {"unraid.vm.start", "unraid.vm.resume", "unraid.vm.pause"}:
|
||||
from .unraid_vm_service import execute_approved_vm_action
|
||||
|
||||
|
||||
Reference in new issue
Block a user