Merge branch 'main' of git-ssh.knoe.dev:knoe.dev/knoe-db

This commit is contained in:
chrisfu 2026-04-27 13:33:49 -07:00
commit 22906ee656
686 changed files with 9279 additions and 467411 deletions

View File

@ -1,17 +0,0 @@
<component name="RunManager">
<configuration name="Ansible: Run Site Playbook" type="ShConfigurationType">
<option name="SCRIPT_TEXT" value="ansible-playbook infrastructure/playbooks/site.yml --vault-password-file .vault_pass" />
<option name="INDEPENDENT_SCRIPT_PATH" value="true" />
<option name="SCRIPT_PATH" value="" />
<option name="SCRIPT_OPTIONS" value="" />
<option name="INDEPENDENT_SCRIPT_WORKING_DIRECTORY" value="true" />
<option name="SCRIPT_WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="INDEPENDENT_INTERPRETER_PATH" value="true" />
<option name="INTERPRETER_PATH" value="/bin/zsh" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="EXECUTE_IN_TERMINAL" value="true" />
<option name="EXECUTE_SCRIPT_FILE" value="false" />
<envs />
<method v="2" />
</configuration>
</component>

View File

@ -1,19 +0,0 @@
<component name="RunManager">
<configuration name="Silent Install Test" type="ShConfigurationType">
<option name="SCRIPT_TEXT" value="" />
<option name="INDEPENDENT_SCRIPT_PATH" value="true" />
<option name="SCRIPT_PATH" value="$PROJECT_DIR$/tests/silent_install_test.sh" />
<option name="SCRIPT_OPTIONS" value="" />
<option name="INDEPENDENT_SCRIPT_WORKING_DIRECTORY" value="true" />
<option name="SCRIPT_WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="INDEPENDENT_INTERPRETER_PATH" value="true" />
<option name="INTERPRETER_PATH" value="/bin/bash" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="EXECUTE_IN_TERMINAL" value="true" />
<option name="EXECUTE_SCRIPT_FILE" value="true" />
<envs>
<env name="SILENT_INSTALL_LOG" value="true" />
</envs>
<method v="2" />
</configuration>
</component>

117
AGENTS.md Normal file
View File

@ -0,0 +1,117 @@
# AGENTS.md — AI coding agent guide for knoe-db / Knoe
## What this repo is
**Knoe** is an infrastructure stack for deploying a Supabase-style internal developer platform (PostgreSQL, object storage, secrets, auth, observability) across K3d (local), K3s (on-prem), and GKE (cloud) environments. The Python "Knoe" installer (`knoe/cli.py`) drives all cluster setup via milestones.
---
## Architecture overview
### Dual-cluster GKE layout (prod)
Two GKE clusters in `us-west3`:
| Cluster | Context | Purpose |
|---|---|---|
| `knoe-dev-0` | `gke_plenary-truck-485623-p7_us-west3_knoe-dev-0` | App cluster — Garage, Registry, OpenBao, Kong, GitLab, monitoring |
| `knoe-cnpg-0` | `gke_plenary-truck-485623-p7_us-west3_knoe-cnpg-0` | DB cluster — CNPG/PostgreSQL only |
**Critical:** Garage must NEVER be deployed to `knoe-cnpg-0`. SSD quota (300 GB) is fully consumed by CNPG — all non-CNPG PVCs must use `standard` storage class (HDD), not `standard-rwo`/`premium-rwo`.
### Deployment environments / modes
| `cluster_env` | `KNOE_MODE` | Target |
|---|---|---|
| `dev` | `k3d` | Local K3d cluster |
| `service` | `k3s` | On-prem K3s cluster |
| `prod` | `k8s` | GKE (or other cloud) |
`_deployment_mode_from_env()` in `knoe/core/env.py` converts env strings to mode strings.
### Config file mapping
`knoe/knoe_conf.py` maps environments to config files under `conf/`:
- `dev``k3d.cfg`
- `service``k3s.cfg`
- `prod``gke.cfg`
Config is layered: env-specific file overrides base. `KNOE_CONF` env var or `conf/service/` subdirs point to the active config.
---
## Key source locations
| Path | Purpose |
|---|---|
| `knoe/core/env.py` | Core config/env helpers, secret encryption, kubeconfig resolution |
| `knoe/core/actions.py` | All installer actions and unattended workflow helpers (~8k lines) |
| `knoe/milestone.py` | `Milestone` ABC — all install steps implement this; `_get_script_env()` builds the env for subprocesses |
| `knoe/knoe_conf.py` | Config path resolution and layered loading |
| `knoe/core/milestones.py` | Concrete milestone definitions |
| `conf/gke.cfg` | Production GKE config (must have correct `app_cluster_kubecontext` / `db_cluster_kubecontext`) |
| `conf/service/prod.cfg` | Unattended deploy config for `./deploy.sh` |
| `etc/` | Shell init scripts (`init_*.sh`) called by milestones |
| `k8s/` | Kubernetes manifests by service |
| `scripts/reset_clusters.sh` | Full cluster teardown + recreate |
---
## Developer workflows
### Install dependencies
```bash
make requirements # pip install -r requirements.txt
```
### Run tests
```bash
make test # runs pyconv (black check) then pytest with coverage
# or directly:
PYTHONPATH=. pytest tests/
```
### Build the knoe CLI binary
```bash
make build # PyInstaller one-file binary → dist/knoe
```
### Interactive installer (ncurses)
```bash
make knoe # launches ./install.sh
# or via the unified launcher:
./knoe.sh install
```
### Unattended deploy
```bash
./deploy.sh # reads conf/service/prod.cfg
```
### Code style
```bash
black . # formatter (black --check . is enforced in CI)
```
---
## Secret handling
Secrets in `knoe.cfg` are AES-GCM encrypted at rest using `${KNOE_SECRET:v1:...}` tokens. On macOS, the key is in Keychain (`knoe-installer` service); on Linux, at `~/.knoe/secrets/knoe.key`. OpenBao references use `${OPENBAO:kv/knoe/<ns>/<leaf>#<key>}`. Never store plaintext passwords in config files.
---
## Milestone pattern
All installer steps subclass `Milestone` (`knoe/milestone.py`). They must:
- Be UI-agnostic (no tkinter/ncurses imports)
- Use `_run_cmd()` for subprocesses (handles env injection)
- Use `_get_script_env(state)` to build env dicts for shell scripts — this is where `KUBECONTEXT`, `DB_CLUSTER_KUBECONTEXT`, `KNOE_CONF`, etc. are set
Missing `init_cluster.app_cluster_kubecontext` in config causes Garage to deploy to the wrong cluster.
---
## CNPG / backup specifics
- CNPG backups go to **GCS** (not Garage): `gs://knoe-0-backups/` and `gs://knoe-0-wal/`
- Workload Identity SA: `cnpg-backup@plenary-truck-485623-p7.iam.gserviceaccount.com`
- ObjectStore manifest: `k8s/knoe/knoe-db-barman-objectstore-gcs.yaml`
- Setup: `etc/init_cnpg_gke.sh` and `etc/init_cnpg_backup.sh`

View File

@ -7,26 +7,26 @@
make package
```
This creates `dist/Prole Installer.app` - a self-contained macOS application.
This creates `dist/Knoe Installer.app` - a self-contained macOS application.
## Usage
**GUI Mode (double-click):**
- Open `dist/Prole Installer.app` in Finder
- Open `dist/Knoe Installer.app` in Finder
**Command-line:**
```bash
# Auto-detect display (GUI or ncurses)
./dist/Prole\ Installer.app/Contents/MacOS/prole-installer
./dist/Knoe\ Installer.app/Contents/MacOS/knoe-installer
# Force ncurses mode
./dist/Prole\ Installer.app/Contents/MacOS/prole-installer --no-gui
./dist/Knoe\ Installer.app/Contents/MacOS/knoe-installer --no-gui
```
## Install to /Applications
```bash
cp -r "dist/Prole Installer.app" /Applications/
cp -r "dist/Knoe Installer.app" /Applications/
```
## Makefile Targets

View File

@ -1,4 +1,4 @@
# CLAUDE.md — prole project context
# CLAUDE.md — knoe project context
> Loaded automatically by Claude Code (CLI and IntelliJ plugin) as project context.
@ -53,7 +53,7 @@ Backups use **GCS with Workload Identity** (not Garage):
- WAL bucket: `gs://knoe-0-wal/`
- GCP SA: `cnpg-backup@plenary-truck-485623-p7.iam.gserviceaccount.com`
- K8s SA: `cnpg-backup-sa` in `knoe-db-0` (annotated with WI)
- ObjectStore manifest: `k8s/prole/knoe-db-barman-objectstore-gcs.yaml`
- ObjectStore manifest: `k8s/knoe/knoe-db-barman-objectstore-gcs.yaml`
Setup script: `etc/init_cnpg_gke.sh` (creates buckets, GCP SA, WI binding, applies CNPG cluster).

View File

@ -1,4 +1,4 @@
# Makefile for Prole Database Deployment and Installer
# Makefile for Knoe Database Deployment and Installer
ifneq ($(wildcard bin/python3),)
PYTHON ?= bin/python3
@ -8,72 +8,59 @@ endif
PYINSTALLER = $(PYTHON) -m PyInstaller
DIST_DIR = dist
BUILD_DIR = build
PROLE_CONF ?= conf
PROLE_MODE ?= k3d
KNOE_CONF ?= conf
KNOE_MODE ?= k3d
PIPELINE_DIR ?= deploy/opentofu/k3s
DEPLOYMENT_GIT_DIR ?= prole/deployment
GITEA_SCRIPT ?= prole/etc/gitea.sh
KUBECONFIG_PATH ?= $(CURDIR)/prole-k3s.kubeconfig
DEPLOYMENT_REPO_URL ?= http://gitea.local/prole/deployment.git
DEPLOYMENT_GIT_DIR ?= knoe/deployment
GITEA_SCRIPT ?= knoe/etc/gitea.sh
KUBECONFIG_PATH ?= $(CURDIR)/knoe-k3s.kubeconfig
DEPLOYMENT_REPO_URL ?= http://gitea.local/knoe/deployment.git
.PHONY: all prole install deploy init clean help requirements test pyconv
.PHONY: all knoe build install deploy init clean help requirements test pyconv start
all: prole
all: build
start: build
open "$(DIST_DIR)/Knoe.DB Installer.app"
help:
@echo "Prole Build & Deployment System"
@echo "Knoe Build & Deployment System"
@echo ""
@echo "Targets:"
@echo " prole - Build the 'prole' CLI binary (ncurses/silent only)"
@echo " knoe - Launch the Ncurses installer"
@echo " start - Build and launch the GUI installer"
@echo " install - Run silent install via install.sh"
@echo " deploy - Run infrastructure deployment via deploy.sh"
@echo " build - Build the 'knoe' CLI binary"
@echo " requirements - Install Python dependencies"
@echo " install - Run silent install via prole.sh"
@echo " init - Sync OpenTofu pipeline, tofu init, stage deployment git dir"
@echo " deploy - Run infrastructure deployment via OpenTofu"
@echo " test - Run full install.py test suite with pyconv and coverage summary"
@echo " test - Run full test suite"
@echo " pyconv - Check Python code style conventions (black)"
@echo " clean - Remove build artifacts"
@echo ""
@echo "Environment:"
@echo " PROLE_CONF - Directory containing prole.cfg (default: conf)"
@echo " KNOE_CONF - Directory containing knoe.cfg (default: conf)"
requirements:
@echo "Installing dependencies..."
$(PYTHON) -m pip install -r prole_requirements.txt
$(PYTHON) -m pip install -r requirements.txt
prole:
@$(PYTHON) -c "import PyInstaller" 2>/dev/null || (echo "Error: PyInstaller not found. Please run 'make requirements' or install it with: $(PYTHON) -m pip install -r prole_requirements.txt" && exit 1)
@echo "Building 'prole' CLI binary (excluding Tk UI)..."
$(PYINSTALLER) --clean --noconfirm --onefile \
--name prole \
--exclude-module tkinter \
--exclude-module _tkinter \
--exclude-module Tkinter \
--add-data "etc:etc" \
--add-data "prole-net:prole-net" \
--add-data "k8s:k8s" \
--add-data "conf:conf" \
prole/cli.py
@echo "✓ Build complete: $(DIST_DIR)/prole"
knoe:
./install.sh
build:
@$(PYTHON) -c "import PyInstaller" 2>/dev/null || (echo "Error: PyInstaller not found. Please run 'make requirements' or install it with: $(PYTHON) -m pip install -r requirements.txt" && exit 1)
@echo "Building 'Knoe.DB Installer' macOS App Bundle..."
$(PYINSTALLER) --clean --noconfirm knoe.spec
@echo "✓ Build complete: $(DIST_DIR)/Knoe.DB Installer.app"
install:
@echo "Running silent install..."
PROLE_CONF=$(PROLE_CONF) ./prole.sh install -s -c $(PROLE_CONF)/prole.cfg
KNOE_CONF=$(KNOE_CONF) ./install.sh -s -c $(KNOE_CONF)/knoe.cfg
init:
@command -v tofu >/dev/null 2>&1 || (echo "Error: OpenTofu (tofu) not found in PATH." && exit 1)
@echo "Syncing OpenTofu pipeline from $(PROLE_MODE) runtime into $(PIPELINE_DIR)..."
@PROLE_MODE=$(PROLE_MODE) PROLE_CONF=$(PROLE_CONF) PROLE_GIT_REPO=$(DEPLOYMENT_REPO_URL) PYTHONPATH=$(CURDIR) $(PYTHON) - <<'PY'
from knoe.core.controller import ProleController
from knoe.core.env import PROJECT_ROOT
from prole.deployment import ProleDeployment
import sys, os
from pathlib import Path
conf_dir = os.environ.get('PROLE_CONF', 'conf')
cfg_path = PROJECT_ROOT / conf_dir / 'prole.cfg'
deployment = ProleDeployment(ProleController(PROJECT_ROOT, verbose=False, cfg_path=cfg_path), PROJECT_ROOT)
ok = deployment.duplicate_k3d_to_k3s()
sys.exit(0 if ok else 1)
PY
@echo "Syncing OpenTofu pipeline from $(KNOE_MODE) runtime into $(PIPELINE_DIR)..."
@KNOE_MODE=$(KNOE_MODE) KNOE_CONF=$(KNOE_CONF) KNOE_GIT_REPO=$(DEPLOYMENT_REPO_URL) PYTHONPATH=$(CURDIR) $(PYTHON) -c "from knoe.core.controller import KnoeController; from knoe.core.env import PROJECT_ROOT; from knoe.deployment import KnoeDeployment; import sys, os; conf_dir = os.environ.get('KNOE_CONF', 'conf'); cfg_path = PROJECT_ROOT / conf_dir / 'knoe.cfg'; deployment = KnoeDeployment(KnoeController(PROJECT_ROOT, verbose=False, cfg_path=cfg_path), PROJECT_ROOT); ok = deployment.duplicate_k3d_to_k3s(); sys.exit(0 if ok else 1)"
@echo "Initializing OpenTofu backend in $(PIPELINE_DIR)..."
@cd $(PIPELINE_DIR) && tofu init
@echo "Staging pipeline sources into $(DEPLOYMENT_GIT_DIR) for Gitea"
@ -82,14 +69,12 @@ PY
@cd $(DEPLOYMENT_GIT_DIR) && if [ ! -d .git ]; then git init -q; fi
@echo "✓ init complete"
deploy: init
@echo "Deploying internal Gitea to k3s..."
@KUBECONFIG=$(KUBECONFIG_PATH) PROLE_MODE=k3s PROLE_CONF=$(PROLE_CONF) $(GITEA_SCRIPT) deploy -c $(PROLE_CONF)/prole.cfg
@echo "Running Prole deployment (OpenTofu)..."
KUBECONFIG=$(KUBECONFIG_PATH) PYTHONPATH=$(CURDIR) PROLE_CONF=$(PROLE_CONF) PROLE_MODE=$(PROLE_MODE) PROLE_GIT_REPO=$(DEPLOYMENT_REPO_URL) $(PYTHON) prole/cli.py deploy
deploy:
@echo "Running Knoe deployment..."
./deploy.sh
test: pyconv
@echo "Running full install.py test suite..."
@echo "Running full test suite..."
@./tests/run_tests.sh
@echo ""
@echo "Test Summary:"
@ -102,5 +87,5 @@ pyconv:
clean:
@echo "Cleaning build artifacts..."
rm -rf $(BUILD_DIR) $(DIST_DIR) *.spec
rm -rf __pycache__ prole/__pycache__ knoe/__pycache__
rm -rf __pycache__ knoe/__pycache__
@echo "✓ Clean complete"

View File

