ops(kms): audit + migration scripts for KMSSecret CRD ↔ Lux KMS cutover
* scripts/kms-crd-host-migrate.sh — bulk-patch every KMSSecret CRD's
hostAPI to point at kms.lux-kms-go.svc.cluster.local. Idempotent.
Already executed against lux-k8s + hanzo-k8s (147 CRDs).
* scripts/kms-orphan-audit.sh — audit which K8s Secrets are NOT backed
by a KMSSecret CRD or whitelisted bootstrap creds. Output:
lux-k8s 323 non-system Secrets, 268 orphan
hanzo-k8s 461 non-system Secrets, 367 orphan
Most orphans are ARC runner state, cert-manager cert content, and
operator-internal config — not appropriate for KMS migration.
Run before sweeping anything.
This commit is contained in:
Executable
+29
@@ -0,0 +1,29 @@
|
||||
#!/bin/bash
|
||||
# Bulk-patch every KMSSecret CRD in both clusters to point at Lux KMS.
|
||||
#
|
||||
# OLD: hostAPI=http://kms.hanzo.svc.cluster.local/api (Infisical-fork)
|
||||
# NEW: hostAPI=http://kms.lux-kms-go.svc.cluster.local (Lux Go-native)
|
||||
#
|
||||
# Auth credentials secret name stays as `universal-auth-credentials`.
|
||||
set -euo pipefail
|
||||
|
||||
NEW_HOST="http://kms.lux-kms-go.svc.cluster.local"
|
||||
|
||||
migrate_cluster() {
|
||||
local ctx=$1
|
||||
echo "=== ${ctx} ==="
|
||||
kubectl --context "${ctx}" get kmssecrets -A -o jsonpath='{range .items[*]}{.metadata.namespace}/{.metadata.name}{"\n"}{end}' | \
|
||||
while IFS=/ read -r ns name; do
|
||||
[ -z "${ns}" ] && continue
|
||||
echo " patch ${ns}/${name}"
|
||||
kubectl --context "${ctx}" -n "${ns}" patch kmssecret "${name}" \
|
||||
--type=merge -p "{\"spec\":{\"hostAPI\":\"${NEW_HOST}\"}}" || true
|
||||
done
|
||||
}
|
||||
|
||||
for ctx in lux-k8s hanzo-k8s; do
|
||||
migrate_cluster "${ctx}"
|
||||
done
|
||||
|
||||
echo "DONE — restart operator to pick up changes:"
|
||||
echo " kubectl --context <ctx> -n kms-operator-system rollout restart deploy/kms-operator-controller-manager"
|
||||
Executable
+46
@@ -0,0 +1,46 @@
|
||||
#!/bin/bash
|
||||
# Audit K8s Secrets that are NOT (a) backed by a KMSSecret CRD,
|
||||
# (b) system secrets, (c) TLS, (d) image pull, (e) Helm release.
|
||||
set -uo pipefail
|
||||
|
||||
audit_cluster() {
|
||||
local ctx=$1
|
||||
echo "=========== ${ctx} ==========="
|
||||
|
||||
# All KMSSecret-managed K8s Secret refs (managed by operator)
|
||||
local managed
|
||||
managed=$(kubectl --context "${ctx}" get kmssecrets -A \
|
||||
-o jsonpath='{range .items[*]}{.spec.managedSecretReference.secretNamespace}{"/"}{.spec.managedSecretReference.secretName}{"\n"}{end}' \
|
||||
2>/dev/null | sort -u)
|
||||
echo " KMSSecret-managed targets: $(echo "$managed" | grep -c .)"
|
||||
|
||||
# All K8s Secrets, excluding system types
|
||||
local all
|
||||
all=$(kubectl --context "${ctx}" get secrets -A \
|
||||
--field-selector type!=kubernetes.io/service-account-token \
|
||||
--field-selector type!=kubernetes.io/dockerconfigjson \
|
||||
--field-selector type!=kubernetes.io/tls \
|
||||
--field-selector type!=helm.sh/release.v1 \
|
||||
-o jsonpath='{range .items[*]}{.metadata.namespace}{"/"}{.metadata.name}{"\n"}{end}' \
|
||||
2>/dev/null | sort -u)
|
||||
local total
|
||||
total=$(echo "$all" | grep -c .)
|
||||
echo " Non-system Secrets total: ${total}"
|
||||
|
||||
# Orphans = in all but not managed and not whitelisted
|
||||
local orphans
|
||||
orphans=$(comm -23 <(echo "$all") <(echo "$managed") \
|
||||
| grep -vE '^[^/]+/(universal-auth-credentials|ghcr-luxfi|ghcr-secret|ghcr-zoo|kms-machine-identity)$' \
|
||||
| grep -vE 'sh\.helm\.release')
|
||||
local count
|
||||
count=$(echo "$orphans" | grep -c . || true)
|
||||
echo " Orphan Secrets (no KMSSecret CRD backing, not bootstrap creds): ${count}"
|
||||
if [ "$count" != "0" ] && [ -n "$orphans" ]; then
|
||||
echo " Sample (first 10):"
|
||||
echo "$orphans" | head -10 | sed 's/^/ /'
|
||||
fi
|
||||
}
|
||||
|
||||
for ctx in lux-k8s hanzo-k8s; do
|
||||
audit_cluster "$ctx"
|
||||
done
|
||||
Reference in New Issue
Block a user