import os import yaml 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) -> yaml: # Load the Docker Compose file with open(dockerComposeFile, 'r') as file: docker_compose = yaml.safe_load(file) return docker_compose def getExposedPortsFromDockerComposeFile(dockerComposeFile: str): exposedPorts = [] services = readDockerComposeFile(dockerComposeFile).get('services', {}) # Iterate through services to find ports for service, config in services.items(): ports = config.get('ports', []) for port in ports: # Split the port mapping if it's in the "host:container" format exposedPort = port.split(':')[0] # Get the host port exposedPorts.append(exposedPort) return exposedPorts def checkPortUnique(ports: dict) -> bool: portNumbers = [] wrong = False for project in ports: for port in ports[project]: if port in portNumbers: if not wrong: print("\n\nšŸ”“ Some ports are not unique šŸ–\n") print(f"šŸ”“ ERROR : Port *{port}* is not unique") wrong = True for project2 in ports: if port in ports[project2]: print(f"\t{project} and {project2}") portNumbers.append(port) return wrong def main(watchFolder: str): # For each folder, read docker-compose.yaml and look for exposed ports dockerComposeList = recursiveSearchForDockerComposeFiles(watchFolder) ports = {} for dockerComposeFile in dockerComposeList: # Get exposed ports exposedPorts = getExposedPortsFromDockerComposeFile(dockerComposeFile) ports[dockerComposeFile] = exposedPorts if len(exposedPorts) == 0: print(f"\nšŸ“¦ {dockerComposeFile}" f"\nšŸ”“ No exposed ports found" f"\n") else: print(f"\nšŸ“¦ {dockerComposeFile}" f"\nšŸ”— Exposed ports: {exposedPorts}" f"\n") wrong = checkPortUnique(ports) if wrong: exit(1) else: print("\n\nāœ… All ports 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)