def sync_prefixes(self, prefixes): """ Apply prefixes to database :param prefixes: :return: """ # vpn_id -> [prefix, ] vrf_prefixes = defaultdict(list) for vpn_id, p in prefixes: vrf_prefixes[vpn_id] += [p] # build vpn_id -> VRF mapping self.logger.debug("Building VRF map") vrfs = {} for vpn_id in vrf_prefixes: vrf = VRF.get_by_vpn_id(vpn_id) if vrf: vrfs[vpn_id] = vrf missed_vpn_id = set(vrf_prefixes) - set(vrfs) if missed_vpn_id: self.logger.info("RD missed in VRF database and to be ignored: %s", ", ".join(missed_vpn_id)) # self.logger.debug("Getting prefixes to synchronize") for vpn_id in vrfs: vrf = vrfs[vpn_id] seen = set() for p in Prefix.objects.filter(vrf=vrf, prefix__in=vrf_prefixes[vpn_id]): norm_prefix = IP.expand(p.prefix) # Confirmed prefix, apply changes and touch prefix = prefixes[vpn_id, norm_prefix] self.apply_prefix_changes(p, prefix) seen.add(norm_prefix) for p in set(vrf_prefixes[vpn_id]) - seen: # New prefix, create self.create_prefix(prefixes[vpn_id, p])
def create_address(self, address): """ Create new address :param address: DiscoveredAddress instance :return: """ if self.is_ignored_address(address): return vrf = VRF.get_by_vpn_id(address.vpn_id) self.ensure_afi(vrf, address) if not self.has_address_permission(vrf, address): self.logger.debug( "Do not creating vpn_id=%s address=%s: Disabled by policy", address.vpn_id, address.address) metrics["address_creation_denied"] += 1 return a = Address(vrf=vrf, address=address.address, name=self.get_address_name(address), fqdn=address.fqdn, profile=address.profile, description=address.description, source=address.source, mac=address.mac) if address.source in LOCAL_SRC: a.managed_object = self.object a.subinterface = address.subinterface self.logger.info( "Creating address %s (%s): name=%s fqdn=%s mac=%s profile=%s source=%s", a.address, a.vrf.name, a.name, a.fqdn, a.mac, a.profile.name, a.source) a.save() self.fire_seen(a) metrics["address_created"] += 1
def sync_addresses(self, addresses): """ Apply addresses to database :param addresses: :return: """ # vpn_id -> [address, ] vrf_addresses = defaultdict(list) for vpn_id, a in addresses: vrf_addresses[vpn_id] += [a] # build vpn_id -> VRF mapping self.logger.debug("Building VRF map") vrfs = {} for vpn_id in vrf_addresses: vrf = VRF.get_by_vpn_id(vpn_id) if vrf: vrfs[vpn_id] = vrf missed_vpn_id = set(vrf_addresses) - set(vrfs) if missed_vpn_id: self.logger.info( "VPN ID are missed in VRF database and to be ignored: %s", ", ".join(missed_vpn_id)) # self.logger.debug("Getting addresses to synchronize") for vpn_id in vrfs: vrf = vrfs[vpn_id] seen = set() for a in Address.objects.filter(vrf=vrf, address__in=vrf_addresses[vpn_id]): norm_address = IP.expand(a.address) # Confirmed address, apply changes and touch address = addresses[vpn_id, norm_address] self.apply_address_changes(a, address) seen.add(norm_address) for a in set(vrf_addresses[vpn_id]) - seen: # New address, create self.create_address(addresses[vpn_id, a]) # Detaching hanging addresses self.logger.debug("Checking for hanging addresses") for a in Address.objects.filter(managed_object=self.object): norm_address = IP.expand(a.address) address = addresses.get((a.vrf.vpn_id, norm_address)) if not address or address.source not in LOCAL_SRC: self.logger.info("Detaching %s:%s", a.vrf.name, a.address) a.managed_object = None a.save()
def create_prefix(self, prefix): """ Create new prefix :param prefix: DiscoveredPrefix instance :return: """ if self.is_ignored_prefix(prefix): return vrf = VRF.get_by_vpn_id(prefix.vpn_id) self.ensure_afi(vrf, prefix) if not self.has_prefix_permission(vrf, prefix): self.logger.debug( "Do not creating vpn_id=%s asn=%s prefix=%s: Disabled by policy", prefix.vpn_id, prefix.asn.asn if prefix.asn else None, prefix.prefix, ) metrics["prefix_creation_denied"] += 1 return p = Prefix( vrf=vrf, prefix=prefix.prefix, name=self.get_prefix_name(prefix), profile=prefix.profile, asn=prefix.asn, description=prefix.description, source=prefix.source, ) self.logger.info( "Creating prefix %s (%s): name=%s profile=%s source=%s", p.prefix, p.vrf.name, p.name, p.profile.name, p.source, ) p.save() self.fire_seen(p) metrics["prefix_created"] += 1