Establish clean homelab infrastructure baseline
Reorganize the brownfield repository, remove retired and generated artifacts, harden ignore rules, and record the GitOps/IaC redesign.
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
# Casdoor — RETIRED (2026-07-10)
|
||||
|
||||
Casdoor was an SSO/IdP experiment, evaluated and rejected in favour of **Authelia**
|
||||
(see `../../apps/authelia/`). Decommissioned:
|
||||
|
||||
- Deleted the entire `casdoor` Kubernetes namespace (Helm releases `casdoor` +
|
||||
`casdoor-postgresql`, deployment, services, secrets, configmap, in-namespace Postgres).
|
||||
- Dropped the orphaned `casdoor` database from the shared Postgres (`shared-db`).
|
||||
|
||||
It was never publicly routed (no cloudflared/gateway ingress) and had no consumers.
|
||||
This directory is kept only as a tombstone.
|
||||
@@ -0,0 +1,32 @@
|
||||
# Keycloak — RETIRED (2026-07-10)
|
||||
|
||||
Keycloak has been **decommissioned** and replaced by **Authelia** as the SSO / OIDC
|
||||
provider (issuer `https://auth.ddupan.top`, backed by Samba AD via LDAP). See
|
||||
`../../apps/authelia/`.
|
||||
|
||||
## What was removed
|
||||
- The entire `keycloak` Kubernetes namespace (Deployment, Service, bootstrap Job,
|
||||
ConfigMaps, `keycloak-db-secret`) — `kubectl delete namespace keycloak`.
|
||||
- A **second, abandoned Keycloak** in the `shared-db` namespace (raw manifests:
|
||||
`deploy/svc/job/cm keycloak*`) that never became ready (crashlooped ~21.8k times over
|
||||
82 days). Deleted the four Keycloak objects only; the `shared-postgresql` CNPG tenant in
|
||||
that namespace was left untouched.
|
||||
- The `idm.ddupan.top` public-hostname route from the cloudflared tunnel ingress
|
||||
(`../../infrastructure/cloudflared/terraform/main.tf`). `idm.ddupan.top` now returns HTTP 404.
|
||||
|
||||
## Consumers migrated
|
||||
- **Gitea** — OIDC provider switched from `keycloak` to `authelia`
|
||||
(`../../apps/gitea/gitea-values.yaml`, secret `gitea-oidc-secret`). The `panxiao81`
|
||||
account was re-linked to the Authelia source by email (`ACCOUNT_LINKING=auto`).
|
||||
|
||||
## Leftovers (intentionally not cleaned up)
|
||||
- **Orphaned tables** in the shared `postgres` database: Keycloak ran against
|
||||
`jdbc:postgresql://shared-postgresql.shared-db.svc:5432/postgres` as the
|
||||
superuser, creating its tables in that DB's `public` schema. They are inert;
|
||||
dropping ~90 tables by hand was judged risky/low-value. Drop them manually if
|
||||
you want the DB tidy.
|
||||
- **DNS**: the `idm.ddupan.top` CNAME still exists at Cloudflare (points at the
|
||||
tunnel, so it just hits the 404 catch-all). Remove it in the Cloudflare dash if
|
||||
desired; it is not managed by Terraform.
|
||||
|
||||
The manifests in this directory are kept for reference only. Safe to delete.
|
||||
@@ -0,0 +1,25 @@
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: keycloak-bootstrap
|
||||
namespace: keycloak
|
||||
spec:
|
||||
backoffLimit: 2
|
||||
template:
|
||||
spec:
|
||||
serviceAccountName: keycloak-bootstrap
|
||||
restartPolicy: OnFailure
|
||||
volumes:
|
||||
- name: bootstrap
|
||||
configMap:
|
||||
name: keycloak-bootstrap
|
||||
containers:
|
||||
- name: bootstrap
|
||||
image: curlimages/curl:8.12.1
|
||||
command:
|
||||
- /bin/sh
|
||||
- -ec
|
||||
- sh /bootstrap/bootstrap.sh
|
||||
volumeMounts:
|
||||
- name: bootstrap
|
||||
mountPath: /bootstrap
|
||||
@@ -0,0 +1,26 @@
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: keycloak-db-secret-sync
|
||||
namespace: keycloak
|
||||
spec:
|
||||
backoffLimit: 2
|
||||
template:
|
||||
spec:
|
||||
serviceAccountName: keycloak-bootstrap
|
||||
restartPolicy: OnFailure
|
||||
volumes:
|
||||
- name: sync
|
||||
configMap:
|
||||
name: keycloak-db-secret-sync
|
||||
defaultMode: 493
|
||||
containers:
|
||||
- name: sync
|
||||
image: registry.k8s.io/kubectl:v1.31.0
|
||||
command:
|
||||
- /bin/sh
|
||||
- -ec
|
||||
- /sync/sync.sh
|
||||
volumeMounts:
|
||||
- name: sync
|
||||
mountPath: /sync
|
||||
@@ -0,0 +1,22 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: keycloak-db-secret-sync
|
||||
namespace: keycloak
|
||||
data:
|
||||
sync.sh: |
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
until kubectl -n shared-db get secret shared-postgresql-superuser-secret >/dev/null 2>&1; do
|
||||
sleep 5
|
||||
done
|
||||
|
||||
username=$(kubectl -n shared-db get secret shared-postgresql-superuser-secret -o jsonpath='{.data.username}' | base64 -d)
|
||||
password=$(kubectl -n shared-db get secret shared-postgresql-superuser-secret -o jsonpath='{.data.password}' | base64 -d)
|
||||
|
||||
kubectl create secret generic keycloak-db-secret \
|
||||
--namespace keycloak \
|
||||
--from-literal=username="${username}" \
|
||||
--from-literal=password="${password}" \
|
||||
--dry-run=client -o yaml | kubectl -n keycloak apply -f -
|
||||
@@ -0,0 +1,4 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: keycloak
|
||||
@@ -0,0 +1,53 @@
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: keycloak-bootstrap
|
||||
namespace: keycloak
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: keycloak-secret-writer
|
||||
namespace: keycloak
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["secrets"]
|
||||
verbs: ["get", "create", "update", "patch"]
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: keycloak-secret-writer
|
||||
namespace: keycloak
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: keycloak-bootstrap
|
||||
namespace: keycloak
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: keycloak-secret-writer
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: shared-postgresql-secret-reader
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["secrets"]
|
||||
resourceNames: ["shared-postgresql-superuser-secret"]
|
||||
verbs: ["get"]
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: shared-postgresql-secret-reader
|
||||
namespace: shared-db
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: keycloak-bootstrap
|
||||
namespace: keycloak
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: shared-postgresql-secret-reader
|
||||
@@ -0,0 +1,10 @@
|
||||
# Traefik Gateway API helpers
|
||||
|
||||
- Define the GatewayClass/Gateway that Traefik's controller expects so later HTTPRoutes can bind to it.
|
||||
- All manifests live here for GitOps sync; the Gateway uses the `traefik` controller name (`traefik.io/gateway-controller`) that k3s bundled Traefik advertises.
|
||||
- Apply with:
|
||||
```bash
|
||||
kubectl apply -f ~/services/archive/traefik/gatewayclass.yaml
|
||||
kubectl apply -f ~/services/archive/traefik/gateway.yaml
|
||||
```
|
||||
- Once accepted you can add HTTPRoute objects (e.g., `~/services/apps/http-echo/httproute-traefik.yaml`) targeting the Gateway.
|
||||
@@ -0,0 +1,17 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: traefik-gateway
|
||||
namespace: default
|
||||
spec:
|
||||
gatewayClassName: traefik
|
||||
listeners:
|
||||
- name: http
|
||||
protocol: HTTP
|
||||
port: 80
|
||||
allowedRoutes:
|
||||
namespaces:
|
||||
from: All
|
||||
kinds:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: HTTPRoute
|
||||
@@ -0,0 +1,6 @@
|
||||
apiVersion: gateway.networking.k8s.io/v1
|
||||
kind: GatewayClass
|
||||
metadata:
|
||||
name: traefik
|
||||
spec:
|
||||
controllerName: traefik.io/gateway-controller
|
||||
Reference in New Issue
Block a user