@ -35,26 +35,18 @@ from ipaddress import IPv6Address
from itertools import chain
from django . core . validators import MaxValueValidator , MinValueValidator
from django . db import models
from django . db import models , transaction
from django . db . models import Q
from django . db . models . signals import post_save , post_delet e
from django . db . models . signals import post_delete , post_sav e
from django . dispatch import receiver
from django . forms import ValidationError
from django . utils import timezone
from django . db import transaction
from reversion import revisions as reversion
from django . utils . functional import cached_property
from django . utils . translation import ugettext_lazy as _
from macaddress . fields import MACAddressField , default_dialect
from netaddr import (
mac_bare ,
EUI ,
NotRegisteredError ,
IPSet ,
IPRange ,
IPNetwork ,
IPAddress ,
)
from netaddr import ( EUI , IPAddress , IPNetwork , IPRange , IPSet ,
NotRegisteredError , mac_bare )
from reversion import revisions as reversion
import preferences . models
import users . models
@ -79,9 +71,7 @@ class Machine(RevMixin, FieldPermissionModelMixin, AclMixin, models.Model):
active = models . BooleanField ( default = True )
class Meta :
permissions = (
( " change_machine_user " , _ ( " Can change the user of a machine " ) ) ,
)
permissions = ( ( " change_machine_user " , _ ( " Can change the user of a machine " ) ) , )
verbose_name = _ ( " machine " )
verbose_name_plural = _ ( " machines " )
@ -342,9 +332,7 @@ class MachineType(RevMixin, AclMixin, models.Model):
)
class Meta :
permissions = (
( " use_all_machinetype " , _ ( " Can use all machine types " ) ) ,
)
permissions = ( ( " use_all_machinetype " , _ ( " Can use all machine types " ) ) , )
verbose_name = _ ( " machine type " )
verbose_name_plural = _ ( " machine types " )
@ -356,7 +344,9 @@ class MachineType(RevMixin, AclMixin, models.Model):
""" Update domains extension with the extension of interface_parent. Called after update of an ip_type or a machine_type object. Exceptions are handled in the views.
( Calling domain . clear ( ) for all domains could take several minutes )
"""
Domain . objects . filter ( interface_parent__machine_type = self ) . update ( extension = self . ip_type . extension )
Domain . objects . filter ( interface_parent__machine_type = self ) . update (
extension = self . ip_type . extension
)
@staticmethod
def can_use_all ( user_request , * _args , * * _kwargs ) :
@ -389,20 +379,13 @@ class MachineType(RevMixin, AclMixin, models.Model):
"""
can , _message , _group = cls . can_use_all ( user_request )
if can :
return (
True ,
None ,
None ,
cls . objects . all ( )
)
return ( True , None , None , cls . objects . all ( ) )
else :
return (
True ,
_ ( " You don ' t have the right to use all machine types. " ) ,
( " machines.use_all_machinetype " , ) ,
cls . objects . filter (
ip_type__in = IpType . objects . filter ( need_infra = False )
) ,
cls . objects . filter ( ip_type__in = IpType . objects . filter ( need_infra = False ) ) ,
)
def __str__ ( self ) :
@ -455,12 +438,12 @@ class IpType(RevMixin, AclMixin, models.Model):
default = False , help_text = _ ( " Enable reverse DNS for IPv6. " )
)
vlan = models . ForeignKey ( " Vlan " , on_delete = models . PROTECT , blank = True , null = True )
ouverture_ports = models . ForeignKey ( " OuverturePortList " , blank = True , null = True , on_delete = models . PROTECT )
ouverture_ports = models . ForeignKey (
" OuverturePortList " , blank = True , null = True , on_delete = models . PROTECT
)
class Meta :
permissions = (
( " use_all_iptype " , _ ( " Can use all IP types " ) ) ,
)
permissions = ( ( " use_all_iptype " , _ ( " Can use all IP types " ) ) , )
verbose_name = _ ( " IP type " )
verbose_name_plural = _ ( " IP types " )
@ -897,9 +880,7 @@ class Extension(RevMixin, AclMixin, models.Model):
)
class Meta :
permissions = (
( " use_all_extension " , _ ( " Can use all extensions " ) ) ,
)
permissions = ( ( " use_all_extension " , _ ( " Can use all extensions " ) ) , )
verbose_name = _ ( " DNS extension " )
verbose_name_plural = _ ( " DNS extensions " )
@ -987,12 +968,7 @@ class Extension(RevMixin, AclMixin, models.Model):
"""
can , _message , _group = cls . can_use_all ( user_request )
if can :
return (
True ,
None ,
None ,
cls . objects . all ( )
)
return ( True , None , None , cls . objects . all ( ) )
else :
return (
True ,
@ -1035,8 +1011,7 @@ class Mx(RevMixin, AclMixin, models.Model):
@cached_property
def dns_entry ( self ) :
""" Get the complete DNS entry of the MX record, to put in zone files.
"""
""" Get the complete DNS entry of the MX record, to put in zone files. """
return " @ IN MX {prior} {name} " . format (
prior = str ( self . priority ) . ljust ( 3 ) , name = str ( self . name )
)
@ -1066,8 +1041,7 @@ class Ns(RevMixin, AclMixin, models.Model):
@cached_property
def dns_entry ( self ) :
""" Get the complete DNS entry of the NS record, to put in zone files.
"""
""" Get the complete DNS entry of the NS record, to put in zone files. """
return " @ IN NS " + str ( self . ns )
def __str__ ( self ) :
@ -1100,8 +1074,7 @@ class Txt(RevMixin, AclMixin, models.Model):
@cached_property
def dns_entry ( self ) :
""" Get the complete DNS entry of the TXT record, to put in zone files.
"""
""" Get the complete DNS entry of the TXT record, to put in zone files. """
return str ( self . field1 ) . ljust ( 15 ) + " IN TXT " + str ( self . field2 )
@ -1129,8 +1102,7 @@ class DName(RevMixin, AclMixin, models.Model):
@cached_property
def dns_entry ( self ) :
""" Get the complete DNS entry of the TXT record, to put in zone files.
"""
""" Get the complete DNS entry of the TXT record, to put in zone files. """
return str ( self . alias ) . ljust ( 15 ) + " IN DNAME " + str ( self . zone )
@ -1204,8 +1176,7 @@ class Srv(RevMixin, AclMixin, models.Model):
@cached_property
def dns_entry ( self ) :
""" Get the complete DNS entry of the SRV record, to put in zone files.
"""
""" Get the complete DNS entry of the SRV record, to put in zone files. """
return (
str ( self . service )
+ " ._ "
@ -1387,8 +1358,7 @@ class Interface(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
return vendor
def sync_ipv6_dhcpv6 ( self ) :
""" Assign an IPv6 address by DHCPv6, computed from the interface ' s ID.
"""
""" Assign an IPv6 address by DHCPv6, computed from the interface ' s ID. """
ipv6_dhcpv6 = self . gen_ipv6_dhcpv6
if not ipv6_dhcpv6 :
return
@ -1414,8 +1384,7 @@ class Interface(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
ipv6_object . save ( )
def sync_ipv6 ( self ) :
""" Create and update the IPv6 addresses according to the IPv6 mode set.
"""
""" Create and update the IPv6 addresses according to the IPv6 mode set. """
if preferences . models . OptionalMachine . get_cached_value ( " ipv6_mode " ) == " SLAAC " :
self . sync_ipv6_slaac ( )
elif (
@ -1581,8 +1550,10 @@ class Interface(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
_ ( " You don ' t have the right to add a machine. " ) ,
( " machines.add_interface " , ) ,
)
max_lambdauser_interfaces = preferences . models . OptionalMachine . get_cached_value (
" max_lambdauser_interfaces "
max_lambdauser_interfaces = (
preferences . models . OptionalMachine . get_cached_value (
" max_lambdauser_interfaces "
)
)
if machine . user != user_request :
return (
@ -1721,8 +1692,7 @@ class Ipv6List(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
)
slaac_ip = models . BooleanField ( default = False )
active = models . BooleanField (
default = True ,
help_text = _ ( " If false,the DNS will not provide this ip. " )
default = True , help_text = _ ( " If false,the DNS will not provide this ip. " )
)
class Meta :
@ -1856,8 +1826,9 @@ class Ipv6List(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
def check_and_replace_prefix ( self , prefix = None ) :
""" Check if the IPv6 prefix is correct and update it if not. """
prefix_v6 = prefix or self . interface . machine_type . ip_type . prefix_v6 . encode ( ) . decode (
" utf-8 "
prefix_v6 = (
prefix
or self . interface . machine_type . ip_type . prefix_v6 . encode ( ) . decode ( " utf-8 " )
)
if not prefix_v6 :
return
@ -1930,7 +1901,11 @@ class Domain(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
)
extension = models . ForeignKey ( " Extension " , on_delete = models . PROTECT )
cname = models . ForeignKey (
" self " , null = True , blank = True , related_name = " related_domain " , on_delete = models . PROTECT
" self " ,
null = True ,
blank = True ,
related_name = " related_domain " ,
on_delete = models . PROTECT ,
)
ttl = models . PositiveIntegerField (
verbose_name = _ ( " Time To Live (TTL) " ) ,
@ -1940,9 +1915,7 @@ class Domain(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
class Meta :
unique_together = ( ( " name " , " extension " ) , )
permissions = (
( " change_ttl " , _ ( " Can change the TTL of a domain object " ) ) ,
)
permissions = ( ( " change_ttl " , _ ( " Can change the TTL of a domain object " ) ) , )
verbose_name = _ ( " domain " )
verbose_name_plural = _ ( " domains " )
@ -2037,8 +2010,10 @@ class Domain(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model):
except Interface . DoesNotExist :
return False , _ ( " Nonexistent interface. " ) , None
if not user_request . has_perm ( " machines.add_domain " ) :
max_lambdauser_aliases = preferences . models . OptionalMachine . get_cached_value (
" max_lambdauser_aliases "
max_lambdauser_aliases = (
preferences . models . OptionalMachine . get_cached_value (
" max_lambdauser_aliases "
)
)
if interface . machine . user != user_request :
return (
@ -2173,8 +2148,7 @@ class IpList(RevMixin, AclMixin, models.Model):
@cached_property
def need_infra ( self ) :
""" Check if the ' infra ' right is required to assign this IP address.
"""
""" Check if the ' infra ' right is required to assign this IP address. """
return self . ip_type . need_infra
def clean ( self ) :
@ -2206,20 +2180,13 @@ class IpList(RevMixin, AclMixin, models.Model):
"""
can , _message , _group = IpType . can_use_all ( user_request )
if can :
return (
True ,
None ,
None ,
cls . objects . all ( )
)
return ( True , None , None , cls . objects . all ( ) )
else :
return (
True ,
_ ( " You don ' t have the right to use all machine types. " ) ,
( " machines.use_all_machinetype " , ) ,
cls . objects . filter (
ip_type__in = IpType . objects . filter ( need_infra = False )
) ,
cls . objects . filter ( ip_type__in = IpType . objects . filter ( need_infra = False ) ) ,
)
def __str__ ( self ) :
@ -2517,7 +2484,13 @@ class OuverturePort(RevMixin, AclMixin, models.Model):
def machine_post_save ( * * kwargs ) :
""" Synchronise LDAP and regen firewall/DHCP after a machine is edited. """
user = kwargs [ " instance " ] . user
users . signals . synchronise . send ( sender = users . models . User , instance = user , base = False , access_refresh = False , mac_refresh = True )
users . signals . synchronise . send (
sender = users . models . User ,
instance = user ,
base = False ,
access_refresh = False ,
mac_refresh = True ,
)
regen ( " dhcp " )
regen ( " mac_ip_list " )
@ -2527,7 +2500,13 @@ def machine_post_delete(**kwargs):
""" Synchronise LDAP and regen firewall/DHCP after a machine is deleted. """
machine = kwargs [ " instance " ]
user = machine . user
users . signals . synchronise . send ( sender = users . models . User , instance = user , base = False , access_refresh = False , mac_refresh = True )
users . signals . synchronise . send (
sender = users . models . User ,
instance = user ,
base = False ,
access_refresh = False ,
mac_refresh = True ,
)
regen ( " dhcp " )
regen ( " mac_ip_list " )
@ -2540,7 +2519,13 @@ def interface_post_save(**kwargs):
interface = kwargs [ " instance " ]
interface . sync_ipv6 ( )
user = interface . machine . user
users . signals . synchronise . send ( sender = users . models . User , instance = user , base = False , access_refresh = False , mac_refresh = True )
users . signals . synchronise . send (
sender = users . models . User ,
instance = user ,
base = False ,
access_refresh = False ,
mac_refresh = True ,
)
# Regen services
regen ( " dhcp " )
regen ( " mac_ip_list " )
@ -2552,11 +2537,16 @@ def interface_post_save(**kwargs):
@receiver ( post_delete , sender = Interface )
def interface_post_delete ( * * kwargs ) :
""" Synchronise LDAP and regen firewall/DHCP after an interface is deleted.
"""
""" Synchronise LDAP and regen firewall/DHCP after an interface is deleted. """
interface = kwargs [ " instance " ]
user = interface . machine . user
users . signals . synchronise . send ( sender = users . models . User , instance = user , base = False , access_refresh = False , mac_refresh = True )
users . signals . synchronise . send (
sender = users . models . User ,
instance = user ,
base = False ,
access_refresh = False ,
mac_refresh = True ,
)
@receiver ( post_save , sender = IpType )