CHAT_OUTPUT_BEGIN
COMMAND_ID=SUPPORT-260922-SPB-ACME-CERTBOT-FAIL-RCA-9124R1
STATUS=OK
RC=0
HOST=pve01
MODE=read-only
COMPONENT=spb-acme-certbot-fail-rca
REFERENCE_REGISTER_CHECK=OK
REFERENCE_SHA256=5a3d8e5154c41cb582a4e0aca68090be1f0138918bf82131a948df326f9d8d66
ERROR_REGISTER_CHECK=OK
ERROR_REGISTER_SHA256=3b09a553ec0f527ed3afeed4753f52a74ee3036045bbfb3c685e9f8af4ba7ba0
COMMAND_SHA256=65e45035e738859d7301cc86383acdbc514310a22e8a10f9a86928f593b10521
DUPLICATE_FAILED_COMMAND_BLOCKED=false
EXECUTION_STARTED=true
CHANGE_DECLARED=false
RESULT_CONTRACT_VALID=true
RESULT_CONTRACT_STATUS=NOT_APPLICABLE
RESULT_CONTRACT_ERROR=NONE
COMMAND_RC=0
CHANGES_MADE=false
ROLLBACK_STARTED=false
ROLLBACK_RESTORED=null
MUTATION_OUTCOME=NO_MUTATION
SANITIZED=yes
SECRETS_INCLUDED=no
PRIVATE_ADDRESSES_INCLUDED=no
RAW_EVIDENCE_SHA256=0d656c5cf4c2e5febffda0117d173fb22f193ad50645d09c55e3eb5d4bbcb85c
SANITIZED_OUTPUT_SHA256=0d656c5cf4c2e5febffda0117d173fb22f193ad50645d09c55e3eb5d4bbcb85c
OUTPUT_BEGIN
SPB9124_RCA={"guest":{"ok":true,"data":{"hook":{"exists":true,"sha256":"dcaffc5a248359fa3ed93b7bf8af33ad69985776c4a8e3e7f2016c6168da5aee","sha_matches_9120":true,"functions":["out","token","api","zone_id","state_path","auth","cleanup"],"safe_to_import_without_main":false,"unsafe_top_level_types":["Expr"],"selected_string_constants":[".json","/dns_records","/dns_records/","/opt/npmplus/secure/gram1_cf_token","/zones/","/zones?","GRAM1_CF_ZONE_LOOKUP ok=no http=","GRAM1_CF_ZONE_LOOKUP ok=yes id_prefix=","_acme-challenge.","gram1.ru","https://api.cloudflare.com/client/v4","www.gram1.ru","zone_id"],"function_sources":{"token":["def token(): return TOKEN_PATH.read_text(encoding=\"utf-8\").strip()"],"api":["def api(method, path, payload=None):","    data = json.dumps(payload).encode(\"utf-8\") if payload is not None else None","    req = urllib.request.Request(\"https://api.cloudflare.com/client/v4\" + path, data=data, headers={\"Authorization\": \"Bearer[REDACTED_EXPR]\" + token(), \"Content-Type\": \"application/json\"}, method=method)","    try:","        with urllib.request.urlopen(req, timeout=25) as r: return r.status, json.loads(r.read().decode(\"utf-8\", \"replace\"))","    except urllib.error.HTTPError as e:","        try: body = json.loads(e.read().decode(\"utf-8\", \"replace\"))","        except Exception: body = {\"success\": False, \"errors\": [{\"message\": \"http_error_non_json\"}]}","        return e.code, body"],"zone_id":["def zone_id():","    status, data = api(\"GET\", \"/zones?\" + urllib.parse.urlencode({\"name\": ZONE}))","    if not data.get(\"success\") or not data.get(\"result\"):","        out(f\"GRAM1_CF_ZONE_LOOKUP ok=no http={status}\"); return None","    zid = data[\"result\"][0][\"id\"]; out(f\"GRAM1_CF_ZONE_LOOKUP ok=yes id_prefix={zid[:8]}\"); return zid"],"auth":["def auth():","    domain = os.environ.get(\"CERTBOT_DOMAIN\", \"\"); validation = os.environ.get(\"CERTBOT_VALIDATION\", \"\")","    if domain not in (\"gram1.ru\", \"www.gram1.ru\") or not validation:","        out(f\"GRAM1_CF_AUTH domain={domain} status=review reason=bad_env\"); return 2","    zid = zone_id()","    if not zid: return 2","    name = \"_acme-challenge.\" + domain","    status, data = api(\"POST\", f\"/zones/{zid}/dns_records\", {\"type\": \"TXT\", \"name\": name, \"content\": validation, \"ttl\": 120})","    if not data.get(\"success\"):","        errs = data.get(\"errors\") or []; msg = str(errs[0].get(\"message\", \"\"))[:80].replace(\"\\n\", \" \") if errs else \"\"","        out(f\"GRAM1_CF_AUTH domain={domain} status=review http={status} error={msg}\"); return 2","    rec = data[\"result\"][\"id\"]; state_path(domain, validation).write_text(json.dumps({\"zone_id\": zid, \"record_id\": rec}), encoding=\"utf-8\")","    out(f\"GRAM1_CF_AUTH domain={domain} status=ok record_id_prefix={rec[:8]}\"); time.sleep(45); return 0"],"cleanup":["def cleanup():","    domain = os.environ.get(\"CERTBOT_DOMAIN\", \"\"); validation = os.environ.get(\"CERTBOT_VALIDATION\", \"\")","    sp = state_path(domain, validation)","    if sp.exists():","        try:","            data = json.loads(sp.read_text(encoding=\"utf-8\"))","            status, resp = api(\"DELETE\", f\"/zones/{data['zone_id']}/dns_records/{data['record_id']}\")","            out(f\"GRAM1_CF_CLEANUP domain={domain} status={'ok' if resp.get('success') else 'review'} http={status}\"); sp.unlink(missing_ok=True)","        except Exception as e: out(f\"GRAM1_CF_CLEANUP domain={domain} status=review error={type(e).__name__}\")","    else: out(f\"GRAM1_CF_CLEANUP domain={domain} status=skip reason=no_state\")","    return 0"]}},"cloudflare_readonly":{},"certbot":{"data_mount_found":true,"data_mount_hash":"ec0ac67820f88633","config_exists":true,"config_mode":"0o700","account_json_count":6,"renewal_count":13,"renewal_basenames":["hbarhub.ru.conf","newfi-staging-gram1-ru.conf","newfilya.ru.conf","npm-17.conf","npm-21.conf","npm-26.conf","npm-27.conf","npm-29.conf","npm-30.conf","npm-31.conf","npm-32.conf","npm-35.conf","npm-38.conf"],"certificates_rc":0,"certificates_diag":["Renewal configuration file [PATH] produced an unexpected error: expected [PATH] to be a symlink. Skipping.","Renewal configuration file [PATH] produced an unexpected error: expected [PATH] to be a symlink. Skipping.","Renewal configuration file [PATH] produced an unexpected error: expected [PATH] to be a symlink. Skipping.","Renewal configuration file [PATH] produced an unexpected error: expected [PATH] to be a symlink. Skipping.","Renewal configuration file [PATH] produced an unexpected error: expected [PATH] to be a symlink. Skipping.","Renewal configuration file [PATH] produced an unexpected error: expected [PATH] to be a symlink. Skipping.","Renewal configuration file [PATH] produced an unexpected error: expected [PATH] to be a symlink. Skipping.","Renewal configuration file [PATH] produced an unexpected error: expected [PATH] to be a symlink. Skipping.","Renewal configuration file [PATH] produced an unexpected error: expected [PATH] to be a symlink. Skipping.","Renewal configuration file [PATH] produced an unexpected error: expected [PATH] to be a symlink. Skipping.","Renewal configuration file [PATH] produced an unexpected error: expected [PATH] to be a symlink. Skipping.","Renewal configuration file [PATH] produced an unexpected error: expected [PATH] to be a symlink. Skipping.","Renewal configuration file [PATH] produced an unexpected error: expected [PATH] to be a symlink. Skipping.","The following renewal configurations were invalid:","  [PATH]","  [PATH]","  [PATH]","  [PATH]","  [PATH]","  [PATH]","  [PATH]","  [PATH]","  [PATH]","  [PATH]","  [PATH]","  [PATH]","  [PATH]"],"certificates_stderr_sha":"d744a29aaabe2413","show_account_rc":1,"show_account_diag":["An unexpected error occurred:","ValueError: Requesting acme-v02.api.letsencrypt.org/directory: No route to host"],"gitread_live_exists":false,"gitread_renewal_exists":false,"new_vhost_files_exist":[]},"locks":{"present":[]},"processes":{"certbot_related":[]}}}}
TASK_COMPLETE=true
TASK_RESULT=PASS_SPB_ACME_CERTBOT_FAIL_RCA
DECISION=READ_EXACT_9124_THEN_CORRECT_ACME_EXECUTION_PATH

OUTPUT_END
CHAT_OUTPUT_END
