def test_create_check(self, form_data):
        # Create a UserAS with the given data
        create_form = UserASForm(user=get_testuser(), data=form_data)
        self.assertIsNotNone(create_form.as_table())
        self.assertTrue(create_form.is_valid(), create_form.errors)
        user_as = create_form.save()

        self.assertIsNotNone(user_as.pk)
        links = [iface.link().pk for iface in user_as.interfaces.all()]
        self.assertEqual(len(links), form_data['form-TOTAL_FORMS'])

        # Submittng the ~same data on the previously created instance should have no changes
        form_data_2 = _get_form_fields_for_edit(form_data, user_as)

        edit_form = UserASForm(user=get_testuser(),
                               instance=user_as,
                               data=form_data_2)
        self.assertFalse(edit_form.has_changed(),
                         _get_forms_change_data(edit_form))
        self.assertTrue(edit_form.is_valid(), edit_form.errors)

        # Also, if we save the updated form, nothing should change
        user_as_edited = edit_form.save()
        self.assertEqual(user_as.pk, user_as_edited.pk)
        links_edited = [iface.link().pk for iface in user_as.interfaces.all()]
        self.assertEqual(links, links_edited)
Beispiel #2
0
 def test_server_vpn_ip(self):
     """ Its IP is not at the beginning of the subnet """
     attachment_point = AttachmentPoint.objects.filter(
         vpn__isnull=False).first()
     vpn = attachment_point.vpn
     server_orig_ip = ip_address(vpn.server_vpn_ip)
     vpn.server_vpn_ip = str(server_orig_ip + 1)
     vpn.save()
     # create two clients and check their IP addresses
     c1 = create_and_check_useras(
         self,
         owner=get_testuser(),
         attachment_point=attachment_point,
         public_port=50000,
         use_vpn=True).hosts.get().vpn_clients.get()
     c2 = create_and_check_useras(
         self,
         owner=get_testuser(),
         attachment_point=attachment_point,
         public_port=50000,
         use_vpn=True).hosts.get().vpn_clients.get()
     ip1 = ip_address(c1.ip)
     ip2 = ip_address(c2.ip)
     self.assertEqual(ip1, server_orig_ip)
     self.assertEqual(ip2, ip_address(vpn.server_vpn_ip) + 1)
Beispiel #3
0
    def test_vpn_client_next_ip(self):
        attachment_point = AttachmentPoint.objects.filter(
            AS__as_id='ffaa:0:1404').get()
        vpn = attachment_point.vpn
        vpn.clients.all().delete()  # check creation of first client

        user_as = create_and_check_useras(self,
                                          attachment_point=attachment_point,
                                          owner=get_testuser(),
                                          use_vpn=True,
                                          public_port=50000)
        vpn_client = user_as.hosts.get().vpn_clients.get()
        # consecutive: (assumes server at begin of IP range, not the case for all APs in testdata)
        self.assertEqual(
            ip_address(vpn.server_vpn_ip) + 1, ip_address(vpn_client.ip))
        # leave a gap at the beginning
        former_vpn_ip = ip_address(vpn_client.ip)
        vpn_client.ip = str(former_vpn_ip + 1)
        vpn_client.save()
        user_as = create_and_check_useras(self,
                                          attachment_point=attachment_point,
                                          owner=get_testuser(),
                                          use_vpn=True,
                                          public_port=50000)
        vpn_client_new = user_as.hosts.get().vpn_clients.get()
        self.assertEqual(ip_address(vpn_client_new.ip), former_vpn_ip)
Beispiel #4
0
 def test_vpn_client_next_ip(self):
     attachment_point = AttachmentPoint.objects.filter(
         vpn__isnull=False).first()
     vpn_server = VPN.objects.first()
     user_as = create_and_check_useras(self,
                                       attachment_point=attachment_point,
                                       owner=get_testuser(),
                                       use_vpn=True,
                                       public_port=50000)
     vpn_client = user_as.hosts.get().vpn_clients.get()
     # consecutive:
     self.assertEqual(
         ip_address(vpn_server.server_vpn_ip) + 1,
         ip_address(vpn_client.ip))
     # leave a gap at the beginning
     former_vpn_ip = ip_address(vpn_client.ip)
     vpn_client.ip = str(former_vpn_ip + 1)
     vpn_client.save()
     user_as = create_and_check_useras(self,
                                       attachment_point=attachment_point,
                                       owner=get_testuser(),
                                       use_vpn=True,
                                       public_port=50000)
     vpn_client_new = user_as.hosts.get().vpn_clients.get()
     self.assertEqual(ip_address(vpn_client_new.ip), former_vpn_ip)
