コード例 #1
0
ファイル: forms.py プロジェクト: zhengfengran/freenas
class ProductionForm(Form):

    production = forms.BooleanField(
        label=_('This is production system'),
        required=False,
    )

    send_debug = forms.BooleanField(
        label=_('Send initial debug'),
        required=False,
    )

    def __init__(self, *args, **kwargs):
        super(ProductionForm, self).__init__(*args, **kwargs)

        self.fields['production'].widget.attrs['onChange'] = (
            'support_production_toggle();')

        with client as c:
            self.initial['production'] = c.call('truenas.is_production')

    def save(self):
        with client as c:
            c.call('truenas.set_production', self.cleaned_data['production'],
                   self.cleaned_data['send_debug'])
コード例 #2
0
class JailConfigureForm(ModelForm):

    jail_autostart = forms.BooleanField(label=_("autostart"), required=False)
    jail_source = forms.BooleanField(label=_("source"), required=False)
    jail_ports = forms.BooleanField(label=_("ports"), required=False)

    class Meta:
        model = Jails
コード例 #3
0
 def __init__(self, *args, **kwargs):
     super(AFP_ShareForm, self).__init__(*args, **kwargs)
     self.fields['afp_upriv'].widget.attrs['onChange'] = (
         'javascript:toggleGeneric("id_afp_upriv", ["id_afp_fperm", '
         '"id_afp_dperm"], true);')
     self.fields['afp_fperm'] = UnixPermissionField(
         label=self.fields['afp_fperm'].label,
         initial=self.fields['afp_fperm'].initial,
         required=False,
     )
     self.fields['afp_dperm'] = UnixPermissionField(
         label=self.fields['afp_dperm'].label,
         initial=self.fields['afp_dperm'].initial,
         required=False,
     )
     if self.instance.id:
         self.fields['afp_sharepw2'].initial = self.instance.afp_sharepw
         if self.instance.afp_sharepw:
             self.fields['afp_deletepw'] = forms.BooleanField(
                 label=_("Delete password"),
                 initial=False,
                 required=False,
             )
             self.fields.keyOrder.remove('afp_deletepw')
             self.fields.keyOrder.insert(5, 'afp_deletepw')
         if not self.instance.afp_upriv:
             self.fields['afp_fperm'].widget.attrs['disabled'] = 'true'
             self.fields['afp_dperm'].widget.attrs['disabled'] = 'true'
         else:
             self.fields['afp_fperm'].widget.attrs['disabled'] = 'false'
             self.fields['afp_dperm'].widget.attrs['disabled'] = 'false'
コード例 #4
0
class ProductionForm(Form):

    production = forms.BooleanField(
        label=_('This is production system'),
        required=False,
    )

    send_debug = forms.BooleanField(
        label=_('Send initial debug'),
        required=False,
    )

    def __init__(self, *args, **kwargs):
        super(ProductionForm, self).__init__(*args, **kwargs)

        self.fields['production'].widget.attrs['onChange'] = (
            'support_production_toggle();')

        with client as c:
            self.initial['production'] = c.call('keyvalue.get',
                                                'truenas:production', False)

    def save(self):
        with client as c:
            send_debug = (
                not c.call('keyvalue.get', 'truenas:production', False)
                and self.cleaned_data['production']
                and self.cleaned_data['send_debug'])
            c.call('keyvalue.set', 'truenas:production',
                   self.cleaned_data['production'])
            if send_debug:
                serial = c.call('system.info')["system_serial"]
                c.call(
                    'support.new_ticket', {
                        "title":
                        f"System has been just put into production ({serial})",
                        "body":
                        "This system has been just put into production",
                        "attach_debug": True,
                        "category": "Installation/Setup",
                        "criticality": "Inquiry",
                        "environment": "Production",
                        "name": "Automatic Alert",
                        "email": "*****@*****.**",
                        "phone": "-",
                    })
コード例 #5
0
ファイル: forms.py プロジェクト: BillTheBest/MetaNAS
 def __init__(self, *args, **kwargs):
     self.instance = kwargs.pop('instance', None)
     services = kwargs.pop('services', {})
     super(VolumeExport, self).__init__(*args, **kwargs)
     if services.keys():
         self.fields['cascade'] = forms.BooleanField(
             initial=True,
             required=False,
             label=_("Delete all shares related to this volume"))
コード例 #6
0
ファイル: forms.py プロジェクト: neojiangtw/freenas
 def __init__(self, *args, **kwargs):
     self.instance = kwargs.pop('instance', None)
     super(DeleteUserForm, self).__init__(*args, **kwargs)
     qs = models.bsdUsers.objects.filter(bsdusr_group__id=self.instance.bsdusr_group.id).exclude(id=self.instance.id)
     if not qs.exists():
         self.fields['nodelgroup'] = forms.BooleanField(
             label=_("Do not delete user primary group"),
             required=False,
             initial=False,
         )
コード例 #7
0
class IPMIForm(Form):
    # Max password length via IPMI v2.0 is 20 chars. We only support IPMI
    # v2.0+ compliant boards thus far.
    ipmi_password1 = forms.CharField(label=_("Password"),
                                     max_length=20,
                                     widget=forms.PasswordInput,
                                     required=False)
    ipmi_password2 = forms.CharField(
        label=_("Password confirmation"),
        max_length=20,
        widget=forms.PasswordInput,
        help_text=_("Enter the same password as above, for verification."),
        required=False)
    dhcp = forms.BooleanField(
        label=_("DHCP"),
        required=False,
    )
    ipv4address = IP4AddressFormField(
        initial='',
        required=False,
        label=_("IPv4 Address"),
    )
    ipv4netmaskbit = forms.ChoiceField(
        choices=choices.v4NetmaskBitList,
        required=False,
        label=_("IPv4 Netmask"),
    )
    ipv4gw = IP4AddressFormField(
        initial='',
        required=False,
        label=_("IPv4 Default Gateway"),
    )

    def __init__(self, *args, **kwargs):
        super(IPMIForm, self).__init__(*args, **kwargs)
        self.fields['dhcp'].widget.attrs['onChange'] = (
            'javascript:toggleGeneric('
            '"id_dhcp", ["id_ipv4address", "id_ipv4netmaskbit"]);')

    def clean_ipmi_password2(self):
        ipmi_password1 = self.cleaned_data.get("ipmi_password1", "")
        ipmi_password2 = self.cleaned_data["ipmi_password2"]
        if ipmi_password1 != ipmi_password2:
            raise forms.ValidationError(
                _("The two password fields didn't match."))
        return ipmi_password2

    def clean_ipv4netmaskbit(self):
        try:
            cidr = int(self.cleaned_data.get("ipv4netmaskbit"))
        except ValueError:
            return None
        bits = 0xffffffff ^ (1 << 32 - cidr) - 1
        return socket.inet_ntoa(pack('>I', bits))
コード例 #8
0
ファイル: forms.py プロジェクト: noprobs/freenas
class PasswordChangeForm(SetPasswordForm):
    """
    A form that lets a user change his/her password by entering
    their old password.
    """
    change_root = forms.BooleanField(
        label=_("Change root password as well"),
        initial=True,
        required=False,
    )

    def __init__(self, *args, **kwargs):
        super(PasswordChangeForm, self).__init__(*args, **kwargs)
        if self.user.has_usable_password():
            self.fields['old_password'] = forms.CharField(
                label=_("Old password"),
                widget=forms.PasswordInput,
            )
            self.fields.keyOrder = [
                'old_password', 'new_password', 'new_password2', 'change_root'
            ]
        else:
            self.fields.keyOrder = [
                'new_password', 'new_password2', 'change_root'
            ]
        if self._api is True:
            del self.fields['new_password2']

    def clean_old_password(self):
        """
        Validates that the old_password field is correct.
        """
        if not self.user.has_usable_password():
            return ''
        old_password = self.cleaned_data["old_password"]
        if not self.user.check_password(old_password):
            raise forms.ValidationError(_(
                "Your old password was entered incorrectly. Please enter it "
                "again."
            ))
        return old_password

    def save(self, *args, **kwargs):
        with transaction.commit_on_success():
            if self.cleaned_data.get('change_root'):
                root = models.bsdUsers.objects.get(bsdusr_username='******')
                new_password = self.cleaned_data.get('new_password')
                bsdpasswdform = bsdUserPasswordForm(instance=root)
                bsdpasswdform.cleaned_data = {}
                bsdpasswdform.cleaned_data['bsdusr_password'] = new_password
                bsdpasswdform.cleaned_data['bsdusr_password2'] = new_password
                bsdpasswdform.save()
            return super(PasswordChangeForm, self).save(*args, **kwargs)
コード例 #9
0
ファイル: forms.py プロジェクト: BillTheBest/MetaNAS
 def __init__(self, *args, **kwargs):
     self.fs = kwargs.pop('fs')
     self.datasets = kwargs.pop('datasets', [])
     super(Dataset_Destroy, self).__init__(*args, **kwargs)
     snaps = notifier().zfs_snapshot_list(path=self.fs)
     if len(snaps.get(self.fs, [])) > 0:
         label = ungettext(
             "I'm aware this will destroy snapshots within this dataset",
             ("I'm aware this will destroy all child datasets and "
              "snapshots within this dataset"), len(self.datasets))
         self.fields['cascade'] = forms.BooleanField(initial=True,
                                                     label=label)
コード例 #10
0
 def __init__(self, *args, **kwargs):
     super(bsdGroupsForm, self).__init__(*args, **kwargs)
     if self.instance.id:
         self.fields['bsdgrp_gid'].widget.attrs['readonly'] = True
         self.fields['bsdgrp_gid'].widget.attrs['class'] = (
             'dijitDisabled dijitTextBoxDisabled '
             'dijitValidationTextBoxDisabled')
     else:
         self.initial['bsdgrp_gid'] = notifier().user_getnextgid()
         self.fields['allow'] = forms.BooleanField(
             label=_("Allow repeated GIDs"),
             initial=False,
             required=False,
         )
コード例 #11
0
ファイル: forms.py プロジェクト: vaibhav-rbs/freenas
class CIFS_ShareForm(MiddlewareModelForm, ModelForm):

    cifs_default_permissions = forms.BooleanField(
        label=_('Apply Default Permissions'),
        help_text=_(
            'Recursively set appropriate default Windows permissions on share'
        ),
        required=False)
    middleware_attr_prefix = "cifs_"
    middleware_attr_schema = "sharingsmb"
    middleware_plugin = "sharing.smb"
    is_singletone = False

    def __init__(self, *args, **kwargs):
        super(CIFS_ShareForm, self).__init__(*args, **kwargs)
        if self.instance.id:
            self.fields['cifs_default_permissions'].initial = False
            self._original_cifs_vfsobjects = self.instance.cifs_vfsobjects
        else:
            self.fields['cifs_default_permissions'].initial = True
            self._original_cifs_vfsobjects = []

        key_order(self, 4, 'cifs_default_permissions', instance=True)

        self.fields['cifs_guestok'].widget.attrs['onChange'] = (
            'javascript:toggleGeneric("id_cifs_guestok", '
            '["id_cifs_guestonly"], true);')
        if self.data:
            if self.data.get('cifs_guestok') is False:
                self.fields['cifs_guestonly'].widget.attrs['disabled'] = \
                    'disabled'
        elif self.instance.cifs_guestok is False:
            self.fields['cifs_guestonly'].widget.attrs['disabled'] = 'disabled'
        self.fields['cifs_name'].required = False

    class Meta:
        fields = '__all__'
        model = models.CIFS_Share

    def middleware_clean(self, data):
        data['hostsallow'] = data['hostsallow'].split()
        data['hostsdeny'] = data['hostsdeny'].split()

        return data

    def done(self, request, events):
        if not services.objects.get(srv_service='cifs').srv_enable:
            events.append('ask_service("cifs")')
        super(CIFS_ShareForm, self).done(request, events)
