diff --git a/passbook/outposts/controllers/base.py b/passbook/outposts/controllers/base.py index 4821ac83c..371ba65e1 100644 --- a/passbook/outposts/controllers/base.py +++ b/passbook/outposts/controllers/base.py @@ -26,16 +26,21 @@ class BaseController: ) self.deployment_ports = {} - def run(self): + # pylint: disable=invalid-name + def up(self): """Called by scheduled task to reconcile deployment/service/etc""" raise NotImplementedError - def run_with_logs(self) -> List[str]: - """Call .run() but capture all log output and return it.""" + def up_with_logs(self) -> List[str]: + """Call .up() but capture all log output and return it.""" with capture_logs() as logs: - self.run() + self.up() return [f"{x['controller']}: {x['event']}" for x in logs] + def down(self): + """Handler to delete everything we've created""" + raise NotImplementedError + def get_static_deployment(self) -> str: """Return a static deployment configuration""" raise NotImplementedError diff --git a/passbook/outposts/controllers/docker.py b/passbook/outposts/controllers/docker.py index 737ae735e..72d0e0753 100644 --- a/passbook/outposts/controllers/docker.py +++ b/passbook/outposts/controllers/docker.py @@ -62,7 +62,7 @@ class DockerController(BaseController): True, ) - def run(self): + def up(self): try: container, has_been_created = self._get_container() if has_been_created: @@ -79,13 +79,13 @@ class DockerController(BaseController): ) container.kill() container.remove(force=True) - return self.run() + return self.up() # Check that container values match our values if self._comp_env(container): self.logger.info("Container has outdated config, re-creating...") container.kill() container.remove(force=True) - return self.run() + return self.up() # Check that container is healthy if ( container.status == "running" @@ -104,6 +104,13 @@ class DockerController(BaseController): except DockerException as exc: raise ControllerException from exc + def down(self): + try: + container, _ = self._get_container() + container.kill() + except DockerException as exc: + raise ControllerException from exc + def get_static_deployment(self) -> str: """Generate docker-compose yaml for proxy, version 3.5""" ports = [f"{x}:{x}" for _, x in self.deployment_ports.items()] diff --git a/passbook/outposts/controllers/k8s/base.py b/passbook/outposts/controllers/k8s/base.py index 50b236fda..76097aadc 100644 --- a/passbook/outposts/controllers/k8s/base.py +++ b/passbook/outposts/controllers/k8s/base.py @@ -33,7 +33,7 @@ class KubernetesObjectReconciler(Generic[T]): self.namespace = "" self.logger = get_logger(controller=self.__class__.__name__, outpost=outpost) - def run(self): + def up(self): """Create object if it doesn't exist, update if needed or recreate if needed.""" current = None reference = self.get_reference_object() @@ -45,6 +45,7 @@ class KubernetesObjectReconciler(Generic[T]): self.logger.debug("Failed to get current, triggering recreate") raise NeedsRecreate from exc self.logger.debug("Other unhandled error", exc=exc) + raise exc else: self.logger.debug("Got current, running reconcile") self.reconcile(current, reference) @@ -63,6 +64,19 @@ class KubernetesObjectReconciler(Generic[T]): else: self.logger.debug("Nothing to do...") + def down(self): + """Delete object if found""" + try: + current = self.retrieve() + self.delete(current) + self.logger.debug("Removing") + except ApiException as exc: + if exc.status == 404: + self.logger.debug("Failed to get current, assuming non-existant") + return + self.logger.debug("Other unhandled error", exc=exc) + raise exc + def get_reference_object(self) -> T: """Return object as it should be""" raise NotImplementedError diff --git a/passbook/outposts/controllers/kubernetes.py b/passbook/outposts/controllers/kubernetes.py index e3a0413e6..6fd8d1ceb 100644 --- a/passbook/outposts/controllers/kubernetes.py +++ b/passbook/outposts/controllers/kubernetes.py @@ -23,24 +23,43 @@ class KubernetesController(BaseController): except ConfigException: load_kube_config() - def run(self): - """Called by scheduled task to reconcile deployment/service/etc""" + def up(self): try: namespace = self.outpost.config.kubernetes_namespace secret_reconciler = SecretReconciler(self.outpost) secret_reconciler.namespace = namespace - secret_reconciler.run() + secret_reconciler.up() deployment_reconciler = DeploymentReconciler(self.outpost) deployment_reconciler.namespace = namespace deployment_reconciler.deployment_ports = self.deployment_ports - deployment_reconciler.run() + deployment_reconciler.up() service_reconciler = ServiceReconciler(self.outpost) service_reconciler.namespace = namespace service_reconciler.deployment_ports = self.deployment_ports - service_reconciler.run() + service_reconciler.up() + except OpenApiException as exc: + raise ControllerException from exc + + def down(self): + try: + namespace = self.outpost.config.kubernetes_namespace + + secret_reconciler = SecretReconciler(self.outpost) + secret_reconciler.namespace = namespace + secret_reconciler.down() + + deployment_reconciler = DeploymentReconciler(self.outpost) + deployment_reconciler.namespace = namespace + deployment_reconciler.deployment_ports = self.deployment_ports + deployment_reconciler.down() + + service_reconciler = ServiceReconciler(self.outpost) + service_reconciler.namespace = namespace + service_reconciler.deployment_ports = self.deployment_ports + service_reconciler.down() except OpenApiException as exc: raise ControllerException from exc diff --git a/passbook/outposts/tasks.py b/passbook/outposts/tasks.py index a4b121735..a3acbee48 100644 --- a/passbook/outposts/tasks.py +++ b/passbook/outposts/tasks.py @@ -41,9 +41,9 @@ def outpost_controller(self: MonitoredTask, outpost_pk: str): try: if outpost.type == OutpostType.PROXY: if outpost.deployment_type == OutpostDeploymentType.KUBERNETES: - logs = ProxyKubernetesController(outpost).run_with_logs() + logs = ProxyKubernetesController(outpost).up_with_logs() if outpost.deployment_type == OutpostDeploymentType.DOCKER: - logs = ProxyDockerController(outpost).run_with_logs() + logs = ProxyDockerController(outpost).up_with_logs() except ControllerException as exc: self.set_status( TaskResult(TaskResultStatus.ERROR, uid=slugify(outpost.name)).with_error( diff --git a/passbook/providers/proxy/tests.py b/passbook/providers/proxy/tests.py index 23d0a5aad..a9ce5dd45 100644 --- a/passbook/providers/proxy/tests.py +++ b/passbook/providers/proxy/tests.py @@ -52,4 +52,4 @@ class TestControllers(TestCase): outpost.save() controller = ProxyKubernetesController(outpost.pk) - controller.run() + controller.up()