def notify_error(self, error): now = datetime.datetime.now(datetime.timezone.utc) notified = self.ixlan.ixf_ixp_import_error_notified prev_error = self.ixlan.ixf_ixp_import_error if notified: diff = (now - notified).total_seconds() / 3600 if diff < settings.IXF_PARSE_ERROR_NOTIFICATION_PERIOD: return self.ixlan.ixf_ixp_import_error_notified = now self.ixlan.ixf_ixp_import_error = error self.ixlan.save() ixf_member_data = IXFMemberData(ixlan=self.ixlan, asn=0) ixf_member_data._notify( "email/notify-ixf-source-error.txt", "Could not process IX-F Data", context={ "error": error, "dt": now }, save=False, ix=True, ac=True, )
def create_IXFMemberData(network, ixlan, prefixes, dismissed): """ Creates IXFMember data """ for prefix in prefixes: ixfmember = IXFMemberData.instantiate(network.asn, prefix[0], prefix[1], ixlan) ixfmember.save() ixfmember.dismissed = dismissed ixfmember.save()
def create_IXFMemberData(network, ixlan, ip_addresses, dismissed): """ Creates IXFMember data """ for ip_address in ip_addresses: ixfmember = IXFMemberData.instantiate(network.asn, ip_address[0], ip_address[1], ixlan, data={"foo": "bar"}) ixfmember.save() ixfmember.dismissed = dismissed ixfmember.save()
def create_IXFMemberData(network, ixlan, ip_addresses, dismissed): """ Creates IXFMember data. Returns the ids of the created instances. """ ids = [] for ip_address in ip_addresses: ixfmember = IXFMemberData.instantiate(network.asn, ip_address[0], ip_address[1], ixlan, data={"foo": "bar"}) ixfmember.save() ixfmember.dismissed = dismissed ixfmember.save() ids.append(ixfmember.id) return ids
def process_deletions(self): """ Cycles all netixlans on the ixlan targeted by the importer and will remove any that are no longer found in the ixf data by their ip addresses In order for a netixlan to be removed both it's ipv4 and ipv6 address or it's asn need to be gone from the ixf data after validation """ netixlan_qset = self.ixlan.netixlan_set_active # if we are only processing a specific asn ignore # all that dont match if self.asn: netixlan_qset = netixlan_qset.filter(asn=self.asn) for netixlan in netixlan_qset: if netixlan.ixf_id not in self.ixf_ids: ixf_member_data = IXFMemberData.instantiate( netixlan.asn, netixlan.ipaddr4, netixlan.ipaddr6, netixlan.ixlan, data={}, ) if netixlan.network.allow_ixp_update: self.log_apply( ixf_member_data.apply(save=self.save), reason=REASON_ENTRY_GONE_FROM_REMOTE, ) else: ixf_member_data.set_remove( save=self.save, reason=REASON_ENTRY_GONE_FROM_REMOTE) self.log_ixf_member_data(ixf_member_data)
def parse_vlans(self, vlan_list, network, member, connection, speed): """ Parse the 'vlan_list' section of the ixf_schema Arguments: - vlan_list <list> - network <Network>: pdb network instance - member <dict>: row from ixf member_list - connection <dict>: row from ixf connection_list - speed <int>: interface speed """ asn = member["asnum"] for lan in vlan_list: ipv4_valid = False ipv6_valid = False ipv4 = lan.get("ipv4", {}) ipv6 = lan.get("ipv6", {}) # vlan entry has no ipaddresses set, log and ignore if not ipv4 and not ipv6: self.log_error( _("Could not find ipv4 or 6 address in " "vlan_list entry for vlan_id {} (AS{})").format( lan.get("vlan_id"), asn)) continue ipv4_addr = ipv4.get("address") ipv6_addr = ipv6.get("address") # parse and validate the ipaddresses attached to the vlan # append a unqiue ixf identifier to self.ixf_ids # # identifier is a tuple of (asn, ip4, ip6) # # we will later check them to see which netixlans need to be # dropped during `process_deletions` try: ixf_id = [asn] if ipv4_addr: ixf_id.append(ipaddress.ip_address(f"{ipv4_addr}")) else: ixf_id.append(None) if ipv6_addr: ixf_id.append(ipaddress.ip_address(f"{ipv6_addr}")) else: ixf_id.append(None) ixf_id = tuple(ixf_id) self.ixf_ids.append(ixf_id) except (ipaddress.AddressValueError, ValueError) as exc: self.invalid_ip_errors.append(f"{exc}") self.log_error( _("Ip address error '{}' in vlan_list entry for vlan_id {}" ).format(exc, lan.get("vlan_id"))) continue if not self.save and (not self.ixlan.test_ipv4_address(ipv4_addr) and not self.ixlan.test_ipv6_address(ipv6_addr)): # for the preview we don't care at all about new ip addresses # not at the ixlan if they dont match the prefix continue if connection.get("state", "active") == "inactive": operational = False else: operational = True is_rs_peer = ipv4.get("routeserver", False) or ipv6.get( "routeserver", False) ixf_member_data = IXFMemberData.instantiate( asn, ipv4_addr, ipv6_addr, speed=speed, operational=operational, is_rs_peer=is_rs_peer, data=json.dumps(member), ixlan=self.ixlan, save=self.save, ) if self.connection_errors: ixf_member_data.error = "\n".join(self.connection_errors) else: ixf_member_data.error = ixf_member_data.previous_error self.pending_save.append(ixf_member_data)