Example #1
0
    def test_init(self):
        model = FullModel()

        new0 = URLField()
        new1 = URLField()
        assert 1 == len(new0.default_validators)
        assert 1 == len(new1.default_validators)

        new0 = ASNField()
        new1 = ASNField()
        assert 0 == len(new0.default_validators)
        assert 0 == len(new1.default_validators)

        new0 = IPAddressField()
        new1 = IPAddressField()
        assert_ip_validator(new0)
        assert_ip_validator(new1)

        new0 = IPPrefixField()
        new1 = IPPrefixField()
        assert_ip_validator(new0)
        assert_ip_validator(new1)

        new0 = MacAddressField()
        new1 = MacAddressField()
        assert 1 == len(new0.default_validators)
        assert 1 == len(new1.default_validators)
Example #2
0
class IXLanBase(HandleRefModel):
    name = models.CharField(_("Name"), max_length=255, blank=True)
    descr = models.TextField(_("Description"), blank=True)
    mtu = models.PositiveIntegerField("MTU", null=True, blank=True)
    vlan = models.PositiveIntegerField("VLAN", null=True, blank=True)
    dot1q_support = models.BooleanField("802.1Q", default=False)
    rs_asn = ASNField(verbose_name=_("Route Server ASN"),
                      null=True,
                      blank=True,
                      default=0)
    arp_sponge = MacAddressField(verbose_name=_("ARP sponging MAC"),
                                 null=True,
                                 unique=True,
                                 blank=True)

    ixf_ixp_member_list_url = models.URLField(
        verbose_name=_("IX-F Member Export URL"), null=True, blank=True)
    ixf_ixp_member_list_url_visible = models.CharField(
        verbose_name=_("IX-F Member Export URL Visibility"),
        max_length=64,
        choices=const.VISIBILITY,
        default="Private",
    )

    class Meta:
        abstract = True
        db_table = "%sixlan" % settings.TABLE_PREFIX
        verbose_name = _("Internet Exchange LAN")
        verbose_name_plural = _("Internet Exchange LANs")

    class HandleRef:
        tag = "ixlan"
        delete_cascade = ["ixpfx_set", "netixlan_set"]
Example #3
0
class NetworkBase(HandleRefModel):
    asn = ASNField(unique=True)
    name = models.CharField(max_length=255, unique=True)
    aka = models.CharField(max_length=255, blank=True)
    irr_as_set = models.CharField(max_length=255, blank=True)

    website = URLField(blank=True)
    looking_glass = URLField(blank=True)
    route_server = URLField(blank=True)

    notes = models.TextField(blank=True)
    notes_private = models.TextField(blank=True)

    info_traffic = models.CharField(max_length=39,
                                    blank=True,
                                    choices=const.TRAFFIC)
    info_ratio = models.CharField(max_length=45,
                                  blank=True,
                                  choices=const.RATIOS,
                                  default='Not Disclosed')
    info_scope = models.CharField(max_length=39,
                                  blank=True,
                                  choices=const.SCOPES,
                                  default='Not Disclosed')
    info_type = models.CharField(max_length=60,
                                 blank=True,
                                 choices=const.NET_TYPES,
                                 default='Not Disclosed')
    info_prefixes4 = models.PositiveIntegerField(null=True, blank=True)
    info_prefixes6 = models.PositiveIntegerField(null=True, blank=True)
    info_unicast = models.BooleanField(default=False)
    info_multicast = models.BooleanField(default=False)
    info_ipv6 = models.BooleanField(default=False)

    policy_url = URLField(blank=True)
    policy_general = models.CharField(max_length=72,
                                      blank=True,
                                      choices=const.POLICY_GENERAL)
    policy_locations = models.CharField(max_length=72,
                                        blank=True,
                                        choices=const.POLICY_LOCATIONS)
    policy_ratio = models.BooleanField(default=False)
    policy_contracts = models.CharField(max_length=36,
                                        blank=True,
                                        choices=const.POLICY_CONTRACTS)

    class Meta:
        abstract = True
        db_table = '%snetwork' % settings.TABLE_PREFIX
        verbose_name_plural = "Networks"

    class HandleRef:
        tag = 'net'
        delete_cascade = ["poc_set", "netfac_set", "netixlan_set"]

    def __str__(self):
        return self.name