コード例 #12
0
ファイル: forms.py プロジェクト: BillTheBest/MetaNAS
class ExtentDelete(Form):
    delete = forms.BooleanField(
        label=_("Delete underlying file"),
        initial=False,
        required=False,
    )

    def __init__(self, *args, **kwargs):
        self.instance = kwargs.pop('instance', None)
        super(ExtentDelete, self).__init__(*args, **kwargs)

    def done(self, *args, **kwargs):
        if self.cleaned_data['delete'] and \
            self.instance.iscsi_target_extent_type == 'File':
            os.unlink(self.instance.iscsi_target_extent_path)
コード例 #13
0
ファイル: forms.py プロジェクト: BillTheBest/MetaNAS
class PluginsJailDeleteForm(Form):
    delete = forms.BooleanField(
        label=_("Are you sure you want to delete?"),
        initial=False,
        required=True,
    )

    def __init__(self, *args, **kwargs):
        self.instance = kwargs.pop('instance', None)
        super(PluginsJailDeleteForm, self).__init__(*args, **kwargs)

    def done(self, *args, **kwargs):
        events = kwargs.pop('events', None)
        if events is not None:
            events.append("refreshPlugins()")
コード例 #14
0
ファイル: forms.py プロジェクト: lokiscarlet/freenas
class DeleteGroupForm(forms.Form):

    cascade = forms.BooleanField(
        label=_("Do you want to delete all users with this primary group?"),
        required=False,
        initial=False,
    )

    def __init__(self, *args, **kwargs):
        self.instance = kwargs.pop('instance', None)
        super(DeleteGroupForm, self).__init__(*args, **kwargs)

    def done(self, *args, **kwargs):
        if self.cleaned_data.get("cascade") is True:
            models.bsdUsers.objects.filter(bsdusr_group=self.instance).delete()
コード例 #15
0
ファイル: forms.py プロジェクト: BillTheBest/MetaNAS
class VolumeExport(Form):
    mark_new = forms.BooleanField(
        required=False,
        initial=False,
        label=_("Mark the disks as new (destroy data)"),
    )

    def __init__(self, *args, **kwargs):
        self.instance = kwargs.pop('instance', None)
        services = kwargs.pop('services', {})
        super(VolumeExport, self).__init__(*args, **kwargs)
        if services.keys():
            self.fields['cascade'] = forms.BooleanField(
                initial=True,
                required=False,
                label=_("Delete all shares related to this volume"))
コード例 #16
0
class NTPForm(ModelForm):

    force = forms.BooleanField(label=_("Force"), required=False)

    class Meta:
        fields = '__all__'
        model = models.NTPServer

    def __init__(self, *args, **kwargs):
        super(NTPForm, self).__init__(*args, **kwargs)
        self.usable = True

    def clean_ntp_address(self):
        addr = self.cleaned_data.get("ntp_address")
        p1 = subprocess.Popen(
            ["/usr/sbin/ntpdate", "-q", addr],
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE
        )
        p1.communicate()
        if p1.returncode != 0:
            self.usable = False
        return addr

    def clean_ntp_maxpoll(self):
        maxp = self.cleaned_data.get("ntp_maxpoll")
        minp = self.cleaned_data.get("ntp_minpoll")
        if not maxp > minp:
            raise forms.ValidationError(_(
                "Max Poll should be higher than Min Poll"
            ))
        return maxp

    def clean(self):
        cdata = self.cleaned_data
        if not cdata.get("force", False) and not self.usable:
            self._errors['ntp_address'] = self.error_class([_(
                "Server could not be reached. Check \"Force\" to continue "
                "regardless."
            )])
            del cdata['ntp_address']
        return cdata

    def save(self):
        super(NTPForm, self).save()
        notifier().start("ix-ntpd")
        notifier().restart("ntpd")
コード例 #17
0
ファイル: forms.py プロジェクト: vaibhav-rbs/freenas
class ExtentDelete(Form):
    delete = forms.BooleanField(
        label=_("Delete underlying file"),
        initial=False,
        required=False,
    )

    def __init__(self, *args, **kwargs):
        self.instance = kwargs.pop('instance', None)
        super(ExtentDelete, self).__init__(*args, **kwargs)
        if self.instance.iscsi_target_extent_type != 'File':
            self.fields.pop('delete')
        if not self.data:
            target_to_extent_list = models.iSCSITargetToExtent.objects.filter(
                iscsi_extent__iscsi_target_extent_name=self.instance.
                iscsi_target_extent_name)
            basename = models.iSCSITargetGlobalConfiguration.objects.order_by(
                '-id')[0].iscsi_basename
            targets = []
            for target_to_extent in target_to_extent_list:
                target = target_to_extent.iscsi_target.iscsi_target_name
                if not target.startswith(('iqn.', 'naa.', 'eui.')):
                    target = basename + ':' + target
                targets.append(target)

            if not targets:
                return

            with client as c:
                if c.call('iscsi.global.sessions',
                          [['target', 'in', targets]]):
                    self.errors['__all__'] = self.error_class(
                        ["Warning: Associated Target is in use"])

    def done(self, *args, **kwargs):
        if (self.instance.iscsi_target_extent_type == 'File'
                and self.cleaned_data['delete']
                and os.path.exists(self.instance.iscsi_target_extent_path)):
            data = {}
            data['type'] = self.instance.iscsi_target_extent_type
            data['path'] = self.instance.iscsi_target_extent_path

            with client as c:
                c.call('iscsi.extent.remove_extent_file', data)
コード例 #18
0
class ExtentDelete(Form):
    delete = forms.BooleanField(
        label=_("Delete underlying file"),
        initial=False,
        required=False,
    )

    def __init__(self, *args, **kwargs):
        self.instance = kwargs.pop('instance', None)
        super(ExtentDelete, self).__init__(*args, **kwargs)
        if self.instance.iscsi_target_extent_type != 'File':
            self.fields.pop('delete')
        if not self.data:
            targets_in_use = notifier().iscsi_connected_targets()
            is_extent_active = False
            target_to_extent_list = models.iSCSITargetToExtent.objects.filter(
                iscsi_extent__iscsi_target_extent_name=self.instance.
                iscsi_target_extent_name)
            basename = models.iSCSITargetGlobalConfiguration.objects.order_by(
                '-id')[0].iscsi_basename
            for target_to_extent in target_to_extent_list:
                target = target_to_extent.iscsi_target.iscsi_target_name
                if not target.startswith(('iqn.', 'naa.', 'eui.')):
                    target = basename + ':' + target
                if target in targets_in_use:
                    is_extent_active = True
                    # Extent is active. No need to check other targets.
                    break
            if is_extent_active:
                self.errors['__all__'] = self.error_class(
                    ["Warning: Associated Target is in use"])

    def done(self, *args, **kwargs):
        if (self.instance.iscsi_target_extent_type == 'File'
                and self.cleaned_data['delete']
                and os.path.exists(self.instance.iscsi_target_extent_path)):
            data = {}
            data['type'] = self.instance.iscsi_target_extent_type
            data['path'] = self.instance.iscsi_target_extent_path

            with client as c:
                c.call('iscsi.extent.remove_extent_file', data)
コード例 #19
0
    def __init__(self, *args, **kwargs):
        super(bsdGroupsForm, self).__init__(*args, **kwargs)
        if self.instance.id:
            self.fields['bsdgrp_gid'].widget.attrs['readonly'] = True
            self.fields['bsdgrp_gid'].widget.attrs['class'] = (
                'dijitDisabled dijitTextBoxDisabled '
                'dijitValidationTextBoxDisabled')
            self.instance._original_bsdgrp_group = self.instance.bsdgrp_group

        else:
            try:
                with client as c:
                    self.initial['bsdgrp_gid'] = c.call('group.get_next_gid')
            except Exception:
                pass
            self.fields['allow'] = forms.BooleanField(
                label=_("Allow repeated GIDs"),
                initial=False,
                required=False,
            )
コード例 #20
0
ファイル: forms.py プロジェクト: BillTheBest/MetaNAS
class ManualSnapshotForm(Form):
    ms_recursively = forms.BooleanField(initial=False,
                                        required=False,
                                        label=_('Recursive snapshot'))
    ms_name = forms.CharField(label=_('Snapshot Name'))

    def __init__(self, *args, **kwargs):
        super(ManualSnapshotForm, self).__init__(*args, **kwargs)
        self.fields['ms_name'].initial = datetime.today().strftime(
            'manual-%Y%m%d')

    def clean_ms_name(self):
        regex = re.compile('^[-a-zA-Z0-9_.]+$')
        if regex.match(self.cleaned_data['ms_name'].__str__()) is None:
            raise forms.ValidationError(
                _("Only [-a-zA-Z0-9_.] permitted as snapshot name"))
        return self.cleaned_data['ms_name']

    def commit(self, fs):
        notifier().zfs_mksnap(fs, str(self.cleaned_data['ms_name']),
                              self.cleaned_data['ms_recursively'])
コード例 #21
0
ファイル: forms.py プロジェクト: BillTheBest/MetaNAS
class MountPointAccessForm(Form):
    mp_user = UserField(label=_('Owner (user)'))
    mp_group = GroupField(label=_('Owner (group)'))
    mp_mode = UnixPermissionField(label=_('Mode'))
    mp_acl = forms.ChoiceField(label=_('Type of ACL'),
                               choices=(
                                   ('unix', 'Unix'),
                                   ('windows', 'Windows'),
                               ),
                               initial='unix',
                               widget=forms.widgets.RadioSelect())
    mp_recursive = forms.BooleanField(initial=False,
                                      required=False,
                                      label=_('Set permission recursively'))

    def __init__(self, *args, **kwargs):
        super(MountPointAccessForm, self).__init__(*args, **kwargs)

        path = kwargs.get('initial', {}).get('path', None)
        if path:
            if os.path.exists(os.path.join(path, ".windows")):
                self.fields['mp_acl'].initial = 'windows'
            else:
                self.fields['mp_acl'].initial = 'unix'
            user, group = notifier().mp_get_owner(path)
            self.fields['mp_mode'].initial = "%.3o" % (
                notifier().mp_get_permission(path), )
            self.fields['mp_user'].initial = user
            self.fields['mp_group'].initial = group

    def commit(self, path='/mnt/'):

        notifier().mp_change_permission(
            path=path,
            user=self.cleaned_data['mp_user'].__str__(),
            group=self.cleaned_data['mp_group'].__str__(),
            mode=self.cleaned_data['mp_mode'].__str__(),
            recursive=self.cleaned_data['mp_recursive'],
            acl=self.cleaned_data['mp_acl'])
