From 4fa65ff87bd1229b3bff04967418e1eedd7a39ef Mon Sep 17 00:00:00 2001 From: Maurice Faber Date: Wed, 3 Apr 2024 12:33:13 +0200 Subject: [PATCH] refactor: merge traefik instances --- README.md | 6 +++--- db.yml.sample | 23 ++++------------------- lib/data.py | 7 +++++++ lib/data_test.py | 33 ++++++++++++++++++--------------- lib/models.py | 2 +- lib/proxy.py | 5 +++-- lib/proxy_test.py | 1 - lib/test_stubs.py | 19 ------------------- proxy/docker-compose.yml | 3 +-- proxy/tpl/docker-compose.yml.j2 | 4 ++-- 10 files changed, 39 insertions(+), 64 deletions(-) diff --git a/README.md b/README.md index b03eccb..69d7933 100644 --- a/README.md +++ b/README.md @@ -83,10 +83,10 @@ It is surely possible to deploy stateful services but beware that those might no ## Apps included -- minio/minio: S3 storage +- [traefik/traefik](https://github.com/traefik/traefik): the famous L7 routing proxy +- [minio/minio](https://github.com/minio/minio): S3 storage - [nubacuk/docker-openvpn](https://github.com/nuBacuk/docker-openvpn): vpn access to the host running this stack -- traefik/whoami: to check if headers are correctly passed along -- morriz/hello-world +- [traefik/whoami](https://github.com/traefik/whoami): to demonstrate that headers are correctly passed along ## Prerequisites diff --git a/db.yml.sample b/db.yml.sample index 7225dee..ea81feb 100644 --- a/db.yml.sample +++ b/db.yml.sample @@ -1,3 +1,7 @@ +versions: + traefik: v2.11 + crowdsec: v1.6.0 + plugins: crowdsec: enabled: false @@ -80,25 +84,6 @@ projects: restart: always volumes: - /etc/openvpn - - description: test project to demonstrate inter service connectivity - name: test - services: - - env: - TARGET: cost concerned people - INFORMANT: http://test-informant:8080 - host: master - image: otomi/nodejs-helloworld:v1.2.13 - ingress: - - domain: hello.example.com - volumes: - - /data/bla - - /etc/dida - - additional_properties: - cpus: 0.1 - env: - TARGET: boss - host: informant - image: otomi/nodejs-helloworld:v1.2.13 - description: whoami service name: whoami services: diff --git a/lib/data.py b/lib/data.py index aa15d55..b838c11 100644 --- a/lib/data.py +++ b/lib/data.py @@ -48,6 +48,13 @@ def validate_db() -> None: Project.model_validate(project) +def get_versions() -> Dict[str, Any]: + """Get versions of all images used in proxy setup""" + debug("Getting proxy image versions") + db = get_db() + return cast(Dict[str, Any], db["versions"]) + + def get_plugin_registry() -> PluginRegistry: """Get plugin registry.""" debug("Getting plugin registry") diff --git a/lib/data_test.py b/lib/data_test.py index 9a1ddbd..a3215a9 100644 --- a/lib/data_test.py +++ b/lib/data_test.py @@ -16,7 +16,7 @@ write_db, write_projects, ) -from lib.models import Env, Project, Service +from lib.models import Env, Ingress, Project, Service from lib.test_stubs import test_db, test_projects @@ -37,7 +37,12 @@ def test_write_db(self, mock_open: Mock, mock_yaml: Mock, _: Mock) -> None: # Assert that the mock functions were called correctly mock_yaml.dump.assert_called_once_with( - {"plugins": test_db["plugins"], "projects": test_db["projects"]}, mock_open() + { + "versions": {"traefik": "v2.11", "crowdsec": "v1.6.0"}, + "plugins": test_db["plugins"], + "projects": test_db["projects"], + }, + mock_open(), ) @mock.patch("lib.data.write_db") @@ -57,17 +62,15 @@ def test_write_projects(self, mock_write_db: Mock) -> None: def test_get_projects_with_filter(self, _: Mock) -> None: # Call the function under test - result = get_projects(lambda p, s: p.name == "test" and s.ingress) + result = get_projects(lambda p, s: p.name == "whoami" and s.ingress) # Assert the result expected_result = [ Project( - name="test", - description="test project to demonstrate inter service connectivity", - domain="hello.example.com", - entrypoint="master", + description="whoami service", + name="whoami", services=[ - test_projects[5].services[0], + Service(image="traefik/whoami:latest", ingress=[Ingress(domain="whoami.example.com")], host="web"), ], ), ] @@ -127,24 +130,24 @@ def test_upsert_nonexistent_project_fixed(self, mock_write_projects: Mock, mock_ # Upsert a project's service' env @mock.patch("lib.data.get_project", return_value=test_projects[5].model_copy()) - @mock.patch("lib.data.get_service", return_value=test_projects[5].services[1].model_copy()) + @mock.patch("lib.data.get_service", return_value=test_projects[5].services[0].model_copy()) @mock.patch("lib.data.upsert_service") def test_upsert_env(self, mock_upsert_service: Mock, mock_get_service: Mock, mock_get_project: Mock) -> None: - extra_env = Env(**{"TARGET": "sir", "x": 1, "y": 2}) + extra_env = Env(**{"OKI": "doki"}) # Call the function under test - upsert_env(project="test", service="informant", env=extra_env) + upsert_env(project="whoami", service="web", env=extra_env) # Assert that the mock functions were called correctly mock_get_project.assert_called_once() mock_get_service.assert_called_once() mock_upsert_service.assert_called_once_with( - "test", + "whoami", Service( env=extra_env, - image="otomi/nodejs-helloworld:v1.2.13", - host="informant", - additional_properties={"cpus": 0.1}, + image="traefik/whoami:latest", + ingress=[Ingress(domain="whoami.example.com")], + host="web", ), ) diff --git a/lib/models.py b/lib/models.py index cda4f8f..ade54f7 100644 --- a/lib/models.py +++ b/lib/models.py @@ -105,7 +105,7 @@ class Service(BaseModel): """The command to run in the service""" depends_on: List[str] = [] """A list of services to depend on""" - env: Env = None + env: Env = Env() """A dictionary of environment variables to pass to the service""" host: str """The host (name/ip) of the service""" diff --git a/lib/proxy.py b/lib/proxy.py index c7240ad..9079b3b 100644 --- a/lib/proxy.py +++ b/lib/proxy.py @@ -5,7 +5,7 @@ from dotenv import load_dotenv from jinja2 import Template -from lib.data import get_plugin_registry, get_project, get_projects +from lib.data import get_plugin_registry, get_project, get_projects, get_versions from lib.models import Protocol, ProxyProtocol, Router from lib.utils import run_command @@ -149,12 +149,13 @@ def write_config() -> None: def write_compose() -> None: plugin_registry = get_plugin_registry() + versions = get_versions() with open("proxy/tpl/docker-compose.yml.j2", encoding="utf-8") as f: t = f.read() tpl_compose = Template(t) tpl_compose.globals["Protocol"] = Protocol projects_hostport = get_projects(filter=lambda _, _2, i: bool(i.hostport)) - compose = tpl_compose.render(projects=projects_hostport, plugin_registry=plugin_registry) + compose = tpl_compose.render(versions=versions, projects=projects_hostport, plugin_registry=plugin_registry) with open("proxy/docker-compose.yml", "w", encoding="utf-8") as f: f.write(compose) diff --git a/lib/proxy_test.py b/lib/proxy_test.py index 9650532..add28b2 100644 --- a/lib/proxy_test.py +++ b/lib/proxy_test.py @@ -49,7 +49,6 @@ def test_get_terminate_map(self, _: Mock) -> None: # Assert the result expected_map = { "itsup.example.com": "172.17.0.1:8888", - "hello.example.com": "test-master:8080", "minio-api.example.com": "minio-app:9000", "minio-ui.example.com": "minio-app:9001", "vpn.example.com": "vpn-openvpn:1194", diff --git a/lib/test_stubs.py b/lib/test_stubs.py index 77cdc88..5e56d28 100644 --- a/lib/test_stubs.py +++ b/lib/test_stubs.py @@ -109,25 +109,6 @@ ), ], ), - Project( - description="test project to demonstrate inter service connectivity", - name="test", - services=[ - Service( - env={"TARGET": "cost concerned people", "INFORMANT": "http://test-informant:8080"}, - image="otomi/nodejs-helloworld:v1.2.13", - ingress=[Ingress(domain="hello.example.com")], - host="master", - volumes=["/data/bla", "/etc/dida"], - ), - Service( - env={"TARGET": "boss"}, - image="otomi/nodejs-helloworld:v1.2.13", - host="informant", - additional_properties={"cpus": 0.1}, - ), - ], - ), Project( description="whoami service", name="whoami", diff --git a/proxy/docker-compose.yml b/proxy/docker-compose.yml index 811287b..dd2105a 100755 --- a/proxy/docker-compose.yml +++ b/proxy/docker-compose.yml @@ -47,7 +47,7 @@ services: - /var/run/docker.sock:/var/run/docker.sock:ro traefik: - image: traefik:v2.11 + image: v2.11 container_name: traefik networks: - default @@ -59,7 +59,6 @@ services: - 8080:8080/tcp - 8443:8443/tcp - 1194:1194/udp - - 5432:5432/tcp volumes: - ./traefik/traefik.yml:/etc/traefik/traefik.yml:ro - ./traefik/dynamic:/etc/traefik/dynamic:ro diff --git a/proxy/tpl/docker-compose.yml.j2 b/proxy/tpl/docker-compose.yml.j2 index 2f97a1e..bb93b97 100755 --- a/proxy/tpl/docker-compose.yml.j2 +++ b/proxy/tpl/docker-compose.yml.j2 @@ -47,7 +47,7 @@ services: - /var/run/docker.sock:/var/run/docker.sock:ro traefik: - image: traefik:v2.11 + image: traefik/traefik:{{ versions.traefik }} container_name: traefik networks: - default @@ -76,7 +76,7 @@ services: - crowdsec crowdsec: - image: crowdsecurity/crowdsec:v1.6.0 + image: crowdsecurity/crowdsec:{{ versions.crowdsec }} container_name: crowdsec restart: unless-stopped networks: