docker-services/.ci/port_attribution_watcher.py

81 lines
No EOL
2.7 KiB
Python

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)