Beispiel #5
0
 def test_exhaust_vpn_clients(self, _):
     attachment_point = AttachmentPoint.objects.filter(
         vpn__isnull=False).first()
     vpn = attachment_point.vpn
     vpn.subnet = '10.0.8.0/28'
     vpn.server_vpn_ip = '10.0.8.10'
     vpn.save()
     subnet = ip_network(vpn.subnet)
     used_ips = list()
     it = subnet.hosts()
     next(it)  # skip one for the server
     for i in it:
         a = create_and_check_useras(self,
                                     owner=get_testuser(),
                                     attachment_point=attachment_point,
                                     public_port=50000,
                                     use_vpn=True)
         used_ips.append(ip_address(a.hosts.get().vpn_clients.get().ip))
     self.assertEqual(len(used_ips),
                      13)  # 16 - network, broadcast and server addrs
     used_ips_set = set(used_ips)
     self.assertEqual(len(used_ips), len(used_ips_set))
     self.assertNotIn(ip_address(vpn.server_vpn_ip), used_ips_set)
     for ip in used_ips:
         self.assertIn(ip, subnet)
     # one too many:
     with self.assertRaises(RuntimeError):
         a = create_and_check_useras(self,
                                     owner=get_testuser(),
                                     attachment_point=attachment_point,
                                     public_port=50000,
                                     use_vpn=True)
Beispiel #6
0
    def test_edit_render(self, **kwargs):
        """
        The form can be instantiated with a (freshly created) UserAS.
        The instantiated form should not show any changes if the same data is
        submitted.
        """
        form_data = self._get_initial_dict()
        form_data.update(**kwargs)

        # Create a UserAS with the given data
        create_form = UserASForm(user=get_testuser(), data=form_data)
        self.assertIsNotNone(create_form.as_table())
        self.assertTrue(create_form.is_valid(), create_form.errors)
        user_as = create_form.save()
        self.assertIsNotNone(user_as)

        # Check that the form can be instantiated for the object just created
        # and check that the forms initial values are the same as the
        # previously submitted values.
        edit_form_1 = UserASForm(user=get_testuser(), instance=user_as, data=form_data)
        self.assertIsNotNone(edit_form_1.as_table())
        self.assertTrue(edit_form_1.is_valid(), edit_form_1.errors)
        self.assertFalse(edit_form_1.has_changed(), edit_form_1.changed_data)
        user_as_edited_1 = edit_form_1.save()
        self.assertEqual(user_as.pk, user_as_edited_1.pk)

        # Do it again!
        edit_form_2 = UserASForm(user=get_testuser(), instance=user_as, data=form_data)
        self.assertTrue(edit_form_2.is_valid(), edit_form_2.errors)
        self.assertFalse(edit_form_2.has_changed(), edit_form_2.changed_data)
        user_as_edited_2 = edit_form_2.save()
        self.assertEqual(user_as.pk, user_as_edited_2.pk)