コード例 #22
0
ファイル: forms.py プロジェクト: lokiscarlet/freenas
class PasswordChangeForm(SetPasswordForm):
    """
    A form that lets a user change his/her password by entering
    their old password.
    """
    change_root = forms.BooleanField(
        label=_("Change root password as well"),
        initial=True,
        required=False,
    )

    def __init__(self, *args, **kwargs):
        super(PasswordChangeForm, self).__init__(*args, **kwargs)
        if self.user.has_usable_password():
            self.fields['old_password'] = forms.CharField(
                label=_("Old password"),
                widget=forms.PasswordInput,
            )
            self.fields.keyOrder = [
                'old_password', 'new_password1', 'new_password2', 'change_root'
            ]
        else:
            self.fields.keyOrder = [
                'new_password1', 'new_password2', 'change_root'
            ]

    def clean_old_password(self):
        """
        Validates that the old_password field is correct.
        """
        if not self.user.has_usable_password():
            return ''
        old_password = self.cleaned_data["old_password"]
        if not self.user.check_password(old_password):
            raise forms.ValidationError(
                _("Your old password was entered incorrectly. Please enter it "
                  "again."))
        return old_password
コード例 #23
0
class bsdUsersForm(ModelForm):

    bsdusr_username = forms.CharField(label=_("Username"), max_length=16)
    bsdusr_password = forms.CharField(label=_("Password"),
                                      widget=forms.PasswordInput,
                                      required=False)
    bsdusr_password2 = forms.CharField(
        label=_("Password confirmation"),
        widget=forms.PasswordInput,
        help_text=_("Enter the same password as above, for verification."),
        required=False)
    bsdusr_group = forms.ModelChoiceField(
        label=_("Primary Group"),
        queryset=models.bsdGroups.objects.all(),
        required=False)
    bsdusr_creategroup = forms.BooleanField(
        label=_("Create a new primary group for the user"),
        required=False,
        initial=True)
    bsdusr_sshpubkey = forms.CharField(label=_("SSH Public Key"),
                                       widget=forms.Textarea,
                                       required=False)
    bsdusr_mode = UnixPermissionField(label=_('Home Directory Mode'),
                                      initial='755',
                                      required=False)
    bsdusr_to_group = SelectMultipleField(label=_('Auxiliary groups'),
                                          choices=(),
                                          required=False)

    advanced_fields = ['bsdusr_mode']
    middleware_attr_map = {
        'groups': 'bsdusr_to_group',
        'group_create': 'bsdusr_creategroup',
        'home_mode': 'bsdusr_home',
    }
    middleware_attr_prefix = 'bsdusr_'

    class Meta:
        model = models.bsdUsers
        widgets = {
            'bsdusr_uid': forms.widgets.ValidationTextInput(),
        }
        exclude = (
            'bsdusr_unixhash',
            'bsdusr_smbhash',
            'bsdusr_group',
        )
        fields = (
            'bsdusr_uid',
            'bsdusr_username',
            'bsdusr_creategroup',
            'bsdusr_home',
            'bsdusr_mode',
            'bsdusr_shell',
            'bsdusr_full_name',
            'bsdusr_email',
            'bsdusr_password',
            'bsdusr_password2',
            'bsdusr_password_disabled',
            'bsdusr_locked',
            'bsdusr_sudo',
            'bsdusr_microsoft_account',
            'bsdusr_sshpubkey',
            'bsdusr_to_group',
        )

    def __init__(self, *args, **kwargs):
        #FIXME: Workaround for DOJO not showing select with blank values
        if len(args) > 0 and isinstance(args[0], QueryDict):
            new = args[0].copy()
            if new.get('bsdusr_group', None) == '-----':
                new['bsdusr_group'] = ''
            args = (new, ) + args[1:]
        super(bsdUsersForm, self).__init__(*args, **kwargs)
        key_order(self, 3, 'bsdusr_group', instance=True)
        if self._api is True:
            del self.fields['bsdusr_password2']
        self.fields['bsdusr_to_group'].choices = [
            (x.id, x.bsdgrp_group) for x in models.bsdGroups.objects.all()
        ]
        self.fields['bsdusr_password_disabled'].widget.attrs['onChange'] = (
            'javascript:toggleGeneric("id_bsdusr_password_disabled", '
            '["id_bsdusr_locked", "id_bsdusr_sudo"], false);')
        self.fields['bsdusr_locked'].widget.attrs['onChange'] = (
            'javascript:toggleGeneric("id_bsdusr_locked", '
            '["id_bsdusr_password_disabled"], false);')
        self.fields['bsdusr_sudo'].widget.attrs['onChange'] = (
            'javascript:toggleGeneric("id_bsdusr_sudo", '
            '["id_bsdusr_password_disabled"], false);')

        if not self.instance.id:
            try:
                with client as c:
                    self.fields['bsdusr_uid'].initial = c.call(
                        'user.get_next_uid')
            except Exception:
                pass
            self.fields['bsdusr_home'].label = _('Create Home Directory In')
            self.fields['bsdusr_creategroup'].widget.attrs['onChange'] = (
                'javascript:toggleGeneric("id_bsdusr_creategroup", '
                '["id_bsdusr_group"], false);')
            self.fields['bsdusr_group'].widget.attrs['maxHeight'] = 200
            self.fields['bsdusr_group'].widget.attrs['disabled'] = 'disabled'
            self.fields['bsdusr_group'].choices = (
                ('-----', '-----'), ) + tuple(
                    [x for x in self.fields['bsdusr_group'].choices][1:])
            self.fields['bsdusr_group'].required = False
            self.bsdusr_home_saved = '/nonexistent'

        elif self.instance.id:
            self.fields['bsdusr_to_group'].initial = [
                x.bsdgrpmember_group.id
                for x in models.bsdGroupMembership.objects.filter(
                    bsdgrpmember_user=self.instance.id)
            ]

            del self.fields['bsdusr_creategroup']
            self.fields['bsdusr_group'].initial = self.instance.bsdusr_group
            self.advanced_fields = []
            self.bsdusr_home_saved = self.instance.bsdusr_home
            key_order(self, len(self.fields) - 1, 'bsdusr_mode', instance=True)
            self.fields['bsdusr_username'].widget.attrs['readonly'] = True
            self.fields['bsdusr_username'].widget.attrs['class'] = (
                'dijitDisabled dijitTextBoxDisabled '
                'dijitValidationTextBoxDisabled')
            if os.path.exists(self.instance.bsdusr_home):
                mode = os.stat(self.instance.bsdusr_home).st_mode & 0o777
                self.fields['bsdusr_mode'].initial = oct(mode)[2:]
            if self.instance.bsdusr_builtin:
                self.fields['bsdusr_uid'].widget.attrs['readonly'] = True
                self.fields['bsdusr_uid'].widget.attrs['class'] = (
                    'dijitDisabled dijitTextBoxDisabled '
                    'dijitValidationTextBoxDisabled')
                self.fields['bsdusr_group'].widget.attrs['readonly'] = True
                self.fields['bsdusr_group'].widget.attrs['class'] = (
                    'dijitDisabled dijitSelectDisabled')
                self.fields['bsdusr_home'].widget.attrs['readonly'] = True
                self.fields['bsdusr_home'].widget.attrs['class'] = (
                    'dijitDisabled dijitTextBoxDisabled '
                    'dijitValidationTextBoxDisabled')
                self.fields['bsdusr_mode'].widget.attrs['disabled'] = True
                self.fields['bsdusr_mode'].required = False
            if self.instance.bsdusr_locked or self.instance.bsdusr_sudo:
                self.fields['bsdusr_password_disabled'].widget.attrs[
                    'disabled'] = True
            if self.instance.bsdusr_password_disabled is True:
                self.fields['bsdusr_locked'].widget.attrs['disabled'] = True
                self.fields['bsdusr_sudo'].widget.attrs['disabled'] = True
            self.fields['bsdusr_sshpubkey'].initial = (
                self.instance.bsdusr_sshpubkey)

    def clean_bsdusr_password2(self):
        bsdusr_password = self.cleaned_data.get("bsdusr_password", "")
        bsdusr_password2 = self.cleaned_data["bsdusr_password2"]
        if bsdusr_password and bsdusr_password != bsdusr_password2:
            raise forms.ValidationError(
                _("The two password fields didn't match."))
        return bsdusr_password2

    def clean_bsdusr_home(self):
        home = self.cleaned_data['bsdusr_home']
        user_home = self.instance.bsdusr_home

        if self.instance.bsdusr_builtin:
            return self.instance.bsdusr_home
        if home is not None:
            if home == '/nonexistent':
                return home

            if home.startswith('/mnt/'):
                bsdusr_username = self.cleaned_data.get('bsdusr_username', '')
                volumes = [
                    '/mnt/{}'.format(volume.vol_name)
                    for volume in Volume.objects.all()
                ]

                if self.instance.id and home != user_home:
                    if len(zfs.list_datasets(path=user_home)) > 0 and \
                            (len(zfs.list_datasets(path=home)) > 0 and home.startswith(user_home + '/')):
                        raise forms.ValidationError(
                            _("A dataset inside the home dataset "
                              "cannot be used as a home directory."))

                if home in volumes:
                    raise forms.ValidationError(
                        _("Volume root directories cannot be used as user home directories."
                          ))

                if home.endswith(bsdusr_username):
                    return home

                if not self.instance.id:
                    home = "%s/%s" % (home.rstrip('/'), bsdusr_username)

                if not self.instance.id and not home.endswith(bsdusr_username):
                    raise forms.ValidationError(
                        _('Home directory must end with username'))

                return home

    def clean_bsdusr_mode(self):
        mode = self.cleaned_data.get('bsdusr_mode')
        if not self.instance.id and not mode:
            return '755'
        return mode

    def clean_bsdusr_sshpubkey(self):
        ssh = self.cleaned_data.get('bsdusr_sshpubkey', '')
        ssh = ssh.strip(' ').strip('\n')
        ssh = re.sub(r'[ ]{2,}', ' ', ssh, re.M)
        ssh = re.sub(r'\n{2,}', '\n', ssh, re.M)
        old = ssh
        while True:
            ssh = re.sub(r'(\S{20,})\n(\S{20,})', '\\1\\2', ssh, re.M)
            if ssh == old:
                break
            old = ssh
        return ssh

    def save(self, *args, **kwargs):
        data = self.cleaned_data.copy()

        # Convert attributes to new middleware API
        for k in list(data.keys()):
            if k.startswith('bsdusr_'):
                data[k[len('bsdusr_'):]] = data.pop(k)

        if self.instance.id is None:
            args = ['user.create']
            data['group_create'] = data.pop('creategroup', False)
        else:
            args = ['user.update', self.instance.id]
            # If password is blank, do not send it to middleware
            if not data.get('password'):
                data.pop('password', None)

        data.pop('password2', None)
        data['home_mode'] = data.pop('mode')
        if data['group']:
            data['group'] = data['group'].id
        else:
            data.pop('group')
        data['groups'] = [int(group) for group in data.pop('to_group', [])]

        if self.instance.bsdusr_builtin:
            data.pop('home', None)
            data.pop('home_mode', None)
            data.pop('uid', None)
            data.pop('username', None)
            data.pop('group', None)

        with client as c:
            pk = c.call(*args, data)

        self.instance = models.bsdUsers.objects.get(pk=pk)
        return self.instance

    def delete(self, **kwargs):
        data = {
            'delete_group': False if self.data.get('nodelgroup') else True,
        }
        with client as c:
            c.call('user.delete', self.instance.id, data)
