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)