Esempio n. 1
0
def get_static_intr_q(vrf):
    from cyder.cydhcp.utils import start_end_filter, four_to_two
    from cyder.cydhcp.constants import STATIC

    q_list = list()
    for network_ in vrf.network_set.all():
        for range_ in network_.range_set.filter(range_type=STATIC):
            two = four_to_two(range_.start_upper, range_.start_lower,
                              range_.end_upper, range_.end_lower)
            q_list += [start_end_filter(two[0], two[1], range_.ip_type)[2]]

    q = reduce(lambda x, y: x | y, q_list, Q())
    return q or None
Esempio n. 2
0
def build_range_qsets(range_):
    try:
        start, end = range_.split(',')
    except ValueError:
        raise BadDirective("Specify a range using the format: start,end")
    if start.find(':') > -1:
        ip_type = '6'
    if end.find('.') > -1:
        ip_type = '4'
    try:
        istart, iend, ipf_q = start_end_filter(start, end, ip_type)
    except (ValidationError, ipaddr.AddressValueError), e:
        raise BadDirective(str(e))
Esempio n. 3
0
def build_range_qsets(range_):
    try:
        start, end = range_.split(',')
    except ValueError:
        raise BadDirective("Specify a range using the format: start,end")
    if start.find(':') > -1:
        ip_type = '6'
    if end.find('.') > -1:
        ip_type = '4'
    try:
        istart, iend, ipf_q = start_end_filter(start, end, ip_type)
    except (ValidationError, ipaddr.AddressValueError), e:
        raise BadDirective(str(e))
Esempio n. 4
0
def get_static_intr_q(vrf):
    from cyder.cydhcp.utils import start_end_filter, four_to_two
    from cyder.cydhcp.constants import STATIC

    q_list = list()
    for network_ in vrf.network_set.all():
        for range_ in network_.range_set.filter(range_type=STATIC):
            two = four_to_two(range_.start_upper, range_.start_lower,
                              range_.end_upper, range_.end_lower)
            q_list += [start_end_filter(two[0], two[1], range_.ip_type)[2]]

    q = reduce(lambda x, y: x | y, q_list, Q())
    return q or None
Esempio n. 5
0
def range_usage(start, end, ip_type):
    """
    Takes a start and end address as integers and returns a range usage list
    containing tuples of the available ips and lists of contiguously used ip
    addresses.
    """
    ip_start, ip_end, ipf_q = start_end_filter(start, end, ip_type)
    record_ip = lambda x: two_to_one(x.ip_upper, x.ip_lower)
    taken_ips = sorted(chain(
        AddressRecord.objects.filter(ipf_q),
        PTR.objects.filter(ipf_q),
        StaticInterface.objects.filter(ipf_q)),
        key=record_ip)
    contiguous_ip_list, total_used = contiguous_ips(taken_ips)
    total_ips = (end - start) + 1
    range_usage_list = []
    free_range_start = ip_start
    for filled_range in contiguous_ip_list:
        # if the first address in the current contiguous range is greater
        # than the first free address add that free range of ips to the range
        # usage list
        if free_range_start < filled_range[0][0]:
            range_usage_list.append(
                ("Free",
                 free_range_start, filled_range[0][0] - 1,
                 json.dumps({"ip_str": str(free_range_start),
                             "ip_type": ip_type})))
        # the new free range may start with the next address after the end of
        # the current filled range
        free_range_start = filled_range[-1][0] + 1
        range_usage_list.append(filled_range)
    # handle the case where there is an additional free range after the final
    # filled range
    if free_range_start < ip_end:
        range_usage_list.append(
            ("Free",
             free_range_start, ip_end,
             json.dumps({"ip_str": str(free_range_start),
                         "ip_type": ip_type})))

    return range_usage_list, int((float(total_used) / total_ips) * 100)