コード例 #24
0
class bsdUsersForm(ModelForm, bsdUserGroupMixin):

    bsdusr_username = forms.CharField(label=_("Username"), max_length=16)
    bsdusr_password = forms.CharField(label=_("Password"),
                                      widget=forms.PasswordInput,
                                      required=False)
    bsdusr_password2 = forms.CharField(
        label=_("Password confirmation"),
        widget=forms.PasswordInput,
        help_text=_("Enter the same password as above, for verification."),
        required=False)
    bsdusr_group = forms.ModelChoiceField(
        label=_("Primary Group"),
        queryset=models.bsdGroups.objects.all(),
        required=False)
    bsdusr_shell = forms.ChoiceField(label=_("Shell"),
                                     initial=u'/bin/csh',
                                     choices=())
    bsdusr_creategroup = forms.BooleanField(
        label=_("Create a new primary group for the user"),
        required=False,
        initial=True)
    bsdusr_sshpubkey = forms.CharField(label=_("SSH Public Key"),
                                       widget=forms.Textarea,
                                       max_length=8192,
                                       required=False)
    bsdusr_mode = UnixPermissionField(label=_('Home Directory Mode'),
                                      initial='755',
                                      required=False)
    bsdusr_to_group = SelectMultipleField(label=_('Auxiliary groups'),
                                          choices=(),
                                          required=False)
    advanced_fields = ['bsdusr_mode']

    class Meta:
        model = models.bsdUsers
        widgets = {
            'bsdusr_uid': forms.widgets.ValidationTextInput(),
        }
        exclude = (
            'bsdusr_unixhash',
            'bsdusr_smbhash',
            'bsdusr_group',
        )
        fields = (
            'bsdusr_uid',
            'bsdusr_username',
            'bsdusr_creategroup',
            'bsdusr_home',
            'bsdusr_mode',
            'bsdusr_shell',
            'bsdusr_full_name',
            'bsdusr_email',
            'bsdusr_password',
            'bsdusr_password2',
            'bsdusr_password_disabled',
            'bsdusr_locked',
            'bsdusr_sudo',
            'bsdusr_sshpubkey',
            'bsdusr_to_group',
        )

    def __init__(self, *args, **kwargs):
        #FIXME: Workaround for DOJO not showing select with blank values
        if len(args) > 0 and isinstance(args[0], QueryDict):
            new = args[0].copy()
            if new.get('bsdusr_group', None) == '-----':
                new['bsdusr_group'] = ''
            args = (new, ) + args[1:]
        super(bsdUsersForm, self).__init__(*args, **kwargs)
        self.fields.keyOrder.remove('bsdusr_group')
        self.fields.keyOrder.insert(3, 'bsdusr_group')
        if self._api is True:
            del self.fields['bsdusr_password2']
        self.fields['bsdusr_shell'].choices = self._populate_shell_choices()
        self.fields['bsdusr_shell'].choices.sort()
        self.fields['bsdusr_to_group'].choices = [
            (x.id, x.bsdgrp_group)
            for x in models.bsdGroups.objects.order_by('bsdgrp_group')
        ]
        self.fields['bsdusr_password_disabled'].widget.attrs['onChange'] = (
            'javascript:toggleGeneric("id_bsdusr_password_disabled", '
            '["id_bsdusr_locked", "id_bsdusr_sudo"], false);')
        self.fields['bsdusr_locked'].widget.attrs['onChange'] = (
            'javascript:toggleGeneric("id_bsdusr_locked", '
            '["id_bsdusr_password_disabled"], false);')
        self.fields['bsdusr_sudo'].widget.attrs['onChange'] = (
            'javascript:toggleGeneric("id_bsdusr_sudo", '
            '["id_bsdusr_password_disabled"], false);')

        if not self.instance.id:
            self.fields['bsdusr_uid'].initial = notifier().user_getnextuid()
            self.fields['bsdusr_home'].label = _('Create Home Directory In')
            self.fields['bsdusr_creategroup'].widget.attrs['onChange'] = (
                'javascript:toggleGeneric("id_bsdusr_creategroup", '
                '["id_bsdusr_group"], false);')
            self.fields['bsdusr_group'].widget.attrs['maxHeight'] = 200
            self.fields['bsdusr_group'].widget.attrs['disabled'] = 'disabled'
            self.fields['bsdusr_group'].choices = (
                ('-----', '-----'), ) + tuple(
                    [x for x in self.fields['bsdusr_group'].choices][1:])
            self.fields['bsdusr_group'].required = False
            self.bsdusr_home_saved = u'/nonexistent'
            self.bsdusr_home_copy = False

        elif self.instance.id:
            self.fields['bsdusr_to_group'].initial = [
                x.bsdgrpmember_group.id
                for x in models.bsdGroupMembership.objects.filter(
                    bsdgrpmember_user=self.instance.id)
            ]

            del self.fields['bsdusr_creategroup']
            self.fields['bsdusr_group'].initial = self.instance.bsdusr_group
            self.advanced_fields = []
            self.bsdusr_home_saved = self.instance.bsdusr_home
            self.bsdusr_home_copy = False
            self.fields.keyOrder.remove('bsdusr_mode')
            self.fields.keyOrder.insert(
                len(self.fields.keyOrder) - 1,
                'bsdusr_mode',
            )
            self.fields['bsdusr_username'].widget.attrs['readonly'] = True
            self.fields['bsdusr_username'].widget.attrs['class'] = (
                'dijitDisabled dijitTextBoxDisabled '
                'dijitValidationTextBoxDisabled')
            if os.path.exists(self.instance.bsdusr_home):
                mode = os.stat(self.instance.bsdusr_home).st_mode & 0o777
                self.fields['bsdusr_mode'].initial = oct(mode)
            if self.instance.bsdusr_builtin:
                self.fields['bsdusr_uid'].widget.attrs['readonly'] = True
                self.fields['bsdusr_uid'].widget.attrs['class'] = (
                    'dijitDisabled dijitTextBoxDisabled '
                    'dijitValidationTextBoxDisabled')
                self.fields['bsdusr_group'].widget.attrs['readonly'] = True
                self.fields['bsdusr_group'].widget.attrs['class'] = (
                    'dijitDisabled dijitSelectDisabled')
                self.fields['bsdusr_home'].widget.attrs['readonly'] = True
                self.fields['bsdusr_home'].widget.attrs['class'] = (
                    'dijitDisabled dijitTextBoxDisabled '
                    'dijitValidationTextBoxDisabled')
                self.fields['bsdusr_mode'].widget.attrs['disabled'] = True
                self.fields['bsdusr_mode'].required = False
            if self.instance.bsdusr_locked or self.instance.bsdusr_sudo:
                self.fields['bsdusr_password_disabled'].widget.attrs[
                    'disabled'] = True
            if self.instance.bsdusr_password_disabled is True:
                self.fields['bsdusr_locked'].widget.attrs['disabled'] = True
                self.fields['bsdusr_sudo'].widget.attrs['disabled'] = True
            self.fields['bsdusr_sshpubkey'].initial = (
                self.instance.bsdusr_sshpubkey)

    def clean_bsdusr_username(self):
        if self.instance.id is None:
            bsdusr_username = self.cleaned_data["bsdusr_username"]
            self.pw_checkname(bsdusr_username)
            try:
                models.bsdUsers.objects.get(bsdusr_username=bsdusr_username)
            except models.bsdUsers.DoesNotExist:
                return bsdusr_username
            raise forms.ValidationError(
                _("A user with that username already exists."))
        else:
            return self.instance.bsdusr_username

    def clean_bsdusr_uid(self):
        if self.instance.id and self.instance.bsdusr_builtin:
            return self.instance.bsdusr_uid
        else:
            return self.cleaned_data.get("bsdusr_uid")

    def clean_bsdusr_group(self):
        if self.instance.id and self.instance.bsdusr_builtin:
            return self.instance.bsdusr_group
        else:
            create = self.cleaned_data.get("bsdusr_creategroup")
            group = self.cleaned_data.get("bsdusr_group")
            if not group and not create:
                raise forms.ValidationError(_("This field is required"))
            return group

    def clean_bsdusr_password(self):
        bsdusr_password = self.cleaned_data.get('bsdusr_password')
        # See bug #4098
        if bsdusr_password and '?' in bsdusr_password:
            raise forms.ValidationError(
                _('Passwords containing a question mark (?) are currently not '
                  'allowed due to problems with CIFS.'))
        return bsdusr_password

    def clean_bsdusr_password2(self):
        bsdusr_password = self.cleaned_data.get("bsdusr_password", "")
        bsdusr_password2 = self.cleaned_data["bsdusr_password2"]
        if bsdusr_password and bsdusr_password != bsdusr_password2:
            raise forms.ValidationError(
                _("The two password fields didn't match."))
        return bsdusr_password2

    def clean_bsdusr_home(self):
        home = self.cleaned_data['bsdusr_home']
        if self.instance.id and self.instance.bsdusr_uid == 0:
            return self.instance.bsdusr_home
        elif home is not None:
            if ':' in home:
                raise forms.ValidationError(
                    _("Home directory cannot contain colons"))

            if home == u'/nonexistent':
                return home

            if home.startswith(u'/mnt/'):
                bsdusr_username = self.cleaned_data.get('bsdusr_username', '')
                saved_home = self.bsdusr_home_saved

                if home.endswith(bsdusr_username):
                    if home != saved_home:
                        self.bsdusr_home_copy = True
                    return home

                if not self.instance.id:
                    home = "%s/%s" % (home.rstrip('/'), bsdusr_username)

                if not self.instance.id and not home.endswith(bsdusr_username):
                    raise forms.ValidationError(
                        _('Home directory must end with username'))

                if home != saved_home:
                    self.bsdusr_home_copy = True

                return home

        raise forms.ValidationError(
            _('Home directory has to start with /mnt/ or be /nonexistent'))

    def clean_bsdusr_mode(self):
        mode = self.cleaned_data.get('bsdusr_mode')
        if not self.instance.id and not mode:
            return '755'
        return mode

    def clean_bsdusr_sshpubkey(self):
        ssh = self.cleaned_data.get('bsdusr_sshpubkey', '')
        ssh = ssh.strip(' ').strip('\n')
        ssh = re.sub(r'[ ]{2,}', ' ', ssh, re.M)
        ssh = re.sub(r'\n{2,}', '\n', ssh, re.M)
        old = ssh
        while True:
            ssh = re.sub(r'(\S{10,})\n(\S{10,})', '\\1\\2', ssh, re.M)
            if ssh == old:
                break
            old = ssh
        return ssh

    def clean_bsdusr_full_name(self):
        name = self.cleaned_data["bsdusr_full_name"]
        self.pw_checkfullname(name)
        return name

    def clean_bsdusr_to_group(self):
        v = self.cleaned_data.get("bsdusr_to_group")
        if len(v) > 64:
            raise forms.ValidationError(
                _("A user cannot belong to more than 64 auxiliary groups"))
        return v

    def clean(self):
        cleaned_data = self.cleaned_data

        password_disable = cleaned_data["bsdusr_password_disabled"] = (
            cleaned_data.get("bsdusr_password_disabled", False))
        bsdusr_home = cleaned_data.get('bsdusr_home', '')
        if (bsdusr_home and cleaned_data.get('bsdusr_sshpubkey')
                and (not bsdusr_home.startswith(u'/mnt/') and
                     (self.instance.id is None or
                      (self.instance.id and self.instance.bsdusr_uid != 0)))):
            del cleaned_data['bsdusr_sshpubkey']
            self._errors['bsdusr_sshpubkey'] = self.error_class(
                [_("Home directory is not writable, leave this blank")])
        if self.instance.id is None:
            FIELDS = ['bsdusr_password', 'bsdusr_password2']
            if password_disable:
                for field in FIELDS:
                    if field in cleaned_data and cleaned_data.get(field) != '':
                        self._errors[field] = self.error_class(
                            [_("Password is disabled, leave this blank")])
                        del cleaned_data[field]
            else:
                for field in FIELDS:
                    if field in cleaned_data and cleaned_data.get(field) == '':
                        self._errors[field] = self.error_class(
                            [_("This field is required.")])
                        del cleaned_data[field]

        return cleaned_data

    def save(self, commit=True):
        _notifier = notifier()
        if self.instance.id is None:
            group = self.cleaned_data['bsdusr_group']
            if group is None:
                try:
                    gid = models.bsdGroups.objects.get(
                        bsdgrp_group=self.cleaned_data['bsdusr_username']
                    ).bsdgrp_gid
                except:
                    gid = -1
            else:
                gid = group.bsdgrp_gid
            uid, gid, unixhash, smbhash = _notifier.user_create(
                username=str(self.cleaned_data['bsdusr_username']),
                fullname=self.cleaned_data['bsdusr_full_name'].encode(
                    'utf8', 'ignore').replace(':', ''),
                password=self.cleaned_data['bsdusr_password'].encode(
                    'utf8', 'ignore'),
                uid=self.cleaned_data['bsdusr_uid'],
                gid=gid,
                shell=str(self.cleaned_data['bsdusr_shell']),
                homedir=str(self.cleaned_data['bsdusr_home']),
                homedir_mode=int(self.cleaned_data.get('bsdusr_mode', '755'),
                                 8),
                password_disabled=self.cleaned_data.get(
                    'bsdusr_password_disabled', False),
            )
            bsduser = super(bsdUsersForm, self).save(commit=False)
            try:
                grp = models.bsdGroups.objects.get(bsdgrp_gid=gid)
            except models.bsdGroups.DoesNotExist:
                grp = models.bsdGroups(
                    bsdgrp_gid=gid,
                    bsdgrp_group=self.cleaned_data['bsdusr_username'],
                    bsdgrp_builtin=False,
                )
                grp.save()
            bsduser.bsdusr_group = grp
            bsduser.bsdusr_uid = uid
            bsduser.bsdusr_shell = self.cleaned_data['bsdusr_shell']
            bsduser.bsdusr_unixhash = unixhash
            bsduser.bsdusr_smbhash = smbhash
            bsduser.bsdusr_builtin = False
            bsduser.save()

        else:
            bsduser = super(bsdUsersForm, self).save(commit=False)
            bsduser.bsdusr_group = self.cleaned_data['bsdusr_group']
            bsduser.save()

            #
            # Check if updating password
            #
            bsdusr_password = self.cleaned_data.get("bsdusr_password", "")
            if self._api is True:
                bsdusr_password2 = bsdusr_password
            else:
                bsdusr_password2 = self.cleaned_data["bsdusr_password2"]
            if bsdusr_password and (bsdusr_password == bsdusr_password2):
                unixhash, smbhash = _notifier.user_changepassword(
                    username=bsduser.bsdusr_username.encode('utf8'),
                    password=bsdusr_password.encode('utf8'),
                )
                bsduser.bsdusr_unixhash = unixhash
                bsduser.bsdusr_smbhash = smbhash
                bsduser.save()

        #
        # Check if updating group membership
        #
        models.bsdGroupMembership.objects.filter(
            bsdgrpmember_user=bsduser).delete()
        groupid_list = self.cleaned_data['bsdusr_to_group']
        for groupid in groupid_list:
            group = models.bsdGroups.objects.get(id=groupid)
            m = models.bsdGroupMembership(bsdgrpmember_group=group,
                                          bsdgrpmember_user=bsduser)
            m.save()

        _notifier.reload("user")
        if self.bsdusr_home_copy:
            p = pipeopen(
                "su - %s -c '/bin/cp -a %s/* %s/'" %
                (self.cleaned_data['bsdusr_username'], self.bsdusr_home_saved,
                 self.cleaned_data['bsdusr_home']))
            p.communicate()

        bsdusr_sshpubkey = self.cleaned_data.get('bsdusr_sshpubkey')
        if bsdusr_sshpubkey:
            _notifier.save_pubkey(bsduser.bsdusr_home, bsdusr_sshpubkey,
                                  bsduser.bsdusr_username,
                                  bsduser.bsdusr_group.bsdgrp_group)
        else:
            _notifier.delete_pubkey(bsduser.bsdusr_home)
        return bsduser
