fix: keep the nginx ingress annotations when the ingress controller is traefik #13
@@ -1,6 +1,6 @@
|
|||||||
# supaspin
|
# supaspin
|
||||||
|
|
||||||
Version 1.6.1
|
Version 1.6.2
|
||||||
|
|
||||||
Create, list, show and delete throwaway [Supabase](https://supabase.com) instances on a
|
Create, list, show and delete throwaway [Supabase](https://supabase.com) instances on a
|
||||||
single-node [microk8s](https://microk8s.io) server, from a terminal menu.
|
single-node [microk8s](https://microk8s.io) server, from a terminal menu.
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ import tty
|
|||||||
|
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
VERSION = "1.6.1"
|
VERSION = "1.6.2"
|
||||||
CONFIG_PATH = os.environ.get("SUPASPIN_CONFIG", "/etc/supaspin/config.yaml")
|
CONFIG_PATH = os.environ.get("SUPASPIN_CONFIG", "/etc/supaspin/config.yaml")
|
||||||
STATE_DIR = os.environ.get("SUPASPIN_STATE", "/var/lib/supaspin")
|
STATE_DIR = os.environ.get("SUPASPIN_STATE", "/var/lib/supaspin")
|
||||||
CHART_REPO = "https://supabase-community.github.io/supabase-kubernetes"
|
CHART_REPO = "https://supabase-community.github.io/supabase-kubernetes"
|
||||||
@@ -189,24 +189,27 @@ def buffering_middleware(n):
|
|||||||
|
|
||||||
|
|
||||||
def ingress_annotations(cfg, n):
|
def ingress_annotations(cfg, n):
|
||||||
"""Ingress annotations for instance n, shaped for the configured ingress controller.
|
"""Ingress annotations for instance n.
|
||||||
With Traefik the upload cap lives in a Middleware object created next to the instance
|
Both controllers' annotations are always present: an annotation only takes effect
|
||||||
and the ingress points at it; with nginx it is proxy-body-size, and the chart's own
|
when a controller of that family actually routes the ingress, so on a Traefik
|
||||||
rewrite-target default must be nullified or every API path breaks. The cert-manager
|
cluster the nginx keys sit inert (and vice versa) and nothing needs reconfiguring
|
||||||
annotation orders a certificate from the supaspin-letsencrypt issuer; without it the
|
when the router changes. The upload cap therefore lives in two places that agree:
|
||||||
TLS secret keeps whatever supaspin put there (a saved or a self-signed certificate)."""
|
proxy-body-size for nginx, and the Middleware object the traefik annotation points
|
||||||
|
at. The chart's own rewrite-target default must be nullified or every API path
|
||||||
|
breaks. The cert-manager annotation orders a certificate from the
|
||||||
|
supaspin-letsencrypt issuer; without it the TLS secret keeps whatever supaspin put
|
||||||
|
there (a saved or a self-signed certificate)."""
|
||||||
anns = {}
|
anns = {}
|
||||||
if cfg.get("lets_encrypt", True):
|
if cfg.get("lets_encrypt", True):
|
||||||
anns["cert-manager.io/cluster-issuer"] = ISSUER
|
anns["cert-manager.io/cluster-issuer"] = ISSUER
|
||||||
if cfg.get("ingress_controller", "nginx") == "traefik":
|
|
||||||
anns["traefik.ingress.kubernetes.io/router.middlewares"] = \
|
|
||||||
f"{namespace(n)}-{buffering_middleware(n)}@kubernetescrd"
|
|
||||||
else:
|
|
||||||
# The chart default rewrites every path to "/", which breaks all APIs; null removes it.
|
# The chart default rewrites every path to "/", which breaks all APIs; null removes it.
|
||||||
anns["nginx.ingress.kubernetes.io/rewrite-target"] = None
|
anns["nginx.ingress.kubernetes.io/rewrite-target"] = None
|
||||||
anns["nginx.ingress.kubernetes.io/proxy-body-size"] = "50m"
|
anns["nginx.ingress.kubernetes.io/proxy-body-size"] = "50m"
|
||||||
anns["nginx.ingress.kubernetes.io/proxy-read-timeout"] = "3600"
|
anns["nginx.ingress.kubernetes.io/proxy-read-timeout"] = "3600"
|
||||||
anns["nginx.ingress.kubernetes.io/proxy-send-timeout"] = "3600"
|
anns["nginx.ingress.kubernetes.io/proxy-send-timeout"] = "3600"
|
||||||
|
if cfg.get("ingress_controller", "nginx") == "traefik":
|
||||||
|
anns["traefik.ingress.kubernetes.io/router.middlewares"] = \
|
||||||
|
f"{namespace(n)}-{buffering_middleware(n)}@kubernetescrd"
|
||||||
return anns
|
return anns
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -216,13 +216,15 @@ class IngressShaping(unittest.TestCase):
|
|||||||
self.assertEqual(a["nginx.ingress.kubernetes.io/proxy-read-timeout"], "3600")
|
self.assertEqual(a["nginx.ingress.kubernetes.io/proxy-read-timeout"], "3600")
|
||||||
self.assertNotIn("traefik.ingress.kubernetes.io/router.middlewares", a)
|
self.assertNotIn("traefik.ingress.kubernetes.io/router.middlewares", a)
|
||||||
|
|
||||||
def test_traefik_native(self):
|
def test_traefik_also_keeps_nginx_annotations(self):
|
||||||
|
# The nginx keys must be present in traefik mode too: while nginx routes the
|
||||||
|
# ingress they enforce the cap, and they are inert the day Traefik takes over.
|
||||||
a = self.ann({"ingress_controller": "traefik"})
|
a = self.ann({"ingress_controller": "traefik"})
|
||||||
self.assertEqual(a["traefik.ingress.kubernetes.io/router.middlewares"],
|
self.assertEqual(a["traefik.ingress.kubernetes.io/router.middlewares"],
|
||||||
"supaspin-2-supa2-buffering@kubernetescrd")
|
"supaspin-2-supa2-buffering@kubernetescrd")
|
||||||
for nginx_key in ("rewrite-target", "proxy-body-size", "proxy-read-timeout",
|
self.assertIsNone(a["nginx.ingress.kubernetes.io/rewrite-target"])
|
||||||
"proxy-send-timeout"):
|
self.assertEqual(a["nginx.ingress.kubernetes.io/proxy-body-size"], "50m")
|
||||||
self.assertNotIn(f"nginx.ingress.kubernetes.io/{nginx_key}", a)
|
self.assertEqual(a["nginx.ingress.kubernetes.io/proxy-read-timeout"], "3600")
|
||||||
self.assertEqual(a["cert-manager.io/cluster-issuer"], "supaspin-letsencrypt")
|
self.assertEqual(a["cert-manager.io/cluster-issuer"], "supaspin-letsencrypt")
|
||||||
|
|
||||||
def test_lets_encrypt_off_drops_cert_manager_annotation(self):
|
def test_lets_encrypt_off_drops_cert_manager_annotation(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user