Publish curated Unraid-AppOps-Gateway source from ad0a390e431166c3198a2ac3bec010c2b44f2dea

This commit is contained in:
Public Source Publisher committed 2026-10-02 09:56:13 +00:00
1 parent 29c1e3d5a1
commit 98d31477f9
35 files changed
+7264 -185

No files matched your search

+432
View File
@@ -2226,6 +2226,96 @@ def test_managed_repopulse_render_accepts_only_its_read_only_source_mount(
deploy_module.validate_managed_v1_runtime(project, "a" * 40, "jens/repopulse")
def test_managed_appdata_roots_are_fixed_and_bound_to_each_registration(
deploy_module, monkeypatch, tmp_path
):
legacy_root = tmp_path / "legacy-appdata"
managed_root = tmp_path / "managed-volume" / "_data"
monkeypatch.setattr(deploy_module, "LEGACY_MANAGED_APPCONFIG_ROOT", legacy_root)
monkeypatch.setattr(deploy_module, "MANAGED_APPCONFIG_ROOT", legacy_root)
monkeypatch.setattr(deploy_module, "MANAGED_APPCONFIG_VOLUME_ROOT", managed_root)
monkeypatch.setattr(deploy_module, "managed_appdata_volume_initialized", lambda: False)
assert deploy_module._registered_managed_appdata_root({}) == legacy_root
assert deploy_module._registered_managed_appdata_root(
{"managed_appdata_root": legacy_root.as_posix()}
) == legacy_root
with pytest.raises(deploy_module.DeployError, match="not initialized and available"):
deploy_module._registered_managed_appdata_root(
{"managed_appdata_root": managed_root.as_posix()}
)
with pytest.raises(deploy_module.DeployError, match="fixed registered roots"):
deploy_module._registered_managed_appdata_root(
{"managed_appdata_root": (tmp_path / "arbitrary").as_posix()}
)
monkeypatch.setattr(deploy_module, "managed_appdata_volume_initialized", lambda: True)
assert deploy_module._registered_managed_appdata_root(
{"managed_appdata_root": managed_root.as_posix()}
) == managed_root
for root, host in ((legacy_root, "legacy.example"), (managed_root, "managed.example")):
env_path = root / "demo" / "deploy.env"
env_path.parent.mkdir(parents=True)
env_path.write_text(f"APPOPS_PUBLIC_URL=https://{host}\n", encoding="utf-8")
if os.name != "nt":
env_path.chmod(0o600)
project = {
"appops_managed_target": True,
"managed_plan_version": "itworx.deployment/v1",
"managed_profile": "internal-webapp",
"managed_application_id": "demo",
"managed_runtime_environment_keys": ["APPOPS_PUBLIC_URL"],
"env_source": (legacy_root / "demo" / "deploy.env").as_posix(),
}
assert deploy_module.managed_runtime_environment(project) == {
"APPOPS_PUBLIC_URL": "https://legacy.example"
}
project["managed_appdata_root"] = managed_root.as_posix()
project["env_source"] = (managed_root / "demo" / "deploy.env").as_posix()
assert deploy_module.managed_runtime_environment(project) == {
"APPOPS_PUBLIC_URL": "https://managed.example"
}
def test_managed_project_path_is_derived_from_its_stored_appdata_root(
deploy_module, monkeypatch
):
monkeypatch.setattr(deploy_module, "managed_appdata_volume_initialized", lambda: True)
monkeypatch.setattr(deploy_module, "git_path_exists", lambda *_args: True)
project = {
"containers": ["demo"],
"source_dir": (deploy_module.EXACT_SOURCE_ROOT / "demo").as_posix(),
"exact_source": True,
"compose_dir": ".",
"compose_files": ["compose.yml"],
"compose_project": "demo",
"managed_plan_version": "itworx.deployment/v1",
"managed_application_id": "demo",
"managed_appdata_path": "/srv/example/appdata/demo",
"managed_image_repository": "demo",
"managed_image_tag": "production",
"managed_proxy_network": "itworx-proxy",
"managed_internal_port": 8000,
"appops_deployment_secret_file": "jens__demo",
}
deploy_module.validate_project_config(Path("repo.git"), project, "a" * 40)
managed = {
**project,
"managed_appdata_root": deploy_module.MANAGED_APPCONFIG_VOLUME_ROOT.as_posix(),
"managed_appdata_path": (
deploy_module.MANAGED_APPCONFIG_VOLUME_ROOT / "demo"
).as_posix(),
}
deploy_module.validate_project_config(Path("repo.git"), managed, "a" * 40)
remapped = {**managed, "managed_appdata_path": "/srv/example/appdata/demo"}
with pytest.raises(deploy_module.DeployError, match="not derived"):
deploy_module.validate_project_config(Path("repo.git"), remapped, "a" * 40)
def test_repopulse_project_registry_requires_its_fixed_build_identity(
deploy_module, monkeypatch
):
@@ -4582,6 +4672,25 @@ def _appops_plan(revision: str) -> dict[str, object]:
}
def test_appops_plan_root_must_match_the_registered_target_root(status_module):
project = _appops_project()
plan = _appops_plan("a" * 40)
assert status_module._appops_plan({"jens/repo-a": project}, plan) == (
"jens/repo-a", "a" * 40, project,
)
project["managed_appdata_root"] = "/var/lib/docker/volumes/itworx-managed-appdata/_data"
project["managed_appdata_path"] = "/var/lib/docker/volumes/itworx-managed-appdata/_data/repo-a"
alternate_plan = {**plan, "trusted_appdata_root": "/var/lib/docker/volumes/itworx-managed-appdata/_data"}
assert status_module._appops_plan({"jens/repo-a": project}, alternate_plan) == (
"jens/repo-a", "a" * 40, project,
)
assert status_module._appops_plan({"jens/repo-a": project}, plan) is None
drifted = {**project, "managed_appdata_path": "/srv/example/appdata/repo-a"}
assert status_module._appops_plan({"jens/repo-a": drifted}, alternate_plan) is None
def _write_appops_secret(root: Path, name: str, value: bytes) -> None:
root.mkdir(mode=0o700)
root.chmod(0o700)
@@ -5838,6 +5947,7 @@ def _controller_enrollment_payload(*, credential: bool = False) -> dict[str, obj
"profile": "internal-webapp-oidc",
"container_name": "wsbc-portal",
"compose_file": ".itworx/deployment.yml",
"trusted_appdata_root": "/srv/example/appdata",
"appdata_path": "/srv/example/appdata/wsbc-portal",
"data_path": "/srv/example/appdata/wsbc-portal/data",
"runtime_uid": 1654,
@@ -5871,6 +5981,7 @@ def _repopulse_controller_enrollment_payload(*, credential: bool = False) -> dic
"profile": "repopulse-authenticated",
"container_name": "repopulse",
"compose_file": ".itworx/deployment.yml",
"trusted_appdata_root": "/srv/example/appdata",
"appdata_path": "/srv/example/appdata/repopulse",
"data_path": "/srv/example/appdata/repopulse/data",
"runtime_uid": 10001,
@@ -5929,8 +6040,10 @@ def test_controller_repopulse_runtime_seal_fixes_gitea_url_and_hides_values(stat
env_path = app_root / "deploy.managed.env"
env_path.write_text("", encoding="utf-8")
monkeypatch.setattr(status_module, "TRUSTED_APPCONFIG_ROOT", appdata_root)
monkeypatch.setattr(status_module, "LEGACY_APPDATA_ROOT", appdata_root)
monkeypatch.setattr(status_module, "EXACT_SOURCE_ROOT", tmp_path / "sources")
payload = _repopulse_controller_enrollment_payload(credential=True)
payload["trusted_appdata_root"] = appdata_root.as_posix()
payload["appdata_path"] = app_root.as_posix()
payload["data_path"] = (app_root / "data").as_posix()
enrollment = status_module._controller_enrollment(payload, require_credential=True)
@@ -6106,6 +6219,76 @@ def test_controller_enrollment_contract_rejects_arbitrary_compose_and_paths(stat
assert status_module._controller_enrollment(unsafe, require_credential=True) is None
def test_controller_enrollment_derives_paths_from_the_selected_fixed_root(status_module, monkeypatch):
managed_root = "/var/lib/docker/volumes/itworx-managed-appdata/_data"
monkeypatch.setattr(status_module, "TRUSTED_APPCONFIG_ROOT", Path(managed_root))
monkeypatch.setattr(status_module, "appdata_root_is_safe", lambda root: root.as_posix() == managed_root)
alternate = _controller_enrollment_payload()
alternate["trusted_appdata_root"] = managed_root
alternate["appdata_path"] = managed_root + "/wsbc-portal"
alternate["data_path"] = managed_root + "/wsbc-portal/data"
enrollment = status_module._controller_enrollment(alternate, require_credential=False)
assert enrollment is not None
project = status_module._enrollment_project(enrollment)
assert project["managed_appdata_root"] == managed_root
assert project["managed_appdata_path"] == managed_root + "/wsbc-portal"
unsafe_path = {**alternate, "data_path": "/srv/example/appdata/wsbc-portal/data"}
assert status_module._controller_enrollment(unsafe_path, require_credential=False) is None
unsupported_root = {**alternate, "trusted_appdata_root": "/srv/example/other"}
assert status_module._controller_enrollment(unsupported_root, require_credential=False) is None
def test_controller_accepts_legacy_requests_after_managed_marker_is_initialized(status_module, monkeypatch):
managed_root = "/var/lib/docker/volumes/itworx-managed-appdata/_data"
monkeypatch.setattr(status_module, "_refresh_appdata_root_selection", lambda: Path(managed_root))
monkeypatch.setattr(status_module, "appdata_root_is_safe", lambda root: root.as_posix() == managed_root)
legacy = _controller_enrollment_payload()
assert legacy["trusted_appdata_root"] == "/srv/example/appdata"
enrollment = status_module._controller_enrollment(legacy, require_credential=False)
assert enrollment is not None
assert enrollment["trusted_appdata_root"] == "/srv/example/appdata"
assert "managed_appdata_root" not in status_module._enrollment_project(enrollment)
def test_controller_accepts_legacy_v1_payload_without_root_field(status_module):
legacy = _controller_enrollment_payload()
legacy.pop("trusted_appdata_root")
enrollment = status_module._controller_enrollment(legacy, require_credential=False)
assert enrollment is not None
assert enrollment["trusted_appdata_root"] == "/srv/example/appdata"
assert "managed_appdata_root" not in status_module._enrollment_project(enrollment)
def test_repopulse_enrollment_remains_bound_to_legacy_appdata_root(status_module, monkeypatch):
monkeypatch.setattr(status_module, "TRUSTED_APPCONFIG_ROOT", Path("/var/lib/docker/volumes/itworx-managed-appdata/_data"))
payload = _repopulse_controller_enrollment_payload()
payload["trusted_appdata_root"] = "/var/lib/docker/volumes/itworx-managed-appdata/_data"
payload["appdata_path"] = "/var/lib/docker/volumes/itworx-managed-appdata/_data/repopulse"
payload["data_path"] = "/var/lib/docker/volumes/itworx-managed-appdata/_data/repopulse/data"
assert status_module._controller_enrollment(payload, require_credential=False) is None
def test_fixed_repopulse_profile_stays_legacy_with_managed_marker(status_module, monkeypatch):
managed_root = "/var/lib/docker/volumes/itworx-managed-appdata/_data"
monkeypatch.setattr(status_module, "_refresh_appdata_root_selection", lambda: Path(managed_root))
monkeypatch.setattr(status_module, "appdata_root_is_safe", lambda root: root.as_posix() == managed_root)
enrollment = status_module._controller_enrollment(
_repopulse_controller_enrollment_payload(),
require_credential=False,
)
assert enrollment is not None
assert enrollment["trusted_appdata_root"] == "/srv/example/appdata"
def test_controller_runtime_seal_accepts_only_profile_owned_keys(status_module, tmp_path, monkeypatch):
appdata_root = tmp_path / "appdata"
app_root = appdata_root / "wsbc-portal"
@@ -6113,8 +6296,10 @@ def test_controller_runtime_seal_accepts_only_profile_owned_keys(status_module,
env_path = app_root / "deploy.env"
env_path.write_text("", encoding="utf-8")
monkeypatch.setattr(status_module, "TRUSTED_APPCONFIG_ROOT", appdata_root)
monkeypatch.setattr(status_module, "LEGACY_APPDATA_ROOT", appdata_root)
monkeypatch.setattr(status_module, "EXACT_SOURCE_ROOT", tmp_path / "sources")
payload = _controller_enrollment_payload(credential=True)
payload["trusted_appdata_root"] = appdata_root.as_posix()
payload["appdata_path"] = app_root.as_posix()
payload["data_path"] = (app_root / "data").as_posix()
enrollment = status_module._controller_enrollment(payload, require_credential=True)
@@ -6154,6 +6339,7 @@ def test_controller_enrollment_replay_requires_the_existing_target_credential(st
projects_path.write_text(json.dumps({"jens/windows-support-bundle-collector": project}), encoding="utf-8")
monkeypatch.setattr(status_module, "PROJECTS_PATH", projects_path)
monkeypatch.setattr(status_module, "APPOPS_DEPLOYMENT_SECRET_ROOT", secrets_root)
monkeypatch.setattr(status_module, "appdata_root_is_safe", lambda _root: True)
enrollment["target_credential"] = "y" * 64
status, _evidence = status_module._enroll_controller_target(enrollment)
@@ -7316,3 +7502,249 @@ def test_workmesh_backup_receipt_requires_bound_manifest_and_verified_restore_by
assert status_module._verified_workmesh_backup_receipt(
request_id, candidate, preflight, inputs
) is None
def _managed_storage_http_request(
status_module,
server,
*,
body: bytes,
nonce: str,
secret: bytes | None,
signature: str | None = None,
signed_path: str | None = None,
):
path = status_module.MANAGED_APPDATA_INITIALIZE_PATH
timestamp = str(int(status_module.time.time()))
headers = {"Content-Type": "application/json", "Content-Length": str(len(body))}
if nonce:
headers["X-ITWorx-Deployment-Nonce"] = nonce
if timestamp:
headers["X-ITWorx-Deployment-Timestamp"] = timestamp
if signature is None and secret is not None:
signature = status_module._request_signature(
secret,
method="POST",
path=signed_path or path,
timestamp=timestamp,
nonce=nonce,
raw_body=body,
)
if signature is not None:
headers["X-ITWorx-Deployment-Signature"] = signature
connection = http.client.HTTPConnection(*server.server_address, timeout=2)
connection.request("POST", path, body=body, headers=headers)
response = connection.getresponse()
status = response.status
payload = json.loads(response.read())
connection.close()
return status, payload, headers
def test_managed_appdata_initializer_http_requires_exact_signed_one_time_request(
status_module, tmp_path, monkeypatch
):
secret = b"managed-storage-bootstrap-" + b"x" * 48
secret_path = tmp_path / "bootstrap"
secret_path.write_bytes(secret)
secret_path.chmod(0o600)
nonce_root = tmp_path / "nonces"
monkeypatch.setattr(status_module, "APPOPS_ENROLLMENT_BOOTSTRAP_SECRET_FILE", secret_path)
monkeypatch.setattr(status_module, "APPOPS_NONCE_ROOT", nonce_root)
monkeypatch.setattr(
status_module.Handler,
"_managed_storage_initialization_prerequisites",
lambda _handler: True,
)
initialized = []
monkeypatch.setattr(
status_module,
"ensure_managed_appdata_root",
lambda: initialized.append(True) or "initialized",
)
monkeypatch.setattr(
status_module,
"_refresh_appdata_root_selection",
lambda: status_module.MANAGED_APPDATA_ROOT,
)
server = status_module.BoundedThreadingHTTPServer(
("127.0.0.1", 0), status_module.Handler
)
serving = threading.Thread(target=server.serve_forever, daemon=True)
serving.start()
body = json.dumps(
{
"apiVersion": status_module.MANAGED_APPDATA_INITIALIZE_API_VERSION,
"target": status_module.MANAGED_APPDATA_INITIALIZE_TARGET,
},
separators=(",", ":"),
).encode("utf-8")
try:
success_status, success_payload, success_headers = _managed_storage_http_request(
status_module,
server,
body=body,
nonce="a" * 32,
secret=secret,
)
assert success_status == 200
assert success_payload == {
"status": "initialized",
"trustedAppdataRoot": status_module.MANAGED_APPDATA_ROOT.as_posix(),
"backupLocation": "dockerRootDir",
}
assert initialized == [True]
assert secret.decode("ascii") not in json.dumps(success_payload)
replay = http.client.HTTPConnection(*server.server_address, timeout=2)
replay.request(
"POST",
status_module.MANAGED_APPDATA_INITIALIZE_PATH,
body=body,
headers=success_headers,
)
replay_response = replay.getresponse()
replay_payload = json.loads(replay_response.read())
replay.close()
assert replay_response.status == 403
assert replay_payload == {"status": "authentication_rejected"}
assert initialized == [True]
invalid_requests = [
_managed_storage_http_request(
status_module,
server,
body=body,
nonce="b" * 32,
secret=secret,
signature="0" * 64,
),
_managed_storage_http_request(
status_module,
server,
body=body,
nonce="c" * 32,
secret=secret,
signed_path="/v1/appops/enrollments/capabilities",
),
_managed_storage_http_request(
status_module,
server,
body=body,
nonce="d" * 32,
secret=None,
),
]
assert [status for status, _payload, _headers in invalid_requests] == [403, 403, 403]
assert initialized == [True]
for index, payload in enumerate(
[
{
"apiVersion": status_module.MANAGED_APPDATA_INITIALIZE_API_VERSION,
"target": "tower/other-controller",
},
{
"apiVersion": status_module.MANAGED_APPDATA_INITIALIZE_API_VERSION,
"target": status_module.MANAGED_APPDATA_INITIALIZE_TARGET,
"path": "C:/private/sentinel",
},
],
start=1,
):
raw_body = json.dumps(payload, separators=(",", ":")).encode("utf-8")
rejected_status, rejected_payload, _headers = _managed_storage_http_request(
status_module,
server,
body=raw_body,
nonce=f"{index:032x}",
secret=secret,
)
assert rejected_status == 400
assert rejected_payload == {"status": "invalid_managed_storage_request"}
assert "C:/private/sentinel" not in json.dumps(rejected_payload)
oversized_status, oversized_payload, _headers = _managed_storage_http_request(
status_module,
server,
body=b"x" * 1025,
nonce="e" * 32,
secret=None,
)
assert oversized_status == 413
assert oversized_payload == {"status": "invalid_body_size"}
assert initialized == [True]
finally:
server.shutdown()
server.server_close()
serving.join(timeout=2)
def test_managed_appdata_initializer_http_prerequisite_and_refusal_are_sanitized(
status_module, tmp_path, monkeypatch
):
secret = b"managed-storage-bootstrap-" + b"y" * 48
secret_path = tmp_path / "bootstrap"
secret_path.write_bytes(secret)
secret_path.chmod(0o600)
monkeypatch.setattr(status_module, "APPOPS_ENROLLMENT_BOOTSTRAP_SECRET_FILE", secret_path)
monkeypatch.setattr(status_module, "APPOPS_NONCE_ROOT", tmp_path / "nonces")
prerequisites = {"ready": False}
monkeypatch.setattr(
status_module.Handler,
"_managed_storage_initialization_prerequisites",
lambda _handler: prerequisites["ready"],
)
calls = []
monkeypatch.setattr(
status_module,
"ensure_managed_appdata_root",
lambda: calls.append(True) or "initialized",
)
monkeypatch.setattr(
status_module,
"_refresh_appdata_root_selection",
lambda: status_module.MANAGED_APPDATA_ROOT,
)
server = status_module.BoundedThreadingHTTPServer(
("127.0.0.1", 0), status_module.Handler
)
serving = threading.Thread(target=server.serve_forever, daemon=True)
serving.start()
body = json.dumps(
{
"apiVersion": status_module.MANAGED_APPDATA_INITIALIZE_API_VERSION,
"target": status_module.MANAGED_APPDATA_INITIALIZE_TARGET,
},
separators=(",", ":"),
).encode("utf-8")
try:
status, payload, _headers = _managed_storage_http_request(
status_module, server, body=body, nonce="f" * 32, secret=secret
)
assert status == 503
assert payload == {"status": "managed_storage_prerequisite_unavailable"}
assert calls == []
prerequisites["ready"] = True
def refuse_with_sensitive_diagnostic():
raise status_module.UnsafeManagedAppdataRoot(
"secret/path sentinel C:/private/appdata"
)
monkeypatch.setattr(
status_module, "ensure_managed_appdata_root", refuse_with_sensitive_diagnostic
)
status, payload, _headers = _managed_storage_http_request(
status_module, server, body=body, nonce="1" * 32, secret=secret
)
assert status == 409
assert payload == {"status": "managed_storage_initialization_refused"}
assert "secret/path sentinel" not in json.dumps(payload)
assert "C:/private/appdata" not in json.dumps(payload)
assert secret.decode("ascii") not in json.dumps(payload)
finally:
server.shutdown()
server.server_close()
serving.join(timeout=2)