<commit_before>from django.db import models
from django.core.exceptions import ValidationError, ObjectDoesNotExist

import mozdns
from mozdns.domain.models import Domain, _name_to_domain
from mozdns.models import MozdnsRecord
from mozdns.validation import validate_name, find_root_domain
from mozdns.search_utils import smart_fqdn_exists

import pdb

class CNAME(MozdnsRecord):
    """CNAMES can't point to an any other records. Said another way,
    CNAMES can't be at the samle level as any other record. This means
    that when you are creating a CNAME every other record type must be
    checked to make sure that the name about to be taken by the CNAME
    isn't taken by another record. Likewise, all other records must
    check that no CNAME exists with the same name before being created.

    >>> CNAME(label = label, domain = domain, target = target)

    """
    # TODO cite an RFC for that ^ (it's around somewhere)
    id = models.AutoField(primary_key=True)
    target = models.CharField(max_length=100, validators=[validate_name],
            help_text="CNAME Target")
    target_domain = models.ForeignKey(Domain, null=True,
                        related_name='target_domains', blank=True,
                        on_delete=models.SET_NULL)

    search_fields = ('fqdn', 'target')

    def details(self):
        return  (
                    ('FQDN', self.fqdn),
                    ('Record Type', 'CNAME'),
                    ('Target', self.target),
               )

    class Meta:
        db_table = 'cname'
        unique_together = ('domain', 'label', 'target')

    @classmethod
    def get_api_fields(cls):
        return super(CNAME, cls).get_api_fields() + ['target']

    def save(self, *args, **kwargs):
        # If label, and domain have not changed, don't mark our domain for
        # rebuilding.
        if self.pk:  # We need to exist in the db first.
            db_self = CNAME.objects.get(pk=self.pk)
            if db_self.label == self.label and db_self.domain == self.domain:
                kwargs['no_build'] = True
                 # Either nothing has changed or just target_domain. We want
                 # rebuild.
        super(CNAME, self).save(*args, **kwargs)

    def clean(self, *args, **kwargs):
        super(CNAME, self).clean(*args, **kwargs)
        super(CNAME, self).check_for_delegation()
        self.check_SOA_condition()
        self.target_domain = _name_to_domain(self.target)
        self.existing_node_check()

    def __str__(self):
        return "{0} CNAME {1}".format(self.fqdn, self.target)

    def check_SOA_condition(self):
        """We need to check if the domain is the root domain in a zone.
        If the domain is the root domain, it will have an soa, but the
        master domain will have no soa (or it will have a a different
        soa).
        """
        try:
            self.domain
        except ObjectDoesNotExist:
            return # Validation will fail eventually
        root_domain = find_root_domain(self.domain.soa)
        if root_domain is None:
            return
        if self.fqdn == root_domain.name:
            raise ValidationError("You cannot create a CNAME that points to a"
                                  "domain at the root of a zone.")
        return

    def existing_node_check(self):
        """Make sure no other nodes exist at the level of this CNAME.
<commit_msg>fixed spacing<commit_after>from django.db import models
from django.core.exceptions import ValidationError, ObjectDoesNotExist

import mozdns
from mozdns.domain.models import Domain, _name_to_domain
from mozdns.models import MozdnsRecord
from mozdns.validation import validate_name, find_root_domain
from mozdns.search_utils import smart_fqdn_exists

import pdb

class CNAME(MozdnsRecord):
    """CNAMES can't point to an any other records. Said another way,
    CNAMES can't be at the samle level as any other record. This means
    that when you are creating a CNAME every other record type must be
    checked to make sure that the name about to be taken by the CNAME
    isn't taken by another record. Likewise, all other records must
    check that no CNAME exists with the same name before being created.

    >>> CNAME(label = label, domain = domain, target = target)

    """
    # TODO cite an RFC for that ^ (it's around somewhere)
    id = models.AutoField(primary_key=True)
    target = models.CharField(max_length=100, validators=[validate_name],
            help_text="CNAME Target")
    target_domain = models.ForeignKey(Domain, null=True,
                        related_name='target_domains', blank=True,
                        on_delete=models.SET_NULL)

    search_fields = ('fqdn', 'target')

    def details(self):
        return  (
                    ('FQDN', self.fqdn),
                    ('Record Type', 'CNAME'),
                    ('Target', self.target),
               )

    class Meta:
        db_table = 'cname'
        unique_together = ('domain', 'label', 'target')

    @classmethod
    def get_api_fields(cls):
        return super(CNAME, cls).get_api_fields() + ['target']

    def save(self, *args, **kwargs):
        # If label, and domain have not changed, don't mark our domain for
        # rebuilding.
        if self.pk:  # We need to exist in the db first.
            db_self = CNAME.objects.get(pk=self.pk)
            if db_self.label == self.label and db_self.domain == self.domain:
                kwargs['no_build'] = True
                 # Either nothing has changed or just target_domain. We want
                 # rebuild.
        super(CNAME, self).save(*args, **kwargs)

    def clean(self, *args, **kwargs):
        super(CNAME, self).clean(*args, **kwargs)
        super(CNAME, self).check_for_delegation()
        self.check_SOA_condition()
        self.target_domain = _name_to_domain(self.target)
        self.existing_node_check()

    def __str__(self):
        return "{0} CNAME {1}".format(self.fqdn, self.target)

    def check_SOA_condition(self):
        """We need to check if the domain is the root domain in a zone.
        If the domain is the root domain, it will have an soa, but the
        master domain will have no soa (or it will have a a different
        soa).
        """
        try:
            self.domain
        except ObjectDoesNotExist:
            return # Validation will fail eventually
        root_domain = find_root_domain(self.domain.soa)
        if root_domain is None:
            return
        if self.fqdn == root_domain.name:
            raise ValidationError("You cannot create a CNAME that points to a "
                                  "domain at the root of a zone.")
        return

    def existing_node_check(self):
        """Make sure no other nodes exist at the level of this CNAME.

{'fraction_non_alphanumeric': 0.08584448037630457, 'fraction_numerical': 0.0014699397324709686, 'mean_word_length': 2.3633217993079585, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6237018', 'n_tokens_mistral': 1959, 'n_tokens_neox': 1889, 'n_words': 657}