Пример #1
0
 def create_missing_in_portal(cls):
     """
     Scans the Kubernetes cluster for namespaces that have no representation
     as KubernetesNamespace object, and creates the latter accordingly.
     """
     try:
         k8s_ns_list = api.get_namespaces()
         if k8s_ns_list:
             for k8s_ns in k8s_ns_list:
                 k8s_ns_name, k8s_ns_uid = k8s_ns.metadata.name, k8s_ns.metadata.uid
                 # First calling exists(), and creating it in case, is faster than get_or_create()
                 # but may impose an extremely small danger of race conditions.
                 # We trade performance for reliability here.
                 if not cls.objects.filter(name=k8s_ns_name,
                                           uid=k8s_ns_uid).exists():
                     logger.info(
                         f"Found new Kubernetes namespace {k8s_ns_name}, creating record."
                     )
                     new_obj = cls(name=k8s_ns_name, uid=k8s_ns_uid)
                     if k8s_ns_name in HIDDEN_NAMESPACES:
                         new_obj.visible = False
                     else:
                         new_obj.visible = True
                     new_obj.save()
         return True
     except Exception as e:
         logger.exception(
             f"Syncing new cluster namespaces into the portal failed.")
         return False
Пример #2
0
    def create_missing_in_cluster(cls):
        """
        Scans the portal database for namespaces that have no representation
        in the Kubernetes cluster, and creates the latter accordingly.
        """
        try:
            # Create a list of cluster namespace UIDs that already exist
            k8s_ns_uid_list = [
                k8s_ns.metadata.uid for k8s_ns in api.get_namespaces()
            ]

            # Scan portal namespace entries
            for portal_ns in cls.objects.all():
                if portal_ns.uid:
                    # Portal namespace records with UID must be given in K8S, or they are stale und should be deleted
                    if portal_ns.uid not in k8s_ns_uid_list:
                        logger.warning(
                            f"Removing stale portal record for Kubernetes namespace '{portal_ns.name}'"
                        )
                        portal_ns.delete()
                else:
                    # Portal namespace records without UID are new and should be created in K8S
                    logger.debug(
                        f"Namespace record {portal_ns.name} has no UID, creating it in Kubernetes ..."
                    )
                    portal_ns.create_in_cluster(
                    )  # ignore success, continue sync in any case
            return True
        except Exception as e:
            logger.exception(
                f"Syncing new portal namespaces into the cluster failed.")
            return False
Пример #3
0
def test_new_ns_sync(random_namespace_name):
    run_minikube_sync()
    new_ns = KubernetesNamespace(name=random_namespace_name)
    new_ns.save()
    run_minikube_sync()
    ns_names = [ns.metadata.name for ns in api.get_namespaces()]
    assert random_namespace_name in ns_names
Пример #4
0
 def test_new_ns_broken_name_sync(self):
     test_cases = {"foo_bar": "foobar", "ABCDEF": "abcdef"}
     for old, new in test_cases.items():
         new_ns = KubernetesNamespace(name=old)
         new_ns.save()
         self._call_sync()
         ns_names = [ns.metadata.name for ns in api.get_namespaces()]
         self.assertNotIn(old, ns_names)
         self.assertIn(new, ns_names)
Пример #5
0
def test_new_ns_broken_name_sync():
    run_minikube_sync()
    test_cases = {"foo_bar": "foobar", "ABCDEF": "abcdef"}
    for old, new in test_cases.items():
        new_ns = KubernetesNamespace(name=old)
        new_ns.save()
        run_minikube_sync()
        ns_names = [ns.metadata.name for ns in api.get_namespaces()]
        assert old not in ns_names
        assert new in ns_names
        api.delete_k8s_ns(new)
Пример #6
0
def _sync_namespaces(request):
    #################################################
    # K8S namespaces -> portal namespaces
    #################################################
    success_count_push = 0
    success_count_pull = 0

    try:
        k8s_ns_list = api.get_namespaces()
    except Exception as e:
        error_log(request, e, None, 'Sync failed, error while fetching list of namespaces: {e}')
        return

    for k8s_ns in k8s_ns_list:
        try:
            k8s_ns_name, k8s_ns_uid = k8s_ns.metadata.name, k8s_ns.metadata.uid
            # remember for later use
            k8s_ns_uids.append(k8s_ns_uid)

            portal_ns, created = KubernetesNamespace.objects.get_or_create(name=k8s_ns_name, uid=k8s_ns_uid)
            if created:
                ns_utils.add_namespace_to_kubeportal(k8s_ns_name, portal_ns, request)
            else:
                # No action needed
                logger.debug(f"Found existing record for Kubernetes namespace '{k8s_ns_name}'")
                success_count_pull += 1
        except Exception as e:
            error_log(request, e, k8s_ns.metadata.name, 'Sync from Kubernetes for namespace {} failed: {}.')

    #################################################
    # portal namespaces -> K8S namespaces
    #################################################
    portal_ns_list = KubernetesNamespace.objects.all()
    for portal_ns in portal_ns_list:
        try:
            if portal_ns.uid:
                ns_utils.check_if_portal_ns_exists_in_k8s(request, portal_ns, k8s_ns_uids, success_count_push)
            else:
                # Portal namespaces without UID are new and should be created in K8S
                ns_utils.add_namespace_to_kubernetes(portal_ns, request, api)
        except Exception as e:
            error_log(request, e, portal_ns, 'Sync to Kubernetes for namespace {} failed: {}."')

    if success_count_push == success_count_pull:
        messages.success(request, "All valid namespaces are in sync.")

    ns_utils.check_role_bindings_of_namespaces(request)
Пример #7
0
 def test_new_ns_sync(self):
     new_ns = KubernetesNamespace(name="foo")
     new_ns.save()
     self._call_sync()
     ns_names = [ns.metadata.name for ns in api.get_namespaces()]
     self.assertIn("foo", ns_names)