Beispiel #1
0
class Host(models.Model):
    fqdn = models.CharField(unique=True,
                            max_length=255,
                            verbose_name=_("FQDN"))
    external_hostname = models.CharField(max_length=255,
                                         blank=True,
                                         verbose_name=_("External hostname"))
    external_ipv4 = netfields.InetAddressField(
        blank=True,
        null=True,
        store_prefix_length=False,
        verbose_name=_("External IPv4 address"))
    internal_ipv4 = netfields.InetAddressField(
        blank=True, null=True, verbose_name=_("Internal IPv4 address"))
    tunnel_ipv4 = netfields.InetAddressField(
        blank=True, null=True, verbose_name=_("Tunnel IPv4 address"))
    comment = models.CharField(max_length=255,
                               blank=True,
                               verbose_name=_("Comment"))

    private = models.BooleanField(default=False, verbose_name=_("Private"))
    autonomous_system = models.ForeignKey(AutonomousSystem,
                                          on_delete=models.CASCADE,
                                          related_name='hosts',
                                          verbose_name=_("Autonomous System"))

    objects = netfields.NetManager()

    class Meta:
        ordering = ['fqdn']
        verbose_name = ungettext_lazy("Host", "Hosts", 1)
        verbose_name_plural = ungettext_lazy("Host", "Hosts", 2)

    @classmethod
    def get_view_qs(cls, user):
        return cls.objects.filter(
            Q(private=False)
            | Q(autonomous_system__institution__owners=user)).distinct('fqdn')

    @property
    def institution(self):
        return self.autonomous_system.institution

    @property
    def has_geo(self):
        return self.autonomous_system.has_geo

    def __str__(self):
        return self.fqdn

    def can_edit(self, user):
        return self.autonomous_system.can_edit(user)
Beispiel #2
0
class IPv4Subnet(models.Model):
    network = netfields.CidrAddressField(unique=True,
                                         verbose_name=_("Network"))
    dns_server = netfields.InetAddressField(blank=True,
                                            null=True,
                                            store_prefix_length=False,
                                            verbose_name=_("DNS Server"))
    comment = models.CharField(max_length=255,
                               blank=True,
                               null=True,
                               verbose_name=_("Comment"))

    private = models.BooleanField(default=False, verbose_name=_("Private"))
    institution = models.ForeignKey(Institution,
                                    on_delete=models.CASCADE,
                                    related_name='ipv4_subnets',
                                    verbose_name=_("Institution"))

    objects = netfields.NetManager()

    class Meta:
        ordering = ['network']
        verbose_name = ungettext_lazy("IPv4 Subnet", "IPv4 Subnets", 1)
        verbose_name_plural = ungettext_lazy("IPv4 Subnet", "IPv4 Subnets", 2)

    @classmethod
    def get_view_qs(cls, user):
        return cls.objects.filter(
            Q(private=False) | Q(institution__owners=user)).distinct('network')

    def __str__(self):
        return str(self.network)

    def can_edit(self, user):
        return self.institution.can_edit(user)
Beispiel #3
0
class IPAddress(models.Model):
    address = netfields.InetAddressField(primary_key=True)
    ptr = models.ForeignKey('DomainName', null=True, blank=True)

    class Meta:
        app_label = 'admtooCore'
        verbose_name_plural = 'IP Addresses'

    def __str__(self):
        return str(self.address)
Beispiel #4
0
class Vlan(models.Model):
    vlan_id = models.IntegerField(primary_key=True)
    name = models.CharField(max_length=64, null=False)
    ip_block = netfields.CidrAddressField(unique=True, null=False)
    gateway = netfields.InetAddressField(unique=True, null=False)

    class Meta:
        app_label = 'admtooCore'

    def __str__(self):
        return str(self.name)
Beispiel #5
0
class ServerInetAttribute(ServerAttribute):
    attribute = models.ForeignKey(
        Attribute,
        db_index=False,
        on_delete=models.CASCADE,
        limit_choices_to=dict(type='inet'),
    )
    value = netfields.InetAddressField()

    class Meta:
        app_label = 'serverdb'
        db_table = 'server_inet_attribute'
        unique_together = [['server', 'attribute', 'value']]
        index_together = [['attribute', 'value']]