Example #4
0
class NetworkFacilityBase(HandleRefModel):
    local_asn = ASNField(null=True, blank=True)
    avail_sonet = models.BooleanField(default=False)
    avail_ethernet = models.BooleanField(default=False)
    avail_atm = models.BooleanField(default=False)

    class Meta:
        abstract = True
        db_table = '%snetwork_facility' % settings.TABLE_PREFIX
        verbose_name_plural = "Network Facilities"

    class HandleRef:
        tag = 'netfac'
Example #5
0
class NetworkFacilityBase(HandleRefModel):
    local_asn = ASNField(verbose_name=_("Local ASN"), null=True, blank=True)
    avail_sonet = models.BooleanField("SONET", default=False)
    avail_ethernet = models.BooleanField("Ethernet", default=False)
    avail_atm = models.BooleanField("ATM", default=False)

    class Meta:
        abstract = True
        db_table = "%snetwork_facility" % settings.TABLE_PREFIX
        verbose_name = _("Network Facility")
        verbose_name_plural = _("Network Facilities")

    class HandleRef:
        tag = "netfac"
Example #6
0
class NetworkIXLanBase(HandleRefModel):
    asn = ASNField()
    ipaddr4 = IPAddressField(version=4, blank=True, null=True)
    ipaddr6 = IPAddressField(version=6, blank=True, null=True)
    is_rs_peer = models.BooleanField(default=False)
    notes = models.CharField(max_length=255, blank=True)
    speed = models.PositiveIntegerField()

    class Meta:
        abstract = True
        db_table = '%snetwork_ixlan' % settings.TABLE_PREFIX

    class HandleRef:
        tag = "netixlan"
Example #7
0
class FullModel(models.Model):
    url = URLField(null=True, blank=True)
    asn = ASNField(null=True, blank=True)
    ipv4 = IPAddressField(version=4, null=True, blank=True)
    ipv6 = IPAddressField(version=6, null=True, blank=True)
    ip_address = IPAddressField(null=True, blank=True)

    prefix = IPPrefixField(null=True, blank=True)
    prefix4 = IPPrefixField(version=4, null=True, blank=True)
    prefix6 = IPPrefixField(version=6, null=True, blank=True)
    mac = MacAddressField(null=True, blank=True)

    class Meta:
        app_label = 'django_inet.tests'
Example #8
0
class IXLanBase(HandleRefModel):
    name = models.CharField(max_length=255, blank=True)
    descr = models.TextField(blank=True)
    mtu = models.PositiveIntegerField(null=True, blank=True)
    vlan = models.PositiveIntegerField(null=True, blank=True)
    dot1q_support = models.BooleanField(default=False)
    rs_asn = ASNField(null=True, blank=True, default=0)
    arp_sponge = MacAddressField(null=True, unique=True, blank=True)

    class Meta:
        abstract = True
        db_table = '%sixlan' % settings.TABLE_PREFIX

    class HandleRef:
        tag = 'ixlan'
        delete_cascade = ["ixpfx_set", "netixlan_set"]
Example #9
0
class NetworkIXLanBase(HandleRefModel):
    asn = ASNField(verbose_name="ASN")
    ipaddr4 = IPAddressField(verbose_name="IPv4",
                             version=4,
                             blank=True,
                             null=True)
    ipaddr6 = IPAddressField(verbose_name="IPv6",
                             version=6,
                             blank=True,
                             null=True)
    is_rs_peer = models.BooleanField(_("RS peer"), default=False)
    notes = models.CharField(_("Notes"), max_length=255, blank=True)
    speed = models.PositiveIntegerField(_("Speed (mbit/sec)"))
    operational = models.BooleanField(_("Operational"), default=True)

    class Meta:
        abstract = True
        db_table = "%snetwork_ixlan" % settings.TABLE_PREFIX
        verbose_name = _("Public Peering Exchange Point")
        verbose_name_plural = _("Public Peering Exchange Points")

    class HandleRef:
        tag = "netixlan"
