diff --git a/kube/clusters/biohazard/flux/kustomization.yaml b/kube/clusters/biohazard/flux/kustomization.yaml index c811569c4d..d9cba66fa5 100644 --- a/kube/clusters/biohazard/flux/kustomization.yaml +++ b/kube/clusters/biohazard/flux/kustomization.yaml @@ -126,6 +126,7 @@ resources: - ../../../deploy/apps/goatcounter/ - ../../../deploy/apps/ollama/ - ../../../deploy/apps/davis/ + - ../../../deploy/apps/radicale/ - ../../../deploy/apps/immich/ - ../../../deploy/apps/kromgo/ - ../../../deploy/apps/komga/ diff --git a/kube/deploy/apps/radicale/app/es.yaml b/kube/deploy/apps/radicale/app/es.yaml new file mode 100644 index 0000000000..793d36880d --- /dev/null +++ b/kube/deploy/apps/radicale/app/es.yaml @@ -0,0 +1,52 @@ +--- +# yaml-language-server: $schema=https://crds.jank.ing/external-secrets.io/externalsecret_v1beta1.json +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: &name radicale-secrets + namespace: radicale +spec: + refreshInterval: 1m + secretStoreRef: + kind: ClusterSecretStore + name: 1p + dataFrom: + - extract: + key: "radicale - ${CLUSTER_NAME}" + target: + creationPolicy: Owner + deletionPolicy: Retain + name: *name + template: + type: Opaque + data: + config: | + [server] + hosts = 0.0.0.0:8080 + ssl = False + [encoding] + request = utf-8 + stock = utf-8 + [auth] + type = radicale_auth_ldap + realm = Radicale - Password Required + ldap_url = ldaps://{{ .APP_DNS_AUTHENTIK_LDAP }}:636 + ldap_base = ou=users,dc=ldap,dc=goauthentik,dc=io + ldap_attribute = cn + ldap_filter = (memberOf=cn=Role-Radicale-Auth,ou=groups,dc=ldap,dc=goauthentik,dc=io) + ldap_binddn = CN=radicale-ldap,OU=service-accounts,OU=goauthentik.io,DC=ldap,DC=goauthentik,DC=io + ldap_password = {{ .LDAP_PASSWORD }} + ldap_scope = SUBTREE + [rights] + type = owner_only + [storage] + type = multifilesystem + filesystem_folder = /data/collections + hook = ([ -d .git ] || git init) && git add -A && (git diff --cached --quiet || git commit -m "changes by "%(user)s) + [web] + type = internal + [logging] + level = debug + mask_passwords = True + [headers] + diff --git a/kube/deploy/apps/radicale/app/hr.yaml b/kube/deploy/apps/radicale/app/hr.yaml new file mode 100644 index 0000000000..bdee3df0d1 --- /dev/null +++ b/kube/deploy/apps/radicale/app/hr.yaml @@ -0,0 +1,117 @@ +--- +apiVersion: helm.toolkit.fluxcd.io/v2beta2 +kind: HelmRelease +metadata: + name: &app radicale + namespace: *app +spec: + interval: 5m + chart: + spec: + chart: app-template + version: 3.1.0 + sourceRef: + name: bjw-s + kind: HelmRepository + namespace: flux-system + values: + controllers: + radicale: + type: deployment + replicas: 1 + pod: + labels: + ingress.home.arpa/nginx-internal: allow + authentik.home.arpa/ldap: allow + containers: + main: + image: &img + repository: jank.ing/jjgadgets/radicale + tag: 3.2.2@sha256:973e80ba840319b5b0543f7f77235e793c5a065dee7e081efe22d9e0bd5776ce + env: &env + TZ: "${CONFIG_TZ}" + securityContext: &sc + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + capabilities: + drop: ["ALL"] + resources: + requests: + cpu: "10m" + memory: "128Mi" + limits: + cpu: "3000m" + memory: "1Gi" + probes: + liveness: + enabled: true + readiness: + enabled: true + service: + radicale: + controller: radicale + ports: + http: + port: 8080 + protocol: HTTP + appProtocol: http + ingress: + main: + className: nginx-internal + hosts: + - host: &host "${APP_DNS_RADICALE:=RADICALE}" + paths: &paths + - path: / + pathType: Prefix + service: + identifier: radicale + port: http + tls: + - hosts: [*host] + persistence: + config: + type: secret + name: radicale-secrets + globalMounts: + - subPath: config + path: /config/config + data: + existingClaim: radicale-data + globalMounts: + - subPath: data + path: /data + tmp: + type: emptyDir + medium: Memory + globalMounts: + - subPath: tmp + path: /tmp + defaultPodOptions: + automountServiceAccountToken: false + enableServiceLinks: false + hostAliases: + - ip: "${APP_IP_AUTHENTIK:=127.0.0.1}" + hostnames: ["${APP_DNS_AUTHENTIK:=authentik}"] + - ip: "${APP_IP_AUTHENTIK_LDAP:=127.0.0.1}" + hostnames: ["${APP_DNS_AUTHENTIK_LDAP:=authentik}"] + securityContext: + runAsNonRoot: true + runAsUser: &uid ${APP_UID_RADICALE:=1000} + runAsGroup: *uid + fsGroup: *uid + fsGroupChangePolicy: Always + seccompProfile: { type: "RuntimeDefault" } + topologySpreadConstraints: + - maxSkew: 1 + topologyKey: kubernetes.io/hostname + whenUnsatisfiable: DoNotSchedule + labelSelector: + matchLabels: + app.kubernetes.io/name: *app + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: fuckoff.home.arpa/radicale + operator: DoesNotExist diff --git a/kube/deploy/apps/radicale/ks.yaml b/kube/deploy/apps/radicale/ks.yaml new file mode 100644 index 0000000000..5d180562fe --- /dev/null +++ b/kube/deploy/apps/radicale/ks.yaml @@ -0,0 +1,45 @@ +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: radicale-app + namespace: flux-system + labels: &l + app.kubernetes.io/name: "radicale" +spec: + commonMetadata: + labels: *l + path: ./kube/deploy/apps/radicale/app + targetNamespace: "radicale" + dependsOn: + - name: radicale-pvc +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: radicale-pvc + namespace: flux-system + labels: &l + app.kubernetes.io/name: "radicale" +spec: + commonMetadata: + labels: *l + path: ./kube/deploy/core/storage/volsync/template + targetNamespace: "radicale" + dependsOn: + - name: 1-core-storage-volsync-app + - name: 1-core-storage-snapscheduler-app + - name: 1-core-storage-rook-ceph-cluster + postBuild: + substitute: + PVC: "radicale-data" + SIZE: "10Gi" + SC: &sc "file" + SNAP: *sc + ACCESSMODE: "ReadWriteMany" + RUID: !!str &uid | + ${APP_UID_RADICALE:=1000} + RGID: !!str | + ${APP_UID_RADICALE:=1000} + RFSG: !!str | + ${APP_UID_RADICALE:=1000} diff --git a/kube/deploy/apps/radicale/kustomization.yaml b/kube/deploy/apps/radicale/kustomization.yaml new file mode 100644 index 0000000000..5eeb2657b6 --- /dev/null +++ b/kube/deploy/apps/radicale/kustomization.yaml @@ -0,0 +1,6 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - ns.yaml + - ks.yaml diff --git a/kube/deploy/apps/radicale/ns.yaml b/kube/deploy/apps/radicale/ns.yaml new file mode 100644 index 0000000000..97fb0d5de2 --- /dev/null +++ b/kube/deploy/apps/radicale/ns.yaml @@ -0,0 +1,10 @@ +--- +apiVersion: v1 +kind: Namespace +metadata: + name: radicale + labels: + kustomize.toolkit.fluxcd.io/prune: disabled + pod-security.kubernetes.io/enforce: &ps restricted + pod-security.kubernetes.io/audit: *ps + pod-security.kubernetes.io/warn: *ps