Beispiel #7
0
    def test_get_config(self):
        _create_ases_for_testuser(get_testuser().max_num_ases())

        self.client.force_login(get_testuser())
        user_as_pks = [user_as.pk for user_as
                       in UserAS.objects.filter(owner=get_testuser()).iterator()]
        for pk in user_as_pks:
            response = self.client.get(reverse('user_as_config', kwargs={'pk': pk}))
            self.assertEqual(response.status_code, 200)
            utils.check_tarball_user_as(self, response, UserAS.objects.get(pk=pk))
    def test_edit(self, initial_data, new_data):
        # Create a UserAS with the given data
        create_form = UserASForm(user=get_testuser(), data=initial_data)
        self.assertIsNotNone(create_form.as_table())
        self.assertTrue(create_form.is_valid(), create_form.errors)
        user_as = create_form.save()
        self.assertIsNotNone(user_as)

        # Submittng the new data on the previously created instance should change it
        edit_form_1_data = _get_form_fields_for_edit(new_data, user_as)

        edit_form_1 = UserASForm(user=get_testuser(),
                                 instance=user_as,
                                 data=edit_form_1_data)
        rendered_1 = edit_form_1.as_table()
        self.assertIsNotNone(rendered_1)
        rendered_formset_1 = edit_form_1.attachment_conf_form_set.as_table()
        self.assertIsNotNone(rendered_formset_1)
        self.assertTrue(edit_form_1.is_valid(), edit_form_1.errors)
        if initial_data == new_data:
            self.assertFalse(edit_form_1.has_changed(),
                             _get_forms_change_data(edit_form_1))
        else:
            self.assertTrue(edit_form_1.has_changed())
        user_as_edited_1 = edit_form_1.save()
        self.assertEqual(user_as.pk, user_as_edited_1.pk)

        links_edited_1 = [
            iface.link().pk for iface in user_as.interfaces.all()
        ]
        self.assertEqual(len(links_edited_1), new_data['form-TOTAL_FORMS'])

        if initial_data == new_data:
            return  # no need to do this _again_

        # Submittng the ~same data on the previously edited instance should have no further changes
        edit_form_2_data = _get_form_fields_for_edit(new_data, user_as)

        edit_form_2 = UserASForm(user=get_testuser(),
                                 instance=user_as,
                                 data=edit_form_2_data)
        self.assertFalse(edit_form_2.has_changed(),
                         _get_forms_change_data(edit_form_2))
        self.assertTrue(edit_form_2.is_valid(), edit_form_2.errors)

        links_edited_2 = [
            iface.link().pk for iface in user_as.interfaces.all()
        ]
        self.assertEqual(links_edited_1, links_edited_2)
 def test_create_invalid(self, form_data):
     error_desc = form_data.pop('error', None)
     form = UserASForm(user=get_testuser(), data=form_data)
     self.assertFalse(form.is_valid())
     if error_desc:
         error_descs = _get_forms_error_descs(form)
         self.assertIn(error_desc, error_descs)
Beispiel #10
0
 def test_create_vpn(self):
     attachment_point = AttachmentPoint.objects.get(vpn__isnull=False)
     create_and_check_useras(self,
                             owner=get_testuser(),
                             attachment_point=attachment_point,
                             use_vpn=True,
                             public_port=test_public_port)
Beispiel #11
0
 def _get_initial_dict(self):
     """
     Return a dict containing the initial value for each UserAS form field
     """
     # Create a form instance, only to extract the initial values
     form = UserASForm(user=get_testuser())
     return {key: field.initial for (key, field) in form.fields.items()}
Beispiel #12
0
    def test_delete_user(self):
        testuser = get_testuser()
        user_as_pks = []
        user_as_hosts = []
        attachment_point_hosts = set()
        as_ids_combs = get_random_as_ids_combinations()
        vpn_choice = VPNChoice.SOME
        for i in range(testuser.max_num_ases()):
            seed = 789 + i
            r = random.Random(seed)
            as_ids = r.choice(as_ids_combs)
            user_as, att_confs = create_and_check_random_useras(
                self, seed, as_ids, vpn_choice)
            user_as_pks.append(user_as.pk)
            user_as_hosts += list(user_as.hosts.all())
            attachment_point_hosts |= set([
                h for c in att_confs
                for h in c.attachment_point.AS.hosts.all()
            ])

        testuser.delete()

        for user_as_pk in user_as_pks:
            self.assertFalse(UserAS.objects.filter(pk=user_as_pk).exists())

        self.assertEqual(
            list(Host.objects.needs_config_deployment()),
            sorted(user_as_hosts + list(attachment_point_hosts),
                   key=lambda host: host.pk))

        utils.check_topology(self)
Beispiel #13
0
 def test_create_public_ip(self, ap_index):
     attachment_point = AttachmentPoint.objects.all()[ap_index]
     create_and_check_useras(self,
                             owner=get_testuser(),
                             attachment_point=attachment_point,
                             use_vpn=False,
                             public_ip=test_public_ip,
                             public_port=test_public_port)