Esempio n. 6
0
def range_usage(start, end, ip_type):
    """
    Takes a start and end address as integers and returns a range usage list
    containing tuples of the available ips and lists of contiguously used ip
    addresses.
    """
    ip_start, ip_end, ipf_q = start_end_filter(start, end, ip_type)
    record_ip = lambda x: two_to_one(x.ip_upper, x.ip_lower)
    taken_ips = sorted(chain(AddressRecord.objects.filter(ipf_q),
                             PTR.objects.filter(ipf_q),
                             StaticInterface.objects.filter(ipf_q)),
                       key=record_ip)
    contiguous_ip_list, total_used = contiguous_ips(taken_ips)
    total_ips = (end - start) + 1
    range_usage_list = []
    free_range_start = ip_start
    for filled_range in contiguous_ip_list:
        # if the first address in the current contiguous range is greater
        # than the first free address add that free range of ips to the range
        # usage list
        if free_range_start < filled_range[0][0]:
            range_usage_list.append(
                ("Free", free_range_start, filled_range[0][0] - 1,
                 json.dumps({
                     "ip_str": str(free_range_start),
                     "ip_type": ip_type
                 })))
        # the new free range may start with the next address after the end of
        # the current filled range
        free_range_start = filled_range[-1][0] + 1
        range_usage_list.append(filled_range)
    # handle the case where there is an additional free range after the final
    # filled range
    if free_range_start < ip_end:
        range_usage_list.append(("Free", free_range_start, ip_end,
                                 json.dumps({
                                     "ip_str": str(free_range_start),
                                     "ip_type": ip_type
                                 })))

    return range_usage_list, int((float(total_used) / total_ips) * 100)
Esempio n. 7
0
def range_usage(ip_start, ip_end, ip_type, get_objects=True):
    """Returns ip usage statistics about the range starting at ip_start and
    ending at ip_end.

    Given an inclusive contiguous range of positive integers (IP addresses)
    between `a` and `b` and a list of lists where each sublist contains
    integers (IP addresses) that are within the range, how many integers
    between `a` and `b` do not exist in any of the lists; this is what this
    function calculates.

    For example:

    ```
        Start = 0
        End = 9
        Lists = [[1,2,3], [2,3,4]]
    ```

    The integers that do not occur in `Lists` are `0`, `5`, `6`, `7`, `8`, and
    `9`, so there are 6 integers that do not exist in Lists that satisfy `Start
    <= n <= End`.

    Start can be small and End can be very large (the range may be
    larger than you would want to itterate over). Due to the size of IPv6
    ranges, we should not use recursion.

    There are three types of objects (that we care about) that have IP's
    associated with them: AddressRecord, PTR, StaticInterface. Because we get
    objects back as Queryset's that are hard to merge, we have to do this
    algorithm while retaining all three lists. The gist of the algoritm is as
    follows::

        # Assume the lists are sorted
        while lists:
            note the start number (ip)
            lowest =: of the things in list (PTR, A, INTR), find the lowest
            difference =: start - lowest.ip
            total_free +=: difference
            start =: lowest.ip + 1

            if any PTR, A, or INTR has the same IP as lowest:
                remove those items from their lists

    """
    StaticInterface = get_model('cyder', 'staticinterface')
    PTR = get_model('cyder', 'ptr')
    AddressRecord = get_model('cyder', 'addressrecord')
    istart, iend, ipf_q = start_end_filter(ip_start, ip_end, ip_type)

    def get_ip(rec):
        return two_to_one(rec.ip_upper, rec.ip_lower)

    lists = [
        sorted(AddressRecord.objects.filter(ipf_q), key=get_ip),
        sorted(PTR.objects.filter(ipf_q), key=get_ip),
        sorted(StaticInterface.objects.filter(ipf_q), key=get_ip)
    ]

    free_ranges = []

    def cmp_ip_upper_lower(a, b):
        if a.ip_upper > b.ip_upper:
            return a
        elif a.ip_upper < b.ip_upper:
            return b
        elif a.ip_lower > b.ip_lower:
            return a
        elif a.ip_lower < b.ip_lower:
            return b
        else:
            return a  # redundant, maybe?

    unused = 0
    minimum_i = 0
    rel_start = int(istart)
    end = int(iend)

    # This is translated directly from a recursive implementation.
    while True:
        if rel_start > end:
            break
        lists = [l for l in lists if l]
        if not lists:
            free_ranges.append((rel_start, end))
            unused += end - rel_start + 1
            break

        min_list = min(lists,
                       key=lambda x: two_to_one(x[0].ip_upper, x[0].ip_lower))

        minimum = min_list[0]
        minimum_i = two_to_one(minimum.ip_upper, minimum.ip_lower)
        unused += minimum_i - rel_start
        if minimum_i != rel_start:
            free_ranges.append((rel_start, minimum_i - 1))

        for l in lists:
            while (l and l[0].ip_upper == minimum.ip_upper
                   and l[0].ip_lower == minimum.ip_lower):
                l.pop(0)

        rel_start = minimum_i + 1

    return {
        'unused': unused,
        'used': int(iend) - int(istart) - unused + 1,
        'free_ranges': free_ranges,
    }
