// SPEC: PJ2026-01060307 控制面模块化 draft-2026-06-25-p0. secrets module for scripts/src/hwlab-g14.ts. // Moved mechanically from scripts/src/hwlab-g14.ts:5055-5524 for #903. import { chmodSync, existsSync, mkdirSync, readFileSync, rmSync, statSync, writeFileSync } from "node:fs"; import { dirname, join } from "node:path"; import { createHash, randomBytes } from "node:crypto"; import { repoRoot, rootPath, type Config } from "../config"; import { runCommand } from "../command"; import { cancelJob, listJobs, readJob, startJob } from "../jobs"; import { hwlabRequiredNoProxyEntries, hwlabRuntimeLaneConfigPath, hwlabRuntimeLaneIds, hwlabRuntimeLaneSpec, isHwlabRuntimeLane, type HwlabRuntimeLane, type HwlabRuntimeLaneSpec } from "../hwlab-node-lanes"; import type { G14SecretOptions } from "./types"; import { statusText } from "./pr-monitor"; import { compactCommandResult, g14K3s, g14K3sInlineScriptWithInput, isCommandSuccess, readOrCreateLocalMasterAdminApiKey, runtimeLaneMasterAdminApiKeySecretName, runtimeLaneOpenFgaSecretName, runtimeLanePostgresSecretName, runtimeLanePrimaryDbName, runtimeLaneSecretFieldManager, shellQuote } from "./remote"; import { V02_MASTER_ADMIN_API_KEY_SECRET, V02_MASTER_ADMIN_API_KEY_SECRET_KEY, V02_OPENFGA_AUTHN_SECRET_KEY, V02_OPENFGA_DATASTORE_URI_SECRET_KEY, V02_OPENFGA_DB_NAME, V02_OPENFGA_DB_USER, V02_OPENFGA_POSTGRES_PASSWORD_SECRET_KEY, V02_OPENFGA_SECRET, V02_RUNTIME_NAMESPACE } from "./types"; import { keyValueLinesFromText, numericField } from "./v02-status"; export function v02SecretScript(options: G14SecretOptions): string { const spec = hwlabRuntimeLaneSpec(options.lane); if (options.preset === "generic-delete") return v02DeleteSecretScript(options); if (options.preset === "master-server-admin-api-key") return v02MasterAdminApiKeySecretScript(options, spec); return [ v02OpenFgaSecretScript(options, spec), ].join("\n"); } export function v02DeleteSecretScript(options: G14SecretOptions): string { return [ "set +e", `namespace=${shellQuote(V02_RUNTIME_NAMESPACE)}`, `name=${shellQuote(options.name)}`, `dry_run=${shellQuote(options.dryRun ? "true" : "false")}`, "preset=generic-delete", "secret_exists_flag() { kubectl -n \"$namespace\" get secret \"$name\" >/dev/null 2>&1 && printf yes || printf no; }", "before_exists=$(secret_exists_flag)", "delete_exit=", "action=observed", "mutation=false", "if [ \"$dry_run\" = true ]; then", " if [ \"$before_exists\" = yes ]; then action=would-delete; else action=already-absent; fi", "else", " kubectl -n \"$namespace\" delete secret \"$name\" --ignore-not-found=true >/tmp/hwlab-secret-delete.out 2>/tmp/hwlab-secret-delete.err", " delete_exit=$?", " if [ \"$delete_exit\" -eq 0 ]; then", " if [ \"$before_exists\" = yes ]; then action=deleted; mutation=true; else action=already-absent; fi", " else", " action=delete-failed", " fi", "fi", "after_exists=$(secret_exists_flag)", "printf 'namespace\\t%s\\n' \"$namespace\"", "printf 'secret\\t%s\\n' \"$name\"", "printf 'preset\\t%s\\n' \"$preset\"", "printf 'action\\t%s\\n' \"$action\"", "printf 'dryRun\\t%s\\n' \"$dry_run\"", "printf 'mutation\\t%s\\n' \"$mutation\"", "printf 'beforeExists\\t%s\\n' \"$before_exists\"", "printf 'afterExists\\t%s\\n' \"$after_exists\"", "printf 'deleteExitCode\\t%s\\n' \"$delete_exit\"", "if [ -n \"$delete_exit\" ] && [ \"$delete_exit\" != 0 ]; then exit \"$delete_exit\"; fi", ].join("\n"); } export function v02OpenFgaSecretScript(options: G14SecretOptions, spec: HwlabRuntimeLaneSpec): string { const selectedKey = options.key ?? ""; const namespace = spec.runtimeNamespace; const openFgaSecret = runtimeLaneOpenFgaSecretName(spec); const postgresSecret = runtimeLanePostgresSecretName(spec); const primaryDbName = runtimeLanePrimaryDbName(spec); const dedicatedDb = spec.lane === "v02"; const dbMode = dedicatedDb ? "dedicated" : "primary"; const dbName = dedicatedDb ? V02_OPENFGA_DB_NAME : primaryDbName; const dbUser = dedicatedDb ? V02_OPENFGA_DB_USER : primaryDbName; const dbHost = `${postgresSecret}.${namespace}.svc.cluster.local`; const fieldManager = runtimeLaneSecretFieldManager(spec); return [ "set +e", `namespace=${shellQuote(namespace)}`, `name=${shellQuote(openFgaSecret)}`, `selected_key=${shellQuote(selectedKey)}`, `authn_key=${shellQuote(V02_OPENFGA_AUTHN_SECRET_KEY)}`, `datastore_uri_key=${shellQuote(V02_OPENFGA_DATASTORE_URI_SECRET_KEY)}`, `postgres_password_key=${shellQuote(V02_OPENFGA_POSTGRES_PASSWORD_SECRET_KEY)}`, `db_mode=${shellQuote(dbMode)}`, `db_name=${shellQuote(dbName)}`, `db_user=${shellQuote(dbUser)}`, `postgres_secret=${shellQuote(postgresSecret)}`, `postgres_statefulset=${shellQuote(postgresSecret)}`, `postgres_admin_user=${shellQuote(primaryDbName)}`, `db_host=${shellQuote(dbHost)}`, `action_request=${shellQuote(options.action)}`, `dry_run=${shellQuote(options.dryRun ? "true" : "false")}`, `field_manager=${shellQuote(fieldManager)}`, "preset=openfga", "secret_exists_flag() { kubectl -n \"$namespace\" get secret \"$name\" >/dev/null 2>&1 && printf yes || printf no; }", "secret_b64_key() { kubectl -n \"$namespace\" get secret \"$name\" -o \"go-template={{ index .data \\\"$1\\\" }}\" 2>/dev/null || true; }", "decoded_value() { if [ -n \"$1\" ]; then printf '%s' \"$1\" | base64 -d 2>/dev/null || true; fi; }", "decoded_length() { if [ -n \"$1\" ]; then printf '%s' \"$1\" | base64 -d 2>/dev/null | wc -c | tr -d ' '; else printf '0'; fi; }", "psql_scalar() { kubectl -n \"$namespace\" exec \"statefulset/$postgres_statefulset\" -c postgres -- env PGPASSWORD=\"$postgres_admin_password\" psql -U \"$postgres_admin_user\" -d postgres -tAc \"$1\" 2>/dev/null | tr -d '[:space:]'; }", "probe_db() {", " if [ \"$db_mode\" = primary ]; then", " role_result=primary", " database_result=primary", " probe_exit=not-required", " return", " fi", " role_result=unknown", " database_result=unknown", " probe_exit=missing-postgres-admin-secret", " if [ -n \"$postgres_admin_password\" ]; then", " role_result=$(psql_scalar \"select exists(select 1 from pg_roles where rolname='$db_user');\")", " role_exit=$?", " database_result=$(psql_scalar \"select exists(select 1 from pg_database where datname='$db_name');\")", " database_exit=$?", " if [ \"$role_exit\" -eq 0 ] && [ \"$database_exit\" -eq 0 ]; then probe_exit=0; else probe_exit=$role_exit/$database_exit; fi", " fi", "}", "before_exists=$(secret_exists_flag)", "before_authn_b64=$(secret_b64_key \"$authn_key\")", "before_uri_b64=$(secret_b64_key \"$datastore_uri_key\")", "before_pg_password_b64=$(secret_b64_key \"$postgres_password_key\")", "before_authn_present=$([ -n \"$before_authn_b64\" ] && printf yes || printf no)", "before_uri_present=$([ -n \"$before_uri_b64\" ] && printf yes || printf no)", "before_pg_password_present=$([ -n \"$before_pg_password_b64\" ] && printf yes || printf no)", "before_authn_bytes=$(decoded_length \"$before_authn_b64\")", "before_uri_bytes=$(decoded_length \"$before_uri_b64\")", "before_pg_password_bytes=$(decoded_length \"$before_pg_password_b64\")", "authn_value=$(decoded_value \"$before_authn_b64\")", "datastore_uri=$(decoded_value \"$before_uri_b64\")", "pg_password=$(decoded_value \"$before_pg_password_b64\")", "postgres_admin_b64=$(kubectl -n \"$namespace\" get secret \"$postgres_secret\" -o 'go-template={{ index .data \"POSTGRES_PASSWORD\" }}' 2>/dev/null || true)", "postgres_admin_present=$([ -n \"$postgres_admin_b64\" ] && printf yes || printf no)", "postgres_admin_password=$(decoded_value \"$postgres_admin_b64\")", "probe_db", "db_role_exists_before=$role_result", "db_database_exists_before=$database_result", "db_probe_exit_before=$probe_exit", "action=observed", "mutation=false", "apply_exit=", "db_ensure_exit=", "if [ \"$action_request\" = ensure ]; then", " missing_secret=false", " [ \"$before_authn_present\" = yes ] && [ \"$before_authn_bytes\" -gt 0 ] || missing_secret=true", " [ \"$before_uri_present\" = yes ] && [ \"$before_uri_bytes\" -gt 0 ] || missing_secret=true", " [ \"$before_pg_password_present\" = yes ] && [ \"$before_pg_password_bytes\" -gt 0 ] || missing_secret=true", " missing_db=false", " if [ \"$db_mode\" = dedicated ]; then", " [ \"$db_role_exists_before\" = t ] || missing_db=true", " [ \"$db_database_exists_before\" = t ] || missing_db=true", " fi", " if [ \"$dry_run\" = true ]; then", " if [ \"$missing_secret\" = true ] || [ \"$missing_db\" = true ]; then action=would-ensure; else action=kept; fi", " elif ! command -v openssl >/dev/null 2>&1; then", " action=openssl-missing", " apply_exit=127", " elif [ -z \"$postgres_admin_password\" ]; then", " action=postgres-admin-secret-missing", " apply_exit=44", " else", " [ -n \"$authn_value\" ] || authn_value=$(openssl rand -base64 48)", " if [ \"$db_mode\" = primary ]; then", " [ -n \"$pg_password\" ] || pg_password=\"$postgres_admin_password\"", " else", " [ -n \"$pg_password\" ] || pg_password=$(openssl rand -hex 24)", " fi", " [ -n \"$datastore_uri\" ] || datastore_uri=\"postgres://$db_user:$pg_password@$db_host:5432/$db_name?sslmode=disable\"", " kubectl -n \"$namespace\" create secret generic \"$name\" --from-literal=\"$authn_key=$authn_value\" --from-literal=\"$datastore_uri_key=$datastore_uri\" --from-literal=\"$postgres_password_key=$pg_password\" --dry-run=client -o yaml | kubectl apply --server-side --force-conflicts --field-manager=\"$field_manager\" -f -", " apply_exit=$?", " if [ \"$apply_exit\" -eq 0 ]; then", " if [ \"$db_mode\" = primary ]; then", " action=ensured", " mutation=true", " else", " kubectl -n \"$namespace\" exec -i \"statefulset/$postgres_statefulset\" -c postgres -- env PGPASSWORD=\"$postgres_admin_password\" psql -v ON_ERROR_STOP=1 -U \"$postgres_admin_user\" -d postgres -v db_name=\"$db_name\" -v db_user=\"$db_user\" -v db_pass=\"$pg_password\" >/tmp/hwlab-openfga-psql.out 2>/tmp/hwlab-openfga-psql.err <<'SQL'", "SELECT format('CREATE ROLE %I LOGIN PASSWORD %L', :'db_user', :'db_pass')", "WHERE NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = :'db_user')", "\\gexec", "ALTER ROLE :\"db_user\" LOGIN PASSWORD :'db_pass';", "SELECT format('CREATE DATABASE %I OWNER %I', :'db_name', :'db_user')", "WHERE NOT EXISTS (SELECT 1 FROM pg_database WHERE datname = :'db_name')", "\\gexec", "ALTER DATABASE :\"db_name\" OWNER TO :\"db_user\";", "SQL", " db_ensure_exit=$?", " if [ \"$db_ensure_exit\" -eq 0 ]; then action=ensured; mutation=true; else action=db-ensure-failed; fi", " fi", " else", " action=apply-failed", " fi", " fi", "fi", "after_exists=$(secret_exists_flag)", "after_authn_b64=$(secret_b64_key \"$authn_key\")", "after_uri_b64=$(secret_b64_key \"$datastore_uri_key\")", "after_pg_password_b64=$(secret_b64_key \"$postgres_password_key\")", "after_authn_present=$([ -n \"$after_authn_b64\" ] && printf yes || printf no)", "after_uri_present=$([ -n \"$after_uri_b64\" ] && printf yes || printf no)", "after_pg_password_present=$([ -n \"$after_pg_password_b64\" ] && printf yes || printf no)", "after_authn_bytes=$(decoded_length \"$after_authn_b64\")", "after_uri_bytes=$(decoded_length \"$after_uri_b64\")", "after_pg_password_bytes=$(decoded_length \"$after_pg_password_b64\")", "probe_db", "db_role_exists_after=$role_result", "db_database_exists_after=$database_result", "db_probe_exit_after=$probe_exit", "printf 'namespace\\t%s\\n' \"$namespace\"", "printf 'secret\\t%s\\n' \"$name\"", "printf 'key\\t%s\\n' \"$selected_key\"", "printf 'preset\\t%s\\n' \"$preset\"", "printf 'action\\t%s\\n' \"$action\"", "printf 'dryRun\\t%s\\n' \"$dry_run\"", "printf 'mutation\\t%s\\n' \"$mutation\"", "printf 'dbMode\\t%s\\n' \"$db_mode\"", "printf 'beforeExists\\t%s\\n' \"$before_exists\"", "printf 'beforeAuthnPresent\\t%s\\n' \"$before_authn_present\"", "printf 'beforeAuthnBytes\\t%s\\n' \"$before_authn_bytes\"", "printf 'beforeDatastoreUriPresent\\t%s\\n' \"$before_uri_present\"", "printf 'beforeDatastoreUriBytes\\t%s\\n' \"$before_uri_bytes\"", "printf 'beforePostgresPasswordPresent\\t%s\\n' \"$before_pg_password_present\"", "printf 'beforePostgresPasswordBytes\\t%s\\n' \"$before_pg_password_bytes\"", "printf 'afterExists\\t%s\\n' \"$after_exists\"", "printf 'afterAuthnPresent\\t%s\\n' \"$after_authn_present\"", "printf 'afterAuthnBytes\\t%s\\n' \"$after_authn_bytes\"", "printf 'afterDatastoreUriPresent\\t%s\\n' \"$after_uri_present\"", "printf 'afterDatastoreUriBytes\\t%s\\n' \"$after_uri_bytes\"", "printf 'afterPostgresPasswordPresent\\t%s\\n' \"$after_pg_password_present\"", "printf 'afterPostgresPasswordBytes\\t%s\\n' \"$after_pg_password_bytes\"", "printf 'postgresAdminSecretPresent\\t%s\\n' \"$postgres_admin_present\"", "printf 'postgresSecret\\t%s\\n' \"$postgres_secret\"", "printf 'dbName\\t%s\\n' \"$db_name\"", "printf 'dbUser\\t%s\\n' \"$db_user\"", "printf 'dbRoleExistsBefore\\t%s\\n' \"$db_role_exists_before\"", "printf 'dbDatabaseExistsBefore\\t%s\\n' \"$db_database_exists_before\"", "printf 'dbProbeExitCodeBefore\\t%s\\n' \"$db_probe_exit_before\"", "printf 'dbRoleExistsAfter\\t%s\\n' \"$db_role_exists_after\"", "printf 'dbDatabaseExistsAfter\\t%s\\n' \"$db_database_exists_after\"", "printf 'dbProbeExitCodeAfter\\t%s\\n' \"$db_probe_exit_after\"", "printf 'applyExitCode\\t%s\\n' \"$apply_exit\"", "printf 'dbEnsureExitCode\\t%s\\n' \"$db_ensure_exit\"", "authn_value=", "datastore_uri=", "pg_password=", "postgres_admin_password=", "if [ -n \"$apply_exit\" ] && [ \"$apply_exit\" != 0 ]; then exit \"$apply_exit\"; fi", "if [ -n \"$db_ensure_exit\" ] && [ \"$db_ensure_exit\" != 0 ]; then exit \"$db_ensure_exit\"; fi", ].join("\n"); } export function v02MasterAdminApiKeySecretScript(options: G14SecretOptions, spec: HwlabRuntimeLaneSpec): string { const namespace = spec.runtimeNamespace; const name = runtimeLaneMasterAdminApiKeySecretName(spec); const fieldManager = runtimeLaneSecretFieldManager(spec); return [ "set +e", `namespace=${shellQuote(namespace)}`, `name=${shellQuote(name)}`, `api_key_name=${shellQuote(V02_MASTER_ADMIN_API_KEY_SECRET_KEY)}`, `action_request=${shellQuote(options.action)}`, `dry_run=${shellQuote(options.dryRun ? "true" : "false")}`, `field_manager=${shellQuote(fieldManager)}`, "preset=master-server-admin-api-key", "secret_exists_flag() { kubectl -n \"$namespace\" get secret \"$name\" >/dev/null 2>&1 && printf yes || printf no; }", "secret_b64_key() { kubectl -n \"$namespace\" get secret \"$name\" -o \"go-template={{ index .data \\\"$1\\\" }}\" 2>/dev/null || true; }", "decoded_length() { if [ -n \"$1\" ]; then printf '%s' \"$1\" | base64 -d 2>/dev/null | wc -c | tr -d ' '; else printf '0'; fi; }", "decoded_prefix() { if [ -n \"$1\" ]; then value=$(printf '%s' \"$1\" | base64 -d 2>/dev/null || true); printf '%s' \"$value\" | cut -c1-24; value=; fi; }", "before_exists=$(secret_exists_flag)", "before_api_key_b64=$(secret_b64_key \"$api_key_name\")", "before_api_key_present=$([ -n \"$before_api_key_b64\" ] && printf yes || printf no)", "before_api_key_bytes=$(decoded_length \"$before_api_key_b64\")", "before_api_key_prefix=$(decoded_prefix \"$before_api_key_b64\")", "action=observed", "mutation=false", "apply_exit=", "if [ \"$action_request\" = ensure ]; then", " missing_secret=false", " [ \"$before_api_key_present\" = yes ] && [ \"$before_api_key_bytes\" -gt 0 ] || missing_secret=true", " if [ \"$dry_run\" = true ]; then", " if [ \"$missing_secret\" = true ]; then action=would-ensure; else action=kept; fi", " else", " api_key=$(cat)", " case \"$api_key\" in hwl_live_*) ;; *) action=api-key-invalid; apply_exit=43 ;; esac", " if [ -z \"$apply_exit\" ]; then", " kubectl -n \"$namespace\" create secret generic \"$name\" --from-literal=\"$api_key_name=$api_key\" --dry-run=client -o yaml | kubectl apply --server-side --force-conflicts --field-manager=\"$field_manager\" -f -", " apply_exit=$?", " if [ \"$apply_exit\" -eq 0 ]; then action=ensured; mutation=true; else action=apply-failed; fi", " fi", " api_key=", " fi", "fi", "after_exists=$(secret_exists_flag)", "after_api_key_b64=$(secret_b64_key \"$api_key_name\")", "after_api_key_present=$([ -n \"$after_api_key_b64\" ] && printf yes || printf no)", "after_api_key_bytes=$(decoded_length \"$after_api_key_b64\")", "after_api_key_prefix=$(decoded_prefix \"$after_api_key_b64\")", "printf 'namespace\\t%s\\n' \"$namespace\"", "printf 'secret\\t%s\\n' \"$name\"", "printf 'key\\t%s\\n' \"$api_key_name\"", "printf 'preset\\t%s\\n' \"$preset\"", "printf 'action\\t%s\\n' \"$action\"", "printf 'dryRun\\t%s\\n' \"$dry_run\"", "printf 'mutation\\t%s\\n' \"$mutation\"", "printf 'beforeExists\\t%s\\n' \"$before_exists\"", "printf 'beforeApiKeyPresent\\t%s\\n' \"$before_api_key_present\"", "printf 'beforeApiKeyBytes\\t%s\\n' \"$before_api_key_bytes\"", "printf 'beforeApiKeyPrefix\\t%s\\n' \"$before_api_key_prefix\"", "printf 'afterExists\\t%s\\n' \"$after_exists\"", "printf 'afterApiKeyPresent\\t%s\\n' \"$after_api_key_present\"", "printf 'afterApiKeyBytes\\t%s\\n' \"$after_api_key_bytes\"", "printf 'afterApiKeyPrefix\\t%s\\n' \"$after_api_key_prefix\"", "printf 'applyExitCode\\t%s\\n' \"$apply_exit\"", "if [ -n \"$apply_exit\" ] && [ \"$apply_exit\" != 0 ]; then exit \"$apply_exit\"; fi", ].join("\n"); } export function v02SecretStatusFromText(text: string, commandOk: boolean, exitCode: number | null, stderr: string): Record { const fields = keyValueLinesFromText(text); if (fields.preset === "generic-delete") { const absent = fields.afterExists !== "yes"; return { ok: commandOk && absent, namespace: fields.namespace || V02_RUNTIME_NAMESPACE, secret: fields.secret || null, preset: "generic-delete", action: fields.action || null, dryRun: fields.dryRun === "true", mutation: fields.mutation === "true", before: { exists: fields.beforeExists === "yes", }, after: { exists: fields.afterExists === "yes", }, deleteExitCode: numericField(fields.deleteExitCode), exitCode, stderr: commandOk ? "" : stderr.trim().slice(0, 2000), valuesRedacted: true, summary: absent ? `${fields.secret || "secret"} absent` : `${fields.secret || "secret"} still exists`, }; } if (fields.preset === "master-server-admin-api-key") { const afterBytes = numericField(fields.afterApiKeyBytes); const healthy = fields.afterExists === "yes" && fields.afterApiKeyPresent === "yes" && typeof afterBytes === "number" && afterBytes > 0 && String(fields.afterApiKeyPrefix ?? "").startsWith("hwl_live_"); return { ok: commandOk && healthy, namespace: fields.namespace || V02_RUNTIME_NAMESPACE, secret: fields.secret || V02_MASTER_ADMIN_API_KEY_SECRET, key: fields.key || V02_MASTER_ADMIN_API_KEY_SECRET_KEY, preset: "master-server-admin-api-key", action: fields.action || null, dryRun: fields.dryRun === "true", mutation: fields.mutation === "true", before: { exists: fields.beforeExists === "yes", apiKey: { keyPresent: fields.beforeApiKeyPresent === "yes", valueBytes: numericField(fields.beforeApiKeyBytes), keyPrefix: fields.beforeApiKeyPrefix || null }, }, after: { exists: fields.afterExists === "yes", apiKey: { keyPresent: fields.afterApiKeyPresent === "yes", valueBytes: afterBytes, keyPrefix: fields.afterApiKeyPrefix || null }, }, applyExitCode: numericField(fields.applyExitCode), exitCode, stderr: commandOk ? "" : stderr.trim().slice(0, 2000), valuesRedacted: true, summary: healthy ? `${fields.secret || V02_MASTER_ADMIN_API_KEY_SECRET}/${fields.key || V02_MASTER_ADMIN_API_KEY_SECRET_KEY} exists` : `${fields.secret || V02_MASTER_ADMIN_API_KEY_SECRET}/${fields.key || V02_MASTER_ADMIN_API_KEY_SECRET_KEY} missing`, }; } if (fields.preset === "openfga") { const afterAuthnBytes = numericField(fields.afterAuthnBytes); const afterUriBytes = numericField(fields.afterDatastoreUriBytes); const afterPasswordBytes = numericField(fields.afterPostgresPasswordBytes); const keysHealthy = fields.afterExists === "yes" && fields.afterAuthnPresent === "yes" && fields.afterDatastoreUriPresent === "yes" && fields.afterPostgresPasswordPresent === "yes" && typeof afterAuthnBytes === "number" && afterAuthnBytes > 0 && typeof afterUriBytes === "number" && afterUriBytes > 0 && typeof afterPasswordBytes === "number" && afterPasswordBytes > 0; const databaseHealthy = fields.dbMode === "primary" || (fields.dbRoleExistsAfter === "t" && fields.dbDatabaseExistsAfter === "t"); const healthy = keysHealthy && databaseHealthy; return { ok: commandOk && healthy, namespace: fields.namespace || V02_RUNTIME_NAMESPACE, secret: fields.secret || V02_OPENFGA_SECRET, key: fields.key || null, preset: "openfga", action: fields.action || null, dryRun: fields.dryRun === "true", mutation: fields.mutation === "true", dbMode: fields.dbMode || "dedicated", before: { exists: fields.beforeExists === "yes", authnPresharedKey: { keyPresent: fields.beforeAuthnPresent === "yes", valueBytes: numericField(fields.beforeAuthnBytes) }, datastoreUri: { keyPresent: fields.beforeDatastoreUriPresent === "yes", valueBytes: numericField(fields.beforeDatastoreUriBytes) }, postgresPassword: { keyPresent: fields.beforePostgresPasswordPresent === "yes", valueBytes: numericField(fields.beforePostgresPasswordBytes) }, database: { roleExists: fields.dbRoleExistsBefore || "unknown", databaseExists: fields.dbDatabaseExistsBefore || "unknown", probeExitCode: fields.dbProbeExitCodeBefore || null, }, }, after: { exists: fields.afterExists === "yes", authnPresharedKey: { keyPresent: fields.afterAuthnPresent === "yes", valueBytes: afterAuthnBytes }, datastoreUri: { keyPresent: fields.afterDatastoreUriPresent === "yes", valueBytes: afterUriBytes }, postgresPassword: { keyPresent: fields.afterPostgresPasswordPresent === "yes", valueBytes: afterPasswordBytes }, database: { roleExists: fields.dbRoleExistsAfter || "unknown", databaseExists: fields.dbDatabaseExistsAfter || "unknown", probeExitCode: fields.dbProbeExitCodeAfter || null, }, }, postgresAdminSecretPresent: fields.postgresAdminSecretPresent === "yes", postgresSecret: fields.postgresSecret || null, dbName: fields.dbName || V02_OPENFGA_DB_NAME, dbUser: fields.dbUser || V02_OPENFGA_DB_USER, applyExitCode: numericField(fields.applyExitCode), dbEnsureExitCode: numericField(fields.dbEnsureExitCode), exitCode, stderr: commandOk ? "" : stderr.trim().slice(0, 2000), valuesRedacted: true, summary: healthy ? `${fields.secret || V02_OPENFGA_SECRET} keys and Postgres database exist` : `${fields.secret || V02_OPENFGA_SECRET} keys or Postgres database missing`, }; } return { ok: false, namespace: fields.namespace || V02_RUNTIME_NAMESPACE, secret: fields.secret || null, preset: fields.preset || null, action: fields.action || null, dryRun: fields.dryRun === "true", mutation: fields.mutation === "true", exitCode, stderr: stderr.trim().slice(0, 2000), valuesRedacted: true, summary: "unrecognized secret status output", }; } export function runG14Secret(options: G14SecretOptions): Record { const spec = hwlabRuntimeLaneSpec(options.lane); const script = v02SecretScript(options); const localAdminApiKey = options.preset === "master-server-admin-api-key" ? readOrCreateLocalMasterAdminApiKey(spec, options.action !== "ensure" || options.dryRun) : null; const result = options.preset === "master-server-admin-api-key" ? g14K3sInlineScriptWithInput(script, localAdminApiKey?.key ?? "", options.timeoutSeconds * 1000 + 2000) : g14K3s(["sh", "--", script], options.timeoutSeconds * 1000); const status = v02SecretStatusFromText(statusText(result), isCommandSuccess(result), result.exitCode, result.stderr); const dryRunOk = options.action === "ensure" && options.dryRun && isCommandSuccess(result); const deleteDryRunOk = options.action === "delete" && options.dryRun && isCommandSuccess(result); const ok = dryRunOk || deleteDryRunOk ? true : status.ok === true; return { ok, command: `hwlab g14 secret ${options.action} --lane ${options.lane}`, lane: options.lane, namespace: spec.runtimeNamespace, secret: options.name, key: options.key ?? null, preset: options.preset, mode: options.action === "status" ? "status" : options.dryRun ? "dry-run" : options.action === "delete" ? "confirmed-delete" : "confirmed-ensure", status, localMasterServer: localAdminApiKey ? { created: localAdminApiKey.created, envFile: localAdminApiKey.status, valuesRedacted: true } : undefined, mutation: status.mutation === true, result: compactCommandResult(result), valuesRedacted: true, next: ok && options.action === "status" ? undefined : options.action === "delete" ? undefined : { ensure: `bun scripts/cli.ts hwlab g14 secret ensure --lane ${options.lane} --name ${options.name}${options.key ? ` --key ${options.key}` : ""} --confirm` }, }; }