Beispiel #14
0
    def test_create_too_many(self):
        """
        Submitting the creation form with quota exceeded leads to
        a form-error.
        """
        form_data = self._get_initial_dict()
        form_data.update(**self.valid_form_params[0].kwargs)

        for i in range(get_testuser().max_num_ases()):
            form = UserASForm(user=get_testuser(), data=form_data)
            # Check that form is valid, otherwise this test will not make sense
            self.assertTrue(form.is_valid(), form.errors)
            form.save()

        form = UserASForm(user=get_testuser(), data=form_data)
        self.assertFalse(form.is_valid())
        self.assertTrue(any(e.find("quota exceeded") >= 0 for e in form.non_field_errors()),
                        form.errors)
 def test_create_valid(self, form_data):
     """
     Check that the form is valid with the given values as user input,
     and saving the form results in a new UserAS object.
     """
     form = UserASForm(user=get_testuser(), data=form_data)
     error_descs = _get_forms_error_descs(form)
     self.assertTrue(form.is_valid(), error_descs)
     user_as = form.save()
     self.assertIsNotNone(user_as)
Beispiel #16
0
    def test_post_create_form_no_quota(self):
        """ Submitting the create form with quota exceeded is not allowed """
        self.app.set_user(TESTUSER_EMAIL)
        create_page = self.app.get(reverse('user_as_add'), expect_errors=True)

        _create_ases_for_testuser(get_testuser().max_num_ases())

        self._fill_form(create_page.form, **UserASFormTests.valid_form_params[-1].kwargs)
        response = create_page.form.submit(expect_errors=True)
        self.assertEqual(response.status_code, 403)
Beispiel #17
0
def create_user_as(ap, label='Some label'):
    user_as = UserAS.objects.create(
        owner=get_testuser(),
        installation_type=UserAS.VM,
        isd=ap.AS.isd,
        label=label,
    )
    att_conf = AttachmentConf(ap, use_vpn=True, public_port=test_public_port)
    user_as.update_attachments([att_conf])
    return user_as
Beispiel #18
0
    def test_submit_create_form_valid(self, **kwargs):
        """ Submitting valid data creates the AS and forwards to the detail page """
        self.app.set_user(TESTUSER_EMAIL)
        create_page = self.app.get(reverse('user_as_add'))
        self._fill_form(create_page.form, **kwargs)
        response = create_page.form.submit()

        user_as = UserAS.objects.filter(owner=get_testuser()).last()
        self.assertEqual(response.status_code, 302)
        self.assertEqual(response.location,
                         reverse('user_as_detail', kwargs={'pk': user_as.pk}))
        self.assertEqual(response.follow().status_code, 200)

        # submit the form again, forwards to the next AS:
        response_2 = create_page.form.submit()
        user_as_2 = UserAS.objects.filter(owner=get_testuser()).last()
        self.assertEqual(response_2.status_code, 302)
        self.assertEqual(response_2.location,
                         reverse('user_as_detail', kwargs={'pk': user_as_2.pk}))
        self.assertEqual(response_2.follow().status_code, 200)
Beispiel #19
0
def _create_ases_for_testuser(num):
    """ Create a number `num` UserASes for testuser """
    user = get_testuser()
    num_existing_ases = UserAS.objects.filter(owner=user).count()
    for i in range(num_existing_ases, num_existing_ases + num):
        UserAS.objects.create(owner=user,
                              attachment_point=AttachmentPoint.objects.first(),
                              public_ip=_test_ip,
                              public_port=_test_start_port + i,
                              label="Testuser's AS number %i" % (i + 1),
                              installation_type=UserAS.VM)
Beispiel #20
0
def create_user_as(ap, label='Some label'):
    return UserAS.objects.create(
        owner=get_testuser(),
        attachment_point=ap,
        installation_type=UserAS.VM,
        label=label,
        use_vpn=True,
        public_ip=None,
        public_port=test_public_port,
        bind_ip=None,
        bind_port=None,
    )
