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
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:
@@ -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],
|
||||
|
||||
@@ -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(
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user