Exemplo n.º 1
0
 def test_special_k8s_approved(self):
     # Creating an auto_add_approved group should not change its member list.
     group = PortalGroup.objects.get(special_k8s_accounts=True)
     self.assertEqual(group.members.count(), 0)
     # Create a new user should not change the member list
     User = get_user_model()
     u = User(username="******", email="*****@*****.**")
     u.save()
     self.assertEqual(group.members.count(), 0)
     # walk through approval workflow
     url = reverse('welcome')
     request = self.factory.get(url)
     u.send_access_request(request)
     u.save()
     # Just sending an approval request should not change to member list
     self.assertEqual(group.members.count(), 0)
     # Build full-fledged request object for logged-in admin
     request = self._build_full_request_mock('admin:index')
     # Prepare K8S namespace
     ns = KubernetesNamespace(name="default")
     ns.save()
     new_svc = KubernetesServiceAccount(name="foobar", namespace=ns)
     new_svc.save()
     # Perform approval
     assert (u.approve(request, new_svc))
     u.save()
     # Should lead to addition of user to the add_approved group
     self.assertEqual(group.members.count(), 1)
Exemplo n.º 2
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
Exemplo n.º 3
0
 def test_exists_both_sides_sync(self):
     self._call_sync()
     api.create_k8s_ns("new-external-ns2")
     new_ns = KubernetesNamespace(name="new-external-ns2")
     new_ns.save()
     try:
         self._call_sync()
     finally:
         api.delete_k8s_ns("new-external-ns2")
Exemplo n.º 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)
Exemplo n.º 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)
Exemplo n.º 6
0
    def get_context_data(self, *args, **kwargs):
        context = super().get_context_data(*args, **kwargs)
        context['site_header'] = settings.BRANDING + " (Admin Backend)"
        context['title'] = "Clean Up"

        context[
            'namespaces_no_service_acc'] = KubernetesNamespace.without_service_accounts(
            )
        context['namespaces_no_pods'] = KubernetesNamespace.without_pods()
        context['months'] = settings.LAST_LOGIN_MONTHS_AGO
        context['inactive_users'] = User.inactive_users()
        return context
Exemplo n.º 7
0
def test_user_merge_access_approved(admin_index_request, django_user_model):
    run_minikube_sync()
    primary = django_user_model(
        username="******",
        email="*****@*****.**")
    primary.save()

    ns = KubernetesNamespace(name="default")
    ns.save()
    new_svc = KubernetesServiceAccount(name="foobar", namespace=ns)
    new_svc.save()
    secondary = django_user_model(
        username="******",
        state=User.ACCESS_APPROVED,
        email="*****@*****.**",
        comments="secondary user comment",
        service_account=new_svc)
    secondary.save()

    group1 = PortalGroup(name="testgroup1")
    group1.save()
    group2 = PortalGroup(name="testgroup2")
    group2.save()

    secondary.portal_groups.add(group1)
    secondary.portal_groups.add(group2)
    secondary.save()

    # Build full-fledged request object for logged-in admin
    # approve secondary for cluster access
    secondary.approve(admin_index_request, new_svc)

    # the merge method only accepts a queryset of users since that's what
    # the admin interface creates
    queryset_of_users = django_user_model.objects.filter(
        pk__in=[primary.id, secondary.id])

    # merge both users. shouldn't return anything
    assert(not merge_users(UserAdmin, admin_index_request, queryset_of_users))

    # the primary user has been altered but the old object is still in memory
    # we need to query for the updated user again
    primary = django_user_model.objects.get(pk=primary.id)

    # Does primary have all the values of secondary user?
    assert primary.comments == "secondary user comment"
    assert primary.portal_groups.filter(name=group1.name)
    assert primary.portal_groups.filter(name=group2.name)
    assert primary.has_access_approved
Exemplo n.º 8
0
 def create_missing_in_portal(cls):
     """
     Scans the Kubernetes cluster for service accounts that have no representation
     as KubernetesServiceAccount object, and creates the latter accordingly.
     """
     try:
         k8s_svca_list = api.get_service_accounts()
         if k8s_svca_list:
             for k8s_svca in k8s_svca_list:
                 # 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_svca.metadata.name,
                         uid=k8s_svca.metadata.uid).exists():
                     logger.info(
                         f"Found new Kubernetes service account {k8s_svca.metadata.name}, creating record."
                     )
                     ns = KubernetesNamespace.get_or_sync(
                         k8s_svca.metadata.namespace)
                     new_obj = cls(name=k8s_svca.metadata.name,
                                   uid=k8s_svca.metadata.uid,
                                   namespace=ns)
                     new_obj.save()
         return True
     except Exception as e:
         logger.exception(
             f"Syncing new cluster service accounts into the portal failed."
         )
         return False