Beispiel #21
0
def _get_random_useras_params(seed,
                              force_public_ip=False,
                              force_bind_ip=False,
                              **kwargs):
    """
    Generate some "random" parameters for a UserAS based on `seed`.
    Any parameters to UserAS.objects.create can be specified to override the generated values.
    Note: overriding parameters may affect the generated value for other parameters.
    :returns: kwargs dict for UserAS.objects.create
    """
    r = random.Random(seed)

    def _randbool():
        return r.choice([True, False])

    use_vpn = kwargs.setdefault('use_vpn', _randbool())
    # Make AP choice both with/without VPN to always consume same amount of random state
    candidate_AP_vpn = r.choice(
        AttachmentPoint.objects.filter(vpn__isnull=False))
    candidate_AP_novpn = r.choice(AttachmentPoint.objects.all())
    if use_vpn:
        kwargs.setdefault('attachment_point', candidate_AP_vpn)
    else:
        kwargs.setdefault('attachment_point', candidate_AP_novpn)
    kwargs.setdefault('owner', get_testuser())

    public_ip = '172.31.0.%i' % r.randint(10, 254)
    public_port = r.choice(range(DEFAULT_PUBLIC_PORT,
                                 DEFAULT_PUBLIC_PORT + 20))
    if _randbool() or not use_vpn or force_public_ip:
        kwargs.setdefault('public_ip', public_ip)
    else:
        kwargs.setdefault('public_ip', None)
    kwargs.setdefault('public_port', public_port)

    bind_ip = '192.168.1.%i' % r.randint(10, 254)
    bind_port = r.choice(
        range(DEFAULT_PUBLIC_PORT + 1000, DEFAULT_PUBLIC_PORT + 1020))
    if _randbool() or force_bind_ip:
        kwargs.setdefault('bind_ip', bind_ip)
        kwargs.setdefault('bind_port', bind_port)
    else:
        kwargs.setdefault('bind_ip', None)
        kwargs.setdefault('bind_port', None)

    kwargs.setdefault('installation_type',
                      r.choice((UserAS.VM, UserAS.PKG, UserAS.SRC)))
    randstr = r.getrandbits(1024).to_bytes(1024 // 8,
                                           'little').decode('utf8', 'ignore')
    kwargs.setdefault('label', randstr)

    return kwargs
    def test_create_as_button_no_quota(self):
        """
        If the AS quota has been exceeded, the Create AS page is not available
        anymore.
        """
        _create_ases_for_testuser(get_testuser().max_num_ases())

        self.app.set_user(TESTUSER_EMAIL)
        # The quota should be exceeded: the Create AS button is gone
        user_page = self.app.get(reverse('user'))
        user_page.mustcontain(_QUOTA_EXCEEDED_MESSAGE)
        add_links = user_page.html.find_all("a", href=reverse('user_as_add'))
        self.assertEqual([], add_links)
Beispiel #23
0
    def test_create_valid(self, **kwargs):
        """
        Check that the form is valid with the given values as user input,
        and saving the form results in a new UserAS object.
        """
        form_data = self._get_initial_dict()
        form_data.update(**kwargs)

        form = UserASForm(user=get_testuser(), data=form_data)
        self.assertTrue(form.is_valid(), form.errors)

        user_as = form.save()
        self.assertIsNotNone(user_as)
 def test_create_valid(self, form_data):
     """
     Check that the form is valid with the given values as user input,
     and saving the form results in a new UserAS object.
     """
     form = UserASForm(user=get_testuser(), data=form_data)
     error_descs = _get_forms_error_descs(form)
     self.assertTrue(form.is_valid(), error_descs)
     user_as = form.save()
     self.assertIsNotNone(user_as)
     if form_data.get("user-as-become_user_ap", "") == "on":
         self.assertTrue(
             AttachmentPoint.objects.filter(AS=user_as).count() > 0)
Beispiel #25
0
def _create_user_as(attachment_point, label="Some label"):
    """
    Create a UserAS in a transaction, as would happen in a view.
    This will then trigger the on_commit and run the deployment tasks.
    """
    return UserAS.objects.create(
        owner=get_testuser(),
        attachment_point=attachment_point,
        installation_type=UserAS.PKG,
        label=label,
        use_vpn=False,
        public_ip=str(ipaddress.ip_address(test_public_ip) + 2),
        public_port=test_public_port,
    )