コード例 #25
0
class JailCreateForm(ModelForm):
    jail_type = forms.ChoiceField(label=_("type"), )

    jail_vanilla = forms.BooleanField(label=_("vanilla"),
                                      required=False,
                                      initial=True)

    class Meta:
        model = Jails
        exclude = ('jail_id', 'jail_status', 'jail_alias_ipv4',
                   'jail_alias_bridge_ipv4', 'jail_alias_ipv6',
                   'jail_alias_bridge_ipv6')
        #FIXME: translate in dojango
        widgets = {
            'jail_defaultrouter_ipv4': forms.widgets.TextInput(),
            'jail_defaultrouter_ipv6': forms.widgets.TextInput(),
        }

    def __init__(self, *args, **kwargs):
        super(JailCreateForm, self).__init__(*args, **kwargs)
        self.logfile = "/var/tmp/warden.log"
        self.statusfile = "/var/tmp/status"
        try:
            os.unlink(self.logfile)
        except:
            pass
        try:
            os.unlink(self.statusfile)
        except:
            pass

        arch = platform.architecture()
        if arch[0] == '64bit':
            arch = 'x64'
        else:
            arch = 'x86'
        self.arch = arch

        os.environ['EXTRACT_TARBALL_STATUSFILE'] = self.statusfile
        types = ((jt.jt_name, jt.jt_name) for jt in JailTemplate.objects.all())

        self.fields['jail_type'].choices = types
        self.fields['jail_type'].widget.attrs['onChange'] = (
            "jail_type_toggle();")
        self.fields['jail_vnet'].widget.attrs['onChange'] = (
            "jail_vnet_toggle();")
        self.fields['jail_nat'].widget.attrs['onChange'] = (
            "jail_nat_toggle();")

        addrs = guess_addresses()

        if addrs['high_ipv4']:
            parts = str(addrs['high_ipv4']).split('/')
            self.fields['jail_ipv4'].initial = parts[0]
            if len(parts) > 1:
                self.fields['jail_ipv4_netmask'].initial = parts[1]

        if addrs['high_ipv6']:
            parts = str(addrs['high_ipv6']).split('/')
            self.fields['jail_ipv6'].initial = parts[0]
            if len(parts) > 1:
                self.fields['jail_ipv6_prefix'].initial = parts[1]

        if addrs['bridge_ipv4']:
            parts = str(addrs['bridge_ipv4']).split('/')
            self.fields['jail_bridge_ipv4'].initial = parts[0]
            if len(parts) > 1:
                self.fields['jail_bridge_ipv4_netmask'].initial = parts[1]

        if addrs['bridge_ipv6']:
            parts = str(addrs['bridge_ipv6']).split('/')
            self.fields['jail_bridge_ipv6'].initial = parts[0]
            if len(parts) > 1:
                self.fields['jail_bridge_ipv6_prefix'].initial = parts[1]

    def save(self):
        try:
            jc = JailsConfiguration.objects.order_by("-id")[0]
        except Exception as e:
            raise MiddlewareError(e.message)

        if not jc.jc_path:
            raise MiddlewareError(_("No jail root configured."))

        jc_ipv4_netmask = 24
        if jc.jc_ipv4_network:
            parts = jc.jc_ipv4_network.split('/')
            if len(parts) > 1:
                jc_ipv4_netmask = parts[1]

        jc_ipv6_prefix = 64
        if jc.jc_ipv6_network:
            parts = jc.jc_ipv6_network.split('/')
            if len(parts) > 1:
                jc_ipv6_prefix = parts[1]

        jail_host = self.cleaned_data.get('jail_host')

        jail_ipv4 = self.cleaned_data.get('jail_ipv4')
        jail_ipv4_netmask = self.cleaned_data.get('jail_ipv4_netmask',
                                                  jc_ipv4_netmask)

        jail_ipv6 = self.cleaned_data.get('jail_ipv6')
        jail_ipv6_prefix = self.cleaned_data.get('jail_ipv6_prefix',
                                                 jc_ipv6_prefix)

        jail_flags = WARDEN_FLAGS_NONE
        jail_create_args = {}
        jail_create_args['jail'] = jail_host

        w = Warden()

        #        if self.cleaned_data['jail_source']:
        #            jail_flags |= WARDEN_CREATE_FLAGS_SRC
        #        if self.cleaned_data['jail_ports']:
        #            jail_flags |= WARDEN_CREATE_FLAGS_PORTS
        if self.cleaned_data['jail_vanilla']:
            jail_flags |= WARDEN_CREATE_FLAGS_VANILLA

        template_create_args = {}

        jail_type = self.cleaned_data['jail_type']
        template = JailTemplate.objects.get(jt_name=jail_type)
        template_create_args['nick'] = template.jt_name
        template_create_args['tar'] = template.jt_url
        template_create_args['flags'] = WARDEN_TEMPLATE_FLAGS_CREATE | \
            WARDEN_TEMPLATE_CREATE_FLAGS_NICK | \
            WARDEN_TEMPLATE_CREATE_FLAGS_TAR

        saved_template = template
        template = None
        template_list_flags = {}
        template_list_flags['flags'] = WARDEN_TEMPLATE_FLAGS_LIST
        templates = w.template(**template_list_flags)
        for t in templates:
            if t['nick'] == template_create_args['nick']:
                template = t
                break

        createfile = "/var/tmp/.templatecreate"
        if not template:
            try:
                cf = open(createfile, "a+")
                cf.close()
                w.template(**template_create_args)

            except Exception as e:
                self.errors['__all__'] = self.error_class([_(e.message)])
                if os.path.exists(createfile):
                    os.unlink(createfile)
                return

            template_list_flags = {}
            template_list_flags['flags'] = WARDEN_TEMPLATE_FLAGS_LIST
            templates = w.template(**template_list_flags)
            for t in templates:
                if t['nick'] == template_create_args['nick']:
                    template = t
                    break

        if not template:
            self.errors['__all__'] = self.error_class(
                [_('Unable to find template!')])
            return

        if template['type'] == 'Linux':
            jail_flags |= WARDEN_CREATE_FLAGS_LINUXJAIL
        if template['arch'] == 'i386' and self.arch == 'x64':
            jail_flags |= WARDEN_CREATE_FLAGS_32BIT

        jail_flags |= WARDEN_CREATE_FLAGS_TEMPLATE
        jail_create_args['template'] = template_create_args['nick']

        if jail_ipv4:
            jail_flags |= WARDEN_CREATE_FLAGS_IPV4
            jail_create_args['ipv4'] = "%s/%s" % (jail_ipv4, jail_ipv4_netmask)

        if jail_ipv6:
            jail_flags |= WARDEN_CREATE_FLAGS_IPV6
            jail_create_args['ipv6'] = "%s/%s" % (jail_ipv6, jail_ipv6_prefix)

        jail_flags |= WARDEN_CREATE_FLAGS_LOGFILE
        jail_flags |= WARDEN_CREATE_FLAGS_SYSLOG

        jail_create_args['logfile'] = self.logfile
        jail_create_args['flags'] = jail_flags

        createfile = "/var/tmp/.jailcreate"
        try:
            cf = open(createfile, "a+")
            cf.close()
            w.create(**jail_create_args)

        except Exception as e:
            self.errors['__all__'] = self.error_class([_(e.message)])
            if os.path.exists(createfile):
                os.unlink(createfile)
            return

        if os.path.exists(createfile):
            os.unlink(createfile)

        for key in ('jail_bridge_ipv4', 'jail_bridge_ipv6',
                    'jail_defaultrouter_ipv4', 'jail_defaultrouter_ipv6',
                    'jail_mac', 'jail_flags'):
            jail_set_args = {}
            jail_set_args['jail'] = jail_host
            jail_flags = WARDEN_FLAGS_NONE
            val = self.cleaned_data.get(key, None)
            if val:
                if key == 'jail_bridge_ipv4':
                    mask = self.cleaned_data.get('jail_bridge_ipv4_netmask',
                                                 jc_ipv4_netmask)
                    jail_flags |= WARDEN_SET_FLAGS_BRIDGE_IPV4
                    jail_set_args['bridge-ipv4'] = "%s/%s" % (val, mask)

                elif key == 'jail_bridge_ipv6':
                    prefix = self.cleaned_data.get('jail_bridge_ipv6_prefix',
                                                   jc_ipv6_prefix)
                    jail_flags |= WARDEN_SET_FLAGS_BRIDGE_IPV6
                    jail_set_args['bridge-ipv6'] = "%s/%s" % (val, prefix)

                elif key == 'jail_defaultrouter_ipv4':
                    jail_flags |= WARDEN_SET_FLAGS_DEFAULTROUTER_IPV4
                    jail_set_args['defaultrouter-ipv4'] = val

                elif key == 'jail_defaultrouter_ipv6':
                    jail_flags |= WARDEN_SET_FLAGS_DEFAULTROUTER_IPV6
                    jail_set_args['defaultrouter-ipv6'] = val

                elif key == 'jail_mac':
                    jail_flags |= WARDEN_SET_FLAGS_MAC
                    jail_set_args['mac'] = val

                elif key == 'jail_flags':
                    jail_flags |= WARDEN_SET_FLAGS_FLAGS
                    jail_set_args['jflags'] = val

                jail_set_args['flags'] = jail_flags
                try:
                    w.set(**jail_set_args)
                except Exception as e:
                    self.errors['__all__'] = self.error_class([_(e.message)])
                    return

        jail_nat = self.cleaned_data.get('jail_nat', None)
        jail_vnet = self.cleaned_data.get('jail_vnet', None)

        jail_set_args = {}
        jail_set_args['jail'] = jail_host
        jail_flags = WARDEN_FLAGS_NONE
        if jail_nat:
            jail_flags |= WARDEN_SET_FLAGS_NAT_ENABLE
        else:
            jail_flags |= WARDEN_SET_FLAGS_NAT_DISABLE

        jail_set_args['flags'] = jail_flags
        try:
            w.set(**jail_set_args)
        except Exception as e:
            self.errors['__all__'] = self.error_class([_(e.message)])
            return

        jail_set_args = {}
        jail_set_args['jail'] = jail_host
        jail_flags = WARDEN_FLAGS_NONE
        if jail_vnet:
            # XXXX if NOT LINUX XXXX (revisit this)
            if (saved_template.jt_arch != 'x86'
                    and saved_template.jt_os != 'Linux'):
                jail_flags |= WARDEN_SET_FLAGS_VNET_ENABLE
            else:
                jail_flags |= WARDEN_SET_FLAGS_VNET_DISABLE

            jail_set_args['flags'] = jail_flags
            try:
                w.set(**jail_set_args)
            except Exception as e:
                self.errors['__all__'] = self.error_class([_(e.message)])
                return

        if self.cleaned_data['jail_autostart']:
            try:
                w.auto(jail=jail_host)
            except Exception as e:
                self.errors['__all__'] = self.error_class([_(e.message)])
                return

        try:
            w.start(jail=jail_host)
        except Exception as e:
            self.errors['__all__'] = self.error_class([_(e.message)])
            return