Beispiel #6
0
class TunnelEndpoint(models.Model):
    override_internal_ipv4 = netfields.InetAddressField(
        blank=True,
        null=True,
        verbose_name=_("Override internal IPv4 address"))
    dynamic_ipv4 = models.BooleanField(default=False,
                                       verbose_name=_("Dynamic IPv4 address"))

    host = models.ForeignKey(Host,
                             models.CASCADE,
                             related_name='tunnel_endpoints',
                             verbose_name=_("Host"))

    objects = netfields.NetManager()

    @property
    def tunnel(self):
        if hasattr(self, 'tunnel1'):
            return self.tunnel1
        if hasattr(self, 'tunnel2'):
            return self.tunnel2
        return None

    @property
    def autonomous_system(self):
        return self.host.autonomous_system

    @property
    def institution(self):
        return self.autonomous_system.institution

    @property
    def internal_ipv4(self):
        return self.override_internal_ipv4 or self.host.tunnel_ipv4

    @property
    def has_geo(self):
        return self.autonomous_system.has_geo

    def can_edit(self, user):
        return self.host.can_edit(user)

    def is_config_complete(self):
        return False
Beispiel #7
0
class ServerInetAttribute(ServerAttribute):
    attribute = models.ForeignKey(
        Attribute,
        db_index=False,
        on_delete=models.CASCADE,
        limit_choices_to=dict(type='inet'),
    )
    value = netfields.InetAddressField()

    class Meta:
        app_label = 'serverdb'
        db_table = 'server_inet_attribute'
        unique_together = [['server', 'attribute', 'value']]
        index_together = [['attribute', 'value']]

    def clean(self):
        super(ServerAttribute, self).clean()

        if type(self.value) not in [IPv4Interface, IPv6Interface]:
            self.value = inet_to_python(self.value)

        # Get the ip_addr_type of the servertype
        ip_addr_type = self.server.servertype.ip_addr_type

        if ip_addr_type == 'null':
            # A Servertype with ip_addr_type "null" and attributes of type
            # inet must be denied per configuration. This is just a safety net
            # in case e.g. somebody creates them programmatically.
            raise ValidationError(_('%(attribute_id)s must be null'),
                                  code='invalid value',
                                  params={'attribute_id': self.attribute_id})
        elif ip_addr_type == 'host':
            is_ip_address(self.value)
            is_unique_ip(self.value, self.server.server_id)
        elif ip_addr_type == 'loadbalancer':
            is_ip_address(self.value)
        elif ip_addr_type == 'network':
            is_network(self.value)
            network_overlaps(self.value, self.server.servertype_id,
                             self.server.server_id)
