diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f394bfb --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +# Helm chart dependencies (packaged library charts) +# These are generated by 'helm dependency update' and should not be committed +**/charts/*.tgz +charts/*.tgz + +**/Chart.lock diff --git a/apps/charts/audiobookshelf/Chart.lock b/apps/charts/audiobookshelf/Chart.lock new file mode 100644 index 0000000..0b66763 --- /dev/null +++ b/apps/charts/audiobookshelf/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: common + repository: file://../common + version: 1.0.0 +digest: sha256:07cebde439abe4ba19bb28e844b7419dab83c7f613886416aaf3ec08e8059144 +generated: "2026-01-01T12:59:49.454842+01:00" diff --git a/apps/charts/audiobookshelf/Chart.yaml b/apps/charts/audiobookshelf/Chart.yaml index b6db4d9..dda1777 100644 --- a/apps/charts/audiobookshelf/Chart.yaml +++ b/apps/charts/audiobookshelf/Chart.yaml @@ -1,3 +1,7 @@ apiVersion: v2 version: 1.0.0 name: audiobookshelf +dependencies: + - name: common + version: 1.0.0 + repository: file://../common diff --git a/apps/charts/audiobookshelf/templates/deployment.yaml b/apps/charts/audiobookshelf/templates/deployment.yaml index 119a656..4508e33 100644 --- a/apps/charts/audiobookshelf/templates/deployment.yaml +++ b/apps/charts/audiobookshelf/templates/deployment.yaml @@ -1,52 +1 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: '{{ .Release.Name }}' -spec: - strategy: - type: Recreate - replicas: 1 - selector: - matchLabels: - app: '{{ .Release.Name }}' - template: - metadata: - labels: - app: '{{ .Release.Name }}' - spec: - containers: - - name: '{{ .Release.Name }}' - image: '{{ .Values.image.repository }}:{{ .Values.image.tag }}' - imagePullPolicy: '{{ .Values.image.pullPolicy }}' - ports: - - name: http - containerPort: 80 - protocol: TCP - livenessProbe: - tcpSocket: - port: http - readinessProbe: - tcpSocket: - port: http - volumeMounts: - - mountPath: /config - name: config - - mountPath: /metadata - name: metadata - - mountPath: /audiobooks - name: audiobooks - - mountPath: /podcasts - name: podcasts - volumes: - - name: config - persistentVolumeClaim: - claimName: '{{ .Release.Name }}-config' - - name: metadata - persistentVolumeClaim: - claimName: '{{ .Release.Name }}-metadata' - - name: audiobooks - persistentVolumeClaim: - claimName: books - - name: podcasts - persistentVolumeClaim: - claimName: podcasts +{{ include "common.deployment" . }} diff --git a/apps/charts/audiobookshelf/templates/dns.yaml b/apps/charts/audiobookshelf/templates/dns.yaml new file mode 100644 index 0000000..60dc0c8 --- /dev/null +++ b/apps/charts/audiobookshelf/templates/dns.yaml @@ -0,0 +1 @@ +{{ include "common.dns" . }} diff --git a/apps/charts/audiobookshelf/templates/oidc.yaml b/apps/charts/audiobookshelf/templates/oidc.yaml index a9e49c0..c13745f 100644 --- a/apps/charts/audiobookshelf/templates/oidc.yaml +++ b/apps/charts/audiobookshelf/templates/oidc.yaml @@ -1,15 +1 @@ - -apiVersion: authentik.homelab.mortenolsen.pro/v1alpha1 -kind: AuthentikClient -metadata: - name: "{{ .Release.Name }}" - namespace: "{{ .Release.Namespace }}" -spec: - serverRef: - name: authentik - namespace: shared - name: "{{ .Release.Name }}" - redirectUris: - - "https://{{ .Values.subdomain }}.{{ .Values.globals.domain }}/audiobookshelf/auth/openid/callback" - - "https://{{ .Values.subdomain }}.{{ .Values.globals.domain }}/audiobookshelf/auth/openid/mobile-redirect" - +{{ include "common.oidc" . }} diff --git a/apps/charts/audiobookshelf/templates/pvc.yaml b/apps/charts/audiobookshelf/templates/pvc.yaml index 14c9293..379bad9 100644 --- a/apps/charts/audiobookshelf/templates/pvc.yaml +++ b/apps/charts/audiobookshelf/templates/pvc.yaml @@ -1,24 +1 @@ -kind: PersistentVolumeClaim -apiVersion: v1 -metadata: - name: '{{ .Release.Name }}-config' -spec: - accessModes: - - 'ReadWriteOnce' - resources: - requests: - storage: '1Gi' - storageClassName: '{{ .Values.globals.environment }}' - ---- -kind: PersistentVolumeClaim -apiVersion: v1 -metadata: - name: '{{ .Release.Name }}-metadata' -spec: - accessModes: - - 'ReadWriteOnce' - resources: - requests: - storage: '1Gi' - storageClassName: '{{ .Values.globals.environment }}' +{{ include "common.pvc" . }} diff --git a/apps/charts/audiobookshelf/templates/service.yaml b/apps/charts/audiobookshelf/templates/service.yaml index ac45675..f024c64 100644 --- a/apps/charts/audiobookshelf/templates/service.yaml +++ b/apps/charts/audiobookshelf/templates/service.yaml @@ -1,15 +1 @@ -apiVersion: v1 -kind: Service -metadata: - name: '{{ .Release.Name }}' - labels: - app: '{{ .Release.Name }}' -spec: - type: ClusterIP - ports: - - port: 80 - targetPort: 80 - protocol: TCP - name: http - selector: - app: '{{ .Release.Name }}' +{{ include "common.service" . }} diff --git a/apps/charts/audiobookshelf/templates/virtual-service.yaml b/apps/charts/audiobookshelf/templates/virtual-service.yaml index 36e9d43..766f6b9 100644 --- a/apps/charts/audiobookshelf/templates/virtual-service.yaml +++ b/apps/charts/audiobookshelf/templates/virtual-service.yaml @@ -1,39 +1 @@ -apiVersion: networking.istio.io/v1 -kind: VirtualService -metadata: - name: "{{ .Release.Name }}-public" - namespace: "{{ .Release.Namespace }}" -spec: - gateways: - - "{{ .Values.globals.istio.gateways.public }}" - - mesh - hosts: - - "{{ .Values.subdomain }}.{{ .Values.globals.domain }}" - - mesh - http: - - route: - - destination: - host: "{{ .Release.Name }}" - port: - number: 80 - ---- -apiVersion: networking.istio.io/v1 -kind: VirtualService -metadata: - name: "{{ .Release.Name }}-private" - namespace: "{{ .Release.Namespace }}" -spec: - gateways: - - "{{ .Values.globals.istio.gateways.private }}" - - mesh - hosts: - - "{{ .Values.subdomain }}.{{ .Values.globals.domain }}" - - mesh - http: - - route: - - destination: - host: "{{ .Release.Name }}" - port: - number: 80 - +{{ include "common.virtualService" . }} diff --git a/apps/charts/audiobookshelf/values.yaml b/apps/charts/audiobookshelf/values.yaml index 3534726..e034bf8 100644 --- a/apps/charts/audiobookshelf/values.yaml +++ b/apps/charts/audiobookshelf/values.yaml @@ -2,4 +2,66 @@ image: repository: ghcr.io/advplyr/audiobookshelf tag: 2.32.1@sha256:a52dc5db694a5bf041ce38f285dd6c6a660a4b1b21e37ad6b6746433263b2ae5 pullPolicy: IfNotPresent + subdomain: audiobookshelf + +# Deployment configuration +deployment: + strategy: Recreate + replicas: 1 + revisionHistoryLimit: 0 + +# Container configuration +container: + port: 80 + healthProbe: + type: httpGet + path: /ping + +# Service configuration +service: + port: 80 + type: ClusterIP + +# Volume configuration +volumes: + - name: config + mountPath: /config + persistentVolumeClaim: config # Will be prefixed with release name in template + - name: metadata + mountPath: /metadata + persistentVolumeClaim: metadata # Will be prefixed with release name in template + - name: audiobooks + mountPath: /audiobooks + persistentVolumeClaim: books + - name: podcasts + mountPath: /podcasts + persistentVolumeClaim: podcasts + +# Persistent volume claims +persistentVolumeClaims: + - name: config + size: 1Gi + - name: metadata + size: 1Gi + +# DNS configuration +dns: + enabled: true + type: A + dnsClassRef: + name: private-dns + +# OIDC/Authentik configuration +oidc: + enabled: true + redirectUris: + - "/audiobookshelf/auth/openid/callback" + - "/audiobookshelf/auth/openid/mobile-redirect" + +# VirtualService configuration +virtualService: + enabled: true + gateways: + public: true + private: true diff --git a/apps/charts/baikal/templates/database.yaml b/apps/charts/baikal/templates/database.yaml deleted file mode 100644 index 6a30b53..0000000 --- a/apps/charts/baikal/templates/database.yaml +++ /dev/null @@ -1,6 +0,0 @@ -apiVersion: homelab.mortenolsen.pro/v1 -kind: PostgresDatabase -metadata: - name: '{{ .Release.Name }}' -spec: - environment: '{{ .Values.globals.environment }}' diff --git a/apps/charts/common/Chart.yaml b/apps/charts/common/Chart.yaml new file mode 100644 index 0000000..34acdf7 --- /dev/null +++ b/apps/charts/common/Chart.yaml @@ -0,0 +1,5 @@ +apiVersion: v2 +name: common +description: A Helm library chart for shared templates +type: library +version: 1.0.0 diff --git a/apps/charts/common/README.md b/apps/charts/common/README.md new file mode 100644 index 0000000..684c754 --- /dev/null +++ b/apps/charts/common/README.md @@ -0,0 +1,54 @@ +# Common Library Chart + +This is a Helm library chart that provides shared template helpers for all application charts in this repository. + +## Usage + +To use this library chart in your application chart, add it as a dependency in your `Chart.yaml`: + +```yaml +apiVersion: v2 +version: 1.0.0 +name: your-app +dependencies: + - name: common + version: 1.0.0 + repository: file://../common +``` + +Then run `helm dependency update` to download the dependency. + +## Available Helpers + +All helpers use the `common.*` prefix: + +- `common.fullname` - Full name of the release +- `common.name` - Name of the chart +- `common.labels` - Standard Kubernetes labels +- `common.selectorLabels` - Selector labels for matching +- `common.deploymentStrategy` - Deployment strategy (defaults to Recreate) +- `common.containerPort` - Container port (defaults to 80) +- `common.servicePort` - Service port (defaults to 80) +- `common.healthProbe` - Health probe configuration +- `common.domain` - Full domain name (subdomain.domain) +- `common.url` - Full URL (https://subdomain.domain) +- `common.volumeMounts` - Volume mounts from values +- `common.volumes` - Volumes from values +- `common.env` - Environment variables including TZ +- `common.virtualServiceGatewaysPublic` - Public gateway list +- `common.virtualServiceGatewaysPrivate` - Private gateway list + +## Example + +In your templates, use the helpers like this: + +```yaml +metadata: + name: {{ include "common.fullname" . }} + labels: + {{- include "common.labels" . | nindent 4 }} +``` + +## Values Structure + +The library expects a standardized values structure. See `audiobookshelf/values.yaml` for an example. diff --git a/apps/charts/common/templates/_helpers.tpl b/apps/charts/common/templates/_helpers.tpl new file mode 100644 index 0000000..13250ec --- /dev/null +++ b/apps/charts/common/templates/_helpers.tpl @@ -0,0 +1,415 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "common.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +*/}} +{{- define "common.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "common.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "common.labels" -}} +helm.sh/chart: {{ include "common.chart" . }} +{{ include "common.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "common.selectorLabels" -}} +app.kubernetes.io/name: {{ include "common.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Standard deployment strategy +*/}} +{{- define "common.deploymentStrategy" -}} +{{- if .Values.deployment.strategy }} +{{- .Values.deployment.strategy }} +{{- else }} +Recreate +{{- end }} +{{- end }} + +{{/* +Standard container port +*/}} +{{- define "common.containerPort" -}} +{{- if .Values.container.port }} +{{- .Values.container.port }} +{{- else }} +80 +{{- end }} +{{- end }} + +{{/* +Standard service port +*/}} +{{- define "common.servicePort" -}} +{{- if .Values.service.port }} +{{- .Values.service.port }} +{{- else }} +80 +{{- end }} +{{- end }} + +{{/* +Standard health probe +*/}} +{{- define "common.healthProbe" -}} +{{- if .Values.container.healthProbe }} +{{- if eq .Values.container.healthProbe.type "httpGet" }} +httpGet: + path: {{ .Values.container.healthProbe.path | default "/" }} + port: {{ include "common.containerPort" . }} +{{- else if eq .Values.container.healthProbe.type "tcpSocket" }} +tcpSocket: + port: {{ include "common.containerPort" . }} +{{- end }} +{{- if .Values.container.healthProbe.initialDelaySeconds }} +initialDelaySeconds: {{ .Values.container.healthProbe.initialDelaySeconds }} +{{- end }} +{{- if .Values.container.healthProbe.periodSeconds }} +periodSeconds: {{ .Values.container.healthProbe.periodSeconds }} +{{- end }} +{{- if .Values.container.healthProbe.timeoutSeconds }} +timeoutSeconds: {{ .Values.container.healthProbe.timeoutSeconds }} +{{- end }} +{{- if .Values.container.healthProbe.failureThreshold }} +failureThreshold: {{ .Values.container.healthProbe.failureThreshold }} +{{- end }} +{{- else }} +tcpSocket: + port: {{ include "common.containerPort" . }} +{{- end }} +{{- end }} + +{{/* +Full domain name +*/}} +{{- define "common.domain" -}} +{{ .Values.subdomain }}.{{ .Values.globals.domain }} +{{- end }} + +{{/* +Full URL +*/}} +{{- define "common.url" -}} +https://{{ include "common.domain" . }} +{{- end }} + +{{/* +Standard volume mounts +*/}} +{{- define "common.volumeMounts" -}} +{{- range .Values.volumes }} +- name: {{ .name }} + mountPath: {{ .mountPath }} +{{- if .subPath }} + subPath: {{ .subPath }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Standard volumes +*/}} +{{- define "common.volumes" -}} +{{- range .Values.volumes }} +- name: {{ .name }} + {{- if .persistentVolumeClaim }} + persistentVolumeClaim: + {{- if or (eq .persistentVolumeClaim "config") (eq .persistentVolumeClaim "metadata") (eq .persistentVolumeClaim "data") }} + claimName: {{ $.Release.Name }}-{{ .persistentVolumeClaim }} + {{- else }} + claimName: {{ .persistentVolumeClaim }} + {{- end }} + {{- else if .configMap }} + configMap: + name: {{ .configMap }} + {{- else if .secret }} + secret: + secretName: {{ .secret }} + {{- end }} +{{- end }} +{{- end }} + +{{/* +Standard environment variables +*/}} +{{- define "common.env" -}} +{{- if .Values.env }} +{{- range $key, $value := .Values.env }} +- name: {{ $key }} + {{- if kindIs "map" $value }} + {{- if $value.valueFrom }} + valueFrom: + {{- if $value.valueFrom.secretKeyRef }} + secretKeyRef: + name: {{ $value.valueFrom.secretKeyRef.name }} + key: {{ $value.valueFrom.secretKeyRef.key }} + {{- else if $value.valueFrom.configMapKeyRef }} + configMapKeyRef: + name: {{ $value.valueFrom.configMapKeyRef.name }} + key: {{ $value.valueFrom.configMapKeyRef.key }} + {{- end }} + {{- end }} + {{- else }} + value: {{ $value | quote }} + {{- end }} +{{- end }} +{{- end }} +{{- if .Values.globals.timezone }} +- name: TZ + value: {{ .Values.globals.timezone | quote }} +{{- end }} +{{- end }} + +{{/* +VirtualService gateway list for public gateway +*/}} +{{- define "common.virtualServiceGatewaysPublic" -}} +- {{ .Values.globals.istio.gateways.public | quote }} +- mesh +{{- end }} + +{{/* +VirtualService gateway list for private gateway +*/}} +{{- define "common.virtualServiceGatewaysPrivate" -}} +- {{ .Values.globals.istio.gateways.private | quote }} +- mesh +{{- end }} + +{{/* +Full Deployment resource +*/}} +{{- define "common.deployment" -}} +{{- if .Values.deployment }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "common.fullname" . }} + labels: + {{- include "common.labels" . | nindent 4 }} +spec: + strategy: + type: {{ include "common.deploymentStrategy" . }} + replicas: {{ .Values.deployment.replicas | default 1 }} + {{- if .Values.deployment.revisionHistoryLimit }} + revisionHistoryLimit: {{ .Values.deployment.revisionHistoryLimit }} + {{- end }} + selector: + matchLabels: + {{- include "common.selectorLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "common.selectorLabels" . | nindent 8 }} + spec: + containers: + - name: {{ .Chart.Name }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy | default "IfNotPresent" }} + ports: + - name: http + containerPort: {{ include "common.containerPort" . }} + protocol: TCP + {{- if .Values.container.healthProbe }} + livenessProbe: +{{ include "common.healthProbe" . | indent 12 }} + readinessProbe: +{{ include "common.healthProbe" . | indent 12 }} + {{- end }} + {{- if .Values.volumes }} + volumeMounts: +{{ include "common.volumeMounts" . | indent 12 }} + {{- end }} + {{- if or .Values.env .Values.globals.timezone }} + env: +{{ include "common.env" . | indent 12 }} + {{- end }} + {{- if .Values.volumes }} + volumes: + {{- include "common.volumes" . | nindent 8 }} + {{- end }} +{{- end }} +{{- end }} + +{{/* +Full Service resource +*/}} +{{- define "common.service" -}} +{{- if .Values.service }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "common.fullname" . }} + labels: + {{- include "common.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type | default "ClusterIP" }} + ports: + - port: {{ include "common.servicePort" . }} + targetPort: {{ include "common.containerPort" . }} + protocol: TCP + name: http + selector: + {{- include "common.selectorLabels" . | nindent 4 }} +{{- end }} +{{- end }} + +{{/* +Full PVC resources +*/}} +{{- define "common.pvc" -}} +{{- if .Values.persistentVolumeClaims }} +{{- range .Values.persistentVolumeClaims }} +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ $.Release.Name }}-{{ .name }} + labels: + {{- include "common.labels" $ | nindent 4 }} +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .size }} + {{- if $.Values.globals.environment }} + storageClassName: {{ $.Values.globals.environment }} + {{- end }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Full VirtualService resources +*/}} +{{- define "common.virtualService" -}} +{{- if and .Values.virtualService.enabled .Values.subdomain (hasKey .Values.globals "domain") (ne .Values.globals.domain "") }} +{{- if and .Values.virtualService.gateways.public (hasKey .Values.globals "istio") (hasKey .Values.globals.istio "gateways") (hasKey .Values.globals.istio.gateways "public") (ne .Values.globals.istio.gateways.public "") }} +apiVersion: networking.istio.io/v1 +kind: VirtualService +metadata: + name: {{ include "common.fullname" . }}-public + namespace: {{ .Release.Namespace }} + labels: + {{- include "common.labels" . | nindent 4 }} +spec: + gateways: + {{- include "common.virtualServiceGatewaysPublic" . | nindent 4 }} + hosts: + - {{ include "common.domain" . }} + - mesh + http: + - route: + - destination: + host: {{ include "common.fullname" . }} + port: + number: {{ include "common.servicePort" . }} + +--- +{{- end }} +{{- if and .Values.virtualService.gateways.private (hasKey .Values.globals "istio") (hasKey .Values.globals.istio "gateways") (hasKey .Values.globals.istio.gateways "private") (ne .Values.globals.istio.gateways.private "") }} +apiVersion: networking.istio.io/v1 +kind: VirtualService +metadata: + name: {{ include "common.fullname" . }}-private + namespace: {{ .Release.Namespace }} + labels: + {{- include "common.labels" . | nindent 4 }} +spec: + gateways: + {{- include "common.virtualServiceGatewaysPrivate" . | nindent 4 }} + hosts: + - {{ include "common.domain" . }} + - mesh + http: + - route: + - destination: + host: {{ include "common.fullname" . }} + port: + number: {{ include "common.servicePort" . }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Full DNS resource +*/}} +{{- define "common.dns" -}} +{{- if and .Values.dns.enabled (hasKey .Values.globals "networking") (hasKey .Values.globals.networking "private") (hasKey .Values.globals.networking.private "ip") (ne .Values.globals.networking.private.ip "") }} +apiVersion: dns.homelab.mortenolsen.pro/v1alpha1 +kind: DNSRecord +metadata: + name: {{ include "common.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "common.labels" . | nindent 4 }} +spec: + type: {{ .Values.dns.type | default "A" }} + domain: {{ .Values.globals.domain }} + subdomain: {{ .Values.subdomain }} + {{- if .Values.dns.dnsClassRef }} + dnsClassRef: + {{- toYaml .Values.dns.dnsClassRef | nindent 4 }} + {{- end }} + values: + - {{ .Values.globals.networking.private.ip | quote }} +{{- end }} +{{- end }} + +{{/* +Full OIDC/AuthentikClient resource +*/}} +{{- define "common.oidc" -}} +{{- if and .Values.oidc.enabled (hasKey .Values.globals "authentik") (hasKey .Values.globals.authentik "ref") (hasKey .Values.globals.authentik.ref "name") (hasKey .Values.globals.authentik.ref "namespace") (ne .Values.globals.authentik.ref.name "") (ne .Values.globals.authentik.ref.namespace "") }} +apiVersion: authentik.homelab.mortenolsen.pro/v1alpha1 +kind: AuthentikClient +metadata: + name: {{ include "common.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "common.labels" . | nindent 4 }} +spec: + serverRef: + name: {{ .Values.globals.authentik.ref.name }} + namespace: {{ .Values.globals.authentik.ref.namespace }} + name: {{ include "common.fullname" . }} + redirectUris: + {{- range .Values.oidc.redirectUris }} + - {{ printf "https://%s%s" (include "common.domain" $) . | quote }} + {{- end }} +{{- end }} +{{- end }} diff --git a/apps/root/values.yaml b/apps/root/values.yaml index 972cc64..e3177a4 100644 --- a/apps/root/values.yaml +++ b/apps/root/values.yaml @@ -12,4 +12,10 @@ globals: gateways: private: shared/private public: shared/public - + authentik: + ref: + name: authentik + namespace: shared + networking: + private: + ip: 192.168.20.180