Example #10
0
class NetworkBase(HandleRefModel):
    asn = ASNField(verbose_name="ASN", unique=True)
    name = models.CharField(_("Name"), max_length=255, unique=True)

    aka = models.CharField(_("Also Known As"), max_length=255, blank=True)
    name_long = models.CharField(_("Long Name"), max_length=255, blank=True)

    irr_as_set = models.CharField(
        _("IRR as-set/route-set"),
        max_length=255,
        blank=True,
        help_text=_("Reference to an AS-SET or "
                    "ROUTE-SET in Internet "
                    "Routing Registry (IRR)"),
    )
    website = URLField(_("Website"), blank=True)
    looking_glass = LG_URLField(_("Looking Glass URL"), blank=True)
    route_server = LG_URLField(_("Route Server URL"), blank=True)

    notes = models.TextField(_("Notes"), blank=True)
    notes_private = models.TextField(_("Private notes"), blank=True)

    info_traffic = models.CharField(_("Traffic Levels"),
                                    max_length=39,
                                    blank=True,
                                    choices=const.TRAFFIC)
    info_ratio = models.CharField(
        _("Traffic Ratios"),
        max_length=45,
        blank=True,
        choices=const.RATIOS,
        default="Not Disclosed",
    )
    info_scope = models.CharField(
        _("Geographic Scope"),
        max_length=39,
        blank=True,
        choices=const.SCOPES,
        default="Not Disclosed",
    )
    info_type = models.CharField(
        _("Network Type"),
        max_length=60,
        blank=True,
        choices=const.NET_TYPES,
        default="Not Disclosed",
    )
    info_prefixes4 = models.PositiveIntegerField(
        _("IPv4 Prefixes"),
        null=True,
        blank=True,
        help_text=_("Recommended maximum number of IPv4 "
                    "routes/prefixes to be configured on peering "
                    "sessions for this ASN"),
    )
    info_prefixes6 = models.PositiveIntegerField(
        _("IPv6 Prefixes"),
        null=True,
        blank=True,
        help_text=_("Recommended maximum number of IPv6 "
                    "routes/prefixes to be configured on peering "
                    "sessions for this ASN"),
    )
    info_unicast = models.BooleanField(_("Unicast IPv4"), default=False)
    info_multicast = models.BooleanField(_("Multicast"), default=False)
    info_ipv6 = models.BooleanField(_("Unicast IPv6"), default=False)
    info_never_via_route_servers = models.BooleanField(
        _("Never via route servers"),
        default=False,
        help_text=_("Indicates if this network "
                    "will announce its routes "
                    "via route servers or not"),
    )

    policy_url = URLField(_("Peering Policy"), blank=True)
    policy_general = models.CharField(_("General Policy"),
                                      max_length=72,
                                      blank=True,
                                      choices=const.POLICY_GENERAL)
    policy_locations = models.CharField(
        _("Multiple Locations"),
        max_length=72,
        blank=True,
        choices=const.POLICY_LOCATIONS,
    )
    policy_ratio = models.BooleanField(_("Ratio Requirement"), default=False)
    policy_contracts = models.CharField(
        _("Contract Requirement"),
        max_length=36,
        blank=True,
        choices=const.POLICY_CONTRACTS,
    )

    status_dashboard = URLField(_("Status Dashboard"), null=True, blank=True)

    rir_status = models.CharField(
        _("RIR status"),
        null=True,
        default=None,
        max_length=255,
    )
    rir_status_updated = models.DateTimeField(_("RIR status updated"),
                                              blank=True,
                                              null=True)

    class Meta:
        abstract = True
        db_table = "%snetwork" % settings.TABLE_PREFIX
        verbose_name = _("Network")
        verbose_name_plural = _("Networks")

    class HandleRef:
        tag = "net"
        delete_cascade = ["poc_set", "netfac_set", "netixlan_set"]

    def __str__(self):
        return self.name
