fix(recovery): classify ssh local metadata blockers
Some checks failed
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 35s
CD Pipeline / build-and-deploy (push) Failing after 28s
CD Pipeline / post-deploy-checks (push) Has been skipped

This commit is contained in:
Your Name
2026-07-01 12:46:21 +08:00
parent f963894995
commit 7019d4a005
2 changed files with 132 additions and 3 deletions

View File

@@ -198,6 +198,21 @@ def validate_harbor_registry_controlled_recovery_receipt(
"ssh_local_repair_control_channel_metadata_ready": ssh_local[
"control_channel_metadata_ready"
],
"ssh_local_repair_account_metadata_ready": ssh_local[
"account_metadata_ready"
],
"ssh_local_repair_target_user_account_locked": ssh_local[
"target_user_account_locked"
],
"ssh_local_repair_target_user_shell_executable": ssh_local[
"target_user_shell_executable"
],
"ssh_local_repair_sshd_pubkeyauthentication": ssh_local[
"sshd_pubkeyauthentication"
],
"ssh_local_repair_sshd_authorized_keys_file_default": ssh_local[
"sshd_authorized_keys_file_default"
],
"watchdog_check_receipt_seen": watchdog_check["receipt_seen"],
"watchdog_check_harbor_ready": watchdog_check["harbor_ready"],
"watchdog_repair_receipt_seen": watchdog_repair["receipt_seen"],
@@ -936,15 +951,23 @@ def _parse_ssh_local_repair_output(output: str) -> dict[str, Any]:
"SSHD_CONFIG_SYNTAX_AFTER_APPLY=ok" in output
or not _bool_from_field(fields.get("APPLY"))
)
user_exists = "USER_STATUS user=" in output and "exists=1" in output
authorized_keys_exists = (
"AUTHORIZED_KEYS_STATUS" in output and "exists=1" in output
user_status = _first_key_value_line(output, prefix="USER_STATUS ")
authorized_keys_status = _first_key_value_line(
output,
prefix="AUTHORIZED_KEYS_STATUS ",
)
user_exists = _bool_from_field(user_status.get("exists"))
authorized_keys_exists = _bool_from_field(authorized_keys_status.get("exists"))
account_locked = _bool_from_field(fields.get("account_locked"))
shell_executable = _bool_from_field(fields.get("shell_executable"))
sshd_effective_config_available = _bool_from_field(fields.get("available"))
pubkey_authentication = str(fields.get("pubkeyauthentication") or "")
password_authentication = str(fields.get("passwordauthentication") or "")
kbdinteractive_authentication = str(
fields.get("kbdinteractiveauthentication") or ""
)
usepam = str(fields.get("usepam") or "")
maxstartups = str(fields.get("maxstartups") or "")
authorized_keys_file_default = _bool_from_field(
fields.get("authorized_keys_file_default")
)
@@ -968,7 +991,10 @@ def _parse_ssh_local_repair_output(output: str) -> dict[str, Any]:
"target_user_shell_executable": shell_executable,
"sshd_effective_config_available": sshd_effective_config_available,
"sshd_pubkeyauthentication": pubkey_authentication,
"sshd_passwordauthentication": password_authentication,
"sshd_kbdinteractiveauthentication": kbdinteractive_authentication,
"sshd_usepam": usepam,
"sshd_maxstartups": maxstartups,
"sshd_authorized_keys_file_default": authorized_keys_file_default,
"account_metadata_ready": account_metadata_ready,
"authorized_keys_metadata_present": authorized_keys_exists,
@@ -986,6 +1012,13 @@ def _parse_ssh_local_repair_output(output: str) -> dict[str, Any]:
}
def _first_key_value_line(output: str, *, prefix: str) -> dict[str, str]:
for line in output.splitlines():
if line.startswith(prefix):
return _parse_key_values(line)
return {}
def _parse_watchdog_output(output: str) -> dict[str, Any]:
fields = _parse_key_values(output)
marker_seen = "AWOOOI_HARBOR_WATCHDOG_CHECK" in output
@@ -1804,6 +1837,7 @@ def _active_blockers(
if ssh_diagnosis["node_high_load_seen"]:
blockers.append("ssh_publickey_node_high_load_on_110")
if ssh_local["receipt_seen"] and not ssh_local["control_channel_metadata_ready"]:
blockers.extend(_ssh_local_metadata_blockers(ssh_local))
blockers.append("ssh_local_repair_receipt_metadata_not_ready")
if not watchdog_check["receipt_seen"]:
blockers.append("harbor_watchdog_check_receipt_missing")
@@ -1826,6 +1860,29 @@ def _active_blockers(
return _unique_strings(blockers)
def _ssh_local_metadata_blockers(ssh_local: dict[str, Any]) -> list[str]:
blockers: list[str] = []
if not ssh_local["sshd_config_syntax_ok"]:
blockers.append("ssh_local_repair_sshd_config_syntax_not_ok")
if not ssh_local["sshd_config_syntax_after_apply_ok"]:
blockers.append("ssh_local_repair_sshd_config_syntax_after_apply_not_ok")
if not ssh_local["target_user_exists"]:
blockers.append("ssh_local_repair_target_user_missing")
if ssh_local["target_user_account_locked"]:
blockers.append("ssh_local_repair_target_user_account_locked")
if not ssh_local["target_user_shell_executable"]:
blockers.append("ssh_local_repair_target_user_shell_not_executable")
if not ssh_local["authorized_keys_metadata_present"]:
blockers.append("ssh_local_repair_authorized_keys_missing")
if not ssh_local["sshd_effective_config_available"]:
blockers.append("ssh_local_repair_sshd_effective_config_unavailable")
if ssh_local["sshd_pubkeyauthentication"] != "yes":
blockers.append("ssh_local_repair_sshd_pubkeyauthentication_not_enabled")
if not ssh_local["sshd_authorized_keys_file_default"]:
blockers.append("ssh_local_repair_sshd_authorized_keys_file_drift")
return blockers
def _status(
*,
ssh_diagnosis: dict[str, Any],

View File

@@ -75,6 +75,78 @@ def test_harbor_recovery_receipt_accepts_verified_repair() -> None:
assert payload["learning_writeback_contracts"][0]["raw_log_allowed"] is False
def test_harbor_recovery_receipt_surfaces_ssh_local_metadata_blockers() -> None:
ssh_local_output = (
_ssh_local_apply_output()
.replace(
"account_locked=false shell=/bin/bash shell_exists=true shell_executable=true",
"account_locked=true shell=/bin/false shell_exists=true shell_executable=false",
)
.replace(
"AUTHORIZED_KEYS_STATUS path=/home/wooo/.ssh/authorized_keys exists=1 bytes=380 lines=1",
"AUTHORIZED_KEYS_STATUS path=/home/wooo/.ssh/authorized_keys exists=0",
)
.replace(
"pubkeyauthentication=yes passwordauthentication=no "
"kbdinteractiveauthentication=no usepam=yes maxstartups=10:30:100 "
"authorized_keys_file_default=true",
"pubkeyauthentication=no passwordauthentication=no "
"kbdinteractiveauthentication=no usepam=yes maxstartups=10:30:100 "
"authorized_keys_file_default=false",
)
)
payload = validate_harbor_registry_controlled_recovery_receipt(
{"ssh_local_repair_output": ssh_local_output}
)
assert payload["status"] == (
"ssh_local_repair_receipt_waiting_harbor_watchdog_check"
)
assert "ssh_local_repair_target_user_account_locked" in payload[
"active_blockers"
]
assert "ssh_local_repair_target_user_shell_not_executable" in payload[
"active_blockers"
]
assert "ssh_local_repair_authorized_keys_missing" in payload["active_blockers"]
assert "ssh_local_repair_sshd_pubkeyauthentication_not_enabled" in payload[
"active_blockers"
]
assert "ssh_local_repair_sshd_authorized_keys_file_drift" in payload[
"active_blockers"
]
assert "ssh_local_repair_receipt_metadata_not_ready" in payload[
"active_blockers"
]
ssh_local = payload["readback"]["ssh_local_repair"]
assert ssh_local["control_channel_metadata_ready"] is False
assert ssh_local["account_metadata_ready"] is False
assert ssh_local["target_user_account_locked"] is True
assert ssh_local["target_user_shell_executable"] is False
assert ssh_local["authorized_keys_metadata_present"] is False
assert ssh_local["sshd_pubkeyauthentication"] == "no"
assert ssh_local["sshd_passwordauthentication"] == "no"
assert ssh_local["sshd_kbdinteractiveauthentication"] == "no"
assert ssh_local["sshd_maxstartups"] == "10:30:100"
assert ssh_local["sshd_authorized_keys_file_default"] is False
assert payload["rollups"]["ssh_local_repair_account_metadata_ready"] is False
assert (
payload["rollups"]["ssh_local_repair_target_user_account_locked"] is True
)
assert (
payload["rollups"]["ssh_local_repair_target_user_shell_executable"]
is False
)
assert payload["rollups"]["ssh_local_repair_sshd_pubkeyauthentication"] == "no"
assert (
payload["rollups"]["ssh_local_repair_sshd_authorized_keys_file_default"]
is False
)
assert payload["input_redaction"]["ssh_local_repair_output"]["line_count"] > 0
assert "secret-token-like-content" not in str(payload)
def test_harbor_recovery_receipt_routes_unhealthy_check_to_repair_once() -> None:
payload = validate_harbor_registry_controlled_recovery_receipt(
{