Exemplo n.º 9
0
 def test_special_k8s_unapproved(self):
     group = PortalGroup.objects.get(special_k8s_accounts=True)
     ns = KubernetesNamespace(name="default")
     ns.save()
     new_svc = KubernetesServiceAccount(name="foobar", namespace=ns)
     new_svc.save()
     User = get_user_model()
     # create approved user
     u = User(username="******",
              email="*****@*****.**",
              state=UserState.ACCESS_APPROVED,
              service_account=new_svc)
     u.save()
     self.assertEqual(group.members.count(), 1)
     # unapprove
     u.state = UserState.ACCESS_REJECTED
     u.save()
     self.assertEqual(group.members.count(), 0)
Exemplo n.º 10
0
def test_special_k8s_unapproved(django_user_model, random_namespace_name):
    run_minikube_sync()
    group = PortalGroup.objects.get(special_k8s_accounts=True)
    ns = KubernetesNamespace(name=random_namespace_name)
    ns.save()
    new_svc = KubernetesServiceAccount(name="foobar", namespace=ns)
    new_svc.save()
    # create approved user
    u = django_user_model(username="******",
             email="*****@*****.**",
             state=User.ACCESS_APPROVED,
             service_account=new_svc)
    u.save()
    assert group.members.count() == 1
    # unapprove
    u.state = User.ACCESS_REJECTED
    u.save()
    assert group.members.count() == 0
Exemplo n.º 11
0
    def test_backend_cleanup_view(self):
        User = get_user_model()
        u = User(username="******", email="*****@*****.**")
        u.save()

        # we need an inactive user for the the filter to work
        from dateutil.parser import parse
        u.last_login = parse("2017-09-23 11:21:52.909020")
        u.save()

        ns = KubernetesNamespace(name="aaasdfadfasdfasdf", visible=True)
        ns.save()

        new_svc = KubernetesServiceAccount(name="foobar", namespace=ns)
        new_svc.save()
        new_svc.delete()

        request = self._build_full_request_mock('admin:cleanup')
        assert (request)
Exemplo n.º 12
0
def test_backend_cleanup_view(rf, admin_user, random_namespace_name):
    run_minikube_sync()
    User = get_user_model()
    u = User(
        username="******",
        email="*****@*****.**")
    u.save()

    # we need an inactive user for the the filter to work
    u.last_login = parse("2017-09-23 11:21:52.909020 +02:00")
    u.save()

    ns = KubernetesNamespace(name=random_namespace_name)
    ns.save()

    new_svc = KubernetesServiceAccount(name="foobar", namespace=ns)
    new_svc.save()
    new_svc.delete()

    assert admin_request(rf, admin_user, 'admin:cleanup')
Exemplo n.º 13
0
    def test_user_merge_access_rejected(self):
        request = self._build_full_request_mock('admin:index')

        User = get_user_model()
        primary = User(username="******", email="*****@*****.**")
        primary.save()

        ns = KubernetesNamespace(name="default")
        ns.save()

        new_svc = KubernetesServiceAccount(name="foobar", namespace=ns)
        new_svc.save()
        # Perform approval
        assert (primary.approve(request, new_svc))
        primary.save()

        secondary = User(username="******",
                         state=UserState.ACCESS_APPROVED,
                         email="*****@*****.**",
                         comments="secondary user comment",
                         service_account=new_svc)
        secondary.save()

        # Build full-fledged request object for logged-in admin
        request = self._build_full_request_mock('admin:index')
        # reject cluster access for secondary
        secondary.reject(request)

        # the merge method only accepts a queryset of users since that's what
        # the admin interface creates
        queryset_of_users = User.objects.filter(
            pk__in=[primary.id, secondary.id])

        # merge both users. shouldn't return anything
        assert (not merge_users(UserAdmin, request, queryset_of_users))

        # the primary user has been altered but the old object is still in memory
        # we need to query for the updated user again
        primary = User.objects.get(pk=primary.id)

        assert primary.has_access_rejected
Exemplo n.º 14
0
def sync(request=None):
    '''
    Synchronizes the local shallow copy of Kubernetes data.
    Returns True on success.
    '''
    try:
        res1 = KubernetesNamespace.create_missing_in_portal()
        res2 = KubernetesNamespace.create_missing_in_cluster()
        res3 = KubernetesServiceAccount.create_missing_in_portal()
        res4 = KubernetesServiceAccount.create_missing_in_cluster()
        if request:
            messages.info(request, "Synchronization finished.")
        logger.debug("Synchronization finished.")
        return True == res1 == res2 == res3 == res4
    except client.rest.ApiException as e:
        msg = json.loads(e.body)['message']
        logger.error(
            "API server exception during synchronization: {0}".format(msg))
        if request:
            messages.error(
                request, "Kubernetes returned an error during synchronization: {0}".format(msg))
        return False