コード例 #26
0
class NullMountPointForm(ModelForm):

    create = forms.BooleanField(
        label=('Create directory'),
        required=False,
        initial=True,
        help_text=_('Create destination directory if it does not exist'),
    )

    mounted = forms.BooleanField(
        label=_("Mounted?"),
        required=False,
        initial=True,
    )

    # Do not remove: used in javascript side
    mpjc_path = forms.CharField(required=False)

    class Meta:
        fields = '__all__'
        model = NullMountPoint
        widgets = {
            'source':
            forms.widgets.TextInput(
                attrs={
                    'data-dojo-type': 'freeadmin.form.PathSelector',
                }),
            'destination':
            forms.widgets.TextInput(
                attrs={
                    'data-dojo-type': 'freeadmin.form.PathSelector',
                }),
        }

    def clean_source(self):
        src = self.cleaned_data.get("source")
        src = os.path.abspath(src.strip().replace("..", ""))
        return src

    def clean_destination(self):
        dest = self.cleaned_data.get("destination")
        dest = os.path.abspath(dest.strip().replace("..", ""))

        if not self.jail:
            jail = self.cleaned_data.get("jail")
            if jail:
                self.jail = Jails.objects.get(jail_host=jail)

        if not self.jail:
            raise forms.ValidationError(
                _("This shouldn't happen, but the jail could not be found"))

        full = "%s/%s%s" % (self.jc.jc_path, self.jail.jail_host, dest)

        if len(full) > 88:
            raise forms.ValidationError(
                _("The full path cannot exceed 88 characters"))

        create = self.cleaned_data.get('create')
        if not os.path.exists(full) and create:
            os.makedirs(full)

        return dest

    def __init__(self, *args, **kwargs):
        self.jail = None
        if kwargs and 'jail' in kwargs:
            self.jail = kwargs.pop('jail')

        super(NullMountPointForm, self).__init__(*args, **kwargs)

        if kwargs and 'instance' in kwargs:
            self.instance = kwargs.pop('instance')
            if not self.jail:
                self.jail = Jails.objects.filter(
                    jail_host=self.instance.jail)[0]

        self.jc = JailsConfiguration.objects.order_by("-id")[0]
        self.fields['jail'] = forms.ChoiceField(
            label=_("Jail"),
            choices=(),
            widget=forms.Select(attrs={'class': 'required'}),
        )
        if self.jail:
            self.fields['jail'].initial = self.jail.jail_host
            self.fields['jail'].widget.attrs['readonly'] = True

        try:
            clean_path_execbit(self.jc.jc_path)
        except forms.ValidationError, e:
            self.errors['__all__'] = self.error_class(e.messages)

        pjlist = []
        try:
            wlist = Warden().list()
        except:
            wlist = []

        for wj in wlist:
            pjlist.append(wj[WARDEN_KEY_HOST])

        self.fields['jail'].choices = [(pj, pj) for pj in pjlist]
        self.fields['jail'].widget.attrs['onChange'] = (
            'addStorageJailChange(this);')
        jail_path = "%s/%s" % (self.jc.jc_path, self.jail.jail_host)
        self.fields['destination'].widget.attrs['root'] = jail_path

        self.fields['mpjc_path'].widget = forms.widgets.HiddenInput()
        self.fields['mpjc_path'].initial = self.jc.jc_path

        if self.instance.id:
            self.fields['mounted'].initial = self.instance.mounted
        else:
            self.fields['mounted'].widget = forms.widgets.HiddenInput()