Example #11
0
class NetworkBase(HandleRefModel):
    asn = ASNField(unique=True)
    name = models.CharField(max_length=255, unique=True)
    aka = models.CharField(max_length=255, blank=True)
    irr_as_set = models.CharField(max_length=255,
                                  blank=True,
                                  help_text=_("Reference to an AS-SET or "
                                              "ROUTE-SET in Internet "
                                              "Routing Registry (IRR)"))
    website = URLField(blank=True)
    looking_glass = URLField(blank=True)
    route_server = URLField(blank=True)

    notes = models.TextField(blank=True)
    notes_private = models.TextField(blank=True)

    info_traffic = models.CharField(max_length=39,
                                    blank=True,
                                    choices=const.TRAFFIC)
    info_ratio = models.CharField(max_length=45,
                                  blank=True,
                                  choices=const.RATIOS,
                                  default='Not Disclosed')
    info_scope = models.CharField(max_length=39,
                                  blank=True,
                                  choices=const.SCOPES,
                                  default='Not Disclosed')
    info_type = models.CharField(max_length=60,
                                 blank=True,
                                 choices=const.NET_TYPES,
                                 default='Not Disclosed')
    info_prefixes4 = models.PositiveIntegerField(
        null=True,
        blank=True,
        help_text=_("Recommended IPv4 maximum-prefix "
                    "limit to be configured on peering "
                    "sessions for this ASN"))
    info_prefixes6 = models.PositiveIntegerField(
        null=True,
        blank=True,
        help_text=_("Recommended IPv6 maximum-prefix "
                    "limit to be configured on peering "
                    "sessions for this ASN"))
    info_unicast = models.BooleanField(default=False)
    info_multicast = models.BooleanField(default=False)
    info_ipv6 = models.BooleanField(default=False)
    info_never_via_route_servers = models.BooleanField(
        default=False,
        help_text=_("Indicates if this network "
                    "will announce its routes "
                    "via rout servers or not"))

    policy_url = URLField(blank=True)
    policy_general = models.CharField(max_length=72,
                                      blank=True,
                                      choices=const.POLICY_GENERAL)
    policy_locations = models.CharField(max_length=72,
                                        blank=True,
                                        choices=const.POLICY_LOCATIONS)
    policy_ratio = models.BooleanField(default=False)
    policy_contracts = models.CharField(max_length=36,
                                        blank=True,
                                        choices=const.POLICY_CONTRACTS)

    class Meta:
        abstract = True
        db_table = '%snetwork' % settings.TABLE_PREFIX
        verbose_name_plural = "Networks"

    class HandleRef:
        tag = 'net'
        delete_cascade = ["poc_set", "netfac_set", "netixlan_set"]

    def __str__(self):
        return self.name