@ -1,5 +1,5 @@
<div align="center">
<a href="https://svc.prole.org"><pre>
<a href="https://svc.knoe.org"><pre>
# ###########################
# ╭──────────────────────╮ #
# │ _ │ #
@ -64,7 +64,7 @@ It packages the core building blocks needed for a modern internal developer plat
![Google Workspace](https://img.shields.io/badge/Google%20Workspace-4285F4?style=for-the-badge&logo=google&logoColor=white)
![Samba AD](https://img.shields.io/badge/Samba%20AD-0C4DA2?style=for-the-badge&logo=windows&logoColor=white)
![Ansible](https://img.shields.io/badge/Ansible-EE0000?style=for-the-badge&logo=ansible&logoColor=white)
![1Password](https://img.shields.io/badge/1Password-3B66BC?style=for-the-badge&logo=1password&logoColor=white)
![OpenTofu](https://img.shields.io/badge/OpenTofu-FFDA18?style=for-the-badge&logo=opentofu&logoColor=black)
![Linux](https://img.shields.io/badge/Linux-333333?style=for-the-badge&logo=linux&logoColor=white)
![Raspberry%20Pi](https://img.shields.io/badge/Raspberry%20Pi-C51A4A?style=for-the-badge&logo=raspberrypi&logoColor=white)

View File

@ -1,27 +0,0 @@
FROM ubuntu:24.04
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
acl \
adcli \
attr \
ca-certificates \
curl \
dnsutils \
krb5-admin-server \
krb5-config \
krb5-kdc \
krb5-user \
libnss-winbind \
libpam-krb5 \
libpam-winbind \
python3-samba \
realmd \
samba \
samba-common-bin \
samba-dsdb-modules \
samba-vfs-modules \
winbind \
&& rm -rf /var/lib/apt/lists/*

View File

@ -1,11 +0,0 @@
package org.prole.authority;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class AuthorityApplication {
public static void main(String[] args) {
SpringApplication.run(AuthorityApplication.class, args);
}
}

View File

@ -1,13 +0,0 @@
package org.prole.authority;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HealthController {
@GetMapping("/health")
public String health() {
return "ok";
}
}

View File

@ -1,3 +0,0 @@
server.port=8080
management.endpoints.web.exposure.include=health,info

View File

@ -1,12 +0,0 @@
package org.prole.authority;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class AuthorityApplicationTests {
@Test
void contextLoads() {
}
}

View File

@ -10,32 +10,67 @@
<relativePath/>
</parent>
<groupId>org.prole</groupId>
<artifactId>authority-parent</artifactId>
<groupId>org.knoe</groupId>
<artifactId>authority</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>authority-parent</name>
<description>Parent POM for the Knoe authority modules</description>
<name>knoe-authority</name>
<description>Knoe authentication gateway</description>
<properties>
<java.version>21</java.version>
</properties>
<modules>
<module>common</module>
<module>kdc</module>
<module>prole-auth</module>
<module>gcp-auth</module>
</modules>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Kerberos/Security dependencies -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-kerberos-client</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.5</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.5</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.11.5</version>
<scope>runtime</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.prole</groupId>
<artifactId>authority-common</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -1,11 +0,0 @@
package org.prole.authority;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class AuthorityApplication {
public static void main(String[] args) {
SpringApplication.run(AuthorityApplication.class, args);
}
}

View File

@ -1,4 +1,4 @@
package org.prole.authority;
package org.knoe.authority;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

View File

@ -1,4 +1,4 @@
package org.prole.auth;
package org.knoe.authority;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@ -6,8 +6,8 @@ import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
@SpringBootApplication
@ConfigurationPropertiesScan
public class ProleAuthApplication {
public class KnoeAuthApplication {
public static void main(String[] args) {
SpringApplication.run(ProleAuthApplication.class, args);
SpringApplication.run(KnoeAuthApplication.class, args);
}
}

View File

@ -1,4 +1,4 @@
package org.prole.auth.config;
package org.knoe.authority.config;
import java.time.Duration;
import java.util.ArrayList;
@ -6,14 +6,14 @@ import java.util.List;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "prole.auth")
@ConfigurationProperties(prefix = "knoe.auth")
public class AuthProperties {
private boolean enabled = true;
private String cookieName = "prole_session";
private String cookieDomain = ".prole.org";
private String cookieName = "knoe_session";
private String cookieDomain = ".knoe.dev";
private Duration sessionTtl = Duration.ofHours(8);
private String sessionSecret = "";
private String emailDomain = "prole.org";
private String emailDomain = "knoe.dev";
private boolean formEnabled = false;
private List<String> adminPrincipals = new ArrayList<>();

View File

@ -1,8 +1,8 @@
package org.prole.auth.config;
package org.knoe.authority.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "prole.kerberos")
@ConfigurationProperties(prefix = "knoe.kerberos")
public class KerberosProperties {
private String servicePrincipal = "";
private String keytabPath = "";

View File

@ -1,4 +1,4 @@
package org.prole.auth.kerberos;
package org.knoe.authority.kerberos;
import java.io.IOException;
import java.util.Map;
@ -23,7 +23,7 @@ public class KerberosPasswordService {
throw new IllegalArgumentException("password required");
}
Configuration jaasConfig = new PasswordJaasConfiguration();
LoginContext loginContext = new LoginContext("prole-krb5-pw", null, new FixedCallbackHandler(principal, password), jaasConfig);
LoginContext loginContext = new LoginContext("knoe-krb5-pw", null, new FixedCallbackHandler(principal, password), jaasConfig);
loginContext.login();
}

View File

@ -1,4 +1,4 @@
package org.prole.auth.kerberos;
package org.knoe.authority.kerberos;
import java.security.PrivilegedExceptionAction;
import java.util.Map;
@ -38,7 +38,7 @@ public class KerberosSpnegoService {
}
Configuration jaasConfig = new KeytabJaasConfiguration(servicePrincipal, keytabPath);
LoginContext loginContext = new LoginContext("prole-krb5", null, null, jaasConfig);
LoginContext loginContext = new LoginContext("knoe-krb5", null, null, jaasConfig);
loginContext.login();
Subject subject = loginContext.getSubject();

View File

@ -1,4 +1,4 @@
package org.prole.auth.session;
package org.knoe.authority.session;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.databind.ObjectMapper;

View File

@ -1,4 +1,4 @@
package org.prole.auth.session;
package org.knoe.authority.session;
import java.util.List;

View File

@ -1,4 +1,4 @@
package org.prole.auth.user;
package org.knoe.authority.user;
import java.util.Locale;
import java.util.Optional;

View File

@ -1,4 +1,4 @@
package org.prole.auth.web;
package org.knoe.authority.web;
import java.net.URI;
import java.util.ArrayList;
@ -10,13 +10,13 @@ import jakarta.annotation.PostConstruct;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.prole.auth.config.AuthProperties;
import org.prole.auth.config.KerberosProperties;
import org.prole.auth.kerberos.KerberosPasswordService;
import org.prole.auth.kerberos.KerberosSpnegoService;
import org.prole.auth.session.SessionTokenService;
import org.prole.auth.session.SessionUser;
import org.prole.auth.user.PrincipalNormalizer;
import org.knoe.authority.config.AuthProperties;
import org.knoe.authority.config.KerberosProperties;
import org.knoe.authority.kerberos.KerberosPasswordService;
import org.knoe.authority.kerberos.KerberosSpnegoService;
import org.knoe.authority.session.SessionTokenService;
import org.knoe.authority.session.SessionUser;
import org.knoe.authority.user.PrincipalNormalizer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
@ -60,7 +60,7 @@ public class LoginController {
return;
}
if (auth.getSessionSecret() == null || auth.getSessionSecret().isBlank()) {
throw new IllegalStateException("prole.auth.sessionSecret is required when auth is enabled");
throw new IllegalStateException("knoe.auth.sessionSecret is required when auth is enabled");
}
}
@ -73,7 +73,7 @@ public class LoginController {
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Prole Login</title>
<title>Knoe Login</title>
<style>
body { font-family: system-ui, -apple-system, Segoe UI, Roboto, sans-serif; max-width: 720px; margin: 40px auto; padding: 0 16px; }
code { background: #f3f3f3; padding: 2px 4px; }
@ -84,7 +84,7 @@ public class LoginController {
</style>
</head>
<body>
<h1>Prole Login</h1>
<h1>Knoe Login</h1>
<div class="box">
<h2>Kerberos (recommended)</h2>
<p>If your browser is configured for Kerberos/SPNEGO, use this.</p>
@ -238,7 +238,7 @@ public class LoginController {
}
private URI safeNext(String next) {
URI defaultNext = URI.create("https://svc.prole.org/");
URI defaultNext = URI.create("https://svc.knoe.dev/");
if (next == null || next.isBlank()) {
return defaultNext;
}
@ -249,13 +249,13 @@ public class LoginController {
return defaultNext;
}
String host = u.getHost();
if (host == null || !host.endsWith(".prole.org")) {
if (host == null || !host.endsWith(".knoe.dev")) {
return defaultNext;
}
return u;
}
if (next.startsWith("/")) {
return URI.create("https://svc.prole.org" + next);
return URI.create("https://svc.knoe.dev" + next);
}
return defaultNext;
} catch (Exception e) {

View File

@ -1,13 +1,13 @@
package org.prole.auth.web;
package org.knoe.authority.web;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Optional;
import org.prole.auth.config.AuthProperties;
import org.prole.auth.session.SessionTokenService;
import org.prole.auth.session.SessionUser;
import org.knoe.authority.config.AuthProperties;
import org.knoe.authority.session.SessionTokenService;
import org.knoe.authority.session.SessionUser;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
@ -18,9 +18,9 @@ import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/auth")
public class VerifyController {
public static final String USER_HEADER = "X-Prole-User";
public static final String EMAIL_HEADER = "X-Prole-Email";
public static final String GROUPS_HEADER = "X-Prole-Groups";
public static final String USER_HEADER = "X-Knoe-User";
public static final String EMAIL_HEADER = "X-Knoe-Email";
public static final String GROUPS_HEADER = "X-Knoe-Groups";
private final AuthProperties auth;
private final SessionTokenService tokens;

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/java" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -1,3 +0,0 @@
server.port=8080
management.endpoints.web.exposure.include=health,info

View File

@ -7,18 +7,18 @@ management:
exposure:
include: health,info
prole:
knoe:
auth:
enabled: false
cookieName: prole_session
cookieDomain: ${PROLE_AUTH_COOKIE_DOMAIN:.prole.org}
cookieName: knoe_session
cookieDomain: ${KNOE_AUTH_COOKIE_DOMAIN:.knoe.dev}
sessionTtl: 8h
# REQUIRED in production when enabled. Provide via env: PROLE_AUTH_SESSION_SECRET
# REQUIRED in production when enabled. Provide via env: KNOE_AUTH_SESSION_SECRET
sessionSecret: ""
emailDomain: prole.org
emailDomain: knoe.dev
formEnabled: false
# Comma-separated list of bare usernames granted admin group membership.
# Override via env: PROLE_AUTH_ADMIN_PRINCIPALS=admin
# Override via env: KNOE_AUTH_ADMIN_PRINCIPALS=admin
adminPrincipals: []
kerberos:
# REQUIRED for SPNEGO when enabled. Provide via env.

View File

@ -1,12 +0,0 @@
package org.prole.authority;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class AuthorityApplicationTests {
@Test
void contextLoads() {
}
}

View File

@ -1,4 +1,4 @@
package org.prole.auth.session;
package org.knoe.authority.session;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.time.Clock;
@ -16,12 +16,12 @@ class SessionTokenServiceTest {
Clock clock = Clock.fixed(Instant.parse("2026-03-20T00:00:00Z"), ZoneOffset.UTC);
SessionTokenService svc = SessionTokenService.forTests(om, clock);
String token = svc.issue("secret", new SessionUser("alice", "alice@prole.org", java.util.List.of()), Duration.ofMinutes(5));
String token = svc.issue("secret", new SessionUser("alice", "alice@knoe.org", java.util.List.of()), Duration.ofMinutes(5));
assertNotNull(token);
SessionUser user = svc.verify("secret", token).orElseThrow();
assertEquals("alice", user.username());
assertEquals("alice@prole.org", user.email());
assertEquals("alice@knoe.org", user.email());
}
@Test
@ -29,7 +29,7 @@ class SessionTokenServiceTest {
ObjectMapper om = new ObjectMapper();
Clock clock = Clock.fixed(Instant.parse("2026-03-20T00:00:00Z"), ZoneOffset.UTC);
SessionTokenService svc = SessionTokenService.forTests(om, clock);
String token = svc.issue("secret", new SessionUser("alice", "alice@prole.org", java.util.List.of()), Duration.ofMinutes(5));
String token = svc.issue("secret", new SessionUser("alice", "alice@knoe.org", java.util.List.of()), Duration.ofMinutes(5));
assertTrue(svc.verify("other", token).isEmpty());
}
@ -38,7 +38,7 @@ class SessionTokenServiceTest {
ObjectMapper om = new ObjectMapper();
Clock clock = Clock.fixed(Instant.parse("2026-03-20T00:00:00Z"), ZoneOffset.UTC);
SessionTokenService svc = SessionTokenService.forTests(om, clock);
String token = svc.issue("secret", new SessionUser("alice", "alice@prole.org", java.util.List.of()), Duration.ofSeconds(1));
String token = svc.issue("secret", new SessionUser("alice", "alice@knoe.org", java.util.List.of()), Duration.ofSeconds(1));
SessionTokenService svcLater = SessionTokenService.forTests(om, Clock.fixed(Instant.parse("2026-03-20T00:10:00Z"), ZoneOffset.UTC));
assertTrue(svcLater.verify("secret", token).isEmpty());

View File

@ -1,9 +1,9 @@
package org.prole.auth.web;
package org.knoe.authority.web;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import org.prole.auth.session.SessionTokenService;
import org.prole.auth.session.SessionUser;
import org.knoe.authority.session.SessionTokenService;
import org.knoe.authority.session.SessionUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
@ -14,12 +14,12 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@SpringBootTest(properties = {
"prole.auth.enabled=true",
"prole.auth.sessionSecret=test-secret",
"prole.auth.cookieName=prole_session",
"prole.auth.sessionTtl=1h",
"prole.kerberos.servicePrincipal=HTTP/api.prole.org@EXAMPLE.TEST",
"prole.kerberos.keytabPath=/tmp/does-not-matter"
"knoe.auth.enabled=true",
"knoe.auth.sessionSecret=test-secret",
"knoe.auth.cookieName=knoe_session",
"knoe.auth.sessionTtl=1h",
"knoe.kerberos.servicePrincipal=HTTP/api.knoe.org@EXAMPLE.TEST",
"knoe.kerberos.keytabPath=/tmp/does-not-matter"
})
@AutoConfigureMockMvc
class VerifyControllerTest {
@ -34,8 +34,8 @@ class VerifyControllerTest {
@Test
void authenticatedGetsHeaders() throws Exception {
String token = tokens.issue("test-secret", new SessionUser("alice", "alice@prole.org", java.util.List.of()), Duration.ofMinutes(10));
mvc.perform(get("/auth/verify").header(HttpHeaders.COOKIE, "prole_session=" + token))
String token = tokens.issue("test-secret", new SessionUser("alice", "alice@knoe.org", java.util.List.of()), Duration.ofMinutes(10));
mvc.perform(get("/auth/verify").header(HttpHeaders.COOKIE, "knoe_session=" + token))
.andExpect(status().isOk())
.andExpect(header().string(VerifyController.USER_HEADER, "alice"));
}

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/java" isTestSource="true" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@ -1,11 +0,0 @@
#!/usr/bin/env bash
# Prole environment file. Sourced by other scripts in ~/.prole/bin.
# Customize PATH, KUBECONFIG, contexts, etc.
# Ensure common kubectl locations are available
export PATH="/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin:$PATH"
# Example: point to a specific kubeconfig if needed
# export KUBECONFIG="$HOME/.kube/config"
# You can add any environment variables that your port-forward commands require here.

View File

@ -1,76 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
LABEL="org.prole.knoe-db.kpf-dev"
PLIST="$HOME/Library/LaunchAgents/$LABEL.plist"
PROLE_HOME="$HOME/.prole"
BIN_DIR="$PROLE_HOME/bin"
RUN_DIR="$PROLE_HOME/run"
PIDFILE="$RUN_DIR/kpf.pids"
# Source environment if present
if [ -f "$BIN_DIR/prole-env.sh" ]; then
# shellcheck source=/dev/null
. "$BIN_DIR/prole-env.sh"
fi
ensure_dirs() {
mkdir -p "$BIN_DIR" "$RUN_DIR"
}
list_cmds() {
if /usr/libexec/PlistBuddy -c "Print :ProleCommands" "$PLIST" >/dev/null 2>&1; then
local i=0
while true; do
if ! val=$(/usr/libexec/PlistBuddy -c "Print :ProleCommands:$i" "$PLIST" 2>/dev/null); then
break
fi
echo "$val"
i=$((i+1))
done
fi
}
start() {
ensure_dirs
: > "$PIDFILE"
# Iterate over commands and start each in background shell
while IFS= read -r cmd; do
[ -z "$cmd" ] && continue
(sh -lc "$cmd") &
echo $! >> "$PIDFILE"
done < <(list_cmds)
wait || true
}
stop() {
if [ -f "$PIDFILE" ]; then
while read -r pid; do
[ -z "$pid" ] && continue
kill "$pid" 2>/dev/null || true
done < "$PIDFILE"
rm -f "$PIDFILE"
fi
}
status() {
if [ ! -f "$PIDFILE" ]; then
echo "not running"
exit 3
fi
local alive=0 total=0
while read -r pid; do
[ -z "$pid" ] && continue
total=$((total+1))
if kill -0 "$pid" 2>/dev/null; then alive=$((alive+1)); fi
done < "$PIDFILE"
echo "$alive/$total running"
}
case "${1:-}" in
start) start ;;
stop) stop ;;
restart) stop; start ;;
status) status ;;
*) echo "Usage: $0 {start|stop|restart|status}" >&2; exit 2 ;;
esac

View File

@ -1,15 +1,15 @@
{
"assignments": {
"0": "gandalf.prole.org",
"1": "merlin.prole.org",
"2": "myrddin.prole.org"
"0": "gandalf.knoe.org",
"1": "merlin.knoe.org",
"2": "myrddin.knoe.org"
},
"cluster_name": "knoe-db",
"desired_instances": 3,
"eligible_nodes": [
"gandalf.prole.org",
"merlin.prole.org",
"myrddin.prole.org"
"gandalf.knoe.org",
"merlin.knoe.org",
"myrddin.knoe.org"
],
"metadata": {
"prior_plan_present": true,

View File

@ -1,15 +1,15 @@
{
"assignments": {
"0": "merlin.prole.org",
"1": "myrddin.prole.org",
"2": "pi.prole.org"
"0": "merlin.knoe.org",
"1": "myrddin.knoe.org",
"2": "pi.knoe.org"
},
"cluster_name": "knoe-db",
"desired_instances": 3,
"eligible_nodes": [
"merlin.prole.org",
"myrddin.prole.org",
"pi.prole.org"
"merlin.knoe.org",
"myrddin.knoe.org",
"pi.knoe.org"
],
"metadata": {
"prior_plan_present": true,

View File

@ -1,4 +1,4 @@
; Prole Master Configuration File
; Knoe Master Configuration File
; Generated by install.py on 2026-04-21 20:06:41
; This file is used as input for Ansible deployment and k8s cluster creation.
@ -35,11 +35,11 @@ env_setup.DATABASE_NAMESPACE = ${DATABASE_NAMESPACE}
env_setup.DB_CLUSTER_KUBECONTEXT = gke_plenary-truck-485623-p7_us-west3_knoe-dev-cnpg-0
env_setup.DB_CLUSTER_MODE = standard
env_setup.DB_CLUSTER_NAME = knoe-dev-cnpg-0
env_setup.PROLE_CONF = /Users/chrisfu/dev/prole/conf
env_setup.PROLE_DATA = /Users/chrisfu/dev/prole/data
env_setup.PROLE_HOME = /Users/chrisfu/dev/prole
env_setup.PROLE_LOGS = /Users/chrisfu/dev/prole/logs
env_setup.PROLE_SERVICE = /Users/chrisfu/dev/prole/etc
env_setup.KNOE_CONF = /Users/chrisfu/dev/knoe/conf
env_setup.PROLE_DATA = /Users/chrisfu/dev/knoe/data
env_setup.KNOE_HOME = /Users/chrisfu/dev/knoe
env_setup.PROLE_LOGS = /Users/chrisfu/dev/knoe/logs
env_setup.KNOE_SERVICE = /Users/chrisfu/dev/knoe/etc
gitops.git_provider = GitLab
init_cluster.app_cluster_kubecontext = gke_plenary-truck-485623-p7_us-west3_knoe-dev-0
init_cluster.app_cluster_machine_type = e2-small
@ -79,8 +79,8 @@ init_password.cluster_name = ${CLUSTER_NAME}
init_password.db_cluster_name = knoe-dev-cnpg-0
init_password.db_host_port = 5432
init_password.db_namespace = ${DATABASE_NAMESPACE}
init_password.db_password = ${PROLE_SECRET:v1:ZFFldOYIZkB0YP4L:hPhu1R9jyKh5lYPsbrtLdd8F0leQ_yBODT6f4cYL9lU9GrBh}
init_password.db_password_confirm = ${PROLE_SECRET:v1:ZFFldOYIZkB0YP4L:hPhu1R9jyKh5lYPsbrtLdd8F0leQ_yBODT6f4cYL9lU9GrBh}
init_password.db_password = ${KNOE_SECRET:v1:ZFFldOYIZkB0YP4L:hPhu1R9jyKh5lYPsbrtLdd8F0leQ_yBODT6f4cYL9lU9GrBh}
init_password.db_password_confirm = ${KNOE_SECRET:v1:ZFFldOYIZkB0YP4L:hPhu1R9jyKh5lYPsbrtLdd8F0leQ_yBODT6f4cYL9lU9GrBh}
init_password.db_username = chrisfu
init_password.generate_ssh_key = true
init_scripts.run_scripts = true
@ -104,7 +104,7 @@ ARTIFACT_REGISTRY = us-west3-docker.pkg.dev/plenary-truck-485623-p7/knoe-system
AUTHORITY_ENABLED = true
AUTH_HOSTNAME = api.knoe.dev
AUTH_LOGIN_PATH = /auth/login
AUTH_RESPONSE_HEADERS = X-Prole-User,X-Prole-Email,X-Prole-Groups
AUTH_RESPONSE_HEADERS = X-Knoe-User,X-Knoe-Email,X-Knoe-Groups
AUTH_VERIFY_PATH = /auth/verify
CLUSTER_ENV = prod
CLUSTER_NAME = knoe-db
@ -114,9 +114,9 @@ CNPG_SIZE_PROFILE = small
DATABASE_NAMESPACE = knoe-db-0
DB_CLUSTER_KUBECONTEXT = gke_plenary-truck-485623-p7_us-west3_knoe-dev-cnpg-0
DB_HOST_PORT = 5432
DB_PASSWORD = ${PROLE_SECRET:v1:MnnRuv9H3uhhWQp2:-oCq5ybT1tVEOjAiH5DjrTDrPa8hYituYyK1gdxlcuLFfmXa}
DB_PASSWORD = ${KNOE_SECRET:v1:MnnRuv9H3uhhWQp2:-oCq5ybT1tVEOjAiH5DjrTDrPa8hYituYyK1gdxlcuLFfmXa}
DEPLOYMENT_MODE = k8s
DEPLOYMENT_TARGET = prole-prod-cluster
DEPLOYMENT_TARGET = knoe-prod-cluster
DOCKER_IMPORT_DIR =
DOCKER_PRELOAD = false
GARAGE_PRIVATE_S3_ENDPOINT = http://10.180.15.239:3900
@ -149,7 +149,7 @@ KNOE_USER_GITLAB_OIDC_REDIRECT_URI = https://git.knoe.dev/users/auth/openid_conn
KNOE_USER_GITLAB_PROVISIONING_READY = true
OPENTOFU_URL = http://127.0.0.1:8080
OPTIONAL_WORKLOADS_MIN_READY_SCHEDULABLE_NODES = 2
PROLE_HOME = $HOME/dev/prole
KNOE_HOME = $HOME/dev/knoe
PROTECTED_DB_HOSTS = db.0.knoe.dev,api.0.knoe.dev
PROTECTED_GIT_HOSTS = git.knoe.dev
REDIS_HOST = redis-master.knoe-system.svc.cluster.local
@ -193,11 +193,11 @@ PORT_FORWARD_K3D_MAPPING_8 = id=grafana;namespace=monitoring;target=svc/kps-graf
PORT_FORWARD_K3D_MAPPING_9 = id=supabase-kong;namespace=supabase;target=svc/kong;address=0.0.0.0;hostPort=8000;servicePort=8000;protocol=TCP;description=Supabase API (Kong)
[System Environment]
PROLE_CONF = $HOME/dev/prole/conf
PROLE_DATA = $HOME/dev/prole/data
PROLE_HOME = $HOME/dev/prole
PROLE_LOGS = $HOME/dev/prole/logs
PROLE_SERVICE = $HOME/dev/prole/etc
KNOE_CONF = $HOME/dev/knoe/conf
PROLE_DATA = $HOME/dev/knoe/data
KNOE_HOME = $HOME/dev/knoe
PROLE_LOGS = $HOME/dev/knoe/logs
KNOE_SERVICE = $HOME/dev/knoe/etc
[Monitoring]
; No configuration values captured yet for this section.
@ -233,8 +233,8 @@ KUBECTL_CONTEXT = prod
MODE = k3d
[Service Cluster (k3s)]
CLUSTER_ENV = prole-service-cluster
DISPLAY_NAME = prole-service-cluster
CLUSTER_ENV = knoe-service-cluster
DISPLAY_NAME = knoe-service-cluster
K3S_SERVER_URL =
K3S_TOKEN =
MODE = k3s
@ -245,8 +245,8 @@ PIPELINE_URL = http://127.0.0.1:8080
[Prod Cluster (k8s)]
ARTIFACTS_DIR =
CLUSTER_ENV = prole-prod-cluster
DISPLAY_NAME = prole-prod-cluster
CLUSTER_ENV = knoe-prod-cluster
DISPLAY_NAME = knoe-prod-cluster
MODE = k8s
PIPELINE_URL = http://127.0.0.1:8080
@ -258,7 +258,7 @@ PIPELINE_URL = http://127.0.0.1:8080
[Deployment]
MODE = k8s
TARGET = prole-prod-cluster
TARGET = knoe-prod-cluster
[Install]
STATUS = Finished

View File

@ -1,4 +1,4 @@
; Prole Master Configuration File
; Knoe Master Configuration File
; Generated by install.py on 2026-04-14 06:09:00
; This file is used as input for Ansible deployment and k8s cluster creation.
@ -40,24 +40,24 @@ dependencies.opentofu.install = true
dependencies.python.install = true
dependencies.verify_all = false
disk_selection.disk_type = local
disk_selection.local_path = /Users/chrisfu/dev/prole/prole-tools-app/dist
disk_selection.local_path = /Users/chrisfu/dev/knoe/knoe-tools-app/dist
disk_selection.removable_mount =
env_setup.CLUSTER_NAME = ${CLUSTER_NAME}
env_setup.DATABASE_NAMESPACE = ${DATABASE_NAMESPACE}
env_setup.PROLE_CONF = /Users/chrisfu/dev/prole/conf
env_setup.PROLE_DATA = /Users/chrisfu/dev/prole/data
env_setup.PROLE_HOME = /Users/chrisfu/dev/prole
env_setup.PROLE_LOGS = /Users/chrisfu/dev/prole/logs
env_setup.PROLE_SERVICE = /Users/chrisfu/dev/prole/etc
env_setup.KNOE_CONF = /Users/chrisfu/dev/knoe/conf
env_setup.PROLE_DATA = /Users/chrisfu/dev/knoe/data
env_setup.KNOE_HOME = /Users/chrisfu/dev/knoe
env_setup.PROLE_LOGS = /Users/chrisfu/dev/knoe/logs
env_setup.KNOE_SERVICE = /Users/chrisfu/dev/knoe/etc
gitops.git_provider = Gitea
gitops.node_selector =
init_cluster.argocd_enabled = false
init_cluster.at_rest_encryption_enabled = true
init_cluster.cluster_env = dev
init_cluster.deployment_target = prole-dev-cluster
init_cluster.deployment_target = knoe-dev-cluster
init_cluster.gitops_enabled = true
init_cluster.k3s_server_url = https://myrddin.prole.org:6443
init_cluster.k3s_token = ${PROLE_SECRET:v1:-cslrAhG8WhxxJLY:vAx5MGOBcU1NBMjf4U-3y1djMDmwwOjiWkrutxPa4Li5P8RBjCBhEOCEdGP2CiPJJ6UQK-ietX-mu_5nO3yNNjpwDququT4U6lWHPEInSvUNH6ImU-HzPvm_diL2FwJtZm3sY5HgecIy2dwXB_vLnYaA_7VXt9zf0T70rw==}
init_cluster.k3s_server_url = https://myrddin.knoe.org:6443
init_cluster.k3s_token = ${KNOE_SECRET:v1:-cslrAhG8WhxxJLY:vAx5MGOBcU1NBMjf4U-3y1djMDmwwOjiWkrutxPa4Li5P8RBjCBhEOCEdGP2CiPJJ6UQK-ietX-mu_5nO3yNNjpwDququT4U6lWHPEInSvUNH6ImU-HzPvm_diL2FwJtZm3sY5HgecIy2dwXB_vLnYaA_7VXt9zf0T70rw==}
init_cluster.kerberos_enabled = true
init_cluster.mode = k3d
init_cluster.start_cluster = true
@ -84,46 +84,46 @@ ollama_config.model =
ollama_config.server_host =
ollama_config.server_port = 11434
supabase_config.pv_base_dir = /synology/d005
supabase_config.pv_node = gandalf.prole.org
supabase_config.pv_node = gandalf.knoe.org
[Global]
; Variables used by name in more than one place or assumed global scope
ARGOCD_NAMESPACE = argocd
ARTIFACT_REGISTRY = us-west3-docker.pkg.dev/plenary-truck-485623-p7/knoe-system
AUTHORITY_ENABLED = true
AUTH_HOSTNAME = api.prole.org
AUTH_HOSTNAME = api.knoe.org
AUTH_LOGIN_PATH = /auth/login
AUTH_RESPONSE_HEADERS = X-Prole-User,X-Prole-Email,X-Prole-Groups
AUTH_RESPONSE_HEADERS = X-Knoe-User,X-Knoe-Email,X-Knoe-Groups
AUTH_VERIFY_PATH = /auth/verify
CLUSTER_ENV = dev
CLUSTER_NAME = knoe-db
CNPG_PLACEMENT_PLAN_FILE = /Users/chrisfu/dev/prole/conf/cnpg-placement/knoe-system-knoe-db.json
CNPG_PLACEMENT_PLAN_FILE = /Users/chrisfu/dev/knoe/conf/cnpg-placement/knoe-system-knoe-db.json
CNPG_PLACEMENT_PLAN_HASH = 965d2fde4035059f
CNPG_PLACEMENT_PLAN_ID = cnpg-placement-965d2fde4035059f
DATABASE_NAMESPACE = knoe-db-18-008-18-009-18-013-18-014
DB_HOST_PORT = 5432
DEPLOYMENT_MODE = k3d
DEPLOYMENT_TARGET = prole-dev-cluster
DEPLOYMENT_TARGET = knoe-dev-cluster
DOCKER_PRELOAD = false
GITLAB_PUBLIC_HOSTS = git.knoe.dev,git.prole.org
K3S_SERVER = https://myrddin.prole.org:6443
K3S_TOKEN = ${PROLE_SECRET:v1:CWWf3RHFdbUrmfrY:It8a2G8QUUIsqVwMsm3LsI4UvSSChEc_uAdESwzYplZLOCiSsCbOKuT9FbPpIwQvEaG_gLz9ZAfkD0EQxJp81KAtpk_X3K_nxVUa0RPRlbt_wdeXXoMoFFpN5BqXXz2HZwKgh_gpK1hjVbsJQHKAbTqWfu8u_LTmYYg4ag==}
GITLAB_PUBLIC_HOSTS = git.knoe.dev,git.knoe.org
K3S_SERVER = https://myrddin.knoe.org:6443
K3S_TOKEN = ${KNOE_SECRET:v1:CWWf3RHFdbUrmfrY:It8a2G8QUUIsqVwMsm3LsI4UvSSChEc_uAdESwzYplZLOCiSsCbOKuT9FbPpIwQvEaG_gLz9ZAfkD0EQxJp81KAtpk_X3K_nxVUa0RPRlbt_wdeXXoMoFFpN5BqXXz2HZwKgh_gpK1hjVbsJQHKAbTqWfu8u_LTmYYg4ag==}
KNOE_DB_USER = root
KUBECONTEXT = dev
MONITORING_STORAGE_CLASS = local-path
OPENTOFU_URL = http://127.0.0.1:8080
OPTIONAL_WORKLOADS_MIN_READY_SCHEDULABLE_NODES = 2
PROLE_K3S_SERVER = https://myrddin.prole.org:6443
PROLE_K3S_TOKEN = ${PROLE_SECRET:v1:-cslrAhG8WhxxJLY:vAx5MGOBcU1NBMjf4U-3y1djMDmwwOjiWkrutxPa4Li5P8RBjCBhEOCEdGP2CiPJJ6UQK-ietX-mu_5nO3yNNjpwDququT4U6lWHPEInSvUNH6ImU-HzPvm_diL2FwJtZm3sY5HgecIy2dwXB_vLnYaA_7VXt9zf0T70rw==}
PROLE_K3S_SERVER = https://myrddin.knoe.org:6443
PROLE_K3S_TOKEN = ${KNOE_SECRET:v1:-cslrAhG8WhxxJLY:vAx5MGOBcU1NBMjf4U-3y1djMDmwwOjiWkrutxPa4Li5P8RBjCBhEOCEdGP2CiPJJ6UQK-ietX-mu_5nO3yNNjpwDququT4U6lWHPEInSvUNH6ImU-HzPvm_diL2FwJtZm3sY5HgecIy2dwXB_vLnYaA_7VXt9zf0T70rw==}
PROLE_OPENTOFU_URL = http://127.0.0.1:8080
PROTECTED_DB_HOSTS = db.0.knoe.dev,db.prole.org
PROTECTED_GIT_HOSTS = git.knoe.dev,git.prole.org
PROTECTED_DB_HOSTS = db.0.knoe.dev,db.knoe.org
PROTECTED_GIT_HOSTS = git.knoe.dev,git.knoe.org
REGISTRY_NAMESPACE = knoe-system
SERVICE_NAMESPACE = knoe-system
SUPABASE_PV_BASE = /synology/d005
SUPABASE_PV_BASE_DIR = /synology/d005
SUPABASE_PV_NODE = gandalf.prole.org
SUPABASE_STUDIO_HOSTNAME = db.0.knoe.dev,db.prole.org
SUPABASE_PV_NODE = gandalf.knoe.org
SUPABASE_STUDIO_HOSTNAME = db.0.knoe.dev,db.knoe.org
[Welcome]
; No configuration values captured yet for this section.
@ -132,13 +132,13 @@ SUPABASE_STUDIO_HOSTNAME = db.0.knoe.dev,db.prole.org
STATUS = All installed
[Network]
AD_DC_HOST = myrddin.prole.org
AD_DC_HOST = myrddin.knoe.org
AD_DC_IP = 10.0.0.3
ANSIBLE_DOMAIN = prole.org
ANSIBLE_INFRASTRUCTURE = $HOME/dev/prole/infrastructure
ANSIBLE_INVENTORY = $HOME/dev/prole/infrastructure/inventory
ANSIBLE_DOMAIN = knoe.org
ANSIBLE_INFRASTRUCTURE = $HOME/dev/knoe/infrastructure
ANSIBLE_INVENTORY = $HOME/dev/knoe/infrastructure/inventory
ANSIBLE_REALM = PROLE.ORG
ANSIBLE_TOPOLOGY = {"domain":"prole.org","realm":"PROLE.ORG","internal_records":{"aventage.prole.org":"10.0.0.206","fairyland.prole.org":"10.0.0.208","loghost.prole.org":"10.0.0.3","merlin.prole.org":"10.0.0.6","morana.prole.org":"10.0.0.66","morgoth.prole.org":"10.0.0.204","myrddin.prole.org":"10.0.0.3","pi.prole.org":"10.0.0.5","raspberry.prole.org":"10.0.0.4","retropie.prole.org":"10.0.0.207","synology.prole.org":"10.0.0.203","zinfandel.prole.org":"10.0.0.205"},"ad_dc":{"host":"myrddin.prole.org","ip":"10.0.0.3"},"k3s":{"server_url":"https://myrddin.prole.org:6443","server_host":"myrddin.prole.org","token_present":true},"groups":{"iscsi":["pi.prole.org","raspberry.prole.org","myrddin.prole.org","retropie.prole.org","merlin.prole.org","gandalf.prole.org"],"pihole":["pi.prole.org","raspberry.prole.org"],"ad_dc":["myrddin.prole.org"],"k3s_servers":["myrddin.prole.org"],"k3s_agents":["merlin.prole.org","gandalf.prole.org"],"k3s_hosts:children":["k3s_servers","k3s_agents"],"linux_hosts":["pi.prole.org","raspberry.prole.org","myrddin.prole.org","retropie.prole.org","merlin.prole.org","gandalf.prole.org"],"ssl_hosts":["myrddin.prole.org"],"mariadb_primary":["merlin.prole.org"],"mariadb_replica":["raspberry.prole.org"],"mariadb:children":["mariadb_primary","mariadb_replica"],"merlin_bootstrap":["merlin"],"k3s_hosts":["gandalf.prole.org"]},"hosts":{"merlin":"10.0.0.6","merlin.prole.org":"10.0.0.6","myrddin.prole.org":"10.0.0.3","pi.prole.org":"10.0.0.5","raspberry.prole.org":"10.0.0.4","retropie.prole.org":"10.0.0.207"},"unmapped_hosts":["gandalf.prole.org","k3s_agents","k3s_servers","mariadb_primary","mariadb_replica"]}
ANSIBLE_TOPOLOGY = {"domain":"knoe.org","realm":"PROLE.ORG","internal_records":{"aventage.knoe.org":"10.0.0.206","fairyland.knoe.org":"10.0.0.208","loghost.knoe.org":"10.0.0.3","merlin.knoe.org":"10.0.0.6","morana.knoe.org":"10.0.0.66","morgoth.knoe.org":"10.0.0.204","myrddin.knoe.org":"10.0.0.3","pi.knoe.org":"10.0.0.5","raspberry.knoe.org":"10.0.0.4","retropie.knoe.org":"10.0.0.207","synology.knoe.org":"10.0.0.203","zinfandel.knoe.org":"10.0.0.205"},"ad_dc":{"host":"myrddin.knoe.org","ip":"10.0.0.3"},"k3s":{"server_url":"https://myrddin.knoe.org:6443","server_host":"myrddin.knoe.org","token_present":true},"groups":{"iscsi":["pi.knoe.org","raspberry.knoe.org","myrddin.knoe.org","retropie.knoe.org","merlin.knoe.org","gandalf.knoe.org"],"pihole":["pi.knoe.org","raspberry.knoe.org"],"ad_dc":["myrddin.knoe.org"],"k3s_servers":["myrddin.knoe.org"],"k3s_agents":["merlin.knoe.org","gandalf.knoe.org"],"k3s_hosts:children":["k3s_servers","k3s_agents"],"linux_hosts":["pi.knoe.org","raspberry.knoe.org","myrddin.knoe.org","retropie.knoe.org","merlin.knoe.org","gandalf.knoe.org"],"ssl_hosts":["myrddin.knoe.org"],"mariadb_primary":["merlin.knoe.org"],"mariadb_replica":["raspberry.knoe.org"],"mariadb:children":["mariadb_primary","mariadb_replica"],"merlin_bootstrap":["merlin"],"k3s_hosts":["gandalf.knoe.org"]},"hosts":{"merlin":"10.0.0.6","merlin.knoe.org":"10.0.0.6","myrddin.knoe.org":"10.0.0.3","pi.knoe.org":"10.0.0.5","raspberry.knoe.org":"10.0.0.4","retropie.knoe.org":"10.0.0.207"},"unmapped_hosts":["gandalf.knoe.org","k3s_agents","k3s_servers","mariadb_primary","mariadb_replica"]}
KDC_ANSIBLE_DETECTED = 10.0.0.3
KDC_AUTO_DETECTED = 10.0.0.3
KERBEROS_AUTO_ENABLED = True
@ -147,11 +147,11 @@ KERBEROS_AUTO_ENABLED = True
; No configuration values captured yet for this section.
[System Environment]
PROLE_CONF = $HOME/dev/prole/conf
PROLE_DATA = $HOME/dev/prole/data
PROLE_HOME = $HOME/dev/prole
PROLE_LOGS = $HOME/dev/prole/logs
PROLE_SERVICE = $HOME/dev/prole/etc
KNOE_CONF = $HOME/dev/knoe/conf
PROLE_DATA = $HOME/dev/knoe/data
KNOE_HOME = $HOME/dev/knoe
PROLE_LOGS = $HOME/dev/knoe/logs
KNOE_SERVICE = $HOME/dev/knoe/etc
[Monitoring]
MONITORING_STORAGE_CLASS = local-path
@ -160,7 +160,7 @@ MONITORING_STORAGE_CLASS = local-path
; No configuration values captured yet for this section.
[Ollama]
OLLAMA_SERVERS = 10.0.0.208:11434,fairyland.prole.org:11434,k3d.localhost:11434,morgoth.prole.org:11434
OLLAMA_SERVERS = 10.0.0.208:11434,fairyland.knoe.org:11434,k3d.localhost:11434,morgoth.knoe.org:11434
[Optional Features]
AT_REST_ENCRYPTION_ENABLED = true
@ -179,8 +179,8 @@ DB_USER = root
[Initialize Cluster]
ENVIRONMENT = dev
K3S_SERVER_URL = https://myrddin.prole.org:6443
K3S_TOKEN = ${PROLE_SECRET:v1:ozzcomisjsQYIkSH:Ytp91WR_iP4tJyTAmdH_SRhcKycgzea0zLAgTBNxDsQaBPM-pR_VK3u9wc5QkFzszdAHZGBhVN2HKyqnz-cqDR0WAus88DFbF4zWlgvl6gKEAynaXbdMwAa6vYLUGi8ZE0u1pRiO4KJyiulhBIpfoMReM1Wu6Mj1-20hXw==}
K3S_SERVER_URL = https://myrddin.knoe.org:6443
K3S_TOKEN = ${KNOE_SECRET:v1:ozzcomisjsQYIkSH:Ytp91WR_iP4tJyTAmdH_SRhcKycgzea0zLAgTBNxDsQaBPM-pR_VK3u9wc5QkFzszdAHZGBhVN2HKyqnz-cqDR0WAus88DFbF4zWlgvl6gKEAynaXbdMwAa6vYLUGi8ZE0u1pRiO4KJyiulhBIpfoMReM1Wu6Mj1-20hXw==}
[Dev Cluster (k3d)]
CLUSTER_ENV = dev
@ -189,10 +189,10 @@ KUBECTL_CONTEXT = dev
MODE = k3d
[Service Cluster (k3s)]
CLUSTER_ENV = prole-service-cluster
DISPLAY_NAME = prole-service-cluster
K3S_SERVER_URL = https://myrddin.prole.org:6443
K3S_TOKEN = ${PROLE_SECRET:v1:-cslrAhG8WhxxJLY:vAx5MGOBcU1NBMjf4U-3y1djMDmwwOjiWkrutxPa4Li5P8RBjCBhEOCEdGP2CiPJJ6UQK-ietX-mu_5nO3yNNjpwDququT4U6lWHPEInSvUNH6ImU-HzPvm_diL2FwJtZm3sY5HgecIy2dwXB_vLnYaA_7VXt9zf0T70rw==}
CLUSTER_ENV = knoe-service-cluster
DISPLAY_NAME = knoe-service-cluster
K3S_SERVER_URL = https://myrddin.knoe.org:6443
K3S_TOKEN = ${KNOE_SECRET:v1:-cslrAhG8WhxxJLY:vAx5MGOBcU1NBMjf4U-3y1djMDmwwOjiWkrutxPa4Li5P8RBjCBhEOCEdGP2CiPJJ6UQK-ietX-mu_5nO3yNNjpwDququT4U6lWHPEInSvUNH6ImU-HzPvm_diL2FwJtZm3sY5HgecIy2dwXB_vLnYaA_7VXt9zf0T70rw==}
MODE = k3s
[GCP]
@ -202,21 +202,21 @@ ORG_ID = 584001916389
PROJECT_ID = plenary-truck-485623-p7
[Prod Cluster (k8s)]
ARTIFACTS_DIR = $HOME/dev/prole/data/staging
CLUSTER_ENV = prole-prod-cluster
DISPLAY_NAME = prole-prod-cluster
ARTIFACTS_DIR = $HOME/dev/knoe/data/staging
CLUSTER_ENV = knoe-prod-cluster
DISPLAY_NAME = knoe-prod-cluster
MODE = k8s
[Docker Build]
LOCAL_REGISTRY = localhost:5000
LOCAL_REGISTRY_INTERNAL = k3d-prole-registry.localhost:5000
LOCAL_REGISTRY_INTERNAL = k3d-knoe-registry.localhost:5000
[Initialization Scripts]
; No configuration values captured yet for this section.
[Deployment]
MODE = k3d
TARGET = prole-dev-cluster
TARGET = knoe-dev-cluster
[Install]
STATUS = Failed

View File

@ -1,4 +1,4 @@
; Prole Master Configuration File
; Knoe Master Configuration File
; Generated by install.py on 2026-04-17 00:35:15
; This file is used as input for Ansible deployment and k8s cluster creation.
@ -40,7 +40,7 @@ dependencies.opentofu.install = true
dependencies.python.install = true
dependencies.verify_all = false
disk_selection.disk_type = local
disk_selection.local_path = /Users/chrisfu/dev/prole/prole-tools-app/dist
disk_selection.local_path = /Users/chrisfu/dev/knoe/knoe-tools-app/dist
disk_selection.removable_mount =
env_setup.APP_CLUSTER_KUBECONTEXT =
env_setup.APP_CLUSTER_MODE = standard
@ -50,11 +50,11 @@ env_setup.DATABASE_NAMESPACE = ${DATABASE_NAMESPACE}
env_setup.DB_CLUSTER_KUBECONTEXT =
env_setup.DB_CLUSTER_MODE = standard
env_setup.DB_CLUSTER_NAME = knoe-cnpg-0
env_setup.PROLE_CONF = /Users/chrisfu/dev/prole/conf
env_setup.PROLE_DATA = /Users/chrisfu/dev/prole/data
env_setup.PROLE_HOME = /Users/chrisfu/dev/prole
env_setup.PROLE_LOGS = /Users/chrisfu/dev/prole/logs
env_setup.PROLE_SERVICE = /Users/chrisfu/dev/prole/etc
env_setup.KNOE_CONF = /Users/chrisfu/dev/knoe/conf
env_setup.PROLE_DATA = /Users/chrisfu/dev/knoe/data
env_setup.KNOE_HOME = /Users/chrisfu/dev/knoe
env_setup.PROLE_LOGS = /Users/chrisfu/dev/knoe/logs
env_setup.KNOE_SERVICE = /Users/chrisfu/dev/knoe/etc
gitops.git_provider = Gitea
gitops.node_selector =
init_cluster.app_cluster_kubecontext =
@ -74,10 +74,10 @@ init_cluster.db_cluster_name = knoe-cnpg-0
init_cluster.db_cluster_node_count = 3
init_cluster.db_cluster_region =
init_cluster.db_cluster_zones =
init_cluster.deployment_target = prole-service-cluster
init_cluster.deployment_target = knoe-service-cluster
init_cluster.gitops_enabled = true
init_cluster.k3s_server_url = https://myrddin.prole.org:6443
init_cluster.k3s_token = ${PROLE_SECRET:v1:-cslrAhG8WhxxJLY:vAx5MGOBcU1NBMjf4U-3y1djMDmwwOjiWkrutxPa4Li5P8RBjCBhEOCEdGP2CiPJJ6UQK-ietX-mu_5nO3yNNjpwDququT4U6lWHPEInSvUNH6ImU-HzPvm_diL2FwJtZm3sY5HgecIy2dwXB_vLnYaA_7VXt9zf0T70rw==}
init_cluster.k3s_server_url = https://myrddin.knoe.org:6443
init_cluster.k3s_token = ${KNOE_SECRET:v1:-cslrAhG8WhxxJLY:vAx5MGOBcU1NBMjf4U-3y1djMDmwwOjiWkrutxPa4Li5P8RBjCBhEOCEdGP2CiPJJ6UQK-ietX-mu_5nO3yNNjpwDququT4U6lWHPEInSvUNH6ImU-HzPvm_diL2FwJtZm3sY5HgecIy2dwXB_vLnYaA_7VXt9zf0T70rw==}
init_cluster.kerberos_enabled = true
init_cluster.mode = k3s
init_cluster.start_cluster = true
@ -96,8 +96,8 @@ init_password.cluster_name = ${CLUSTER_NAME}
init_password.db_cluster_name = knoe-cnpg-0
init_password.db_host_port = 5432
init_password.db_namespace = ${DATABASE_NAMESPACE}
init_password.db_password = ${PROLE_SECRET:v1:CsdBnE_l6fe36We6:QO1ZEnnsfovmzFHFfEtPwvi2FPKzLxu0pmg0K3X3DSTIt-Fx}
init_password.db_password_confirm = ${PROLE_SECRET:v1:CsdBnE_l6fe36We6:QO1ZEnnsfovmzFHFfEtPwvi2FPKzLxu0pmg0K3X3DSTIt-Fx}
init_password.db_password = ${KNOE_SECRET:v1:CsdBnE_l6fe36We6:QO1ZEnnsfovmzFHFfEtPwvi2FPKzLxu0pmg0K3X3DSTIt-Fx}
init_password.db_password_confirm = ${KNOE_SECRET:v1:CsdBnE_l6fe36We6:QO1ZEnnsfovmzFHFfEtPwvi2FPKzLxu0pmg0K3X3DSTIt-Fx}
init_password.db_username = root
init_password.generate_ssh_key = true
init_scripts.run_scripts = true
@ -113,55 +113,55 @@ ollama_config.model =
ollama_config.server_host =
ollama_config.server_port = 11434
supabase_config.pv_base_dir = /synology/d005
supabase_config.pv_node = gandalf.prole.org
supabase_config.pv_node = gandalf.knoe.org
[Global]
; Variables used by name in more than one place or assumed global scope
ARGOCD_NAMESPACE = argocd
ARTIFACT_REGISTRY = us-west3-docker.pkg.dev/plenary-truck-485623-p7/knoe-system
AUTHORITY_ENABLED = true
AUTH_HOSTNAME = api.prole.org
AUTH_HOSTNAME = api.knoe.org
AUTH_LOGIN_PATH = /auth/login
AUTH_RESPONSE_HEADERS = X-Prole-User,X-Prole-Email,X-Prole-Groups
AUTH_RESPONSE_HEADERS = X-Knoe-User,X-Knoe-Email,X-Knoe-Groups
AUTH_VERIFY_PATH = /auth/verify
CLUSTER_ENV = service
CLUSTER_NAME = knoe-db
CNPG_ELIGIBLE_NODES = gandalf.prole.org,merlin.prole.org,myrddin.prole.org
CNPG_PLACEMENT_PLAN_FILE = $HOME/dev/prole/conf/cnpg-placement/knoe-system-knoe-db.json
CNPG_ELIGIBLE_NODES = gandalf.knoe.org,merlin.knoe.org,myrddin.knoe.org
CNPG_PLACEMENT_PLAN_FILE = $HOME/dev/knoe/conf/cnpg-placement/knoe-system-knoe-db.json
CNPG_PLACEMENT_PLAN_HASH = 962fb2e7bfd2a48b
CNPG_PLACEMENT_PLAN_ID = cnpg-placement-962fb2e7bfd2a48b
CNPG_STAGE1_NODE = gandalf.prole.org
CNPG_STAGE1_NODE = gandalf.knoe.org
DATABASE_NAMESPACE = knoe-db
DB_HOST_PORT = 5432
DB_PASSWORD = ${PROLE_SECRET:v1:Vc5Sow_MQksbOtOJ:bvD1ABxenFlo0304dhf0Me_nzBX0SvLJ7oFvE_TkHGqc0YF8}
DB_PASSWORD = ${KNOE_SECRET:v1:Vc5Sow_MQksbOtOJ:bvD1ABxenFlo0304dhf0Me_nzBX0SvLJ7oFvE_TkHGqc0YF8}
DEPLOYMENT_MODE = k3s
DEPLOYMENT_TARGET = prole-service-cluster
DEPLOYMENT_TARGET = knoe-service-cluster
DOCKER_IMPORT_DIR =
DOCKER_PRELOAD = false
GITEA_HOSTNAME = git-internal.prole.org
GITLAB_PUBLIC_HOSTS = git.prole.org
GITEA_HOSTNAME = git-internal.knoe.org
GITLAB_PUBLIC_HOSTS = git.knoe.org
GITLAB_REPAIR_BLOCKED_AUTOCLEAN = 1
K3S_SERVER = https://myrddin.prole.org:6443
K3S_TOKEN = ${PROLE_SECRET:v1:CWWf3RHFdbUrmfrY:It8a2G8QUUIsqVwMsm3LsI4UvSSChEc_uAdESwzYplZLOCiSsCbOKuT9FbPpIwQvEaG_gLz9ZAfkD0EQxJp81KAtpk_X3K_nxVUa0RPRlbt_wdeXXoMoFFpN5BqXXz2HZwKgh_gpK1hjVbsJQHKAbTqWfu8u_LTmYYg4ag==}
K3S_SERVER = https://myrddin.knoe.org:6443
K3S_TOKEN = ${KNOE_SECRET:v1:CWWf3RHFdbUrmfrY:It8a2G8QUUIsqVwMsm3LsI4UvSSChEc_uAdESwzYplZLOCiSsCbOKuT9FbPpIwQvEaG_gLz9ZAfkD0EQxJp81KAtpk_X3K_nxVUa0RPRlbt_wdeXXoMoFFpN5BqXXz2HZwKgh_gpK1hjVbsJQHKAbTqWfu8u_LTmYYg4ag==}
KNOE_DB_USER = root
KNOE_IMAGE_REGISTRY = registry.prole.org
KNOE_IMAGE_REGISTRY = registry.knoe.org
MONITORING_STORAGE_CLASS = local-path
OPENTOFU_URL = http://127.0.0.1:8080
OPTIONAL_WORKLOADS_MIN_READY_SCHEDULABLE_NODES = 2
PROLE_HOME = $HOME/dev/prole
PROLE_K3S_SERVER = https://myrddin.prole.org:6443
PROLE_K3S_TOKEN = ${PROLE_SECRET:v1:-cslrAhG8WhxxJLY:vAx5MGOBcU1NBMjf4U-3y1djMDmwwOjiWkrutxPa4Li5P8RBjCBhEOCEdGP2CiPJJ6UQK-ietX-mu_5nO3yNNjpwDququT4U6lWHPEInSvUNH6ImU-HzPvm_diL2FwJtZm3sY5HgecIy2dwXB_vLnYaA_7VXt9zf0T70rw==}
PROTECTED_DB_HOSTS = db.prole.org
PROTECTED_GIT_HOSTS = git.prole.org
KNOE_HOME = $HOME/dev/knoe
PROLE_K3S_SERVER = https://myrddin.knoe.org:6443
PROLE_K3S_TOKEN = ${KNOE_SECRET:v1:-cslrAhG8WhxxJLY:vAx5MGOBcU1NBMjf4U-3y1djMDmwwOjiWkrutxPa4Li5P8RBjCBhEOCEdGP2CiPJJ6UQK-ietX-mu_5nO3yNNjpwDququT4U6lWHPEInSvUNH6ImU-HzPvm_diL2FwJtZm3sY5HgecIy2dwXB_vLnYaA_7VXt9zf0T70rw==}
PROTECTED_DB_HOSTS = db.knoe.org
PROTECTED_GIT_HOSTS = git.knoe.org
REDIS_HOST = redis-master.knoe-system.svc.cluster.local
REGISTRY_NAMESPACE = knoe-system
SERVICE_HOSTNAME = svc.prole.org
SERVICE_HOSTNAME = svc.knoe.org
SERVICE_NAMESPACE = knoe-system
SUPABASE_API_HOSTNAME = supabase.prole.org
SUPABASE_API_HOSTNAME = supabase.knoe.org
SUPABASE_PV_BASE = /synology/d005
SUPABASE_PV_BASE_DIR = /synology/d005
SUPABASE_PV_NODE = gandalf.prole.org
SUPABASE_STUDIO_HOSTNAME = db.prole.org
SUPABASE_PV_NODE = gandalf.knoe.org
SUPABASE_STUDIO_HOSTNAME = db.knoe.org
SYNOLOGY_ROOTS = /synology/d001,/synology/d002,/synology/d004,/synology/d005
[Welcome]
@ -171,13 +171,13 @@ SYNOLOGY_ROOTS = /synology/d001,/synology/d002,/synology/d004,/synology/d005
STATUS = All installed
[Network]
AD_DC_HOST = myrddin.prole.org
AD_DC_HOST = myrddin.knoe.org
AD_DC_IP = 10.0.0.3
ANSIBLE_DOMAIN = prole.org
ANSIBLE_INFRASTRUCTURE = $HOME/dev/prole/infrastructure
ANSIBLE_INVENTORY = $HOME/dev/prole/infrastructure/inventory
ANSIBLE_DOMAIN = knoe.org
ANSIBLE_INFRASTRUCTURE = $HOME/dev/knoe/infrastructure
ANSIBLE_INVENTORY = $HOME/dev/knoe/infrastructure/inventory
ANSIBLE_REALM = PROLE.ORG
ANSIBLE_TOPOLOGY = {"domain":"prole.org","realm":"PROLE.ORG","internal_records":{"aventage.prole.org":"10.0.0.206","fairyland.prole.org":"10.0.0.208","loghost.prole.org":"10.0.0.3","merlin.prole.org":"10.0.0.6","morana.prole.org":"10.0.0.66","morgoth.prole.org":"10.0.0.204","myrddin.prole.org":"10.0.0.3","pi.prole.org":"10.0.0.5","raspberry.prole.org":"10.0.0.4","retropie.prole.org":"10.0.0.207","synology.prole.org":"10.0.0.203","zinfandel.prole.org":"10.0.0.205"},"ad_dc":{"host":"myrddin.prole.org","ip":"10.0.0.3"},"k3s":{"server_url":"https://myrddin.prole.org:6443","server_host":"myrddin.prole.org","token_present":true},"groups":{"iscsi":["pi.prole.org","raspberry.prole.org","myrddin.prole.org","retropie.prole.org","merlin.prole.org","gandalf.prole.org"],"pihole":["pi.prole.org","raspberry.prole.org"],"ad_dc":["myrddin.prole.org"],"k3s_servers":["myrddin.prole.org"],"k3s_agents":["merlin.prole.org","gandalf.prole.org"],"k3s_hosts:children":["k3s_servers","k3s_agents"],"linux_hosts":["pi.prole.org","raspberry.prole.org","myrddin.prole.org","retropie.prole.org","merlin.prole.org","gandalf.prole.org"],"ssl_hosts":["myrddin.prole.org"],"mariadb_primary":["merlin.prole.org"],"mariadb_replica":["raspberry.prole.org"],"mariadb:children":["mariadb_primary","mariadb_replica"],"merlin_bootstrap":["merlin"],"k3s_hosts":["gandalf.prole.org"]},"hosts":{"merlin":"10.0.0.6","merlin.prole.org":"10.0.0.6","myrddin.prole.org":"10.0.0.3","pi.prole.org":"10.0.0.5","raspberry.prole.org":"10.0.0.4","retropie.prole.org":"10.0.0.207"},"unmapped_hosts":["gandalf.prole.org","k3s_agents","k3s_servers","mariadb_primary","mariadb_replica"]}
ANSIBLE_TOPOLOGY = {"domain":"knoe.org","realm":"PROLE.ORG","internal_records":{"aventage.knoe.org":"10.0.0.206","fairyland.knoe.org":"10.0.0.208","loghost.knoe.org":"10.0.0.3","merlin.knoe.org":"10.0.0.6","morana.knoe.org":"10.0.0.66","morgoth.knoe.org":"10.0.0.204","myrddin.knoe.org":"10.0.0.3","pi.knoe.org":"10.0.0.5","raspberry.knoe.org":"10.0.0.4","retropie.knoe.org":"10.0.0.207","synology.knoe.org":"10.0.0.203","zinfandel.knoe.org":"10.0.0.205"},"ad_dc":{"host":"myrddin.knoe.org","ip":"10.0.0.3"},"k3s":{"server_url":"https://myrddin.knoe.org:6443","server_host":"myrddin.knoe.org","token_present":true},"groups":{"iscsi":["pi.knoe.org","raspberry.knoe.org","myrddin.knoe.org","retropie.knoe.org","merlin.knoe.org","gandalf.knoe.org"],"pihole":["pi.knoe.org","raspberry.knoe.org"],"ad_dc":["myrddin.knoe.org"],"k3s_servers":["myrddin.knoe.org"],"k3s_agents":["merlin.knoe.org","gandalf.knoe.org"],"k3s_hosts:children":["k3s_servers","k3s_agents"],"linux_hosts":["pi.knoe.org","raspberry.knoe.org","myrddin.knoe.org","retropie.knoe.org","merlin.knoe.org","gandalf.knoe.org"],"ssl_hosts":["myrddin.knoe.org"],"mariadb_primary":["merlin.knoe.org"],"mariadb_replica":["raspberry.knoe.org"],"mariadb:children":["mariadb_primary","mariadb_replica"],"merlin_bootstrap":["merlin"],"k3s_hosts":["gandalf.knoe.org"]},"hosts":{"merlin":"10.0.0.6","merlin.knoe.org":"10.0.0.6","myrddin.knoe.org":"10.0.0.3","pi.knoe.org":"10.0.0.5","raspberry.knoe.org":"10.0.0.4","retropie.knoe.org":"10.0.0.207"},"unmapped_hosts":["gandalf.knoe.org","k3s_agents","k3s_servers","mariadb_primary","mariadb_replica"]}
KDC_ANSIBLE_DETECTED = 10.0.0.3
KDC_AUTO_DETECTED = 10.0.0.3
KERBEROS_AUTO_ENABLED = True
@ -195,11 +195,11 @@ PORT_FORWARD_K3S_MAPPING_8 = id=grafana;namespace=monitoring;target=svc/kps-graf
PORT_FORWARD_K3S_MAPPING_9 = id=gitea-http;namespace=gitea;target=svc/gitea-http;address=0.0.0.0;hostPort=13000;servicePort=3000;protocol=TCP;description=Gitea Web
[System Environment]
PROLE_CONF = $HOME/dev/prole/conf
PROLE_DATA = $HOME/dev/prole/data
PROLE_HOME = $HOME/dev/prole
PROLE_LOGS = $HOME/dev/prole/logs
PROLE_SERVICE = $HOME/dev/prole/etc
KNOE_CONF = $HOME/dev/knoe/conf
PROLE_DATA = $HOME/dev/knoe/data
KNOE_HOME = $HOME/dev/knoe
PROLE_LOGS = $HOME/dev/knoe/logs
KNOE_SERVICE = $HOME/dev/knoe/etc
[Monitoring]
MONITORING_STORAGE_CLASS = local-path
@ -226,8 +226,8 @@ DB_USER = root
[Initialize Cluster]
ENVIRONMENT = service
K3S_SERVER_URL = https://myrddin.prole.org:6443
K3S_TOKEN = ${PROLE_SECRET:v1:-cslrAhG8WhxxJLY:vAx5MGOBcU1NBMjf4U-3y1djMDmwwOjiWkrutxPa4Li5P8RBjCBhEOCEdGP2CiPJJ6UQK-ietX-mu_5nO3yNNjpwDququT4U6lWHPEInSvUNH6ImU-HzPvm_diL2FwJtZm3sY5HgecIy2dwXB_vLnYaA_7VXt9zf0T70rw==}
K3S_SERVER_URL = https://myrddin.knoe.org:6443
K3S_TOKEN = ${KNOE_SECRET:v1:-cslrAhG8WhxxJLY:vAx5MGOBcU1NBMjf4U-3y1djMDmwwOjiWkrutxPa4Li5P8RBjCBhEOCEdGP2CiPJJ6UQK-ietX-mu_5nO3yNNjpwDququT4U6lWHPEInSvUNH6ImU-HzPvm_diL2FwJtZm3sY5HgecIy2dwXB_vLnYaA_7VXt9zf0T70rw==}
[Dev Cluster (k3d)]
CLUSTER_ENV = k3d-knoe-dev-cluster
@ -236,11 +236,11 @@ KUBECTL_CONTEXT = service
MODE = k3d
[Service Cluster (k3s)]
CLUSTER_ENV = prole-service-cluster
DISPLAY_NAME = prole-service-cluster
K3S_SERVER_URL = https://myrddin.prole.org:6443
K3S_TOKEN = ${PROLE_SECRET:v1:-cslrAhG8WhxxJLY:vAx5MGOBcU1NBMjf4U-3y1djMDmwwOjiWkrutxPa4Li5P8RBjCBhEOCEdGP2CiPJJ6UQK-ietX-mu_5nO3yNNjpwDququT4U6lWHPEInSvUNH6ImU-HzPvm_diL2FwJtZm3sY5HgecIy2dwXB_vLnYaA_7VXt9zf0T70rw==}
KUBECTL_CONTEXT = prole-service-cluster
CLUSTER_ENV = knoe-service-cluster
DISPLAY_NAME = knoe-service-cluster
K3S_SERVER_URL = https://myrddin.knoe.org:6443
K3S_TOKEN = ${KNOE_SECRET:v1:-cslrAhG8WhxxJLY:vAx5MGOBcU1NBMjf4U-3y1djMDmwwOjiWkrutxPa4Li5P8RBjCBhEOCEdGP2CiPJJ6UQK-ietX-mu_5nO3yNNjpwDququT4U6lWHPEInSvUNH6ImU-HzPvm_diL2FwJtZm3sY5HgecIy2dwXB_vLnYaA_7VXt9zf0T70rw==}
KUBECTL_CONTEXT = knoe-service-cluster
MODE = k3s
PIPELINE_URL = http://127.0.0.1:8080
@ -249,8 +249,8 @@ PIPELINE_URL = http://127.0.0.1:8080
[Prod Cluster (k8s)]
ARTIFACTS_DIR =
CLUSTER_ENV = prole-prod-cluster
DISPLAY_NAME = prole-prod-cluster
CLUSTER_ENV = knoe-prod-cluster
DISPLAY_NAME = knoe-prod-cluster
MODE = k8s
PIPELINE_URL = http://127.0.0.1:8080
@ -262,7 +262,7 @@ PIPELINE_URL = http://127.0.0.1:8080
[Deployment]
MODE = k3d
TARGET = prole-dev-cluster
TARGET = knoe-dev-cluster
[Install]
STATUS = Failed

View File

@ -1,4 +1,4 @@
; Prole Master Configuration File
; Knoe Master Configuration File
; Generated by install.py on 2026-04-02 23:44:38
; This file is used as input for Ansible deployment and k8s cluster creation.
@ -8,7 +8,7 @@
[Inputs]
; Screen-scoped inputs used for unattended replays (-S)
argocd.node_selector = gandalf.prole.org
argocd.node_selector = gandalf.knoe.org
build.deploy_env = Dev
build.run_build = false
database_options.distribution = percona
@ -39,24 +39,24 @@ dependencies.opentofu.install = true
dependencies.python.install = true
dependencies.verify_all = false
disk_selection.disk_type = local
disk_selection.local_path = /Users/chrisfu/dev/prole/prole-tools-app/dist
disk_selection.local_path = /Users/chrisfu/dev/knoe/knoe-tools-app/dist
disk_selection.removable_mount =
env_setup.CLUSTER_NAME = ${CLUSTER_NAME}
env_setup.DATABASE_NAMESPACE = ${DATABASE_NAMESPACE}
env_setup.PROLE_CONF = /Users/chrisfu/dev/prole/conf
env_setup.PROLE_DATA = /Users/chrisfu/dev/prole/data
env_setup.PROLE_HOME = /Users/chrisfu/dev/prole
env_setup.PROLE_LOGS = /Users/chrisfu/dev/prole/logs
env_setup.PROLE_SERVICE = /Users/chrisfu/dev/prole/etc
env_setup.KNOE_CONF = /Users/chrisfu/dev/knoe/conf
env_setup.PROLE_DATA = /Users/chrisfu/dev/knoe/data
env_setup.KNOE_HOME = /Users/chrisfu/dev/knoe
env_setup.PROLE_LOGS = /Users/chrisfu/dev/knoe/logs
env_setup.KNOE_SERVICE = /Users/chrisfu/dev/knoe/etc
gitops.git_provider = GitLab
gitops.node_selector = gandalf.prole.org
gitops.node_selector = gandalf.knoe.org
init_cluster.argocd_enabled = true
init_cluster.at_rest_encryption_enabled = true
init_cluster.cluster_env = service
init_cluster.deployment_target = prole-service-cluster
init_cluster.deployment_target = knoe-service-cluster
init_cluster.gitops_enabled = true
init_cluster.k3s_server_url = https://myrddin.prole.org:6443
init_cluster.k3s_token = ${PROLE_SECRET:v1:-5rud_XHzHRKoZIU:Dxv2nKbY883uDrJlmjRIqUKTtF42KPwXmzONy1s0-cIsJ2TLpTkaSWjfYx0tXNnz65lPnwIR16kXVtICYHhOxhfSIaz-lQiNGwZ_hm1tGMjp9BvpANt_l5Ie6swbOHVw8QfpGLtiXuIv7ur2ocSX4xAYSdCKtYWWV58U0Q==}
init_cluster.k3s_server_url = https://myrddin.knoe.org:6443
init_cluster.k3s_token = ${KNOE_SECRET:v1:-5rud_XHzHRKoZIU:Dxv2nKbY883uDrJlmjRIqUKTtF42KPwXmzONy1s0-cIsJ2TLpTkaSWjfYx0tXNnz65lPnwIR16kXVtICYHhOxhfSIaz-lQiNGwZ_hm1tGMjp9BvpANt_l5Ie6swbOHVw8QfpGLtiXuIv7ur2ocSX4xAYSdCKtYWWV58U0Q==}
init_cluster.kerberos_enabled = true
init_cluster.mode = k3s
init_cluster.start_cluster = true
@ -66,65 +66,65 @@ init_cluster.supabase_enabled = true
init_cluster.supabase_meta_enabled = true
init_cluster.supabase_realtime_enabled = true
init_cluster.supabase_studio_enabled = false
init_cluster.supabase_studio_url = db.prole.org
init_cluster.supabase_studio_url = db.knoe.org
init_cnpg_deploy.force_rollout = false
init_cnpg_deploy.run_deploy = true
init_db_build.run_build = true
init_password.cluster_name = ${CLUSTER_NAME}
init_password.db_host_port = 5432
init_password.db_namespace = ${DATABASE_NAMESPACE}
init_password.db_password = ${PROLE_SECRET:v1:TYl1mPEwJblWR-4g:PalHm2ODG8WF1ZRVeUt51erDvA0W0icX}
init_password.db_password_confirm = ${PROLE_SECRET:v1:TYl1mPEwJblWR-4g:PalHm2ODG8WF1ZRVeUt51erDvA0W0icX}
init_password.db_password = ${KNOE_SECRET:v1:TYl1mPEwJblWR-4g:PalHm2ODG8WF1ZRVeUt51erDvA0W0icX}
init_password.db_password_confirm = ${KNOE_SECRET:v1:TYl1mPEwJblWR-4g:PalHm2ODG8WF1ZRVeUt51erDvA0W0icX}
init_password.db_username = root
init_password.generate_ssh_key = true
init_scripts.run_scripts = true
kerberos_config.enabled = true
kerberos_config.init_authority = false
kerberos_config.kdc = 10.0.0.3
kerberos_config.password = ${PROLE_SECRET:v1:U-EPMl7qv4heEB1k:BEcXGbI_LT4lCXwBuvFEGgPbLFa9MpVzECObdH0pbLtClDHf}
kerberos_config.password = ${KNOE_SECRET:v1:U-EPMl7qv4heEB1k:BEcXGbI_LT4lCXwBuvFEGgPbLFa9MpVzECObdH0pbLtClDHf}
kerberos_config.realm = PROLE.ORG
kerberos_config.test_connection = true
kerberos_config.user = administrator
network_scan.run = true
ollama_config.model =
ollama_config.server_host = fairyland.prole.org
ollama_config.server_host = fairyland.knoe.org
ollama_config.server_port = 11434
supabase_config.pv_base_dir = /synology/d005
supabase_config.pv_node = gandalf.prole.org
supabase_config.pv_node = gandalf.knoe.org
[Global]
; Variables used by name in more than one place or assumed global scope
ARGOCD_NAMESPACE = argocd
ARGOCD_NODE_SELECTOR = gandalf.prole.org
ARGOCD_NODE_SELECTOR = gandalf.knoe.org
CLUSTER_ENV = service
CLUSTER_NAME = knoe-db
CNPG_ELIGIBLE_NODES = gandalf.prole.org,merlin.prole.org,myrddin.prole.org
CNPG_PLACEMENT_PLAN_FILE = /Users/chrisfu/dev/prole/conf/cnpg-placement/knoe-system-knoe-db.json
CNPG_ELIGIBLE_NODES = gandalf.knoe.org,merlin.knoe.org,myrddin.knoe.org
CNPG_PLACEMENT_PLAN_FILE = /Users/chrisfu/dev/knoe/conf/cnpg-placement/knoe-system-knoe-db.json
CNPG_PLACEMENT_PLAN_HASH = 962fb2e7bfd2a48b
CNPG_PLACEMENT_PLAN_ID = cnpg-placement-962fb2e7bfd2a48b
CNPG_STAGE1_NODE = gandalf.prole.org
CNPG_STAGE1_NODE = gandalf.knoe.org
DATABASE_NAMESPACE = knoe-db
DB_HOST_PORT = 5432
DB_PASSWORD = ${PROLE_SECRET:v1:t7NgRHfXTXH-mHcx:CRbKP9b6ccuxrTMMeJ742Q48_vegoUY4}
DB_PASSWORD = ${KNOE_SECRET:v1:t7NgRHfXTXH-mHcx:CRbKP9b6ccuxrTMMeJ742Q48_vegoUY4}
DEPLOYMENT_MODE = k3s
DEPLOYMENT_TARGET = prole-service-cluster
DEPLOYMENT_TARGET = knoe-service-cluster
DOCKER_IMPORT_DIR =
DOCKER_PRELOAD = false
GITEA_NODE_SELECTOR = gandalf.prole.org
K3S_SERVER = https://myrddin.prole.org:6443
K3S_TOKEN = ${PROLE_SECRET:v1:gnQjvO_dhM7qkU_g:kFb7E6IQ40RM64JfsrJWBPzkJsMaLXNpNPxfho6t8w5KAeWCAyrw2bMsQtJ8n7cPc_SLWh_zX53Sa1pvEOclmd79e-c_Qff0gZleba1PzzfkjsYRfVlpzQ34gdAHrNHQG2mKnpkcyrNFZ0j6J-w4c3m_m6bTN1cV1KQvMQ==}
GITEA_NODE_SELECTOR = gandalf.knoe.org
K3S_SERVER = https://myrddin.knoe.org:6443
K3S_TOKEN = ${KNOE_SECRET:v1:gnQjvO_dhM7qkU_g:kFb7E6IQ40RM64JfsrJWBPzkJsMaLXNpNPxfho6t8w5KAeWCAyrw2bMsQtJ8n7cPc_SLWh_zX53Sa1pvEOclmd79e-c_Qff0gZleba1PzzfkjsYRfVlpzQ34gdAHrNHQG2mKnpkcyrNFZ0j6J-w4c3m_m6bTN1cV1KQvMQ==}
KNOE_DB_USER = root
KUBECONTEXT = knoe.dev.prole.org
OPENTOFU_URL = http://myrddin.prole.org:8080
KUBECONTEXT = knoe.dev.knoe.org
OPENTOFU_URL = http://myrddin.knoe.org:8080
OPTIONAL_WORKLOADS_MIN_READY_SCHEDULABLE_NODES = 2
PROLE_HOME = /Users/chrisfu/dev/prole
PROLE_K3S_SERVER = https://myrddin.prole.org:6443
PROLE_K3S_TOKEN = ${PROLE_SECRET:v1:-5rud_XHzHRKoZIU:Dxv2nKbY883uDrJlmjRIqUKTtF42KPwXmzONy1s0-cIsJ2TLpTkaSWjfYx0tXNnz65lPnwIR16kXVtICYHhOxhfSIaz-lQiNGwZ_hm1tGMjp9BvpANt_l5Ie6swbOHVw8QfpGLtiXuIv7ur2ocSX4xAYSdCKtYWWV58U0Q==}
KNOE_HOME = /Users/chrisfu/dev/knoe
PROLE_K3S_SERVER = https://myrddin.knoe.org:6443
PROLE_K3S_TOKEN = ${KNOE_SECRET:v1:-5rud_XHzHRKoZIU:Dxv2nKbY883uDrJlmjRIqUKTtF42KPwXmzONy1s0-cIsJ2TLpTkaSWjfYx0tXNnz65lPnwIR16kXVtICYHhOxhfSIaz-lQiNGwZ_hm1tGMjp9BvpANt_l5Ie6swbOHVw8QfpGLtiXuIv7ur2ocSX4xAYSdCKtYWWV58U0Q==}
REGISTRY_NAMESPACE = knoe-system
SERVICE_NAMESPACE = knoe-system
SUPABASE_PV_BASE = /synology/d005
SUPABASE_PV_BASE_DIR = /synology/d005
SUPABASE_PV_NODE = gandalf.prole.org
SUPABASE_PV_NODE = gandalf.knoe.org
SYNOLOGY_ROOTS = /synology/d001,/synology/d002,/synology/d004,/synology/d005
[Welcome]
@ -134,13 +134,13 @@ SYNOLOGY_ROOTS = /synology/d001,/synology/d002,/synology/d004,/synology/d005
STATUS = All installed
[Network]
AD_DC_HOST = myrddin.prole.org
AD_DC_HOST = myrddin.knoe.org
AD_DC_IP = 10.0.0.3
ANSIBLE_DOMAIN = prole.org
ANSIBLE_INFRASTRUCTURE = /Users/chrisfu/dev/prole/infrastructure
ANSIBLE_INVENTORY = /Users/chrisfu/dev/prole/infrastructure/inventory
ANSIBLE_DOMAIN = knoe.org
ANSIBLE_INFRASTRUCTURE = /Users/chrisfu/dev/knoe/infrastructure
ANSIBLE_INVENTORY = /Users/chrisfu/dev/knoe/infrastructure/inventory
ANSIBLE_REALM = PROLE.ORG
ANSIBLE_TOPOLOGY = {"domain":"prole.org","realm":"PROLE.ORG","internal_records":{"aventage.prole.org":"10.0.0.206","fairyland.prole.org":"10.0.0.208","loghost.prole.org":"10.0.0.3","merlin.prole.org":"10.0.0.6","morana.prole.org":"10.0.0.66","morgoth.prole.org":"10.0.0.204","myrddin.prole.org":"10.0.0.3","pi.prole.org":"10.0.0.5","raspberry.prole.org":"10.0.0.4","retropie.prole.org":"10.0.0.207","synology.prole.org":"10.0.0.203","zinfandel.prole.org":"10.0.0.205"},"ad_dc":{"host":"myrddin.prole.org","ip":"10.0.0.3"},"k3s":{"server_url":"https://myrddin.prole.org:6443","server_host":"myrddin.prole.org","token_present":true},"groups":{"iscsi":["pi.prole.org","raspberry.prole.org","myrddin.prole.org","retropie.prole.org","merlin.prole.org","gandalf.prole.org"],"pihole":["pi.prole.org","raspberry.prole.org"],"ad_dc":["myrddin.prole.org"],"k3s_servers":["myrddin.prole.org"],"k3s_agents":["merlin.prole.org","gandalf.prole.org"],"k3s_hosts:children":["k3s_servers","k3s_agents"],"linux_hosts":["pi.prole.org","raspberry.prole.org","myrddin.prole.org","retropie.prole.org","merlin.prole.org","gandalf.prole.org"],"ssl_hosts":["myrddin.prole.org"],"mariadb_primary":["merlin.prole.org"],"mariadb_replica":["raspberry.prole.org"],"mariadb:children":["mariadb_primary","mariadb_replica"],"merlin_bootstrap":["merlin"],"k3s_hosts":["gandalf.prole.org"]},"hosts":{"merlin":"10.0.0.6","merlin.prole.org":"10.0.0.6","myrddin.prole.org":"10.0.0.3","pi.prole.org":"10.0.0.5","raspberry.prole.org":"10.0.0.4","retropie.prole.org":"10.0.0.207"},"unmapped_hosts":["gandalf.prole.org","k3s_agents","k3s_servers","mariadb_primary","mariadb_replica"]}
ANSIBLE_TOPOLOGY = {"domain":"knoe.org","realm":"PROLE.ORG","internal_records":{"aventage.knoe.org":"10.0.0.206","fairyland.knoe.org":"10.0.0.208","loghost.knoe.org":"10.0.0.3","merlin.knoe.org":"10.0.0.6","morana.knoe.org":"10.0.0.66","morgoth.knoe.org":"10.0.0.204","myrddin.knoe.org":"10.0.0.3","pi.knoe.org":"10.0.0.5","raspberry.knoe.org":"10.0.0.4","retropie.knoe.org":"10.0.0.207","synology.knoe.org":"10.0.0.203","zinfandel.knoe.org":"10.0.0.205"},"ad_dc":{"host":"myrddin.knoe.org","ip":"10.0.0.3"},"k3s":{"server_url":"https://myrddin.knoe.org:6443","server_host":"myrddin.knoe.org","token_present":true},"groups":{"iscsi":["pi.knoe.org","raspberry.knoe.org","myrddin.knoe.org","retropie.knoe.org","merlin.knoe.org","gandalf.knoe.org"],"pihole":["pi.knoe.org","raspberry.knoe.org"],"ad_dc":["myrddin.knoe.org"],"k3s_servers":["myrddin.knoe.org"],"k3s_agents":["merlin.knoe.org","gandalf.knoe.org"],"k3s_hosts:children":["k3s_servers","k3s_agents"],"linux_hosts":["pi.knoe.org","raspberry.knoe.org","myrddin.knoe.org","retropie.knoe.org","merlin.knoe.org","gandalf.knoe.org"],"ssl_hosts":["myrddin.knoe.org"],"mariadb_primary":["merlin.knoe.org"],"mariadb_replica":["raspberry.knoe.org"],"mariadb:children":["mariadb_primary","mariadb_replica"],"merlin_bootstrap":["merlin"],"k3s_hosts":["gandalf.knoe.org"]},"hosts":{"merlin":"10.0.0.6","merlin.knoe.org":"10.0.0.6","myrddin.knoe.org":"10.0.0.3","pi.knoe.org":"10.0.0.5","raspberry.knoe.org":"10.0.0.4","retropie.knoe.org":"10.0.0.207"},"unmapped_hosts":["gandalf.knoe.org","k3s_agents","k3s_servers","mariadb_primary","mariadb_replica"]}
KDC_ANSIBLE_DETECTED = 10.0.0.3
KDC_AUTO_DETECTED = 10.0.0.3
KERBEROS_AUTO_ENABLED = True
@ -163,33 +163,33 @@ PORT_FORWARD_K3S_MAPPING_8 = id=grafana;namespace=monitoring;target=svc/kps-graf
PORT_FORWARD_K3S_MAPPING_9 = id=supabase-kong;namespace=supabase;target=svc/kong;address=0.0.0.0;hostPort=8000;servicePort=8000;protocol=TCP;description=Supabase API (Kong)
[System Environment]
PROLE_CONF = /Users/chrisfu/dev/prole/conf
PROLE_DATA = /Users/chrisfu/dev/prole/data
PROLE_HOME = /Users/chrisfu/dev/prole
PROLE_LOGS = /Users/chrisfu/dev/prole/logs
PROLE_SERVICE = /Users/chrisfu/dev/prole/etc
KNOE_CONF = /Users/chrisfu/dev/knoe/conf
PROLE_DATA = /Users/chrisfu/dev/knoe/data
KNOE_HOME = /Users/chrisfu/dev/knoe
PROLE_LOGS = /Users/chrisfu/dev/knoe/logs
KNOE_SERVICE = /Users/chrisfu/dev/knoe/etc
[Monitoring]
GRAFANA_ADMIN_PASSWORD = ${PROLE_SECRET:v1:L2BhAyHRKVei4cGM:-J83-HR_CpnPFpiB6NbOXKdmmagVW2qL}
GRAFANA_ADMIN_PASSWORD = ${KNOE_SECRET:v1:L2BhAyHRKVei4cGM:-J83-HR_CpnPFpiB6NbOXKdmmagVW2qL}
[Kerberos Authentication]
AD_PORT_FORWARD = 1
AD_PROXY_HOST_NETWORK = 1
AD_PROXY_IMAGE = alpine/socat
AD_PROXY_SERVICE = prole-kerberos-ad-dc
AD_PROXY_SERVICE = knoe-kerberos-ad-dc
AD_TCP_PORTS = 88 389 445 464 636
AD_UDP_PORTS = 88 464
ENABLED = True
KDC = 10.0.0.3
PASSWORD = ${PROLE_SECRET:v1:1nB72WDtH1Crj8Ey:ssg1wYn-1Y5Q4wF1tUZL2kO-7kLL-cSxq5GkTdeY_N3JQtJW}
PASSWORD = ${KNOE_SECRET:v1:1nB72WDtH1Crj8Ey:ssg1wYn-1Y5Q4wF1tUZL2kO-7kLL-cSxq5GkTdeY_N3JQtJW}
REALM = PROLE.ORG
SERVER = 10.0.0.3
STATUS = Initialized
USER = administrator
[Ollama]
OLLAMA_HOST = http://fairyland.prole.org:11434
OLLAMA_SERVER_HOST = fairyland.prole.org
OLLAMA_HOST = http://fairyland.knoe.org:11434
OLLAMA_SERVER_HOST = fairyland.knoe.org
OLLAMA_SERVER_PORT = 11434
[Optional Features]
@ -207,8 +207,8 @@ DB_USER = root
[Initialize Cluster]
ENVIRONMENT = service
K3S_SERVER_URL = https://myrddin.prole.org:6443
K3S_TOKEN = ${PROLE_SECRET:v1:-5rud_XHzHRKoZIU:Dxv2nKbY883uDrJlmjRIqUKTtF42KPwXmzONy1s0-cIsJ2TLpTkaSWjfYx0tXNnz65lPnwIR16kXVtICYHhOxhfSIaz-lQiNGwZ_hm1tGMjp9BvpANt_l5Ie6swbOHVw8QfpGLtiXuIv7ur2ocSX4xAYSdCKtYWWV58U0Q==}
K3S_SERVER_URL = https://myrddin.knoe.org:6443
K3S_TOKEN = ${KNOE_SECRET:v1:-5rud_XHzHRKoZIU:Dxv2nKbY883uDrJlmjRIqUKTtF42KPwXmzONy1s0-cIsJ2TLpTkaSWjfYx0tXNnz65lPnwIR16kXVtICYHhOxhfSIaz-lQiNGwZ_hm1tGMjp9BvpANt_l5Ie6swbOHVw8QfpGLtiXuIv7ur2ocSX4xAYSdCKtYWWV58U0Q==}
[Dev Cluster (k3d)]
CLUSTER_ENV = k3d-knoe-dev-cluster
@ -217,22 +217,22 @@ KUBECTL_CONTEXT = service
MODE = k3d
[Service Cluster (k3s)]
CLUSTER_ENV = prole-service-cluster
DISPLAY_NAME = prole-service-cluster
K3S_SERVER_URL = https://myrddin.prole.org:6443
K3S_TOKEN = ${PROLE_SECRET:v1:-5rud_XHzHRKoZIU:Dxv2nKbY883uDrJlmjRIqUKTtF42KPwXmzONy1s0-cIsJ2TLpTkaSWjfYx0tXNnz65lPnwIR16kXVtICYHhOxhfSIaz-lQiNGwZ_hm1tGMjp9BvpANt_l5Ie6swbOHVw8QfpGLtiXuIv7ur2ocSX4xAYSdCKtYWWV58U0Q==}
CLUSTER_ENV = knoe-service-cluster
DISPLAY_NAME = knoe-service-cluster
K3S_SERVER_URL = https://myrddin.knoe.org:6443
K3S_TOKEN = ${KNOE_SECRET:v1:-5rud_XHzHRKoZIU:Dxv2nKbY883uDrJlmjRIqUKTtF42KPwXmzONy1s0-cIsJ2TLpTkaSWjfYx0tXNnz65lPnwIR16kXVtICYHhOxhfSIaz-lQiNGwZ_hm1tGMjp9BvpANt_l5Ie6swbOHVw8QfpGLtiXuIv7ur2ocSX4xAYSdCKtYWWV58U0Q==}
MODE = k3s
PIPELINE_URL = http://myrddin.prole.org:8080
PIPELINE_URL = http://myrddin.knoe.org:8080
[GCP]
; No configuration values captured yet for this section.
[Prod Cluster (k8s)]
ARTIFACTS_DIR =
CLUSTER_ENV = prole-prod-cluster
DISPLAY_NAME = prole-prod-cluster
CLUSTER_ENV = knoe-prod-cluster
DISPLAY_NAME = knoe-prod-cluster
MODE = k8s
PIPELINE_URL = http://myrddin.prole.org:8080
PIPELINE_URL = http://myrddin.knoe.org:8080
[Docker Build]
; No configuration values captured yet for this section.
@ -242,7 +242,7 @@ STATUS = Completed
[Deployment]
MODE = k3s
TARGET = prole-service-cluster
TARGET = knoe-service-cluster
[Install]
STATUS = Failed

View File

@ -1,4 +1,4 @@
# Port mappings for Prole Tools (generated).
# Port mappings for Knoe Tools (generated).
# Format: key: local=... remote=... ns=... svc=... address=...
argocd: local=8081 remote=80 ns=argocd svc=argocd-server address=0.0.0.0

View File

@ -1,5 +1,5 @@
; Port mappings generated by init_port_forwards
; Source: /Users/chrisfu/dev/prole/conf/k3s.cfg
; Source: /Users/chrisfu/dev/knoe/conf/k3s.cfg
[PortMappings]
PORT_FORWARD_K3S_MAPPING_1 = id=argocd;namespace=argocd;target=svc/argocd-server;address=0.0.0.0;hostPort=8081;servicePort=80;protocol=TCP;description=ArgoCD
PORT_FORWARD_K3S_MAPPING_10 = id=supabase-studio;namespace=supabase;target=svc/studio;address=0.0.0.0;hostPort=18080;servicePort=3000;protocol=TCP;description=Supabase Studio

View File

@ -1,4 +1,4 @@
; Prole Master Configuration File
; Knoe Master Configuration File
; Generated by install.py on 2026-04-10 12:30:35
; This file is used as input for Ansible deployment and k8s cluster creation.
@ -31,11 +31,11 @@ env_setup.DATABASE_NAMESPACE = ${DATABASE_NAMESPACE}
env_setup.DB_CLUSTER_KUBECONTEXT =
env_setup.DB_CLUSTER_MODE = standard
env_setup.DB_CLUSTER_NAME = knoe-dev-cnpg-0
env_setup.PROLE_CONF = /Users/chrisfu/dev/prole/conf
env_setup.PROLE_DATA = /Users/chrisfu/dev/prole/data
env_setup.PROLE_HOME = /Users/chrisfu/dev/prole
env_setup.PROLE_LOGS = /Users/chrisfu/dev/prole/logs
env_setup.PROLE_SERVICE = /Users/chrisfu/dev/prole/etc
env_setup.KNOE_CONF = /Users/chrisfu/dev/knoe/conf
env_setup.PROLE_DATA = /Users/chrisfu/dev/knoe/data
env_setup.KNOE_HOME = /Users/chrisfu/dev/knoe
env_setup.PROLE_LOGS = /Users/chrisfu/dev/knoe/logs
env_setup.KNOE_SERVICE = /Users/chrisfu/dev/knoe/etc
init_cluster.app_cluster_kubecontext = gke_plenary-truck-485623-p7_us-west3_knoe-dev-0
init_cluster.app_cluster_machine_type = e2-standard-2
init_cluster.app_cluster_mode = standard
@ -104,7 +104,7 @@ DATABASE_NAMESPACE = knoe-db-0
DB_HOST_PORT = 5432
DB_PASSWORD= vzx.wC4Akd4x-Dj6Wguh
DEPLOYMENT_MODE = k8s
DEPLOYMENT_TARGET = prole-prod-cluster
DEPLOYMENT_TARGET = knoe-prod-cluster
DOCKER_IMPORT_DIR =
DOCKER_PRELOAD = false
K3S_SERVER =
@ -112,7 +112,7 @@ K3S_TOKEN =
KNOE_DB_USER = chrisfu
OPENTOFU_URL = http://127.0.0.1:8080
OPTIONAL_WORKLOADS_MIN_READY_SCHEDULABLE_NODES = 2
PROLE_HOME = /Users/chrisfu/dev/prole
KNOE_HOME = /Users/chrisfu/dev/knoe
REGISTRY_NAMESPACE = knoe-system
SERVICE_NAMESPACE = knoe-system
@ -142,11 +142,11 @@ PORT_FORWARD_K3D_MAPPING_8 = id=grafana;namespace=monitoring;target=svc/kps-graf
PORT_FORWARD_K3D_MAPPING_9 = id=supabase-kong;namespace=supabase;target=svc/kong;address=0.0.0.0;hostPort=8000;servicePort=8000;protocol=TCP;description=Supabase API (Kong)
[System Environment]
PROLE_CONF = /Users/chrisfu/dev/prole/conf
PROLE_DATA = /Users/chrisfu/dev/prole/data
PROLE_HOME = /Users/chrisfu/dev/prole
PROLE_LOGS = /Users/chrisfu/dev/prole/logs
PROLE_SERVICE = /Users/chrisfu/dev/prole/etc
KNOE_CONF = /Users/chrisfu/dev/knoe/conf
PROLE_DATA = /Users/chrisfu/dev/knoe/data
KNOE_HOME = /Users/chrisfu/dev/knoe
PROLE_LOGS = /Users/chrisfu/dev/knoe/logs
KNOE_SERVICE = /Users/chrisfu/dev/knoe/etc
[Monitoring]
; No configuration values captured yet for this section.
@ -181,8 +181,8 @@ KUBECTL_CONTEXT = prod
MODE = k3d
[Service Cluster (k3s)]
CLUSTER_ENV = prole-service-cluster
DISPLAY_NAME = prole-service-cluster
CLUSTER_ENV = knoe-service-cluster
DISPLAY_NAME = knoe-service-cluster
K3S_SERVER_URL =
K3S_TOKEN =
MODE = k3s
@ -193,8 +193,8 @@ PIPELINE_URL = http://127.0.0.1:8080
[Prod Cluster (k8s)]
ARTIFACTS_DIR =
CLUSTER_ENV = prole-prod-cluster
DISPLAY_NAME = prole-prod-cluster
CLUSTER_ENV = knoe-prod-cluster
DISPLAY_NAME = knoe-prod-cluster
MODE = k8s
PIPELINE_URL = http://127.0.0.1:8080
@ -206,7 +206,7 @@ PIPELINE_URL = http://127.0.0.1:8080
[Deployment]
MODE = k8s
TARGET = prole-prod-cluster
TARGET = knoe-prod-cluster
[Install]
STATUS = Finished

View File

@ -1,4 +1,4 @@
; Prole Master Configuration File
; Knoe Master Configuration File
; Generated by install.py on 2026-03-17 00:58:58
; This file is used as input for Ansible deployment and k8s cluster creation.
@ -36,15 +36,15 @@ dependencies.opentofu.install = true
dependencies.python.install = true
dependencies.verify_all = false
disk_selection.disk_type = local
disk_selection.local_path = /Users/chrisfu/dev/prole/prole-tools-app/dist
disk_selection.local_path = /Users/chrisfu/dev/knoe/knoe-tools-app/dist
disk_selection.removable_mount =
init_cluster.argocd_enabled = false
init_cluster.at_rest_encryption_enabled = true
init_cluster.cluster_env = service
init_cluster.deployment_target = prole-service-cluster
init_cluster.deployment_target = knoe-service-cluster
init_cluster.gitops_enabled = false
init_cluster.k3s_server_url = https://myrddin.prole.org:6443
init_cluster.k3s_token = ${PROLE_SECRET:v1:tOW53iZqoGRwqxUz:n0jktIyKBQ5cAggXfdR2oZ7OYyt859dRFHn5f4MzCy2zL7D_Ur9C-4e89RrTNPVLlGmd2GbHnP9uSLfnxRKe4zmypr5CfQnj3WDpwTr977EZBckkGFaSUQvUq-nShA-mRNDj14bXc2s5Oba9IQ9tiYRj4HT0W32MQ04HzQ==}
init_cluster.k3s_server_url = https://myrddin.knoe.org:6443
init_cluster.k3s_token = ${KNOE_SECRET:v1:tOW53iZqoGRwqxUz:n0jktIyKBQ5cAggXfdR2oZ7OYyt859dRFHn5f4MzCy2zL7D_Ur9C-4e89RrTNPVLlGmd2GbHnP9uSLfnxRKe4zmypr5CfQnj3WDpwTr977EZBckkGFaSUQvUq-nShA-mRNDj14bXc2s5Oba9IQ9tiYRj4HT0W32MQ04HzQ==}
init_cluster.kerberos_enabled = true
init_cluster.mode = k3s
init_cluster.start_cluster = true
@ -74,14 +74,14 @@ CLUSTER_ENV = service
DB_HOST_PORT = 5432
DB_PASSWORD =
DEPLOYMENT_MODE = k3s
DEPLOYMENT_TARGET = prole-service-cluster
DEPLOYMENT_TARGET = knoe-service-cluster
DOCKER_PRELOAD = false
KUBECONTEXT = prole-k3s
KUBECONTEXT = knoe-k3s
NAMESPACE = knoe-db
KNOE_DB_USER = root
PROLE_HOME = $HOME/dev/prole
PROLE_K3S_SERVER = https://myrddin.prole.org:6443
PROLE_K3S_TOKEN = ${PROLE_SECRET:v1:tOW53iZqoGRwqxUz:n0jktIyKBQ5cAggXfdR2oZ7OYyt859dRFHn5f4MzCy2zL7D_Ur9C-4e89RrTNPVLlGmd2GbHnP9uSLfnxRKe4zmypr5CfQnj3WDpwTr977EZBckkGFaSUQvUq-nShA-mRNDj14bXc2s5Oba9IQ9tiYRj4HT0W32MQ04HzQ==}
KNOE_HOME = $HOME/dev/knoe
PROLE_K3S_SERVER = https://myrddin.knoe.org:6443
PROLE_K3S_TOKEN = ${KNOE_SECRET:v1:tOW53iZqoGRwqxUz:n0jktIyKBQ5cAggXfdR2oZ7OYyt859dRFHn5f4MzCy2zL7D_Ur9C-4e89RrTNPVLlGmd2GbHnP9uSLfnxRKe4zmypr5CfQnj3WDpwTr977EZBckkGFaSUQvUq-nShA-mRNDj14bXc2s5Oba9IQ9tiYRj4HT0W32MQ04HzQ==}
PROLE_OPENTOFU_URL = http://127.0.0.1:8080
SERVICE_NAMESPACE = knoe-system
@ -92,13 +92,13 @@ SERVICE_NAMESPACE = knoe-system
; No configuration values captured yet for this section.
[Network]
AD_DC_HOST = myrddin.prole.org
AD_DC_HOST = myrddin.knoe.org
AD_DC_IP = 10.0.0.3
ANSIBLE_DOMAIN = prole.org
ANSIBLE_INFRASTRUCTURE = ${HOME}/dev/prole/infrastructure
ANSIBLE_INVENTORY = ${HOME}/dev/prole/infrastructure/inventory
ANSIBLE_DOMAIN = knoe.org
ANSIBLE_INFRASTRUCTURE = ${HOME}/dev/knoe/infrastructure
ANSIBLE_INVENTORY = ${HOME}/dev/knoe/infrastructure/inventory
ANSIBLE_REALM = PROLE.ORG
ANSIBLE_TOPOLOGY = {"domain":"prole.org","realm":"PROLE.ORG","internal_records":{"aventage.prole.org":"10.0.0.206","fairyland.prole.org":"10.0.0.208","loghost.prole.org":"10.0.0.3","merlin.prole.org":"10.0.0.6","morana.prole.org":"10.0.0.66","morgoth.prole.org":"10.0.0.204","myrddin.prole.org":"10.0.0.3","pi.prole.org":"10.0.0.5","raspberry.prole.org":"10.0.0.4","retropie.prole.org":"10.0.0.207","synology.prole.org":"10.0.0.203","zinfandel.prole.org":"10.0.0.205"},"ad_dc":{"host":"myrddin.prole.org","ip":"10.0.0.3"},"k3s":{"server_url":"https://myrddin.prole.org:6443","server_host":"myrddin.prole.org","token_present":true},"groups":{"iscsi":["pi.prole.org","raspberry.prole.org","myrddin.prole.org","retropie.prole.org","merlin.prole.org"],"pihole":["pi.prole.org","raspberry.prole.org"],"ad_dc":["myrddin.prole.org"],"k3s_servers":["myrddin.prole.org"],"k3s_agents":["pi.prole.org","merlin.prole.org"],"k3s_hosts:children":["k3s_servers","k3s_agents"],"linux_hosts":["pi.prole.org","raspberry.prole.org","myrddin.prole.org","retropie.prole.org","merlin.prole.org"],"ssl_hosts":["myrddin.prole.org"],"mariadb_primary":["merlin.prole.org"],"mariadb_replica":["raspberry.prole.org"],"mariadb:children":["mariadb_primary","mariadb_replica"],"merlin_bootstrap":["merlin"]},"hosts":{"merlin":"10.0.0.6","merlin.prole.org":"10.0.0.6","myrddin.prole.org":"10.0.0.3","pi.prole.org":"10.0.0.5","raspberry.prole.org":"10.0.0.4","retropie.prole.org":"10.0.0.207"},"unmapped_hosts":["k3s_agents","k3s_servers","mariadb_primary","mariadb_replica"]}
ANSIBLE_TOPOLOGY = {"domain":"knoe.org","realm":"PROLE.ORG","internal_records":{"aventage.knoe.org":"10.0.0.206","fairyland.knoe.org":"10.0.0.208","loghost.knoe.org":"10.0.0.3","merlin.knoe.org":"10.0.0.6","morana.knoe.org":"10.0.0.66","morgoth.knoe.org":"10.0.0.204","myrddin.knoe.org":"10.0.0.3","pi.knoe.org":"10.0.0.5","raspberry.knoe.org":"10.0.0.4","retropie.knoe.org":"10.0.0.207","synology.knoe.org":"10.0.0.203","zinfandel.knoe.org":"10.0.0.205"},"ad_dc":{"host":"myrddin.knoe.org","ip":"10.0.0.3"},"k3s":{"server_url":"https://myrddin.knoe.org:6443","server_host":"myrddin.knoe.org","token_present":true},"groups":{"iscsi":["pi.knoe.org","raspberry.knoe.org","myrddin.knoe.org","retropie.knoe.org","merlin.knoe.org"],"pihole":["pi.knoe.org","raspberry.knoe.org"],"ad_dc":["myrddin.knoe.org"],"k3s_servers":["myrddin.knoe.org"],"k3s_agents":["pi.knoe.org","merlin.knoe.org"],"k3s_hosts:children":["k3s_servers","k3s_agents"],"linux_hosts":["pi.knoe.org","raspberry.knoe.org","myrddin.knoe.org","retropie.knoe.org","merlin.knoe.org"],"ssl_hosts":["myrddin.knoe.org"],"mariadb_primary":["merlin.knoe.org"],"mariadb_replica":["raspberry.knoe.org"],"mariadb:children":["mariadb_primary","mariadb_replica"],"merlin_bootstrap":["merlin"]},"hosts":{"merlin":"10.0.0.6","merlin.knoe.org":"10.0.0.6","myrddin.knoe.org":"10.0.0.3","pi.knoe.org":"10.0.0.5","raspberry.knoe.org":"10.0.0.4","retropie.knoe.org":"10.0.0.207"},"unmapped_hosts":["k3s_agents","k3s_servers","mariadb_primary","mariadb_replica"]}
KDC_ANSIBLE_DETECTED = 10.0.0.3
KDC_AUTO_DETECTED = 10.0.0.3
KERBEROS_AUTO_ENABLED = True
@ -107,11 +107,11 @@ KERBEROS_AUTO_ENABLED = True
; No configuration values captured yet for this section.
[System Environment]
PROLE_CONF = ${PROLE_CONF}
KNOE_CONF = ${KNOE_CONF}
PROLE_DATA = ${PROLE_DATA}
PROLE_HOME = ${PROLE_HOME}
KNOE_HOME = ${KNOE_HOME}
PROLE_LOGS = ${PROLE_LOGS}
PROLE_SERVICE = ${PROLE_SERVICE}
KNOE_SERVICE = ${KNOE_SERVICE}
[Monitoring]
; No configuration values captured yet for this section.
@ -136,27 +136,27 @@ SUPABASE_ENABLED = False
[Initialize Cluster]
ENVIRONMENT = service
K3S_SERVER_URL = https://myrddin.prole.org:6443
K3S_TOKEN = ${PROLE_SECRET:v1:tOW53iZqoGRwqxUz:n0jktIyKBQ5cAggXfdR2oZ7OYyt859dRFHn5f4MzCy2zL7D_Ur9C-4e89RrTNPVLlGmd2GbHnP9uSLfnxRKe4zmypr5CfQnj3WDpwTr977EZBckkGFaSUQvUq-nShA-mRNDj14bXc2s5Oba9IQ9tiYRj4HT0W32MQ04HzQ==}
K3S_SERVER_URL = https://myrddin.knoe.org:6443
K3S_TOKEN = ${KNOE_SECRET:v1:tOW53iZqoGRwqxUz:n0jktIyKBQ5cAggXfdR2oZ7OYyt859dRFHn5f4MzCy2zL7D_Ur9C-4e89RrTNPVLlGmd2GbHnP9uSLfnxRKe4zmypr5CfQnj3WDpwTr977EZBckkGFaSUQvUq-nShA-mRNDj14bXc2s5Oba9IQ9tiYRj4HT0W32MQ04HzQ==}
[Dev Cluster (k3d)]
CLUSTER_ENV = dev
DISPLAY_NAME = knoe-dev-cluster
KUBECTL_CONTEXT = prole-k3s
KUBECTL_CONTEXT = knoe-k3s
MODE = k3d
[Service Cluster (k3s)]
CLUSTER_ENV = prole-service-cluster
DISPLAY_NAME = prole-service-cluster
K3S_SERVER_URL = https://myrddin.prole.org:6443
K3S_TOKEN = ${PROLE_SECRET:v1:tOW53iZqoGRwqxUz:n0jktIyKBQ5cAggXfdR2oZ7OYyt859dRFHn5f4MzCy2zL7D_Ur9C-4e89RrTNPVLlGmd2GbHnP9uSLfnxRKe4zmypr5CfQnj3WDpwTr977EZBckkGFaSUQvUq-nShA-mRNDj14bXc2s5Oba9IQ9tiYRj4HT0W32MQ04HzQ==}
CLUSTER_ENV = knoe-service-cluster
DISPLAY_NAME = knoe-service-cluster
K3S_SERVER_URL = https://myrddin.knoe.org:6443
K3S_TOKEN = ${KNOE_SECRET:v1:tOW53iZqoGRwqxUz:n0jktIyKBQ5cAggXfdR2oZ7OYyt859dRFHn5f4MzCy2zL7D_Ur9C-4e89RrTNPVLlGmd2GbHnP9uSLfnxRKe4zmypr5CfQnj3WDpwTr977EZBckkGFaSUQvUq-nShA-mRNDj14bXc2s5Oba9IQ9tiYRj4HT0W32MQ04HzQ==}
MODE = k3s
PIPELINE_URL = http://127.0.0.1:8080
[Prod Cluster (k8s)]
ARTIFACTS_DIR = ${PROLE_DATA}/staging
CLUSTER_ENV = prole-prod-cluster
DISPLAY_NAME = prole-prod-cluster
CLUSTER_ENV = knoe-prod-cluster
DISPLAY_NAME = knoe-prod-cluster
MODE = k8s
PIPELINE_URL = http://127.0.0.1:8080
@ -168,7 +168,7 @@ PIPELINE_URL = http://127.0.0.1:8080
[Deployment]
MODE = k3s
TARGET = prole-service-cluster
TARGET = knoe-service-cluster
[Install]
; No configuration values captured yet for this section.

248
config.py
View File

@ -1,7 +1,7 @@
"""
Shared configuration and utility functions for the Prole installer (root-level).
Shared configuration and utility functions for the Knoe installer (root-level).
This mirrors `prole.knoe.config` but is located under the root `installer/`
This mirrors `knoe.knoe.config` but is located under the root `installer/`
package per the refactor request. UI code should import from `knoe.config`.
"""
@ -24,29 +24,29 @@ from typing import Optional, Tuple
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
def resolve_prole_home(env: dict[str, str] | None = None) -> Path:
"""Resolve `PROLE_HOME` from `env`/process environment.
def resolve_knoe_home(env: dict[str, str] | None = None) -> Path:
"""Resolve `KNOE_HOME` from `env`/process environment.
Falls back to `$HOME/.prole` when `PROLE_HOME` is not set.
Falls back to `$HOME/.knoe` when `KNOE_HOME` is not set.
NOTE: This is duplicated here (and in `knoe.core.env`) to avoid circular
imports between the two modules.
"""
env_map = env or os.environ
raw = (env_map.get("PROLE_HOME") or "").strip()
raw = (env_map.get("KNOE_HOME") or "").strip()
if raw:
expanded = os.path.expanduser(os.path.expandvars(raw))
return Path(expanded)
return Path.home() / ".prole"
return Path.home() / ".knoe"
# Secret handling (temporary encrypted values in prole.cfg)
PROLE_SECRET_PREFIX = "${PROLE_SECRET:"
PROLE_SECRET_SUFFIX = "}"
# Secret handling (temporary encrypted values in knoe.cfg)
KNOE_SECRET_PREFIX = "${KNOE_SECRET:"
KNOE_SECRET_SUFFIX = "}"
OPENBAO_PREFIX = "${OPENBAO:"
OPENBAO_SUFFIX = "}"
PROLE_SECRET_VERSION = "v1"
PROLE_SECRET_SERVICE = "prole-installer"
KNOE_SECRET_VERSION = "v1"
KNOE_SECRET_SERVICE = "knoe-installer"
# Map config keys to OpenBao paths (namespace injected at runtime)
SECRET_KEY_SPECS = {
@ -59,11 +59,11 @@ SECRET_KEY_SPECS = {
}
def _is_prole_secret(value: str | None) -> bool:
def _is_knoe_secret(value: str | None) -> bool:
return (
bool(value)
and value.startswith(PROLE_SECRET_PREFIX)
and value.endswith(PROLE_SECRET_SUFFIX)
and value.startswith(KNOE_SECRET_PREFIX)
and value.endswith(KNOE_SECRET_SUFFIX)
)
@ -76,7 +76,7 @@ def _is_openbao_ref(value: str | None) -> bool:
def _get_secret_key_file() -> Path:
return resolve_prole_home() / "secrets" / "knoe.key"
return resolve_knoe_home() / "secrets" / "knoe.key"
def _get_keychain_key(service: str, account: str) -> bytes:
@ -132,16 +132,16 @@ def _get_file_key(path: Path) -> bytes:
def _get_secret_key() -> bytes:
system = platform.system()
account = getpass.getuser() or "prole"
account = getpass.getuser() or "knoe"
if system == "Darwin":
return _get_keychain_key(PROLE_SECRET_SERVICE, account)
return _get_keychain_key(KNOE_SECRET_SERVICE, account)
return _get_file_key(_get_secret_key_file())
def _encrypt_prole_secret(plaintext: str) -> str:
def _encrypt_knoe_secret(plaintext: str) -> str:
if plaintext is None:
return ""
if _is_prole_secret(plaintext):
if _is_knoe_secret(plaintext):
return plaintext
key = _get_secret_key()
aesgcm = AESGCM(key)
@ -149,15 +149,15 @@ def _encrypt_prole_secret(plaintext: str) -> str:
ciphertext = aesgcm.encrypt(nonce, plaintext.encode("utf-8"), None)
nonce_b64 = base64.urlsafe_b64encode(nonce).decode("utf-8")
ct_b64 = base64.urlsafe_b64encode(ciphertext).decode("utf-8")
return f"{PROLE_SECRET_PREFIX}{PROLE_SECRET_VERSION}:{nonce_b64}:{ct_b64}{PROLE_SECRET_SUFFIX}"
return f"{KNOE_SECRET_PREFIX}{KNOE_SECRET_VERSION}:{nonce_b64}:{ct_b64}{KNOE_SECRET_SUFFIX}"
def _decrypt_prole_secret(value: str) -> str:
if not _is_prole_secret(value):
def _decrypt_knoe_secret(value: str) -> str:
if not _is_knoe_secret(value):
return value
inner = value[len(PROLE_SECRET_PREFIX) : -len(PROLE_SECRET_SUFFIX)]
inner = value[len(KNOE_SECRET_PREFIX) : -len(KNOE_SECRET_SUFFIX)]
parts = inner.split(":")
if len(parts) != 3 or parts[0] != PROLE_SECRET_VERSION:
if len(parts) != 3 or parts[0] != KNOE_SECRET_VERSION:
return value
try:
nonce = base64.urlsafe_b64decode(parts[1].encode("utf-8"))
@ -173,10 +173,10 @@ def _decrypt_prole_secret(value: str) -> str:
def _encrypt_cfg_secret(plaintext: str | None) -> str:
if not plaintext:
return ""
if _is_prole_secret(plaintext) or _is_openbao_ref(plaintext):
if _is_knoe_secret(plaintext) or _is_openbao_ref(plaintext):
return plaintext
try:
return _encrypt_prole_secret(plaintext)
return _encrypt_knoe_secret(plaintext)
except Exception:
return str(plaintext)
@ -199,9 +199,9 @@ def _resolve_openbao_ref(value: str) -> str:
secret_path = rest
token = os.environ.get("OPENBAO_ROOT_TOKEN", "")
if not token:
prole_service = os.environ.get("PROLE_SERVICE")
if prole_service:
token_path = Path(prole_service) / "secrets" / "openbao-root-token"
knoe_service = os.environ.get("KNOE_SERVICE")
if knoe_service:
token_path = Path(knoe_service) / "secrets" / "openbao-root-token"
if token_path.exists():
token = token_path.read_text().strip()
if not token:
@ -232,8 +232,8 @@ def _resolve_openbao_ref(value: str) -> str:
def _resolve_secret_value(value: str) -> str:
if _is_prole_secret(value):
return _decrypt_prole_secret(value)
if _is_knoe_secret(value):
return _decrypt_knoe_secret(value)
if _is_openbao_ref(value):
return _resolve_openbao_ref(value)
return value
@ -261,8 +261,8 @@ def _load_properties(path: Path) -> dict:
# Repository root: this file lives at <repo>/installer/config.py → parent is repo
PROJECT_ROOT = Path(__file__).resolve().parents[1]
PROLE_APP_DIR = PROJECT_ROOT / "prole-app"
PROLE_PROPS_PATH = PROLE_APP_DIR / "prole.properties"
KNOE_APP_DIR = PROJECT_ROOT / "knoe-app"
KNOE_PROPS_PATH = KNOE_APP_DIR / "knoe.properties"
import logging
@ -314,30 +314,30 @@ def setup_logging(verbose=False, debug=False):
)
_PROLE_PROPS_CACHE: Optional[dict] = None
_KNOE_PROPS_CACHE: Optional[dict] = None
def get_properties() -> dict:
"""Load and cache prole.properties from the repo (installer context).
"""Load and cache knoe.properties from the repo (installer context).
Order:
- Repo default at prole-app/prole.properties
- Optional env override: PROLE_PROPERTIES points to a file
- Repo default at knoe-app/knoe.properties
- Optional env override: KNOE_PROPERTIES points to a file
"""
global _PROLE_PROPS_CACHE
if _PROLE_PROPS_CACHE is None:
global _KNOE_PROPS_CACHE
if _KNOE_PROPS_CACHE is None:
props: dict[str, str] = {}
# repo default
if PROLE_PROPS_PATH.exists():
props.update(_load_properties(PROLE_PROPS_PATH))
if KNOE_PROPS_PATH.exists():
props.update(_load_properties(KNOE_PROPS_PATH))
# env override (absolute path)
env_path = os.environ.get("PROLE_PROPERTIES")
env_path = os.environ.get("KNOE_PROPERTIES")
if env_path:
p = Path(env_path)
if p.exists():
props.update(_load_properties(p))
_PROLE_PROPS_CACHE = props
return dict(_PROLE_PROPS_CACHE)
_KNOE_PROPS_CACHE = props
return dict(_KNOE_PROPS_CACHE)
def get_config_value(key: str, default: Optional[str] = None) -> Optional[str]:
@ -348,39 +348,39 @@ def get_ui_icon_image_path() -> Path:
"""Return absolute path to the UI icon image for the installer.
Priority (new legacy):
- `icon` key in prole.properties (requested)
- `icon` key in knoe.properties (requested)
- legacy `ui.icon`
Defaults to img/proleIcon.png under repo root if not set or missing.
Defaults to img/knoeIcon.png under repo root if not set or missing.
"""
# Prefer new key `icon`, fall back to old `ui.icon`
rel = get_config_value("icon") or get_config_value("ui.icon") or "img/proleIcon.png"
rel = get_config_value("icon") or get_config_value("ui.icon") or "img/knoeIcon.png"
p = (PROJECT_ROOT / rel).resolve()
if p.exists():
return p
# fallback
return (PROJECT_ROOT / "img/proleIcon.png").resolve()
return (PROJECT_ROOT / "img/knoeIcon.png").resolve()
def get_ui_background_image_path() -> Path:
"""Return absolute path to the UI background image.
Priority (new legacy):
- `background` key in prole.properties (requested)
- `background` key in knoe.properties (requested)
- legacy `ui.background`
Defaults to img/proleLogoSepia.png under repo root if not set or missing.
Defaults to img/knoeLogoSepia.png under repo root if not set or missing.
"""
rel = (
get_config_value("background")
or get_config_value("ui.background")
or "img/proleLogoSepia.png"
or "img/knoeLogoSepia.png"
)
p = (PROJECT_ROOT / rel).resolve()
if p.exists():
return p
# fallback
return (PROJECT_ROOT / "img/proleLogoSepia.png").resolve()
return (PROJECT_ROOT / "img/knoeLogoSepia.png").resolve()
def is_apple_silicon() -> bool:
@ -394,7 +394,7 @@ def get_docker_build_platform_args(target_env: Optional[str] = None) -> list[str
env_key = (target_env or "").strip().lower()
if env_key == "dev" and is_apple_silicon():
return ["--platform", "linux/arm64"]
if env_key in ("service", "k3s", "prole-service-cluster"):
if env_key in ("service", "k3s", "knoe-service-cluster"):
return ["--platform", "linux/arm64"]
if is_apple_silicon():
return ["--platform", "linux/amd64"]
@ -434,7 +434,7 @@ def _expand_path(val: str | None) -> str:
if not val:
return ""
# Expand ~ and shell-style variables like $HOME. Use a small fixed-point loop
# so nested refs (e.g. PROLE_HOME=$HOME/...) expand fully.
# so nested refs (e.g. KNOE_HOME=$HOME/...) expand fully.
out = os.path.expanduser(str(val))
for _ in range(10):
new = os.path.expandvars(out)
@ -448,9 +448,9 @@ def _normalize_persistence_mode(mode: str | None) -> str:
raw = (mode or "").strip().lower()
if raw in {"dev", "k3d", "local"}:
return "dev"
if raw in {"service", "k3s", "k3s-hosts", "prole-service-cluster"}:
if raw in {"service", "k3s", "k3s-hosts", "knoe-service-cluster"}:
return "k3s-hosts"
if raw in {"prod", "k8s", "prole-prod-cluster"}:
if raw in {"prod", "k8s", "knoe-prod-cluster"}:
return "prod"
return raw
@ -604,7 +604,7 @@ def _collect_cfg_vars_from_data(
mode: str | None = None,
explicit_keys: set[tuple[str, str]] | None = None,
) -> dict[str, str]:
"""Collect variable names from a `prole_cfg_data`-style dict.
"""Collect variable names from a `knoe_cfg_data`-style dict.
This mirrors `_collect_cfg_vars()` but operates on the UI/controller's in-memory
dict instead of a `configparser.ConfigParser`.
@ -649,7 +649,7 @@ def _expand_cfg_vars_shellstyle(val: str, variables: dict[str, str]) -> str:
Notes:
- Only expands simple shell-style identifiers (letters/digits/underscore).
This intentionally avoids treating `${PROLE_SECRET:...}` or similar
This intentionally avoids treating `${KNOE_SECRET:...}` or similar
colon-delimited references as variables.
- Unknown variables are left intact.
"""
@ -730,99 +730,9 @@ def _extract_yaml_scalar_from_text(text: str, key: str) -> str:
return ""
def _extract_inline_vault_block(text: str, key: str) -> str:
lines = text.splitlines()
for i, line in enumerate(lines):
if line.strip().startswith(f"{key}:"):
base_indent = len(line) - len(line.lstrip())
block = []
i += 1
while i < len(lines):
line = lines[i]
if not line.strip():
i += 1
continue
indent = len(line) - len(line.lstrip())
if indent <= base_indent:
break
block.append(line.strip())
i += 1
if block and block[0].startswith("$ANSIBLE_VAULT"):
return "\n".join(block) + "\n"
return ""
return ""
def _try_read_ansible_vault_value(vault_path: Path, key: str) -> str:
if not vault_path.exists():
return ""
# Simple search in plain text first
try:
raw_text = vault_path.read_text()
plain = _extract_yaml_scalar_from_text(raw_text, key)
if (
plain
and not plain.startswith("$ANSIBLE_VAULT")
and not plain.startswith("!vault")
):
return plain
except Exception:
pass
password_file = (os.environ.get("ANSIBLE_VAULT_PASSWORD_FILE") or "").strip()
if not password_file:
candidate = PROJECT_ROOT / ".vault_pass"
if candidate.is_file():
password_file = str(candidate)
if not password_file or shutil.which("ansible-vault") is None:
return ""
def _vault_view(path: str) -> str:
try:
res = subprocess.run(
["ansible-vault", "view", path, "--vault-password-file", password_file],
capture_output=True,
text=True,
timeout=5,
env=os.environ.copy(),
stdin=subprocess.DEVNULL,
)
if res.returncode == 0:
return res.stdout or ""
except Exception:
pass
return ""
try:
output = _vault_view(str(vault_path))
if output:
return _extract_yaml_scalar_from_text(output, key)
# Inline vault
inline_block = _extract_inline_vault_block(vault_path.read_text(), key)
if not inline_block:
return ""
import tempfile
with tempfile.NamedTemporaryFile(mode="w", delete=False) as tmp:
tmp.write(inline_block)
tmp_name = tmp.name
try:
output = _vault_view(tmp_name)
return output.strip()
finally:
if os.path.exists(tmp_name):
os.unlink(tmp_name)
except Exception:
pass
return ""
def _update_prole_cfg_value(
def _update_knoe_cfg_value(
section: str,
key: str,
value: str,
@ -830,15 +740,15 @@ def _update_prole_cfg_value(
mode: str | None = None,
explicit: bool = False,
):
# Prefer `$PROLE_CONF/prole.cfg` (single entrypoint) and follow symlink so we
# Prefer `$KNOE_CONF/knoe.cfg` (single entrypoint) and follow symlink so we
# update the active environment base file without mutating other environments.
try:
from knoe import prole_conf
from knoe import knoe_conf
conf_dir = prole_conf.resolve_prole_conf_dir(PROJECT_ROOT)
cfg_path = prole_conf.entrypoint_path(conf_dir)
conf_dir = knoe_conf.resolve_knoe_conf_dir(PROJECT_ROOT)
cfg_path = knoe_conf.entrypoint_path(conf_dir)
except Exception:
cfg_path = PROJECT_ROOT / "conf" / "prole.cfg"
cfg_path = PROJECT_ROOT / "conf" / "knoe.cfg"
if not cfg_path.exists():
return
@ -900,27 +810,27 @@ def _write_k3s_kubeconfig(server_url: str, token: str) -> Path:
"- cluster:\n"
f" server: {server_url}\n"
" insecure-skip-tls-verify: true\n"
" name: prole-k3s\n"
" name: knoe-k3s\n"
"contexts:\n"
"- context:\n"
" cluster: prole-k3s\n"
" user: prole-k3s\n"
" name: prole-k3s\n"
"current-context: prole-k3s\n"
" cluster: knoe-k3s\n"
" user: knoe-k3s\n"
" name: knoe-k3s\n"
"current-context: knoe-k3s\n"
"users:\n"
"- name: prole-k3s\n"
"- name: knoe-k3s\n"
" user:\n"
f" token: {token}\n"
)
prole_service = os.environ.get("PROLE_SERVICE", "").strip()
if prole_service:
path = Path(prole_service).expanduser() / "secrets" / "k3s.kubeconfig"
knoe_service = os.environ.get("KNOE_SERVICE", "").strip()
if knoe_service:
path = Path(knoe_service).expanduser() / "secrets" / "k3s.kubeconfig"
else:
prole_home = os.environ.get("PROLE_HOME", "").strip()
if prole_home:
path = Path(prole_home).expanduser() / "prole-k3s.kubeconfig"
knoe_home = os.environ.get("KNOE_HOME", "").strip()
if knoe_home:
path = Path(knoe_home).expanduser() / "knoe-k3s.kubeconfig"
else:
path = PROJECT_ROOT / "prole-k3s.kubeconfig"
path = PROJECT_ROOT / "knoe-k3s.kubeconfig"
# Never overwrite a kubeconfig that uses client-certificate auth (e.g.
# one fetched by Ansible) with a token-based fallback.
if path.exists():
@ -1036,7 +946,7 @@ DEPENDENCIES = [
{
"id": "docker",
"name": "Docker",
"description": "Container platform for running Prole services",
"description": "Container platform for running Knoe services",
"url": "https://www.docker.com/products/docker-desktop",
"install_cmd": None,
"check_cmd": "docker --version",

View File

@ -90,9 +90,9 @@
[0.672, "o", "\u001b[H\n\u001b[J\u001b[AFetching billing accounts…"]
[31.063, "o", "\r\u001b(B\u001b[0;1mSelect Billing Account\u001b(B\u001b[m\u001b[K\r\n───────────────────────────────────────────────────────────────────────────────\r\n \u001b(B\u001b[0;2mProject: plenary-truck-485623-p7\n\u001b[3G\u001b(B\u001b[0;7m My Billing Account 01193C-25783B-3211AD \r\u001b[24d\u001b(B\u001b[0;2m↑↓/jk navigate Enter select q quit 1/1\u001b(B\u001b[m"]
[2.113, "o", "\u001b[?12l\u001b[?25h"]
[0.001, "o", "\u001b[H\u001b(B\u001b[0;1mConfig: --mode k8s --provider gcp — Confirm & Save\n\n\u001b[3G\u001b(B\u001b[mOrg ID: 584001916389\u001b[K\r\n Org Name: knoey.com\u001b[K\r\n Project ID:\u001b[5;22Hplenary-truck-485623-p7\r\n Project Name:\u001b[22GKnoey Auth\r\n Project Number: 507759242125\r\n Billing Account: 01193C-25783B-3211AD\r\n Billing Name:\u001b[22GMy Billing Account\r\n\n \u001b(B\u001b[0;1mOutput file: \u001b(B\u001b[m/Users/chrisfu/dev/prole/conf/prod/gcp.cfg\r\u001b[24d\u001b(B\u001b[0;2mEdit path above Enter to write Esc to cancel\u001b(B\u001b[m"]
[0.001, "o", "\u001b[H\u001b(B\u001b[0;1mConfig: --mode k8s --provider gcp — Confirm & Save\n\n\u001b[3G\u001b(B\u001b[mOrg ID: 584001916389\u001b[K\r\n Org Name: knoey.com\u001b[K\r\n Project ID:\u001b[5;22Hplenary-truck-485623-p7\r\n Project Name:\u001b[22GKnoey Auth\r\n Project Number: 507759242125\r\n Billing Account: 01193C-25783B-3211AD\r\n Billing Name:\u001b[22GMy Billing Account\r\n\n \u001b(B\u001b[0;1mOutput file: \u001b(B\u001b[m/Users/chrisfu/dev/knoe/conf/prod/gcp.cfg\r\u001b[24d\u001b(B\u001b[0;2mEdit path above Enter to write Esc to cancel\u001b(B\u001b[m"]
[4.691, "o", "\u001b[?25l"]
[0.002, "o", "\u001b[HConfiguration written.\u001b[K\r\n\u001b[K\n /Users/chrisfu/dev/prole/conf/prod/gcp.cfg\r\n\u001b[K\nNext steps:\u001b[K\r\n 1. Copy org_id / billing_account / billing_project into:\n\u001b[7G\u001b[1K deploy/gcp/terraform/cloud-setup.auto.tfvars\r\n 2. Open the installer — Prod Cluster → Cloud tab will be pre-filled\r\n (or click 'Load from gcp.cfg' to refresh on demand)\r\n\n\u001b[K\u001b[24d\u001b(B\u001b[0;2mPress any key to continue…\u001b(B\u001b[m\u001b[K"]
[0.002, "o", "\u001b[HConfiguration written.\u001b[K\r\n\u001b[K\n /Users/chrisfu/dev/knoe/conf/prod/gcp.cfg\r\n\u001b[K\nNext steps:\u001b[K\r\n 1. Copy org_id / billing_account / billing_project into:\n\u001b[7G\u001b[1K deploy/gcp/terraform/cloud-setup.auto.tfvars\r\n 2. Open the installer — Prod Cluster → Cloud tab will be pre-filled\r\n (or click 'Load from gcp.cfg' to refresh on demand)\r\n\n\u001b[K\u001b[24d\u001b(B\u001b[0;2mPress any key to continue…\u001b(B\u001b[m\u001b[K"]
[2.724, "o", "\u001b[?1l\u001b>"]
[0.000, "o", "\u001b[24;1H\u001b[?12l\u001b[?25h\u001b[?1049l\r\u001b[?1l\u001b>"]
[0.011, "x", "0"]

View File

@ -63,7 +63,7 @@ except subprocess.CalledProcessError:
PY
fi
"${PYTHON_BIN}" -m prole.deploy_pipeline --config "${CONFIG_PATH}" "$@"
"${PYTHON_BIN}" -m knoe.deploy_pipeline --config "${CONFIG_PATH}" "$@"
# Post-deploy summary
echo ""
@ -132,7 +132,7 @@ def get_runtime_config(path):
gitlab_public_hosts_raw = _cfg_first(g, e, i, "GITLAB_PUBLIC_HOSTS", "gitlab_public_hosts")
gitlab_domain = _cfg_first(g, e, i, "GITLAB_DOMAIN", "GITLAB_HOSTNAME", "gitlab_domain", "gitlab_hostname")
if not gitlab_domain:
gitlab_domain = "git.knoe.dev" if mode == "k8s" else "git.prole.org"
gitlab_domain = "git.knoe.dev" if mode == "k8s" else "git.knoe.org"
gitlab_public_hosts = [h.strip() for h in str(gitlab_public_hosts_raw or "").split(",") if h.strip()]
if not gitlab_public_hosts:
gitlab_public_hosts = [gitlab_domain]
@ -145,11 +145,11 @@ def get_runtime_config(path):
auth_host = _cfg_first(g, e, i, "AUTH_HOSTNAME", "auth_hostname")
if not auth_host:
auth_host = "api.knoe.dev" if mode == "k8s" else "api.prole.org"
auth_host = "api.knoe.dev" if mode == "k8s" else "api.knoe.org"
service_host = _cfg_first(g, e, i, "SERVICE_HOSTNAME", "service_hostname", "GRAFANA_HOSTNAME", "grafana_hostname")
if not service_host:
service_host = "svc.knoe.dev" if mode == "k8s" else "svc.prole.org"
service_host = "svc.knoe.dev" if mode == "k8s" else "svc.knoe.org"
service_ns = _cfg_first(g, e, i, "SERVICE_NAMESPACE", "service_namespace") or "knoe-system"

View File

@ -4,7 +4,7 @@ metadata:
name: gitlab-google-oidc
namespace: gitlab
labels:
app.kubernetes.io/managed-by: prole-installer
app.kubernetes.io/managed-by: knoe-installer
# GitLab OmniAuth provider config for OpenID Connect via knoe-auth.
# See: https://docs.gitlab.com/ee/administration/auth/oidc.html
# Applied by etc/init_gitlab.sh --mode k8s

View File

@ -4,7 +4,7 @@ metadata:
name: knoe-auth-google-oidc
namespace: knoe-system
labels:
app.kubernetes.io/managed-by: prole-installer
app.kubernetes.io/managed-by: knoe-installer
# Fill in client_id and client_secret from your Google Cloud Console OAuth 2.0 credentials.
# Create at: https://console.cloud.google.com/apis/credentials
# Authorized redirect URI: https://<frontdoor-host>/auth/callback/google

View File

@ -41,16 +41,16 @@ spec:
- pg_tde
pg_hba:
- local all postgres trust
- local all prole scram-sha-256
- local all knoe scram-sha-256
- host all postgres all scram-sha-256
- host prole knoe-db all scram-sha-256
- host knoe knoe-db all scram-sha-256
- host all all all scram-sha-256
- hostssl prole knoe-db all scram-sha-256
- hostssl knoe knoe-db all scram-sha-256
bootstrap:
initdb:
database: knoe-db
owner: prole
owner: knoe
localeCollate: 'en_US.utf8'
localeCType: 'en_US.utf8'
secret:
@ -59,7 +59,7 @@ spec:
- CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
postInitSQL:
- DO $do$ BEGIN IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = 'knoe') THEN CREATE ROLE knoe LOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT; END IF; END $do$;
- DO $do$ DECLARE owner_password text; BEGIN SELECT rolpassword INTO owner_password FROM pg_authid WHERE rolname = 'prole'; IF owner_password IS NOT NULL THEN EXECUTE format('ALTER ROLE knoe PASSWORD %L', owner_password); END IF; END $do$;
- DO $do$ DECLARE owner_password text; BEGIN SELECT rolpassword INTO owner_password FROM pg_authid WHERE rolname = 'knoe'; IF owner_password IS NOT NULL THEN EXECUTE format('ALTER ROLE knoe PASSWORD %L', owner_password); END IF; END $do$;
- DO $do$ BEGIN IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = 'knoe_catalog_executor') THEN CREATE ROLE knoe_catalog_executor NOLOGIN; END IF; END $do$;
- CREATE SCHEMA IF NOT EXISTS knoe AUTHORIZATION knoe;
- ALTER SCHEMA knoe OWNER TO knoe;
@ -72,12 +72,12 @@ spec:
- ALTER SCHEMA topology OWNER TO knoe;
- CREATE EXTENSION IF NOT EXISTS vector SCHEMA knoe;
- CREATE EXTENSION IF NOT EXISTS tds_fdw SCHEMA knoe;
- GRANT USAGE ON SCHEMA knoe TO prole;
- GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA knoe TO prole;
- GRANT USAGE ON SCHEMA knoe TO knoe;
- GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA knoe TO knoe;
- GRANT USAGE ON SCHEMA knoe TO knoe_catalog_executor;
- GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA knoe TO knoe_catalog_executor;
- ALTER DEFAULT PRIVILEGES FOR ROLE knoe IN SCHEMA knoe GRANT EXECUTE ON FUNCTIONS TO knoe_catalog_executor;
- GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA topology TO prole;
- GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA topology TO knoe;
- CREATE SCHEMA IF NOT EXISTS storage;
- CREATE SCHEMA IF NOT EXISTS graphql_public;
- DO $do$ BEGIN IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = 'anon') THEN CREATE ROLE anon NOLOGIN; END IF; END $do$;
@ -94,9 +94,9 @@ spec:
# knoe.user — identity registry (Knoey Users)
- CREATE TABLE IF NOT EXISTS knoe.user (id SERIAL PRIMARY KEY, username TEXT NOT NULL UNIQUE, realm TEXT NOT NULL DEFAULT 'PROLE.LOCAL', email TEXT, display_name TEXT, tenant_realm TEXT, is_realm_admin BOOLEAN DEFAULT false, created_at TIMESTAMPTZ DEFAULT now(), updated_at TIMESTAMPTZ DEFAULT now());
- CREATE TABLE IF NOT EXISTS knoe.user_role (user_id INT NOT NULL REFERENCES knoe.user(id) ON DELETE CASCADE, role TEXT NOT NULL, granted_at TIMESTAMPTZ DEFAULT now(), PRIMARY KEY (user_id, role));
- GRANT SELECT, INSERT, UPDATE ON knoe.user TO prole;
- GRANT SELECT, INSERT, UPDATE ON knoe.user_role TO prole;
- GRANT USAGE, SELECT ON SEQUENCE knoe.user_id_seq TO prole;
- GRANT SELECT, INSERT, UPDATE ON knoe.user TO knoe;
- GRANT SELECT, INSERT, UPDATE ON knoe.user_role TO knoe;
- GRANT USAGE, SELECT ON SEQUENCE knoe.user_id_seq TO knoe;
managed:
roles:

View File

@ -3,4 +3,4 @@ kind: Namespace
metadata:
name: knoe-db-0
labels:
app.kubernetes.io/managed-by: prole-installer
app.kubernetes.io/managed-by: knoe-installer

View File

@ -10,7 +10,7 @@ module.cs-folders-level-1["Team 1/Production"].ids["Production"] and rename to
module.cs-folders-level-1["Team 1/Prod"].ids["Prod"]
*/
folders = {
"prole-db" : {
"knoe-db" : {
"infrastructure" : {
"Production" : {},
"Non-Production" : {},
@ -79,51 +79,51 @@ folders = {
}
cmek_autokey_folders = [
{
"folder_path" : "prole-db/infrastructure/Production",
"folder_path" : "knoe-db/infrastructure/Production",
"key_project_name" : "kms-key-project",
},
{
"folder_path" : "prole-db/infrastructure/Non-Production",
"folder_path" : "knoe-db/infrastructure/Non-Production",
"key_project_name" : "kms-key-project",
},
{
"folder_path" : "prole-db/infrastructure/Development",
"folder_path" : "knoe-db/infrastructure/Development",
"key_project_name" : "kms-key-project",
},
{
"folder_path" : "prole-db/app/Production",
"folder_path" : "knoe-db/app/Production",
"key_project_name" : "kms-key-project",
},
{
"folder_path" : "prole-db/app/Non-Production",
"folder_path" : "knoe-db/app/Non-Production",
"key_project_name" : "kms-key-project",
},
{
"folder_path" : "prole-db/app/Development",
"folder_path" : "knoe-db/app/Development",
"key_project_name" : "kms-key-project",
},
{
"folder_path" : "prole-db/client/Production",
"folder_path" : "knoe-db/client/Production",
"key_project_name" : "kms-key-project",
},
{
"folder_path" : "prole-db/client/Non-Production",
"folder_path" : "knoe-db/client/Non-Production",
"key_project_name" : "kms-key-project",
},
{
"folder_path" : "prole-db/client/Development",
"folder_path" : "knoe-db/client/Development",
"key_project_name" : "kms-key-project",
},
{
"folder_path" : "prole-db/eng/Production",
"folder_path" : "knoe-db/eng/Production",
"key_project_name" : "kms-key-project",
},
{
"folder_path" : "prole-db/eng/Non-Production",
"folder_path" : "knoe-db/eng/Non-Production",
"key_project_name" : "kms-key-project",
},
{
"folder_path" : "prole-db/eng/Development",
"folder_path" : "knoe-db/eng/Development",
"key_project_name" : "kms-key-project",
},
{
@ -224,18 +224,18 @@ cmek_autokey_folders = [
},
]
application_enabled_folder_paths = [
"prole-db/infrastructure/Production",
"prole-db/infrastructure/Non-Production",
"prole-db/infrastructure/Development",
"prole-db/app/Production",
"prole-db/app/Non-Production",
"prole-db/app/Development",
"prole-db/client/Production",
"prole-db/client/Non-Production",
"prole-db/client/Development",
"prole-db/eng/Production",
"prole-db/eng/Non-Production",
"prole-db/eng/Development",
"knoe-db/infrastructure/Production",
"knoe-db/infrastructure/Non-Production",
"knoe-db/infrastructure/Development",
"knoe-db/app/Production",
"knoe-db/app/Non-Production",
"knoe-db/app/Development",
"knoe-db/client/Production",
"knoe-db/client/Non-Production",
"knoe-db/client/Development",
"knoe-db/eng/Production",
"knoe-db/eng/Non-Production",
"knoe-db/eng/Development",
"frobozzRobotics/infrastructure/Production",
"frobozzRobotics/infrastructure/Non-Production",
"frobozzRobotics/infrastructure/Development",

View File

@ -5,7 +5,7 @@ module "cs-gg-knoe-db-infrastr-prod-svc" {
source = "terraform-google-modules/group/google"
version = "~> 0.6"
id = "knoe-db-infrastr-prod-svc@prole.org"
id = "knoe-db-infrastr-prod-svc@knoe.org"
display_name = "knoe-db-infrastr-prod-svc"
customer_id = data.google_organization.org.directory_customer_id
types = [
@ -18,7 +18,7 @@ module "cs-gg-knoe-db-infrastr-nonprod-svc" {
source = "terraform-google-modules/group/google"
version = "~> 0.6"
id = "knoe-db-infrastr-nonprod-svc@prole.org"
id = "knoe-db-infrastr-nonprod-svc@knoe.org"
display_name = "knoe-db-infrastr-nonprod-svc"
customer_id = data.google_organization.org.directory_customer_id
types = [
@ -31,7 +31,7 @@ module "cs-gg-knoe-db-app-prod-svc" {
source = "terraform-google-modules/group/google"
version = "~> 0.6"
id = "knoe-db-app-prod-svc@prole.org"
id = "knoe-db-app-prod-svc@knoe.org"
display_name = "knoe-db-app-prod-svc"
customer_id = data.google_organization.org.directory_customer_id
types = [
@ -44,7 +44,7 @@ module "cs-gg-knoe-db-app-nonprod-svc" {
source = "terraform-google-modules/group/google"
version = "~> 0.6"
id = "knoe-db-app-nonprod-svc@prole.org"
id = "knoe-db-app-nonprod-svc@knoe.org"
display_name = "knoe-db-app-nonprod-svc"
customer_id = data.google_organization.org.directory_customer_id
types = [

View File

@ -7,7 +7,7 @@ module "cs-folders-iam-0-computeinstanceAdminv1" {
]
bindings = {
"roles/compute.instanceAdmin.v1" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -21,7 +21,7 @@ module "cs-folders-iam-0-containeradmin" {
]
bindings = {
"roles/container.admin" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -35,7 +35,7 @@ module "cs-folders-iam-1-computeinstanceAdminv1" {
]
bindings = {
"roles/compute.instanceAdmin.v1" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -49,7 +49,7 @@ module "cs-folders-iam-1-containeradmin" {
]
bindings = {
"roles/container.admin" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -63,7 +63,7 @@ module "cs-folders-iam-2-computeinstanceAdminv1" {
]
bindings = {
"roles/compute.instanceAdmin.v1" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -77,7 +77,7 @@ module "cs-folders-iam-2-containeradmin" {
]
bindings = {
"roles/container.admin" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -91,7 +91,7 @@ module "cs-folders-iam-3-computeinstanceAdminv1" {
]
bindings = {
"roles/compute.instanceAdmin.v1" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -105,7 +105,7 @@ module "cs-folders-iam-3-containeradmin" {
]
bindings = {
"roles/container.admin" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -119,7 +119,7 @@ module "cs-folders-iam-4-computeinstanceAdminv1" {
]
bindings = {
"roles/compute.instanceAdmin.v1" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -133,7 +133,7 @@ module "cs-folders-iam-4-containeradmin" {
]
bindings = {
"roles/container.admin" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -147,7 +147,7 @@ module "cs-folders-iam-5-computeinstanceAdminv1" {
]
bindings = {
"roles/compute.instanceAdmin.v1" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -161,7 +161,7 @@ module "cs-folders-iam-5-containeradmin" {
]
bindings = {
"roles/container.admin" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -175,7 +175,7 @@ module "cs-folders-iam-6-computeinstanceAdminv1" {
]
bindings = {
"roles/compute.instanceAdmin.v1" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -189,7 +189,7 @@ module "cs-folders-iam-6-containeradmin" {
]
bindings = {
"roles/container.admin" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -203,7 +203,7 @@ module "cs-folders-iam-7-computeinstanceAdminv1" {
]
bindings = {
"roles/compute.instanceAdmin.v1" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -217,7 +217,7 @@ module "cs-folders-iam-7-containeradmin" {
]
bindings = {
"roles/container.admin" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -231,7 +231,7 @@ module "cs-folders-iam-8-computeinstanceAdminv1" {
]
bindings = {
"roles/compute.instanceAdmin.v1" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -245,7 +245,7 @@ module "cs-folders-iam-8-containeradmin" {
]
bindings = {
"roles/container.admin" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -259,7 +259,7 @@ module "cs-folders-iam-9-computeinstanceAdminv1" {
]
bindings = {
"roles/compute.instanceAdmin.v1" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -273,7 +273,7 @@ module "cs-folders-iam-9-containeradmin" {
]
bindings = {
"roles/container.admin" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -287,7 +287,7 @@ module "cs-folders-iam-10-computeinstanceAdminv1" {
]
bindings = {
"roles/compute.instanceAdmin.v1" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -301,7 +301,7 @@ module "cs-folders-iam-10-containeradmin" {
]
bindings = {
"roles/container.admin" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -315,7 +315,7 @@ module "cs-folders-iam-11-computeinstanceAdminv1" {
]
bindings = {
"roles/compute.instanceAdmin.v1" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -329,7 +329,7 @@ module "cs-folders-iam-11-containeradmin" {
]
bindings = {
"roles/container.admin" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -343,7 +343,7 @@ module "cs-folders-iam-12-computeinstanceAdminv1" {
]
bindings = {
"roles/compute.instanceAdmin.v1" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -357,7 +357,7 @@ module "cs-folders-iam-12-containeradmin" {
]
bindings = {
"roles/container.admin" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -371,7 +371,7 @@ module "cs-folders-iam-13-computeinstanceAdminv1" {
]
bindings = {
"roles/compute.instanceAdmin.v1" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -385,7 +385,7 @@ module "cs-folders-iam-13-containeradmin" {
]
bindings = {
"roles/container.admin" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -399,7 +399,7 @@ module "cs-folders-iam-14-computeinstanceAdminv1" {
]
bindings = {
"roles/compute.instanceAdmin.v1" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -413,7 +413,7 @@ module "cs-folders-iam-14-containeradmin" {
]
bindings = {
"roles/container.admin" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -427,7 +427,7 @@ module "cs-folders-iam-15-computeinstanceAdminv1" {
]
bindings = {
"roles/compute.instanceAdmin.v1" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -441,7 +441,7 @@ module "cs-folders-iam-15-containeradmin" {
]
bindings = {
"roles/container.admin" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -455,7 +455,7 @@ module "cs-folders-iam-16-computeinstanceAdminv1" {
]
bindings = {
"roles/compute.instanceAdmin.v1" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -469,7 +469,7 @@ module "cs-folders-iam-16-containeradmin" {
]
bindings = {
"roles/container.admin" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -483,7 +483,7 @@ module "cs-folders-iam-17-computeinstanceAdminv1" {
]
bindings = {
"roles/compute.instanceAdmin.v1" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -497,7 +497,7 @@ module "cs-folders-iam-17-containeradmin" {
]
bindings = {
"roles/container.admin" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -511,7 +511,7 @@ module "cs-folders-iam-18-computeinstanceAdminv1" {
]
bindings = {
"roles/compute.instanceAdmin.v1" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -525,7 +525,7 @@ module "cs-folders-iam-18-containeradmin" {
]
bindings = {
"roles/container.admin" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -539,7 +539,7 @@ module "cs-folders-iam-19-computeinstanceAdminv1" {
]
bindings = {
"roles/compute.instanceAdmin.v1" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -553,7 +553,7 @@ module "cs-folders-iam-19-containeradmin" {
]
bindings = {
"roles/container.admin" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -567,7 +567,7 @@ module "cs-folders-iam-20-computeinstanceAdminv1" {
]
bindings = {
"roles/compute.instanceAdmin.v1" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -581,7 +581,7 @@ module "cs-folders-iam-20-containeradmin" {
]
bindings = {
"roles/container.admin" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -595,7 +595,7 @@ module "cs-folders-iam-21-computeinstanceAdminv1" {
]
bindings = {
"roles/compute.instanceAdmin.v1" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -609,7 +609,7 @@ module "cs-folders-iam-21-containeradmin" {
]
bindings = {
"roles/container.admin" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -623,7 +623,7 @@ module "cs-folders-iam-22-computeinstanceAdminv1" {
]
bindings = {
"roles/compute.instanceAdmin.v1" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -637,7 +637,7 @@ module "cs-folders-iam-22-containeradmin" {
]
bindings = {
"roles/container.admin" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -651,7 +651,7 @@ module "cs-folders-iam-23-computeinstanceAdminv1" {
]
bindings = {
"roles/compute.instanceAdmin.v1" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -665,7 +665,7 @@ module "cs-folders-iam-23-containeradmin" {
]
bindings = {
"roles/container.admin" = [
"group:gcp-developers@prole.org",
"group:gcp-developers@knoe.org",
]
}
}
@ -679,7 +679,7 @@ module "cs-projects-iam-24-loggingviewer" {
]
bindings = {
"roles/logging.viewer" = [
"group:gcp-logging-monitoring-viewers@prole.org",
"group:gcp-logging-monitoring-viewers@knoe.org",
]
}
}
@ -693,7 +693,7 @@ module "cs-projects-iam-24-loggingprivateLogViewer" {
]
bindings = {
"roles/logging.privateLogViewer" = [
"group:gcp-logging-monitoring-viewers@prole.org",
"group:gcp-logging-monitoring-viewers@knoe.org",
]
}
}
@ -707,7 +707,7 @@ module "cs-projects-iam-24-bigquerydataViewer" {
]
bindings = {
"roles/bigquery.dataViewer" = [
"group:gcp-logging-monitoring-viewers@prole.org",
"group:gcp-logging-monitoring-viewers@knoe.org",
]
}
}
@ -721,7 +721,7 @@ module "cs-projects-iam-24-pubsubviewer" {
]
bindings = {
"roles/pubsub.viewer" = [
"group:gcp-logging-monitoring-viewers@prole.org",
"group:gcp-logging-monitoring-viewers@knoe.org",
]
}
}
@ -735,7 +735,7 @@ module "cs-projects-iam-24-monitoringviewer" {
]
bindings = {
"roles/monitoring.viewer" = [
"group:gcp-logging-monitoring-viewers@prole.org",
"group:gcp-logging-monitoring-viewers@knoe.org",
]
}
}
@ -749,7 +749,7 @@ module "cs-projects-iam-25-bigquerydataViewer" {
]
bindings = {
"roles/bigquery.dataViewer" = [
"group:gcp-security-admins@prole.org",
"group:gcp-security-admins@knoe.org",
]
}
}
@ -763,7 +763,7 @@ module "cs-projects-iam-25-pubsubviewer" {
]
bindings = {
"roles/pubsub.viewer" = [
"group:gcp-security-admins@prole.org",
"group:gcp-security-admins@knoe.org",
]
}
}
@ -773,7 +773,7 @@ module "cs-service-projects-iam-26-computeinstanceAdminv1" {
version = "~> 8.0"
projects = [
module.cs-svc-prole--infras-prod-svc-a4ci.project_id,
module.cs-svc-knoe--infras-prod-svc-a4ci.project_id,
]
bindings = {
"roles/compute.instanceAdmin.v1" = [
@ -787,7 +787,7 @@ module "cs-service-projects-iam-27-computeinstanceAdminv1" {
version = "~> 8.0"
projects = [
module.cs-svc-prole--infras-nonprod-svc-a4ci.project_id,
module.cs-svc-knoe--infras-nonprod-svc-a4ci.project_id,
]
bindings = {
"roles/compute.instanceAdmin.v1" = [
@ -801,7 +801,7 @@ module "cs-service-projects-iam-28-computeinstanceAdminv1" {
version = "~> 8.0"
projects = [
module.cs-svc-prole--app-prod-svc-a4ci.project_id,
module.cs-svc-knoe--app-prod-svc-a4ci.project_id,
]
bindings = {
"roles/compute.instanceAdmin.v1" = [
@ -815,7 +815,7 @@ module "cs-service-projects-iam-29-computeinstanceAdminv1" {
version = "~> 8.0"
projects = [
module.cs-svc-prole--app-nonprod-svc-a4ci.project_id,
module.cs-svc-knoe--app-nonprod-svc-a4ci.project_id,
]
bindings = {
"roles/compute.instanceAdmin.v1" = [

View File

@ -20,7 +20,7 @@ module "cs-logging-destination" {
version = "~> 11.0"
project_id = module.cs-project-logging-monitoring.project_id
name = "prole-logging"
name = "knoe-logging"
location = "global"
retention_days = 30
log_sink_writer_identity = module.cs-logsink-logbucketsink.writer_identity

View File

@ -2,10 +2,10 @@ resource "google_monitoring_monitored_project" "cs-monitored-projects" {
for_each = toset([
module.cs-project-vpc-host-prod.project_id,
module.cs-project-vpc-host-nonprod.project_id,
module.cs-svc-prole--infras-prod-svc-a4ci.project_id,
module.cs-svc-prole--infras-nonprod-svc-a4ci.project_id,
module.cs-svc-prole--app-prod-svc-a4ci.project_id,
module.cs-svc-prole--app-nonprod-svc-a4ci.project_id,
module.cs-svc-knoe--infras-prod-svc-a4ci.project_id,
module.cs-svc-knoe--infras-nonprod-svc-a4ci.project_id,
module.cs-svc-knoe--app-prod-svc-a4ci.project_id,
module.cs-svc-knoe--app-nonprod-svc-a4ci.project_id,
])
metrics_scope = "locations/global/metricsScopes/${module.cs-project-logging-monitoring.project_id}"
name = each.value

View File

@ -13,7 +13,7 @@ module "cs-org-policy-essentialcontacts_allowedContactDomains" {
{
enforcement = null
allow = [
"@prole.org",
"@knoe.org",
]
deny = []
conditions = []

View File

@ -1,9 +1,9 @@
module "cs-svc-prole--infras-prod-svc-a4ci" {
module "cs-svc-knoe--infras-prod-svc-a4ci" {
source = "terraform-google-modules/project-factory/google//modules/svpc_service_project"
version = "~> 18.0"
name = "knoe-db-infrastr-prod-svc"
project_id = "prole--infras-prod-svc-a4ci"
project_id = "knoe--infras-prod-svc-a4ci"
org_id = var.org_id
billing_account = var.billing_account
folder_id = local.folder_map["knoe-db/infrastructure/Production"].id
@ -25,12 +25,12 @@ module "cs-svc-prole--infras-prod-svc-a4ci" {
]
}
module "cs-svc-prole--infras-nonprod-svc-a4ci" {
module "cs-svc-knoe--infras-nonprod-svc-a4ci" {
source = "terraform-google-modules/project-factory/google//modules/svpc_service_project"
version = "~> 18.0"
name = "knoe-db-infrastr-nonprod-svc"
project_id = "prole--infras-nonprod-svc-a4ci"
project_id = "knoe--infras-nonprod-svc-a4ci"
org_id = var.org_id
billing_account = var.billing_account
folder_id = local.folder_map["knoe-db/infrastructure/Non-Production"].id
@ -47,12 +47,12 @@ module "cs-svc-prole--infras-nonprod-svc-a4ci" {
]
}
module "cs-svc-prole--app-prod-svc-a4ci" {
module "cs-svc-knoe--app-prod-svc-a4ci" {
source = "terraform-google-modules/project-factory/google//modules/svpc_service_project"
version = "~> 18.0"
name = "knoe-db-app-prod-svc"
project_id = "prole--app-prod-svc-a4ci"
project_id = "knoe--app-prod-svc-a4ci"
org_id = var.org_id
billing_account = var.billing_account
folder_id = local.folder_map["knoe-db/app/Production"].id
@ -69,12 +69,12 @@ module "cs-svc-prole--app-prod-svc-a4ci" {
]
}
module "cs-svc-prole--app-nonprod-svc-a4ci" {
module "cs-svc-knoe--app-nonprod-svc-a4ci" {
source = "terraform-google-modules/project-factory/google//modules/svpc_service_project"
version = "~> 18.0"
name = "knoe-db-app-nonprod-svc"
project_id = "prole--app-nonprod-svc-a4ci"
project_id = "knoe--app-nonprod-svc-a4ci"
org_id = var.org_id
billing_account = var.billing_account
folder_id = local.folder_map["knoe-db/app/Non-Production"].id

View File

@ -40,7 +40,7 @@ module "cs-prod-prod-us-west1-gateway" {
network = module.cs-vpc-prod-shared.network_self_link
stack_type = "IPV4_IPV6"
peer_external_gateway = {
name = "svc-prole-org"
name = "svc-knoe-org"
redundancy_type = "TWO_IPS_REDUNDANCY"
interfaces = [
{

View File

@ -1,6 +1,6 @@
# OpenTofu k3s Pipeline
This pipeline re-deploys the Prole environment into a k3s cluster using OpenTofu.
This pipeline re-deploys the Knoe environment into a k3s cluster using OpenTofu.
## Usage
@ -18,5 +18,5 @@ tofu apply
- `main.tf`: Applies Kubernetes manifests with the configured namespace.
- `variables.tf`: Pipeline inputs (server URL, token, namespace).
- `opentofu.auto.tfvars`: Auto-generated values from Prole install/config.
- `opentofu.auto.tfvars`: Auto-generated values from Knoe install/config.
- `manifests/`: Copy of `k8s/` manifests to re-deploy.

View File

@ -1,16 +1,16 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: prole-db
name: knoe-db
namespace: argocd
spec:
project: default
source:
repoURL: git@github.com:dredx/prole.git
repoURL: git@github.com:dredx/knoe.git
targetRevision: main
path: deploy/opentofu/k3s/manifests/db
destination:
server: https://myrddin.prole.org:6443
server: https://myrddin.knoe.org:6443
namespace: knoe-db
syncPolicy:
automated:

View File

@ -1,16 +1,16 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: prole-opentofu
name: knoe-opentofu
namespace: argocd
spec:
project: default
source:
repoURL: git@github.com:dredx/prole.git
repoURL: git@github.com:dredx/knoe.git
targetRevision: main
path: deploy/opentofu/k3s/manifests/opentofu
destination:
server: https://myrddin.prole.org:6443
server: https://myrddin.knoe.org:6443
namespace: knoe-db
syncPolicy:
automated:

View File

@ -1,16 +1,16 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: prole-prole
name: knoe-knoe
namespace: argocd
spec:
project: default
source:
repoURL: git@github.com:dredx/prole.git
repoURL: git@github.com:dredx/knoe.git
targetRevision: main
path: deploy/opentofu/k3s/manifests/prole
path: deploy/opentofu/k3s/manifests/knoe
destination:
server: https://myrddin.prole.org:6443
server: https://myrddin.knoe.org:6443
namespace: knoe-system
syncPolicy:
automated:

View File

@ -2,6 +2,6 @@ apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../prole/knoe-db-barman-objectstore.yaml
- ../prole/knoe-db.yaml
- ../prole/knoe-db-postgres-service.yaml
- ../knoe/knoe-db-barman-objectstore.yaml
- ../knoe/knoe-db.yaml
- ../knoe/knoe-db-postgres-service.yaml

View File

@ -7,7 +7,7 @@ metadata:
kubernetes.io/ingress.class: traefik
spec:
rules:
- host: dashboard.prole.org
- host: dashboard.knoe.org
http:
paths:
- path: /

View File

@ -16,7 +16,7 @@ spec:
app: garage
spec:
nodeSelector:
kubernetes.io/hostname: myrddin.prole.org
kubernetes.io/hostname: myrddin.knoe.org
containers:
- name: garage
image: dxflrs/garage:v1.3.1

View File

@ -1,7 +1,7 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: prole-grafana-proxy-nginx
name: knoe-grafana-proxy-nginx
data:
nginx.conf: |
worker_processes 1;
@ -18,11 +18,11 @@ data:
# Never trust inbound auth headers from clients.
proxy_set_header X-WEBAUTH-USER "";
proxy_set_header X-Prole-Groups "";
proxy_set_header X-Knoe-Groups "";
location = /_auth_verify {
internal;
proxy_pass http://prole-auth:8080/auth/verify;
proxy_pass http://knoe-auth:8080/auth/verify;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
@ -32,14 +32,14 @@ data:
location / {
auth_request /_auth_verify;
auth_request_set $prole_user $upstream_http_x_prole_user;
auth_request_set $prole_groups $upstream_http_x_prole_groups;
auth_request_set $knoe_user $upstream_http_x_knoe_user;
auth_request_set $knoe_groups $upstream_http_x_knoe_groups;
error_page 401 = @login;
error_page 403 = @login;
proxy_set_header X-WEBAUTH-USER $prole_user;
proxy_set_header X-Prole-Groups $prole_groups;
proxy_set_header X-WEBAUTH-USER $knoe_user;
proxy_set_header X-Knoe-Groups $knoe_groups;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
@ -52,7 +52,7 @@ data:
}
location @login {
return 302 https://api.prole.org/auth/login?next=$scheme://$host$request_uri;
return 302 https://api.knoe.org/auth/login?next=$scheme://$host$request_uri;
}
}
}

View File

@ -1,18 +1,18 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: prole-grafana-proxy
name: knoe-grafana-proxy
labels:
app: prole-grafana-proxy
app: knoe-grafana-proxy
spec:
replicas: 1
selector:
matchLabels:
app: prole-grafana-proxy
app: knoe-grafana-proxy
template:
metadata:
labels:
app: prole-grafana-proxy
app: knoe-grafana-proxy
spec:
containers:
- name: nginx
@ -27,4 +27,4 @@ spec:
volumes:
- name: nginx-config
configMap:
name: prole-grafana-proxy-nginx
name: knoe-grafana-proxy-nginx

View File

@ -1,12 +1,12 @@
apiVersion: v1
kind: Service
metadata:
name: prole-grafana-proxy
name: knoe-grafana-proxy
labels:
app: prole-grafana-proxy
app: knoe-grafana-proxy
spec:
selector:
app: prole-grafana-proxy
app: knoe-grafana-proxy
ports:
- name: http
port: 80

View File

@ -1,29 +1,29 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: prole-ingress
name: knoe-ingress
annotations:
kubernetes.io/ingress.class: traefik
spec:
rules:
- host: git.prole.org
- host: git.knoe.org
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: prole
name: knoe
port:
number: 443
- host: api.prole.org
- host: api.knoe.org
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: prole
name: knoe
port:
number: 443
---
@ -36,7 +36,7 @@ metadata:
kubernetes.io/ingress.class: traefik
spec:
rules:
- host: dashboard.prole.org
- host: dashboard.knoe.org
http:
paths:
- path: /
@ -56,7 +56,7 @@ metadata:
kubernetes.io/ingress.class: traefik
spec:
rules:
- host: db.prole.org
- host: db.knoe.org
http:
paths:
- path: /
@ -66,7 +66,7 @@ spec:
name: kong
port:
number: 8000
- host: supabase.prole.org
- host: supabase.knoe.org
http:
paths:
- path: /

View File

@ -22,7 +22,7 @@ spec:
- key: kubernetes.io/hostname
operator: In
values:
- myrddin.prole.org
- myrddin.knoe.org
---
apiVersion: v1
kind: PersistentVolume
@ -48,7 +48,7 @@ spec:
- key: kubernetes.io/hostname
operator: In
values:
- myrddin.prole.org
- myrddin.knoe.org
---
apiVersion: v1
kind: PersistentVolume
@ -74,7 +74,7 @@ spec:
- key: kubernetes.io/hostname
operator: In
values:
- myrddin.prole.org
- myrddin.knoe.org
---
apiVersion: v1
kind: PersistentVolume
@ -100,7 +100,7 @@ spec:
- key: kubernetes.io/hostname
operator: In
values:
- merlin.prole.org
- merlin.knoe.org
---
apiVersion: v1
kind: PersistentVolume
@ -126,7 +126,7 @@ spec:
- key: kubernetes.io/hostname
operator: In
values:
- merlin.prole.org
- merlin.knoe.org
---
apiVersion: v1
kind: PersistentVolume
@ -152,7 +152,7 @@ spec:
- key: kubernetes.io/hostname
operator: In
values:
- pi.prole.org
- pi.knoe.org
---
apiVersion: v1
kind: PersistentVolume
@ -178,7 +178,7 @@ spec:
- key: kubernetes.io/hostname
operator: In
values:
- pi.prole.org
- pi.knoe.org
---
apiVersion: v1
kind: PersistentVolume
@ -204,7 +204,7 @@ spec:
- key: kubernetes.io/hostname
operator: In
values:
- pi.prole.org
- pi.knoe.org
---
apiVersion: v1
kind: PersistentVolume
@ -230,7 +230,7 @@ spec:
- key: kubernetes.io/hostname
operator: In
values:
- merlin.prole.org
- merlin.knoe.org
---
apiVersion: v1
kind: PersistentVolume
@ -256,4 +256,4 @@ spec:
- key: kubernetes.io/hostname
operator: In
values:
- myrddin.prole.org
- myrddin.knoe.org

View File

@ -41,17 +41,17 @@ spec:
- pg_tde
pg_hba:
- local all postgres trust
- local all prole scram-sha-256
- local all knoe scram-sha-256
# SCRAM auth — Kerberos/GSS rules omitted (kerberos_enabled=false on k3s)
- host all postgres all scram-sha-256
- host prole knoe-db all scram-sha-256
- host knoe knoe-db all scram-sha-256
- host all all all scram-sha-256
- hostssl prole knoe-db all scram-sha-256
- hostssl knoe knoe-db all scram-sha-256
bootstrap:
initdb:
database: knoe-db
owner: prole
owner: knoe
localeCollate: 'en_US.utf8'
localeCType: 'en_US.utf8'
secret:
@ -61,13 +61,13 @@ spec:
postInitSQL:
- CREATE EXTENSION IF NOT EXISTS pg_tde;
- CREATE EXTENSION IF NOT EXISTS pgcrypto;
- GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public TO prole;
- GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public TO knoe;
- CREATE EXTENSION IF NOT EXISTS postgis;
- CREATE EXTENSION IF NOT EXISTS postgis_topology;
- CREATE EXTENSION IF NOT EXISTS vector;
- CREATE EXTENSION IF NOT EXISTS tds_fdw;
- GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public TO prole;
- GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA topology TO prole;
- GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public TO knoe;
- GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA topology TO knoe;
- CREATE SCHEMA IF NOT EXISTS storage;
- CREATE SCHEMA IF NOT EXISTS graphql_public;
- CREATE ROLE anon NOLOGIN;
@ -87,13 +87,13 @@ spec:
- ALTER SCHEMA knoe OWNER TO knoe;
- REVOKE ALL ON SCHEMA knoe FROM PUBLIC;
- ALTER ROLE knoe SET search_path TO knoe, public;
- GRANT USAGE ON SCHEMA knoe TO prole;
- GRANT USAGE ON SCHEMA knoe TO knoe;
# knoe.user — identity registry (Knoey Users)
- CREATE TABLE IF NOT EXISTS knoe.user (id SERIAL PRIMARY KEY, username TEXT NOT NULL UNIQUE, realm TEXT NOT NULL DEFAULT 'PROLE.LOCAL', email TEXT, display_name TEXT, tenant_realm TEXT, is_realm_admin BOOLEAN DEFAULT false, created_at TIMESTAMPTZ DEFAULT now(), updated_at TIMESTAMPTZ DEFAULT now());
- CREATE TABLE IF NOT EXISTS knoe.user_role (user_id INT NOT NULL REFERENCES knoe.user(id) ON DELETE CASCADE, role TEXT NOT NULL, granted_at TIMESTAMPTZ DEFAULT now(), PRIMARY KEY (user_id, role));
- GRANT SELECT, INSERT, UPDATE ON knoe.user TO prole;
- GRANT SELECT, INSERT, UPDATE ON knoe.user_role TO prole;
- GRANT USAGE, SELECT ON SEQUENCE knoe.user_id_seq TO prole;
- GRANT SELECT, INSERT, UPDATE ON knoe.user TO knoe;
- GRANT SELECT, INSERT, UPDATE ON knoe.user_role TO knoe;
- GRANT USAGE, SELECT ON SEQUENCE knoe.user_id_seq TO knoe;
managed:
roles:

View File

@ -1,7 +1,7 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: prole-svc-kong-config
name: knoe-svc-kong-config
annotations:
argocd.argoproj.io/sync-wave: "0"
data:
@ -10,12 +10,12 @@ data:
_transform: true
services:
- name: prole-service
url: http://prole-svc.knoe-system.svc.cluster.local:8080
- name: knoe-service
url: http://knoe-svc.knoe-system.svc.cluster.local:8080
routes:
- name: prole-k3s-kubeconfig
- name: knoe-k3s-kubeconfig
hosts:
- svc.prole.org
- svc.knoe.org
paths:
- /k3s/kube_config.sh
strip_path: false
@ -25,7 +25,7 @@ data:
routes:
- name: backup-route
hosts:
- svc.prole.org
- svc.knoe.org
paths:
- /backup
strip_path: false
@ -35,7 +35,7 @@ data:
routes:
- name: grafana-root
hosts:
- svc.prole.org
- svc.knoe.org
paths:
- /
strip_path: false
@ -45,7 +45,7 @@ data:
routes:
- name: knoe-auth-root
hosts:
- api.prole.org
- api.knoe.org
paths:
- /
strip_path: false
@ -55,7 +55,7 @@ data:
routes:
- name: gitea-root
hosts:
- git.prole.org
- git.knoe.org
paths:
- /
strip_path: false

View File

@ -1,31 +1,31 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: prole-svc-kong
name: knoe-svc-kong
annotations:
argocd.argoproj.io/sync-wave: "1"
labels:
app: prole-svc-kong
app: knoe-svc-kong
spec:
replicas: 1
selector:
matchLabels:
app: prole-svc-kong
app: knoe-svc-kong
template:
metadata:
labels:
app: prole-svc-kong
app: knoe-svc-kong
spec:
affinity:
nodeAffinity:
# Never schedule on pi.prole.org — pihole-FTL owns ports 80/443 there
# Never schedule on pi.knoe.org — pihole-FTL owns ports 80/443 there
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: NotIn
values:
- pi.prole.org
- pi.knoe.org
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 80
preference:
@ -33,7 +33,7 @@ spec:
- key: kubernetes.io/hostname
operator: In
values:
- gandalf.prole.org
- gandalf.knoe.org
containers:
- name: kong
image: kong:3.9
@ -85,4 +85,4 @@ spec:
volumes:
- name: kong-config
configMap:
name: prole-svc-kong-config
name: knoe-svc-kong-config

View File

@ -1,14 +1,14 @@
apiVersion: v1
kind: Service
metadata:
name: prole-svc-kong
name: knoe-svc-kong
annotations:
argocd.argoproj.io/sync-wave: "1"
labels:
app: prole-svc-kong
app: knoe-svc-kong
spec:
selector:
app: prole-svc-kong
app: knoe-svc-kong
ports:
- name: proxy
port: 8000

View File

@ -5,13 +5,13 @@ resources:
- garage-configmap.yaml
- garage-statefulset.yaml
- garage-service.yaml
- prole-configmap.yaml
- prole-deployment.yaml
- prole-service.yaml
- prole-auth-deployment.yaml
- prole-auth-service.yaml
- prole-auth-kerberos-configmap.yaml
- prole-kdc-configmap.yaml
- knoe-configmap.yaml
- knoe-deployment.yaml
- knoe-service.yaml
- knoe-auth-deployment.yaml
- knoe-auth-service.yaml
- knoe-auth-kerberos-configmap.yaml
- knoe-kdc-configmap.yaml
- grafana-proxy-configmap.yaml
- grafana-proxy-deployment.yaml
- grafana-proxy-service.yaml

View File

@ -16,7 +16,7 @@ spec:
app: openbao
spec:
nodeSelector:
kubernetes.io/hostname: myrddin.prole.org
kubernetes.io/hostname: myrddin.knoe.org
containers:
- name: openbao
image: ghcr.io/openbao/openbao:2.0.0

View File

@ -1,22 +1,22 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: prole-auth
name: knoe-auth
labels:
app: prole-auth
app: knoe-auth
spec:
replicas: 1
selector:
matchLabels:
app: prole-auth
app: knoe-auth
template:
metadata:
labels:
app: prole-auth
app: knoe-auth
spec:
initContainers:
- name: keytab-bootstrap
image: myrddin.prole.org:5000/prole-authority:latest
image: myrddin.knoe.org:5000/knoe-authority:latest
imagePullPolicy: IfNotPresent
command:
- /bin/bash
@ -36,7 +36,7 @@ spec:
svc_principal="${svc_principal}@${realm}"
fi
keytab_out="/etc/prole/keytabs/http.keytab"
keytab_out="/etc/knoe/keytabs/http.keytab"
mkdir -p "$(dirname "${keytab_out}")"
if [[ -f /mnt/keytab-secret/http.keytab ]]; then
@ -56,22 +56,22 @@ spec:
fi
mkdir -p /etc/krb5kdc /var/lib/krb5kdc
if [[ -f /opt/prole-kdc/krb5.conf ]]; then
cp /opt/prole-kdc/krb5.conf /etc/krb5.conf
if [[ -f /opt/knoe-kdc/krb5.conf ]]; then
cp /opt/knoe-kdc/krb5.conf /etc/krb5.conf
fi
if [[ -f /opt/prole-kdc/kdc.conf ]]; then
cp /opt/prole-kdc/kdc.conf /etc/krb5kdc/kdc.conf
if [[ -f /opt/knoe-kdc/kdc.conf ]]; then
cp /opt/knoe-kdc/kdc.conf /etc/krb5kdc/kdc.conf
fi
if [[ -f /opt/prole-kdc/kadm5.acl ]]; then
cp /opt/prole-kdc/kadm5.acl /etc/krb5kdc/kadm5.acl
if [[ -f /opt/knoe-kdc/kadm5.acl ]]; then
cp /opt/knoe-kdc/kadm5.acl /etc/krb5kdc/kadm5.acl
fi
if [[ -z "${PROLE_KDC_MASTER_PASSWORD:-}" ]]; then
echo "ERROR: Missing required env PROLE_KDC_MASTER_PASSWORD (secret 'prole-kdc-secrets/master_password')." >&2
echo "ERROR: Missing required env PROLE_KDC_MASTER_PASSWORD (secret 'knoe-kdc-secrets/master_password')." >&2
exit 1
fi
if [[ -z "${PROLE_KDC_ADMIN_PASSWORD:-}" ]]; then
echo "ERROR: Missing required env PROLE_KDC_ADMIN_PASSWORD (secret 'prole-kdc-secrets/admin_password')." >&2
echo "ERROR: Missing required env PROLE_KDC_ADMIN_PASSWORD (secret 'knoe-kdc-secrets/admin_password')." >&2
exit 1
fi
@ -96,40 +96,40 @@ spec:
- name: PROLE_KDC_REALM
valueFrom:
configMapKeyRef:
name: prole-auth-kerberos
name: knoe-auth-kerberos
key: realm
- name: PROLE_KDC_ADMIN_PRINCIPAL
value: "admin/admin"
- name: PROLE_KDC_MASTER_PASSWORD
valueFrom:
secretKeyRef:
name: prole-kdc-secrets
name: knoe-kdc-secrets
key: master_password
- name: PROLE_KDC_ADMIN_PASSWORD
valueFrom:
secretKeyRef:
name: prole-kdc-secrets
name: knoe-kdc-secrets
key: admin_password
- name: PROLE_KERBEROS_SERVICE_PRINCIPAL
valueFrom:
configMapKeyRef:
name: prole-auth-kerberos
name: knoe-auth-kerberos
key: servicePrincipal
volumeMounts:
- name: keytab
mountPath: /etc/prole/keytabs
mountPath: /etc/knoe/keytabs
- name: keytab-secret
mountPath: /mnt/keytab-secret
readOnly: true
- name: prole-kdc-config
mountPath: /opt/prole-kdc
- name: prole-kdc-data
- name: knoe-kdc-config
mountPath: /opt/knoe-kdc
- name: knoe-kdc-data
mountPath: /var/lib/krb5kdc
- name: prole-kdc-data
- name: knoe-kdc-data
mountPath: /etc/krb5kdc
containers:
- name: prole-auth
image: prole-auth:latest
- name: knoe-auth
image: knoe-auth:latest
ports:
- containerPort: 8080
name: http
@ -139,25 +139,25 @@ spec:
- name: PROLE_AUTH_COOKIE_DOMAIN
valueFrom:
configMapKeyRef:
name: prole-platform-config
name: knoe-platform-config
key: authCookieDomain
optional: true
- name: PROLE_AUTH_SESSION_SECRET
valueFrom:
secretKeyRef:
name: prole-auth-secrets
name: knoe-auth-secrets
key: sessionSecret
- name: PROLE_KERBEROS_SERVICE_PRINCIPAL
valueFrom:
configMapKeyRef:
name: prole-auth-kerberos
name: knoe-auth-kerberos
key: servicePrincipal
- name: PROLE_KERBEROS_KEYTAB_PATH
value: "/etc/prole/keytabs/http.keytab"
value: "/etc/knoe/keytabs/http.keytab"
- name: PROLE_KERBEROS_REALM
valueFrom:
configMapKeyRef:
name: prole-auth-kerberos
name: knoe-auth-kerberos
key: realm
# ── Google Workspace OIDC (primary auth for GKE/prod) ──────────
# Secret created by installer from Auth+Routing tab OIDC fields.
@ -187,7 +187,7 @@ spec:
- name: OIDC_BASE_URL
valueFrom:
configMapKeyRef:
name: prole-platform-config
name: knoe-platform-config
key: frontdoorHost
optional: true
# Comma-separated list of bare usernames granted admin group in OIDC tokens
@ -195,38 +195,38 @@ spec:
value: "admin"
volumeMounts:
- name: keytab
mountPath: /etc/prole/keytabs
mountPath: /etc/knoe/keytabs
readOnly: true
- name: prole-kdc-config
- name: knoe-kdc-config
mountPath: /etc/krb5.conf
subPath: krb5.conf
readOnly: true
- name: kdc
image: myrddin.prole.org:5000/prole-authority:latest
image: myrddin.knoe.org:5000/knoe-authority:latest
imagePullPolicy: IfNotPresent
command: ["/bin/bash", "/opt/prole-kdc/entrypoint.sh"]
command: ["/bin/bash", "/opt/knoe-kdc/entrypoint.sh"]
env:
- name: PROLE_KDC_REALM
valueFrom:
configMapKeyRef:
name: prole-auth-kerberos
name: knoe-auth-kerberos
key: realm
- name: PROLE_KDC_ADMIN_PRINCIPAL
value: "admin/admin"
- name: PROLE_KDC_MASTER_PASSWORD
valueFrom:
secretKeyRef:
name: prole-kdc-secrets
name: knoe-kdc-secrets
key: master_password
- name: PROLE_KDC_ADMIN_PASSWORD
valueFrom:
secretKeyRef:
name: prole-kdc-secrets
name: knoe-kdc-secrets
key: admin_password
- name: PROLE_KDC_GUEST_PASSWORD
valueFrom:
secretKeyRef:
name: prole-kdc-secrets
name: knoe-kdc-secrets
key: guest_password
optional: true # auto-generated by init_knoe_users.sh if absent
ports:
@ -246,22 +246,22 @@ spec:
containerPort: 749
protocol: TCP
volumeMounts:
- name: prole-kdc-config
mountPath: /opt/prole-kdc
- name: prole-kdc-data
- name: knoe-kdc-config
mountPath: /opt/knoe-kdc
- name: knoe-kdc-data
mountPath: /var/lib/krb5kdc
- name: prole-kdc-data
- name: knoe-kdc-data
mountPath: /etc/krb5kdc
volumes:
- name: keytab
emptyDir: {}
- name: keytab-secret
secret:
secretName: prole-auth-keytab
secretName: knoe-auth-keytab
optional: true
- name: prole-kdc-config
- name: knoe-kdc-config
configMap:
name: prole-kdc-config
name: knoe-kdc-config
defaultMode: 0755
- name: prole-kdc-data
- name: knoe-kdc-data
emptyDir: {}

View File

@ -1,8 +1,8 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: prole-auth-kerberos
name: knoe-auth-kerberos
data:
# Kerberos HTTP service principal for SPNEGO (must match keytab)
servicePrincipal: "HTTP/api.prole.org@PROLE.LOCAL"
servicePrincipal: "HTTP/api.knoe.org@PROLE.LOCAL"
realm: "PROLE.LOCAL"

View File

@ -2,7 +2,7 @@
apiVersion: v1
kind: Secret
metadata:
name: prole-auth-secrets
name: knoe-auth-secrets
type: Opaque
stringData:
# Strong random value (e.g. 32+ bytes). Used to HMAC-sign session cookies.

View File

@ -1,12 +1,12 @@
apiVersion: v1
kind: Service
metadata:
name: prole-auth
name: knoe-auth
labels:
app: prole-auth
app: knoe-auth
spec:
selector:
app: prole-auth
app: knoe-auth
ports:
- name: http
port: 8080

View File

@ -1,7 +1,7 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: prole-nginx-config
name: knoe-nginx-config
data:
nginx.conf: |
user nginx;

View File

@ -1,21 +1,21 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: prole
name: knoe
labels:
app: prole
app: knoe
spec:
replicas: 1
selector:
matchLabels:
app: prole
app: knoe
template:
metadata:
labels:
app: prole
app: knoe
spec:
nodeSelector:
kubernetes.io/hostname: myrddin.prole.org
kubernetes.io/hostname: myrddin.knoe.org
containers:
- name: nginx
image: nginx:1.27-alpine
@ -41,10 +41,10 @@ spec:
volumes:
- name: nginx-config
configMap:
name: prole-nginx-config
name: knoe-nginx-config
- name: tls
secret:
secretName: prole-nginx-tls
secretName: knoe-nginx-tls
- name: web-root
configMap:
name: prole-index-html
name: knoe-index-html

View File

@ -1,7 +1,7 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: prole-kdc-config
name: knoe-kdc-config
data:
krb5.conf: |
[libdefaults]
@ -15,8 +15,8 @@ data:
admin_server = 127.0.0.1
}
PROLE.ORG = {
kdc = myrddin.prole.org
admin_server = myrddin.prole.org
kdc = myrddin.knoe.org
admin_server = myrddin.knoe.org
}
[capaths]
@ -64,22 +64,22 @@ data:
fi
mkdir -p /etc/krb5kdc /var/lib/krb5kdc
if [[ -f /opt/prole-kdc/krb5.conf ]]; then
cp /opt/prole-kdc/krb5.conf /etc/krb5.conf
if [[ -f /opt/knoe-kdc/krb5.conf ]]; then
cp /opt/knoe-kdc/krb5.conf /etc/krb5.conf
fi
if [[ -f /opt/prole-kdc/kdc.conf ]]; then
cp /opt/prole-kdc/kdc.conf /etc/krb5kdc/kdc.conf
if [[ -f /opt/knoe-kdc/kdc.conf ]]; then
cp /opt/knoe-kdc/kdc.conf /etc/krb5kdc/kdc.conf
fi
if [[ -f /opt/prole-kdc/kadm5.acl ]]; then
cp /opt/prole-kdc/kadm5.acl /etc/krb5kdc/kadm5.acl
if [[ -f /opt/knoe-kdc/kadm5.acl ]]; then
cp /opt/knoe-kdc/kadm5.acl /etc/krb5kdc/kadm5.acl
fi
if [[ -z "${PROLE_KDC_MASTER_PASSWORD:-}" ]]; then
echo "ERROR: Missing required env PROLE_KDC_MASTER_PASSWORD (secret 'prole-kdc-secrets/master_password')." >&2
echo "ERROR: Missing required env PROLE_KDC_MASTER_PASSWORD (secret 'knoe-kdc-secrets/master_password')." >&2
exit 1
fi
if [[ -z "${PROLE_KDC_ADMIN_PASSWORD:-}" ]]; then
echo "ERROR: Missing required env PROLE_KDC_ADMIN_PASSWORD (secret 'prole-kdc-secrets/admin_password')." >&2
echo "ERROR: Missing required env PROLE_KDC_ADMIN_PASSWORD (secret 'knoe-kdc-secrets/admin_password')." >&2
exit 1
fi

View File

@ -1,15 +1,15 @@
apiVersion: v1
kind: Secret
metadata:
name: prole-kdc-secrets
name: knoe-kdc-secrets
type: Opaque
stringData:
# Strong random values (do not commit real secrets)
master_password: "CHANGE_ME"
admin_password: "CHANGE_ME"
# Shared secret used for cross-realm trust with myrddin.prole.org PROLE.ORG realm
# Shared secret used for cross-realm trust with myrddin.knoe.org PROLE.ORG realm
trust_shared_password: "CHANGE_ME"
# myrddin.prole.org Samba AD admin password (for reciprocal trust principal creation)
# myrddin.knoe.org Samba AD admin password (for reciprocal trust principal creation)
trust_password: "CHANGE_ME"
# Password for guest@PROLE.LOCAL read-only principal (auto-generated by init_knoe_users.sh if absent)
guest_password: "CHANGE_ME"

View File

@ -1,12 +1,12 @@
apiVersion: v1
kind: Service
metadata:
name: prole
name: knoe
labels:
app: prole
app: knoe
spec:
selector:
app: prole
app: knoe
ports:
- name: https
port: 443

View File

@ -7,7 +7,7 @@ metadata:
kubernetes.io/ingress.class: traefik
spec:
rules:
- host: db.prole.org
- host: db.knoe.org
http:
paths:
- path: /
@ -17,7 +17,7 @@ spec:
name: kong
port:
number: 8000
- host: supabase.prole.org
- host: supabase.knoe.org
http:
paths:
- path: /

View File

@ -1,7 +1,7 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: prole-krb5-conf
name: knoe-krb5-conf
namespace: default
data:
krb5.conf: |
@ -17,5 +17,5 @@ data:
}
[domain_realm]
.prole.org = PROLE.ORG
prole.org = PROLE.ORG
.knoe.org = PROLE.ORG
knoe.org = PROLE.ORG

View File

@ -33,7 +33,7 @@ data:
<body>
<div class="wrap">
<h1>OpenTofu Pipeline Ready</h1>
<p>This service hosts the OpenTofu control plane for Prole deployments.</p>
<p>This service hosts the OpenTofu control plane for Knoe deployments.</p>
<p>Pipeline root (on disk): <code>deploy/opentofu/k3s</code></p>
</div>
</body>
@ -56,7 +56,7 @@ spec:
app: opentofu
spec:
nodeSelector:
kubernetes.io/hostname: myrddin.prole.org
kubernetes.io/hostname: myrddin.knoe.org
containers:
- name: opentofu-ui
image: nginx:1.27-alpine

View File

@ -1,4 +1,4 @@
k3s_server_url = "https://myrddin.prole.org:6443"
k3s_server_url = "https://myrddin.knoe.org:6443"
k3s_token = "K107c8c6000488eca4a067d8a73119bbae2f07b4ea1bac7d8d3dc9c500cbb8acb18::server:04572345810eae2f9619a6ed4239702b"
namespace = "prole-db"
kubeconfig_path = "../../../prole-k3s.kubeconfig"
namespace = "knoe-db"
kubeconfig_path = "../../../knoe-k3s.kubeconfig"

View File

@ -1,6 +1,6 @@
variable "k3s_server_url" {
type = string
description = "K3s API server URL (e.g., https://pi.prole.org:6443)"
description = "K3s API server URL (e.g., https://pi.knoe.org:6443)"
}
variable "k3s_token" {
@ -18,6 +18,6 @@ variable "kubeconfig_path" {
variable "namespace" {
type = string
description = "Target namespace for Prole resources"
description = "Target namespace for Knoe resources"
default = "default"
}

View File

@ -1,6 +1,6 @@
# OpenTofu Production Pipeline
This pipeline deploys Prole into a production cluster (AWS EKS / GCloud GKE).
This pipeline deploys Knoe into a production cluster (AWS EKS / GCloud GKE).
## Usage
1. Copy manifests from the k3s pipeline into `manifests/`.

View File

@ -17,6 +17,6 @@ variable "cluster_ca_cert" {
variable "namespace" {
type = string
description = "Target namespace for Prole resources"
description = "Target namespace for Knoe resources"
default = "default"
}

View File

@ -2,7 +2,7 @@
## Problem
When the Prole Installer is packaged with PyInstaller and run as a standalone binary, Docker builds fail with the error:
When the Knoe Installer is packaged with PyInstaller and run as a standalone binary, Docker builds fail with the error:
```
Building knoe-db:17.7-037 in /var/folders/rt/pywlnmxj3dn7t5552vwdcpp80000gn/T/_MEIGozuj4/knoe-db...
@ -38,11 +38,11 @@ def worker():
def worker():
tag = self.get_knoe_db_version()
# Use $PROLE_HOME/build for Docker build context
prole_home = resolve_prole_home()
# Use $KNOE_HOME/build for Docker build context
knoe_home = resolve_knoe_home()
# Use a mode-scoped build dir to avoid cross-mode interference (k3d vs k3s)
mode_key = _deployment_mode_from_env(env_key) or "default"
build_dir = prole_home / "build" / mode_key / "knoe-db"
build_dir = knoe_home / "build" / mode_key / "knoe-db"
build_dir.mkdir(parents=True, exist_ok=True)
# Copy DB build context to writable location
@ -66,7 +66,7 @@ def worker():
The installer now creates and uses:
```
$HOME/.prole/
$HOME/.knoe/
└── build/
└── k3d/ # or k3s, k8s
└── knoe-db/ # Docker build context
@ -74,12 +74,12 @@ $HOME/.prole/
├── conf/
├── scripts/
├── ...
└── .prole_build_context_ready # marker to preserve generated Dockerfile
└── .knoe_build_context_ready # marker to preserve generated Dockerfile
Version metadata is also mode-scoped:
```
$HOME/.prole/
$HOME/.knoe/
└── modes/
└── k3d/ # or k3s, k8s
├── conf/postgresql/.version
@ -89,7 +89,7 @@ $HOME/.prole/
## Why This Works
1. **Writable Location:** `$HOME/.prole/` is user-writable
1. **Writable Location:** `$HOME/.knoe/` is user-writable
2. **Persistent:** Files remain between runs (can be cached)
3. **Clean State:** Each build starts fresh (old dir removed)
4. **Docker Compatible:** Standard directory Docker can access
@ -99,7 +99,7 @@ $HOME/.prole/
The `knoe-db` directory is:
- **Included in spec:** `('knoe-db', 'knoe-db')`
- **Extracted by PyInstaller:** To `_MEIPASS/knoe-db/`
- **Copied to writable location:** `$HOME/.prole/build/<mode>/knoe-db/`
- **Copied to writable location:** `$HOME/.knoe/build/<mode>/knoe-db/`
- **Used for build:** Docker builds from writable copy
## Performance
@ -125,16 +125,16 @@ python3 install.py --gui
### Test from Package
```bash
make package
./dist/Prole\ Installer.app/Contents/MacOS/prole-installer --gui
./dist/Knoe\ Installer.app/Contents/MacOS/knoe-installer --gui
# Navigate to "Build Container" screen
# Click "Build Database Image"
# Should create ~/.prole/build/<mode>/knoe-db and succeed
# Should create ~/.knoe/build/<mode>/knoe-db and succeed
```
### Verify Directory Creation
```bash
# After build starts
ls -la ~/.prole/build/<mode>/knoe-db/
ls -la ~/.knoe/build/<mode>/knoe-db/
# Should show Dockerfile and other files
```
@ -143,7 +143,7 @@ ls -la ~/.prole/build/<mode>/knoe-db/
The build directory persists after the installer exits. To clean up:
```bash
rm -rf ~/.prole/build
rm -rf ~/.knoe/build
```
Or include in the installer:
@ -151,7 +151,7 @@ Or include in the installer:
```python
def cleanup_build_dirs():
"""Clean up temporary build directories."""
build_dir = Path.home() / ".prole" / "build"
build_dir = Path.home() / ".knoe" / "build"
if build_dir.exists():
shutil.rmtree(build_dir)
```
@ -167,7 +167,7 @@ If Docker build still hangs, check:
2. **Docker context accessible:**
```bash
ls -la ~/.prole/build/<mode>/knoe-db/Dockerfile
ls -la ~/.knoe/build/<mode>/knoe-db/Dockerfile
```
3. **Disk space:**
@ -186,7 +186,7 @@ If Docker build still hangs, check:
### 1. Use /tmp with Unique Names
```python
import tempfile
build_dir = Path(tempfile.mkdtemp(prefix="prole-build-"))
build_dir = Path(tempfile.mkdtemp(prefix="knoe-build-"))
```
**Pros:** Automatic cleanup
**Cons:** Lost between runs, no caching
@ -205,7 +205,7 @@ cwd = PROJECT_ROOT / "knoe-db"
**Pros:** Works from source
**Cons:** ✗ Fails from package (_MEIPASS is read-only)
### 4. **Chosen: Copy to ~/.prole/build** ✓
### 4. **Chosen: Copy to ~/.knoe/build** ✓
**Pros:** Works from both source and package, writable, persistent
**Cons:** Requires disk space, manual cleanup
@ -249,7 +249,7 @@ cwd = PROJECT_ROOT / "knoe-db"
## Summary
The Docker build now works correctly from both source and packaged binary by:
1. Creating `~/.prole/build/<mode>/knoe-db/` directory
1. Creating `~/.knoe/build/<mode>/knoe-db/` directory
2. Copying build context from embedded resources
3. Running `docker build` in the writable directory
4. Avoiding PyInstaller's read-only temporary extraction directory

Some files were not shown because too many files have changed in this diff Show More