def clean_alias_v4netmaskbit(self): vip = self.cleaned_data.get("alias_vip") ip = self.cleaned_data.get("alias_v4address") nw = self.cleaned_data.get("alias_v4netmaskbit") if not nw or not ip: return nw network = IPNetwork("%s/%s" % (ip, nw)) if vip: if not network.overlaps(IPNetwork("%s/%s" % (vip, nw))): raise forms.ValidationError(_("Virtual IP is not in the same network")) if self.instance.id and self.instance.alias_interface.int_interface.startswith("carp"): return nw used_networks = [] qs = models.Interfaces.objects.all().exclude(int_interface__startswith="carp") if self.instance.id: qs = qs.exclude(id=self.instance.alias_interface.id) elif self.parent.instance.id: qs = qs.exclude(id=self.parent.instance.id) for iface in qs: if iface.int_v4netmaskbit: used_networks.append(IPNetwork("%s/%s" % (iface.int_ipv4address, iface.int_v4netmaskbit))) for alias in iface.alias_set.all(): if alias.alias_v4netmaskbit: used_networks.append(IPNetwork("%s/%s" % (alias.alias_v4address, alias.alias_v4netmaskbit))) for unet in used_networks: if unet.overlaps(network): raise forms.ValidationError(_("The network %s is already in use by another NIC.") % (network.masked(),)) return nw
def clean(self): cdata = self.cleaned_data ipv4key = 'int_ipv4address' ipv4addr = cdata.get(ipv4key) ipv4addr_b = cdata.get('int_ipv4address_b') ipv4net = cdata.get("int_v4netmaskbit") if ipv4addr and ipv4addr_b and ipv4net: network = IPNetwork('%s/%s' % (ipv4addr, ipv4net)) if not network.overlaps( IPNetwork('%s/%s' % (ipv4addr_b, ipv4net)) ): self._errors['int_ipv4address_b'] = self.error_class([ _('The IP must be within the same network') ]) ipv6addr = cdata.get("int_ipv6address") ipv6net = cdata.get("int_v6netmaskbit") ipv4 = True if ipv4addr and ipv4net else False ipv6 = True if ipv6addr and ipv6net else False # IF one field of ipv4 is entered, require the another if (ipv4addr or ipv4net) and not ipv4: if not (ipv4addr or ipv4addr_b) and not self._errors.get(ipv4key): self._errors[ipv4key] = self.error_class([ _("You have to specify IPv4 address as well"), ]) if not ipv4net and 'int_v4netmaskbit' not in self._errors: self._errors['int_v4netmaskbit'] = self.error_class([ _("You have to choose IPv4 netmask as well"), ]) # IF one field of ipv6 is entered, require the another if (ipv6addr or ipv6net) and not ipv6: if not ipv6addr and not self._errors.get('int_ipv6address'): self._errors['int_ipv6address'] = self.error_class([ _("You have to specify IPv6 address as well"), ]) if not ipv6net: self._errors['int_v6netmaskbit'] = self.error_class([ _("You have to choose IPv6 netmask as well"), ]) if ipv6 and ipv4: self._errors['__all__'] = self.error_class([ _("You have to choose between IPv4 or IPv6"), ]) vip = cdata.get("int_vip") if vip and not ipv4addr_b: self._errors['int_ipv4address_b'] = self.error_class([ _("This field is required for failover") ]) if vip and not ipv4addr: self._errors['int_ipv4address'] = self.error_class([ _("This field is required for failover") ]) return cdata
def clean(self): cdata = self.cleaned_data ipv4vip = cdata.get("alias_vip") ipv4addr = cdata.get("alias_v4address") ipv4net = cdata.get("alias_v4netmaskbit") ipv6addr = cdata.get("alias_v6address") ipv6net = cdata.get("alias_v6netmaskbit") ipv4 = True if ipv4addr and ipv4net else False ipv6 = True if ipv6addr and ipv6net else False # IF one field of ipv4 is entered, require the another if (ipv4addr or ipv4net) and not ipv4: if not ipv4addr and not self._errors.get('alias_v4address'): self._errors['alias_v4address'] = self.error_class([ _("You have to specify IPv4 address as well per alias"), ]) if not ipv4net and 'alias_v4netmaskbit' not in self._errors: self._errors['alias_v4netmaskbit'] = self.error_class([ _("You have to choose IPv4 netmask as well per alias"), ]) # IF one field of ipv6 is entered, require the another if (ipv6addr or ipv6net) and not ipv6: if not ipv6addr and not self._errors.get('alias_v6address'): self._errors['alias_v6address'] = self.error_class([ _("You have to specify IPv6 address as well per alias"), ]) if not ipv6net: self._errors['alias_v6netmaskbit'] = self.error_class([ _("You have to choose IPv6 netmask as well per alias"), ]) if ipv6 and ipv4: self._errors['__all__'] = self.error_class([ _("You have to choose between IPv4 or IPv6 per alias"), ]) configured_vip = False if ipv4vip and hasattr(self, 'parent'): iface = self.parent.instance ip = IPNetwork('%s/32' % ipv4vip) network = IPNetwork('%s/%s' % ( iface.int_ipv4address, iface.int_v4netmaskbit, )) if ip.overlaps(network): configured_vip = True if ( not configured_vip and not ipv6 and not (ipv6addr or ipv6net) and not ipv4 and not (ipv4addr or ipv4net) ): self._errors['__all__'] = self.error_class([ _("You must specify either an valid IPv4 or IPv6 with maskbit " "per alias"), ]) return cdata
def clean(self): cdata = self.cleaned_data ipv4key = 'int_ipv4address' ipv4addr = cdata.get(ipv4key) ipv4addr_b = cdata.get('int_ipv4address_b') ipv4net = cdata.get("int_v4netmaskbit") if ipv4addr and ipv4addr_b and ipv4net: network = IPNetwork('%s/%s' % (ipv4addr, ipv4net)) if not network.overlaps(IPNetwork('%s/%s' % (ipv4addr_b, ipv4net))): self._errors['int_ipv4address_b'] = self.error_class( [_('The IP must be within the same network')]) ipv6addr = cdata.get("int_ipv6address") ipv6net = cdata.get("int_v6netmaskbit") ipv4 = True if ipv4addr and ipv4net else False ipv6 = True if ipv6addr and ipv6net else False # IF one field of ipv4 is entered, require the another if (ipv4addr or ipv4net) and not ipv4: if not (ipv4addr or ipv4addr_b) and not self._errors.get(ipv4key): self._errors[ipv4key] = self.error_class([ _("You have to specify IPv4 address as well"), ]) if not ipv4net and 'int_v4netmaskbit' not in self._errors: self._errors['int_v4netmaskbit'] = self.error_class([ _("You have to choose IPv4 netmask as well"), ]) # IF one field of ipv6 is entered, require the another if (ipv6addr or ipv6net) and not ipv6: if not ipv6addr and not self._errors.get('int_ipv6address'): self._errors['int_ipv6address'] = self.error_class([ _("You have to specify IPv6 address as well"), ]) if not ipv6net: self._errors['int_v6netmaskbit'] = self.error_class([ _("You have to choose IPv6 netmask as well"), ]) if ipv6 and ipv4: self._errors['__all__'] = self.error_class([ _("You have to choose between IPv4 or IPv6"), ]) vip = cdata.get("int_vip") dhcp = cdata.get("int_dhcp") if not dhcp: if vip and not ipv4addr_b: self._errors['int_ipv4address_b'] = self.error_class( [_("This field is required for failover")]) if vip and not ipv4addr: self._errors['int_ipv4address'] = self.error_class( [_("This field is required for failover")]) return cdata
def clean(self): cdata = self.cleaned_data _n = notifier() if not _n.is_freenas() and _n.failover_licensed(): from freenasUI.failover.models import Failover try: if Failover.objects.all()[0].disabled is False: self._errors["__all__"] = self.error_class( [_("Failover needs to be disabled to perform network " "changes.")] ) except: log.warn("Failed to verify failover status", exc_info=True) ipv4key = "int_ipv4address" ipv4addr = cdata.get(ipv4key) ipv4addr_b = cdata.get("int_ipv4address_b") ipv4net = cdata.get("int_v4netmaskbit") if ipv4addr and ipv4addr_b and ipv4net: network = IPNetwork("%s/%s" % (ipv4addr, ipv4net)) if not network.overlaps(IPNetwork("%s/%s" % (ipv4addr_b, ipv4net))): self._errors["int_ipv4address_b"] = self.error_class([_("The IP must be within the same network")]) ipv6addr = cdata.get("int_ipv6address") ipv6net = cdata.get("int_v6netmaskbit") ipv4 = True if ipv4addr and ipv4net else False ipv6 = True if ipv6addr and ipv6net else False # IF one field of ipv4 is entered, require the another if (ipv4addr or ipv4net) and not ipv4: if not (ipv4addr or ipv4addr_b) and not self._errors.get(ipv4key): self._errors[ipv4key] = self.error_class([_("You have to specify IPv4 address as well")]) if not ipv4net and "int_v4netmaskbit" not in self._errors: self._errors["int_v4netmaskbit"] = self.error_class([_("You have to choose IPv4 netmask as well")]) # IF one field of ipv6 is entered, require the another if (ipv6addr or ipv6net) and not ipv6: if not ipv6addr and not self._errors.get("int_ipv6address"): self._errors["int_ipv6address"] = self.error_class([_("You have to specify IPv6 address as well")]) if not ipv6net: self._errors["int_v6netmaskbit"] = self.error_class([_("You have to choose IPv6 netmask as well")]) if ipv6 and ipv4: self._errors["__all__"] = self.error_class([_("You have to choose between IPv4 or IPv6")]) vip = cdata.get("int_vip") dhcp = cdata.get("int_dhcp") if not dhcp: if vip and not ipv4addr_b: self._errors["int_ipv4address_b"] = self.error_class([_("This field is required for failover")]) if vip and not ipv4addr: self._errors["int_ipv4address"] = self.error_class([_("This field is required for failover")]) return cdata
def clean_alias_v4netmaskbit(self): vip = self.cleaned_data.get("alias_vip") ip = self.cleaned_data.get("alias_v4address") nw = self.cleaned_data.get("alias_v4netmaskbit") if not nw or not ip: return nw network = IPNetwork('%s/%s' % (ip, nw)) if vip: if not network.overlaps(IPNetwork('%s/%s' % (vip, nw))): raise forms.ValidationError(_( 'Virtual IP is not in the same network' )) if ( self.instance.id and self.instance.alias_interface.int_interface.startswith('carp') ): return nw used_networks = [] qs = models.Interfaces.objects.all().exclude( int_interface__startswith='carp' ) if self.instance.id: qs = qs.exclude(id=self.instance.alias_interface.id) elif self.parent.instance.id: qs = qs.exclude(id=self.parent.instance.id) for iface in qs: if iface.int_v4netmaskbit: used_networks.append( IPNetwork('%s/%s' % ( iface.int_ipv4address, iface.int_v4netmaskbit, )) ) for alias in iface.alias_set.all(): if alias.alias_v4netmaskbit: used_networks.append( IPNetwork('%s/%s' % ( alias.alias_v4address, alias.alias_v4netmaskbit, )) ) for unet in used_networks: if unet.overlaps(network): raise forms.ValidationError( _("The network %s is already in use by another NIC.") % ( network.masked(), ) ) return nw
def clean_nfs_network(self): net = self.cleaned_data['nfs_network'] net = re.sub(r'\s{2,}|\n', ' ', net).strip() if not net: return net seen_networks = [] for n in net.split(' '): try: netobj = IPNetwork(n) if n.find("/") == -1: raise ValueError(n) for i in seen_networks: if netobj.overlaps(i): raise forms.ValidationError( _('The following networks overlap: %(net1)s - %(net2)s' ) % { 'net1': netobj, 'net2': i, }) seen_networks.append(netobj) except (AddressValueError, NetmaskValueError, ValueError): raise forms.ValidationError( _("This is not a valid network: %s") % n) return net
def clean(self): cdata = self.cleaned_data _n = notifier() if ( not _n.is_freenas() and _n.failover_licensed() and _n.failover_status() != 'SINGLE' and ( self.instance.id and self.instance.int_vip ) ): from freenasUI.failover.models import Failover try: if Failover.objects.all()[0].disabled is False: self._errors['__all__'] = self.error_class([_( 'Failover needs to be disabled to perform network ' 'changes.' )]) except: log.warn('Failed to verify failover status', exc_info=True) ipv4key = 'int_ipv4address' ipv4addr = cdata.get(ipv4key) ipv4addr_b = cdata.get('int_ipv4address_b') ipv4net = cdata.get("int_v4netmaskbit") if ipv4addr and ipv4addr_b and ipv4net: network = IPNetwork('%s/%s' % (ipv4addr, ipv4net)) if not network.overlaps( IPNetwork('%s/%s' % (ipv4addr_b, ipv4net)) ): self._errors['int_ipv4address_b'] = self.error_class([ _('The IP must be within the same network') ]) ipv6addr = cdata.get("int_ipv6address") ipv6net = cdata.get("int_v6netmaskbit") ipv4 = True if ipv4addr and ipv4net else False ipv6 = True if ipv6addr and ipv6net else False # IF one field of ipv4 is entered, require the another if (ipv4addr or ipv4net) and not ipv4: if not (ipv4addr or ipv4addr_b) and not self._errors.get(ipv4key): self._errors[ipv4key] = self.error_class([ _("You have to specify IPv4 address as well"), ]) if not ipv4net and 'int_v4netmaskbit' not in self._errors: self._errors['int_v4netmaskbit'] = self.error_class([ _("You have to choose IPv4 netmask as well"), ]) # IF one field of ipv6 is entered, require the another if (ipv6addr or ipv6net) and not ipv6: if not ipv6addr and not self._errors.get('int_ipv6address'): self._errors['int_ipv6address'] = self.error_class([ _("You have to specify IPv6 address as well"), ]) if not ipv6net: self._errors['int_v6netmaskbit'] = self.error_class([ _("You have to choose IPv6 netmask as well"), ]) vip = cdata.get("int_vip") dhcp = cdata.get("int_dhcp") if not dhcp: if vip and not ipv4addr_b: self._errors['int_ipv4address_b'] = self.error_class([ _("This field is required for failover") ]) if vip and not ipv4addr: self._errors['int_ipv4address'] = self.error_class([ _("This field is required for failover") ]) return cdata
def cleanformset_nfs_share_path(self, formset, forms): dev = None valid = True ismp = False for form in forms: if not hasattr(form, "cleaned_data"): continue path = form.cleaned_data.get("path") if not path: continue parent = os.path.join(path, "..") try: stat = os.stat(path.encode("utf8")) if dev is None: dev = stat.st_dev elif dev != stat.st_dev: self._fserrors = self.error_class([ _("Paths for a NFS share must reside within the same " "filesystem") ]) valid = False break if os.stat(parent.encode("utf8")).st_dev != stat.st_dev: ismp = True if ismp and len(forms) > 1: self._fserrors = self.error_class([ _("You cannot share a mount point and subdirectories " "all at once") ]) valid = False break except OSError: pass if not ismp and self.cleaned_data.get('nfs_alldirs'): self._errors['nfs_alldirs'] = self.error_class( [_("This option can only be used for datasets.")]) valid = False networks = self.cleaned_data.get("nfs_network", "") if not networks: networks = ['0.0.0.0/0'] else: networks = networks.split(" ") qs = models.NFS_Share.objects.all() if self.instance.id: qs = qs.exclude(id=self.instance.id) used_networks = [] for share in qs: try: stdev = os.stat( share.paths.all()[0].path.encode("utf8")).st_dev except: continue if share.nfs_network: used_networks.extend([(y, stdev) for y in share.nfs_network.split(" ")]) else: used_networks.append(('0.0.0.0/0', stdev)) if (self.cleaned_data.get("nfs_alldirs") and share.nfs_alldirs and stdev == dev): self._errors['nfs_alldirs'] = self.error_class( [_("This option is only available once per mountpoint")]) valid = False break for network in networks: networkobj = IPNetwork(network) for unetwork, ustdev in used_networks: try: unetworkobj = IPNetwork(unetwork) except Exception: # If for some reason other values in db are not valid networks unetworkobj = IPNetwork('0.0.0.0/0') if networkobj.overlaps(unetworkobj) and dev == ustdev: self._errors['nfs_network'] = self.error_class([ _("The network %s is already being shared and cannot " "be used twice for the same filesystem") % (network, ) ]) valid = False break return valid
def clean(self): cdata = self.cleaned_data _n = notifier() if ( not _n.is_freenas() and _n.failover_licensed() and _n.failover_status() != 'SINGLE' and ( self.instance.id and self.instance.int_vip ) ): from freenasUI.failover.models import Failover try: if Failover.objects.all()[0].disabled is False: self._errors['__all__'] = self.error_class([_( 'Failover needs to be disabled to perform network ' 'changes.' )]) except: log.warn('Failed to verify failover status', exc_info=True) ipv4key = 'int_ipv4address' ipv4addr = cdata.get(ipv4key) ipv4addr_b = cdata.get('int_ipv4address_b') ipv4net = cdata.get("int_v4netmaskbit") if ipv4addr and ipv4addr_b and ipv4net: network = IPNetwork('%s/%s' % (ipv4addr, ipv4net)) if not network.overlaps( IPNetwork('%s/%s' % (ipv4addr_b, ipv4net)) ): self._errors['int_ipv4address_b'] = self.error_class([ _('The IP must be within the same network') ]) ipv6addr = cdata.get("int_ipv6address") ipv6net = cdata.get("int_v6netmaskbit") ipv4 = True if ipv4addr and ipv4net else False ipv6 = True if ipv6addr and ipv6net else False # IF one field of ipv4 is entered, require the another if (ipv4addr or ipv4net) and not ipv4: if not (ipv4addr or ipv4addr_b) and not self._errors.get(ipv4key): self._errors[ipv4key] = self.error_class([ _("You have to specify IPv4 address as well"), ]) if not ipv4net and 'int_v4netmaskbit' not in self._errors: self._errors['int_v4netmaskbit'] = self.error_class([ _("You have to choose IPv4 netmask as well"), ]) # IF one field of ipv6 is entered, require the another if (ipv6addr or ipv6net) and not ipv6: if not ipv6addr and not self._errors.get('int_ipv6address'): self._errors['int_ipv6address'] = self.error_class([ _("You have to specify IPv6 address as well"), ]) if not ipv6net: self._errors['int_v6netmaskbit'] = self.error_class([ _("You have to choose IPv6 netmask as well"), ]) vip = cdata.get("int_vip") dhcp = cdata.get("int_dhcp") if not dhcp: if vip and not ipv4addr_b: self._errors['int_ipv4address_b'] = self.error_class([ _("This field is required for failover") ]) if vip and not ipv4addr: self._errors['int_ipv4address'] = self.error_class([ _("This field is required for failover") ]) else: cdata['int_ipv4address'] = '' cdata['int_v4netmaskbit'] = '' # API backward compatibility options = cdata.get('int_options') if options: reg = RE_MTU.search(options) if reg: cdata['int_mtu'] = int(reg.group(1)) cdata['int_options'] = options.replace(reg.group(0), '') return cdata