Exemplo n.º 1
0
def range_detail(request, pk):
    mrange = get_object_or_404(Range, pk=pk)

    allow = None
    if mrange.allow == ALLOW_OPTION_VRF:
        try:
            allow = [Vrf.objects.get(network=mrange.network)]
        except ObjectDoesNotExist:
            allow = []
    elif mrange.allow == ALLOW_OPTION_KNOWN:
        allow = [ALLOW_OPTION_KNOWN]
    elif mrange.allow == ALLOW_OPTION_LEGACY:
        allow = [ctnr for ctnr in Ctnr.objects.filter(ranges=mrange)]

    start_upper = mrange.start_upper
    start_lower = mrange.start_lower
    end_upper = mrange.end_upper
    end_lower = mrange.end_lower
    range_data, ip_usage_percent = range_usage(
        two_to_one(start_upper, start_lower),
        two_to_one(end_upper, end_lower),
        mrange.ip_type)
    return render(request, 'range/range_detail.html', {
        'obj': mrange,
        'obj_type': 'range',
        'ranges_table': tablefy((mrange,)),
        'range_data': make_paginator(request, range_data, 50),
        'attrs_table': tablefy(mrange.rangekeyvalue_set.all()),
        'allow_list': allow,
        'range_used': "{0}%".format(ip_usage_percent)
    })
Exemplo n.º 2
0
def range_detail(request, pk):
    mrange = get_object_or_404(Range, pk=pk)

    if mrange.allow == ALLOW_ANY:
        allow = ['Any client']
    elif mrange.allow == ALLOW_KNOWN:
        allow = ['Known clients']
    else:
        allow = []
        if mrange.allow == ALLOW_VRF:
            allow += map(str, Vrf.objects.filter(network=mrange.network))
        if mrange.allow == ALLOW_LEGACY:
            allow += map(str, Ctnr.objects.filter(ranges=mrange))

    allow.sort(key=lambda x: x.lower())

    range_type = mrange.range_type
    range_data = []
    ip_usage_percent = None
    dynamic_interfaces = []
    dynamic_interfaces_page_obj = None
    if range_type == 'st':
        start_upper = mrange.start_upper
        start_lower = mrange.start_lower
        end_upper = mrange.end_upper
        end_lower = mrange.end_lower
        range_data, ip_usage_percent = range_usage(
            two_to_one(start_upper, start_lower),
            two_to_one(end_upper, end_lower),
            mrange.ip_type)
    else:
        ip_usage_percent = mrange.range_usage
        DynamicInterface = get_model('cyder', 'dynamicinterface')
        dynamic_interfaces = DynamicInterface.objects.filter(range=mrange)
        dynamic_interfaces_page_obj = make_paginator(
            request, do_sort(request, dynamic_interfaces), 10)

    if ip_usage_percent:
        ip_usage_percent = "{0}%".format(ip_usage_percent)
    return render(request, 'range/range_detail.html', {
        'obj': mrange,
        'obj_type': 'range',
        'pretty_obj_type': mrange.pretty_type,
        'ranges_table': tablefy((mrange,), info=False, request=request),
        'range_data': make_paginator(request, range_data, 50),
        'range_type': range_type,
        'attrs_table': tablefy(mrange.rangeav_set.all(),
                               request=request),
        'allow_list': allow,
        'range_used': ip_usage_percent,
        'dynamic_intr_table': tablefy(dynamic_interfaces_page_obj, info=True,
                                      request=request),
        'page_obj': dynamic_interfaces_page_obj
    })
Exemplo n.º 3
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)
Exemplo n.º 4
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)
Exemplo n.º 5
0
 def get_ip(rec):
     return two_to_one(rec.ip_upper, rec.ip_lower)
Exemplo n.º 6
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,
    }
Exemplo n.º 7
0
 def get_ip(rec):
     return two_to_one(rec.ip_upper, rec.ip_lower)
Exemplo 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,
    }
Exemplo n.º 9
0
 def get_wrapped_ip(self):
     if self.ip_type == IP_TYPE_4:
         ip_klass = ipaddr.IPv4Address
     else:
         ip_klass = ipaddr.IPv6Address
     return ip_klass(two_to_one(self.ip_upper, self.ip_lower))
Exemplo n.º 10
0
 def get_wrapped_ip(self):
     if self.ip_type == IP_TYPE_4:
         ip_klass = ipaddr.IPv4Address
     else:
         ip_klass = ipaddr.IPv6Address
     return ip_klass(two_to_one(self.ip_upper, self.ip_lower))