Beispiel #8
0
class Server(models.Model):
    """Servers are the main objects of the system.  They are stored in
    entity-attribute-value schema.  There are multiple models to store
    the attribute values of the servers by different data types.
    """
    objects = netfields.NetManager()

    server_id = models.AutoField(primary_key=True)
    hostname = models.CharField(max_length=64,
                                unique=True,
                                validators=HOSTNAME_VALIDATORS)
    intern_ip = netfields.InetAddressField(null=True, blank=True)
    servertype = models.ForeignKey(Servertype, on_delete=models.PROTECT)

    class Meta:
        app_label = 'serverdb'
        db_table = 'server'

    def __str__(self):
        return self.hostname

    def get_supernet(self, servertype):
        return Server.objects.get(
            servertype=servertype,
            intern_ip__net_contains_or_equals=self.intern_ip,
        )

    def clean(self, *args, **kwargs):
        super(Server, self).clean(*args, **kwargs)
        if self.servertype.ip_addr_type == 'null':
            if self.intern_ip is not None:
                raise ValidationError('IP address must be null.')
        else:
            if self.intern_ip is None:
                raise ValidationError('IP address must not be null.')

            if self.servertype.ip_addr_type == 'network':
                self._validate_network_intern_ip()
            else:
                self._validate_host_intern_ip()

    def _validate_host_intern_ip(self):
        if self.intern_ip.max_prefixlen != self.netmask_len():
            raise ValidationError('Netmask length must be {0}.'.format(
                self.intern_ip.max_prefixlen))

        # Check for other server with overlapping addresses
        for server in Server.objects.filter(
                intern_ip__net_overlaps=self.intern_ip).exclude(
                    server_id=self.server_id):
            if server.servertype.ip_addr_type == 'host':
                raise ValidationError(
                    'IP address already taken by the host "{0}".'.format(
                        server.hostname))

    def _validate_network_intern_ip(self):
        try:
            ip_network(str(self.intern_ip))
        except ValueError as error:
            raise ValidationError(str(error))

        # Check for other server with overlapping addresses
        for server in Server.objects.filter(
                intern_ip__net_overlaps=self.intern_ip).exclude(
                    server_id=self.server_id):
            if self.servertype == server.servertype:
                raise ValidationError(
                    'IP address overlaps with "{0}" in the same '
                    'servertype.'.format(server.hostname))

    def netmask_len(self):
        return self.intern_ip.network.prefixlen

    def get_attributes(self, attribute):
        model = ServerAttribute.get_model(attribute.type)
        return model.objects.filter(server=self, attribute=attribute)

    def add_attribute(self, attribute, value):
        model = ServerAttribute.get_model(attribute.type)
        if model is ServerBooleanAttribute and not value:
            return
        server_attribute = model(server=self, attribute=attribute)
        server_attribute.save_value(value)
Beispiel #9
0
class Server(models.Model):
    """Servers are the main objects of the system.  They are stored in
    entity-attribute-value schema.  There are multiple models to store
    the attribute values of the servers by different data types.
    """
    objects = netfields.NetManager()

    server_id = models.AutoField(primary_key=True)
    hostname = models.CharField(max_length=254,
                                unique=True,
                                validators=HOSTNAME_VALIDATORS)
    intern_ip = netfields.InetAddressField(null=True, blank=True)
    servertype = models.ForeignKey(Servertype, on_delete=models.PROTECT)

    class Meta:
        app_label = 'serverdb'
        db_table = 'server'

    def __str__(self):
        return self.hostname

    def get_supernet(self, servertype):
        return Server.objects.get(
            servertype=servertype,
            intern_ip__net_contains_or_equals=self.intern_ip,
        )

    def clean(self):
        super(Server, self).clean()

        ip_addr_type = self.servertype.ip_addr_type
        if ip_addr_type == 'null':
            if self.intern_ip is not None:
                raise ValidationError(_('intern_ip must be null'),
                                      code='invalid value')
        else:
            # This is special to intern_ip for inet attributes this is covered
            # by making them required.
            if self.intern_ip is None:
                raise ValidationError(_('intern_ip must not be null'),
                                      code='missing value')

            # TODO: This logic is duplicated to the ServerInetAttribute clean
            #       method but can be removed when we remove the special
            #       intern_ip.
            if type(self.intern_ip) not in [IPv4Interface, IPv6Interface]:
                self.intern_ip = inet_to_python(self.intern_ip)

            if ip_addr_type == 'host':
                is_ip_address(self.intern_ip)
                is_unique_ip(self.intern_ip, self.server_id)
            elif ip_addr_type == 'loadbalancer':
                is_ip_address(self.intern_ip)
            elif ip_addr_type == 'network':
                is_network(self.intern_ip)
                network_overlaps(self.intern_ip, self.servertype.servertype_id,
                                 self.server_id)

    def get_attributes(self, attribute):
        model = ServerAttribute.get_model(attribute.type)
        return model.objects.filter(server=self, attribute=attribute)

    def add_attribute(self, attribute, value):
        model = ServerAttribute.get_model(attribute.type)
        if model is ServerBooleanAttribute and not value:
            return
        server_attribute = model(server=self, attribute=attribute)
        server_attribute.save_value(value)