Esempio n. 8
0
def range_usage(ip_start, ip_end, ip_type, get_objects=True):
    """Returns ip usage statistics about the range starting at ip_start and
    ending at ip_end.

    Given an inclusive contiguous range of positive integers (IP addresses)
    between `a` and `b` and a list of lists where each sublist contains
    integers (IP addresses) that are within the range, how many integers
    between `a` and `b` do not exist in any of the lists; this is what this
    function calculates.

    For example:

    ```
        Start = 0
        End = 9
        Lists = [[1,2,3], [2,3,4]]
    ```

    The integers that do not occur in `Lists` are `0`, `5`, `6`, `7`, `8`, and
    `9`, so there are 6 integers that do not exist in Lists that satisfy `Start
    <= n <= End`.

    Start can be small and End can be very large (the range may be
    larger than you would want to itterate over). Due to the size of IPv6
    ranges, we should not use recursion.

    There are three types of objects (that we care about) that have IP's
    associated with them: AddressRecord, PTR, StaticInterface. Because we get
    objects back as Queryset's that are hard to merge, we have to do this
    algorithm while retaining all three lists. The gist of the algoritm is as
    follows::

        # Assume the lists are sorted
        while lists:
            note the start number (ip)
            lowest =: of the things in list (PTR, A, INTR), find the lowest
            difference =: start - lowest.ip
            total_free +=: difference
            start =: lowest.ip + 1

            if any PTR, A, or INTR has the same IP as lowest:
                remove those items from their lists

    """
    istart, iend, ipf_q = start_end_filter(ip_start, ip_end, ip_type)

    def get_ip(rec):
        return two_to_one(rec.ip_upper, rec.ip_lower)

    lists = [sorted(AddressRecord.objects.filter(ipf_q), key=get_ip),
             sorted(PTR.objects.filter(ipf_q), key=get_ip),
             sorted(StaticInterface.objects.filter(ipf_q), key=get_ip)]

    free_ranges = []

    def cmp_ip_upper_lower(a, b):
        if a.ip_upper > b.ip_upper:
            return a
        elif a.ip_upper < b.ip_upper:
            return b
        elif a.ip_lower > b.ip_lower:
            return a
        elif a.ip_lower < b.ip_lower:
            return b
        else:
            return a  # redundant, maybe?

    unused = 0
    minimum_i = 0
    rel_start = int(istart)
    end = int(iend)

    # This is translated directly from a recursive implementation.
    while True:
        if rel_start > end:
            break
        lists = [l for l in lists if l]
        if not lists:
            free_ranges.append((rel_start, end))
            unused += end - rel_start + 1
            break

        min_list = min(lists, key=lambda x: two_to_one(x[0].ip_upper,
                       x[0].ip_lower))

        minimum = min_list[0]
        minimum_i = two_to_one(minimum.ip_upper, minimum.ip_lower)
        unused += minimum_i - rel_start
        if minimum_i != rel_start:
            free_ranges.append((rel_start, minimum_i - 1))

        for l in lists:
            while (l and l[0].ip_upper == minimum.ip_upper and
                   l[0].ip_lower == minimum.ip_lower):
                l.pop(0)

        rel_start = minimum_i + 1

    return {
        'unused': unused,
        'used': int(iend) - int(istart) - unused + 1,
        'free_ranges': free_ranges,
    }