class EditClusterForm(forms.ModelForm):
    """
    Basic form for editing a cluster.
    """
    class Meta:
        model = Cluster
        widgets = {
            'password': forms.PasswordInput(),
        }

    ram = DataVolumeField(label=_('Memory'), required=False, min_value=0)
    disk = DataVolumeField(label=_('Disk Space'), required=False, min_value=0)

    def clean(self):
        """
        Validate this form.

        Much of the validation is handled in the Cluster model; this method
        should not duplicate any validation done as part of the Cluster model
        definition.
        """

        data = self.cleaned_data = super(EditClusterForm, self).clean()
        user = data.get('username', None)
        password = data.get('password', None)
        hostname = data.get("hostname", None)

        if self.instance is None or not self.instance.username:
            # new cluster or a cluster without a username set
            if user and not password:
                msg = _('Enter a password')
                self._errors['password'] = self.error_class([msg])

            elif password and not user:
                msg = _('Enter a username')
                self._errors['username'] = self.error_class([msg])

            # Automatically set the slug on cluster creation, based on the
            # hostname, if no slug was provided.
            if hostname and 'slug' not in data:
                data['slug'] = slugify(hostname.split('.')[0])
                del self._errors['slug']

        elif self.instance.username:
            # cluster had a username set.  password is not required unless the
            # username is changed
            if user:
                if user != self.instance.username and not password:
                    msg = _('Enter a password')
                    self._errors['password'] = self.error_class([msg])
                elif not password:
                    # user didn't enter a password and it wasn't required
                    # retain existing password instead of setting to empty string
                    data['password'] = self.instance.password

            elif password:
                msg = _('Enter a username')
                self._errors['username'] = self.error_class([msg])

        return data
Beispiel #2
0
class TestDataVolumeFieldToPython(TestCase):
    """
    Test converting DataVolumeField to Python types using the to_python()
    method.
    """

    def setUp(self):
        self.f = DataVolumeField(required=True, min_value=0.)

    def test_trivial(self):
        """
        Check that setUp() is sane.
        """

        pass

    def test_clean_none(self):
        """
        Check that a ValidationError is raised when None is passed in.
        """

        self.assertRaises(ValidationError, self.f.clean, None)

    def test_validationerror(self):
        """
        Make sure that ValidationError is raised when appropriate.
        """

        self.assertRaises(ValidationError, self.f.clean, 'gdrcigeudr7d')
        self.assertRaises(ValidationError, self.f.clean, '     ')
        self.assertRaises(ValidationError, self.f.clean, '')

        # Wrong units?
        self.assertRaises(ValidationError, self.f.clean, '100.0 GMB')
        self.assertRaises(ValidationError, self.f.clean, '250 B')
        self.assertRaises(ValidationError, self.f.clean, '50 yogdiecidu')

    def test_empty_not_required(self):
        """
        Make sure that empty fields clean() to None when a value isn't
        required.
        """

        self.f.required = False
        self.assertEquals(self.f.clean(''), None)
        self.assertEquals(self.f.clean('     '), None)

    def test_correct_values(self):
        """
        Make sure that correct values are generated for valid data.
        """

        self.assertEquals(self.f.clean('9001 GB'), 9217024)
        self.assertEquals(self.f.clean('9001.000 GB'), 9217024)
        self.assertEquals(self.f.clean('9001G'), 9217024)
        self.assertEquals(self.f.clean('0.5G'), 512)
        self.assertEquals(self.f.clean('100.0 MB'), 100)
        self.assertEquals(self.f.clean('100.00MB'), 100)
        self.assertEquals(self.f.clean('100.000 M'), 100)
        self.assertEquals(self.f.clean('100M'), 100)
class QuotaForm(forms.Form):
    """
    Form for editing user quota on a cluster
    """
    input = forms.TextInput(attrs={'size': 5})

    user = forms.ModelChoiceField(queryset=ClusterUser.objects.all(), \
                                  widget=forms.HiddenInput)
    ram = DataVolumeField(label='Memory', required=False, min_value=0)
    virtual_cpus = forms.IntegerField(label='Virtual CPUs', required=False, \
                                    min_value=0, widget=input)
    disk = DataVolumeField(label='Disk Space', required=False, min_value=0)
    delete = forms.BooleanField(required=False, widget=forms.HiddenInput)
