예제 #1
0
    def _iprange_to_glob(lb, ub):
        #   Internal function to process individual IP globs.
        t1 = [int(_) for _ in str(lb).split('.')]
        t2 = [int(_) for _ in str(ub).split('.')]

        tokens = []

        seen_hyphen = False
        seen_asterisk = False

        for i in range(4):
            if t1[i] == t2[i]:
                #   A normal octet.
                tokens.append(str(t1[i]))
            elif (t1[i] == 0) and (t2[i] == 255):
                #   An asterisk octet.
                tokens.append('*')
                seen_asterisk = True
            else:
                #   Create a hyphenated octet - only one allowed per IP glob.
                if not seen_asterisk:
                    if not seen_hyphen:
                        tokens.append('%s-%s' % (t1[i], t2[i]))
                        seen_hyphen = True
                    else:
                        raise AddrConversionError(
                            'only 1 hyphenated octet per IP glob allowed!')
                else:
                    raise AddrConversionError(
                        "asterisks are not allowed before hyphenated octets!")

        return '.'.join(tokens)
예제 #2
0
def cidr_to_glob(cidr):
    """
    A function that accepts an IP subnet in a glob-style format and returns
    a list of CIDR subnets that exactly matches the specified glob.

    :param cidr: an IP object CIDR subnet.

    :return: a list of one or more IP addresses and subnets.
    """
    ip = IPNetwork(cidr)
    globs = iprange_to_globs(ip[0], ip[-1])
    if len(globs) != 1:
        #   There should only ever be a one to one mapping between a CIDR and
        #   an IP glob range.
        raise AddrConversionError('bad CIDR to IP glob conversion!')
    return globs[0]
예제 #3
0
def iprange_to_globs(start, end):
    """
    A function that accepts an arbitrary start and end IP address or subnet
    and returns one or more glob-style IP ranges.

    :param start: the start IP address or subnet.

    :param end: the end IP address or subnet.

    :return: a list containing one or more IP globs.
    """
    start = IPAddress(start)
    end = IPAddress(end)

    if start.version != 4 and end.version != 4:
        raise AddrConversionError('IP glob ranges only support IPv4!')

    def _iprange_to_glob(lb, ub):
        #   Internal function to process individual IP globs.
        t1 = [int(_) for _ in str(lb).split('.')]
        t2 = [int(_) for _ in str(ub).split('.')]

        tokens = []

        seen_hyphen = False
        seen_asterisk = False

        for i in range(4):
            if t1[i] == t2[i]:
                #   A normal octet.
                tokens.append(str(t1[i]))
            elif (t1[i] == 0) and (t2[i] == 255):
                #   An asterisk octet.
                tokens.append('*')
                seen_asterisk = True
            else:
                #   Create a hyphenated octet - only one allowed per IP glob.
                if not seen_asterisk:
                    if not seen_hyphen:
                        tokens.append('%s-%s' % (t1[i], t2[i]))
                        seen_hyphen = True
                    else:
                        raise AddrConversionError(
                            'only 1 hyphenated octet per IP glob allowed!')
                else:
                    raise AddrConversionError(
                        "asterisks are not allowed before hyphenated octets!")

        return '.'.join(tokens)

    globs = []

    try:
        #   IP range can be represented by a single glob.
        ipglob = _iprange_to_glob(start, end)
        if not valid_glob(ipglob):
            #TODO: this is a workaround, it is produces non-optimal but valid
            #TODO: glob conversions. Fix inner function so that is always
            #TODO: produces a valid glob.
            raise AddrConversionError('invalid ip glob created')
        globs.append(ipglob)
    except AddrConversionError:
        #   Break IP range up into CIDRs before conversion to globs.
        #
        #TODO: this is still not completely optimised but is good enough
        #TODO: for the moment.
        #
        for cidr in iprange_to_cidrs(start, end):
            ipglob = _iprange_to_glob(cidr[0], cidr[-1])
            globs.append(ipglob)

    return globs