From 01bba1d3f67603cbc79845383fc99c5790373223 Mon Sep 17 00:00:00 2001 From: bunkerity Date: Wed, 28 Jul 2021 11:56:45 +0200 Subject: [PATCH] autoconf - init refactoring before k8s integration --- autoconf/{ => src}/AutoConf.py | 0 autoconf/{ => src}/Config.py | 0 autoconf/src/Controller.py | 23 ++++++++++++++++++ autoconf/src/DockerController.py | 32 +++++++++++++++++++++++++ autoconf/{ => src}/IngressController.py | 26 ++++++++++---------- autoconf/{ => src}/ReloadServer.py | 0 autoconf/{ => src}/app.py | 22 ++++++++--------- autoconf/{ => src}/utils.py | 0 8 files changed, 79 insertions(+), 24 deletions(-) rename autoconf/{ => src}/AutoConf.py (100%) rename autoconf/{ => src}/Config.py (100%) create mode 100644 autoconf/src/Controller.py create mode 100644 autoconf/src/DockerController.py rename autoconf/{ => src}/IngressController.py (89%) rename autoconf/{ => src}/ReloadServer.py (100%) rename autoconf/{ => src}/app.py (80%) rename autoconf/{ => src}/utils.py (100%) diff --git a/autoconf/AutoConf.py b/autoconf/src/AutoConf.py similarity index 100% rename from autoconf/AutoConf.py rename to autoconf/src/AutoConf.py diff --git a/autoconf/Config.py b/autoconf/src/Config.py similarity index 100% rename from autoconf/Config.py rename to autoconf/src/Config.py diff --git a/autoconf/src/Controller.py b/autoconf/src/Controller.py new file mode 100644 index 0000000..1b896eb --- /dev/null +++ b/autoconf/src/Controller.py @@ -0,0 +1,23 @@ +from abc import ABC, abstractmethod +from Config import Config + +class ControllerType(Enum) : + DOCKER = 1 + SWARM = 2 + KUBERNETES = 3 + +class Controller(ABC) : + + def __init__(self, type) : + self.__config = Config.from_controller_type(type) + + @abstractmethod + def get_env(self) : + pass + + def gen_conf(self, env) : + return self.__config.gen(env) + + @abstractmethod + def process_events(self) : + pass diff --git a/autoconf/src/DockerController.py b/autoconf/src/DockerController.py new file mode 100644 index 0000000..14c9de3 --- /dev/null +++ b/autoconf/src/DockerController.py @@ -0,0 +1,32 @@ +import docker +from Controller import Controller, ControllerType +import utils + +class DockerController(Controller) : + + def __init__(self) : + super().__init__(ControllerType.DOCKER) + # TODO : honor env vars like DOCKER_HOST + self.__client = docker.DockerClient(base_url='unix:///var/run/docker.sock') + + def __get_instances(self) : + return self.__client.containers.list(filters={"label" : "bunkerized-nginx.AUTOCONF"}) + + def __get_containers(self) : + return self.__client.containers.list(filters={"label" : "bunkerized-nginx.SERVER_NAME"}) + + def get_env(self) : + env = {} + for instance in self._get_instances() : + for variable in instance.attrs["Config"]["Env"] : + env[variable.split("=")[0]] = variable.replace(variable.split("=")[0] + "=", "", 1) + pass + + def process_events(self, current_env) : + old_env = current_env + for event in client.events(decode=True, filter={"type": "container", "label": ["bunkerized-nginx.AUTOCONF", "bunkerized-nginx.SERVER_NAME"]}) : + new_env = self.get_env() + if new_env != old_env : + if (self.gen_conf(new_env)) : + old_env = new_env + utils.log("[*] Successfully generated new configuration") diff --git a/autoconf/IngressController.py b/autoconf/src/IngressController.py similarity index 89% rename from autoconf/IngressController.py rename to autoconf/src/IngressController.py index 6f7a095..173eb3b 100644 --- a/autoconf/IngressController.py +++ b/autoconf/src/IngressController.py @@ -1,14 +1,16 @@ from kubernetes import client, config, watch from threading import Thread, Lock +from Controller import Controller + class IngressController : def __init__(self) : - config.load_kube_config() + super().__init__() + config.load_incluster_config() self.__api = client.CoreV1Api() self.__extensions_api = client.ExtensionsV1beta1Api() self.__lock = Lock() - self.__last_conf = {} def __annotations_to_env(self, annotations, service=False) : env = {} @@ -21,22 +23,24 @@ class IngressController : if annotation.startswith("bunkerized-nginx.") and annotation.replace("bunkerized-nginx.", "", 1) != "" and annotation.replace("bunkerized-nginx.", "", 1) != "AUTOCONF" : env[prefix + annotation.replace("bunkerized-nginx.", "", 1)] = annotations[annotation] return env - + def __rules_to_env(self, rules) : env = {} for rule in rules : prefix = "" if "host" in rule : prefix = rule["host"] + "_" + if not "http" in rule or not "paths" in rule["http"] : + continue for path in rule["http"]["paths"] : env[prefix + "USE_REVERSE_PROXY"] = "yes" env[prefix + "REVERSE_PROXY_URL"] = path["path"] env[prefix + "REVERSE_PROXY_HOST"] = "http://" + path["backend"]["serviceName"] + ":" + str(path["backend"]["servicePort"]) return env - def gen_conf(self) : - ingresses = self.get_ingresses() - services = self.get_services() + def get_env(self) : + ingresses = self.__get_ingresses() + services = self.__get_services() env = {} for ingress in ingresses : if ingress.metadata.annotations == None : @@ -49,16 +53,12 @@ class IngressController : continue if "bunkerized-nginx.AUTOCONF" in service.metadata.annotations : env.update(self.__annotations_to_env(service.metadata.annotations, service=True)) - if self.__last_conf != env : - self.__last_conf = env - print("*** NEW CONF ***") - for k, v in env.items() : - print(k + " = " + v) + return env - def get_ingresses(self) : + def __get_ingresses(self) : return self.__extensions_api.list_ingress_for_all_namespaces(watch=False).items - def get_services(self) : + def __get_services(self) : return self.__api.list_service_for_all_namespaces(watch=False).items def watch_ingress(self) : diff --git a/autoconf/ReloadServer.py b/autoconf/src/ReloadServer.py similarity index 100% rename from autoconf/ReloadServer.py rename to autoconf/src/ReloadServer.py diff --git a/autoconf/app.py b/autoconf/src/app.py similarity index 80% rename from autoconf/app.py rename to autoconf/src/app.py index 2c39087..b9bc0e6 100644 --- a/autoconf/app.py +++ b/autoconf/src/app.py @@ -5,19 +5,19 @@ from ReloadServer import run_reload_server import utils import docker, os, stat, sys, select, threading -# Connect to the endpoint -endpoint = "/var/run/docker.sock" -if not os.path.exists(endpoint) or not stat.S_ISSOCK(os.stat(endpoint).st_mode) : - utils.log("[!] /var/run/docker.sock not found (is it mounted ?)") - sys.exit(1) -try : - client = docker.DockerClient(base_url='unix:///var/run/docker.sock') -except Exception as e : - utils.log("[!] Can't instantiate DockerClient : " + str(e)) - sys.exit(2) - # Check if we are in Swarm mode swarm = os.getenv("SWARM_MODE") == "yes" +if swarm : + # Connect to the endpoint + endpoint = "/var/run/docker.sock" + if not os.path.exists(endpoint) or not stat.S_ISSOCK(os.stat(endpoint).st_mode) : + utils.log("[!] /var/run/docker.sock not found (is it mounted ?)") + sys.exit(1) + try : + client = docker.DockerClient(base_url='unix:///var/run/docker.sock') + except Exception as e : + utils.log("[!] Can't instantiate DockerClient : " + str(e)) + sys.exit(2) # Our object to process events api = "" diff --git a/autoconf/utils.py b/autoconf/src/utils.py similarity index 100% rename from autoconf/utils.py rename to autoconf/src/utils.py