mirror of
https://github.com/dredx/prole.git
synced 2026-09-24 14:44:32 +00:00
fix(installer): k3s --reset path hardening (kdc deploy, no-TTY 1password, context overrides)
Five fixes Junie surfaced while running the kdc-trust-reset-repeatable
Junie brief end-to-end (companion to commit 6f99f95). All hit during
the unattended `install.sh --mode k3s --reset` pipeline.
- knoe/core/milestones.py (KerberosMilestone):
For k3s and k3d modes, deploy the KDC pod via `init_kdc.sh start`
before running init_kerberos.sh. init_kerberos.sh only chains into
init_kdc.sh when PROLE_KDC_STANDALONE=1; without this hook the
cluster came up with no KDC pod and the cross-realm trust principals
had nowhere to land.
- knoe/milestone.py (Milestone._get_script_env):
Clear KUBECTL_CONTEXT in addition to KUBECONTEXT so stale entries
from a different machine's cfg don't override the kubeconfig's
own current-context.
- etc/knoe_cfg.sh (_knoe_read_cfg):
Skip KUBECTL_CONTEXT / KUBE_CONTEXT_NAME / KUBECONTEXT entries when
reading cfg in k3s mode. Same theme: kubeconfig current-context is
authoritative.
- etc/init_1password.sh + knoe/core/onepassword.py:
When running non-interactively (no TTY on stdin) and no `op`
session exists, skip rather than hang on `op signin`. Lets the
unattended pipeline proceed for k3s/k3d where in-cluster secrets
are managed separately from 1Password.
Co-authored-by: Junie <junie@jetbrains.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
6f99f95f84
commit
3f34fa8b32
@ -38,6 +38,11 @@ _info "op CLI found: $(op --version)"
|
|||||||
# ── sign in ────────────────────────────────────────────────────────────────
|
# ── sign in ────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
if ! op whoami >/dev/null 2>&1; then
|
if ! op whoami >/dev/null 2>&1; then
|
||||||
|
# If running non-interactively (no TTY), skip rather than hang.
|
||||||
|
if [[ ! -t 0 ]]; then
|
||||||
|
_warn "No active 1Password session and no TTY — skipping 1Password preflight."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
_info "No active 1Password session. Signing in..."
|
_info "No active 1Password session. Signing in..."
|
||||||
op signin
|
op signin
|
||||||
fi
|
fi
|
||||||
|
|||||||
@ -163,6 +163,10 @@ _knoe_cfg_set_default() {
|
|||||||
|
|
||||||
_knoe_read_cfg() {
|
_knoe_read_cfg() {
|
||||||
local cfg="$1" line key value
|
local cfg="$1" line key value
|
||||||
|
# In k3s mode the kubeconfig current-context is authoritative; never set
|
||||||
|
# KUBECTL_CONTEXT / KUBE_CONTEXT_NAME / KUBECONTEXT from cfg file entries.
|
||||||
|
local _knoe_read_cfg_mode
|
||||||
|
_knoe_read_cfg_mode=$(knoe_normalize_mode "${DEPLOYMENT_MODE:-${KNOE_MODE:-${CLUSTER_ENV:-${knoe_mode:-}}}}" 2>/dev/null || true)
|
||||||
while IFS= read -r line || [[ -n "$line" ]]; do
|
while IFS= read -r line || [[ -n "$line" ]]; do
|
||||||
line="$(_knoe_trim "$line")"
|
line="$(_knoe_trim "$line")"
|
||||||
[[ -z "$line" ]] && continue
|
[[ -z "$line" ]] && continue
|
||||||
@ -178,6 +182,12 @@ _knoe_read_cfg() {
|
|||||||
# Normalize to a valid shell variable key for safe export.
|
# Normalize to a valid shell variable key for safe export.
|
||||||
key="$(_knoe_cfg_normalize_key "$key")"
|
key="$(_knoe_cfg_normalize_key "$key")"
|
||||||
[[ -z "$key" ]] && continue
|
[[ -z "$key" ]] && continue
|
||||||
|
# k3s: kubeconfig current-context is authoritative; skip context overrides from cfg.
|
||||||
|
if [[ "$_knoe_read_cfg_mode" == "k3s" ]]; then
|
||||||
|
case "$key" in
|
||||||
|
KUBECTL_CONTEXT|KUBE_CONTEXT_NAME|KUBECONTEXT) continue ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
value="$(_knoe_cfg_expand "$value")"
|
value="$(_knoe_cfg_expand "$value")"
|
||||||
_knoe_cfg_set_default "$key" "$value"
|
_knoe_cfg_set_default "$key" "$value"
|
||||||
fi
|
fi
|
||||||
@ -790,7 +800,7 @@ if [[ -n "$_knoe_cfg_file" ]]; then
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
if [[ $_override_runtime_ctx -eq 1 ]]; then
|
if [[ $_override_runtime_ctx -eq 1 && "$_cfg_mode_hint" != "k3s" ]]; then
|
||||||
export KUBE_CONTEXT_NAME="$_cfg_ctx"
|
export KUBE_CONTEXT_NAME="$_cfg_ctx"
|
||||||
export KUBECTL_CONTEXT="$_cfg_ctx"
|
export KUBECTL_CONTEXT="$_cfg_ctx"
|
||||||
export KUBECONTEXT="$_cfg_ctx"
|
export KUBECONTEXT="$_cfg_ctx"
|
||||||
|
|||||||
@ -1862,6 +1862,21 @@ class KerberosMilestone(Milestone):
|
|||||||
if progress:
|
if progress:
|
||||||
progress("Initializing Kerberos...", 0.4)
|
progress("Initializing Kerberos...", 0.4)
|
||||||
|
|
||||||
|
# For k3s and k3d modes, deploy the KDC pod (authority-knoe-auth) via
|
||||||
|
# init_kdc.sh before running init_kerberos.sh. init_kerberos.sh only
|
||||||
|
# calls init_kdc.sh when PROLE_KDC_STANDALONE=1; we invoke it directly
|
||||||
|
# here so the pod is always present regardless of that flag.
|
||||||
|
if mode in ("k3s", "k3d"):
|
||||||
|
kdc_args = ["--mode", mode, "start"] if mode else ["start"]
|
||||||
|
self.logger.info("Deploying KDC pod via init_kdc.sh start ...")
|
||||||
|
rc_kdc = state.controller.run_script(
|
||||||
|
"init_kdc.sh", args=kdc_args, env=env, on_line=_stream_line
|
||||||
|
)
|
||||||
|
if rc_kdc != 0:
|
||||||
|
msg = f"init_kdc.sh start failed (code {rc_kdc})"
|
||||||
|
self.logger.error(msg)
|
||||||
|
raise Exception(msg)
|
||||||
|
|
||||||
rc = state.controller.run_script(
|
rc = state.controller.run_script(
|
||||||
"init_kerberos.sh", args=args, env=env, on_line=_stream_line
|
"init_kerberos.sh", args=args, env=env, on_line=_stream_line
|
||||||
)
|
)
|
||||||
|
|||||||
@ -41,7 +41,14 @@ def _op(*args: str, check: bool = True, timeout: int = 15) -> subprocess.Complet
|
|||||||
|
|
||||||
|
|
||||||
def ensure_op_signed_in() -> None:
|
def ensure_op_signed_in() -> None:
|
||||||
"""Ensure the op CLI has an active session; trigger sign-in if not."""
|
"""Ensure the op CLI has an active session; trigger sign-in if not.
|
||||||
|
|
||||||
|
When running non-interactively (no TTY on stdin) and no session exists,
|
||||||
|
skip rather than hang or crash — the installer can proceed without 1Password
|
||||||
|
for k3s/k3d modes where secrets are managed separately.
|
||||||
|
"""
|
||||||
|
import sys
|
||||||
|
|
||||||
if not op_available():
|
if not op_available():
|
||||||
raise RuntimeError(
|
raise RuntimeError(
|
||||||
"1Password CLI (op) not found. Install: brew install 1password-cli"
|
"1Password CLI (op) not found. Install: brew install 1password-cli"
|
||||||
@ -52,6 +59,12 @@ def ensure_op_signed_in() -> None:
|
|||||||
text=True,
|
text=True,
|
||||||
)
|
)
|
||||||
if result.returncode != 0:
|
if result.returncode != 0:
|
||||||
|
if not sys.stdin.isatty():
|
||||||
|
print(
|
||||||
|
"[WARN] No active 1Password session and no TTY — skipping op signin.",
|
||||||
|
flush=True,
|
||||||
|
)
|
||||||
|
return
|
||||||
subprocess.run(["op", "signin"], check=True)
|
subprocess.run(["op", "signin"], check=True)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -169,9 +169,11 @@ class Milestone(ABC):
|
|||||||
env["KUBECONFIG"] = str(_kc)
|
env["KUBECONFIG"] = str(_kc)
|
||||||
break
|
break
|
||||||
# k3s kubeconfig's current-context is authoritative (typically "default").
|
# k3s kubeconfig's current-context is authoritative (typically "default").
|
||||||
# Clear any stale KUBECONTEXT written from a different machine's config so
|
# Clear any stale KUBECONTEXT/KUBECTL_CONTEXT written from a different
|
||||||
# kubectl uses KUBECONFIG without a --context override.
|
# machine's config so kubectl uses KUBECONFIG without a --context override.
|
||||||
env.pop("KUBECONTEXT", None)
|
env.pop("KUBECONTEXT", None)
|
||||||
|
env.pop("KUBECTL_CONTEXT", None)
|
||||||
|
env.pop("KUBE_CONTEXT_NAME", None)
|
||||||
elif mode == "k3d":
|
elif mode == "k3d":
|
||||||
# Ensure k3d dev clusters have a resolvable KUBECONFIG.
|
# Ensure k3d dev clusters have a resolvable KUBECONFIG.
|
||||||
# The cluster may already be running from a previous session;
|
# The cluster may already be running from a previous session;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user