feat: replace secret-init Jobs with mittwald operator + cert-manager
Migrate ~180 LOC of openssl/kubectl init Jobs to declarative Secret manifests reconciled by mittwald/kubernetes-secret-generator (random strings, SSH keypair) and cert-manager Certificates (RSA private key + self-signed CA chain). mittwald only fills empty fields, so existing populated Secrets keep their current values across the migration. Changes: - New prototype kubernetes-secret-generator (chart 3.4.1, mittwald helm repo). Cluster-wide informer reconciler, no webhook -> cold-bootstrap safe via ArgoCD retries. - New cert-manager selfsigned ClusterIssuer (in-cluster trust root). letsencrypt remains for public-DNS endpoints. - forgejo: admin-secret Job replaced with a mittwald-annotated Secret (hex-encoded 24-char password). Deploy-key Job split: mittwald ssh-keypair Secret + slim Job that uploads pubkey to Forgejo and copies privkey into the argocd repo Secret. - ocis: 13 Secrets / 16 random fields now mittwald-managed (UUIDs replaced with opaque random hex; ocis treats user-id as opaque). IDP RSA signing key, LDAP self-signed CA, and LDAP server cert produced by cert-manager. Per-Deployment ytt overlay remaps volume key paths (tls.crt -> ldap-ca.crt, tls.key -> private-key.pem, etc.) since the ocis chart mounts Secrets raw without items support. Old multi-secret s3-secret-job replaced with a slim external-secret precheck Job that only validates pre-created Hetzner S3/Storage Box credentials. - Application sync-wave -10 on cert-manager and kubernetes-secret- generator so they install before consumers. ArgoCD selfHeal handles any residual races. CLAUDE.md: remove the "all namespaces use privileged PodSecurity" convention. Existing namespaces still carry the label and will be audited separately. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
9112153e8a
commit
85b8fec6b3
|
|
@ -7,7 +7,6 @@ GitOps-managed Kubernetes cluster on Hetzner Cloud running Talos Linux. Uses [my
|
|||
- **3 Talos control-plane nodes** (CAX11 ARM64, Hetzner Cloud Nuremberg)
|
||||
- Node IPs: `195.201.219.111`, `195.201.140.75`, `195.201.219.17`
|
||||
- `allowSchedulingOnControlPlanes: true` (no dedicated workers)
|
||||
- All namespaces use `pod-security.kubernetes.io/enforce: privileged`
|
||||
|
||||
## Domain & DNS
|
||||
- **Domain**: `tr1ceracop.de` (registered at INWX)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
#@ load("@ytt:overlay", "overlay")
|
||||
|
||||
#@overlay/match by=overlay.all, expects="1+"
|
||||
---
|
||||
metadata:
|
||||
#@overlay/match missing_ok=True
|
||||
#@overlay/match-child-defaults missing_ok=True
|
||||
annotations:
|
||||
argocd.argoproj.io/sync-wave: "-10"
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
#@data/values-schema
|
||||
---
|
||||
#@overlay/match-child-defaults missing_ok=True
|
||||
application:
|
||||
namespace: kubernetes-secret-generator
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
#@ load("@ytt:overlay", "overlay")
|
||||
|
||||
#@overlay/match by=overlay.all, expects="1+"
|
||||
---
|
||||
metadata:
|
||||
#@overlay/match missing_ok=True
|
||||
#@overlay/match-child-defaults missing_ok=True
|
||||
annotations:
|
||||
argocd.argoproj.io/sync-wave: "-10"
|
||||
|
|
@ -6,6 +6,7 @@ environment:
|
|||
- proto: argocd
|
||||
- proto: traefik
|
||||
- proto: cert-manager
|
||||
- proto: kubernetes-secret-generator
|
||||
- proto: forgejo
|
||||
- proto: victoria-metrics-single
|
||||
- proto: grafana
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: ClusterIssuer
|
||||
metadata:
|
||||
name: selfsigned
|
||||
spec:
|
||||
selfSigned: {}
|
||||
|
|
@ -1,73 +0,0 @@
|
|||
#@ load("@ytt:data", "data")
|
||||
|
||||
#@ ns = data.values.application.namespace
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: forgejo-admin-secret-init
|
||||
namespace: #@ ns
|
||||
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: forgejo-admin-secret-init
|
||||
namespace: #@ ns
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["secrets"]
|
||||
verbs: ["get", "create"]
|
||||
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: forgejo-admin-secret-init
|
||||
namespace: #@ ns
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: forgejo-admin-secret-init
|
||||
namespace: #@ ns
|
||||
roleRef:
|
||||
kind: Role
|
||||
name: forgejo-admin-secret-init
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
|
||||
---
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: forgejo-admin-secret-init
|
||||
namespace: #@ ns
|
||||
annotations:
|
||||
argocd.argoproj.io/sync-options: Replace=true
|
||||
spec:
|
||||
ttlSecondsAfterFinished: 300
|
||||
template:
|
||||
spec:
|
||||
serviceAccountName: forgejo-admin-secret-init
|
||||
restartPolicy: OnFailure
|
||||
containers:
|
||||
- name: init
|
||||
image: alpine/k8s:1.32.3
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- |
|
||||
if kubectl get secret forgejo-admin-secret -n ${NAMESPACE} >/dev/null 2>&1; then
|
||||
echo "Secret already exists, skipping"
|
||||
exit 0
|
||||
fi
|
||||
PASSWORD=$(head -c 32 /dev/urandom | base64 | tr -dc 'a-zA-Z0-9' | head -c 24)
|
||||
kubectl create secret generic forgejo-admin-secret \
|
||||
-n ${NAMESPACE} \
|
||||
--from-literal=username=gitea_admin \
|
||||
--from-literal=password="${PASSWORD}"
|
||||
echo "Created forgejo-admin-secret with random password"
|
||||
env:
|
||||
- name: NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
17
prototypes/forgejo/ytt/admin-secret.ytt.yaml
Normal file
17
prototypes/forgejo/ytt/admin-secret.ytt.yaml
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
#@ load("@ytt:data", "data")
|
||||
|
||||
#@ ns = data.values.application.namespace
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: forgejo-admin-secret
|
||||
namespace: #@ ns
|
||||
annotations:
|
||||
secret-generator.v1.mittwald.de/autogenerate: password
|
||||
secret-generator.v1.mittwald.de/encoding: hex
|
||||
secret-generator.v1.mittwald.de/length: "24"
|
||||
type: Opaque
|
||||
stringData:
|
||||
username: gitea_admin
|
||||
|
|
@ -17,7 +17,7 @@ metadata:
|
|||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["secrets"]
|
||||
verbs: ["get", "create"]
|
||||
verbs: ["get", "create", "patch", "update"]
|
||||
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
|
|
@ -40,6 +40,7 @@ metadata:
|
|||
name: argocd-deploy-key-init
|
||||
namespace: #@ ns
|
||||
annotations:
|
||||
argocd.argoproj.io/sync-wave: "1"
|
||||
argocd.argoproj.io/sync-options: Replace=true
|
||||
spec:
|
||||
ttlSecondsAfterFinished: 300
|
||||
|
|
@ -56,8 +57,6 @@ spec:
|
|||
- |
|
||||
set -e
|
||||
|
||||
apk add --no-cache openssh-keygen > /dev/null 2>&1
|
||||
|
||||
ARGOCD_NS="argocd"
|
||||
REPO_SECRET="forgejo-repo"
|
||||
REPO_URL="ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git"
|
||||
|
|
@ -65,6 +64,27 @@ spec:
|
|||
REPO_OWNER="gitea_admin"
|
||||
REPO_NAME="k8s-and-chill"
|
||||
|
||||
# Check if ArgoCD repo secret already exists
|
||||
if kubectl get secret "${REPO_SECRET}" -n "${ARGOCD_NS}" >/dev/null 2>&1; then
|
||||
echo "Secret ${REPO_SECRET} already exists in ${ARGOCD_NS}, skipping"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Wait for mittwald to populate the keypair and admin secrets
|
||||
echo "Waiting for forgejo-repo-keypair to be populated..."
|
||||
for i in $(seq 1 60); do
|
||||
PRIV_B64=$(kubectl get secret forgejo-repo-keypair -n "${NAMESPACE}" -o jsonpath='{.data.ssh-privatekey}' 2>/dev/null || true)
|
||||
PUB_B64=$(kubectl get secret forgejo-repo-keypair -n "${NAMESPACE}" -o jsonpath='{.data.ssh-publickey}' 2>/dev/null || true)
|
||||
if [ -n "${PRIV_B64}" ] && [ -n "${PUB_B64}" ]; then
|
||||
break
|
||||
fi
|
||||
if [ "$i" -eq 60 ]; then
|
||||
echo "forgejo-repo-keypair was not populated in time"
|
||||
exit 1
|
||||
fi
|
||||
sleep 5
|
||||
done
|
||||
|
||||
# Wait for Forgejo to be ready
|
||||
echo "Waiting for Forgejo to be ready..."
|
||||
for i in $(seq 1 60); do
|
||||
|
|
@ -79,22 +99,12 @@ spec:
|
|||
sleep 5
|
||||
done
|
||||
|
||||
# Check if ArgoCD repo secret already exists
|
||||
if kubectl get secret "${REPO_SECRET}" -n "${ARGOCD_NS}" >/dev/null 2>&1; then
|
||||
echo "Secret ${REPO_SECRET} already exists in ${ARGOCD_NS}, skipping"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Read admin credentials
|
||||
ADMIN_USER=$(kubectl get secret forgejo-admin-secret -n "${NAMESPACE}" -o jsonpath='{.data.username}' | base64 -d)
|
||||
ADMIN_PASS=$(kubectl get secret forgejo-admin-secret -n "${NAMESPACE}" -o jsonpath='{.data.password}' | base64 -d)
|
||||
|
||||
# Generate ed25519 SSH keypair
|
||||
KEYDIR=$(mktemp -d)
|
||||
ssh-keygen -t ed25519 -f "${KEYDIR}/id_ed25519" -N "" -q
|
||||
PRIVKEY=$(cat "${KEYDIR}/id_ed25519")
|
||||
PUBKEY=$(cat "${KEYDIR}/id_ed25519.pub")
|
||||
rm -rf "${KEYDIR}"
|
||||
PRIVKEY=$(echo "${PRIV_B64}" | base64 -d)
|
||||
PUBKEY=$(echo "${PUB_B64}" | base64 -d)
|
||||
|
||||
# Register deploy key via Forgejo API
|
||||
echo "Registering deploy key..."
|
||||
|
|
|
|||
13
prototypes/forgejo/ytt/argocd-deploy-keypair.ytt.yaml
Normal file
13
prototypes/forgejo/ytt/argocd-deploy-keypair.ytt.yaml
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
#@ load("@ytt:data", "data")
|
||||
|
||||
#@ ns = data.values.application.namespace
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: forgejo-repo-keypair
|
||||
namespace: #@ ns
|
||||
annotations:
|
||||
secret-generator.v1.mittwald.de/autogenerate: ssh-keypair
|
||||
type: Opaque
|
||||
5
prototypes/kubernetes-secret-generator/app-data.ytt.yaml
Normal file
5
prototypes/kubernetes-secret-generator/app-data.ytt.yaml
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
#@data/values-schema
|
||||
---
|
||||
#@overlay/match-child-defaults missing_ok=True
|
||||
application:
|
||||
namespace: kubernetes-secret-generator
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
---
|
||||
watchNamespace: ""
|
||||
|
||||
regenerateInsecure: false
|
||||
|
||||
resources:
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 32Mi
|
||||
limits:
|
||||
memory: 128Mi
|
||||
16
prototypes/kubernetes-secret-generator/vendir/base.ytt.yaml
Normal file
16
prototypes/kubernetes-secret-generator/vendir/base.ytt.yaml
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
#@ load("@ytt:data", "data")
|
||||
|
||||
#@ app = data.values.application
|
||||
---
|
||||
apiVersion: vendir.k14s.io/v1alpha1
|
||||
kind: Config
|
||||
directories:
|
||||
- path: #@ "charts/" + app.name
|
||||
contents:
|
||||
- path: .
|
||||
helmChart:
|
||||
name: #@ app.name
|
||||
version: #@ app.version
|
||||
repository:
|
||||
url: #@ app.url
|
||||
lazy: true
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
#@data/values-schema
|
||||
---
|
||||
#@overlay/match-child-defaults missing_ok=True
|
||||
application:
|
||||
#! renovate: datasource=helm
|
||||
name: kubernetes-secret-generator
|
||||
url: https://helm.mittwald.de
|
||||
version: 3.4.1
|
||||
16
prototypes/kubernetes-secret-generator/ytt/ns.ytt.yaml
Normal file
16
prototypes/kubernetes-secret-generator/ytt/ns.ytt.yaml
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
#@ load("@ytt:data", "data")
|
||||
#@ load("@ytt:overlay", "overlay")
|
||||
|
||||
#@ ns = data.values.application.namespace
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: #@ ns
|
||||
|
||||
#@overlay/match by=overlay.all, expects="1+"
|
||||
---
|
||||
metadata:
|
||||
#@overlay/match missing_ok=True
|
||||
namespace: #@ ns
|
||||
82
prototypes/ocis/ytt/external-secret-precheck-job.ytt.yaml
Normal file
82
prototypes/ocis/ytt/external-secret-precheck-job.ytt.yaml
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
#@ load("@ytt:data", "data")
|
||||
|
||||
#@ ns = data.values.application.namespace
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: ocis-external-secret-precheck
|
||||
namespace: #@ ns
|
||||
annotations:
|
||||
argocd.argoproj.io/hook: PreSync
|
||||
argocd.argoproj.io/sync-wave: "-2"
|
||||
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: ocis-external-secret-precheck
|
||||
namespace: #@ ns
|
||||
annotations:
|
||||
argocd.argoproj.io/hook: PreSync
|
||||
argocd.argoproj.io/sync-wave: "-2"
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["secrets"]
|
||||
verbs: ["get"]
|
||||
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: ocis-external-secret-precheck
|
||||
namespace: #@ ns
|
||||
annotations:
|
||||
argocd.argoproj.io/hook: PreSync
|
||||
argocd.argoproj.io/sync-wave: "-2"
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: ocis-external-secret-precheck
|
||||
namespace: #@ ns
|
||||
roleRef:
|
||||
kind: Role
|
||||
name: ocis-external-secret-precheck
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
|
||||
---
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: ocis-external-secret-precheck
|
||||
namespace: #@ ns
|
||||
annotations:
|
||||
argocd.argoproj.io/hook: PreSync
|
||||
argocd.argoproj.io/sync-wave: "-1"
|
||||
argocd.argoproj.io/sync-options: Replace=true
|
||||
spec:
|
||||
ttlSecondsAfterFinished: 300
|
||||
template:
|
||||
spec:
|
||||
serviceAccountName: ocis-external-secret-precheck
|
||||
restartPolicy: OnFailure
|
||||
containers:
|
||||
- name: precheck
|
||||
image: alpine/k8s:1.32.3
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- |
|
||||
set -e
|
||||
for s in ocis-s3-credentials ocis-storagebox-credentials; do
|
||||
if ! kubectl get secret "$s" -n "${NAMESPACE}" >/dev/null 2>&1; then
|
||||
echo "ERROR: External secret $s must be created manually before deploying ocis"
|
||||
exit 1
|
||||
fi
|
||||
echo "OK: $s exists"
|
||||
done
|
||||
env:
|
||||
- name: NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
70
prototypes/ocis/ytt/pki-certificates.ytt.yaml
Normal file
70
prototypes/ocis/ytt/pki-certificates.ytt.yaml
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
#@ load("@ytt:data", "data")
|
||||
|
||||
#@ ns = data.values.application.namespace
|
||||
|
||||
---
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: Certificate
|
||||
metadata:
|
||||
name: ocis-idp-rsa
|
||||
namespace: #@ ns
|
||||
spec:
|
||||
secretName: ocis-idp-rsa
|
||||
commonName: ocis-idp
|
||||
duration: 87600h
|
||||
renewBefore: 720h
|
||||
privateKey:
|
||||
algorithm: RSA
|
||||
size: 4096
|
||||
issuerRef:
|
||||
name: selfsigned
|
||||
kind: ClusterIssuer
|
||||
|
||||
---
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: Certificate
|
||||
metadata:
|
||||
name: ocis-ldap-ca
|
||||
namespace: #@ ns
|
||||
spec:
|
||||
secretName: ocis-ldap-ca-tls
|
||||
commonName: ocis-ldap-ca
|
||||
isCA: true
|
||||
duration: 87600h
|
||||
renewBefore: 720h
|
||||
privateKey:
|
||||
algorithm: RSA
|
||||
size: 2048
|
||||
issuerRef:
|
||||
name: selfsigned
|
||||
kind: ClusterIssuer
|
||||
|
||||
---
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: Issuer
|
||||
metadata:
|
||||
name: ocis-ldap-ca
|
||||
namespace: #@ ns
|
||||
spec:
|
||||
ca:
|
||||
secretName: ocis-ldap-ca-tls
|
||||
|
||||
---
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: Certificate
|
||||
metadata:
|
||||
name: ocis-ldap-cert
|
||||
namespace: #@ ns
|
||||
spec:
|
||||
secretName: ocis-ldap-cert-tls
|
||||
commonName: idm
|
||||
dnsNames:
|
||||
- idm
|
||||
duration: 87600h
|
||||
renewBefore: 720h
|
||||
privateKey:
|
||||
algorithm: RSA
|
||||
size: 2048
|
||||
issuerRef:
|
||||
name: ocis-ldap-ca
|
||||
kind: Issuer
|
||||
30
prototypes/ocis/ytt/random-secrets.ytt.yaml
Normal file
30
prototypes/ocis/ytt/random-secrets.ytt.yaml
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
#@ load("@ytt:data", "data")
|
||||
|
||||
#@ ns = data.values.application.namespace
|
||||
|
||||
#@ secrets = [
|
||||
#@ ("ocis-admin-user", "password,user-id"),
|
||||
#@ ("ocis-jwt-secret", "jwt-secret"),
|
||||
#@ ("ocis-machine-auth-api-key", "machine-auth-api-key"),
|
||||
#@ ("ocis-storage-system-jwt-secret", "storage-system-jwt-secret"),
|
||||
#@ ("ocis-storage-system", "api-key,user-id"),
|
||||
#@ ("ocis-transfer-secret", "transfer-secret"),
|
||||
#@ ("ocis-thumbnails-transfer-secret", "thumbnails-transfer-secret"),
|
||||
#@ ("ocis-service-account-secret", "service-account-secret"),
|
||||
#@ ("ocis-collaboration-wopi-secret", "wopi-secret"),
|
||||
#@ ("ocis-ldap-bind-secrets", "reva-ldap-bind-password,idp-ldap-bind-password,graph-ldap-bind-password"),
|
||||
#@ ("ocis-idp-encryption", "encryption.key"),
|
||||
#@ ]
|
||||
|
||||
#@ for name, fields in secrets:
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: #@ name
|
||||
namespace: #@ ns
|
||||
annotations:
|
||||
secret-generator.v1.mittwald.de/autogenerate: #@ fields
|
||||
secret-generator.v1.mittwald.de/length: "32"
|
||||
type: Opaque
|
||||
#@ end
|
||||
|
|
@ -1,182 +0,0 @@
|
|||
#@ load("@ytt:data", "data")
|
||||
|
||||
#@ ns = data.values.application.namespace
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: ocis-secret-init
|
||||
namespace: #@ ns
|
||||
annotations:
|
||||
argocd.argoproj.io/hook: PreSync
|
||||
argocd.argoproj.io/sync-wave: "-2"
|
||||
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: ocis-secret-init
|
||||
namespace: #@ ns
|
||||
annotations:
|
||||
argocd.argoproj.io/hook: PreSync
|
||||
argocd.argoproj.io/sync-wave: "-2"
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["secrets"]
|
||||
verbs: ["get", "create"]
|
||||
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: ocis-secret-init
|
||||
namespace: #@ ns
|
||||
annotations:
|
||||
argocd.argoproj.io/hook: PreSync
|
||||
argocd.argoproj.io/sync-wave: "-2"
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: ocis-secret-init
|
||||
namespace: #@ ns
|
||||
roleRef:
|
||||
kind: Role
|
||||
name: ocis-secret-init
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
|
||||
---
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: ocis-secret-init
|
||||
namespace: #@ ns
|
||||
annotations:
|
||||
argocd.argoproj.io/hook: PreSync
|
||||
argocd.argoproj.io/sync-wave: "-1"
|
||||
argocd.argoproj.io/sync-options: Replace=true
|
||||
spec:
|
||||
ttlSecondsAfterFinished: 300
|
||||
template:
|
||||
spec:
|
||||
serviceAccountName: ocis-secret-init
|
||||
restartPolicy: OnFailure
|
||||
containers:
|
||||
- name: init
|
||||
image: alpine/k8s:1.32.3
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- |
|
||||
set -e
|
||||
|
||||
apk add --no-cache openssl >/dev/null 2>&1
|
||||
|
||||
gen_random() {
|
||||
head -c 32 /dev/urandom | base64 | tr -dc 'a-zA-Z0-9' | head -c "$1"
|
||||
}
|
||||
|
||||
gen_uuid() {
|
||||
cat /proc/sys/kernel/random/uuid
|
||||
}
|
||||
|
||||
create_secret_if_missing() {
|
||||
local name="$1"
|
||||
shift
|
||||
if kubectl get secret "$name" -n "${NAMESPACE}" >/dev/null 2>&1; then
|
||||
echo "Secret $name already exists, skipping"
|
||||
return
|
||||
fi
|
||||
kubectl create secret generic "$name" -n "${NAMESPACE}" "$@"
|
||||
echo "Created secret $name"
|
||||
}
|
||||
|
||||
# Validate external secrets exist
|
||||
if ! kubectl get secret ocis-s3-credentials -n "${NAMESPACE}" >/dev/null 2>&1; then
|
||||
echo "ERROR: External secret ocis-s3-credentials must be created manually"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! kubectl get secret ocis-storagebox-credentials -n "${NAMESPACE}" >/dev/null 2>&1; then
|
||||
echo "ERROR: External secret ocis-storagebox-credentials must be created manually"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Admin user
|
||||
create_secret_if_missing ocis-admin-user \
|
||||
--from-literal=password="$(gen_random 32)" \
|
||||
--from-literal=user-id="$(gen_uuid)"
|
||||
|
||||
# JWT secret
|
||||
create_secret_if_missing ocis-jwt-secret \
|
||||
--from-literal=jwt-secret="$(gen_random 32)"
|
||||
|
||||
# Machine auth API key
|
||||
create_secret_if_missing ocis-machine-auth-api-key \
|
||||
--from-literal=machine-auth-api-key="$(gen_random 32)"
|
||||
|
||||
# Storage system JWT secret
|
||||
create_secret_if_missing ocis-storage-system-jwt-secret \
|
||||
--from-literal=storage-system-jwt-secret="$(gen_random 32)"
|
||||
|
||||
# Storage system secret
|
||||
create_secret_if_missing ocis-storage-system \
|
||||
--from-literal=api-key="$(gen_random 32)" \
|
||||
--from-literal=user-id="$(gen_uuid)"
|
||||
|
||||
# Transfer secret
|
||||
create_secret_if_missing ocis-transfer-secret \
|
||||
--from-literal=transfer-secret="$(gen_random 32)"
|
||||
|
||||
# Thumbnails transfer secret
|
||||
create_secret_if_missing ocis-thumbnails-transfer-secret \
|
||||
--from-literal=thumbnails-transfer-secret="$(gen_random 32)"
|
||||
|
||||
# Service account secret
|
||||
create_secret_if_missing ocis-service-account-secret \
|
||||
--from-literal=service-account-secret="$(gen_random 32)"
|
||||
|
||||
# Collaboration WOPI secret
|
||||
create_secret_if_missing ocis-collaboration-wopi-secret \
|
||||
--from-literal=wopi-secret="$(gen_random 32)"
|
||||
|
||||
# LDAP bind secrets (three passwords for different bind users)
|
||||
create_secret_if_missing ocis-ldap-bind-secrets \
|
||||
--from-literal=reva-ldap-bind-password="$(gen_random 32)" \
|
||||
--from-literal=idp-ldap-bind-password="$(gen_random 32)" \
|
||||
--from-literal=graph-ldap-bind-password="$(gen_random 32)"
|
||||
|
||||
# IDP secret (encryption key + RSA private key)
|
||||
create_secret_if_missing ocis-idp-secrets \
|
||||
--from-literal=encryption.key="$(gen_random 32)" \
|
||||
--from-literal=private-key.pem="$(openssl genrsa 4096 2>/dev/null)"
|
||||
|
||||
# LDAP CA cert + key (self-signed)
|
||||
if ! kubectl get secret ocis-ldap-ca -n "${NAMESPACE}" >/dev/null 2>&1; then
|
||||
openssl req -x509 -newkey rsa:2048 -keyout /tmp/ldap-ca.key -out /tmp/ldap-ca.crt \
|
||||
-days 3650 -nodes -subj "/CN=ldap-ca" 2>/dev/null
|
||||
kubectl create secret generic ocis-ldap-ca -n "${NAMESPACE}" \
|
||||
--from-file=ldap-ca.crt=/tmp/ldap-ca.crt
|
||||
echo "Created secret ocis-ldap-ca"
|
||||
|
||||
# LDAP server cert signed by the CA
|
||||
printf "subjectAltName=DNS:idm" > /tmp/ldap-ext.cnf
|
||||
openssl req -newkey rsa:2048 -keyout /tmp/ldap.key -out /tmp/ldap.csr \
|
||||
-nodes -subj "/CN=idm" -addext "subjectAltName=DNS:idm" 2>/dev/null
|
||||
openssl x509 -req -in /tmp/ldap.csr -CA /tmp/ldap-ca.crt -CAkey /tmp/ldap-ca.key \
|
||||
-CAcreateserial -out /tmp/ldap.crt -days 3650 \
|
||||
-extfile /tmp/ldap-ext.cnf 2>/dev/null
|
||||
kubectl create secret generic ocis-ldap-cert -n "${NAMESPACE}" \
|
||||
--from-file=ldap.crt=/tmp/ldap.crt \
|
||||
--from-file=ldap.key=/tmp/ldap.key
|
||||
echo "Created secret ocis-ldap-cert"
|
||||
rm -f /tmp/ldap-ca.key /tmp/ldap-ca.crt /tmp/ldap.key /tmp/ldap.crt /tmp/ldap.csr /tmp/ldap-ca.srl /tmp/ldap-ext.cnf
|
||||
else
|
||||
echo "Secret ocis-ldap-ca already exists, skipping LDAP certs"
|
||||
fi
|
||||
|
||||
echo "All secrets initialized successfully"
|
||||
env:
|
||||
- name: NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
59
prototypes/ocis/ytt/secret-volume-remap.ytt.yaml
Normal file
59
prototypes/ocis/ytt/secret-volume-remap.ytt.yaml
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
#@ load("@ytt:overlay", "overlay")
|
||||
|
||||
#@ ldap_ca_deployments = ["idp", "graph", "groups", "users"]
|
||||
|
||||
#@ for dep_name in ldap_ca_deployments:
|
||||
#@overlay/match by=overlay.subset({"kind": "Deployment", "metadata": {"name": dep_name}})
|
||||
---
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
volumes:
|
||||
#@overlay/match by=overlay.subset({"secret": {"secretName": "ocis-ldap-ca"}})
|
||||
#@overlay/replace
|
||||
- name: ldap-ca
|
||||
secret:
|
||||
secretName: ocis-ldap-ca-tls
|
||||
items:
|
||||
- key: tls.crt
|
||||
path: ldap-ca.crt
|
||||
#@ end
|
||||
|
||||
#@overlay/match by=overlay.subset({"kind": "Deployment", "metadata": {"name": "idp"}})
|
||||
---
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
volumes:
|
||||
#@overlay/match by=overlay.subset({"secret": {"secretName": "ocis-idp-secrets"}})
|
||||
#@overlay/replace
|
||||
- name: idp-secrets
|
||||
projected:
|
||||
sources:
|
||||
- secret:
|
||||
name: ocis-idp-encryption
|
||||
items:
|
||||
- key: encryption.key
|
||||
path: encryption.key
|
||||
- secret:
|
||||
name: ocis-idp-rsa
|
||||
items:
|
||||
- key: tls.key
|
||||
path: private-key.pem
|
||||
|
||||
#@overlay/match by=overlay.subset({"kind": "Deployment", "metadata": {"name": "idm"}})
|
||||
---
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
volumes:
|
||||
#@overlay/match by=overlay.subset({"secret": {"secretName": "ocis-ldap-cert"}})
|
||||
#@overlay/replace
|
||||
- name: ldap-cert
|
||||
secret:
|
||||
secretName: ocis-ldap-cert-tls
|
||||
items:
|
||||
- key: tls.crt
|
||||
path: ldap.crt
|
||||
- key: tls.key
|
||||
path: ldap.key
|
||||
|
|
@ -2,6 +2,7 @@ apiVersion: argoproj.io/v1alpha1
|
|||
kind: Application
|
||||
metadata:
|
||||
annotations:
|
||||
argocd.argoproj.io/sync-wave: "-10"
|
||||
myks.dev/environment: production
|
||||
finalizers:
|
||||
- resources-finalizer.argocd.argoproj.io
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
annotations:
|
||||
argocd.argoproj.io/sync-wave: "-10"
|
||||
myks.dev/environment: production
|
||||
finalizers:
|
||||
- resources-finalizer.argocd.argoproj.io
|
||||
name: app-production-kubernetes-secret-generator
|
||||
namespace: argocd
|
||||
spec:
|
||||
destination:
|
||||
namespace: kubernetes-secret-generator
|
||||
server: https://kubernetes.default.svc
|
||||
project: env-production
|
||||
source:
|
||||
path: rendered/envs/production/kubernetes-secret-generator
|
||||
repoURL: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
|
||||
targetRevision: main
|
||||
syncPolicy:
|
||||
automated:
|
||||
prune: true
|
||||
selfHeal: true
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
- ServerSideApply=true
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
apiVersion: cert-manager.io/v1
|
||||
kind: ClusterIssuer
|
||||
metadata:
|
||||
annotations:
|
||||
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
|
||||
name: selfsigned
|
||||
namespace: cert-manager
|
||||
spec:
|
||||
selfSigned: {}
|
||||
|
|
@ -13,3 +13,5 @@ rules:
|
|||
verbs:
|
||||
- get
|
||||
- create
|
||||
- patch
|
||||
- update
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ metadata:
|
|||
annotations:
|
||||
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
|
||||
argocd.argoproj.io/sync-options: Replace=true
|
||||
argocd.argoproj.io/sync-wave: "1"
|
||||
name: argocd-deploy-key-init
|
||||
namespace: forgejo
|
||||
spec:
|
||||
|
|
@ -16,8 +17,6 @@ spec:
|
|||
- |
|
||||
set -e
|
||||
|
||||
apk add --no-cache openssh-keygen > /dev/null 2>&1
|
||||
|
||||
ARGOCD_NS="argocd"
|
||||
REPO_SECRET="forgejo-repo"
|
||||
REPO_URL="ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git"
|
||||
|
|
@ -25,6 +24,27 @@ spec:
|
|||
REPO_OWNER="gitea_admin"
|
||||
REPO_NAME="k8s-and-chill"
|
||||
|
||||
# Check if ArgoCD repo secret already exists
|
||||
if kubectl get secret "${REPO_SECRET}" -n "${ARGOCD_NS}" >/dev/null 2>&1; then
|
||||
echo "Secret ${REPO_SECRET} already exists in ${ARGOCD_NS}, skipping"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Wait for mittwald to populate the keypair and admin secrets
|
||||
echo "Waiting for forgejo-repo-keypair to be populated..."
|
||||
for i in $(seq 1 60); do
|
||||
PRIV_B64=$(kubectl get secret forgejo-repo-keypair -n "${NAMESPACE}" -o jsonpath='{.data.ssh-privatekey}' 2>/dev/null || true)
|
||||
PUB_B64=$(kubectl get secret forgejo-repo-keypair -n "${NAMESPACE}" -o jsonpath='{.data.ssh-publickey}' 2>/dev/null || true)
|
||||
if [ -n "${PRIV_B64}" ] && [ -n "${PUB_B64}" ]; then
|
||||
break
|
||||
fi
|
||||
if [ "$i" -eq 60 ]; then
|
||||
echo "forgejo-repo-keypair was not populated in time"
|
||||
exit 1
|
||||
fi
|
||||
sleep 5
|
||||
done
|
||||
|
||||
# Wait for Forgejo to be ready
|
||||
echo "Waiting for Forgejo to be ready..."
|
||||
for i in $(seq 1 60); do
|
||||
|
|
@ -39,22 +59,12 @@ spec:
|
|||
sleep 5
|
||||
done
|
||||
|
||||
# Check if ArgoCD repo secret already exists
|
||||
if kubectl get secret "${REPO_SECRET}" -n "${ARGOCD_NS}" >/dev/null 2>&1; then
|
||||
echo "Secret ${REPO_SECRET} already exists in ${ARGOCD_NS}, skipping"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Read admin credentials
|
||||
ADMIN_USER=$(kubectl get secret forgejo-admin-secret -n "${NAMESPACE}" -o jsonpath='{.data.username}' | base64 -d)
|
||||
ADMIN_PASS=$(kubectl get secret forgejo-admin-secret -n "${NAMESPACE}" -o jsonpath='{.data.password}' | base64 -d)
|
||||
|
||||
# Generate ed25519 SSH keypair
|
||||
KEYDIR=$(mktemp -d)
|
||||
ssh-keygen -t ed25519 -f "${KEYDIR}/id_ed25519" -N "" -q
|
||||
PRIVKEY=$(cat "${KEYDIR}/id_ed25519")
|
||||
PUBKEY=$(cat "${KEYDIR}/id_ed25519.pub")
|
||||
rm -rf "${KEYDIR}"
|
||||
PRIVKEY=$(echo "${PRIV_B64}" | base64 -d)
|
||||
PUBKEY=$(echo "${PUB_B64}" | base64 -d)
|
||||
|
||||
# Register deploy key via Forgejo API
|
||||
echo "Registering deploy key..."
|
||||
|
|
|
|||
|
|
@ -1,36 +0,0 @@
|
|||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
annotations:
|
||||
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
|
||||
argocd.argoproj.io/sync-options: Replace=true
|
||||
name: forgejo-admin-secret-init
|
||||
namespace: forgejo
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- command:
|
||||
- sh
|
||||
- -c
|
||||
- |
|
||||
if kubectl get secret forgejo-admin-secret -n ${NAMESPACE} >/dev/null 2>&1; then
|
||||
echo "Secret already exists, skipping"
|
||||
exit 0
|
||||
fi
|
||||
PASSWORD=$(head -c 32 /dev/urandom | base64 | tr -dc 'a-zA-Z0-9' | head -c 24)
|
||||
kubectl create secret generic forgejo-admin-secret \
|
||||
-n ${NAMESPACE} \
|
||||
--from-literal=username=gitea_admin \
|
||||
--from-literal=password="${PASSWORD}"
|
||||
echo "Created forgejo-admin-secret with random password"
|
||||
env:
|
||||
- name: NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
image: alpine/k8s:1.32.3
|
||||
name: init
|
||||
restartPolicy: OnFailure
|
||||
serviceAccountName: forgejo-admin-secret-init
|
||||
ttlSecondsAfterFinished: 300
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
annotations:
|
||||
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
|
||||
name: forgejo-admin-secret-init
|
||||
namespace: forgejo
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- secrets
|
||||
verbs:
|
||||
- get
|
||||
- create
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
annotations:
|
||||
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
|
||||
name: forgejo-admin-secret-init
|
||||
namespace: forgejo
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: forgejo-admin-secret-init
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: forgejo-admin-secret-init
|
||||
namespace: forgejo
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
annotations:
|
||||
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
|
||||
secret-generator.v1.mittwald.de/autogenerate: password
|
||||
secret-generator.v1.mittwald.de/encoding: hex
|
||||
secret-generator.v1.mittwald.de/length: "24"
|
||||
name: forgejo-admin-secret
|
||||
namespace: forgejo
|
||||
stringData:
|
||||
username: gitea_admin
|
||||
type: Opaque
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
annotations:
|
||||
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
|
||||
secret-generator.v1.mittwald.de/autogenerate: ssh-keypair
|
||||
name: forgejo-repo-keypair
|
||||
namespace: forgejo
|
||||
type: Opaque
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
annotations:
|
||||
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
|
||||
labels:
|
||||
app.kubernetes.io/instance: kubernetes-secret-generator
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/name: kubernetes-secret-generator
|
||||
app.kubernetes.io/version: v3.4.1
|
||||
helm.sh/chart: kubernetes-secret-generator-3.4.1
|
||||
name: kubernetes-secret-generator
|
||||
name: mittwald:kubernetes-secret-generator
|
||||
namespace: kubernetes-secret-generator
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- secrets
|
||||
verbs:
|
||||
- get
|
||||
- create
|
||||
- list
|
||||
- watch
|
||||
- update
|
||||
- apiGroups:
|
||||
- secretgenerator.mittwald.de
|
||||
resources:
|
||||
- basicauths
|
||||
- basicauths/status
|
||||
- sshkeypairs
|
||||
- sshkeypairs/status
|
||||
- stringsecrets
|
||||
- stringsecrets/status
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- update
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
annotations:
|
||||
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
|
||||
labels:
|
||||
app.kubernetes.io/instance: kubernetes-secret-generator
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/name: kubernetes-secret-generator
|
||||
app.kubernetes.io/version: v3.4.1
|
||||
helm.sh/chart: kubernetes-secret-generator-3.4.1
|
||||
name: kubernetes-secret-generator
|
||||
name: mittwald:kubernetes-secret-generator
|
||||
namespace: kubernetes-secret-generator
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: mittwald:kubernetes-secret-generator
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: kubernetes-secret-generator
|
||||
namespace: kubernetes-secret-generator
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
|
||||
name: basicauths.secretgenerator.mittwald.de
|
||||
namespace: kubernetes-secret-generator
|
||||
spec:
|
||||
group: secretgenerator.mittwald.de
|
||||
names:
|
||||
kind: BasicAuth
|
||||
listKind: BasicAuthList
|
||||
plural: basicauths
|
||||
singular: basicauth
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- name: v1alpha1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: BasicAuth is the Schema for the basicauths API
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: BasicAuthSpec defines the desired state of BasicAuth
|
||||
properties:
|
||||
data:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
encoding:
|
||||
type: string
|
||||
forceRegenerate:
|
||||
type: boolean
|
||||
length:
|
||||
type: string
|
||||
username:
|
||||
type: string
|
||||
required:
|
||||
- username
|
||||
type: object
|
||||
status:
|
||||
description: BasicAuthStatus defines the observed state of BasicAuth
|
||||
properties:
|
||||
secret:
|
||||
description: ObjectReference contains enough information to let you inspect or modify the referred object.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
fieldPath:
|
||||
description: 'If referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. For example, if the object reference is to a container within a pod, this would take on a value like: "spec.containers{name}" (where "name" refers to the name of the container that triggered the event) or if no container name is specified "spec.containers[2]" (container with index 2 in this pod). This syntax is chosen only to have some well-defined way of referencing a part of an object. TODO: this design is not final and this field is subject to change in the future.'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
name:
|
||||
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
|
||||
type: string
|
||||
namespace:
|
||||
description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
|
||||
type: string
|
||||
resourceVersion:
|
||||
description: 'Specific resourceVersion to which this reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
|
||||
type: string
|
||||
uid:
|
||||
description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
|
||||
name: sshkeypairs.secretgenerator.mittwald.de
|
||||
namespace: kubernetes-secret-generator
|
||||
spec:
|
||||
group: secretgenerator.mittwald.de
|
||||
names:
|
||||
kind: SSHKeyPair
|
||||
listKind: SSHKeyPairList
|
||||
plural: sshkeypairs
|
||||
singular: sshkeypair
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- name: v1alpha1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: SSHKeyPair is the Schema for the sshkeypairs API
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: SSHKeyPairSpec defines the desired state of SSHKeyPair
|
||||
properties:
|
||||
data:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
forceRegenerate:
|
||||
type: boolean
|
||||
length:
|
||||
type: string
|
||||
privateKey:
|
||||
type: string
|
||||
type:
|
||||
type: string
|
||||
type: object
|
||||
status:
|
||||
description: SSHKeyPairStatus defines the observed state of SSHKeyPair
|
||||
properties:
|
||||
secret:
|
||||
description: 'INSERT ADDITIONAL STATUS FIELD - define observed state of cluster Important: Run "operator-sdk generate k8s" to regenerate code after modifying this file Add custom validation using kubebuilder tags: https://book-v1.book.kubebuilder.io/beyond_basics/generating_crd.html'
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
fieldPath:
|
||||
description: 'If referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. For example, if the object reference is to a container within a pod, this would take on a value like: "spec.containers{name}" (where "name" refers to the name of the container that triggered the event) or if no container name is specified "spec.containers[2]" (container with index 2 in this pod). This syntax is chosen only to have some well-defined way of referencing a part of an object. TODO: this design is not final and this field is subject to change in the future.'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
name:
|
||||
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
|
||||
type: string
|
||||
namespace:
|
||||
description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
|
||||
type: string
|
||||
resourceVersion:
|
||||
description: 'Specific resourceVersion to which this reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
|
||||
type: string
|
||||
uid:
|
||||
description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
|
||||
name: stringsecrets.secretgenerator.mittwald.de
|
||||
namespace: kubernetes-secret-generator
|
||||
spec:
|
||||
group: secretgenerator.mittwald.de
|
||||
names:
|
||||
kind: StringSecret
|
||||
listKind: StringSecretList
|
||||
plural: stringsecrets
|
||||
singular: stringsecret
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- name: v1alpha1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: StringSecret is the Schema for the stringsecrets API
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: StringSecretSpec defines the desired state of StringSecret
|
||||
properties:
|
||||
data:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
fields:
|
||||
items:
|
||||
properties:
|
||||
encoding:
|
||||
type: string
|
||||
fieldName:
|
||||
type: string
|
||||
length:
|
||||
type: string
|
||||
type: object
|
||||
type: array
|
||||
forceRegenerate:
|
||||
type: boolean
|
||||
type:
|
||||
type: string
|
||||
required:
|
||||
- fields
|
||||
type: object
|
||||
status:
|
||||
description: StringSecretStatus defines the observed state of StringSecret
|
||||
properties:
|
||||
secret:
|
||||
description: ObjectReference contains enough information to let you inspect or modify the referred object.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
fieldPath:
|
||||
description: 'If referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. For example, if the object reference is to a container within a pod, this would take on a value like: "spec.containers{name}" (where "name" refers to the name of the container that triggered the event) or if no container name is specified "spec.containers[2]" (container with index 2 in this pod). This syntax is chosen only to have some well-defined way of referencing a part of an object. TODO: this design is not final and this field is subject to change in the future.'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
name:
|
||||
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
|
||||
type: string
|
||||
namespace:
|
||||
description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
|
||||
type: string
|
||||
resourceVersion:
|
||||
description: 'Specific resourceVersion to which this reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
|
||||
type: string
|
||||
uid:
|
||||
description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
annotations:
|
||||
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
|
||||
labels:
|
||||
app.kubernetes.io/instance: kubernetes-secret-generator
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/name: kubernetes-secret-generator
|
||||
app.kubernetes.io/version: v3.4.1
|
||||
helm.sh/chart: kubernetes-secret-generator-3.4.1
|
||||
name: kubernetes-secret-generator
|
||||
name: kubernetes-secret-generator
|
||||
namespace: kubernetes-secret-generator
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/instance: kubernetes-secret-generator
|
||||
app.kubernetes.io/name: kubernetes-secret-generator
|
||||
name: kubernetes-secret-generator
|
||||
strategy:
|
||||
type: Recreate
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/instance: kubernetes-secret-generator
|
||||
app.kubernetes.io/name: kubernetes-secret-generator
|
||||
name: kubernetes-secret-generator
|
||||
spec:
|
||||
automountServiceAccountToken: null
|
||||
containers:
|
||||
- args: []
|
||||
env:
|
||||
- name: WATCH_NAMESPACE
|
||||
value: null
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
- name: OPERATOR_NAME
|
||||
value: kubernetes-secret-generator
|
||||
- name: REGENERATE_INSECURE
|
||||
value: "false"
|
||||
- name: SECRET_LENGTH
|
||||
value: "40"
|
||||
- name: USE_METRICS_SERVICE
|
||||
value: "false"
|
||||
image: quay.io/mittwald/kubernetes-secret-generator:v3.4.1
|
||||
imagePullPolicy: Always
|
||||
livenessProbe:
|
||||
failureThreshold: 3
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: healthcheck
|
||||
initialDelaySeconds: 6
|
||||
periodSeconds: 3
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
name: kubernetes-secret-generator
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
name: healthcheck
|
||||
readinessProbe:
|
||||
failureThreshold: 3
|
||||
httpGet:
|
||||
path: /readyz
|
||||
port: healthcheck
|
||||
initialDelaySeconds: 6
|
||||
periodSeconds: 3
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 1
|
||||
resources:
|
||||
limits:
|
||||
memory: 128Mi
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 32Mi
|
||||
securityContext: {}
|
||||
volumeMounts: []
|
||||
securityContext: {}
|
||||
serviceAccountName: kubernetes-secret-generator
|
||||
volumes: []
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
kind: Namespace
|
||||
metadata:
|
||||
annotations:
|
||||
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
|
||||
name: forgejo-admin-secret-init
|
||||
namespace: forgejo
|
||||
name: kubernetes-secret-generator
|
||||
namespace: kubernetes-secret-generator
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
annotations:
|
||||
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
|
||||
labels:
|
||||
app.kubernetes.io/instance: kubernetes-secret-generator
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/name: kubernetes-secret-generator
|
||||
app.kubernetes.io/version: v3.4.1
|
||||
helm.sh/chart: kubernetes-secret-generator-3.4.1
|
||||
name: kubernetes-secret-generator
|
||||
name: mittwald:kubernetes-secret-generator
|
||||
namespace: kubernetes-secret-generator
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- configmaps
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods
|
||||
verbs:
|
||||
- delete
|
||||
- get
|
||||
- apiGroups:
|
||||
- monitoring.coreos.com
|
||||
resources:
|
||||
- servicemonitors
|
||||
verbs:
|
||||
- get
|
||||
- create
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
annotations:
|
||||
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
|
||||
labels:
|
||||
app.kubernetes.io/instance: kubernetes-secret-generator
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/name: kubernetes-secret-generator
|
||||
app.kubernetes.io/version: v3.4.1
|
||||
helm.sh/chart: kubernetes-secret-generator-3.4.1
|
||||
name: kubernetes-secret-generator
|
||||
name: mittwald:kubernetes-secret-generator
|
||||
namespace: kubernetes-secret-generator
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: mittwald:kubernetes-secret-generator
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: kubernetes-secret-generator
|
||||
namespace: kubernetes-secret-generator
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
apiVersion: v1
|
||||
automountServiceAccountToken: null
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
annotations:
|
||||
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
|
||||
labels:
|
||||
app.kubernetes.io/instance: kubernetes-secret-generator
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/name: kubernetes-secret-generator
|
||||
app.kubernetes.io/version: v3.4.1
|
||||
helm.sh/chart: kubernetes-secret-generator-3.4.1
|
||||
name: kubernetes-secret-generator
|
||||
name: kubernetes-secret-generator
|
||||
namespace: kubernetes-secret-generator
|
||||
18
rendered/envs/production/ocis/certificate-ocis-idp-rsa.yaml
Normal file
18
rendered/envs/production/ocis/certificate-ocis-idp-rsa.yaml
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
apiVersion: cert-manager.io/v1
|
||||
kind: Certificate
|
||||
metadata:
|
||||
annotations:
|
||||
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
|
||||
name: ocis-idp-rsa
|
||||
namespace: ocis
|
||||
spec:
|
||||
commonName: ocis-idp
|
||||
duration: 87600h
|
||||
issuerRef:
|
||||
kind: ClusterIssuer
|
||||
name: selfsigned
|
||||
privateKey:
|
||||
algorithm: RSA
|
||||
size: 4096
|
||||
renewBefore: 720h
|
||||
secretName: ocis-idp-rsa
|
||||
19
rendered/envs/production/ocis/certificate-ocis-ldap-ca.yaml
Normal file
19
rendered/envs/production/ocis/certificate-ocis-ldap-ca.yaml
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
apiVersion: cert-manager.io/v1
|
||||
kind: Certificate
|
||||
metadata:
|
||||
annotations:
|
||||
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
|
||||
name: ocis-ldap-ca
|
||||
namespace: ocis
|
||||
spec:
|
||||
commonName: ocis-ldap-ca
|
||||
duration: 87600h
|
||||
isCA: true
|
||||
issuerRef:
|
||||
kind: ClusterIssuer
|
||||
name: selfsigned
|
||||
privateKey:
|
||||
algorithm: RSA
|
||||
size: 2048
|
||||
renewBefore: 720h
|
||||
secretName: ocis-ldap-ca-tls
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
apiVersion: cert-manager.io/v1
|
||||
kind: Certificate
|
||||
metadata:
|
||||
annotations:
|
||||
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
|
||||
name: ocis-ldap-cert
|
||||
namespace: ocis
|
||||
spec:
|
||||
commonName: idm
|
||||
dnsNames:
|
||||
- idm
|
||||
duration: 87600h
|
||||
issuerRef:
|
||||
kind: Issuer
|
||||
name: ocis-ldap-ca
|
||||
privateKey:
|
||||
algorithm: RSA
|
||||
size: 2048
|
||||
renewBefore: 720h
|
||||
secretName: ocis-ldap-cert-tls
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
apiVersion: v1
|
||||
data:
|
||||
service-account-id: dc1bcd59-afe8-432c-b2c6-bd56fff10cbb
|
||||
service-account-id: af9235cc-560a-4135-8d16-788aa729b35f
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
annotations:
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
apiVersion: v1
|
||||
data:
|
||||
application-id: 91d502c3-d090-49a2-989e-7c8e690751d1
|
||||
application-id: 105ef2f0-3450-491e-9df3-9d3567f2377c
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
annotations:
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
apiVersion: v1
|
||||
data:
|
||||
storage-uuid: cf2b3372-ac52-4654-99ae-cf6518b7a75b
|
||||
storage-uuid: aa2eff14-4594-407b-b06b-aaf7e22a95d1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
annotations:
|
||||
|
|
|
|||
|
|
@ -152,4 +152,7 @@ spec:
|
|||
name: messaging-system-ca
|
||||
- name: ldap-ca
|
||||
secret:
|
||||
secretName: ocis-ldap-ca
|
||||
items:
|
||||
- key: tls.crt
|
||||
path: ldap-ca.crt
|
||||
secretName: ocis-ldap-ca-tls
|
||||
|
|
|
|||
|
|
@ -118,4 +118,7 @@ spec:
|
|||
name: tmp-volume
|
||||
- name: ldap-ca
|
||||
secret:
|
||||
secretName: ocis-ldap-ca
|
||||
items:
|
||||
- key: tls.crt
|
||||
path: ldap-ca.crt
|
||||
secretName: ocis-ldap-ca-tls
|
||||
|
|
|
|||
|
|
@ -150,7 +150,12 @@ spec:
|
|||
volumes:
|
||||
- name: ldap-cert
|
||||
secret:
|
||||
secretName: ocis-ldap-cert
|
||||
items:
|
||||
- key: tls.crt
|
||||
path: ldap.crt
|
||||
- key: tls.key
|
||||
path: ldap.key
|
||||
secretName: ocis-ldap-cert-tls
|
||||
- name: idm-data
|
||||
persistentVolumeClaim:
|
||||
claimName: idm-data
|
||||
|
|
|
|||
|
|
@ -118,7 +118,20 @@ spec:
|
|||
name: ocis-data-tmp
|
||||
- name: ldap-ca
|
||||
secret:
|
||||
secretName: ocis-ldap-ca
|
||||
items:
|
||||
- key: tls.crt
|
||||
path: ldap-ca.crt
|
||||
secretName: ocis-ldap-ca-tls
|
||||
- name: idp-secrets
|
||||
secret:
|
||||
secretName: ocis-idp-secrets
|
||||
projected:
|
||||
sources:
|
||||
- secret:
|
||||
items:
|
||||
- key: encryption.key
|
||||
path: encryption.key
|
||||
name: ocis-idp-encryption
|
||||
- secret:
|
||||
items:
|
||||
- key: tls.key
|
||||
path: private-key.pem
|
||||
name: ocis-idp-rsa
|
||||
|
|
|
|||
|
|
@ -118,4 +118,7 @@ spec:
|
|||
name: tmp-volume
|
||||
- name: ldap-ca
|
||||
secret:
|
||||
secretName: ocis-ldap-ca
|
||||
items:
|
||||
- key: tls.crt
|
||||
path: ldap-ca.crt
|
||||
secretName: ocis-ldap-ca-tls
|
||||
|
|
|
|||
10
rendered/envs/production/ocis/issuer-ocis-ldap-ca.yaml
Normal file
10
rendered/envs/production/ocis/issuer-ocis-ldap-ca.yaml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
apiVersion: cert-manager.io/v1
|
||||
kind: Issuer
|
||||
metadata:
|
||||
annotations:
|
||||
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
|
||||
name: ocis-ldap-ca
|
||||
namespace: ocis
|
||||
spec:
|
||||
ca:
|
||||
secretName: ocis-ldap-ca-tls
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
annotations:
|
||||
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
|
||||
argocd.argoproj.io/hook: PreSync
|
||||
argocd.argoproj.io/sync-options: Replace=true
|
||||
argocd.argoproj.io/sync-wave: "-1"
|
||||
name: ocis-external-secret-precheck
|
||||
namespace: ocis
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- command:
|
||||
- sh
|
||||
- -c
|
||||
- |
|
||||
set -e
|
||||
for s in ocis-s3-credentials ocis-storagebox-credentials; do
|
||||
if ! kubectl get secret "$s" -n "${NAMESPACE}" >/dev/null 2>&1; then
|
||||
echo "ERROR: External secret $s must be created manually before deploying ocis"
|
||||
exit 1
|
||||
fi
|
||||
echo "OK: $s exists"
|
||||
done
|
||||
env:
|
||||
- name: NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
image: alpine/k8s:1.32.3
|
||||
name: precheck
|
||||
restartPolicy: OnFailure
|
||||
serviceAccountName: ocis-external-secret-precheck
|
||||
ttlSecondsAfterFinished: 300
|
||||
|
|
@ -1,136 +0,0 @@
|
|||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
annotations:
|
||||
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
|
||||
argocd.argoproj.io/hook: PreSync
|
||||
argocd.argoproj.io/sync-options: Replace=true
|
||||
argocd.argoproj.io/sync-wave: "-1"
|
||||
name: ocis-secret-init
|
||||
namespace: ocis
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- command:
|
||||
- sh
|
||||
- -c
|
||||
- |
|
||||
set -e
|
||||
|
||||
apk add --no-cache openssl >/dev/null 2>&1
|
||||
|
||||
gen_random() {
|
||||
head -c 32 /dev/urandom | base64 | tr -dc 'a-zA-Z0-9' | head -c "$1"
|
||||
}
|
||||
|
||||
gen_uuid() {
|
||||
cat /proc/sys/kernel/random/uuid
|
||||
}
|
||||
|
||||
create_secret_if_missing() {
|
||||
local name="$1"
|
||||
shift
|
||||
if kubectl get secret "$name" -n "${NAMESPACE}" >/dev/null 2>&1; then
|
||||
echo "Secret $name already exists, skipping"
|
||||
return
|
||||
fi
|
||||
kubectl create secret generic "$name" -n "${NAMESPACE}" "$@"
|
||||
echo "Created secret $name"
|
||||
}
|
||||
|
||||
# Validate external secrets exist
|
||||
if ! kubectl get secret ocis-s3-credentials -n "${NAMESPACE}" >/dev/null 2>&1; then
|
||||
echo "ERROR: External secret ocis-s3-credentials must be created manually"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! kubectl get secret ocis-storagebox-credentials -n "${NAMESPACE}" >/dev/null 2>&1; then
|
||||
echo "ERROR: External secret ocis-storagebox-credentials must be created manually"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Admin user
|
||||
create_secret_if_missing ocis-admin-user \
|
||||
--from-literal=password="$(gen_random 32)" \
|
||||
--from-literal=user-id="$(gen_uuid)"
|
||||
|
||||
# JWT secret
|
||||
create_secret_if_missing ocis-jwt-secret \
|
||||
--from-literal=jwt-secret="$(gen_random 32)"
|
||||
|
||||
# Machine auth API key
|
||||
create_secret_if_missing ocis-machine-auth-api-key \
|
||||
--from-literal=machine-auth-api-key="$(gen_random 32)"
|
||||
|
||||
# Storage system JWT secret
|
||||
create_secret_if_missing ocis-storage-system-jwt-secret \
|
||||
--from-literal=storage-system-jwt-secret="$(gen_random 32)"
|
||||
|
||||
# Storage system secret
|
||||
create_secret_if_missing ocis-storage-system \
|
||||
--from-literal=api-key="$(gen_random 32)" \
|
||||
--from-literal=user-id="$(gen_uuid)"
|
||||
|
||||
# Transfer secret
|
||||
create_secret_if_missing ocis-transfer-secret \
|
||||
--from-literal=transfer-secret="$(gen_random 32)"
|
||||
|
||||
# Thumbnails transfer secret
|
||||
create_secret_if_missing ocis-thumbnails-transfer-secret \
|
||||
--from-literal=thumbnails-transfer-secret="$(gen_random 32)"
|
||||
|
||||
# Service account secret
|
||||
create_secret_if_missing ocis-service-account-secret \
|
||||
--from-literal=service-account-secret="$(gen_random 32)"
|
||||
|
||||
# Collaboration WOPI secret
|
||||
create_secret_if_missing ocis-collaboration-wopi-secret \
|
||||
--from-literal=wopi-secret="$(gen_random 32)"
|
||||
|
||||
# LDAP bind secrets (three passwords for different bind users)
|
||||
create_secret_if_missing ocis-ldap-bind-secrets \
|
||||
--from-literal=reva-ldap-bind-password="$(gen_random 32)" \
|
||||
--from-literal=idp-ldap-bind-password="$(gen_random 32)" \
|
||||
--from-literal=graph-ldap-bind-password="$(gen_random 32)"
|
||||
|
||||
# IDP secret (encryption key + RSA private key)
|
||||
create_secret_if_missing ocis-idp-secrets \
|
||||
--from-literal=encryption.key="$(gen_random 32)" \
|
||||
--from-literal=private-key.pem="$(openssl genrsa 4096 2>/dev/null)"
|
||||
|
||||
# LDAP CA cert + key (self-signed)
|
||||
if ! kubectl get secret ocis-ldap-ca -n "${NAMESPACE}" >/dev/null 2>&1; then
|
||||
openssl req -x509 -newkey rsa:2048 -keyout /tmp/ldap-ca.key -out /tmp/ldap-ca.crt \
|
||||
-days 3650 -nodes -subj "/CN=ldap-ca" 2>/dev/null
|
||||
kubectl create secret generic ocis-ldap-ca -n "${NAMESPACE}" \
|
||||
--from-file=ldap-ca.crt=/tmp/ldap-ca.crt
|
||||
echo "Created secret ocis-ldap-ca"
|
||||
|
||||
# LDAP server cert signed by the CA
|
||||
printf "subjectAltName=DNS:idm" > /tmp/ldap-ext.cnf
|
||||
openssl req -newkey rsa:2048 -keyout /tmp/ldap.key -out /tmp/ldap.csr \
|
||||
-nodes -subj "/CN=idm" -addext "subjectAltName=DNS:idm" 2>/dev/null
|
||||
openssl x509 -req -in /tmp/ldap.csr -CA /tmp/ldap-ca.crt -CAkey /tmp/ldap-ca.key \
|
||||
-CAcreateserial -out /tmp/ldap.crt -days 3650 \
|
||||
-extfile /tmp/ldap-ext.cnf 2>/dev/null
|
||||
kubectl create secret generic ocis-ldap-cert -n "${NAMESPACE}" \
|
||||
--from-file=ldap.crt=/tmp/ldap.crt \
|
||||
--from-file=ldap.key=/tmp/ldap.key
|
||||
echo "Created secret ocis-ldap-cert"
|
||||
rm -f /tmp/ldap-ca.key /tmp/ldap-ca.crt /tmp/ldap.key /tmp/ldap.crt /tmp/ldap.csr /tmp/ldap-ca.srl /tmp/ldap-ext.cnf
|
||||
else
|
||||
echo "Secret ocis-ldap-ca already exists, skipping LDAP certs"
|
||||
fi
|
||||
|
||||
echo "All secrets initialized successfully"
|
||||
env:
|
||||
- name: NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
image: alpine/k8s:1.32.3
|
||||
name: init
|
||||
restartPolicy: OnFailure
|
||||
serviceAccountName: ocis-secret-init
|
||||
ttlSecondsAfterFinished: 300
|
||||
|
|
@ -5,7 +5,7 @@ metadata:
|
|||
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
|
||||
argocd.argoproj.io/hook: PreSync
|
||||
argocd.argoproj.io/sync-wave: "-2"
|
||||
name: ocis-secret-init
|
||||
name: ocis-external-secret-precheck
|
||||
namespace: ocis
|
||||
rules:
|
||||
- apiGroups:
|
||||
|
|
@ -14,4 +14,3 @@ rules:
|
|||
- secrets
|
||||
verbs:
|
||||
- get
|
||||
- create
|
||||
|
|
@ -5,13 +5,13 @@ metadata:
|
|||
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
|
||||
argocd.argoproj.io/hook: PreSync
|
||||
argocd.argoproj.io/sync-wave: "-2"
|
||||
name: ocis-secret-init
|
||||
name: ocis-external-secret-precheck
|
||||
namespace: ocis
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: ocis-secret-init
|
||||
name: ocis-external-secret-precheck
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: ocis-secret-init
|
||||
name: ocis-external-secret-precheck
|
||||
namespace: ocis
|
||||
10
rendered/envs/production/ocis/secret-ocis-admin-user.yaml
Normal file
10
rendered/envs/production/ocis/secret-ocis-admin-user.yaml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
annotations:
|
||||
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
|
||||
secret-generator.v1.mittwald.de/autogenerate: password,user-id
|
||||
secret-generator.v1.mittwald.de/length: "32"
|
||||
name: ocis-admin-user
|
||||
namespace: ocis
|
||||
type: Opaque
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
annotations:
|
||||
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
|
||||
secret-generator.v1.mittwald.de/autogenerate: wopi-secret
|
||||
secret-generator.v1.mittwald.de/length: "32"
|
||||
name: ocis-collaboration-wopi-secret
|
||||
namespace: ocis
|
||||
type: Opaque
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
annotations:
|
||||
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
|
||||
secret-generator.v1.mittwald.de/autogenerate: encryption.key
|
||||
secret-generator.v1.mittwald.de/length: "32"
|
||||
name: ocis-idp-encryption
|
||||
namespace: ocis
|
||||
type: Opaque
|
||||
10
rendered/envs/production/ocis/secret-ocis-jwt-secret.yaml
Normal file
10
rendered/envs/production/ocis/secret-ocis-jwt-secret.yaml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
annotations:
|
||||
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
|
||||
secret-generator.v1.mittwald.de/autogenerate: jwt-secret
|
||||
secret-generator.v1.mittwald.de/length: "32"
|
||||
name: ocis-jwt-secret
|
||||
namespace: ocis
|
||||
type: Opaque
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
annotations:
|
||||
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
|
||||
secret-generator.v1.mittwald.de/autogenerate: reva-ldap-bind-password,idp-ldap-bind-password,graph-ldap-bind-password
|
||||
secret-generator.v1.mittwald.de/length: "32"
|
||||
name: ocis-ldap-bind-secrets
|
||||
namespace: ocis
|
||||
type: Opaque
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
annotations:
|
||||
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
|
||||
secret-generator.v1.mittwald.de/autogenerate: machine-auth-api-key
|
||||
secret-generator.v1.mittwald.de/length: "32"
|
||||
name: ocis-machine-auth-api-key
|
||||
namespace: ocis
|
||||
type: Opaque
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
annotations:
|
||||
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
|
||||
secret-generator.v1.mittwald.de/autogenerate: service-account-secret
|
||||
secret-generator.v1.mittwald.de/length: "32"
|
||||
name: ocis-service-account-secret
|
||||
namespace: ocis
|
||||
type: Opaque
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
annotations:
|
||||
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
|
||||
secret-generator.v1.mittwald.de/autogenerate: storage-system-jwt-secret
|
||||
secret-generator.v1.mittwald.de/length: "32"
|
||||
name: ocis-storage-system-jwt-secret
|
||||
namespace: ocis
|
||||
type: Opaque
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
annotations:
|
||||
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
|
||||
secret-generator.v1.mittwald.de/autogenerate: api-key,user-id
|
||||
secret-generator.v1.mittwald.de/length: "32"
|
||||
name: ocis-storage-system
|
||||
namespace: ocis
|
||||
type: Opaque
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
annotations:
|
||||
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
|
||||
secret-generator.v1.mittwald.de/autogenerate: thumbnails-transfer-secret
|
||||
secret-generator.v1.mittwald.de/length: "32"
|
||||
name: ocis-thumbnails-transfer-secret
|
||||
namespace: ocis
|
||||
type: Opaque
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
annotations:
|
||||
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
|
||||
secret-generator.v1.mittwald.de/autogenerate: transfer-secret
|
||||
secret-generator.v1.mittwald.de/length: "32"
|
||||
name: ocis-transfer-secret
|
||||
namespace: ocis
|
||||
type: Opaque
|
||||
|
|
@ -5,5 +5,5 @@ metadata:
|
|||
a8r.io/repository: ssh://git@git.tr1ceracop.de:222/gitea_admin/k8s-and-chill.git
|
||||
argocd.argoproj.io/hook: PreSync
|
||||
argocd.argoproj.io/sync-wave: "-2"
|
||||
name: ocis-secret-init
|
||||
name: ocis-external-secret-precheck
|
||||
namespace: ocis
|
||||
Loading…
Reference in a new issue