def save(self, *args, **kwargs): """ Create root entries for all enabled AFIs """ from .prefix import Prefix # Generate unique rd, if empty if not self.vpn_id: vdata = {"type": "VRF", "name": self.name, "rd": self.rd} self.vpn_id = get_vpn_id(vdata) if self.initial_data["id"]: # Delete empty ipv4 root if AFI changed if self.initial_data.get("afi_ipv4") != self.afi_ipv4 and not self.afi_ipv4: root = Prefix.objects.filter(vrf=self, afi="4", prefix=self.IPv4_ROOT)[:1] if root: root = root[0] if root.is_empty(): root.disable_delete_protection() root.delete() else: # Cannot change until emptied self.afi_ipv4 = True # Delete empty ipv4 root if AFI changed if self.initial_data.get("afi_ipv6") != self.afi_ipv6 and not self.afi_ipv6: root = Prefix.objects.filter(vrf=self, afi="6", prefix=self.IPv6_ROOT)[:1] if root: root = root[0] if root.is_empty(): root.disable_delete_protection() root.delete() else: # Cannot change until emptied self.afi_ipv6 = True # Save VRF super(VRF, self).save(*args, **kwargs) if self.afi_ipv4: # Create IPv4 root, if not exists Prefix.objects.get_or_create( vrf=self, afi="4", prefix=self.IPv4_ROOT, defaults={ "description": "IPv4 Root", "profile": self.profile.default_prefix_profile, }, ) if self.afi_ipv6: # Create IPv6 root, if not exists Prefix.objects.get_or_create( vrf=self, afi="6", prefix=self.IPv6_ROOT, defaults={ "description": "IPv6 Root", "profile": self.profile.default_prefix_profile, }, )
def script_clean_result(self, __profile, result): """ Inject vpn_id :param result: :return: """ result = super().script_clean_result(__profile, result) for vpn in result: vpn["vpn_id"] = get_vpn_id(vpn) return result
def clean_result(self, result): """ Inject vpn_id :param result: :return: """ result = super().clean_result(result) for vpn in result: vpn["vpn_id"] = get_vpn_id(vpn) return result
def migrate(self): self.db.add_column( "ip_vrf", "vpn_id", models.CharField("VPN ID", max_length=15, null=True, blank=True)) for id, name, rd in self.db.execute("SELECT id, name, rd FROM ip_vrf"): vpn_id = get_vpn_id({"type": "VRF", "name": name, "rd": rd}) self.db.execute("UPDATE ip_vrf SET vpn_id = %s WHERE id = %s", [vpn_id, id]) self.db.execute("ALTER TABLE ip_vrf ALTER vpn_id SET NOT NULL") self.db.execute( "ALTER TABLE ip_vrf ADD CONSTRAINT vpn_id_unique UNIQUE (vpn_id)")
def get_confdb_vpns(self): """ Get VPNs from ConfDB :return: List of DiscoveredVPN :return: """ if not self.object.object_profile.vpn_profile_confdb: self.logger.info( "Default ConfDB VPN profile is not set. Skipping ConfDB VPN discovery" ) return [] # @todo: Check VPN capability confdb = self.get_confdb() if confdb is None: self.logger.error( "confdb artefact is not set. Skipping ConfDB VPNs") return [] self.logger.debug("Getting ConfDB VPNS") r = [] for vpn in confdb.query(self.VRF_QUERY): vpn["type"] = vpn["type"].upper() if vpn["type"] in [ "vrf", "vpls" ] else vpn["type"] try: vpn_id = get_vpn_id(vpn) except ValueError: continue r += [ DiscoveredVPN( rd=vpn.get("rd"), vpn_id=vpn_id, name=vpn["name"], type=vpn["type"], profile=self.object.object_profile.vpn_profile_confdb, description=vpn.get("description"), source=SRC_CONFDB, ) ] return r
def clean(self, data): if not data.get("vpn_id"): vdata = {"type": "VRF", "name": data["name"], "rd": data.get("rd")} data["vpn_id"] = get_vpn_id(vdata) return super().clean(data)
def get_data_from_confdb(self): # Get interfaces and parse result interfaces = { d["if_name"]: d for d in self.confdb.query(self.IF_QUERY) } vrfs = {(d["vr"], d["instance"]): d for d in self.confdb.query(self.VRF_QUERY)} instances = defaultdict(dict) for d in self.confdb.query(self.UNIT_QUERY): r = instances[d["vr"], d["instance"]] if not r: r["virtual_router"] = d["vr"] r["forwarding_instance"] = d["instance"] if vrfs and (d["vr"], d["instance"]) in vrfs: try: vrf = vrfs[d["vr"], d["instance"]] r["type"] = vrf["type"] if vrf.get("rd"): r["rd"] = vrf["rd"] r["rt_export"] = vrf.get("rt_export", []) if vrf.get("rt_import"): r["rt_import"] = vrf["rt_import"] if "vpn_id" in vrf: r["vpn_id"] = vrf["vpn_id"] else: r["vpn_id"] = get_vpn_id({ "name": vrf["instance"], "rd": vrf.get("rd"), "rt_export": vrf.get("rt_export", []), "type": vrf["type"].upper() if vrf["type"] in ["vrf", "vpls", "vll"] else vrf["type"], }) except ValueError: pass if "interfaces" not in r: r["interfaces"] = {} if_name = d["if_name"] p_iface = interfaces.get(if_name) iface = r["interfaces"].get(if_name) if iface is None: iface = { "name": if_name, "type": p_iface.get("type", "unknown") if p_iface else "unknown", "admin_status": False, "subinterfaces": {}, } r["interfaces"][if_name] = iface if p_iface: if "description" in p_iface: iface["description"] = p_iface["description"] if "admin_status" in p_iface: iface["admin_status"] = p_iface["admin_status"] == "on" unit = iface["subinterfaces"].get(d["unit"]) if unit is None: unit = {"name": d["unit"], "enabled_afi": []} iface["subinterfaces"][d["unit"]] = unit unit = iface["subinterfaces"][d["unit"]] description = d.get("description") if description: unit["description"] = description elif p_iface and p_iface.get("description"): unit["description"] = p_iface["description"] if "ipv4_addresses" in d: unit["enabled_afi"] += ["IPv4"] unit["ipv4_addresses"] = d["ipv4_addresses"] if "ipv6_addresses" in d: unit["enabled_afi"] += ["IPv6"] unit["ipv6_addresses"] = d["ipv4_addresses"] if "tagged" in d or "untagged" in d: unit["enabled_afi"] += ["BRIDGE"] if "untagged" in d: unit["untagged_vlan"] = int(d["untagged"]) if "tagged" in d: unit["tagged_vlans"] = ranges_to_list(d["tagged"]) # Flatten units r = list(six.itervalues(instances)) for fi in r: # Flatten interfaces fi["interfaces"] = list(six.itervalues(fi["interfaces"])) # Flatten units for i in fi["interfaces"]: i["subinterfaces"] = list(six.itervalues(i["subinterfaces"])) return IGetInterfaces().clean_result(r)