Example #1
0
    def get_vrf_prefix(self, request, vrf_id, afi, prefix):
        vrf = self.get_object_or_404(VRF, id=int(vrf_id))

        if not prefix:
            prefix = VRF.IPv4_ROOT if afi == "4" else VRF.IPv6_ROOT
        if (afi == "4" and (not is_ipv4_prefix(prefix) or not vrf.afi_ipv4)) or (
            afi == "6" and (not is_ipv6_prefix(prefix) or not vrf.afi_ipv6)
        ):
            return self.response_forbidden("Invalid prefix")
        prefix = self.get_object_or_404(Prefix, vrf=vrf, afi=afi, prefix=prefix)
        return self.prefix_contents(request, prefix=prefix)
Example #2
0
 def view_vrf_index(self, request, vrf_id, afi, prefix):
     """
     Display VRF Index
     """
     # Validate
     vrf = self.get_object_or_404(VRF, id=int(vrf_id))
     if (afi == "4" and (not is_ipv4_prefix(prefix)) or not vrf.afi_ipv4) or (
         afi == "6" and (not is_ipv6_prefix(prefix) or not vrf.afi_ipv6)
     ):
         return self.response_forbidden("Invalid prefix")
     prefix = self.get_object_or_404(Prefix, vrf=vrf, afi=afi, prefix=prefix)
     # Get prefix path
     path = []
     p = prefix.parent
     while p:
         path = [p] + path
         p = p.parent
     # List of nested prefixes
     # @todo: prefetch_related
     prefixes = list(prefix.children_set.select_related().order_by("prefix"))
     # Bulk utilization
     Prefix.update_prefixes_usage(prefixes)
     # Get permissions
     user = request.user
     can_view = prefix.can_view(user)
     can_change = prefix.can_change(user)
     can_bind_vc = can_change and Permission.has_perm(user, "ip:ipam:bind_vc")
     can_change_maintainers = user.is_superuser
     can_add_prefix = can_change
     can_add_address = can_change and len(prefixes) == 0
     can_edit_special = prefix.effective_prefix_special_address == "I"
     # Bookmarks
     has_bookmark = prefix.has_bookmark(user)
     bookmarks = PrefixBookmark.user_bookmarks(user, vrf=vrf, afi=afi)
     s_bookmarks = set(b.prefix for b in bookmarks)
     # Add free prefixes
     free_prefixes = list(IP.prefix(prefix.prefix).iter_free([pp.prefix for pp in prefixes]))
     l_prefixes = sorted(
         (
             [(True, IP.prefix(pp.prefix), pp, pp.prefix in s_bookmarks) for pp in prefixes]
             + [(False, pp, None, None) for pp in free_prefixes]
         ),
         key=lambda x: x[1],
     )
     # List of nested addresses
     # @todo: prefetch_related
     addresses = list(prefix.address_set.select_related().order_by("address"))
     # Prepare block info
     prefix_info = [("Network", prefix.prefix)]
     if afi == "4":
         prefix_info += [
             ("Broadcast", prefix.broadcast),
             ("Netmask", prefix.netmask),
             ("Widlcard", prefix.wildcard),
             ("Size", prefix.size),
             ("Usage", prefix.usage_percent),
             ("Usage Address", prefix.address_usage_percent),
         ]
     if addresses:
         prefix_info += [("Used addresses", len(addresses))]
         if afi == "4":
             free = prefix.size - len(addresses)
             prefix_info += [("Free addresses", free - 2 if free >= 2 else free)]
     # Prefix discovery
     dmap = {"E": "Enabled", "D": "Disabled"}
     if prefix.prefix_discovery_policy == "P":
         t = "Profile (%s)" % dmap[prefix.profile.prefix_discovery_policy]
     else:
         t = dmap[prefix.prefix_discovery_policy]
     prefix_info += [("Prefix Discovery", t)]
     # Address discovery
     if prefix.address_discovery_policy == "P":
         t = "Profile (%s)" % dmap[prefix.profile.address_discovery_policy]
     else:
         t = dmap[prefix.address_discovery_policy]
     prefix_info += [("Address Discovery", t)]
     # Source
     prefix_info += [
         (
             "Source",
             {"M": "Manual", "i": "Interface", "w": "Whois Route", "n": "Neighbor"}.get(
                 prefix.source, "-"
             ),
         )
     ]
     #
     # Add custom fields
     for f in CustomField.table_fields("ip_prefix"):
         v = getattr(prefix, f.name)
         prefix_info += [(f.label, v if v is not None else "")]
     # Ranges
     ranges = []
     rs = []
     max_slots = 0
     r_spots = []
     if addresses:
         # Assign ranges colors
         ranges = list(prefix.address_ranges)
         for r, c in zip(ranges, get_colors(len(ranges))):
             r.color = c
             # Schedule ranges
         r_changes = {}  # Address -> (set of entering ranges, set of leaving ranges)
         for r in ranges:
             if r.from_address not in r_changes:
                 r_changes[r.from_address] = (set(), set())
             if r.to_address not in r_changes:
                 r_changes[r.to_address] = (set(), set())
             r_changes[r.from_address][0].add(r)
             r_changes[r.to_address][1].add(r)
             # <!>
             n = (IP.prefix(r.to_address) + 1).address
             if n not in r_changes:
                 r_changes[n] = (set(), set())
         r_spots = list(six.iterkeys(r_changes))
         # Allocate slots
         used_slots = set()
         free_slots = set()
         r_slots = {}  # Range -> slot
         max_slots = 0
         rs = sorted(
             ([IP.prefix(i), d, []] for i, d in six.iteritems(r_changes)), key=itemgetter(0)
         )
         for address, d, x in rs:
             entering, leaving = d
             for r in entering:
                 if not free_slots:
                     free_slots.add(max_slots)
                     max_slots += 1
                 s = free_slots.pop()
                 used_slots.add(s)
                 r_slots[r] = s
             for r in leaving:
                 s = r_slots[r]
                 used_slots.remove(s)
                 free_slots.add(s)
         # Assign ranges to slots
         slots = [None] * max_slots
         for r in rs:
             address, [entering, leaving], _ = r
             for e in entering:
                 slots[r_slots[e]] = e
             r[2] = slots[:]
             for l in leaving:
                 slots[r_slots[l]] = None
         # Assign slots to addresses
         c = [None] * max_slots
         rrs = rs[:]
         cr = rrs.pop(0) if rrs else None
         for a in addresses:
             address = IP.prefix(a.address)
             while cr and address >= cr[0]:
                 c = cr[2]
                 if rrs:
                     cr = rrs.pop(0)
                 else:
                     break
             a.slots = c
     # Address spot
     if can_add_address:
         special_addr = IP.prefix(prefix.prefix).special_addresses
         c = [None] * max_slots
         rrs = rs[:]
         if rrs:
             cr = rrs.pop(0)
         else:
             cr = None
         spot = []
         for a in self.get_prefix_spot(prefix, extra=r_spots):
             if cr and a is not None and a == cr[0]:
                 c = [None if cc is None else cc.id for cc in cr[2]]
                 if rrs:
                     cr = rrs.pop(0)
             spot += [(None if a is None else a.address, c, a in special_addr)]
         spot = ujson.dumps(spot)
     else:
         spot = None
     can_ping = spot is not None and len([a for a in addresses if a.managed_object]) > 0
     # Build custom styles
     styles = {}
     if prefix.profile.style:
         styles[prefix.profile.style.css_class_name] = prefix.profile.style.css
     for p in prefixes:
         if p.profile.style and p.profile.style.css_class_name not in styles:
             styles[p.profile.style.css_class_name] = p.profile.style.css
     for a in addresses:
         if a.profile.style and a.profile.style.css_class_name not in styles:
             styles[a.profile.style.css_class_name] = a.profile.style.css
     styles = "\n".join(six.itervalues(styles))
     # Render
     return self.render(
         request,
         "vrf_index.html.j2",
         user=request.user,
         vrf=vrf,
         prefix=prefix,
         path=path,
         prefixes=prefixes,
         addresses=addresses,
         prefix_info=prefix_info,
         display_empty_message=not addresses and not prefixes,
         can_view=can_view,
         can_change=can_change,
         can_bind_vc=can_bind_vc,
         can_change_maintainers=can_change_maintainers,
         can_add_prefix=can_add_prefix,
         can_add_address=can_add_address,
         can_edit_special=can_edit_special,
         has_bookmark=has_bookmark,
         bookmarks=bookmarks,
         spot=spot,
         can_ping=can_ping,
         styles=styles,
         ranges=ranges,
         max_slots=max_slots,
         l_prefixes=l_prefixes,
     )
Example #3
0
def test_is_ipv4_prefix(raw, expected):
    assert is_ipv4_prefix(raw) is expected