Beispiel #26
0
    def test_as_listing(self):
        """
        The main user page should contain a listing of the user's ASes with one link
        to the detail page for each of them.
        """
        def check_as_link_count(user_page, expected_count):
            links = user_page.html.find_all("a", href=lambda x: re.fullmatch(r"/user/as/\d*", x))
            self.assertEqual(expected_count, len(links), links)

        self.app.set_user(TESTUSER_EMAIL)

        # Start with no ASes
        self.assertFalse(UserAS.objects.filter(owner=get_testuser()).exists())
        user_page = self.app.get(reverse('user'))
        check_as_link_count(user_page, 0)
        self.assertTrue(_NO_USER_AS_MESSAGE in user_page, user_page)

        for n in range(get_testuser().max_num_ases()):
            _create_ases_for_testuser(1)
            user_page = self.app.get(reverse('user'))
            check_as_link_count(user_page, n+1)

        self.assertFalse(_NO_USER_AS_MESSAGE in user_page, user_page)
Beispiel #27
0
def _get_random_useras_params(seed, vpn_choice, **kwargs):
    """
    Generate some "random" parameters for a UserAS based on `seed`.
    Any parameters to UserAS.objects.create can be specified to override the generated values.
    :returns: kwargs dict for UserAS.objects.create
    """
    r = random.Random(seed)

    kwargs.setdefault('owner', get_testuser())
    kwargs.setdefault('installation_type',
                      r.choice((UserAS.VM, UserAS.PKG, UserAS.SRC)))
    randstr = r.getrandbits(1024).to_bytes(1024 // 8,
                                           'little').decode('utf8', 'ignore')
    kwargs.setdefault('label', randstr)

    return kwargs
def _create_ases_for_testuser(num):
    """ Create a number `num` UserASes for testuser """
    user = get_testuser()
    num_existing_ases = UserAS.objects.filter(owner=user).count()
    for i in range(num_existing_ases, num_existing_ases + num):
        ap = AttachmentPoint.objects.first()
        user_as = UserAS.objects.create(
            owner=user,
            installation_type=UserAS.VM,
            isd=ap.AS.isd,
            label="Testuser's AS number %i" % (i + 1),
        )
        att_conf = AttachmentConf(ap,
                                  public_ip=_test_ip,
                                  public_port=_test_start_port + i)
        user_as.update_attachments([att_conf])
Beispiel #29
0
    def test_cycle_active(self):
        def check_active(active, user_as, edit_page):
            self.assertEqual("Activate" in edit_page, not active, edit_page)
            self.assertEqual("Deactivate" in edit_page, active, edit_page)
            self.assertEqual(user_as.is_active(), active)

        _create_ases_for_testuser(3)
        user_as = UserAS.objects.filter(owner=get_testuser())[1]

        self.app.set_user(TESTUSER_EMAIL)
        user_page = self.app.get(reverse('user'))
        edit_page = user_page.click(href=reverse('user_as_detail', kwargs={'pk': user_as.pk})+'$')
        check_active(True, user_as, edit_page)

        edit_page = edit_page.forms['id_deactivate_form'].submit().maybe_follow()
        check_active(False, user_as, edit_page)

        edit_page = edit_page.forms['id_activate_form'].submit().maybe_follow()
        check_active(True, user_as, edit_page)
Beispiel #30
0
def _create_user_as(attachment_point, label="Some label"):
    """
    Create a UserAS in a transaction, as would happen in a view.
    This will then trigger the on_commit and run the deployment tasks.
    :returns UserAS: the created user_as
    """
    user_as = UserAS.objects.create(
        owner=get_testuser(),
        installation_type=UserAS.PKG,
        isd=attachment_point.AS.isd,
        label=label,
    )
    att_conf = AttachmentConf(attachment_point,
                              str(ipaddress.ip_address(test_public_ip) + 2),
                              test_public_port,
                              bind_ip=None,
                              bind_port=None,
                              use_vpn=False)
    user_as.update_attachments([att_conf])
    return user_as