Exemplo n.º 15
0
def test_user_merge_access_rejected(admin_index_request, django_user_model, random_namespace_name):
    run_minikube_sync()
    primary = django_user_model(
        username="******",
        email="*****@*****.**")
    primary.save()

    ns = KubernetesNamespace(name=random_namespace_name)
    ns.save()

    new_svc = KubernetesServiceAccount(name="foobar", namespace=ns)
    new_svc.save()
    # Perform approval
    assert(primary.approve(admin_index_request, new_svc))

    secondary = django_user_model(
        username="******",
        state=User.ACCESS_APPROVED,
        email="*****@*****.**",
        comments="secondary user comment",
        service_account=new_svc)
    secondary.save()

    # reject cluster access for secondary
    secondary.reject(admin_index_request)

    # the merge method only accepts a queryset of users since that's what
    # the admin interface creates
    queryset_of_users = django_user_model.objects.filter(
        pk__in=[primary.id, secondary.id])

    # merge both users. shouldn't return anything
    assert(not merge_users(UserAdmin, admin_index_request, queryset_of_users))

    # the primary user has been altered but the old object is still in memory
    # we need to query for the updated user again
    primary = django_user_model.objects.get(pk=primary.id)

    assert primary.has_access_rejected
Exemplo n.º 16
0
def test_special_k8s_approved(rf, admin_index_request, django_user_model, random_namespace_name):
    run_minikube_sync()
    # Creating an auto_add_approved group should not change its member list.
    group = PortalGroup.objects.get(special_k8s_accounts=True)
    assert group.members.count() == 0
    # Create a new user should not change the member list
    u = django_user_model(username="******", email="*****@*****.**")
    u.save()
    assert group.members.count() == 0
    # walk through approval workflow
    url = reverse('welcome')
    request = rf.get(url)
    u.send_access_request(request)
    # Just sending an approval request should not change to member list
    assert group.members.count() == 0
    # Prepare K8S namespace
    ns = KubernetesNamespace(name=random_namespace_name)
    ns.save()
    new_svc = KubernetesServiceAccount(name="foobar", namespace=ns)
    new_svc.save()
    # Perform approval
    assert(u.approve(admin_index_request, new_svc))
    # Should lead to addition of user to the add_approved group
    assert group.members.count() == 1
Exemplo n.º 17
0
def test_backend_cleanup_entitity_getters(django_user_model, admin_user, random_namespace_name):
    run_minikube_sync()
    admin_user.last_login = parse("2017-09-23 11:21:52.909020 +02:00")
    admin_user.save()

    ns = KubernetesNamespace(name=random_namespace_name)
    ns.save()

    assert admin_user in django_user_model.inactive_users()
    assert ns in KubernetesNamespace.without_pods()
    assert ns in KubernetesNamespace.without_service_accounts()
Exemplo n.º 18
0
def test_new_svc_sync(random_namespace_name):
    run_minikube_sync()
    ns = KubernetesNamespace(name=random_namespace_name)
    ns.save()
    ns.create_in_cluster()
    new_svc = KubernetesServiceAccount(name="foobar", namespace=ns)
    new_svc.save()
    run_minikube_sync()
    svc_list = api.get_service_accounts()
    for svc in svc_list:
        if svc.metadata.name == "foobar" and svc.metadata.namespace == random_namespace_name:
            return
    assert False
Exemplo n.º 19
0
    def test_backend_cleanup_entitity_getters():
        User = get_user_model()
        from django.utils import dateparse
        # we need an inactive user for the the filter to work
        u = User(username="******",
                 email="*****@*****.**",
                 last_login=dateparse.parse_datetime(
                     "2017-09-23 11:21:52.909020 +02.00"))
        u.save()

        ns = KubernetesNamespace(name="asdfadfasdfasdf", visible=True)
        ns.save()

        assert (User.inactive_users()[0] == User.objects.get(
            username=u.username))
        assert (KubernetesNamespace.without_pods()[0] == ns)
        assert (KubernetesNamespace.without_service_accounts()[0] == ns)
Exemplo n.º 20
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)
Exemplo n.º 21
0
def test_exists_both_sides_sync(random_namespace_name):
    run_minikube_sync()
    api.create_k8s_ns(random_namespace_name)
    new_ns = KubernetesNamespace(name=random_namespace_name)
    new_ns.save()
    run_minikube_sync()