Example #12
0
class Routeserver(HandleRefModel):
    """
    Describes a routeserver at an internet exchange
    """

    ix = models.ForeignKey(
        InternetExchange,
        on_delete=models.CASCADE,
        related_name="rs_set",
    )

    # RS Config

    name = models.CharField(
        max_length=255,
        help_text=_("Routeserver name"),
    )

    asn = ASNField(help_text=_("ASN"))

    router_id = InetAddressField(
        store_prefix_length=False,
        help_text=_("Router Id"),
    )

    rpki_bgp_origin_validation = models.BooleanField(default=False)

    # ARS Config

    ars_type = models.CharField(
        max_length=32,
        choices=django_ixctl.enum.ARS_TYPES,
        default="bird",
    )

    max_as_path_length = models.IntegerField(
        default=32,
        help_text=_("Max length of AS_PATH attribute."),
    )

    no_export_action = models.CharField(
        max_length=8,
        choices=django_ixctl.enum.ARS_NO_EXPORT_ACTIONS,
        default="pass",
        help_text=_(
            "RFC1997 well-known communities (NO_EXPORT and NO_ADVERTISE)"),
    )

    graceful_shutdown = models.BooleanField(
        default=False,
        help_text=_("Graceful BGP session shutdown"),
    )

    extra_config = models.TextField(null=True,
                                    blank=True,
                                    help_text=_("Extra arouteserver config"))

    class Meta:
        db_table = "ixctl_rs"
        unique_together = (("ix", "router_id"), )

    class HandleRef:
        tag = "rs"

    @property
    def org(self):
        return self.ix.instance.org

    @property
    def display_name(self):
        return self.name

    @property
    def rsconf(self):
        """
        Return the rsconf instance for this routeserver

        Will create the rsconf instance if it does not exist yet
        """
        if not hasattr(self, "_rsconf"):
            rsconf, created = RouteserverConfig.objects.get_or_create(rs=self)
            self._rsconf = rsconf
        return self._rsconf

    @property
    def rsconf_status_dict(self):
        """
        Returns a status dict for the current state of this routeserver's
        configuration
        """

        rsconf = self.rsconf

        task = rsconf.task

        # no status

        if not task and not rsconf.rs_response:
            return {"status": None}

        if not task:
            return rsconf.rs_response

        if task.status == "pending":
            return {"status": "queued"}
        if task.status == "running":
            return {"status": "generating"}
        if task.status == "cancelled":
            return {"status": "canceled"}
        if task.status == "failed":
            return {"status": "error", "error": task.error}
        if task.status == "completed":
            if not rsconf.rs_response:
                return {"status": "generated"}
            return rsconf.rs_response

        return {"status": None}

    @property
    def rsconf_status(self):
        return self.rsconf_status_dict.get("status")

    @property
    def rsconf_response(self):
        return self.rsconf.rs_response

    @property
    def rsconf_error(self):
        return self.rsconf_status_dict.get("error")

    @property
    def ars_general(self):
        """
        Generate and return `dict` for ARouteserver general config
        """

        ars_general = {
            "cfg": {
                "rs_as": self.asn,
                "router_id": f"{self.router_id}",
                "filtering": {
                    "max_as_path_len": self.max_as_path_length,
                    "rpki_bgp_origin_validation": {
                        "enabled": self.rpki_bgp_origin_validation
                    },
                },
                "rfc1997_wellknown_communities": {
                    "policy": self.no_export_action,
                },
                "graceful_shutdown": {
                    "enabled": self.graceful_shutdown
                },
            }
        }

        if self.extra_config:
            extra_config = yaml.load(self.extra_config, Loader=Loader)

            # TODO: should we expect people to put the cfg:
            # root element into the extra config or not ?
            #
            # support both approaches for now

            if "cfg" in extra_config:
                ars_general["cfg"].update(extra_config["cfg"])
            else:
                ars_general.update(extra_config)

        return ars_general

    @property
    def ars_clients(self):
        """
        Generate and return `dirct` for ARouteserver clients config
        """

        asns = []
        asn_as_sets = {}
        clients = {}

        # TODO
        # where to get ASN sets from ??
        # peeringdb network ??
        rs_peers = InternetExchangeMember.preload_as_macro(
            self.ix.member_set.filter(is_rs_peer=True))

        for member in rs_peers:
            if member.asn not in asns:
                asns.append(member.asn)
            if member.asn not in clients:
                clients[member.asn] = {"asn": member.asn, "ip": [], "cfg": {}}

            if member.ipaddr4:
                clients[member.asn]["ip"].append(f"{member.ipaddr4}")

            if member.ipaddr6:
                clients[member.asn]["ip"].append(f"{member.ipaddr6}")

            if member.as_macro:
                clients[member.asn]["cfg"].update(
                    filtering={"irrdb": {
                        "as_sets": member.as_sets,
                    }})

        if asns:
            for net in pdbctl.Network().objects(asns=asns):
                as_set = get_as_set(net)
                if as_set:
                    asn_as_sets[f"AS{net.asn}"] = {"as_sets": [as_set]}

        print(asn_as_sets)

        return {"asns": asn_as_sets, "clients": list(clients.values())}

    def __str__(self):
        return f"Routeserver {self.name} AS{self.asn}"