Giter Site home page Giter Site logo

nautobot / nautobot-app-bgp-models Goto Github PK

View Code? Open in Web Editor NEW
17.0 17.0 7.0 5.91 MB

Nautobot BGP models plugin

Home Page: https://docs.nautobot.com/projects/bgp-models/en/latest/

License: Other

Dockerfile 0.98% Python 88.01% HTML 10.82% Jinja 0.20%
nautobot-plugin

nautobot-app-bgp-models's Introduction

Nautobot

Nautobot

Nautobot is a Network Source of Truth and Network Automation Platform built as a web application atop the Django Python framework with a PostgreSQL or MySQL database.

Key Use Cases

1. Flexible Source of Truth for Networking - Nautobot core data models are used to define the intended state of network infrastructure enabling it as a Source of Truth. While a baseline set of models are provided (such as IP networks and addresses, devices and racks, circuits and cable, etc.) it is Nautobot's goal to offer maximum data model flexibility. This is enabled through features such as user-defined relationships, custom fields on any model, and data validation that permits users to codify everything from naming standards to having automated tests run before data can be populated into Nautobot.

2. Extensible Data Platform for Automation - Nautobot has a rich feature set to seamlessly integrate with network automation solutions. Nautobot offers GraphQL and native Git integration along with REST APIs and webhooks. Git integration dynamically loads YAML data files as Nautobot config contexts. Nautobot also has an evolving plugin system that enables users to create custom models, APIs, and UI elements. The plugin system is also used to unify and aggregate disparate data sources creating a Single Source of Truth to streamline data management for network automation.

3. Platform for Network Automation Apps - The Nautobot plugin system enables users to create Network Automation Apps. Apps can be as lightweight or robust as needed based on user needs. Using Nautobot for creating custom applications saves up to 70% development time by re-using features such as authentication, permissions, webhooks, GraphQL, change logging, etc. all while having access to the data already stored in Nautobot. Some production ready applications include:

The complete documentation for Nautobot can be found at Read the Docs.

Questions? Comments? Start by perusing our GitHub discussions for the topic you have in mind, or join the #nautobot channel on Network to Code's Slack community!

Build Status

Branch Status
main Build Status
develop Build Status
next Build Status

Screenshots

Gif of main page


Gif of config contexts


Gif of prefix hierarchy


Gif of GraphQL


Gif of Modes

Installation

Please see the documentation for instructions on installing Nautobot.

Application Stack

Below is a simplified overview of the Nautobot application stack for reference:

Application stack diagram

Plugins and Extensibility

Nautobot offers the ability to customize your setup to better align with your direct business needs. It does so through the use of various plugins that have been developed for network automation, and are designed to be used in environments where needed.

There are many plugins available within the Nautobot Apps ecosystem. The below screenshots are an example of some popular ones that are currently available.

Plugin Screenshots

Golden Config Plugin

Gif of golden config

ChatOps Plugin

Gif of chatops

Device Lifecycle Management Plugin

Gif of DLM

Providing Feedback

The best platform for general feedback, assistance, and other discussion is our GitHub discussions. To report a bug or request a specific feature, please open a GitHub issue using the appropriate template.

If you are interested in contributing to the development of Nautobot, please read our contributing guide prior to beginning any work.

Related projects

Please check out the GitHub nautobot topic for a list of relevant community projects.

Notices

Nautobot was initially developed as a fork of NetBox (v2.10.4). NetBox was originally developed by Jeremy Stretch at DigitalOcean and the NetBox Community.

nautobot-app-bgp-models's People

Contributors

briddo avatar bryanculver avatar cmsirbu avatar dependabot[bot] avatar dgarros avatar gertzakis avatar glennmatthews avatar jathanism avatar kircheneer avatar mzbroch avatar nniehoff avatar progala avatar snaselj avatar ubajze avatar whitej6 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nautobot-app-bgp-models's Issues

Improve Policy support

High Level Overview:
As of today, the policy support implemented in the plugin provides limited user experience with small flexibility. In the technical solution, we use string fields for import and export policies in at least PeerGroup or PeerEndpoint objects (not limited to). Currently implemented solution might require improvements, as we can move to more advanced models for the better user experience.

This issue should track the work needed to improve overall policy related user experience.

Some of low level ideas are:

  • object based policies
  • policy chain support
  • Nautobot Policy integration - plugin, bgp
    • editable policies

Peer Group Templates

During the first phase of the project, we explored modelling of the Peer Groups. In many BGP implementations, Peer Groups are used to define and describe commonalities between multiple endpoints: members can form a group and inherit attributes from a "parent". This also allows for endpoint specific overrides.

In many network implementations we are seeing on a daily basis, peer group configurations are mostly the same. However, discrepancies continue to exist.

While it is tempting to have a PeerGroup object with a global scope (devices being members of PeerGroup), this approach does not provide a way for locally configured PeerGroups to mismatch from the global groups.

Templates bridge this gap:

  • PeerGroup is still thought to local to the device / routing instance (thus potentially thousands of this objects can exist in Nautobot)
  • PeerGroupTemplate provides a global reference

In this proposal, it is assumed that during Endpoint Creation, user experience will be simplified with usability and flexibility in mind.

ASN select menu usability

Proposed Functionality

ASN selection menus need to be ordered and searchable - probably need to be changed to DynamicModelChoiceFields in the form definition.

Incompatible with Nautobot 1.3

Environment

  • Python version: 3.9
  • Nautobot version: 1.3.3
  • nautobot-bgp-models version: 0.4.4
