예제 #1
0
    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,
        )
예제 #2
0
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()
예제 #3
0
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()
예제 #4
0
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
예제 #5
0
    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)
예제 #6
0
    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)