def test_deployment_reconciler(self):
        """test that deployment requires update"""
        controller = ProxyKubernetesController(self.outpost,
                                               self.service_connection)
        deployment_reconciler = DeploymentReconciler(controller)

        self.assertIsNotNone(deployment_reconciler.retrieve())

        config = self.outpost.config
        config.kubernetes_replicas = 3
        self.outpost.config = config

        with self.assertRaises(NeedsUpdate):
            deployment_reconciler.reconcile(
                deployment_reconciler.retrieve(),
                deployment_reconciler.get_reference_object(),
            )

        with CONFIG.patch("outposts.container_image_base", "test"):
            with self.assertRaises(NeedsUpdate):
                deployment_reconciler.reconcile(
                    deployment_reconciler.retrieve(),
                    deployment_reconciler.get_reference_object(),
                )

        deployment_reconciler.delete(
            deployment_reconciler.get_reference_object())
Ejemplo n.º 2
0
def outpost_controller(self: MonitoredTask, outpost_pk: str):
    """Create/update/monitor the deployment of an Outpost"""
    logs = []
    outpost: Outpost = Outpost.objects.get(pk=outpost_pk)
    self.set_uid(slugify(outpost.name))
    try:
        if not outpost.service_connection:
            return
        if outpost.type == OutpostType.PROXY:
            service_connection = outpost.service_connection
            if isinstance(service_connection, DockerServiceConnection):
                logs = ProxyDockerController(
                    outpost, service_connection).up_with_logs()
            if isinstance(service_connection, KubernetesServiceConnection):
                logs = ProxyKubernetesController(
                    outpost, service_connection).up_with_logs()
        LOGGER.debug(
            "---------------Outpost Controller logs starting----------------")
        for log in logs:
            LOGGER.debug(log)
        LOGGER.debug(
            "-----------------Outpost Controller logs end-------------------")
    except ControllerException as exc:
        self.set_status(TaskResult(TaskResultStatus.ERROR).with_error(exc))
    else:
        self.set_status(TaskResult(TaskResultStatus.SUCCESSFUL, logs))
Ejemplo n.º 3
0
def outpost_pre_delete(outpost_pk: str):
    """Delete outpost objects before deleting the DB Object"""
    outpost = Outpost.objects.get(pk=outpost_pk)
    if outpost.type == OutpostType.PROXY:
        service_connection = outpost.service_connection
        if isinstance(service_connection, DockerServiceConnection):
            ProxyDockerController(outpost, service_connection).down()
        if isinstance(service_connection, KubernetesServiceConnection):
            ProxyKubernetesController(outpost, service_connection).down()
Ejemplo n.º 4
0
    def test_kubernetes_controller_static(self):
        """Test Kubernetes Controller"""
        provider: ProxyProvider = ProxyProvider.objects.create(
            name="test",
            internal_host="http://localhost",
            external_host="http://localhost",
            authorization_flow=Flow.objects.first(),
        )
        service_connection = KubernetesServiceConnection.objects.first()
        outpost: Outpost = Outpost.objects.create(
            name="test",
            type=OutpostType.PROXY,
            service_connection=service_connection,
        )
        outpost.providers.add(provider)
        outpost.save()

        controller = ProxyKubernetesController(outpost, service_connection)
        manifest = controller.get_static_deployment()
        self.assertEqual(len(list(yaml.load_all(manifest, Loader=yaml.SafeLoader))), 4)
Ejemplo n.º 5
0
    def test_kubernetes_controller_ingress(self):
        """Test Kubernetes Controller's Ingress"""
        provider: ProxyProvider = ProxyProvider.objects.create(
            name="test",
            internal_host="http://localhost",
            external_host="https://localhost",
            authorization_flow=create_test_flow(),
        )
        provider2: ProxyProvider = ProxyProvider.objects.create(
            name="test2",
            internal_host="http://otherhost",
            external_host="https://otherhost",
            mode=ProxyMode.FORWARD_SINGLE,
            authorization_flow=create_test_flow(),
        )

        service_connection = KubernetesServiceConnection.objects.first()
        outpost: Outpost = Outpost.objects.create(
            name="test",
            type=OutpostType.PROXY,
            service_connection=service_connection,
        )
        outpost.providers.add(provider)

        self.controller = ProxyKubernetesController(outpost,
                                                    service_connection)

        ingress_rec = IngressReconciler(self.controller)
        ingress = ingress_rec.retrieve()

        self.assertEqual(len(ingress.spec.rules), 1)
        self.assertEqual(ingress.spec.rules[0].host, "localhost")

        # add provider, check again
        outpost.providers.add(provider2)
        ingress = ingress_rec.retrieve()

        self.assertEqual(len(ingress.spec.rules), 2)
        self.assertEqual(ingress.spec.rules[0].host, "localhost")
        self.assertEqual(ingress.spec.rules[1].host, "otherhost")
