pvl/dns/labels.py
author Tero Marttila <terom@paivola.fi>
Tue, 10 Mar 2015 00:30:31 +0200
changeset 741 569d13a07ff5
parent 638 92a78c787fe9
permissions -rw-r--r--
version 0.9.0-dev
def join (*parts) :
    """
        Join a domain name from labels.

        >>> print join('foo')
        foo
        >>> print join('foo', 'example.com.')
        foo.example.com.
        >>> print join('foo', 'bar', 'example.com.')
        foo.bar.example.com.
        >>> print join('example.net.', 'example.com')
        example.net.
    """

    out = []

    for part in parts:
        out.append(part)

        if part.endswith('.'):
            break
    
    return '.'.join(out)

def fqdn (*parts) :
    """
        Return an FQND from parts, ending in .
    """

    fqdn = join(*parts)

    # we may be given an fqdn in parts
    if not fqdn.endswith('.') :
        fqdn += '.'
    
    return fqdn

def contains (origin, fqdn):
    """
        Determine if the given FQDN is within the given origin.
    """

    return origin == '.' or fqdn.endswith('.' + origin)

def split (origin, fqdn):
    """
        Determine the relative label from the given zone origin to the given host fqnd.
    """

    if origin == '.':
        return fqdn[:-1]

    elif fqdn.endswith('.' + origin) :
        # strip
        return fqdn[:(len(fqdn) - len(origin) - 1)]
    else:
        raise ValueError("{fqdn} outside of zone {origin}".format(fqdn=fqdn, origin=origin))

def relative (origin, domain, name) :
    """
        relative relative label @origin for name@domain

        Raises ValueError if name is outside of origin

        >>> print relative(None, None, 'fqdn')
        fqdn.
        >>> print relative(None, 'domain', 'host')
        host.domain.
        >>> print relative('origin', 'domain', 'host')
        Traceback (most recent call last):
            ...
        ValueError: host: domain domain out of zone origin.
        >>> print relative('origin', 'origin', 'host')
        host
        >>> print relative('origin', 'domain.origin', 'host')
        host.domain
        >>> print relative('origin', 'domainorigin', 'host')
        Traceback (most recent call last):
            ...
        ValueError: host: domain domainorigin out of zone origin.
        >>> print relative('origin', None, 'host.domain')
        Traceback (most recent call last):
            ...
        ValueError: host.domain: fqdn host.domain. out of zone origin.
        >>> print relative('.', 'domain', 'host')
        host.domain
    """

    if origin:
        origin = fqdn(origin)
    
    if domain:
        host_fqdn = fqdn(name, domain)
    else:
        host_fqdn = fqdn(name)


    if not origin:
        return host_fqdn

    elif domain == origin:
         return name

    elif contains(origin, host_fqdn):
        return split(origin, host_fqdn)

    elif domain:
        raise ValueError("{name}: domain {domain} out of zone {origin}".format(name=name, domain=domain, origin=origin))

    else:
        raise ValueError("{name}: fqdn {fqdn} out of zone {origin}".format(name=name, fqdn=host_fqdn, origin=origin))