Beispiel #4
0
 def create_disk_fields(self, count):
     """
     dynamically add fields for disks
     """
     self.disk_fields = range(count)
     for i in range(count):
         disk_size = DataVolumeField(min_value=100,
                                     required=True,
                                     label=_("Disk/%s Size" % i))
         self.fields['disk_size_%s' % i] = disk_size
Beispiel #5
0
class VirtualMachineForm(forms.ModelForm):
    """
    Parent class that holds all vm clean methods
      and shared form fields.
    """
    memory = DataVolumeField(label=_('Memory'), min_value=100)

    class Meta:
        model = VirtualMachineTemplate

    def create_disk_fields(self, count):
        """
        dynamically add fields for disks
        """
        self.disk_fields = range(count)
        for i in range(count):
            disk_size = DataVolumeField(min_value=100,
                                        required=True,
                                        label=_("Disk/%s Size" % i))
            self.fields['disk_size_%s' % i] = disk_size

    def create_nic_fields(self, count, defaults=None):
        """
        dynamically add fields for nics
        """
        self.nic_fields = range(count)
        for i in range(count):
            nic_mode = forms.ChoiceField(label=_('NIC/%s Mode' % i),
                                         choices=HV_NIC_MODES)
            nic_link = forms.CharField(label=_('NIC/%s Link' % i),
                                       max_length=255)
            if defaults is not None:
                nic_link.initial = defaults['nic_link']
            self.fields['nic_mode_%s' % i] = nic_mode
            self.fields['nic_link_%s' % i] = nic_link

    def clean_hostname(self):
        data = self.cleaned_data
        hostname = data.get('hostname')
        cluster = data.get('cluster')
        if hostname and cluster:
            # Verify that this hostname is not in use for this cluster.  It can
            # only be reused when recovering a VM that failed to deploy.
            #
            # Recoveries are only allowed when the user is the owner of the VM
            try:
                vm = VirtualMachine.objects.get(cluster=cluster,
                                                hostname=hostname)

                # detect vm that failed to deploy
                if not vm.pending_delete and vm.template is not None:
                    current_owner = vm.owner.cast()
                    if current_owner == self.owner:
                        data['vm_recovery'] = vm
                    else:
                        msg = _(
                            "Owner cannot be changed when recovering a failed deployment"
                        )
                        self._errors["owner"] = self.error_class([msg])
                else:
                    raise ValidationError(
                        _("Hostname is already in use for this cluster"))

            except VirtualMachine.DoesNotExist:
                # doesn't exist, no further checks needed
                pass

        # Spaces in hostname will always break things.
        if ' ' in hostname:
            self.errors["hostname"] = self.error_class(
                ["Hostname contains illegal character"])
        return hostname

    def clean_vcpus(self):
        vcpus = self.cleaned_data.get("vcpus", None)

        if vcpus is not None and vcpus < 1:
            self._errors["vcpus"] = self.error_class(
                ["At least one CPU must be present"])
        else:
            return vcpus

    def clean_initrd_path(self):
        data = self.cleaned_data['initrd_path']
        if data and not data.startswith('/') and data != 'no_initrd_path':
            msg = u"%s." % _('This field must start with a "/"')
            self._errors['initrd_path'] = self.error_class([msg])
        return data

    def clean_security_domain(self):
        data = self.cleaned_data['security_domain']
        security_model = self.cleaned_data['security_model']
        msg = None

        if data and security_model != 'user':
            msg = u'%s.' % _(
                'This field can not be set if Security Mode is not set to User'
            )
        elif security_model == 'user':
            if not data:
                msg = u'%s.' % _('This field is required')
            elif not data[0].isalpha():
                msg = u'%s.' % _(
                    'This field must being with an alpha character')

        if msg:
            self._errors['security_domain'] = self.error_class([msg])
        return data

    def clean_vnc_x509_path(self):
        data = self.cleaned_data['vnc_x509_path']
        if data and not data.startswith('/'):
            msg = u'%s,' % _('This field must start with a "/"')
            self._errors['vnc_x509_path'] = self.error_class([msg])
        return data
Beispiel #6
0
 def setUp(self):
     self.f = DataVolumeField(required=True, min_value=0.)