Ejemplo n.º 6
0
def controller_for_outpost(outpost: Outpost) -> Optional[BaseController]:
    """Get a controller for the outpost, when a service connection is defined"""
    if not outpost.service_connection:
        return None
    service_connection = outpost.service_connection
    if outpost.type == OutpostType.PROXY:
        if isinstance(service_connection, DockerServiceConnection):
            return ProxyDockerController(outpost, service_connection)
        if isinstance(service_connection, KubernetesServiceConnection):
            return ProxyKubernetesController(outpost, service_connection)
    if outpost.type == OutpostType.LDAP:
        if isinstance(service_connection, DockerServiceConnection):
            return LDAPDockerController(outpost, service_connection)
        if isinstance(service_connection, KubernetesServiceConnection):
            return LDAPKubernetesController(outpost, service_connection)
    return None
    def test_controller_rename(self):
        """test that objects get deleted and re-created with new names"""
        controller = ProxyKubernetesController(self.outpost,
                                               self.service_connection)

        self.assertIsNone(controller.up())
        self.outpost.name = "foo"
        self.assertIsNone(controller.up())
        apps = AppsV1Api(controller.client)
        with self.assertRaises(OpenApiException):
            apps.read_namespaced_deployment(
                "test", self.outpost.config.kubernetes_namespace)
        controller.down()
    def test_controller_full_update(self):
        """Test an update that triggers all objects"""
        controller = ProxyKubernetesController(self.outpost,
                                               self.service_connection)

        self.assertIsNone(controller.up())
        with patch("authentik.outposts.controllers.k8s.base.get_version",
                   MagicMock(return_value="1234")):
            self.assertIsNone(controller.up())
        deployment_reconciler = DeploymentReconciler(controller)
        deployment = deployment_reconciler.retrieve()
        self.assertEqual(
            deployment.metadata.labels["app.kubernetes.io/version"], "1234")
        controller.down()
Ejemplo n.º 9
0
    def test_kubernetes_controller_deploy(self):
        """Test Kubernetes Controller"""
        provider: ProxyProvider = ProxyProvider.objects.create(
            name="test",
            internal_host="http://localhost",
            external_host="http://localhost",
            authorization_flow=Flow.objects.first(),
        )
        service_connection = KubernetesServiceConnection.objects.first()
        outpost: Outpost = Outpost.objects.create(
            name="test",
            type=OutpostType.PROXY,
            service_connection=service_connection,
        )
        outpost.providers.add(provider)
        outpost.save()

        controller = ProxyKubernetesController(outpost, service_connection)
        controller.up()
        controller.down()
Ejemplo n.º 10
0
class TestProxyKubernetes(TestCase):
    """Test Controllers"""

    controller: Optional[KubernetesController]

    def setUp(self):
        # Ensure that local connection have been created
        outpost_local_connection()
        self.controller = None

    def tearDown(self) -> None:
        if self.controller:
            for log in self.controller.down_with_logs():
                LOGGER.info(log)
        return super().tearDown()

    def test_kubernetes_controller_static(self):
        """Test Kubernetes Controller"""
        provider: ProxyProvider = ProxyProvider.objects.create(
            name="test",
            internal_host="http://localhost",
            external_host="http://localhost",
            authorization_flow=create_test_flow(),
        )
        service_connection = KubernetesServiceConnection.objects.first()
        outpost: Outpost = Outpost.objects.create(
            name="test",
            type=OutpostType.PROXY,
            service_connection=service_connection,
        )
        outpost.providers.add(provider)
        outpost.save()

        self.controller = ProxyKubernetesController(outpost,
                                                    service_connection)
        manifest = self.controller.get_static_deployment()
        self.assertEqual(
            len(list(yaml.load_all(manifest, Loader=yaml.SafeLoader))), 4)

    def test_kubernetes_controller_ingress(self):
        """Test Kubernetes Controller's Ingress"""
        provider: ProxyProvider = ProxyProvider.objects.create(
            name="test",
            internal_host="http://localhost",
            external_host="https://localhost",
            authorization_flow=create_test_flow(),
        )
        provider2: ProxyProvider = ProxyProvider.objects.create(
            name="test2",
            internal_host="http://otherhost",
            external_host="https://otherhost",
            mode=ProxyMode.FORWARD_SINGLE,
            authorization_flow=create_test_flow(),
        )

        service_connection = KubernetesServiceConnection.objects.first()
        outpost: Outpost = Outpost.objects.create(
            name="test",
            type=OutpostType.PROXY,
            service_connection=service_connection,
        )
        outpost.providers.add(provider)

        self.controller = ProxyKubernetesController(outpost,
                                                    service_connection)

        ingress_rec = IngressReconciler(self.controller)
        ingress = ingress_rec.retrieve()

        self.assertEqual(len(ingress.spec.rules), 1)
        self.assertEqual(ingress.spec.rules[0].host, "localhost")

        # add provider, check again
        outpost.providers.add(provider2)
        ingress = ingress_rec.retrieve()

        self.assertEqual(len(ingress.spec.rules), 2)
        self.assertEqual(ingress.spec.rules[0].host, "localhost")
        self.assertEqual(ingress.spec.rules[1].host, "otherhost")