def on_activate(self): # Initialize audit trail from noc.main.models.audittrail import AuditTrail AuditTrail.install() # Initialize site self.logger.info("Registering web applications") from noc.lib.app.site import site site.service = self site.autodiscover() # Install Custom fields CustomField.install_fields()
def get_data(self, vrf, afi, prefix, **kwargs): def get_row(p, level=0): s = "--" * level r = [s + p.prefix, p.state.name, smart_text(p.vc) if p.vc else ""] for f in cf: v = getattr(p, f.name) r += [v if v is not None else ""] r += [p.description, p] return r def get_info(prefix, level=0): data = [get_row(prefix, level)] for c in prefix.children_set.order_by("prefix"): data += get_info(c, level + 1) return data cf = CustomField.table_fields("ip_prefix") # Prepare columns columns = ["Prefix", "State", "VC"] for f in cf: columns += [f.label] columns += ["Description", TableColumn(_("Tags"), format="tags")] data = get_info(prefix) return self.from_dataset( title=_( "All allocated blocks in VRF %(vrf)s (IPv%(afi)s), %(prefix)s" % { "vrf": vrf.name, "afi": afi, "prefix": prefix.prefix }), columns=columns, data=data, enumerate=True, )
def get_data(self, vrf, afi, prefix, **kwargs): def get_row(p): r = [p.prefix, p.state.name, smart_text(p.vc) if p.vc else ""] for f in cf: v = getattr(p, f.name) r += [v if v is not None else ""] r += [p.description, p] return r cf = CustomField.table_fields("ip_prefix") cfn = {f.name: f for f in cf} # Prepare columns columns = ["Prefix", "State", "VC"] for f in cf: columns += [f.label] columns += ["Description", TableColumn(_("Tags"), format="tags")] # Prepare query q = Q() for k in kwargs: v = kwargs[k] if k in cfn and v is not None and v != "": q &= Q(**{str(k): v}) # return self.from_dataset( title=_( "Allocated blocks in VRF %(vrf)s (IPv%(afi)s), %(prefix)s" % {"vrf": vrf.name, "afi": afi, "prefix": prefix.prefix} ), columns=columns, data=[get_row(p) for p in prefix.children_set.filter(q).order_by("prefix")], enumerate=True, )
def get_data(self, request, **kwargs): def get_row(p): r = [p.vrf.name, p.prefix, p.state.name, unicode(p.asn), unicode(p.vc) if p.vc else ""] for f in cf: v = getattr(p, f.name) r += [v if v is not None else ""] r += [p.description, p] return r q = {} for k in kwargs: v = kwargs[k] if v: if k == "description": q[k + "__icontains"] = v else: q[k] = v columns = ["VRF", "Prefix", "State", "AS", "VC"] cf = CustomField.table_fields("ip_prefix") for f in cf: if f.type == "bool": columns += [TableColumn(f.label, format="bool")] else: columns += [f.label] columns += ["Description", TableColumn(_("Tags"), format="tags")] data = [ get_row(p) for p in Prefix.objects.filter(**q) .exclude(prefix="0.0.0.0/0") .exclude(prefix="::/0") .order_by("vrf__name", "prefix") .select_related() ] return self.from_dataset(title=self.title, columns=columns, data=data)
def apply_custom_fields(self, o, v, table): """ Apply custom fields to form :param o: Object :param v: values dict :param table: table :return: """ from noc.main.models.customfield import CustomField for f in CustomField.table_fields(table): n = str(f.name) if n in v: setattr(o, n, v[n]) return o
def get_info_block(self, afi, prefix, addresses): # 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), ] 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"): if f.is_hidden: continue v = getattr(prefix, f.name) prefix_info += [(f.label, v if v is not None else "")] return prefix_info
def get_data(self, request, **kwargs): def get_row(a): r = [ a.vrf.name, a.prefix.prefix, a.address, a.state.name, smart_text(a.fqdn) if a.fqdn else "", ] for f in cf: v = getattr(a, f.name) r += [v if v is not None else ""] r += [a.description, a] return r def get_or_none(classmodel, **kwargs): try: return classmodel.objects.filter(**kwargs) except classmodel.DoesNotExist: return None q = {} for k in kwargs: v = kwargs[k] if v: if k in ["description", "fqdn", "name"]: q[k + "__icontains"] = v elif k == "prefix": q[k + "__in"] = get_or_none(Prefix, prefix=v) elif k == "managed_object": q[k + "__in"] = get_or_none(ManagedObject, name=v) else: q[k] = v columns = ["VRF", "Prefix", "Address", "State", "FQDN"] cf = CustomField.table_fields("ip_address") for f in cf: if f.type == "bool": columns += [TableColumn(f.label, format="bool")] else: columns += [f.label] columns += ["Description", TableColumn(_("Tags"), format="tags")] data = [ get_row(a) for a in Address.objects.filter( **q).order_by("vrf__name", "address").select_related() ] return self.from_dataset(title=self.title, columns=columns, data=data)
def apply_custom_initial(self, o, v, table): """ :param o: Object :param v: Initial data :param table: table :return: """ from noc.main.models.customfield import CustomField for f in CustomField.table_fields(table): n = str(f.name) if n not in v: x = getattr(o, n) if x: v[n] = x return o
def customize_form(self, form, table, search=False): """ Add custom fields to django form class """ from noc.main.models.customfield import CustomField fields = [] for f in CustomField.table_fields(table): if f.is_hidden: continue if f.type == "str": if search and f.is_filtered: ff = forms.ChoiceField(required=False, label=f.label, choices=[("", "---")] + f.get_choices()) elif f.enum_group: ff = forms.ChoiceField(required=False, label=f.label, choices=[("", "---")] + f.get_enums()) else: ml = f.max_length if f.max_length else 256 ff = forms.CharField(required=False, label=f.label, max_length=ml) elif f.type == "int": ff = forms.IntegerField(required=False, label=f.label) elif f.type == "bool": ff = forms.BooleanField(required=False, label=f.label) elif f.type == "date": ff = forms.DateField(required=False, label=f.label) elif f.type == "datetime": ff = forms.DateTimeField(required=False, label=f.label) else: raise ValueError("Invalid field type: '%s'" % f.type) fields += [(str(f.name), ff)] form.base_fields.update(OrderedDict(fields)) return form
def get_custom_fields(self): from noc.main.models.customfield import CustomField return list(CustomField.table_fields(self.model._meta.db_table))
def get_custom_fields(self): from noc.main.models.customfield import CustomField return list(CustomField.table_fields( self.model._get_collection_name()))
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, )
# Third-party modules from django.db import connection # Third-party modules import six # NOC modules from noc.lib.app.reportapplication import ReportApplication from noc.main.models.customfield import CustomField from noc.ip.models.vrfgroup import VRFGroup from noc.ip.models.prefix import Prefix from noc.core.ip import IP prefix_fields = [ f for f in CustomField.table_fields("ip_prefix") if not f.is_hidden ] # % fixme rewrite to separate file CSS = """ <style> TABLE { border-spacing: 8px; } TABLE TR TD { border: none; } .block { padding: 8px;