diff --git a/apps/cilium/RECOVERY.md b/apps/cilium/RECOVERY.md new file mode 100644 index 0000000..674cd91 --- /dev/null +++ b/apps/cilium/RECOVERY.md @@ -0,0 +1,17 @@ +# Cilium recovery + +Argo CD is the normal owner of Cilium. Use this only if Argo CD cannot restore +the CNI and the cluster needs a break-glass repair. Work from a fresh checkout +of this repository and verify `kubectl config current-context` is +`kubernetes-admin@kubernetes` before any cluster changes. + +The chart version is canonically recorded as `spec.sources[0].targetRevision` +in `bootstrap/cilium.yaml`; the cluster configuration is in `apps/cilium/values.yaml`. +Restore the Hubble CA resources from `apps/cilium/resources/hubble-pki.yaml` if +needed. Then use the Cilium CLI's `upgrade` command with the chart version from +the Application and those values. Do not uninstall Cilium, delete its CRDs, or +remove the retained Helm release record during recovery. Once Argo is healthy, +return all routine changes to GitOps and let it reconcile. + +This is a recovery procedure, not a second deployment path. Keep credentials +and secret values out of this public repository. diff --git a/apps/traefik/README.md b/apps/traefik/README.md new file mode 100644 index 0000000..4d50f5b --- /dev/null +++ b/apps/traefik/README.md @@ -0,0 +1,12 @@ +# Traefik + +The Argo CD Application adopts the existing `traefik` Helm release in +`default`. `bootstrap/traefik.yaml` is the single chart-version source; the +values here preserve the cluster's current controller settings and live +file-provider routes. Those routes include the staubsauger vacuum, Victron +NanoPi and WebSocket endpoint, Growatt, and OpenDTU. Do not restore the +commented/retired routers from the former local configuration. + +Traefik CRDs and Gateway API CRDs are cluster-wide prerequisites. Keep the +existing CRDs during adoption and upgrades; they are not safe cleanup targets. +Application-specific ingress resources remain with their owning application. diff --git a/apps/traefik/routes/default-ingressroute-192-168-0-2.json b/apps/traefik/routes/default-ingressroute-192-168-0-2.json new file mode 100644 index 0000000..02ff78e --- /dev/null +++ b/apps/traefik/routes/default-ingressroute-192-168-0-2.json @@ -0,0 +1,25 @@ +{ + "apiVersion": "traefik.io/v1alpha1", + "kind": "IngressRoute", + "metadata": { + "name": "192-168-0-2", + "namespace": "default" + }, + "spec": { + "entryPoints": [ + "web" + ], + "routes": [ + { + "kind": "Rule", + "match": "Host(`192.168.0.2`)", + "services": [ + { + "name": "brunner-ninja", + "port": "http" + } + ] + } + ] + } +} diff --git a/apps/traefik/routes/default-ingressroute-code-brunner-ninja.json b/apps/traefik/routes/default-ingressroute-code-brunner-ninja.json new file mode 100644 index 0000000..def440d --- /dev/null +++ b/apps/traefik/routes/default-ingressroute-code-brunner-ninja.json @@ -0,0 +1,27 @@ +{ + "apiVersion": "traefik.io/v1alpha1", + "kind": "IngressRoute", + "metadata": { + "name": "code-brunner-ninja", + "namespace": "default" + }, + "spec": { + "entryPoints": [ + "websecure" + ], + "routes": [ + { + "kind": "Rule", + "match": "Host(`code.brunner.ninja`)", + "services": [ + { + "kind": "Service", + "name": "legacy-gitea-service", + "passHostHeader": true, + "port": "http" + } + ] + } + ] + } +} diff --git a/apps/traefik/routes/default-ingressroute-code-test-brunner-ninja.json b/apps/traefik/routes/default-ingressroute-code-test-brunner-ninja.json new file mode 100644 index 0000000..d885633 --- /dev/null +++ b/apps/traefik/routes/default-ingressroute-code-test-brunner-ninja.json @@ -0,0 +1,27 @@ +{ + "apiVersion": "traefik.io/v1alpha1", + "kind": "IngressRoute", + "metadata": { + "name": "code-test-brunner-ninja", + "namespace": "default" + }, + "spec": { + "entryPoints": [ + "websecure" + ], + "routes": [ + { + "kind": "Rule", + "match": "Host(`code-test.brunner.ninja`)", + "services": [ + { + "kind": "Service", + "name": "legacy-forgejo-service", + "passHostHeader": true, + "port": "http" + } + ] + } + ] + } +} diff --git a/apps/traefik/routes/default-ingressroute-helm-charts-brunner-ninja.json b/apps/traefik/routes/default-ingressroute-helm-charts-brunner-ninja.json new file mode 100644 index 0000000..c6806c6 --- /dev/null +++ b/apps/traefik/routes/default-ingressroute-helm-charts-brunner-ninja.json @@ -0,0 +1,51 @@ +{ + "apiVersion": "traefik.io/v1alpha1", + "kind": "IngressRoute", + "metadata": { + "name": "helm-charts-brunner-ninja", + "namespace": "default" + }, + "spec": { + "entryPoints": [ + "websecure" + ], + "routes": [ + { + "kind": "Rule", + "match": "Host(`brunner.ninja`) && (Path(`/charts`) || Path(`/charts/`))", + "middlewares": [ + { + "name": "helm-charts-index-rewrite" + } + ], + "priority": 301, + "services": [ + { + "kind": "Service", + "name": "legacy-gitea-service", + "passHostHeader": true, + "port": "http" + } + ] + }, + { + "kind": "Rule", + "match": "Host(`brunner.ninja`) && PathPrefix(`/charts/`)", + "middlewares": [ + { + "name": "helm-charts-path-rewrite" + } + ], + "priority": 300, + "services": [ + { + "kind": "Service", + "name": "legacy-gitea-service", + "passHostHeader": true, + "port": "http" + } + ] + } + ] + } +} diff --git a/apps/traefik/routes/default-ingressroute-immich-brunner-ninja.json b/apps/traefik/routes/default-ingressroute-immich-brunner-ninja.json new file mode 100644 index 0000000..af0f098 --- /dev/null +++ b/apps/traefik/routes/default-ingressroute-immich-brunner-ninja.json @@ -0,0 +1,28 @@ +{ + "apiVersion": "traefik.io/v1alpha1", + "kind": "IngressRoute", + "metadata": { + "name": "immich-brunner-ninja", + "namespace": "default" + }, + "spec": { + "entryPoints": [ + "websecure" + ], + "routes": [ + { + "kind": "Rule", + "match": "Host(`immich.brunner.ninja`)", + "services": [ + { + "kind": "Service", + "name": "legacy-immich-service", + "passHostHeader": true, + "port": "http", + "serversTransport": "immich-transport" + } + ] + } + ] + } +} diff --git a/apps/traefik/routes/default-ingressroute-komposthaufen.json b/apps/traefik/routes/default-ingressroute-komposthaufen.json new file mode 100644 index 0000000..1fda85b --- /dev/null +++ b/apps/traefik/routes/default-ingressroute-komposthaufen.json @@ -0,0 +1,26 @@ +{ + "apiVersion": "traefik.io/v1alpha1", + "kind": "IngressRoute", + "metadata": { + "name": "komposthaufen", + "namespace": "default" + }, + "spec": { + "entryPoints": [ + "websecure" + ], + "routes": [ + { + "kind": "Rule", + "match": "Host(`brunner.ninja`) && PathPrefix(`/komposthaufen`)", + "services": [ + { + "kind": "Service", + "name": "legacy-apache-service", + "port": "http" + } + ] + } + ] + } +} diff --git a/apps/traefik/routes/default-ingressroute-lidarr-brunner-ninja.json b/apps/traefik/routes/default-ingressroute-lidarr-brunner-ninja.json new file mode 100644 index 0000000..ac8d48f --- /dev/null +++ b/apps/traefik/routes/default-ingressroute-lidarr-brunner-ninja.json @@ -0,0 +1,32 @@ +{ + "apiVersion": "traefik.io/v1alpha1", + "kind": "IngressRoute", + "metadata": { + "name": "lidarr-brunner-ninja", + "namespace": "default" + }, + "spec": { + "entryPoints": [ + "websecure" + ], + "routes": [ + { + "kind": "Rule", + "match": "Host(`lidarr.brunner.ninja`)", + "middlewares": [ + { + "name": "authentik" + } + ], + "services": [ + { + "kind": "Service", + "name": "legacy-lidarr-service", + "passHostHeader": true, + "port": "http" + } + ] + } + ] + } +} diff --git a/apps/traefik/routes/default-ingressroute-mcmap.json b/apps/traefik/routes/default-ingressroute-mcmap.json new file mode 100644 index 0000000..d2f6050 --- /dev/null +++ b/apps/traefik/routes/default-ingressroute-mcmap.json @@ -0,0 +1,31 @@ +{ + "apiVersion": "traefik.io/v1alpha1", + "kind": "IngressRoute", + "metadata": { + "name": "mcmap", + "namespace": "default" + }, + "spec": { + "entryPoints": [ + "websecure" + ], + "routes": [ + { + "kind": "Rule", + "match": "Host(`brunner.ninja`) && PathPrefix(`/mcmap`)", + "middlewares": [ + { + "name": "mcmap-strip" + } + ], + "services": [ + { + "kind": "Service", + "name": "legacy-mcmap-service", + "port": "http" + } + ] + } + ] + } +} diff --git a/apps/traefik/routes/default-ingressroute-photos-brunner-ninja.json b/apps/traefik/routes/default-ingressroute-photos-brunner-ninja.json new file mode 100644 index 0000000..63ed7f4 --- /dev/null +++ b/apps/traefik/routes/default-ingressroute-photos-brunner-ninja.json @@ -0,0 +1,27 @@ +{ + "apiVersion": "traefik.io/v1alpha1", + "kind": "IngressRoute", + "metadata": { + "name": "photos-brunner-ninja", + "namespace": "default" + }, + "spec": { + "entryPoints": [ + "websecure" + ], + "routes": [ + { + "kind": "Rule", + "match": "Host(`photos.brunner.ninja`)", + "services": [ + { + "kind": "Service", + "name": "legacy-immich-service", + "passHostHeader": true, + "port": "http" + } + ] + } + ] + } +} diff --git a/apps/traefik/routes/default-ingressroute-prowlarr-brunner-ninja.json b/apps/traefik/routes/default-ingressroute-prowlarr-brunner-ninja.json new file mode 100644 index 0000000..6441b2f --- /dev/null +++ b/apps/traefik/routes/default-ingressroute-prowlarr-brunner-ninja.json @@ -0,0 +1,32 @@ +{ + "apiVersion": "traefik.io/v1alpha1", + "kind": "IngressRoute", + "metadata": { + "name": "prowlarr-brunner-ninja", + "namespace": "default" + }, + "spec": { + "entryPoints": [ + "websecure" + ], + "routes": [ + { + "kind": "Rule", + "match": "Host(`prowlarr.brunner.ninja`)", + "middlewares": [ + { + "name": "authentik" + } + ], + "services": [ + { + "kind": "Service", + "name": "legacy-prowlarr-service", + "passHostHeader": true, + "port": "http" + } + ] + } + ] + } +} diff --git a/apps/traefik/routes/default-ingressroute-qbittorrent-brunner-ninja.json b/apps/traefik/routes/default-ingressroute-qbittorrent-brunner-ninja.json new file mode 100644 index 0000000..31040da --- /dev/null +++ b/apps/traefik/routes/default-ingressroute-qbittorrent-brunner-ninja.json @@ -0,0 +1,32 @@ +{ + "apiVersion": "traefik.io/v1alpha1", + "kind": "IngressRoute", + "metadata": { + "name": "qbittorrent-brunner-ninja", + "namespace": "default" + }, + "spec": { + "entryPoints": [ + "websecure" + ], + "routes": [ + { + "kind": "Rule", + "match": "Host(`qbittorrent.brunner.ninja`)", + "middlewares": [ + { + "name": "authentik" + } + ], + "services": [ + { + "kind": "Service", + "name": "legacy-qbittorrent-service", + "passHostHeader": true, + "port": "http" + } + ] + } + ] + } +} diff --git a/apps/traefik/routes/default-ingressroute-radarr-brunner-ninja.json b/apps/traefik/routes/default-ingressroute-radarr-brunner-ninja.json new file mode 100644 index 0000000..4f62d86 --- /dev/null +++ b/apps/traefik/routes/default-ingressroute-radarr-brunner-ninja.json @@ -0,0 +1,32 @@ +{ + "apiVersion": "traefik.io/v1alpha1", + "kind": "IngressRoute", + "metadata": { + "name": "radarr-brunner-ninja", + "namespace": "default" + }, + "spec": { + "entryPoints": [ + "websecure" + ], + "routes": [ + { + "kind": "Rule", + "match": "Host(`radarr.brunner.ninja`)", + "middlewares": [ + { + "name": "authentik" + } + ], + "services": [ + { + "kind": "Service", + "name": "legacy-radarr-service", + "passHostHeader": true, + "port": "http" + } + ] + } + ] + } +} diff --git a/apps/traefik/routes/default-ingressroute-readarr-brunner-ninja.json b/apps/traefik/routes/default-ingressroute-readarr-brunner-ninja.json new file mode 100644 index 0000000..065f3d3 --- /dev/null +++ b/apps/traefik/routes/default-ingressroute-readarr-brunner-ninja.json @@ -0,0 +1,32 @@ +{ + "apiVersion": "traefik.io/v1alpha1", + "kind": "IngressRoute", + "metadata": { + "name": "readarr-brunner-ninja", + "namespace": "default" + }, + "spec": { + "entryPoints": [ + "websecure" + ], + "routes": [ + { + "kind": "Rule", + "match": "Host(`readarr.brunner.ninja`)", + "middlewares": [ + { + "name": "authentik" + } + ], + "services": [ + { + "kind": "Service", + "name": "legacy-readarr-service", + "passHostHeader": true, + "port": "http" + } + ] + } + ] + } +} diff --git a/apps/traefik/routes/default-ingressroute-sonarr-brunner-ninja.json b/apps/traefik/routes/default-ingressroute-sonarr-brunner-ninja.json new file mode 100644 index 0000000..84cbd8e --- /dev/null +++ b/apps/traefik/routes/default-ingressroute-sonarr-brunner-ninja.json @@ -0,0 +1,32 @@ +{ + "apiVersion": "traefik.io/v1alpha1", + "kind": "IngressRoute", + "metadata": { + "name": "sonarr-brunner-ninja", + "namespace": "default" + }, + "spec": { + "entryPoints": [ + "websecure" + ], + "routes": [ + { + "kind": "Rule", + "match": "Host(`sonarr.brunner.ninja`)", + "middlewares": [ + { + "name": "authentik" + } + ], + "services": [ + { + "kind": "Service", + "name": "legacy-sonarr-service", + "passHostHeader": true, + "port": "http" + } + ] + } + ] + } +} diff --git a/apps/traefik/routes/default-ingressroute-syncthing-brunner-ninja.json b/apps/traefik/routes/default-ingressroute-syncthing-brunner-ninja.json new file mode 100644 index 0000000..5a1bad6 --- /dev/null +++ b/apps/traefik/routes/default-ingressroute-syncthing-brunner-ninja.json @@ -0,0 +1,32 @@ +{ + "apiVersion": "traefik.io/v1alpha1", + "kind": "IngressRoute", + "metadata": { + "name": "syncthing-brunner-ninja", + "namespace": "default" + }, + "spec": { + "entryPoints": [ + "websecure" + ], + "routes": [ + { + "kind": "Rule", + "match": "Host(`syncthing.brunner.ninja`)", + "middlewares": [ + { + "name": "authentik" + } + ], + "services": [ + { + "kind": "Service", + "name": "legacy-syncthing-service", + "passHostHeader": true, + "port": "http" + } + ] + } + ] + } +} diff --git a/apps/traefik/routes/default-ingressroute-vault-brunner-ninja.json b/apps/traefik/routes/default-ingressroute-vault-brunner-ninja.json new file mode 100644 index 0000000..c06da1c --- /dev/null +++ b/apps/traefik/routes/default-ingressroute-vault-brunner-ninja.json @@ -0,0 +1,27 @@ +{ + "apiVersion": "traefik.io/v1alpha1", + "kind": "IngressRoute", + "metadata": { + "name": "vault-brunner-ninja", + "namespace": "default" + }, + "spec": { + "entryPoints": [ + "websecure" + ], + "routes": [ + { + "kind": "Rule", + "match": "Host(`vault.brunner.ninja`)", + "services": [ + { + "kind": "Service", + "name": "legacy-vault-service", + "passHostHeader": true, + "port": "http" + } + ] + } + ] + } +} diff --git a/apps/traefik/routes/default-ingressroute-whisparr-brunner-ninja.json b/apps/traefik/routes/default-ingressroute-whisparr-brunner-ninja.json new file mode 100644 index 0000000..5906cc7 --- /dev/null +++ b/apps/traefik/routes/default-ingressroute-whisparr-brunner-ninja.json @@ -0,0 +1,32 @@ +{ + "apiVersion": "traefik.io/v1alpha1", + "kind": "IngressRoute", + "metadata": { + "name": "whisparr-brunner-ninja", + "namespace": "default" + }, + "spec": { + "entryPoints": [ + "websecure" + ], + "routes": [ + { + "kind": "Rule", + "match": "Host(`whisparr.brunner.ninja`)", + "middlewares": [ + { + "name": "authentik" + } + ], + "services": [ + { + "kind": "Service", + "name": "legacy-whisparr-service", + "passHostHeader": true, + "port": "http" + } + ] + } + ] + } +} diff --git a/apps/traefik/routes/default-ingressroute-youtube-brunner-ninja.json b/apps/traefik/routes/default-ingressroute-youtube-brunner-ninja.json new file mode 100644 index 0000000..de4e7c2 --- /dev/null +++ b/apps/traefik/routes/default-ingressroute-youtube-brunner-ninja.json @@ -0,0 +1,27 @@ +{ + "apiVersion": "traefik.io/v1alpha1", + "kind": "IngressRoute", + "metadata": { + "name": "youtube-brunner-ninja", + "namespace": "default" + }, + "spec": { + "entryPoints": [ + "websecure" + ], + "routes": [ + { + "kind": "Rule", + "match": "Host(`youtube.brunner.ninja`)", + "services": [ + { + "kind": "Service", + "name": "legacy-apache-service", + "passHostHeader": true, + "port": "http" + } + ] + } + ] + } +} diff --git a/apps/traefik/routes/default-middleware-helm-charts-index-rewrite.json b/apps/traefik/routes/default-middleware-helm-charts-index-rewrite.json new file mode 100644 index 0000000..b0538d6 --- /dev/null +++ b/apps/traefik/routes/default-middleware-helm-charts-index-rewrite.json @@ -0,0 +1,13 @@ +{ + "apiVersion": "traefik.io/v1alpha1", + "kind": "Middleware", + "metadata": { + "name": "helm-charts-index-rewrite", + "namespace": "default" + }, + "spec": { + "replacePath": { + "path": "/api/packages/feedc0de/helm/index.yaml" + } + } +} diff --git a/apps/traefik/routes/default-middleware-helm-charts-path-rewrite.json b/apps/traefik/routes/default-middleware-helm-charts-path-rewrite.json new file mode 100644 index 0000000..33762e6 --- /dev/null +++ b/apps/traefik/routes/default-middleware-helm-charts-path-rewrite.json @@ -0,0 +1,14 @@ +{ + "apiVersion": "traefik.io/v1alpha1", + "kind": "Middleware", + "metadata": { + "name": "helm-charts-path-rewrite", + "namespace": "default" + }, + "spec": { + "replacePathRegex": { + "regex": "^/charts/(.*)$", + "replacement": "/api/packages/feedc0de/helm/${1}" + } + } +} diff --git a/apps/traefik/routes/default-middleware-mcmap-strip.json b/apps/traefik/routes/default-middleware-mcmap-strip.json new file mode 100644 index 0000000..d77da4b --- /dev/null +++ b/apps/traefik/routes/default-middleware-mcmap-strip.json @@ -0,0 +1,15 @@ +{ + "apiVersion": "traefik.io/v1alpha1", + "kind": "Middleware", + "metadata": { + "name": "mcmap-strip", + "namespace": "default" + }, + "spec": { + "stripPrefix": { + "prefixes": [ + "/mcmap" + ] + } + } +} diff --git a/apps/traefik/routes/default-service-legacy-apache-service.json b/apps/traefik/routes/default-service-legacy-apache-service.json new file mode 100644 index 0000000..77c68fe --- /dev/null +++ b/apps/traefik/routes/default-service-legacy-apache-service.json @@ -0,0 +1,29 @@ +{ + "apiVersion": "v1", + "kind": "Service", + "metadata": { + "name": "legacy-apache-service", + "namespace": "default" + }, + "spec": { + "clusterIP": "10.105.55.200", + "clusterIPs": [ + "10.105.55.200" + ], + "internalTrafficPolicy": "Cluster", + "ipFamilies": [ + "IPv4" + ], + "ipFamilyPolicy": "SingleStack", + "ports": [ + { + "name": "http", + "port": 81, + "protocol": "TCP", + "targetPort": 81 + } + ], + "sessionAffinity": "None", + "type": "ClusterIP" + } +} diff --git a/apps/traefik/routes/default-service-legacy-forgejo-service.json b/apps/traefik/routes/default-service-legacy-forgejo-service.json new file mode 100644 index 0000000..cd517dc --- /dev/null +++ b/apps/traefik/routes/default-service-legacy-forgejo-service.json @@ -0,0 +1,29 @@ +{ + "apiVersion": "v1", + "kind": "Service", + "metadata": { + "name": "legacy-forgejo-service", + "namespace": "default" + }, + "spec": { + "clusterIP": "10.102.202.224", + "clusterIPs": [ + "10.102.202.224" + ], + "internalTrafficPolicy": "Cluster", + "ipFamilies": [ + "IPv4" + ], + "ipFamilyPolicy": "SingleStack", + "ports": [ + { + "name": "http", + "port": 3005, + "protocol": "TCP", + "targetPort": 3005 + } + ], + "sessionAffinity": "None", + "type": "ClusterIP" + } +} diff --git a/apps/traefik/routes/default-service-legacy-gitea-service.json b/apps/traefik/routes/default-service-legacy-gitea-service.json new file mode 100644 index 0000000..6197c06 --- /dev/null +++ b/apps/traefik/routes/default-service-legacy-gitea-service.json @@ -0,0 +1,29 @@ +{ + "apiVersion": "v1", + "kind": "Service", + "metadata": { + "name": "legacy-gitea-service", + "namespace": "default" + }, + "spec": { + "clusterIP": "10.103.230.204", + "clusterIPs": [ + "10.103.230.204" + ], + "internalTrafficPolicy": "Cluster", + "ipFamilies": [ + "IPv4" + ], + "ipFamilyPolicy": "SingleStack", + "ports": [ + { + "name": "http", + "port": 3004, + "protocol": "TCP", + "targetPort": 3004 + } + ], + "sessionAffinity": "None", + "type": "ClusterIP" + } +} diff --git a/apps/traefik/routes/default-service-legacy-immich-service.json b/apps/traefik/routes/default-service-legacy-immich-service.json new file mode 100644 index 0000000..f693ef0 --- /dev/null +++ b/apps/traefik/routes/default-service-legacy-immich-service.json @@ -0,0 +1,29 @@ +{ + "apiVersion": "v1", + "kind": "Service", + "metadata": { + "name": "legacy-immich-service", + "namespace": "default" + }, + "spec": { + "clusterIP": "10.104.46.119", + "clusterIPs": [ + "10.104.46.119" + ], + "internalTrafficPolicy": "Cluster", + "ipFamilies": [ + "IPv4" + ], + "ipFamilyPolicy": "SingleStack", + "ports": [ + { + "name": "http", + "port": 2283, + "protocol": "TCP", + "targetPort": 2283 + } + ], + "sessionAffinity": "None", + "type": "ClusterIP" + } +} diff --git a/apps/traefik/routes/default-service-legacy-lidarr-service.json b/apps/traefik/routes/default-service-legacy-lidarr-service.json new file mode 100644 index 0000000..d976709 --- /dev/null +++ b/apps/traefik/routes/default-service-legacy-lidarr-service.json @@ -0,0 +1,29 @@ +{ + "apiVersion": "v1", + "kind": "Service", + "metadata": { + "name": "legacy-lidarr-service", + "namespace": "default" + }, + "spec": { + "clusterIP": "10.103.43.185", + "clusterIPs": [ + "10.103.43.185" + ], + "internalTrafficPolicy": "Cluster", + "ipFamilies": [ + "IPv4" + ], + "ipFamilyPolicy": "SingleStack", + "ports": [ + { + "name": "http", + "port": 8686, + "protocol": "TCP", + "targetPort": 8686 + } + ], + "sessionAffinity": "None", + "type": "ClusterIP" + } +} diff --git a/apps/traefik/routes/default-service-legacy-mastodon-service.json b/apps/traefik/routes/default-service-legacy-mastodon-service.json new file mode 100644 index 0000000..bb490a8 --- /dev/null +++ b/apps/traefik/routes/default-service-legacy-mastodon-service.json @@ -0,0 +1,29 @@ +{ + "apiVersion": "v1", + "kind": "Service", + "metadata": { + "name": "legacy-mastodon-service", + "namespace": "default" + }, + "spec": { + "clusterIP": "10.111.83.15", + "clusterIPs": [ + "10.111.83.15" + ], + "internalTrafficPolicy": "Cluster", + "ipFamilies": [ + "IPv4" + ], + "ipFamilyPolicy": "SingleStack", + "ports": [ + { + "name": "http", + "port": 3000, + "protocol": "TCP", + "targetPort": 3000 + } + ], + "sessionAffinity": "None", + "type": "ClusterIP" + } +} diff --git a/apps/traefik/routes/default-service-legacy-matrix-service.json b/apps/traefik/routes/default-service-legacy-matrix-service.json new file mode 100644 index 0000000..ff139bd --- /dev/null +++ b/apps/traefik/routes/default-service-legacy-matrix-service.json @@ -0,0 +1,29 @@ +{ + "apiVersion": "v1", + "kind": "Service", + "metadata": { + "name": "legacy-matrix-service", + "namespace": "default" + }, + "spec": { + "clusterIP": "10.98.20.196", + "clusterIPs": [ + "10.98.20.196" + ], + "internalTrafficPolicy": "Cluster", + "ipFamilies": [ + "IPv4" + ], + "ipFamilyPolicy": "SingleStack", + "ports": [ + { + "name": "http", + "port": 8008, + "protocol": "TCP", + "targetPort": 8008 + } + ], + "sessionAffinity": "None", + "type": "ClusterIP" + } +} diff --git a/apps/traefik/routes/default-service-legacy-mcmap-service.json b/apps/traefik/routes/default-service-legacy-mcmap-service.json new file mode 100644 index 0000000..4c0ae5a --- /dev/null +++ b/apps/traefik/routes/default-service-legacy-mcmap-service.json @@ -0,0 +1,29 @@ +{ + "apiVersion": "v1", + "kind": "Service", + "metadata": { + "name": "legacy-mcmap-service", + "namespace": "default" + }, + "spec": { + "clusterIP": "10.97.249.106", + "clusterIPs": [ + "10.97.249.106" + ], + "internalTrafficPolicy": "Cluster", + "ipFamilies": [ + "IPv4" + ], + "ipFamilyPolicy": "SingleStack", + "ports": [ + { + "name": "http", + "port": 8124, + "protocol": "TCP", + "targetPort": 8124 + } + ], + "sessionAffinity": "None", + "type": "ClusterIP" + } +} diff --git a/apps/traefik/routes/default-service-legacy-prowlarr-service.json b/apps/traefik/routes/default-service-legacy-prowlarr-service.json new file mode 100644 index 0000000..8fed536 --- /dev/null +++ b/apps/traefik/routes/default-service-legacy-prowlarr-service.json @@ -0,0 +1,29 @@ +{ + "apiVersion": "v1", + "kind": "Service", + "metadata": { + "name": "legacy-prowlarr-service", + "namespace": "default" + }, + "spec": { + "clusterIP": "10.97.85.22", + "clusterIPs": [ + "10.97.85.22" + ], + "internalTrafficPolicy": "Cluster", + "ipFamilies": [ + "IPv4" + ], + "ipFamilyPolicy": "SingleStack", + "ports": [ + { + "name": "http", + "port": 9696, + "protocol": "TCP", + "targetPort": 9696 + } + ], + "sessionAffinity": "None", + "type": "ClusterIP" + } +} diff --git a/apps/traefik/routes/default-service-legacy-qbittorrent-service.json b/apps/traefik/routes/default-service-legacy-qbittorrent-service.json new file mode 100644 index 0000000..d45da00 --- /dev/null +++ b/apps/traefik/routes/default-service-legacy-qbittorrent-service.json @@ -0,0 +1,29 @@ +{ + "apiVersion": "v1", + "kind": "Service", + "metadata": { + "name": "legacy-qbittorrent-service", + "namespace": "default" + }, + "spec": { + "clusterIP": "10.97.73.158", + "clusterIPs": [ + "10.97.73.158" + ], + "internalTrafficPolicy": "Cluster", + "ipFamilies": [ + "IPv4" + ], + "ipFamilyPolicy": "SingleStack", + "ports": [ + { + "name": "http", + "port": 8081, + "protocol": "TCP", + "targetPort": 8081 + } + ], + "sessionAffinity": "None", + "type": "ClusterIP" + } +} diff --git a/apps/traefik/routes/default-service-legacy-radarr-service.json b/apps/traefik/routes/default-service-legacy-radarr-service.json new file mode 100644 index 0000000..677c523 --- /dev/null +++ b/apps/traefik/routes/default-service-legacy-radarr-service.json @@ -0,0 +1,29 @@ +{ + "apiVersion": "v1", + "kind": "Service", + "metadata": { + "name": "legacy-radarr-service", + "namespace": "default" + }, + "spec": { + "clusterIP": "10.105.65.227", + "clusterIPs": [ + "10.105.65.227" + ], + "internalTrafficPolicy": "Cluster", + "ipFamilies": [ + "IPv4" + ], + "ipFamilyPolicy": "SingleStack", + "ports": [ + { + "name": "http", + "port": 7878, + "protocol": "TCP", + "targetPort": 7878 + } + ], + "sessionAffinity": "None", + "type": "ClusterIP" + } +} diff --git a/apps/traefik/routes/default-service-legacy-readarr-service.json b/apps/traefik/routes/default-service-legacy-readarr-service.json new file mode 100644 index 0000000..a0c9b95 --- /dev/null +++ b/apps/traefik/routes/default-service-legacy-readarr-service.json @@ -0,0 +1,29 @@ +{ + "apiVersion": "v1", + "kind": "Service", + "metadata": { + "name": "legacy-readarr-service", + "namespace": "default" + }, + "spec": { + "clusterIP": "10.103.216.34", + "clusterIPs": [ + "10.103.216.34" + ], + "internalTrafficPolicy": "Cluster", + "ipFamilies": [ + "IPv4" + ], + "ipFamilyPolicy": "SingleStack", + "ports": [ + { + "name": "http", + "port": 8787, + "protocol": "TCP", + "targetPort": 8787 + } + ], + "sessionAffinity": "None", + "type": "ClusterIP" + } +} diff --git a/apps/traefik/routes/default-service-legacy-sonarr-service.json b/apps/traefik/routes/default-service-legacy-sonarr-service.json new file mode 100644 index 0000000..afa2926 --- /dev/null +++ b/apps/traefik/routes/default-service-legacy-sonarr-service.json @@ -0,0 +1,29 @@ +{ + "apiVersion": "v1", + "kind": "Service", + "metadata": { + "name": "legacy-sonarr-service", + "namespace": "default" + }, + "spec": { + "clusterIP": "10.97.124.201", + "clusterIPs": [ + "10.97.124.201" + ], + "internalTrafficPolicy": "Cluster", + "ipFamilies": [ + "IPv4" + ], + "ipFamilyPolicy": "SingleStack", + "ports": [ + { + "name": "http", + "port": 8989, + "protocol": "TCP", + "targetPort": 8989 + } + ], + "sessionAffinity": "None", + "type": "ClusterIP" + } +} diff --git a/apps/traefik/routes/default-service-legacy-syncthing-service.json b/apps/traefik/routes/default-service-legacy-syncthing-service.json new file mode 100644 index 0000000..7661711 --- /dev/null +++ b/apps/traefik/routes/default-service-legacy-syncthing-service.json @@ -0,0 +1,29 @@ +{ + "apiVersion": "v1", + "kind": "Service", + "metadata": { + "name": "legacy-syncthing-service", + "namespace": "default" + }, + "spec": { + "clusterIP": "10.101.5.124", + "clusterIPs": [ + "10.101.5.124" + ], + "internalTrafficPolicy": "Cluster", + "ipFamilies": [ + "IPv4" + ], + "ipFamilyPolicy": "SingleStack", + "ports": [ + { + "name": "http", + "port": 8384, + "protocol": "TCP", + "targetPort": 8384 + } + ], + "sessionAffinity": "None", + "type": "ClusterIP" + } +} diff --git a/apps/traefik/routes/default-service-legacy-vault-service.json b/apps/traefik/routes/default-service-legacy-vault-service.json new file mode 100644 index 0000000..678b95a --- /dev/null +++ b/apps/traefik/routes/default-service-legacy-vault-service.json @@ -0,0 +1,29 @@ +{ + "apiVersion": "v1", + "kind": "Service", + "metadata": { + "name": "legacy-vault-service", + "namespace": "default" + }, + "spec": { + "clusterIP": "10.101.2.74", + "clusterIPs": [ + "10.101.2.74" + ], + "internalTrafficPolicy": "Cluster", + "ipFamilies": [ + "IPv4" + ], + "ipFamilyPolicy": "SingleStack", + "ports": [ + { + "name": "http", + "port": 8000, + "protocol": "TCP", + "targetPort": 8000 + } + ], + "sessionAffinity": "None", + "type": "ClusterIP" + } +} diff --git a/apps/traefik/routes/default-service-legacy-whisparr-service.json b/apps/traefik/routes/default-service-legacy-whisparr-service.json new file mode 100644 index 0000000..6988ee3 --- /dev/null +++ b/apps/traefik/routes/default-service-legacy-whisparr-service.json @@ -0,0 +1,29 @@ +{ + "apiVersion": "v1", + "kind": "Service", + "metadata": { + "name": "legacy-whisparr-service", + "namespace": "default" + }, + "spec": { + "clusterIP": "10.99.146.118", + "clusterIPs": [ + "10.99.146.118" + ], + "internalTrafficPolicy": "Cluster", + "ipFamilies": [ + "IPv4" + ], + "ipFamilyPolicy": "SingleStack", + "ports": [ + { + "name": "http", + "port": 6969, + "protocol": "TCP", + "targetPort": 6969 + } + ], + "sessionAffinity": "None", + "type": "ClusterIP" + } +} diff --git a/apps/traefik/routes/garrysmod-ingressroute-garrysmod-loading-screen.json b/apps/traefik/routes/garrysmod-ingressroute-garrysmod-loading-screen.json new file mode 100644 index 0000000..208935d --- /dev/null +++ b/apps/traefik/routes/garrysmod-ingressroute-garrysmod-loading-screen.json @@ -0,0 +1,30 @@ +{ + "apiVersion": "traefik.io/v1alpha1", + "kind": "IngressRoute", + "metadata": { + "name": "garrysmod-loading-screen", + "namespace": "garrysmod", + "labels": { + "app.kubernetes.io/name": "garrysmod" + } + }, + "spec": { + "entryPoints": [ + "websecure" + ], + "routes": [ + { + "kind": "Rule", + "match": "Host(`garrysmod.brunner.ninja`)", + "services": [ + { + "kind": "Service", + "name": "garrysmod-loading-screen", + "passHostHeader": true, + "port": "http" + } + ] + } + ] + } +} diff --git a/apps/traefik/routes/jellyfin-ingressroute-jellyfin-brunner-ninja.json b/apps/traefik/routes/jellyfin-ingressroute-jellyfin-brunner-ninja.json new file mode 100644 index 0000000..711b3d1 --- /dev/null +++ b/apps/traefik/routes/jellyfin-ingressroute-jellyfin-brunner-ninja.json @@ -0,0 +1,49 @@ +{ + "apiVersion": "traefik.io/v1alpha1", + "kind": "IngressRoute", + "metadata": { + "name": "jellyfin-brunner-ninja", + "namespace": "jellyfin", + "labels": { + "app.kubernetes.io/name": "jellyfin" + } + }, + "spec": { + "entryPoints": [ + "websecure" + ], + "routes": [ + { + "kind": "Rule", + "match": "Host(`jellyfin.brunner.ninja`) && PathPrefix(`/metrics`)", + "middlewares": [ + { + "name": "jellyfin-metrics-internal" + } + ], + "priority": 100, + "services": [ + { + "kind": "Service", + "name": "jellyfin", + "passHostHeader": true, + "port": "http" + } + ] + }, + { + "kind": "Rule", + "match": "Host(`jellyfin.brunner.ninja`)", + "priority": 10, + "services": [ + { + "kind": "Service", + "name": "jellyfin", + "passHostHeader": true, + "port": "http" + } + ] + } + ] + } +} diff --git a/apps/traefik/routes/jellyfin-middleware-jellyfin-metrics-internal.json b/apps/traefik/routes/jellyfin-middleware-jellyfin-metrics-internal.json new file mode 100644 index 0000000..7127cab --- /dev/null +++ b/apps/traefik/routes/jellyfin-middleware-jellyfin-metrics-internal.json @@ -0,0 +1,18 @@ +{ + "apiVersion": "traefik.io/v1alpha1", + "kind": "Middleware", + "metadata": { + "name": "jellyfin-metrics-internal", + "namespace": "jellyfin", + "labels": { + "app.kubernetes.io/name": "jellyfin" + } + }, + "spec": { + "ipAllowList": { + "sourceRange": [ + "10.0.0.0/8" + ] + } + } +} diff --git a/apps/traefik/routes/kubernetes-dashboard-ingressroute-kubernetes-dashboard-ingressroute.json b/apps/traefik/routes/kubernetes-dashboard-ingressroute-kubernetes-dashboard-ingressroute.json new file mode 100644 index 0000000..0a8e6e9 --- /dev/null +++ b/apps/traefik/routes/kubernetes-dashboard-ingressroute-kubernetes-dashboard-ingressroute.json @@ -0,0 +1,31 @@ +{ + "apiVersion": "traefik.io/v1alpha1", + "kind": "IngressRoute", + "metadata": { + "name": "kubernetes-dashboard-ingressroute", + "namespace": "kubernetes-dashboard" + }, + "spec": { + "entryPoints": [ + "websecure" + ], + "routes": [ + { + "kind": "Rule", + "match": "Host(`kubernetes.brunner.ninja`)", + "middlewares": [ + { + "name": "kubernetes-dashboard-authentik" + } + ], + "services": [ + { + "kind": "Service", + "name": "kubernetes-dashboard-auth-proxy", + "port": "http" + } + ] + } + ] + } +} diff --git a/apps/traefik/routes/kubernetes-dashboard-middleware-kubernetes-dashboard-authentik.json b/apps/traefik/routes/kubernetes-dashboard-middleware-kubernetes-dashboard-authentik.json new file mode 100644 index 0000000..3bb1ce1 --- /dev/null +++ b/apps/traefik/routes/kubernetes-dashboard-middleware-kubernetes-dashboard-authentik.json @@ -0,0 +1,28 @@ +{ + "apiVersion": "traefik.io/v1alpha1", + "kind": "Middleware", + "metadata": { + "name": "kubernetes-dashboard-authentik", + "namespace": "kubernetes-dashboard" + }, + "spec": { + "forwardAuth": { + "address": "http://authentik-server.authentik.svc.cluster.local/outpost.goauthentik.io/auth/traefik", + "authResponseHeaders": [ + "X-authentik-username", + "X-authentik-groups", + "X-authentik-entitlements", + "X-authentik-email", + "X-authentik-name", + "X-authentik-uid", + "X-authentik-jwt", + "X-authentik-meta-jwks", + "X-authentik-meta-outpost", + "X-authentik-meta-provider", + "X-authentik-meta-app", + "X-authentik-meta-version" + ], + "trustForwardHeader": true + } + } +} diff --git a/apps/traefik/routes/loops-ingressroute-loops-brunner-ninja.json b/apps/traefik/routes/loops-ingressroute-loops-brunner-ninja.json new file mode 100644 index 0000000..201b09e --- /dev/null +++ b/apps/traefik/routes/loops-ingressroute-loops-brunner-ninja.json @@ -0,0 +1,53 @@ +{ + "apiVersion": "traefik.io/v1alpha1", + "kind": "IngressRoute", + "metadata": { + "name": "loops-brunner-ninja", + "namespace": "loops", + "labels": { + "app.kubernetes.io/part-of": "loops" + } + }, + "spec": { + "entryPoints": [ + "websecure" + ], + "routes": [ + { + "kind": "Rule", + "match": "Host(`loops.brunner.ninja`) && Path(`/api/v1/feed/for-you`)", + "middlewares": [ + { + "name": "loops-android-for-you" + }, + { + "name": "loops-upload-buffer" + } + ], + "priority": 100, + "services": [ + { + "name": "loops-web", + "port": 80 + } + ] + }, + { + "kind": "Rule", + "match": "Host(`loops.brunner.ninja`)", + "middlewares": [ + { + "name": "loops-upload-buffer" + } + ], + "services": [ + { + "name": "loops-web", + "port": 80 + } + ] + } + ], + "tls": {} + } +} diff --git a/apps/traefik/routes/loops-middleware-loops-android-for-you.json b/apps/traefik/routes/loops-middleware-loops-android-for-you.json new file mode 100644 index 0000000..7c29b0d --- /dev/null +++ b/apps/traefik/routes/loops-middleware-loops-android-for-you.json @@ -0,0 +1,17 @@ +{ + "apiVersion": "traefik.io/v1alpha1", + "kind": "Middleware", + "metadata": { + "name": "loops-android-for-you", + "namespace": "loops", + "labels": { + "app.kubernetes.io/part-of": "loops" + } + }, + "spec": { + "replacePathRegex": { + "regex": "^/api/v1/feed/for-you$", + "replacement": "/api/v0/feed/recommended" + } + } +} diff --git a/apps/traefik/routes/loops-middleware-loops-upload-buffer.json b/apps/traefik/routes/loops-middleware-loops-upload-buffer.json new file mode 100644 index 0000000..e035805 --- /dev/null +++ b/apps/traefik/routes/loops-middleware-loops-upload-buffer.json @@ -0,0 +1,17 @@ +{ + "apiVersion": "traefik.io/v1alpha1", + "kind": "Middleware", + "metadata": { + "name": "loops-upload-buffer", + "namespace": "loops", + "labels": { + "app.kubernetes.io/part-of": "loops" + } + }, + "spec": { + "buffering": { + "maxRequestBodyBytes": 524288000, + "memRequestBodyBytes": 2097152 + } + } +} diff --git a/apps/traefik/routes/mastodon-ingressroute-brunner-ninja-webfinger.json b/apps/traefik/routes/mastodon-ingressroute-brunner-ninja-webfinger.json new file mode 100644 index 0000000..c0f0e6d --- /dev/null +++ b/apps/traefik/routes/mastodon-ingressroute-brunner-ninja-webfinger.json @@ -0,0 +1,34 @@ +{ + "apiVersion": "traefik.io/v1alpha1", + "kind": "IngressRoute", + "metadata": { + "name": "brunner-ninja-webfinger", + "namespace": "mastodon" + }, + "spec": { + "entryPoints": [ + "websecure" + ], + "routes": [ + { + "kind": "Rule", + "match": "Host(`brunner.ninja`) && PathPrefix(`/.well-known/`) && !PathPrefix(`/.well-known/matrix/`)", + "middlewares": [ + { + "name": "webfinger-cors" + }, + { + "name": "webfinger-redirect" + } + ], + "priority": 1000, + "services": [ + { + "name": "mastodon-web", + "port": "http" + } + ] + } + ] + } +} diff --git a/apps/traefik/routes/mastodon-middleware-webfinger-cors.json b/apps/traefik/routes/mastodon-middleware-webfinger-cors.json new file mode 100644 index 0000000..2a0253c --- /dev/null +++ b/apps/traefik/routes/mastodon-middleware-webfinger-cors.json @@ -0,0 +1,15 @@ +{ + "apiVersion": "traefik.io/v1alpha1", + "kind": "Middleware", + "metadata": { + "name": "webfinger-cors", + "namespace": "mastodon" + }, + "spec": { + "headers": { + "customResponseHeaders": { + "Access-Control-Allow-Origin": "*" + } + } + } +} diff --git a/apps/traefik/routes/mastodon-middleware-webfinger-redirect.json b/apps/traefik/routes/mastodon-middleware-webfinger-redirect.json new file mode 100644 index 0000000..3d3b9ea --- /dev/null +++ b/apps/traefik/routes/mastodon-middleware-webfinger-redirect.json @@ -0,0 +1,15 @@ +{ + "apiVersion": "traefik.io/v1alpha1", + "kind": "Middleware", + "metadata": { + "name": "webfinger-redirect", + "namespace": "mastodon" + }, + "spec": { + "redirectRegex": { + "permanent": true, + "regex": "^https://brunner\\.ninja/(.*)", + "replacement": "https://social.brunner.ninja/${1}" + } + } +} diff --git a/apps/traefik/routes/matrix-ingressroute-matrix-well-known.json b/apps/traefik/routes/matrix-ingressroute-matrix-well-known.json new file mode 100644 index 0000000..0e20975 --- /dev/null +++ b/apps/traefik/routes/matrix-ingressroute-matrix-well-known.json @@ -0,0 +1,34 @@ +{ + "apiVersion": "traefik.io/v1alpha1", + "kind": "IngressRoute", + "metadata": { + "name": "matrix-well-known", + "namespace": "matrix" + }, + "spec": { + "entryPoints": [ + "websecure" + ], + "routes": [ + { + "kind": "Rule", + "match": "Host(`brunner.ninja`) && (Path(`/.well-known/matrix/server`) || Path(`/.well-known/matrix/client`))", + "middlewares": [ + { + "name": "matrix-well-known-cors" + }, + { + "name": "matrix-well-known-rewrite" + } + ], + "priority": 1100, + "services": [ + { + "name": "element-web", + "port": "http" + } + ] + } + ] + } +} diff --git a/apps/traefik/routes/matrix-middleware-matrix-well-known-cors.json b/apps/traefik/routes/matrix-middleware-matrix-well-known-cors.json new file mode 100644 index 0000000..58665dc --- /dev/null +++ b/apps/traefik/routes/matrix-middleware-matrix-well-known-cors.json @@ -0,0 +1,15 @@ +{ + "apiVersion": "traefik.io/v1alpha1", + "kind": "Middleware", + "metadata": { + "name": "matrix-well-known-cors", + "namespace": "matrix" + }, + "spec": { + "headers": { + "customResponseHeaders": { + "Access-Control-Allow-Origin": "*" + } + } + } +} diff --git a/apps/traefik/routes/matrix-middleware-matrix-well-known-rewrite.json b/apps/traefik/routes/matrix-middleware-matrix-well-known-rewrite.json new file mode 100644 index 0000000..a94bf2b --- /dev/null +++ b/apps/traefik/routes/matrix-middleware-matrix-well-known-rewrite.json @@ -0,0 +1,14 @@ +{ + "apiVersion": "traefik.io/v1alpha1", + "kind": "Middleware", + "metadata": { + "name": "matrix-well-known-rewrite", + "namespace": "matrix" + }, + "spec": { + "replacePathRegex": { + "regex": "^/\\.well-known/matrix/(server|client)$", + "replacement": "/matrix-well-known/${1}.json" + } + } +} diff --git a/apps/traefik/routes/nextcloud-middleware-nextcloud-security-headers.json b/apps/traefik/routes/nextcloud-middleware-nextcloud-security-headers.json new file mode 100644 index 0000000..bc5529e --- /dev/null +++ b/apps/traefik/routes/nextcloud-middleware-nextcloud-security-headers.json @@ -0,0 +1,15 @@ +{ + "apiVersion": "traefik.io/v1alpha1", + "kind": "Middleware", + "metadata": { + "name": "nextcloud-security-headers", + "namespace": "nextcloud" + }, + "spec": { + "headers": { + "stsIncludeSubdomains": false, + "stsPreload": false, + "stsSeconds": 31536000 + } + } +} diff --git a/apps/traefik/routes/nextcloud-middleware-strip-push-prefix.json b/apps/traefik/routes/nextcloud-middleware-strip-push-prefix.json new file mode 100644 index 0000000..252ff17 --- /dev/null +++ b/apps/traefik/routes/nextcloud-middleware-strip-push-prefix.json @@ -0,0 +1,15 @@ +{ + "apiVersion": "traefik.io/v1alpha1", + "kind": "Middleware", + "metadata": { + "name": "strip-push-prefix", + "namespace": "nextcloud" + }, + "spec": { + "stripPrefix": { + "prefixes": [ + "/push" + ] + } + } +} diff --git a/apps/traefik/routes/ollama-ingressroute-open-webui.json b/apps/traefik/routes/ollama-ingressroute-open-webui.json new file mode 100644 index 0000000..d494caa --- /dev/null +++ b/apps/traefik/routes/ollama-ingressroute-open-webui.json @@ -0,0 +1,30 @@ +{ + "apiVersion": "traefik.io/v1alpha1", + "kind": "IngressRoute", + "metadata": { + "name": "open-webui", + "namespace": "ollama", + "labels": { + "app.kubernetes.io/name": "open-webui", + "app.kubernetes.io/part-of": "ollama-chat" + } + }, + "spec": { + "entryPoints": [ + "websecure" + ], + "routes": [ + { + "kind": "Rule", + "match": "Host(`chat.brunner.ninja`)", + "services": [ + { + "kind": "Service", + "name": "open-webui", + "port": "http" + } + ] + } + ] + } +} diff --git a/apps/traefik/routes/pixelfed-ingressroute-pixels-brunner-ninja.json b/apps/traefik/routes/pixelfed-ingressroute-pixels-brunner-ninja.json new file mode 100644 index 0000000..f2aeb99 --- /dev/null +++ b/apps/traefik/routes/pixelfed-ingressroute-pixels-brunner-ninja.json @@ -0,0 +1,29 @@ +{ + "apiVersion": "traefik.io/v1alpha1", + "kind": "IngressRoute", + "metadata": { + "name": "pixels-brunner-ninja", + "namespace": "pixelfed", + "labels": { + "app.kubernetes.io/part-of": "pixelfed" + } + }, + "spec": { + "entryPoints": [ + "websecure" + ], + "routes": [ + { + "kind": "Rule", + "match": "Host(`pixels.brunner.ninja`)", + "services": [ + { + "name": "pixelfed-web", + "port": 80 + } + ] + } + ], + "tls": {} + } +} diff --git a/apps/traefik/routes/plex-ingressroute-plex-brunner-ninja.json b/apps/traefik/routes/plex-ingressroute-plex-brunner-ninja.json new file mode 100644 index 0000000..307ad9b --- /dev/null +++ b/apps/traefik/routes/plex-ingressroute-plex-brunner-ninja.json @@ -0,0 +1,30 @@ +{ + "apiVersion": "traefik.io/v1alpha1", + "kind": "IngressRoute", + "metadata": { + "name": "plex-brunner-ninja", + "namespace": "plex", + "labels": { + "app.kubernetes.io/name": "plex" + } + }, + "spec": { + "entryPoints": [ + "websecure" + ], + "routes": [ + { + "kind": "Rule", + "match": "Host(`plex.brunner.ninja`)", + "services": [ + { + "kind": "Service", + "name": "plex", + "passHostHeader": true, + "port": "http" + } + ] + } + ] + } +} diff --git a/apps/traefik/values.yaml b/apps/traefik/values.yaml new file mode 100644 index 0000000..ac960d8 --- /dev/null +++ b/apps/traefik/values.yaml @@ -0,0 +1,175 @@ +deployment: + kind: Deployment + replicas: 2 +updateStrategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 0 + maxSurge: 1 +podDisruptionBudget: + enabled: true + minAvailable: 1 +resources: + requests: + cpu: 500m + memory: 1Gi +affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/name: traefik + app.kubernetes.io/instance: traefik-default + topologyKey: kubernetes.io/hostname +service: + enabled: true + annotations: + mikrotik.brunner.ninja/router: newgw + mikrotik.brunner.ninja/forwardings: >- + [{"name":"http","servicePort":"web","dstAddressList":"WANs"},{"name":"https","servicePort":"websecure","dstAddressList":"WANs"}] + spec: + type: LoadBalancer + loadBalancerIP: 192.168.0.10 + externalTrafficPolicy: Local + additionalServices: + funkfeuer: + spec: + type: ClusterIP + externalIPs: + - 10.12.4.170 +accessLog: + enabled: true + format: json + bufferingSize: 100 + fields: + defaultMode: keep + names: + ClientUsername: drop + headers: + defaultMode: drop + names: + User-Agent: keep + Referer: keep + queryParameters: + defaultMode: drop +metrics: + prometheus: + disableAPICheck: true + addEntryPointsLabels: true + addRoutersLabels: true + addServicesLabels: true + buckets: "0.005,0.01,0.025,0.05,0.1,0.25,0.5,1,2.5,5,10" + service: + enabled: true + labels: + app.kubernetes.io/part-of: traefik-observability + serviceMonitor: + enabled: true + interval: 30s + scrapeTimeout: 10s + additionalLabels: + release: prometheus +ports: + web: + expose: + default: true + funkfeuer: true + http: + redirections: + entryPoint: + to: websecure + scheme: https + permanent: true + websecure: + expose: + default: true + funkfeuer: true + http: + tls: + enabled: true + transport: + respondingTimeouts: + readTimeout: 3600 + writeTimeout: 3600 +ingressRoute: + dashboard: + enabled: true + matchRule: Host(`traefik.brunner.ninja`) + entryPoints: + - websecure +additionalArguments: +- --providers.redis.endpoints=valkey-primary.default.svc.cluster.local:6379 +- --providers.redis.password=$(REDIS_PASSWORD) +env: +- name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + name: valkey + key: valkey-password +persistence: + enabled: false +tlsStore: + default: + defaultCertificate: + secretName: brunner-ninja-tls +providers: + file: + enabled: true + content: + http: + routers: + growatt: + rule: "Host(`growatt.brunner.ninja`)" + service: growatt + entryPoints: [websecure] + opendtu: + rule: "Host(`opendtu.brunner.ninja`)" + service: opendtu + entryPoints: [websecure] + staubsauger: + rule: "Host(`staubsauger.brunner.ninja`)" + service: staubsauger + entryPoints: [websecure] + middlewares: [default-authentik@kubernetescrd] + victron: + rule: "Host(`victron.brunner.ninja`)" + service: victron + entryPoints: [websecure] + middlewares: [default-authentik@kubernetescrd] + victron-websockify: + rule: "Host(`victron.brunner.ninja`) && Path(`/websockify`)" + priority: 100 + service: victron-websockify-capture + entryPoints: [websecure] + middlewares: [default-authentik@kubernetescrd, victron-native-origin] + middlewares: + victron-native-origin: + headers: + customRequestHeaders: + Origin: "" + services: + growatt: + loadBalancer: + servers: + - url: http://192.168.0.252:8080 + opendtu: + loadBalancer: + servers: + - url: http://OpenDTU-AB9DF8.localdomain + staubsauger: + loadBalancer: + servers: + - url: http://rockrobo.localdomain + victron: + loadBalancer: + servers: + - url: http://nanopi.localdomain + victron-websockify-capture: + loadBalancer: + servers: + - url: http://192.168.0.93:8080 + kubernetesGateway: + enabled: true +gateway: + namespacePolicy: All + diff --git a/bootstrap/kustomization.yaml b/bootstrap/kustomization.yaml index d44df50..8bb857b 100644 --- a/bootstrap/kustomization.yaml +++ b/bootstrap/kustomization.yaml @@ -12,6 +12,8 @@ resources: - 30-birthday.yaml - phppgadmin.yaml - traefik-error-pages.yaml +- traefik-project.yaml +- traefik.yaml - mktxp.yaml - metrics-server-project.yaml - metrics-server.yaml diff --git a/bootstrap/traefik-project.yaml b/bootstrap/traefik-project.yaml new file mode 100644 index 0000000..a92cd15 --- /dev/null +++ b/bootstrap/traefik-project.yaml @@ -0,0 +1,69 @@ +apiVersion: argoproj.io/v1alpha1 +kind: AppProject +metadata: + name: traefik + namespace: argocd +spec: + description: Traefik ingress controller and cluster ingress integrations + sourceRepos: + - https://ghcr.io/traefik/helm + - https://code.brunner.ninja/feedc0de/homelab-gitops.git + destinations: + - namespace: default + server: https://kubernetes.default.svc + - namespace: garrysmod + server: https://kubernetes.default.svc + - namespace: jellyfin + server: https://kubernetes.default.svc + - namespace: kubernetes-dashboard + server: https://kubernetes.default.svc + - namespace: loops + server: https://kubernetes.default.svc + - namespace: mastodon + server: https://kubernetes.default.svc + - namespace: matrix + server: https://kubernetes.default.svc + - namespace: ollama + server: https://kubernetes.default.svc + - namespace: pixelfed + server: https://kubernetes.default.svc + - namespace: plex + server: https://kubernetes.default.svc + - namespace: nextcloud + server: https://kubernetes.default.svc + clusterResourceWhitelist: + - group: apiextensions.k8s.io + kind: CustomResourceDefinition + - group: gateway.networking.k8s.io + kind: GatewayClass + - group: rbac.authorization.k8s.io + kind: ClusterRole + - group: rbac.authorization.k8s.io + kind: ClusterRoleBinding + namespaceResourceWhitelist: + - group: "" + kind: Service + - group: "" + kind: ConfigMap + - group: "" + kind: Service + - group: "" + kind: ServiceAccount + - group: apps + kind: Deployment + - group: gateway.networking.k8s.io + kind: Gateway + - group: monitoring.coreos.com + kind: ServiceMonitor + - group: policy + kind: PodDisruptionBudget + - group: rbac.authorization.k8s.io + kind: Role + - group: rbac.authorization.k8s.io + kind: RoleBinding + - group: traefik.io + kind: IngressRoute + - group: traefik.io + kind: Middleware + - group: traefik.io + kind: TLSStore diff --git a/bootstrap/traefik.yaml b/bootstrap/traefik.yaml new file mode 100644 index 0000000..30433cd --- /dev/null +++ b/bootstrap/traefik.yaml @@ -0,0 +1,31 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: traefik + namespace: argocd +spec: + project: traefik + sources: + - repoURL: https://ghcr.io/traefik/helm + chart: traefik + targetRevision: 42.0.0 + helm: + releaseName: traefik + valueFiles: + - $values/apps/traefik/values.yaml + - repoURL: https://code.brunner.ninja/feedc0de/homelab-gitops.git + targetRevision: main + ref: values + - repoURL: https://code.brunner.ninja/feedc0de/homelab-gitops.git + targetRevision: main + path: apps/traefik/routes + destination: + server: https://kubernetes.default.svc + namespace: default + syncPolicy: + automated: + enabled: true + prune: false + selfHeal: true + syncOptions: + - CreateNamespace=false