feat: Add internal redirects

This commit is contained in:
Tony Du 2025-02-11 12:08:45 -08:00
parent b2e579f88e
commit d76acef206
18 changed files with 131 additions and 29 deletions

View File

@ -3,3 +3,4 @@ apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization kind: Kustomization
resources: resources:
- bitnami-repository.yaml - bitnami-repository.yaml
- middlewares

View File

@ -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.

View File

@ -26,6 +26,8 @@ spec:
routes: routes:
- match: Host(`media.tonydu.me`) - match: Host(`media.tonydu.me`)
kind: Rule kind: Rule
middlewares:
- name: redirect-tonydu-me-mnke-org
services: services:
- kind: Service - kind: Service
name: jellyfin-tonydu-external name: jellyfin-tonydu-external

View File

@ -4,5 +4,5 @@ kind: Kustomization
resources: resources:
- jellyfin-mnke.yaml - jellyfin-mnke.yaml
- jellyfin-tonydu.yaml - jellyfin-tonydu.yaml
- seerr-tonydu.yaml - seerr-mnke.yaml
- seerr-mnke.yaml - seerr-tonydu.yaml

View File

@ -26,6 +26,8 @@ spec:
routes: routes:
- match: Host(`seerr.tonydu.me`) - match: Host(`seerr.tonydu.me`)
kind: Rule kind: Rule
middlewares:
- name: redirect-tonydu-me-mnke-org
services: services:
- kind: Service - kind: Service
name: seerr-tonydu-external name: seerr-tonydu-external

View File

@ -2,5 +2,4 @@
apiVersion: kustomize.config.k8s.io/v1beta1 apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization kind: Kustomization
resources: resources:
- generated - build
# - middlewares

View File

@ -1,6 +1,7 @@
#!/usr/bin/env python3
from argparse import ArgumentParser from argparse import ArgumentParser
from sys import stderr from sys import stderr
from jinja2 import Template from jinja2 import Environment, FileSystemLoader, Template
from os import path from os import path
from yaml import safe_load from yaml import safe_load
@ -10,12 +11,6 @@ def load_config(config_path):
file.close() file.close()
return config 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): def write_file(filename, content, dry_run):
if dry_run: if dry_run:
print(f'### Would generate {filename} ###', file=stderr) print(f'### Would generate {filename} ###', file=stderr)
@ -39,7 +34,8 @@ def main(args):
template_path = args.template template_path = args.template
output_path = args.output 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) config = load_config(config_path)
@ -61,22 +57,20 @@ def main(args):
write_file(kustomization_filename, kustomization_content, dry_run) write_file(kustomization_filename, kustomization_content, dry_run)
if __name__ == '__main__': if __name__ == '__main__':
default_config_path = path.join(path.dirname(__file__), 'config', 'config.yaml') default_config_path = path.join(path.dirname(__file__), 'values.yaml')
default_template_path = path.join(path.dirname(__file__), 'templates', 'proxy.yaml.j2') default_template_path = path.join(path.dirname(__file__), 'templates')
default_output_path = path.normpath(path.join(path.dirname(__file__), '..', 'generated')) default_output_path = path.normpath(path.join(path.dirname(__file__), '..', 'build'))
parser = ArgumentParser( parser = ArgumentParser(
prog='External Reverse Proxy Generator', prog='External Reverse Proxy Generator',
description='Generate reverse proxy manifests', description='Generate reverse proxy manifests',
) )
parser.add_argument( parser.add_argument(
'-n',
'--dry-run', '--dry-run',
action='store_true', action='store_true',
help='Print generated manifests instead of writing them to disk' help='Print generated manifests instead of writing them to disk'
) )
parser.add_argument( parser.add_argument(
'-k',
'--skip-kustomize', '--skip-kustomize',
action='store_true', action='store_true',
help='Skip generation of kustomization.yaml file' help='Skip generation of kustomization.yaml file'

View File

@ -27,6 +27,15 @@ spec:
{%- for listen_host in listen_hosts %} {%- for listen_host in listen_hosts %}
- match: Host(`{{ listen_host }}`) - match: Host(`{{ listen_host }}`)
kind: Rule 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: services:
- kind: Service - kind: Service
name: {{ service_name }}-external name: {{ service_name }}-external

View File

@ -2,6 +2,11 @@ x-jellyfin: &jellyfin
upstream_host: jellyfin.home.mnke.org upstream_host: jellyfin.home.mnke.org
upstream_port: 8096 upstream_port: 8096
x-seerr: &seerr
upstream_host: seerr.jumper.mnke.org
upstream_port: 443
pass_host_header: false
proxies: proxies:
- <<: *jellyfin - <<: *jellyfin
service_name: jellyfin-mnke service_name: jellyfin-mnke
@ -15,17 +20,18 @@ proxies:
service_name: jellyfin-tonydu service_name: jellyfin-tonydu
tls_secret_name: wildcard-tonydu-me-tls tls_secret_name: wildcard-tonydu-me-tls
listen_host: media.tonydu.me listen_host: media.tonydu.me
middlewares:
- name: redirect-tonydu-me-mnke-org
- service_name: seerr-tonydu - <<: *seerr
tls_secret_name: wildcard-tonydu-me-tls service_name: seerr-mnke
listen_host: seerr.tonydu.me
upstream_host: seerr.jumper.mnke.org
upstream_port: 443
pass_host_header: false
- service_name: seerr-mnke
tls_secret_name: wildcard-mnke-org-tls tls_secret_name: wildcard-mnke-org-tls
listen_host: seerr.mnke.org listen_host: seerr.mnke.org
upstream_host: seerr.jumper.mnke.org
upstream_port: 443 - <<: *seerr
pass_host_header: false service_name: seerr-tonydu
tls_secret_name: wildcard-tonydu-me-tls
listen_host: seerr.tonydu.me
middlewares:
- name: redirect-tonydu-me-mnke-org

View File

@ -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

View File

@ -0,0 +1,5 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- blog-tonydu.yaml

View File

@ -0,0 +1,7 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- middlewares
- internal
- external

View File

@ -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

View File

@ -0,0 +1,6 @@
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- authentik.yaml
- redirect-tonydu-me-mnke-org.yaml

View File

@ -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}

View File

@ -5,4 +5,4 @@ resources:
- common - common
- uptime-kuma - uptime-kuma
- ghost - ghost
- external-reverse-proxies - ingressroutes