コード例 #27
0
class JailsEditForm(ModelForm):

    jail_autostart = forms.BooleanField(label=_("autostart"), required=False)
    jail_vnet = forms.BooleanField(label=_("VIMAGE"), required=False)
    jail_nat = forms.BooleanField(label=_("NAT"), required=False)

    class Meta:
        model = Jails
        exclude = (
            'jail_status',
            'jail_type',
        )
        #FIXME: translate in dojango
        widgets = {
            'jail_defaultrouter_ipv4': forms.widgets.TextInput(),
            'jail_defaultrouter_ipv6': forms.widgets.TextInput(),
        }

    def __set_ro(self, instance, key):
        self.fields[key].widget.attrs['readonly'] = True
        self.fields[key].widget.attrs['class'] = (
            'dijitDisabled dijitTextBoxDisabled dijitValidationTextBoxDisabled'
        )

    def __instance_save(self, instance, keys):
        for key in keys:
            okey = "__original_%s" % key
            instance.__dict__[okey] = instance.__dict__[key]

    def __instance_diff(self, instance, keys):
        res = False

        for key in keys:
            okey = "__original_%s" % key
            if instance.__dict__[okey] != self.cleaned_data.get(key):
                if (not instance.__dict__[okey]
                        and not self.cleaned_data.get(key)):
                    continue
                res = True
                break

        return res

    def __instance_changed_fields(self, instance, keys):
        changed_keys = []

        for key in keys:
            okey = "__original_%s" % key
            if instance.__dict__[okey] != self.cleaned_data.get(key):
                if (not instance.__dict__[okey]
                        and not self.cleaned_data.get(key)):
                    continue
                changed_keys.append(key)

        return changed_keys

    def __init__(self, *args, **kwargs):
        super(JailsEditForm, self).__init__(*args, **kwargs)
        self.__myfields = [
            'jail_autostart',
            'jail_ipv4',
            'jail_ipv4_netmask',
            'jail_alias_ipv4',
            'jail_bridge_ipv4',
            'jail_bridge_ipv4_netmask',
            'jail_alias_bridge_ipv4',
            'jail_defaultrouter_ipv4',
            'jail_ipv6',
            'jail_ipv6_prefix',
            'jail_alias_ipv6',
            'jail_bridge_ipv6',
            'jail_bridge_ipv6_prefix',
            'jail_alias_bridge_ipv6',
            'jail_defaultrouter_ipv6',
            'jail_mac',
            'jail_vnet',
            'jail_nat',
            'jail_flags',
        ]

        if self._api and self.instance and self.instance.id:
            self.instance = Jails.objects.get(id=self.instance.id)
        instance = getattr(self, 'instance', None)
        self.__instance_save(instance, self.__myfields)

        self.fields['jail_vnet'].widget.attrs['onChange'] = (
            "jail_vnet_toggle();")
        self.fields['jail_nat'].widget.attrs['onChange'] = (
            "jail_nat_toggle();")

        self.__set_ro(instance, 'jail_host')

    def save(self):
        jail_host = self.cleaned_data.get('jail_host')

        instance = getattr(self, 'instance', None)
        if self.__instance_diff(instance, self.__myfields):
            self.__instance_changed_fields(instance, self.__myfields)

        changed_fields = self.__instance_changed_fields(
            instance, self.__myfields)

        try:
            jc = JailsConfiguration.objects.order_by("-id")[0]
        except Exception as e:
            raise MiddlewareError(e.message)

        if not jc.jc_path:
            raise MiddlewareError(_("No jail root configured."))

        jc_ipv4_netmask = 24
        if jc.jc_ipv4_network:
            parts = jc.jc_ipv4_network.split('/')
            if len(parts) > 1:
                jc_ipv4_netmask = parts[1]

        jc_ipv6_prefix = 64
        if jc.jc_ipv6_network:
            parts = jc.jc_ipv6_network.split('/')
            if len(parts) > 1:
                jc_ipv6_prefix = parts[1]

        for cf in changed_fields:
            if cf == 'jail_autostart':
                Warden().auto(jail=jail_host)
            else:
                args = {}
                flags = WARDEN_FLAGS_NONE

                if cf == 'jail_ipv4' or cf == 'jail_ipv4_netmask':
                    ipv4 = self.cleaned_data.get('jail_ipv4')
                    mask = self.cleaned_data.get('jail_ipv4_netmask',
                                                 jc_ipv4_netmask)
                    jail_ipv4 = "%s/%s" % (ipv4, mask)

                    flags |= WARDEN_SET_FLAGS_IPV4
                    args['ipv4'] = jail_ipv4

                elif cf == 'jail_ipv6' or cf == 'jail_ipv6_prefix':
                    ipv6 = self.cleaned_data.get('jail_ipv6')
                    prefix = self.cleaned_data.get('jail_ipv6_prefix',
                                                   jc_ipv6_prefix)
                    jail_ipv6 = "%s/%s" % (ipv6, prefix)

                    flags |= WARDEN_SET_FLAGS_IPV6
                    args['ipv6'] = jail_ipv6

                elif cf == 'jail_alias_ipv4':
                    flags |= WARDEN_SET_FLAGS_ALIAS_IPV4
                    args['alias-ipv4'] = self.cleaned_data.get(cf)

                elif cf == 'jail_alias_ipv6':
                    flags |= WARDEN_SET_FLAGS_ALIAS_IPV6
                    args['alias-ipv6'] = self.cleaned_data.get(cf)

                elif cf == 'jail_bridge_ipv4' or cf == 'jail_bridge_ipv4_netmask':
                    bridge_ipv4 = self.cleaned_data.get('jail_bridge_ipv4')
                    mask = self.cleaned_data.get('jail_bridge_ipv4_netmask',
                                                 jc_ipv4_netmask)
                    jail_bridge_ipv4 = "%s/%s" % (bridge_ipv4, mask)

                    flags |= WARDEN_SET_FLAGS_BRIDGE_IPV4
                    args['bridge-ipv4'] = jail_bridge_ipv4

                elif cf == 'jail_bridge_ipv6' or cf == 'jail_bridge_ipv6_prefix':
                    bridge_ipv6 = self.cleaned_data.get('jail_bridge_ipv6')
                    prefix = self.cleaned_data.get('jail_bridge_ipv6_prefix',
                                                   jc_ipv6_prefix)
                    jail_bridge_ipv6 = "%s/%s" % (bridge_ipv6, prefix)

                    flags |= WARDEN_SET_FLAGS_BRIDGE_IPV6
                    args['bridge-ipv6'] = jail_bridge_ipv6

                elif cf == 'jail_alias_bridge_ipv4':
                    flags |= WARDEN_SET_FLAGS_ALIAS_BRIDGE_IPV4
                    args['alias-bridge-ipv4'] = self.cleaned_data.get(cf)

                elif cf == 'jail_alias_bridge_ipv6':
                    flags |= WARDEN_SET_FLAGS_ALIAS_BRIDGE_IPV6
                    args['alias-bridge-ipv6'] = self.cleaned_data.get(cf)

                elif cf == 'jail_defaultrouter_ipv4':
                    flags |= WARDEN_SET_FLAGS_DEFAULTROUTER_IPV4
                    args['defaultrouter-ipv4'] = self.cleaned_data.get(cf)

                elif cf == 'jail_defaultrouter_ipv6':
                    flags |= WARDEN_SET_FLAGS_DEFAULTROUTER_IPV6
                    args['defaultrouter-ipv6'] = self.cleaned_data.get(cf)

                elif cf == 'jail_mac':
                    flags |= WARDEN_SET_FLAGS_MAC
                    args['mac'] = self.cleaned_data.get(cf)

                elif cf == 'jail_vnet':
                    if (self.cleaned_data.get(cf)):
                        flags |= WARDEN_SET_FLAGS_VNET_ENABLE
                        args['vnet-enable'] = self.cleaned_data.get(cf)
                    else:
                        flags |= WARDEN_SET_FLAGS_VNET_DISABLE
                        args['vnet-disable'] = self.cleaned_data.get(cf)

                elif cf == 'jail_nat':
                    if self.cleaned_data.get(cf):
                        flags |= WARDEN_SET_FLAGS_NAT_ENABLE
                        args['nat-enable'] = self.cleaned_data.get(cf)
                    else:
                        flags |= WARDEN_SET_FLAGS_NAT_DISABLE
                        args['nat-disable'] = self.cleaned_data.get(cf)

                elif cf == 'jail_flags':
                    flags |= WARDEN_SET_FLAGS_FLAGS
                    args['jflags'] = self.cleaned_data.get(cf)

                args['jail'] = jail_host
                args['flags'] = flags

                Warden().set(**args)
コード例 #28
0
ファイル: forms.py プロジェクト: vanloswang/freenas
class IPMIForm(Form):
    # Max password length via IPMI v2.0 is 20 chars. We only support IPMI
    # v2.0+ compliant boards thus far.
    ipmi_password1 = forms.CharField(label=_("Password"),
                                     max_length=20,
                                     widget=forms.PasswordInput,
                                     required=False)
    ipmi_password2 = forms.CharField(
        label=_("Password confirmation"),
        max_length=20,
        widget=forms.PasswordInput,
        help_text=_("Enter the same password as above, for verification."),
        required=False)
    dhcp = forms.BooleanField(
        label=_("DHCP"),
        required=False,
    )
    ipv4address = IP4AddressFormField(
        initial='',
        required=False,
        label=_("IPv4 Address"),
    )
    ipv4netmaskbit = forms.ChoiceField(
        choices=choices.v4NetmaskBitList,
        required=False,
        label=_("IPv4 Netmask"),
    )
    ipv4gw = IP4AddressFormField(
        initial='',
        required=False,
        label=_("IPv4 Default Gateway"),
    )
    vlanid = forms.IntegerField(
        label=_("VLAN ID"),
        required=False,
        widget=forms.widgets.TextInput(),
    )

    def __init__(self, *args, **kwargs):
        super(IPMIForm, self).__init__(*args, **kwargs)
        self.fields['dhcp'].widget.attrs['onChange'] = (
            'javascript:toggleGeneric('
            '"id_dhcp", ["id_ipv4address", "id_ipv4netmaskbit"]);')

        channels = []
        _n = notifier()
        for i in range(1, 17):
            try:
                data = _n.ipmi_get_lan(channel=i)
            except:
                continue

            if not data:
                continue

            channels.append((i, i))

        self.fields['channel'] = forms.ChoiceField(
            choices=channels,
            label=_('Channel'),
        )
        self.fields.keyOrder.remove('channel')
        self.fields.keyOrder.insert(0, 'channel')

    def clean_ipmi_password2(self):
        ipmi_password1 = self.cleaned_data.get("ipmi_password1", "")
        ipmi_password2 = self.cleaned_data["ipmi_password2"]
        if ipmi_password1 != ipmi_password2:
            raise forms.ValidationError(
                _("The two password fields didn't match."))
        return ipmi_password2

    def clean_ipv4netmaskbit(self):
        try:
            cidr = int(self.cleaned_data.get("ipv4netmaskbit"))
        except ValueError:
            return None
        bits = 0xffffffff ^ (1 << 32 - cidr) - 1
        return socket.inet_ntoa(pack('>I', bits))

    def clean_ipv4address(self):
        ipv4 = self.cleaned_data.get('ipv4address')
        if ipv4:
            ipv4 = str(ipv4)
        return ipv4

    def clean_ipv4gw(self):
        ipv4 = self.cleaned_data.get('ipv4gw')
        if ipv4:
            ipv4 = str(ipv4)
        return ipv4
