From 783d077a489d15dc239f82bead6bda5ab44f7142 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ma=C3=ABl=20Gramain?= <mael@enpls.org>
Date: Mon, 21 Oct 2024 20:38:51 +0200
Subject: [PATCH] ci for traefik labels uniqueness
---
.ci/traefik_label_watcher.py | 100 +++++++++++++++++++++++++++++++++++
1 file changed, 100 insertions(+)
create mode 100644 .ci/traefik_label_watcher.py
diff --git a/.ci/traefik_label_watcher.py b/.ci/traefik_label_watcher.py
new file mode 100644
index 0000000..dda93b0
--- /dev/null
+++ b/.ci/traefik_label_watcher.py
@@ -0,0 +1,100 @@
+import os
+from pathlib import Path
+
+def recursiveSearchForDockerComposeFiles(watchFolder: Path):
+ dockerComposeList = []
+ for root, _, files in os.walk(watchFolder):
+ for file in files:
+ if file == "docker-compose.yaml":
+ dockerComposeList.append(Path(root) / file)
+ return dockerComposeList
+
+def readDockerComposeFile(dockerComposeFile: Path) -> str:
+ with open(dockerComposeFile, "r") as file:
+ data = file.read()
+ return data
+
+def getTraefikLabelsFromDockerComposeFile(dockerComposeFile: str):
+ traefikLabels = []
+ # Find all traefik labels
+ d = readDockerComposeFile(dockerComposeFile)
+ lines = d.split("\n")
+ for line in lines:
+ if "traefik." in line:
+ traefikLabels.append(line)
+ return traefikLabels
+
+def parseTraefikLabels(traefikLabels: list):
+ s = {
+ "routers": [],
+ "services": [],
+ }
+ for label in traefikLabels:
+ if "traefik.http.routers" in label:
+ routerName = label.split(".")[3]
+ s["routers"].append(routerName)
+ elif "traefik.http.services" in label:
+ serviceName = label.split(".")[3]
+ s["services"].append(serviceName)
+ # Make unique
+ s["routers"] = list(set(s["routers"]))
+ s["services"] = list(set(s["services"]))
+ return s
+
+def checkLabelUnique(labels: dict) -> bool:
+ routerNames = []
+ wrong = False
+ for project in labels:
+ for router in labels[project]["routers"]:
+ if router in routerNames:
+ if not wrong:
+ print("\n\n Seems like some routers are not unique š\n")
+ print(f"š“ ERROR : Router *{router}* is not unique")
+ wrong = True
+ for project2 in labels:
+ if router in labels[project2]["routers"]:
+ print(f"\t{project} and {project2}")
+ routerNames.append(router)
+ return wrong
+def beautifulDisplayLabels(labels: dict, projectName: str):
+ print(f"\n======\nš§° Project: {projectName}")
+ print("šļø Routers:")
+ for router in labels["routers"]:
+ print(f"\t{router}")
+ if len(labels["services"]) != 0:
+ print("šļø Services:")
+ for service in labels["services"]:
+ print(f"\t{service}")
+
+def main(watchFolder: str):
+ # For each folder, read docker-compose.yaml and look for traefik labels
+ dockerComposeList = recursiveSearchForDockerComposeFiles(watchFolder)
+ labels = {}
+ for dockerComposeFile in dockerComposeList:
+ traefikLabels = getTraefikLabelsFromDockerComposeFile(dockerComposeFile)
+ if len(traefikLabels) == 0:
+ #print(f"No traefik labels found in {dockerComposeFile}")
+ continue
+ parsedTraefikLabels = parseTraefikLabels(traefikLabels)
+ projectName = dockerComposeFile.parent.name
+ labels[projectName] = parsedTraefikLabels
+ beautifulDisplayLabels(parsedTraefikLabels, projectName)
+ # Check if all routers are unique
+ wrong = checkLabelUnique(labels)
+
+ if wrong:
+ exit(1)
+ else:
+ print("\n\nā
All routers are unique\n\n")
+ exit(0)
+
+if __name__ == "__main__":
+ print("Traefik label watcher CI/CD")
+ # Read folder from env
+ watchFolder = os.getenv("WATCH_FOLDER")
+ if watchFolder == None:
+ watchFolder = "."
+
+ watchFolder = Path(watchFolder)
+
+ main(watchFolder)
\ No newline at end of file