commit f4dd0870c0ffc79783aa3951fe8993de4ddebc16 Author: Jake Howard Date: Fri Aug 18 17:54:34 2023 +0100 Add consumers for Traefik and Dokku diff --git a/create-nginx-map.py b/create-nginx-map.py new file mode 100644 index 0000000..46bdcaa --- /dev/null +++ b/create-nginx-map.py @@ -0,0 +1,59 @@ +import requests +from typing import NamedTuple +import re + +TRAEFIK_HOST_RE = re.compile(r"Host\(`([a-z0-9\.-]+)`\)") + +class Route(NamedTuple): + name: str + destination: str + hostname: str + + +def get_traefik_routes(traefik_host: str, traefik_route: str): + api_response = requests.get(f"{traefik_host}/api/http/routers").json() + routes = set() + + for router in api_response: + if "Host(" not in router["rule"]: + continue + + hosts = TRAEFIK_HOST_RE.findall(router["rule"]) + + if not hosts: + raise ValueError(f"Failed to find host for {router['rule']}") + + routes.add(Route( + router["service"], + traefik_route, + hosts[0] + )) + + return routes + +def get_dokku_routes(dokku_exporter_url: str, dokku_route: str): + api_response = requests.get(dokku_exporter_url).json() + + routes = set() + + for app in api_response: + for vhost in app["vhosts"]: + routes.add(Route( + app["app"], + dokku_route, + vhost + )) + + return routes + + +def main(): + routes = [] + routes.extend(get_traefik_routes("http://10.23.1.103:8080", "http://10.23.1.103")) + routes.extend(get_dokku_routes("http://10.23.2.3:8000", "http://10.23.2.3")) + + for route in sorted(routes): + print(f"{route.hostname}\t{route.destination}; # {route.name}") + +if __name__ == "__main__": + main() diff --git a/dokku-exporter.py b/dokku-exporter.py new file mode 100644 index 0000000..8a69fca --- /dev/null +++ b/dokku-exporter.py @@ -0,0 +1,58 @@ +from pathlib import Path +from http.server import BaseHTTPRequestHandler, HTTPServer +import json + + +class DokkuHostnameExporter(BaseHTTPRequestHandler): + DOKKU_HOME = Path("~dokku").expanduser().resolve() + VHOST_FILE_NAME = "VHOST" + + def version_string(self) -> str: + return "Magic" + + def do_GET(self): + lines = [] + + for app_dir in self.DOKKU_HOME.iterdir(): + if not app_dir.is_dir(): + continue + + host_file = app_dir / self.VHOST_FILE_NAME + + try: + if not host_file.is_file(): + continue + except PermissionError: + continue + + vhosts = host_file.read_text().splitlines() + + if not vhosts: + continue + + lines.append({ + "app": app_dir.name, + "vhosts": vhosts + }) + + data = json.dumps(lines) + + self.send_response(200) + self.send_header("Content-type", "application/json") + self.end_headers() + self.wfile.write(data.encode()) + +def main(): + web_server = HTTPServer(("0.0.0.0", 8000), DokkuHostnameExporter) + + try: + web_server.serve_forever() + except KeyboardInterrupt: + pass + + web_server.server_close() + print("Server stopped.") + + +if __name__ == "__main__": + main()