From d76acef206eb7f5a5a7a258ca928ce3da0c4e54a Mon Sep 17 00:00:00 2001 From: Tony Du Date: Tue, 11 Feb 2025 12:08:45 -0800 Subject: [PATCH] feat: Add internal redirects --- k8s/apps/common/kustomization.yaml | 1 + k8s/apps/ingressroutes/external/README.md | 19 +++++++++++++ .../external/build}/jellyfin-mnke.yaml | 0 .../external/build}/jellyfin-tonydu.yaml | 2 ++ .../external/build}/kustomization.yaml | 4 +-- .../external/build}/seerr-mnke.yaml | 0 .../external/build}/seerr-tonydu.yaml | 2 ++ .../external}/kustomization.yaml | 3 +- .../external/templater/main.py} | 20 +++++-------- .../external/templater/templates/proxy.yaml} | 9 ++++++ .../external/templater/values.yaml} | 28 +++++++++++-------- .../ingressroutes/internal/blog-tonydu.yaml | 21 ++++++++++++++ .../ingressroutes/internal/kustomization.yaml | 5 ++++ k8s/apps/ingressroutes/kustomization.yaml | 7 +++++ .../ingressroutes/middlewares/authentik.yaml | 21 ++++++++++++++ .../middlewares/kustomization.yaml | 6 ++++ .../redirect-tonydu-me-mnke-org.yaml | 10 +++++++ k8s/apps/kustomization.yaml | 2 +- 18 files changed, 131 insertions(+), 29 deletions(-) create mode 100644 k8s/apps/ingressroutes/external/README.md rename k8s/apps/{external-reverse-proxies/generated => ingressroutes/external/build}/jellyfin-mnke.yaml (100%) rename k8s/apps/{external-reverse-proxies/generated => ingressroutes/external/build}/jellyfin-tonydu.yaml (92%) rename k8s/apps/{external-reverse-proxies/generated => ingressroutes/external/build}/kustomization.yaml (75%) rename k8s/apps/{external-reverse-proxies/generated => ingressroutes/external/build}/seerr-mnke.yaml (100%) rename k8s/apps/{external-reverse-proxies/generated => ingressroutes/external/build}/seerr-tonydu.yaml (92%) rename k8s/apps/{external-reverse-proxies => ingressroutes/external}/kustomization.yaml (71%) rename k8s/apps/{external-reverse-proxies/codegen/generator.py => ingressroutes/external/templater/main.py} (86%) mode change 100644 => 100755 rename k8s/apps/{external-reverse-proxies/codegen/templates/proxy.yaml.j2 => ingressroutes/external/templater/templates/proxy.yaml} (74%) rename k8s/apps/{external-reverse-proxies/codegen/config/config.yaml => ingressroutes/external/templater/values.yaml} (64%) create mode 100644 k8s/apps/ingressroutes/internal/blog-tonydu.yaml create mode 100644 k8s/apps/ingressroutes/internal/kustomization.yaml create mode 100644 k8s/apps/ingressroutes/kustomization.yaml create mode 100644 k8s/apps/ingressroutes/middlewares/authentik.yaml create mode 100644 k8s/apps/ingressroutes/middlewares/kustomization.yaml create mode 100644 k8s/apps/ingressroutes/middlewares/redirect-tonydu-me-mnke-org.yaml diff --git a/k8s/apps/common/kustomization.yaml b/k8s/apps/common/kustomization.yaml index b5b8fbb..2b90248 100644 --- a/k8s/apps/common/kustomization.yaml +++ b/k8s/apps/common/kustomization.yaml @@ -3,3 +3,4 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - bitnami-repository.yaml + - middlewares diff --git a/k8s/apps/ingressroutes/external/README.md b/k8s/apps/ingressroutes/external/README.md new file mode 100644 index 0000000..44917a1 --- /dev/null +++ b/k8s/apps/ingressroutes/external/README.md @@ -0,0 +1,19 @@ +# IngressRoutes + +These manifests define extra ingress routes, most notably routes that are +proxied external to the cluster. +To facilitate easier declaration, the manifests are generated by a +simple templating script with YAML configuration through Jinja templating. + +We decided on the templating solution over Helm because FluxCD, our GitOps tool, +requires a Helm repository to apply a Helm chart. We don't have a Helm +repository and it seems overkill to create even a simple Helm repository just +for a single chart. Additionally, creating a Helm repository creates another +point of failure and adds complexity in the GitOps pipeline. + +## Templating script + +By default, `templater/main.py` sources the config from `templater/values.yaml` +and emits the templated manifests into `build/`. + +Run `templater/main.py -h` for a full list of arguments. diff --git a/k8s/apps/external-reverse-proxies/generated/jellyfin-mnke.yaml b/k8s/apps/ingressroutes/external/build/jellyfin-mnke.yaml similarity index 100% rename from k8s/apps/external-reverse-proxies/generated/jellyfin-mnke.yaml rename to k8s/apps/ingressroutes/external/build/jellyfin-mnke.yaml diff --git a/k8s/apps/external-reverse-proxies/generated/jellyfin-tonydu.yaml b/k8s/apps/ingressroutes/external/build/jellyfin-tonydu.yaml similarity index 92% rename from k8s/apps/external-reverse-proxies/generated/jellyfin-tonydu.yaml rename to k8s/apps/ingressroutes/external/build/jellyfin-tonydu.yaml index 149372f..4b211f5 100644 --- a/k8s/apps/external-reverse-proxies/generated/jellyfin-tonydu.yaml +++ b/k8s/apps/ingressroutes/external/build/jellyfin-tonydu.yaml @@ -26,6 +26,8 @@ spec: routes: - match: Host(`media.tonydu.me`) kind: Rule + middlewares: + - name: redirect-tonydu-me-mnke-org services: - kind: Service name: jellyfin-tonydu-external diff --git a/k8s/apps/external-reverse-proxies/generated/kustomization.yaml b/k8s/apps/ingressroutes/external/build/kustomization.yaml similarity index 75% rename from k8s/apps/external-reverse-proxies/generated/kustomization.yaml rename to k8s/apps/ingressroutes/external/build/kustomization.yaml index c007d4b..735d218 100644 --- a/k8s/apps/external-reverse-proxies/generated/kustomization.yaml +++ b/k8s/apps/ingressroutes/external/build/kustomization.yaml @@ -4,5 +4,5 @@ kind: Kustomization resources: - jellyfin-mnke.yaml - jellyfin-tonydu.yaml - - seerr-tonydu.yaml - - seerr-mnke.yaml \ No newline at end of file + - seerr-mnke.yaml + - seerr-tonydu.yaml \ No newline at end of file diff --git a/k8s/apps/external-reverse-proxies/generated/seerr-mnke.yaml b/k8s/apps/ingressroutes/external/build/seerr-mnke.yaml similarity index 100% rename from k8s/apps/external-reverse-proxies/generated/seerr-mnke.yaml rename to k8s/apps/ingressroutes/external/build/seerr-mnke.yaml diff --git a/k8s/apps/external-reverse-proxies/generated/seerr-tonydu.yaml b/k8s/apps/ingressroutes/external/build/seerr-tonydu.yaml similarity index 92% rename from k8s/apps/external-reverse-proxies/generated/seerr-tonydu.yaml rename to k8s/apps/ingressroutes/external/build/seerr-tonydu.yaml index 062aaac..9ae663f 100644 --- a/k8s/apps/external-reverse-proxies/generated/seerr-tonydu.yaml +++ b/k8s/apps/ingressroutes/external/build/seerr-tonydu.yaml @@ -26,6 +26,8 @@ spec: routes: - match: Host(`seerr.tonydu.me`) kind: Rule + middlewares: + - name: redirect-tonydu-me-mnke-org services: - kind: Service name: seerr-tonydu-external diff --git a/k8s/apps/external-reverse-proxies/kustomization.yaml b/k8s/apps/ingressroutes/external/kustomization.yaml similarity index 71% rename from k8s/apps/external-reverse-proxies/kustomization.yaml rename to k8s/apps/ingressroutes/external/kustomization.yaml index cecdc53..fa6d59c 100644 --- a/k8s/apps/external-reverse-proxies/kustomization.yaml +++ b/k8s/apps/ingressroutes/external/kustomization.yaml @@ -2,5 +2,4 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - - generated - # - middlewares + - build diff --git a/k8s/apps/external-reverse-proxies/codegen/generator.py b/k8s/apps/ingressroutes/external/templater/main.py old mode 100644 new mode 100755 similarity index 86% rename from k8s/apps/external-reverse-proxies/codegen/generator.py rename to k8s/apps/ingressroutes/external/templater/main.py index b52109b..b798c25 --- a/k8s/apps/external-reverse-proxies/codegen/generator.py +++ b/k8s/apps/ingressroutes/external/templater/main.py @@ -1,6 +1,7 @@ +#!/usr/bin/env python3 from argparse import ArgumentParser from sys import stderr -from jinja2 import Template +from jinja2 import Environment, FileSystemLoader, Template from os import path from yaml import safe_load @@ -10,12 +11,6 @@ def load_config(config_path): file.close() return config -def load_proxy_template(template_path): - file = open(template_path, 'r') - template = Template(file.read()) - file.close() - return template - def write_file(filename, content, dry_run): if dry_run: print(f'### Would generate {filename} ###', file=stderr) @@ -39,7 +34,8 @@ def main(args): template_path = args.template output_path = args.output - template = load_proxy_template(template_path) + env = Environment(loader=FileSystemLoader(template_path)) + template = env.get_template('proxy.yaml') config = load_config(config_path) @@ -61,22 +57,20 @@ def main(args): write_file(kustomization_filename, kustomization_content, dry_run) if __name__ == '__main__': - default_config_path = path.join(path.dirname(__file__), 'config', 'config.yaml') - default_template_path = path.join(path.dirname(__file__), 'templates', 'proxy.yaml.j2') - default_output_path = path.normpath(path.join(path.dirname(__file__), '..', 'generated')) + default_config_path = path.join(path.dirname(__file__), 'values.yaml') + default_template_path = path.join(path.dirname(__file__), 'templates') + default_output_path = path.normpath(path.join(path.dirname(__file__), '..', 'build')) parser = ArgumentParser( prog='External Reverse Proxy Generator', description='Generate reverse proxy manifests', ) parser.add_argument( - '-n', '--dry-run', action='store_true', help='Print generated manifests instead of writing them to disk' ) parser.add_argument( - '-k', '--skip-kustomize', action='store_true', help='Skip generation of kustomization.yaml file' diff --git a/k8s/apps/external-reverse-proxies/codegen/templates/proxy.yaml.j2 b/k8s/apps/ingressroutes/external/templater/templates/proxy.yaml similarity index 74% rename from k8s/apps/external-reverse-proxies/codegen/templates/proxy.yaml.j2 rename to k8s/apps/ingressroutes/external/templater/templates/proxy.yaml index 398df23..22c7fe5 100644 --- a/k8s/apps/external-reverse-proxies/codegen/templates/proxy.yaml.j2 +++ b/k8s/apps/ingressroutes/external/templater/templates/proxy.yaml @@ -27,6 +27,15 @@ spec: {%- for listen_host in listen_hosts %} - match: Host(`{{ listen_host }}`) kind: Rule + {%- if middlewares is defined %} + middlewares: + {%- for middleware in middlewares %} + - name: {{ middleware.name }} + {%- if middleware.namespace is defined %} + namespace: {{ middleware.namespace }} + {%- endif %} + {%- endfor %} + {%- endif %} services: - kind: Service name: {{ service_name }}-external diff --git a/k8s/apps/external-reverse-proxies/codegen/config/config.yaml b/k8s/apps/ingressroutes/external/templater/values.yaml similarity index 64% rename from k8s/apps/external-reverse-proxies/codegen/config/config.yaml rename to k8s/apps/ingressroutes/external/templater/values.yaml index 7712e28..67cf98c 100644 --- a/k8s/apps/external-reverse-proxies/codegen/config/config.yaml +++ b/k8s/apps/ingressroutes/external/templater/values.yaml @@ -2,6 +2,11 @@ x-jellyfin: &jellyfin upstream_host: jellyfin.home.mnke.org upstream_port: 8096 +x-seerr: &seerr + upstream_host: seerr.jumper.mnke.org + upstream_port: 443 + pass_host_header: false + proxies: - <<: *jellyfin service_name: jellyfin-mnke @@ -15,17 +20,18 @@ proxies: service_name: jellyfin-tonydu tls_secret_name: wildcard-tonydu-me-tls listen_host: media.tonydu.me + middlewares: + - name: redirect-tonydu-me-mnke-org - - service_name: seerr-tonydu - tls_secret_name: wildcard-tonydu-me-tls - listen_host: seerr.tonydu.me - upstream_host: seerr.jumper.mnke.org - upstream_port: 443 - pass_host_header: false - - - service_name: seerr-mnke + - <<: *seerr + service_name: seerr-mnke tls_secret_name: wildcard-mnke-org-tls listen_host: seerr.mnke.org - upstream_host: seerr.jumper.mnke.org - upstream_port: 443 - pass_host_header: false + + - <<: *seerr + service_name: seerr-tonydu + tls_secret_name: wildcard-tonydu-me-tls + listen_host: seerr.tonydu.me + middlewares: + - name: redirect-tonydu-me-mnke-org + diff --git a/k8s/apps/ingressroutes/internal/blog-tonydu.yaml b/k8s/apps/ingressroutes/internal/blog-tonydu.yaml new file mode 100644 index 0000000..bcda2bf --- /dev/null +++ b/k8s/apps/ingressroutes/internal/blog-tonydu.yaml @@ -0,0 +1,21 @@ +--- +apiVersion: traefik.io/v1alpha1 +kind: IngressRoute +metadata: + name: blog-tonydu + namespace: default +spec: + entryPoints: + - websecure + routes: + - match: Host(`blog.tonydu.me`) + kind: Rule + middlewares: + - name: redirect-tonydu-me-mnke-org + services: + - kind: Service + name: ghost + port: http + passHostHeader: False + tls: + secretName: wildcard-tonydu-me-tls diff --git a/k8s/apps/ingressroutes/internal/kustomization.yaml b/k8s/apps/ingressroutes/internal/kustomization.yaml new file mode 100644 index 0000000..0c4c006 --- /dev/null +++ b/k8s/apps/ingressroutes/internal/kustomization.yaml @@ -0,0 +1,5 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - blog-tonydu.yaml diff --git a/k8s/apps/ingressroutes/kustomization.yaml b/k8s/apps/ingressroutes/kustomization.yaml new file mode 100644 index 0000000..bd65fdb --- /dev/null +++ b/k8s/apps/ingressroutes/kustomization.yaml @@ -0,0 +1,7 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - middlewares + - internal + - external diff --git a/k8s/apps/ingressroutes/middlewares/authentik.yaml b/k8s/apps/ingressroutes/middlewares/authentik.yaml new file mode 100644 index 0000000..ac7e291 --- /dev/null +++ b/k8s/apps/ingressroutes/middlewares/authentik.yaml @@ -0,0 +1,21 @@ +apiVersion: traefik.io/v1alpha1 +kind: Middleware +metadata: + name: authentik +spec: + forwardAuth: + address: https://authentik.mnke.org/auth/traefik + trustForwardHeader: true + 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 diff --git a/k8s/apps/ingressroutes/middlewares/kustomization.yaml b/k8s/apps/ingressroutes/middlewares/kustomization.yaml new file mode 100644 index 0000000..8bfb746 --- /dev/null +++ b/k8s/apps/ingressroutes/middlewares/kustomization.yaml @@ -0,0 +1,6 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - authentik.yaml + - redirect-tonydu-me-mnke-org.yaml diff --git a/k8s/apps/ingressroutes/middlewares/redirect-tonydu-me-mnke-org.yaml b/k8s/apps/ingressroutes/middlewares/redirect-tonydu-me-mnke-org.yaml new file mode 100644 index 0000000..1ff0eea --- /dev/null +++ b/k8s/apps/ingressroutes/middlewares/redirect-tonydu-me-mnke-org.yaml @@ -0,0 +1,10 @@ +--- +apiVersion: traefik.io/v1alpha1 +kind: Middleware +metadata: + name: redirect-tonydu-me-mnke-org +spec: + redirectRegex: + permanent: false + regex: ^https?://([a-zA-Z0-9]+)\.tonydu\.me(/)? + replacement: https://${1}.mnke.org${2} diff --git a/k8s/apps/kustomization.yaml b/k8s/apps/kustomization.yaml index 317cb44..2ec704d 100644 --- a/k8s/apps/kustomization.yaml +++ b/k8s/apps/kustomization.yaml @@ -5,4 +5,4 @@ resources: - common - uptime-kuma - ghost - - external-reverse-proxies + - ingressroutes