コード例 #29
0
ファイル: forms.py プロジェクト: skarekrow/freenas
class DeviceForm(ModelForm):

    CDROM_path = PathField(
        label=_('CD-ROM (ISO)'),
        required=False,
        dirsonly=False,
    )
    DISK_zvol = forms.ChoiceField(
        label=_('ZVol'),
        required=False,
    )
    DISK_mode = forms.ChoiceField(
        label=_('Mode'),
        choices=choices.VM_DISKMODETYPES,
        required=False,
        initial='AHCI',
    )
    DISK_raw = PathField(
        label=_('Raw File'),
        required=False,
        dirsonly=False,
    )
    DISK_sectorsize = forms.IntegerField(
        label=_('Disk sectorsize'),
        required=False,
        initial=0,
        help_text=_("Logical and physical sector size in bytes of the emulated disk."
                    "If 0, a sector size is not set."),
    )
    NIC_type = forms.ChoiceField(
        label=_('Adapter Type'),
        choices=choices.VM_NICTYPES,
        required=False,
        initial='E1000',
    )
    NIC_attach = forms.ChoiceField(
        label=_('Nic to attach'),
        choices=choices.NICChoices(exclude_configured=False),
        required=False,
    )
    NIC_mac = forms.CharField(
        label=_('Mac Address'),
        required=False,
        help_text=_("You can specify the adapter MAC Address or let it be auto generated."),
        validators=[RegexValidator("^([0-9a-fA-F]{2}([::]?|$)){6}$", "Invalid MAC format.")],
        initial='00:a0:98:FF:FF:FF',
    )
    VNC_resolution = forms.ChoiceField(
        label=_('Resolution'),
        choices=choices.VNC_RESOLUTION,
        required=False,
        initial='1024x768',
    )
    VNC_port = forms.CharField(
        label=_('VNC port'),
        required=False,
        help_text=_("You can specify the VNC port or 0 for auto."),
        validators=[RegexValidator("^[0-9]*$", "Only integer is accepted")],
        initial=0,
    )
    VNC_bind = forms.ChoiceField(
        label=_('Bind to'),
        choices=(),
        required=False,
        initial='0.0.0.0'
    )
    VNC_wait = forms.BooleanField(
        label=_('Wait to boot'),
        required=False,
    )

    class Meta:
        fields = '__all__'
        model = models.Device

    def __init__(self, *args, **kwargs):
        super(DeviceForm, self).__init__(*args, **kwargs)
        self.fields['dtype'].widget.attrs['onChange'] = (
            "deviceTypeToggle();"
        )
        self.fields['VNC_bind'].choices = self.ipv4_list()

        diskchoices = {}
        _n = notifier()
        used_zvol = []
        for volume in Volume.objects.filter():
            zvols = _n.list_zfs_vols(volume.vol_name, sort='name')
            for zvol, attrs in zvols.items():
                if "zvol/" + zvol not in used_zvol:
                    diskchoices["zvol/" + zvol] = "%s (%s)" % (
                        zvol,
                        humanize_size(attrs['volsize']))
        self.fields['DISK_zvol'].choices = diskchoices.items()

        if self.instance.id:
            if self.instance.dtype == 'CDROM':
                self.fields['CDROM_path'].initial = self.instance.attributes.get('path', '')
            elif self.instance.dtype == 'DISK':
                self.fields['DISK_zvol'].initial = self.instance.attributes.get('path', '').replace('/dev/', '')
                self.fields['DISK_mode'].initial = self.instance.attributes.get('type')
                self.fields['DISK_sectorsize'].initial = self.instance.attributes.get('sectorsize', 0)
            elif self.instance.dtype == "RAW":
                self.fields['DISK_raw'].initial = self.instance.attributes.get('path', '')
                self.fields['DISK_mode'].initial = self.instance.attributes.get('type')
                self.fields['DISK_sectorsize'].initial = self.instance.attributes.get('sectorsize', 0)
            elif self.instance.dtype == 'NIC':
                self.fields['NIC_type'].initial = self.instance.attributes.get('type')
                self.fields['NIC_mac'].initial = self.instance.attributes.get('mac')
                self.fields['NIC_attach'].initial = self.instance.attributes.get('nic_attach')
            elif self.instance.dtype == 'VNC':
                vnc_port = self.instance.attributes.get('vnc_port')
                vnc_port = 0 if vnc_port is None else vnc_port

                self.fields['VNC_wait'].initial = self.instance.attributes.get('wait')
                self.fields['VNC_port'].initial = vnc_port
                self.fields['VNC_resolution'].initial = self.instance.attributes.get('vnc_resolution')
                self.fields['VNC_bind'].initial = self.instance.attributes.get('vnc_bind')

    def ipv4_list(self):
        choices = (('0.0.0.0', '0.0.0.0'),)
        with client as c:
            ipv4_addresses = c.call('interfaces.ipv4_in_use')
        for ipv4_addr in ipv4_addresses:
            choices = choices + ((ipv4_addr, ipv4_addr),)
        return choices

    def clean(self):
        vm = self.cleaned_data.get('vm')
        vnc_port = self.cleaned_data.get('VNC_port')
        new_vnc_port = 5900
        if vm and vnc_port == '0':
            new_vnc_port = new_vnc_port + int(vm.id)
            self.cleaned_data['VNC_port'] = str(new_vnc_port)

        return self.cleaned_data

    def save(self, *args, **kwargs):
        vm = self.cleaned_data.get('vm')
        kwargs['commit'] = False
        obj = super(DeviceForm, self).save(*args, **kwargs)
        if self.cleaned_data['dtype'] == 'DISK':
            obj.attributes = {
                'path': '/dev/' + self.cleaned_data['DISK_zvol'],
                'type': self.cleaned_data['DISK_mode'],
                'sectorsize': self.cleaned_data['DISK_sectorsize'],
            }
        elif self.cleaned_data['dtype'] == 'RAW':
            obj.attributes = {
                'path': self.cleaned_data['DISK_raw'],
                'type': self.cleaned_data['DISK_mode'],
                'sectorsize': self.cleaned_data['DISK_sectorsize'],
            }
        elif self.cleaned_data['dtype'] == 'CDROM':
            cdrom_path = self.cleaned_data['CDROM_path']
            if cdrom_path:
                obj.attributes = {
                    'path': cdrom_path,
                }
            else:
                self._errors['CDROM_path'] = self.error_class([_('Please choose an ISO file.')])
        elif self.cleaned_data['dtype'] == 'NIC':
            obj.attributes = {
                'type': self.cleaned_data['NIC_type'],
                'mac': self.cleaned_data['NIC_mac'],
                'nic_attach': self.cleaned_data['NIC_attach'],
            }
        elif self.cleaned_data['dtype'] == 'VNC':
            if vm.bootloader == 'UEFI':
                obj.attributes = {
                    'wait': self.cleaned_data['VNC_wait'],
                    'vnc_port': self.cleaned_data['VNC_port'],
                    'vnc_resolution': self.cleaned_data['VNC_resolution'],
                    'vnc_bind': self.cleaned_data['VNC_bind'],
                }
            else:
                self._errors['dtype'] = self.error_class([_('VNC is only allowed for UEFI')])
                self.cleaned_data.pop('VNC_port', None)
                self.cleaned_data.pop('VNC_wait', None)
                self.cleaned_data.pop('VNC_resolution', None)
                self.cleaned_data.pop('VNC_bind', None)
                return obj

        obj.save()
        return obj
コード例 #30
0
class RsyncForm(ModelForm):

    rsync_validate_rpath = forms.BooleanField(
        initial=True,
        label=_("Validate Remote Path"),
        required=False,
        help_text=_("This ensures Remote Path Validation."
                    " Uncheck this if the remote machine"
                    " is currently offline or beyond network reach."
                    " And/Or you do not want validation to be done."),
    )

    class Meta:

        fields = [
            'rsync_path', 'rsync_user', 'rsync_remotehost', 'rsync_remoteport',
            'rsync_mode', 'rsync_remotemodule', 'rsync_remotepath',
            'rsync_validate_rpath', 'rsync_direction', 'rsync_desc',
            'rsync_minute', 'rsync_hour', 'rsync_daymonth', 'rsync_month',
            'rsync_dayweek', 'rsync_recursive', 'rsync_times',
            'rsync_compress', 'rsync_archive', 'rsync_delete', 'rsync_quiet',
            'rsync_preserveperm', 'rsync_preserveattr', 'rsync_delayupdates',
            'rsync_extra', 'rsync_enabled'
        ]
        model = models.Rsync
        widgets = {
            'rsync_minute':
            CronMultiple(attrs={
                'numChoices': 60,
                'label': _("minute")
            }),
            'rsync_hour':
            CronMultiple(attrs={
                'numChoices': 24,
                'label': _("hour")
            }),
            'rsync_daymonth':
            CronMultiple(attrs={
                'numChoices': 31,
                'start': 1,
                'label': _("day of month"),
            }),
            'rsync_dayweek':
            forms.CheckboxSelectMultiple(choices=choices.WEEKDAYS_CHOICES),
            'rsync_month':
            forms.CheckboxSelectMultiple(choices=choices.MONTHS_CHOICES),
        }

    def __init__(self, *args, **kwargs):
        super(RsyncForm, self).__init__(*args, **kwargs)
        mchoicefield(self, 'rsync_month',
                     [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
        mchoicefield(self, 'rsync_dayweek', [1, 2, 3, 4, 5, 6, 7])
        self.fields['rsync_mode'].widget.attrs['onChange'] = (
            "rsyncModeToggle();")

    def check_rpath_exists(self):
        """A function to check if the rsync_remotepath,
        exists or not. Returns TRUE rpath is a directory
        and exists, else FALSE"""

        ruser = self.cleaned_data.get("rsync_user").encode('utf8')
        rhost = str(self.cleaned_data.get("rsync_remotehost"))
        if '@' in rhost:
            remote = rhost
        else:
            remote = '"%s"@%s' % (
                ruser,
                rhost,
            )
        rport = str(self.cleaned_data.get("rsync_remoteport"))
        rpath = self.cleaned_data.get("rsync_remotepath").encode('utf8')
        proc = subprocess.Popen(
            """su -m "%s" -c 'ssh -p %s -o "BatchMode yes" -o """
            """"ConnectTimeout=5" %s test -d \\""%s"\\"' """ %
            (ruser, rport, remote, rpath),
            shell=True)
        proc.wait()
        return proc.returncode == 0

    def clean_rsync_user(self):
        user = self.cleaned_data.get("rsync_user")
        # Windows users can have spaces in their usernames
        # http://www.freebsd.org/cgi/query-pr.cgi?pr=164808
        if ' ' in user:
            raise forms.ValidationError(_("Usernames cannot have spaces"))
        return user

    def clean_rsync_remotemodule(self):
        mode = self.cleaned_data.get("rsync_mode")
        val = self.cleaned_data.get("rsync_remotemodule")
        if mode == 'module' and not val:
            raise forms.ValidationError(_("This field is required"))
        return val

    def clean_rsync_remotepath(self):
        mode = self.cleaned_data.get("rsync_mode")
        val = self.cleaned_data.get("rsync_remotepath")
        if mode == 'ssh' and not val:
            raise forms.ValidationError(_("This field is required"))
        return val

    def clean_rsync_month(self):
        m = self.data.getlist("rsync_month")
        if len(m) == 12:
            return '*'
        m = ",".join(m)
        return m

    def clean_rsync_dayweek(self):
        w = self.data.getlist("rsync_dayweek")
        if len(w) == 7:
            return '*'
        w = ",".join(w)
        return w

    def clean_rsync_extra(self):
        extra = self.cleaned_data.get("rsync_extra")
        if extra:
            extra = extra.replace('\n', ' ')
        return extra

    def clean(self):
        cdata = self.cleaned_data
        mode = cdata.get("rsync_mode")
        user = cdata.get("rsync_user")
        if mode == 'ssh':
            try:
                home = pwd.getpwnam(user).pw_dir
                search = os.path.join(home, ".ssh", "id_[edr]*.*")
                if not glob.glob(search):
                    raise ValueError
            except (KeyError, ValueError, AttributeError, TypeError):
                self._errors['rsync_user'] = self.error_class([
                    _("In order to use rsync over SSH you need a user<br />"
                      "with a public key (DSA/ECDSA/RSA) set up in home dir."),
                ])
                cdata.pop('rsync_user', None)
        if 'rsync_user' in cdata and not (
                self.cleaned_data.get("rsync_mode") == 'module'
                or not self.cleaned_data.get("rsync_validate_rpath")
                or self.check_rpath_exists()):
            self._errors["rsync_remotepath"] = self.error_class([
                _("The Remote Path you specified does not exist or is not a "
                  "directory.<br>Either create one yourself on the remote "
                  "machine or uncheck the<br>'rsync_validate_rpath' field."
                  "<br>**Note**: This could also happen if the remote path "
                  "entered<br> exceeded 255 characters and was truncated, please"
                  " restrict it to<br>255. Or it could also be that your SSH "
                  "credentials (remote host,etc) are wrong.")
            ])
        return cdata

    def save(self):
        super(RsyncForm, self).save()
        notifier().restart("cron")