Traceback (most recent call last):
File "/source/plugins/nautobot_autonet_sync/nautobot_autonet_sync/diffsync/models.py", line 157, in 
createcls.handle_create(model, diffsync, ids, attrs)
File "/source/plugins/nautobot_autonet_sync/nautobot_autonet_sync/diffsync/models.py", line 1334, in 
handle_createpeer_group.save()
File "/usr/local/lib/python3.9/site-packages/django/db/models/base.py", line 739, in 
saveself.save_base(using=using, force_insert=force_insert,
File "/usr/local/lib/python3.9/site-packages/django/db/models/base.py", line 787, in 
save_basepost_save.send(
File "/usr/local/lib/python3.9/site-packages/django/dispatch/dispatcher.py", line 180, in 
sendreturn [
File "/usr/local/lib/python3.9/site-packages/django/dispatch/dispatcher.py", line 181, in 
(receiver, receiver(signal=self, sender=sender, **named))
File "/usr/local/lib/python3.9/site-packages/nautobot/utilities/utils.py", line 354, in 
_curriedreturn _curried_func(*args, *moreargs, *{*kwargs, **morekwargs})
File "/usr/local/lib/python3.9/site-packages/nautobot/extras/signals.py", line 72, in 
_handle_changed_objectobjectchange = instance.to_objectchange(action)
File "/usr/local/lib/python3.9/site-packages/nautobot/extras/models/change_logging.py", line 43, in 
to_objectchangeobject_data_v2=serialize_object_v2(self),
File "/usr/local/lib/python3.9/site-packages/nautobot/utilities/utils.py", line 181, in 
serialize_object_v2data = serializer_class(obj, context={"request": None}).data
File "/usr/local/lib/python3.9/site-packages/rest_framework/serializers.py", line 555, in 
dataret = super().data
File "/usr/local/lib/python3.9/site-packages/rest_framework/serializers.py", line 253, in 
dataself._data = self.to_representation(self.instance)
File "/usr/local/lib/python3.9/site-packages/nautobot_bgp_models/api/serializers.py", line 82, in 
to_representationif self.context["request"].query_params.get("include_inherited", "false") != "false":AttributeError: 'NoneType' object has no attribute 'query_params'```

You can actually see the problem in the stack trace itself:

data = serializer_class(obj, context={"request": None}).data


creates a serializer with "request" set to None, but then the last line:

if self.context["request"].query_params.get("include_inherited", "false") != "false":


is guaranteed to blow up because the request is None, not an object with a `query_params` property.

Allow for regex-ish based bulk creation of ASNs

Environment

  • Nautobot version: 1.5.4
  • nautobot-bgp-models version: 0.7.0-beta.1

Proposed Functionality

Allow users to bulk-create ASNs by setting the name on the form to something like 420000000[1-9] (creating 4200000001 through 4200000009).

Use Case

Better UX for users wanting to bulk-create ASNs.

Expose data via Prometheus metrics

Environment

Nautobot version: 1.5.13 (to get metrics.py support)

Proposed Functionality

Expose Prometheus metrics for this app including, but not limited to:

  • QTY BGP peerings per device
  • QTY BGP peerings per site
  • QTY ASNs per site

ASN Filter

ASN Field in Routing Instance View does not filter for ASNs

Refactor the PeerSeesion views/form to allow users add a PeerEndpoint to a Session from the Session view

Environment

  • Nautobot version: 1.1.2
  • nautobot-bgp-models version: 0.5.0

Proposed Functionality

Currently to create new PeerSession, the user must create the 2 PeerEndpoints first and then create the PeerSession and associate the PeerEndpoints to it otherwise it's not possible to create session
And from the PeerSession detailed view, we can't edit/add or delete and existing PeerSession

The proposal to is update the PeerSession form to allow the creation of a PeerSession without PeerEndpoints at first and add some button in the PeerSession detailed view to directly add a new PeerEndpoint

Also if we have a large number of PeerEndpoint already present, it's can be hard to identify which one to use, especially since we can have multiple PeerEndpoint per IP addresss / ASN

Screen Shot 2021-08-26 at 4 02 45 PM

The idea is to build something similar to the workflow for the Circuit and CircuitTermination today

Use Case

Improve the user experience to create a new PeerSession from the UI

Add more search options in the BGP Peer Session table

Environment

  • Nautobot version: 1.1.2
  • nautobot-bgp-models version: 0.5.0

Proposed Functionality

Currently we can only search BGP Session by Role and Status, it would be very useful to add more options to search

  • By ASN
  • By Device
  • By local_ip

Use Case

Give users more granularity to search BGP Sessions

Screen Shot 2021-08-25 at 4 16 03 PM

API schema needs to switch from drf_yasg to drf_spectacular

Nautobot 1.3 switched its OpenAPI documentation of the REST API from using drf_yasg to drf_spectacular, but the schema extensions in nautobot_bgp_models/api/views.py are still based on drf_yasg. These need to be updated for accurate OpenAPI documentation of the plugin.

Clicking on Autonomous Systems with no Autonomous Systems throws ProgrammingError

Environment

  • Python version: 3.8.5
  • Nautobot version: 1.2.0a1
  • nautobot-bgp-models version: 0.5.0

Installed the plugin and then in the UI clicked on Plugins->BGP Models->Autonomous Systems. I had not created any Autonomous System objects yet.

Expected Behavior

To be taken to an Autonomous System main page

Observed Behavior

Environment:


Request Method: GET
Request URL: https://192.168.18.2/plugins/bgp/autonomous-systems/

Django Version: 3.1.13
Python Version: 3.8.5
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'django.contrib.humanize',
 'cacheops',
 'corsheaders',
 'django_filters',
 'django_jinja',
 'django_tables2',
 'django_prometheus',
 'mptt',
 'rest_framework',
 'social_django',
 'taggit',
 'timezone_field',
 'nautobot.core',
 'nautobot.circuits',
 'nautobot.dcim',
 'nautobot.ipam',
 'nautobot.extras',
 'nautobot.tenancy',
 'nautobot.users',
 'nautobot.utilities',
 'nautobot.virtualization',
 'django_rq',
 'drf_yasg',
 'graphene_django',
 'health_check',
 'health_check.db',
 'health_check.cache',
 'health_check.storage',
 'nautobot_chatops.NautobotChatOpsConfig',
 'nautobot_bgp_models.NautobotBGPModelsConfig']
Installed Middleware:
['django_prometheus.middleware.PrometheusBeforeMiddleware',
 'corsheaders.middleware.CorsMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware',
 'django.middleware.security.SecurityMiddleware',
 'nautobot.core.middleware.ExceptionHandlingMiddleware',
 'nautobot.core.middleware.RemoteUserMiddleware',
 'nautobot.core.middleware.ExternalAuthMiddleware',
 'nautobot.core.middleware.APIVersionMiddleware',
 'nautobot.core.middleware.ObjectChangeMiddleware',
 'django_prometheus.middleware.PrometheusAfterMiddleware']



Traceback (most recent call last):
  File "/opt/nautobot/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)

The above exception (relation "nautobot_bgp_models_autonomoussystem" does not exist
LINE 1: SELECT COUNT(*) AS "__count" FROM "nautobot_bgp_models_auton...
                                          ^
) was the direct cause of the following exception:
  File "/opt/nautobot/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/opt/nautobot/lib/python3.8/site-packages/django/core/handlers/base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/opt/nautobot/lib/python3.8/site-packages/django/views/generic/base.py", line 70, in view
    return self.dispatch(request, *args, **kwargs)
  File "/opt/nautobot/lib/python3.8/site-packages/nautobot/utilities/views.py", line 94, in dispatch
    return super().dispatch(request, *args, **kwargs)
  File "/opt/nautobot/lib/python3.8/site-packages/django/views/generic/base.py", line 98, in dispatch
    return handler(request, *args, **kwargs)
  File "/opt/nautobot/lib/python3.8/site-packages/nautobot/core/views/generic.py", line 239, in get
    RequestConfig(request, paginate).configure(table)
  File "/opt/nautobot/lib/python3.8/site-packages/django_tables2/config.py", line 61, in configure
    table.paginate(**kwargs)
  File "/opt/nautobot/lib/python3.8/site-packages/django_tables2/tables.py", line 584, in paginate
    self.page = self.paginator.page(page)
  File "/opt/nautobot/lib/python3.8/site-packages/django/core/paginator.py", line 73, in page
    number = self.validate_number(number)
  File "/opt/nautobot/lib/python3.8/site-packages/django/core/paginator.py", line 51, in validate_number
    if number > self.num_pages:
  File "/opt/nautobot/lib/python3.8/site-packages/django/utils/functional.py", line 48, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/opt/nautobot/lib/python3.8/site-packages/django/core/paginator.py", line 100, in num_pages
    if self.count == 0 and not self.allow_empty_first_page:
  File "/opt/nautobot/lib/python3.8/site-packages/django/utils/functional.py", line 48, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/opt/nautobot/lib/python3.8/site-packages/django/core/paginator.py", line 95, in count
    return len(self.object_list)
  File "/opt/nautobot/lib/python3.8/site-packages/django_tables2/rows.py", line 325, in __len__
    length = len(self.data)
  File "/opt/nautobot/lib/python3.8/site-packages/django_tables2/data.py", line 153, in __len__
    self._length = self.data.count()
  File "/opt/nautobot/lib/python3.8/site-packages/cacheops/query.py", line 296, in count
    return self._no_monkey.count(self)
  File "/opt/nautobot/lib/python3.8/site-packages/django/db/models/query.py", line 411, in count
    return self.query.get_count(using=self.db)
  File "/opt/nautobot/lib/python3.8/site-packages/django/db/models/sql/query.py", line 517, in get_count
    number = obj.get_aggregation(using, ['__count'])['__count']
  File "/opt/nautobot/lib/python3.8/site-packages/django/db/models/sql/query.py", line 502, in get_aggregation
    result = compiler.execute_sql(SINGLE)
  File "/opt/nautobot/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1156, in execute_sql
    cursor.execute(sql, params)
  File "/opt/nautobot/lib/python3.8/site-packages/django/db/backends/utils.py", line 98, in execute
    return super().execute(sql, params)
  File "/opt/nautobot/lib/python3.8/site-packages/cacheops/transaction.py", line 93, in execute
    result = self._no_monkey.execute(self, sql, params)
  File "/opt/nautobot/lib/python3.8/site-packages/django/db/backends/utils.py", line 66, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "/opt/nautobot/lib/python3.8/site-packages/django/db/backends/utils.py", line 75, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "/opt/nautobot/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "/opt/nautobot/lib/python3.8/site-packages/django/db/utils.py", line 90, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/opt/nautobot/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)

Exception Type: ProgrammingError at /plugins/bgp/autonomous-systems/
Exception Value: relation "nautobot_bgp_models_autonomoussystem" does not exist
LINE 1: SELECT COUNT(*) AS "__count" FROM "nautobot_bgp_models_auton...
                                      ^

Steps to Reproduce

  1. Install plugin
  2. Don't create Autonomous System objects
  3. click on Plugins->BGP Models->Autonomous Systems

ASN model related to `circuits.models.Provider`

Extend existing AutonomousSystem model with FK to circuits.models.Provider.

BGP Plugin supports two use cases:

  • peer device modelled inside Nautobot (Routing Instance for Device exists)
  • ISP's (external) device (no device and device routing instance exist in Nautobot)

For the second use case, where we can't represent the peer's device, the representation should be via Provider model.

Following use cases should be considered:

  • listing and filtering BGP peerings (sessions) by the Provider X / Y filter
  • multiple ASNs related to single Provider (provider merges and acquisitions)
  • ease and clarify modeling for "remote peers" (outside administrative domain):
    • peer endpoint has to be terminated either on BGPRoutingInstance , either to ASN with Provider field defined

Address Families Templates

It was reported, that both global address family template and per device address family model instance are useful for users.
Address family templates should be optional instance definitions for the per-device address family to allow for global policy definitions.

Field Inheritance in BGP models

In many cases, BGP objects are related between themselves and require some form of inheritance.
Examples being:

  • peer endpoint inheriting ASN number defined for BGP process
  • peer endpoint inheriting the policies from peer group

As there are many use cases for inheritance, this PR is to implement a generic pattern for object inheritance within the plugin and providing an opinionated inheritance paths between BGP objects modelled.

Use cases:

  • peer groups and peer's membership
  • peer endpoints under BGP process context
  • address families contexts for peer groups
  • Global Templates:
    • address families
    • peer groups

No Status options available when creating Autonomous System object

Environment

  • Python version: 3.8.5
  • Nautobot version: 1.2.0a1
  • nautobot-bgp-models version: 0.5.0

Tried to create Autonomous System object

Expected Behavior

Status options available in the dropdown

Observed Behavior

No Status options availble

Steps to Reproduce

  1. Click on Plugins-->Autonomous Systems-->+ to create a new Autonomous System

image

Peer Endpoint and Peer Group Contexts

Current implementation of BGP Plugin models does not allow to link a Peer Endpoint to a specific address family.
This results in some limitations, especially around peer customizations or overrides at the address-family level, including enable/disabling specific endpoints under specific Address Families.

In the refactor, I propose PeerEndpointContext and PeerGroupContext models removing this limitation.

Use cases solved:

  • MP-BGP (multi protocol BGP)
  • VPNv4 / eVPN
  • PeerEndpoints under VRF address Families

Following, are the example device configurations and sample modeling:

jcy-bb-01#show run | s r b
router bgp 65251
 bgp router-id 10.0.10.3
 bgp log-neighbor-changes
 neighbor INTERNAL peer-group
 neighbor 1.1.1.1 remote-as 1
 neighbor 1.1.1.1 peer-group INTERNAL
 neighbor 1.2.3.4 remote-as 1234
 neighbor 10.10.0.5 remote-as 65251
 neighbor 10.10.0.13 remote-as 65251
 neighbor 10.10.0.18 remote-as 65252
 !
 address-family ipv4
  network 1.2.3.4 mask 255.255.255.252
  redistribute connected
  redistribute static
  neighbor INTERNAL route-map EXAMPLE-IN in
  neighbor INTERNAL route-map EXAMPLE-OUT out
  neighbor INTERNAL maximum-prefix 1000
  neighbor 1.1.1.1 activate
  neighbor 1.2.3.4 activate
  neighbor 1.2.3.4 send-community extended
  neighbor 1.2.3.4 route-map TEST-IN in
  neighbor 1.2.3.4 maximum-prefix 5000
  neighbor 10.10.0.5 activate
  neighbor 10.10.0.13 activate
  neighbor 10.10.0.18 activate
  maximum-paths 20
 exit-address-family
 !
 address-family ipv6
  neighbor INTERNAL route-map TEST in
  neighbor 1.1.1.1 activate
  neighbor 1.1.1.1 route-map TEST-OVERRIDE in
  neighbor 1.2.3.4 activate
  neighbor 1.2.3.4 send-community
  neighbor 1.2.3.4 capability orf prefix-list both
  neighbor 1.2.3.4 route-map TEST-IPV6-IN in
  neighbor 1.2.3.4 maximum-prefix 1000000
 exit-address-family
jcy-bb-01#

Modelled as following (partial, not all instances but to show general idea about Peer Group Contexts / Peer Endpoint Contexts):

>>> asn_1 = AutonomousSystem.objects.create(asn=1) 
>>> asn_1234 = AutonomousSystem.objects.create(asn=1234)
>>> asn_65251 = AutonomousSystem.objects.create(asn=65251)
>>> cisco_bgp_instance = BGPRoutingInstance.objects.create(device=Device.objects.first() )

>>> cisco_bgp_instance.router_id = IPAddress.objects.first()
>>> cisco_bgp_instance.autonomous_system = asn_65251

>>> pg_INTERNAL = PeerGroup.objects.create(routing_instance=cisco_bgp_instance, name="INTERNAL")


# Create Peer endpoint 1.1.1.1 and assign it to peer group INTERNAL:
>>> peer_endpoint_1_1_1_1 = PeerEndpoint.objects.create(routing_instance=cisco_bgp_instance, ip=IPAddress.objects.all(address="1.1.1.1/32").first(), peer_group=pg_INTERNAL)

# Create two other endpoints without Peer Group:
>>> peer_endpoint_1_2_3_4 = PeerEndpoint.objects.create(routing_instance=cisco_bgp_instance, ip=IPAddress.objects.all(address="1.2.3.4/32").first(), remote_autonomous_system=AutonomousSystem.objects.get(asn=1234))
>>> peer_endpoint_10_10_0_5 = PeerEndpoint.objects.create(routing_instance=cisco_bgp_instance, ip=IPAddress.objects.all(address="10.10.0.5/32").first(), remote_autonomous_system=AutonomousSystem.objects.get(asn=65251))

# Create IPV4 Address Family
>>> local_af_ipv4 = AddressFamily.objects.create(afi_safi=AFISAFIChoices.AFI_IPV4, routing_instance=cisco_bgp_instance)

# Configure Peer Group INTERNAL under Address Family IPv4:
>>> peer_group_context = PeerGroupContext.objects.create(peer_group=pg_INTERNAL, address_family=local_af_ipv4)
>>> peer_group_context.import_policy = "EXAMPLE-IN"
>>> peer_group_context.export_policy = "EXAMPLE-OUT"

# Configure Peer Endpoint 1.1.1.1 under Address Family IPv6:
>>> local_af_ipv6 = AddressFamily(afi_safi=AFISAFIChoices.AFI_IPV6_LU, routing_instance=cisco_bgp_instance)
>>> peer_endpoint_context = PeerEndpointContext.objects.create(peer_endpoint=peer_endpoint_1_1_1_1, address_family=local_af_ipv6)
>>> peer_endpoint_context.import_policy = "TEST-OVERRIDE"

Other valid configuration use cases :
Arista LEAF

router general
   router-id ipv4 <IP router ID>

router bgp <ASN as dot>
   bgp asn notation asdot
   update wait-install
   no bgp default ipv4-unicast
   timers bgp 5 15
   distance bgp 20 200 200
   maximum-paths 4 ecmp 4
   neighbor default send-community
   neighbor EVPN-OVERLAY-LEAF peer group
   neighbor EVPN-OVERLAY-SPINE peer group
   neighbor EVPN-OVERLAY-SPINE remote-as <ASN of spines>
   neighbor EVPN-OVERLAY-SPINE update-source Loopback0
   neighbor EVPN-OVERLAY-SPINE bfd
   neighbor EVPN-OVERLAY-SPINE ebgp-multihop 3
   neighbor EVPN-OVERLAY-SPINE maximum-routes 0
   neighbor IPv4-UNDERLAY-MLAG-PEER peer group
   neighbor IPv4-UNDERLAY-MLAG-PEER remote-as <ASN of other leaf node>
   neighbor IPv4-UNDERLAY-MLAG-PEER next-hop-self
   neighbor IPv4-UNDERLAY-MLAG-PEER maximum-routes 256000 warning-only
   neighbor IPv4-UNDERLAY-SPINE peer group
   neighbor IPv4-UNDERLAY-SPINE remote-as <AS of spines>
   neighbor IPv4-UNDERLAY-SPINE maximum-routes 256000 warning-only
   neighbor <IP neighbor spine1 loopback> peer group EVPN-OVERLAY-SPINE
   neighbor <IP neighbor spine2 loopback> peer group EVPN-OVERLAY-SPINE
   neighbor <IP neighbor spine3 loopback> peer group EVPN-OVERLAY-SPINE
   neighbor <IP neighbor spine1 link1> peer group IPv4-UNDERLAY-SPINE
   neighbor <IP neighbor spine1 link2> peer group IPv4-UNDERLAY-SPINE
   neighbor <IP neighbor spine1 link3> peer group IPv4-UNDERLAY-SPINE
   neighbor <IP neighbor spine2 link1> peer group IPv4-UNDERLAY-SPINE
   neighbor <IP neighbor spine2 link2> peer group IPv4-UNDERLAY-SPINE
   neighbor <IP neighbor spine2 link3> peer group IPv4-UNDERLAY-SPINE
   neighbor <IP neighbor spine3 link1> peer group IPv4-UNDERLAY-SPINE
   neighbor <IP neighbor spine3 link2> peer group IPv4-UNDERLAY-SPINE
   neighbor <IP neighbor spine3 link3> peer group IPv4-UNDERLAY-SPINE
   neighbor <IP neighbor other leaf node> peer group IPv4-UNDERLAY-MLAG-PEER
   !
   address-family evpn
      neighbor EVPN-OVERLAY-SPINE activate
      host-flap detection window 20.0 threshold 4 expiry timeout 30.0 seconds
   !
   address-family ipv4
      neighbor IPv4-UNDERLAY-MLAG-PEER activate
      neighbor IPv4-UNDERLAY-SPINE activate
      network <local IP/network>
      network <local IP/network>
   !
   address-family ipv6
      no neighbor EVPN-OVERLAY-LEAF activate
   !
   address-family rt-membership
      neighbor EVPN-OVERLAY-SPINE activate
   !
   vrf <MGMT VRF>
      rd <(vrf specific) ASN as dot>:<number>
      route-target import evpn <number>:<number>
      route-target export evpn <number:<number>
      neighbor <IP neighbor spine1> remote-as <ASN spine>
      neighbor <IP neighbor spine1> update-source Ethernet33/7
      neighbor <IP neighbor spine2> remote-as <ASN spine>
      neighbor <IP neighbor spine2> update-source Ethernet34/7
      neighbor <IP neighbor spine3> remote-as <ASN spine>
      neighbor <IP neighbor spine3> update-source Ethernet35/7
      neighbor <IP neighbor other leaf node> remote-as <ASN of other leaf node>
      neighbor <IP neighbor other leaf node> next-hop-self
      !
      address-family ipv4
         neighbor <IP neighbor spine1> activate
         neighbor <IP neighbor spine2> activate
         neighbor <IP neighbor spine3> activate
         neighbor <IP neighbor other leaf node> activate
         network <local IP/network>

Arista SPINE

router general
   router-id ipv4 <IP router ID>

peer-filter LEAF-AS-RANGE
   10 match as-range <ASN range start>-<ASN range end> result accept

router bgp <ASN as dot>
   bgp asn notation asdot
   update wait-for-convergence
   update wait-install
   no bgp default ipv4-unicast
   timers bgp 5 15
   distance bgp 20 200 200
   maximum-paths 128
   bgp listen range <IP address range overlay peers> peer-group EVPN-OVERLAY-LEAF peer-filter LEAF-AS-RANGE
   bgp listen range <IP address range underlay peers> peer-group IPv4-UNDERLAY-LEAF peer-filter LEAF-AS-RANGE
   neighbor default send-community
   neighbor EVPN-OVERLAY-LEAF peer group
   neighbor EVPN-OVERLAY-LEAF update-source Loopback0
   neighbor EVPN-OVERLAY-LEAF bfd
   neighbor EVPN-OVERLAY-LEAF ebgp-multihop 3
   neighbor EVPN-OVERLAY-LEAF maximum-routes 0
   neighbor INBAND_PG peer group
   neighbor INBAND_PG local-as <ASN in vrf> no-prepend replace-as
   neighbor IPv4-UNDERLAY-LEAF peer group
   neighbor IPv4-UNDERLAY-LEAF maximum-routes 12000 warning-only
   !
   address-family evpn
      bgp next-hop-unchanged
      neighbor EVPN-OVERLAY-LEAF activate
   !
   address-family ipv4
      neighbor IPv4-UNDERLAY-LEAF activate
      network <local IP/network>
   !
   address-family ipv6
      no neighbor EVPN-OVERLAY-LEAF activate
   !
   address-family rt-membership
      neighbor EVPN-OVERLAY-LEAF activate
   !
   vrf <MGMT VRF>
   rd <(vrf specific) ASN as dot>:<number>
   neighbor <IP neighbor A> peer group INBAND_PG
   neighbor <IP neighbor A> remote-as <remote ASN as dot>
   neighbor <IP neighbor A> update-source Ethernet1/7
   neighbor <IP neighbor B> peer group INBAND_PG
   neighbor <IP neighbor B> remote-as <remote ASN as dot>
   neighbor <IP neighbor B> update-source Ethernet17/7
   neighbor <IP neighbor C> peer group INBAND_PG
   neighbor <IP neighbor C> remote-as <remote ASN as dot>
   neighbor <IP neighbor C> update-source Ethernet2/7
   neighbor <IP neighbor D> peer group INBAND_PG
   neighbor <IP neighbor D> remote-as <remote ASN as dot>
   neighbor <IP neighbor D> update-source Ethernet18/7
   !
   address-family ipv4
      neighbor <IP neighbor A> activate
      neighbor <IP neighbor B> activate
      neighbor <IP neighbor C> activate
      neighbor <IP neighbor D> activate
      network <local inband management IP/network>

ASN info not present in peer-endpoint

Environment

Public Nautobot demo instance: demo.nautobot.com

Expected Behavior

The ASN number is present in the REST API serializer

Observed Behavior

 "autonomous_system": null

Steps to Reproduce

>>> response = requests.get("https://demo.nautobot.com/api/plugins/bgp/peer-endpoints",headers=headers)
>>> bgp_peer_endpoints = response.json()["results"]
>>> print(json.dumps(bgp_peer_endpoints[0], indent=4))
{
    "routing_instance": {
        "display": "dfw01-edge-02 - AS 65535",
    },
    "autonomous_system": null,
}

AS Number management

As ...

Nelly - Network Engineer

I want ...

to be able to manage assignment of public and private autonomous system numbers

So that ...

I can easily reference what ASN's are assigned and where they are assigned, and who (RIR or private entity) assigned them.

I know this is done when...

  • There is data model for AS numbers in Nautobot, that links to RIRs and sites.
  • ASNs can be listed, searched and created from the web interface or API
  • The AS Number field is updated to a foreign key to this new data model
  • The migration takes care of converting the ASN field on a site to a new ASN entry in that model
  • I can request the next free ASN from a specific block (e.g. private ASNs) (Credit to @sirtux )

Optional - Feature groups this request pertains to.

  • Automation
  • Circuits
  • DCIM
  • IPAM
  • Misc (including Data Sources)
  • Organization
  • Plugins (and other Extensibility)
  • Security (Secrets, etc)
  • Image Management
  • UI/UX
  • Documentation
  • Other (not directly a platform feature)

Database Changes

New model for AS Numbers

  • ASN (16 or 32 byte values)
  • Allocating RIR (Nullable)
  • Description
  • Custom fields or config contexts?

External Dependencies

No response

Make device optional for AddressFamily and PeerGroup

Environment

  • Nautobot version: 1.1.2
  • nautobot-bgp-models version: 0.5.0

Proposed Functionality

Currently, both AddressFamily and PeerGroup objects must be associated with a device, either a Device or a VirtualMachine, mode.

I would like to propose to change the schema of these models to make device optional and allow AddressFamily and PeerGroup to be reused across devices

Use Case

Offer more flexibility to the user and do not require to duplicate AddressFamily and PeerGroup objects for each device if they are technically the same across multiple devices.

Add a 'site' field on the ASN model

Environment

  • Nautobot version: 1.5.2
  • nautobot-bgp-models version: 0.7.0-beta1

Proposed Functionality

Add an optional Site ForeignKey field onto the ASN model.

Use Case

Nautobot currently (1.x) has a field for ASNs directly on the Site model. This could be a good stepping stone to eye at Nautobot 2.0 compatibility to enable users to transfer that ASN information into this plugin.

Remote Peer Validation

Enable validations for the following:

  • peering between the same IP
  • peering between the same Routing Instance

For Peering model:

  • ensure no empty peering exists (known issue after deleting two routing instances)
  • ensure no duplicated endpoints create a duplicated peering

Re-factor peering.update_peers methods.

Hide the extensions to the device page when there is no content

Environment

  • Nautobot version: 1.5.7
  • nautobot-bgp-models version: 0.7.0-beta1

Proposed Functionality

Hide the 'BGP Peer Sessions' and 'BGP Routing Instances' boxes on device pages when there are no sessions or routing instances.

Use Case

Servers, PDUs, cable management, and many other devices will not have BGP sessions or instances. Having the empty boxes there clutters the device page, this could be done by checking for the existence of the filtered object before rendering the box, e.g.:

    def right_page(self):
        """Add content to the right side of the Devices detail view."""
        endpoints = PeerEndpoint.objects.filter(
            routing_instance__device=self.context["object"],
        )
        if endpoints:
            return self.render(
                "nautobot_bgp_models/inc/device_peer_endpoints.html",
                extra_context={"endpoints": endpoints},
            )
        else:
            return ""

Idea: consolidate endpoint and session models

Proposed Functionality

Currently defining a session between two devices entails creating a PeerEndpoint for each device and a PeerSession linking those endpoints. It might substantially simplify the data model and the user experience if we were to consolidate these three objects into a single session model/object. This might entail some repetition of fields (similar to a cable's or circuit's side_a/side_z fields) but that shouldn't necessarily be a blocker.

Device (routing-instance) specific Peer Groups and Peer Endpoints

Peer Groups allow for grouping of multiple BGP endpoints (members) into a group and assigning common attributes to the group.

Peer Groups could be both modelled via global and local approaches:

  • In the global approach, a single group represents peers of given role. This removes the complexity and need for re-creating the group, that is nearly similar for multiple members. However, this creates a challenge for brownfield networks and prevents from per-device customizations.
  • In the local approach, each device could have its own peer-group instance.

This issue is to enable local peer group and allow them to integrate with PeerGroupTemplates. With attribute inheritance, a local peer-group could inherit all of the attribute from a Global Template

Use cases solved:

  • integration with Peer Group Templates
  • per-device overrides and customization.

Implement `Notes` feature on BGP models

Environment

  • Nautobot version: 1.5.14
  • nautobot-bgp-models version: 0.7.0-beta.1

Proposed Functionality

Allow users to define notes for BGP models instances.

In detail view, Notes tab is not visible for models defined in this plugin.

https://demo.nautobot.com/plugins/bgp/autonomous-systems/af3f874a-3775-4295-a111-c841eb56d722/?tab=main

As a solution NautobotUIViewSet can be used as a base class for views.

Use Case

As a Nautobot user, I want to store notes on BGP models instances.

Re-evaluate uniqueness of ASN number

Environment

  • Nautobot version: 1.5.4
  • nautobot-bgp-models version: 0.7.0-beta.1

Proposed Functionality

Remove the unique=True parameter to the ASNField on the ASN model.

Use Case

Re-use of private ASNs between either different locations of the same tenant or possibly between different tenants altogether.

Compat. with Nautobot 1.4 - filterset

Just as an FYI, the include_inherited parameter being passed through to the underlying filterset will cause issues under the upcoming Nautobot 1.4 release due to nautobot/nautobot#1794. The fix (which should be possible to implement now if desired) would be to implement get_filterset_kwargs on this mixin and have it explicitly discard include_inherited, similar to https://github.com/nautobot/nautobot/pull/1794/files#diff-9a2bdd132c5e3a0e6947134b0ae99c641837ad953eb9f5585633bf33e4a60dc9.

Originally posted by @glennmatthews in #44 (comment)

Move Menu items out of Plugins into a new top level Routing section

Environment

  • Nautobot version: 1.1.2
  • nautobot-bgp-models version: 0.5.0

Proposed Functionality

I think it would make sense to move the current menu items out of the "plugins" drop down menu and move them to a new top level "Routing" section in the menu, somewhere in the middle

Use Case

When we have a lot of plugins installed the "plugins" menu is getting very long and I think routing is a big enough topic that it deserves it's own menu

Since the ability to create a new top level menu element has been introduced in 1.1, we would have to change the requirements for this plugin.

Device specific BGP instance model

Following objects: ASN, AddressFamily, PeerEndpoint are currently stitched to the dcim.Device via a number of ways: custom fields, custom relationships etc.

After initial plugin usage, we noticed:

  • performance impact
  • modeling challenges:
    • handling several Address Families
    • scaling beyond single BGP process per device
    • supporting multiple routing protocols: OSPF, ISIS (where it is a common practice for OSPF to run multiple processes on the same device)

This PR is to track following:

  • Implement Routing Instance
  • Relate PeerGroup and PeerEndpoints to Routing Instances
  • ...

Use cases solved:

  • performance improvements
  • concrete inheritance model
  • providing pattern for future plugins: OSPF, ISIS.

Models' Extra Attributes

This feature has been already implemented, however requires a decision on which models should be applied vs custom fields applied

Similarly to the Device Config Context, a dedicated and inheritable pattern can exist for BGP Models.

extra_attributes is a JSONField attached to some of the models (Mixin provided by BGPExtraAttributesMixin).

While traditionally, a deepmerge is performed based on the weight of a given context, merging of different BGP extra attributes is based on inheritance order. The inheritance for each class holding the extra_attributes is defined via extra_attributes_inheritance list.

Deepmerge is the method used by Nautobot core to perform the merge of data contexts. This core function has been

Screenshots:
image
image

DESIGN Considerations:

  • BGP inheritance pattern provides methods to inter-object field inheritance. The fields are swapped just next to the presentation layer (API, UI) and not in the database. While it is tempting to provide similar experience for the Nautobot Custom Fields, for the feature parity and simplicity I opt for Inheritable Extra Attributes which are local JSONFields on the objects.

  • There are many unknowns for Custom Field Inheritance implementation, however it has to be decided if non-inherited custom fields should be allowed on the BGP models. (CC: @itdependsnetworks , @glennmatthews )

  • Extra Attributes are currently applied on

    • PeerEndpoint
    • PeerGroup
    • PeerGroupTemplate
    • BGPRoutingInstance
  • Custom Fields are currently allowed for all BGP models. - should they?

Installation Fails

Not sure if it's just me but after install I get:

Traceback (most recent call last):
  File "/usr/local/lib/python3.10/site-packages/django/apps/config.py", line 268, in get_model
    return self.models[model_name.lower()]
KeyError: 'peersession'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/bin/nautobot-server", line 8, in <module>
    sys.exit(main())
  File "/usr/local/lib/python3.10/site-packages/nautobot/core/cli.py", line 54, in main
    run_app(
  File "/usr/local/lib/python3.10/site-packages/nautobot/core/runner/runner.py", line 266, in run_app
    management.execute_from_command_line([runner_name, command] + command_args)
  File "/usr/local/lib/python3.10/site-packages/django/core/management/__init__.py", line 419, in execute_from_command_line
    utility.execute()
  File "/usr/local/lib/python3.10/site-packages/django/core/management/__init__.py", line 413, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/local/lib/python3.10/site-packages/django/core/management/base.py", line 354, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/usr/local/lib/python3.10/site-packages/django/core/management/base.py", line 398, in execute
    output = self.handle(*args, **options)
  File "/usr/local/lib/python3.10/site-packages/nautobot/core/management/commands/post_upgrade.py", line 78, in handle
    call_command(
  File "/usr/local/lib/python3.10/site-packages/django/core/management/__init__.py", line 181, in call_command
    return command.execute(*args, **defaults)
  File "/usr/local/lib/python3.10/site-packages/django/core/management/base.py", line 398, in execute
    output = self.handle(*args, **options)
  File "/usr/local/lib/python3.10/site-packages/django/core/management/base.py", line 89, in wrapped
    res = handle_func(*args, **kwargs)
  File "/usr/local/lib/python3.10/site-packages/django/core/management/commands/migrate.py", line 268, in handle
    emit_post_migrate_signal(
  File "/usr/local/lib/python3.10/site-packages/django/core/management/sql.py", line 42, in emit_post_migrate_signal
    models.signals.post_migrate.send(
  File "/usr/local/lib/python3.10/site-packages/django/dispatch/dispatcher.py", line 180, in send
    return [
  File "/usr/local/lib/python3.10/site-packages/django/dispatch/dispatcher.py", line 181, in <listcomp>
    (receiver, receiver(signal=self, sender=sender, **named))
  File "/usr/local/lib/python3.10/site-packages/nautobot_bgp_models/signals.py", line 14, in post_migrate_create_statuses
    model = sender.get_model(model_name)
  File "/usr/local/lib/python3.10/site-packages/django/apps/config.py", line 270, in get_model
    raise LookupError(
LookupError: App 'nautobot_bgp_models' doesn't have a 'PeerSession' model.

AddressFamily Add/Edit form is slow to render

Environment

  • Python version: 3.6
  • Nautobot version: 1.1.2
  • nautobot-bgp-models version: 0.5..0

Expected Behavior

The Add/Edit form for an AddressFamily object should be fast to load

Observed Behavior

The page is taking multiple seconds to load when there is a large number of peer_endpoint present in Nautobot

Steps to Reproduce

  1. Create a large number of peer endpoint
  2. Try to create a new AddressFamily

I haven't tested but looking at the code, the issue could be related to the peer group as well

IDEA: ASDOT notation

Environment

  • Nautobot version: 1.5.0
  • nautobot-bgp-models version: 0.7.1

Proposed Functionality

32-bit ASN notations. Nautobot should be able to read and convert ASN between AS plain and AS dot notations.

Use Case

This enables human readable ASNs.

Device (routing-instance) specific Address Families

Address Families define how routing information for given IP protocol version is handled between the BGP peers.

Address Families could be both modelled via global and local approaches:

  • the global approach
  • the local approach, where each device could have its own Address Family instance.

This issue is to enable local address families and allow them to integrate with AddressFamiliyTemplates. With attribute inheritance, a local AF could inherit all of the attribute from a Global Template

Use cases solved:

  • integration with Address Family Templates
  • VRFs for address families
  • per-device overrides and customization.
  • device specific address family settings
  • "network x.x.x.x/x" prefix advertisements (possibly via relationship or future extension)
  • "redistribute connected/static/..." configuration statements (relationship or future extension)

Migrate CI to Github Actions

Environment

  • Nautobot version: latest
  • nautobot-bgp-models version: latest

Proposed Functionality

Replace Travis CI with Github actions

Use Case

Align with other NTC projects

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.