prole/docs/intellij-refactor-prompt.md

6.1 KiB

IntelliJ AI Assistant — Structural Refactor Prompt

You are performing a focused structural refactor on the knoe installer project. Make ONLY the changes described below. Do NOT add features, rename identifiers not listed, or change observable behaviour. After each task, run the existing test suite and stop + report if any tests fail.


TASK A — Split ops/registry.py into mode-specific modules

A1. Create knoe/core/ops/k3d_registry.py

  • Move _ensure_k3d_registry() from registry.py
  • Implement initialize, start, update, stop, restart, status for k3d mode (extract the k3d branches that currently live inside each function in registry.py)
  • update() calls _ensure_k3d_registry()
  • stop() deletes the k3d registry and the fallback Docker container
  • status() checks k3d registry list

A2. Create knoe/core/ops/k3s_registry.py

  • Move _manifest() and _deployment_is_available() from registry.py
  • Implement initialize, start, update, stop, restart, status for k3s mode (this is the current default fall-through path in registry.py)
  • update() applies k8s/registry/deployment.yaml, reconciles ReplicaSets, waits rollout

A3. Create knoe/core/ops/k8s_registry.py

  • update() / stop() / restart(): log a no-op message and return
  • status(): return True (GCP Artifact Registry is externally managed)
  • initialize() / start(): delegate to update()

A4. Rewrite knoe/core/ops/registry.py as a pure dispatcher

from ._services_common import _detect_mode
from types import ModuleType

def _module(mode, env) -> ModuleType:
    m = _detect_mode(mode, env)
    if m == "k3d":
        from . import k3d_registry; return k3d_registry
    if m == "k8s":
        from . import k8s_registry; return k8s_registry
    from . import k3s_registry; return k3s_registry

# initialize / start / update / stop / restart / status
# — each delegates to _module(mode, env).<fn>(**kwargs)
# Public signatures are UNCHANGED.

TASK B — Split ops/garage_store.py into mode-specific modules

B1. Create knoe/core/ops/_garage_common.py

  • Move _garage_namespace() and _ensure_garage_secret() from garage_store.py
  • These helpers are shared by all three mode variants

B2. Create knoe/core/ops/k3s_garage_store.py

  • Move _repair_released_garage_pvs() here (k3s / Synology iSCSI only)
  • _manifest_files() returns: storageclass-synology-iscsi.yaml, iscsi-pvs.yaml, garage-configmap.yaml, garage-statefulset.yaml, garage-service.yaml
  • update() calls _repair_released_garage_pvs() before applying manifests
  • Cluster-scoped resources (no -n flag): {"storageclass-synology-iscsi.yaml", "iscsi-pvs.yaml"}

B3. Create knoe/core/ops/k3d_garage_store.py

  • _manifest_files() returns: garage-configmap.yaml, garage-statefulset.yaml, garage-service.yaml (no Synology storage classes, no static PVs)
  • No PV repair

B4. Create knoe/core/ops/k8s_garage_store.py

  • _manifest_files() returns: storageclass-gcp-hdd.yaml, garage-configmap.yaml, garage-statefulset-gcp.yaml, garage-service.yaml
  • No PV repair
  • Cluster-scoped: {"storageclass-gcp-hdd.yaml"}

B5. Rewrite knoe/core/ops/garage_store.py as dispatcher

Same _module() + delegating-function pattern as Task A. stop() and restart() in garage variants take only namespace, env, log (no mode parameter — mode is resolved from env).


TASK C — Rename UI nav labels (display text only)

File: knoe/ui/screens/__init__.py

"Kerberos Authentication"  →  "Knoe Authority"    (nav_items; page_id "kerberos_config" unchanged)
"Knoe User Authority"      →  "Knoe Users"         (nav_items; page_id "knoe_users" unchanged)

File: knoe/ui/screens/security.py

  • Change the _render_title("Kerberos Authentication", ...) call → _render_title("Knoe Authority", ...)
  • Change text="Enable Kerberos Authentication"text="Enable Knoe Authority"
  • Do NOT change self.knoe_cfg_data["Kerberos Authentication"] keys — those are config-file section names

File: knoe/ui/screens/knoe_users.py

  • Update any user-facing title Label text that still reads "Knoe User Authority"
  • Do NOT change log prefixes or cfg/env key names

TASK D — Add k3d | k3s | k8s mode tab strip to sidebar

File: knoe/ui/screens/__init__.py — in __init__, after self.nav_widgets = {}:

self._mode_tab_widgets: dict = {}
self.deployment_mode = tk.StringVar(value=os.environ.get("KNOE_MODE", "k3s"))

File: knoe/ui/screens/navigation.py — in _create_sidebar_nav(), before the "INSTALLER" Label, insert:

_MODE_COLORS = {"k3d": "#4A90D9", "k3s": "#27AE60", "k8s": "#E67E22"}

mode_frame = tk.Frame(self.sidebar, bg="#F5F5DC")
mode_frame.pack(fill="x", padx=12, pady=(14, 4))
for label, value in [("k3d", "k3d"), ("k3s", "k3s"), ("k8s", "k8s")]:
    btn = tk.Label(
        mode_frame, text=label,
        bg="#D5D5C5", fg="#555",
        font=("SF Pro Text", 9, "bold"),
        padx=8, pady=3, cursor="hand2",
    )
    btn.pack(side="left", padx=2)
    btn.bind("<Button-1>", lambda e, v=value: self._set_deployment_mode(v))
    self._mode_tab_widgets[value] = btn
self._refresh_mode_tabs()

Add to the navigation mixin:

def _set_deployment_mode(self, mode: str) -> None:
    self.deployment_mode.set(mode)
    os.environ["KNOE_MODE"] = mode
    self._refresh_mode_tabs()

def _refresh_mode_tabs(self) -> None:
    _MODE_COLORS = {"k3d": "#4A90D9", "k3s": "#27AE60", "k8s": "#E67E22"}
    active = self.deployment_mode.get()
    for value, widget in self._mode_tab_widgets.items():
        if value == active:
            widget.configure(bg=_MODE_COLORS[value], fg="white")
        else:
            widget.configure(bg="#D5D5C5", fg="#555")

CONSTRAINTS

  • All existing import paths must remain valid (from knoe.core.ops import registry etc.)
  • All public function signatures are unchanged
  • Run tests after each task; stop and report failures before continuing
  • Do not create README or documentation files (other than this prompt file)
  • Do not touch any files not listed above