From c0e11cd19fb73b0434b2a0e7a4fb6083371e8a3a Mon Sep 17 00:00:00 2001 From: Yury Hrytsuk <50014626+YuryHrytsuk@users.noreply.github.com> Date: Thu, 21 Nov 2024 14:46:41 +0100 Subject: [PATCH] vendors stack: support multiple domains & maintenance mode (#886) * vendors: support multiple domains + maintenance mode * include maintenance * Fix traefik rule --- scripts/common.Makefile | 12 ++++++++++++ services/maintenance-page/docker-compose.yml.j2 | 3 +-- services/maintenance-page/template.env | 1 + services/vendors/.gitignore | 1 + services/vendors/Makefile | 6 ++++++ .../{docker-compose.yml => docker-compose.yml.j2} | 4 +++- services/vendors/j2cli_customization.py | 11 +++++++++++ services/vendors/template.env | 3 ++- 8 files changed, 37 insertions(+), 4 deletions(-) create mode 100644 services/vendors/.gitignore rename services/vendors/{docker-compose.yml => docker-compose.yml.j2} (85%) create mode 100644 services/vendors/j2cli_customization.py diff --git a/scripts/common.Makefile b/scripts/common.Makefile index 82d27190..8e706fc6 100644 --- a/scripts/common.Makefile +++ b/scripts/common.Makefile @@ -245,10 +245,22 @@ clean-default: .check_clean ## Cleans all outputs @.venv/bin/pip3 install --upgrade pip wheel setuptools @.venv/bin/pip3 install jinja2 j2cli[yaml] + +# https://github.com/kolypto/j2cli?tab=readme-ov-file#customization +ifeq ($(shell test -f j2cli_customization.py && echo -n yes),yes) + +define jinja + .venv/bin/j2 --format=env $(1) .env -o $(2) --customize j2cli_customization.py +endef + +else + define jinja .venv/bin/j2 --format=env $(1) .env -o $(2) endef +endif + # Gracefully use defaults and potentially overwrite them, via https://stackoverflow.com/a/49804748 %: %-default @ true diff --git a/services/maintenance-page/docker-compose.yml.j2 b/services/maintenance-page/docker-compose.yml.j2 index dac0307f..a119e5fc 100644 --- a/services/maintenance-page/docker-compose.yml.j2 +++ b/services/maintenance-page/docker-compose.yml.j2 @@ -28,8 +28,7 @@ services: - traefik.enable=true - traefik.docker.network=${PUBLIC_NETWORK} - traefik.http.routers.{{"maintenance_" + j2item.replace('@','').replace(' ','').replace('.','').replace('-','').replace('\'','') + "_html"}}.priority={{MAINTENANCE_PAGES_TRAEFIK_PRIORITY}} - - traefik.http.routers.{{"maintenance_" + j2item.replace('@','').replace(' ','').replace('.','').replace('-','').replace('\'','') + "_html"}}.rule={{ "Host(`" + j2item + "`)" }} - - traefik.http.routers.{{"maintenance_" + j2item.replace('@','').replace(' ','').replace('.','').replace('-','').replace('\'','') + "_html"}}.rule=(Host(`{{j2item}}`) && PathPrefix(`/`)) || (HostRegexp(`services.{{j2item}}`,`{subhost:[a-zA-Z0-9-]+}.services.{{j2item}}`) && PathPrefix(`/`)) + - traefik.http.routers.{{"maintenance_" + j2item.replace('@','').replace(' ','').replace('.','').replace('-','').replace('\'','') + "_html"}}.rule=Host(`{{VENDOR_MANUAL_SUBDOMAIN_PREFIX}}.{{j2item}}`) || (Host(`{{j2item}}`) && PathPrefix(`/`)) || (HostRegexp(`services.{{j2item}}`,`{subhost:[a-zA-Z0-9-]+}.services.{{j2item}}`) && PathPrefix(`/`)) - traefik.http.routers.{{"maintenance_" + j2item.replace('@','').replace(' ','').replace('.','').replace('-','').replace('\'','') + "_html"}}.tls=true - traefik.http.services.{{"maintenance_" + j2item.replace('@','').replace(' ','').replace('.','').replace('-','').replace('\'','') + "_html"}}.loadbalancer.server.port=80 - traefik.http.routers.{{"maintenance_" + j2item.replace('@','').replace(' ','').replace('.','').replace('-','').replace('\'','') + "_html"}}.entrypoints=https diff --git a/services/maintenance-page/template.env b/services/maintenance-page/template.env index 980494eb..33cd7ee6 100644 --- a/services/maintenance-page/template.env +++ b/services/maintenance-page/template.env @@ -8,3 +8,4 @@ PUBLIC_NETWORK=${PUBLIC_NETWORK} MONITORED_NETWORK=${MONITORED_NETWORK} REPO_CONFIG_LOCATION=${REPO_CONFIG_LOCATION} MAINTENANCE_PAGES_TRAEFIK_PRIORITY=${MAINTENANCE_PAGES_TRAEFIK_PRIORITY} +VENDOR_MANUAL_SUBDOMAIN_PREFIX=${VENDOR_MANUAL_SUBDOMAIN_PREFIX} diff --git a/services/vendors/.gitignore b/services/vendors/.gitignore new file mode 100644 index 00000000..1120be9a --- /dev/null +++ b/services/vendors/.gitignore @@ -0,0 +1 @@ +docker-compose.yml diff --git a/services/vendors/Makefile b/services/vendors/Makefile index 5643540a..f65c210b 100644 --- a/services/vendors/Makefile +++ b/services/vendors/Makefile @@ -30,6 +30,12 @@ up-local: up # Helpers ------------------------------------------------- +.PHONY: docker-compose.yml +docker-compose.yml: .venv .env + @$(call jinja, docker-compose.yml.j2, docker-compose.yml.unlinted) && \ + $(_yq) docker-compose.yml.unlinted > docker-compose.yml; \ + rm docker-compose.yml.unlinted >/dev/null 2>&1; + .PHONY: ${TEMP_COMPOSE} ${TEMP_COMPOSE}: docker-compose.yml .env ${REPO_BASE_DIR}/scripts/docker-stack-config.bash -e .env $< > $@ diff --git a/services/vendors/docker-compose.yml b/services/vendors/docker-compose.yml.j2 similarity index 85% rename from services/vendors/docker-compose.yml rename to services/vendors/docker-compose.yml.j2 index 14a21cab..12b86cdf 100644 --- a/services/vendors/docker-compose.yml +++ b/services/vendors/docker-compose.yml.j2 @@ -4,7 +4,9 @@ services: manual: image: ${VENDOR_MANUAL_IMAGE} init: true +{%- raw %} hostname: "{{.Node.Hostname}}-{{.Task.Slot}}" +{%- endraw %} deploy: replicas: ${VENDOR_MANUAL_REPLICAS} placement: @@ -28,7 +30,7 @@ services: - traefik.http.services.vendor_manual.loadbalancer.server.port=${VENDOR_MANUAL_PORT} - traefik.http.routers.vendor_manual.entrypoints=https - traefik.http.routers.vendor_manual.tls=true - - traefik.http.routers.vendor_manual.rule=Host(`${VENDOR_MANUAL_DOMAIN}`) + - traefik.http.routers.vendor_manual.rule={{ generate_vendors_manual_traefik_rule(VENDOR_MANUAL_PRODUCTS, VENDOR_MANUAL_SUBDOMAIN_PREFIX) }} - traefik.http.routers.vendor_manual.middlewares=ops_gzip@swarm, authenticated_platform_user@swarm networks: - public diff --git a/services/vendors/j2cli_customization.py b/services/vendors/j2cli_customization.py new file mode 100644 index 00000000..802597bf --- /dev/null +++ b/services/vendors/j2cli_customization.py @@ -0,0 +1,11 @@ +def _generate_vendors_manual_traefik_rule(domains: str, subdomain_prefix: str) -> str: + domain_list = domains.strip().strip(",").split(",") + domains = [f"{subdomain_prefix}.{domain}" for domain in domain_list] + return " || ".join(f"Host(`{d}`)" for d in domains) + + +def j2_environment(env): + env.globals.update( + generate_vendors_manual_traefik_rule=_generate_vendors_manual_traefik_rule + ) + return env diff --git a/services/vendors/template.env b/services/vendors/template.env index 65765548..7086513a 100644 --- a/services/vendors/template.env +++ b/services/vendors/template.env @@ -1,5 +1,6 @@ VENDOR_MANUAL_IMAGE=${VENDOR_MANUAL_IMAGE} VENDOR_MANUAL_REPLICAS=${VENDOR_MANUAL_REPLICAS} -VENDOR_MANUAL_DOMAIN=${VENDOR_MANUAL_DOMAIN} +VENDOR_MANUAL_SUBDOMAIN_PREFIX=${VENDOR_MANUAL_SUBDOMAIN_PREFIX} +VENDOR_MANUAL_PRODUCTS=${VENDOR_MANUAL_PRODUCTS} VENDOR_MANUAL_PORT=${VENDOR_MANUAL_PORT} PUBLIC_NETWORK=${PUBLIC_NETWORK}