diff --git a/netbox_cmdb/netbox_cmdb/api/bgp/serializers.py b/netbox_cmdb/netbox_cmdb/api/bgp/serializers.py
index 428bf43..4693417 100644
--- a/netbox_cmdb/netbox_cmdb/api/bgp/serializers.py
+++ b/netbox_cmdb/netbox_cmdb/api/bgp/serializers.py
@@ -1,13 +1,17 @@
from django.core.exceptions import ValidationError
from django.db.models import Q
from ipam.api.nested_serializers import NestedIPAddressSerializer
-from netbox.api.serializers import WritableNestedSerializer
from rest_framework import serializers
-from rest_framework.serializers import IntegerField, ModelSerializer
+from rest_framework.serializers import (
+ IntegerField,
+ ModelSerializer,
+ SerializerMethodField,
+)
from tenancy.api.nested_serializers import NestedTenantSerializer
-from netbox_cmdb.choices import AssetMonitoringStateChoices
+from netbox.api.serializers import WritableNestedSerializer
from netbox_cmdb.api.common_serializers import CommonDeviceSerializer
+from netbox_cmdb.choices import AssetMonitoringStateChoices
from netbox_cmdb.constants import BGP_MAX_ASN, BGP_MIN_ASN
from netbox_cmdb.models.bgp import (
ASN,
@@ -126,10 +130,15 @@ class DeviceBGPSessionSerializer(ModelSerializer):
route_policy_in = RoutePolicySerializer(required=False, many=False, allow_null=True)
route_policy_out = RoutePolicySerializer(required=False, many=False, allow_null=True)
+ display = SerializerMethodField(read_only=True)
+
class Meta:
model = DeviceBGPSession
fields = "__all__"
+ def get_display(self, obj):
+ return str(obj)
+
class CircuitSerializer(ModelSerializer):
class Meta:
@@ -141,6 +150,10 @@ class BGPSessionSerializer(ModelSerializer):
peer_a = DeviceBGPSessionSerializer(many=False)
peer_b = DeviceBGPSessionSerializer(many=False)
tenant = NestedTenantSerializer(required=False, many=False)
+ display = SerializerMethodField(read_only=True)
+
+ def get_display(self, obj):
+ return str(obj)
def create(self, validated_data):
peers_data = {}
diff --git a/netbox_cmdb/netbox_cmdb/api/bgp/views.py b/netbox_cmdb/netbox_cmdb/api/bgp/views.py
index 026aede..06617a1 100644
--- a/netbox_cmdb/netbox_cmdb/api/bgp/views.py
+++ b/netbox_cmdb/netbox_cmdb/api/bgp/views.py
@@ -2,12 +2,12 @@
from django.db import transaction
from django_pglocks import advisory_lock
from drf_yasg.utils import swagger_auto_schema
-from netbox.api.viewsets.mixins import ObjectValidationMixin
from rest_framework import status
from rest_framework.exceptions import ValidationError
from rest_framework.response import Response
from rest_framework.views import APIView
+from netbox.api.viewsets.mixins import ObjectValidationMixin
from netbox_cmdb import filtersets
from netbox_cmdb.api.bgp.serializers import (
AvailableAsnSerializer,
@@ -15,10 +15,21 @@
BGPGlobalSerializer,
BGPPeerGroupSerializer,
BGPSessionSerializer,
+ DeviceBGPSessionSerializer,
)
from netbox_cmdb.api.viewsets import CustomNetBoxModelViewSet
-from netbox_cmdb.filtersets import ASNFilterSet, BGPSessionFilterSet
-from netbox_cmdb.models.bgp import ASN, BGPGlobal, BGPPeerGroup, BGPSession
+from netbox_cmdb.filtersets import (
+ ASNFilterSet,
+ BGPSessionFilterSet,
+ DeviceBGPSessionFilterSet,
+)
+from netbox_cmdb.models.bgp import (
+ ASN,
+ BGPGlobal,
+ BGPPeerGroup,
+ BGPSession,
+ DeviceBGPSession,
+)
class ASNViewSet(CustomNetBoxModelViewSet):
@@ -96,6 +107,12 @@ class BGPSessionsViewSet(CustomNetBoxModelViewSet):
filterset_class = BGPSessionFilterSet
+class DeviceBGPSessionsViewSet(CustomNetBoxModelViewSet):
+ queryset = DeviceBGPSession.objects.all()
+ serializer_class = DeviceBGPSessionSerializer
+ filterset_class = DeviceBGPSessionFilterSet
+
+
class BGPPeerGroupViewSet(CustomNetBoxModelViewSet):
queryset = BGPPeerGroup.objects.all()
serializer_class = BGPPeerGroupSerializer
diff --git a/netbox_cmdb/netbox_cmdb/api/route_policy/serializers.py b/netbox_cmdb/netbox_cmdb/api/route_policy/serializers.py
index 51e5119..68d02b9 100644
--- a/netbox_cmdb/netbox_cmdb/api/route_policy/serializers.py
+++ b/netbox_cmdb/netbox_cmdb/api/route_policy/serializers.py
@@ -1,10 +1,10 @@
"""Route Policy serializers."""
from django.core.exceptions import ValidationError
-from netbox.api.serializers import WritableNestedSerializer
from rest_framework import serializers
-from rest_framework.serializers import ModelSerializer
+from rest_framework.serializers import ModelSerializer, SerializerMethodField
+from netbox.api.serializers import WritableNestedSerializer
from netbox_cmdb.api.bgp.serializers import AsnSerializer
from netbox_cmdb.api.common_serializers import CommonDeviceSerializer
from netbox_cmdb.models.bgp_community_list import BGPCommunityList
@@ -68,12 +68,15 @@ class Meta:
class WritableRoutePolicySerializer(ModelSerializer):
device = CommonDeviceSerializer()
-
terms = RoutePolicyTermSerializer(many=True, source="route_policy_term")
+ display = SerializerMethodField(read_only=True)
class Meta:
model = RoutePolicy
- fields = ["id", "name", "device", "description", "terms"]
+ fields = ["id", "name", "device", "description", "terms", "display"]
+
+ def get_display(self, obj):
+ return obj.name
def _validate_terms(self, terms_data):
if len(terms_data) < 1:
diff --git a/netbox_cmdb/netbox_cmdb/api/route_policy/views.py b/netbox_cmdb/netbox_cmdb/api/route_policy/views.py
index ad83aea..bc976d8 100644
--- a/netbox_cmdb/netbox_cmdb/api/route_policy/views.py
+++ b/netbox_cmdb/netbox_cmdb/api/route_policy/views.py
@@ -1,18 +1,12 @@
"""Route Policy views."""
-from netbox_cmdb import filtersets
-
from netbox_cmdb.api.route_policy.serializers import WritableRoutePolicySerializer
from netbox_cmdb.api.viewsets import CustomNetBoxModelViewSet
+from netbox_cmdb.filtersets import RoutePolicyFilterSet
from netbox_cmdb.models.route_policy import RoutePolicy
class RoutePolicyViewSet(CustomNetBoxModelViewSet):
queryset = RoutePolicy.objects.all()
serializer_class = WritableRoutePolicySerializer
- filterset_fields = [
- "id",
- "name",
- "device__id",
- "device__name",
- ] + filtersets.device_location_filterset
+ filterset_class = RoutePolicyFilterSet
diff --git a/netbox_cmdb/netbox_cmdb/api/urls.py b/netbox_cmdb/netbox_cmdb/api/urls.py
index 0a7edbb..30512b1 100644
--- a/netbox_cmdb/netbox_cmdb/api/urls.py
+++ b/netbox_cmdb/netbox_cmdb/api/urls.py
@@ -7,6 +7,7 @@
BGPGlobalViewSet,
BGPPeerGroupViewSet,
BGPSessionsViewSet,
+ DeviceBGPSessionsViewSet,
)
from netbox_cmdb.api.bgp_community_list.views import BGPCommunityListViewSet
from netbox_cmdb.api.prefix_list.views import PrefixListViewSet
@@ -18,6 +19,7 @@
router.register("asns", ASNViewSet)
router.register("bgp-global", BGPGlobalViewSet)
router.register("bgp-sessions", BGPSessionsViewSet)
+router.register("device-bgp-sessions", DeviceBGPSessionsViewSet)
router.register("bgp-community-lists", BGPCommunityListViewSet)
router.register("peer-groups", BGPPeerGroupViewSet)
router.register("prefix-lists", PrefixListViewSet)
diff --git a/netbox_cmdb/netbox_cmdb/filtersets.py b/netbox_cmdb/netbox_cmdb/filtersets.py
index d5edcc5..3405afa 100644
--- a/netbox_cmdb/netbox_cmdb/filtersets.py
+++ b/netbox_cmdb/netbox_cmdb/filtersets.py
@@ -5,7 +5,8 @@
from utilities.filters import MultiValueCharFilter
from netbox.filtersets import ChangeLoggedModelFilterSet
-from netbox_cmdb.models.bgp import ASN, BGPPeerGroup, BGPSession
+from netbox_cmdb.models.bgp import ASN, BGPPeerGroup, BGPSession, DeviceBGPSession
+from netbox_cmdb.models.route_policy import RoutePolicy
device_location_filterset = [
"device__location__name",
@@ -162,6 +163,44 @@ def search(self, queryset, name, value):
).distinct()
+class DeviceBGPSessionFilterSet(ChangeLoggedModelFilterSet):
+ """Device BGP Session filterset."""
+
+ q = django_filters.CharFilter(
+ method="search",
+ label="Search",
+ )
+
+ class Meta:
+ model = DeviceBGPSession
+ fields = ["id", "device__name", "local_address", "local_asn"]
+
+ def search(self, queryset, name, value):
+ if not value.strip():
+ return queryset
+ return queryset.filter(
+ Q(device__name__icontains=value) | Q(description__icontains=value)
+ ).distinct()
+
+
+class RoutePolicyFilterSet(ChangeLoggedModelFilterSet):
+ """Route Policy filterset."""
+
+ q = django_filters.CharFilter(
+ method="search",
+ label="Search",
+ )
+
+ class Meta:
+ model = RoutePolicy
+ fields = ["id", "device__id", "device__name", "name"] + device_location_filterset
+
+ def search(self, queryset, name, value):
+ if not value.strip():
+ return queryset
+ return queryset.filter(name__icontains=value)
+
+
class BGPPeerGroupFilterSet(ChangeLoggedModelFilterSet):
"""BGP Session filterset."""
diff --git a/netbox_cmdb/netbox_cmdb/forms.py b/netbox_cmdb/netbox_cmdb/forms.py
index ee5dbe9..78b1c65 100644
--- a/netbox_cmdb/netbox_cmdb/forms.py
+++ b/netbox_cmdb/netbox_cmdb/forms.py
@@ -1,19 +1,22 @@
"""Forms."""
+from typing import Any, Sequence
+
from dcim.models import Device
from dcim.models.devices import DeviceType
from dcim.models.sites import SiteGroup
from django import forms
from django.utils.translation import gettext as _
from extras.models import Tag
-from netbox_cmdb.models.snmp import SNMP, SNMPCommunity
-from netbox_cmdb.constants import MAX_COMMUNITY_PER_DEVICE
from utilities.forms import DynamicModelMultipleChoiceField
from utilities.forms.fields import DynamicModelChoiceField, MultipleChoiceField
from netbox.forms import NetBoxModelFilterSetForm, NetBoxModelForm
-from netbox_cmdb.choices import AssetMonitoringStateChoices, AssetStateChoices, SNMPCommunityType
-from netbox_cmdb.models.bgp import ASN, BGPPeerGroup, BGPSession
+from netbox_cmdb.choices import AssetMonitoringStateChoices, AssetStateChoices
+from netbox_cmdb.constants import MAX_COMMUNITY_PER_DEVICE
+from netbox_cmdb.models.bgp import ASN, BGPPeerGroup, BGPSession, DeviceBGPSession
+from netbox_cmdb.models.route_policy import RoutePolicy
+from netbox_cmdb.models.snmp import SNMP, SNMPCommunity
class ASNForm(NetBoxModelForm):
@@ -25,9 +28,56 @@ class Meta:
class BGPSessionForm(NetBoxModelForm):
+ peer_a = DynamicModelChoiceField(
+ queryset=DeviceBGPSession.objects.all(),
+ label=_("Peer A"),
+ required=True,
+ )
+ peer_b = DynamicModelChoiceField(
+ queryset=DeviceBGPSession.objects.all(),
+ label=_("Peer B"),
+ required=True,
+ )
+
class Meta:
model = BGPSession
- fields = ["peer_a", "peer_b", "state", "monitoring_state"]
+ fields = ["peer_a", "peer_b", "state", "monitoring_state", "tenant"]
+
+
+class DeviceBGPSessionForm(NetBoxModelForm):
+ def __init__(self, *args, **kwargs):
+ instance = kwargs.get("instance")
+ initial = kwargs.get("initial", {})
+ if instance is not None and instance.device:
+ initial["device"] = str(instance.device)
+ kwargs["initial"] = initial
+ super().__init__(*args, **kwargs)
+
+ device = forms.CharField(disabled=True)
+ route_policy_in = DynamicModelChoiceField(
+ queryset=RoutePolicy.objects.all(),
+ label=_("Route Policy in"),
+ query_params={
+ "device__id": "$device",
+ },
+ to_field_name="name",
+ fetch_trigger="open",
+ required=False,
+ )
+ route_policy_out = DynamicModelChoiceField(
+ queryset=RoutePolicy.objects.all(),
+ label=_("Route Policy out"),
+ query_params={
+ "device__id": "$device",
+ },
+ to_field_name="name",
+ fetch_trigger="open",
+ required=False,
+ )
+
+ class Meta:
+ model = DeviceBGPSession
+ fields = ["device", "route_policy_in", "route_policy_out"]
class BGPSessionFilterSetForm(NetBoxModelFilterSetForm):
@@ -67,6 +117,31 @@ class Meta:
]
+class RoutePolicyForm(NetBoxModelForm):
+ device = DynamicModelChoiceField(queryset=Device.objects.all())
+
+ class Meta:
+ model = RoutePolicy
+ fields = [
+ "name",
+ "device",
+ "description",
+ ]
+
+
+class RoutePolicyFilterSetForm(NetBoxModelFilterSetForm):
+ device__id = DynamicModelMultipleChoiceField(
+ queryset=Device.objects.all(),
+ label=_("Device"),
+ required=False,
+ )
+ name = forms.CharField(
+ required=False,
+ )
+
+ model = RoutePolicy
+
+
class InlineTermForm(forms.models.BaseInlineFormSet):
"""InlineTermForm is a form that require at least one item to be valid.
It is useful for following models:
diff --git a/netbox_cmdb/netbox_cmdb/models/bgp.py b/netbox_cmdb/netbox_cmdb/models/bgp.py
index e2e4b30..7ed54fd 100644
--- a/netbox_cmdb/netbox_cmdb/models/bgp.py
+++ b/netbox_cmdb/netbox_cmdb/models/bgp.py
@@ -10,7 +10,6 @@
from netbox.models import ChangeLoggedModel
from netbox_cmdb.choices import AssetMonitoringStateChoices, AssetStateChoices
from netbox_cmdb.constants import BGP_MAX_ASN, BGP_MIN_ASN
-from netbox_cmdb.models.circuit import Circuit
class BGPGlobal(ChangeLoggedModel):
diff --git a/netbox_cmdb/netbox_cmdb/models/route_policy.py b/netbox_cmdb/netbox_cmdb/models/route_policy.py
index 7f4548c..cff8789 100644
--- a/netbox_cmdb/netbox_cmdb/models/route_policy.py
+++ b/netbox_cmdb/netbox_cmdb/models/route_policy.py
@@ -1,8 +1,9 @@
from django.core.exceptions import ValidationError
from django.db import models
-from netbox.models import ChangeLoggedModel
+from django.urls import reverse
from utilities.querysets import RestrictedQuerySet
+from netbox.models import ChangeLoggedModel
from netbox_cmdb.choices import DecisionChoice
from netbox_cmdb.fields import CustomIPAddressField
@@ -26,11 +27,14 @@ class RoutePolicy(ChangeLoggedModel):
objects = RestrictedQuerySet.as_manager()
def __str__(self):
- return f"{self.device}--{self.name}"
+ return str(self.name)
def __repr__(self):
return str(self.name)
+ def get_absolute_url(self):
+ return reverse("plugins:netbox_cmdb:routepolicy", args=[self.pk])
+
class Meta:
verbose_name_plural = "Route Policies"
unique_together = ["device", "name"]
diff --git a/netbox_cmdb/netbox_cmdb/navigation.py b/netbox_cmdb/netbox_cmdb/navigation.py
index 246e69a..55bb2a5 100644
--- a/netbox_cmdb/netbox_cmdb/navigation.py
+++ b/netbox_cmdb/netbox_cmdb/navigation.py
@@ -40,6 +40,18 @@
),
),
),
+ PluginMenuItem(
+ link="plugins:netbox_cmdb:routepolicy_list",
+ link_text="Route Policies",
+ buttons=(
+ PluginMenuButton(
+ link="plugins:netbox_cmdb:routepolicy_add",
+ title="Route Policies",
+ icon_class="mdi mdi-plus-thick",
+ color=ButtonColorChoices.GREEN,
+ ),
+ ),
+ ),
PluginMenuItem(
link="plugins:netbox_cmdb:snmp_list",
link_text="SNMP",
diff --git a/netbox_cmdb/netbox_cmdb/tables.py b/netbox_cmdb/netbox_cmdb/tables.py
index b4a5dec..9bea1b0 100644
--- a/netbox_cmdb/netbox_cmdb/tables.py
+++ b/netbox_cmdb/netbox_cmdb/tables.py
@@ -3,7 +3,8 @@
import django_tables2 as tables
from netbox.tables import NetBoxTable, columns
-from netbox_cmdb.models.bgp import ASN, BGPPeerGroup, BGPSession
+from netbox_cmdb.models.bgp import ASN, BGPPeerGroup, BGPSession, DeviceBGPSession
+from netbox_cmdb.models.route_policy import RoutePolicy
from netbox_cmdb.models.snmp import SNMP, SNMPCommunity
@@ -42,27 +43,64 @@ class Meta(NetBoxTable.Meta):
)
+class DeviceBGPSessionTable(NetBoxTable):
+ id = tables.Column()
+ device = tables.Column(verbose_name="Device")
+ description = tables.Column(verbose_name="Description")
+ local_address = tables.Column(verbose_name="Local address")
+ local_asn = tables.Column(verbose_name="Local ASN")
+ route_policy_in = tables.Column(verbose_name="Route Policy in")
+ route_policy_out = tables.Column(verbose_name="Route Policy out")
+ maximum_prefixes = tables.Column(verbose_name="Maximum prefixes")
+
+ class Meta(NetBoxTable.Meta):
+ model = DeviceBGPSession
+ fields = (
+ "id",
+ "device",
+ "description",
+ "local_address",
+ "local_asn",
+ "route_policy_in",
+ "route_policy_out",
+ "maximum_prefixes",
+ )
+
+
class BGPPeerGroupTable(NetBoxTable):
- device = tables.LinkColumn()
- name = tables.LinkColumn()
- asn = tables.Column()
- route_policy_in = tables.Column()
- route_policy_out = tables.Column()
+ name = tables.Column(linkify=True)
+ device = tables.Column(linkify=True)
+ local_asn = tables.Column(linkify=True)
+ remote_asn = tables.Column(linkify=True)
+ route_policy_in = tables.Column(linkify=True)
+ route_policy_out = tables.Column(linkify=True)
maximum_prefixes = tables.Column()
+ refcount = tables.Column()
class Meta(NetBoxTable.Meta):
model = BGPPeerGroup
fields = (
- "pk",
"name",
+ "device",
"local_asn",
"remote_asn",
"route_policy_in",
"route_policy_out",
"maximum_prefixes",
+ "refcount",
)
+class RoutePolicyTable(NetBoxTable):
+ device = tables.Column(linkify=True)
+ name = tables.Column(linkify=True)
+ refcount = tables.Column()
+
+ class Meta(NetBoxTable.Meta):
+ model = RoutePolicy
+ fields = ("name", "device", "refcount")
+
+
class SNMPTable(NetBoxTable):
device = tables.LinkColumn()
diff --git a/netbox_cmdb/netbox_cmdb/templates/netbox_cmdb/bgpsession.html b/netbox_cmdb/netbox_cmdb/templates/netbox_cmdb/bgpsession.html
index b0f57aa..d5f65f2 100644
--- a/netbox_cmdb/netbox_cmdb/templates/netbox_cmdb/bgpsession.html
+++ b/netbox_cmdb/netbox_cmdb/templates/netbox_cmdb/bgpsession.html
@@ -8,39 +8,39 @@
- Device
+ | Device |
{{ object.peer_a.device|linkify}} |
- Description
+ | Description |
{{ object.peer_a.description }} |
- Local address
+ | Local address |
{{ object.peer_a.local_address|linkify}} |
- Local ASN
+ | Local ASN |
{{ object.peer_a.local_asn|linkify}} |
- Route Policy in
+ | Route Policy in |
{{ object.peer_a.route_policy_in|placeholder}} |
- Route Policy out
+ | Route Policy out |
{{ object.peer_a.route_policy_out|placeholder}} |
- Maximum prefixes
+ | Maximum prefixes |
{{ object.peer_a.maximum_prefixes }} |
- Enforce First AS
+ | Enforce First AS |
{% checkmark object.peer_a.enforce_first_as %} |
- Enabled
+ | Enabled |
{% checkmark object.peer_a.enabled %} |
@@ -87,10 +87,6 @@
Circuit |
{{ object.circuit|placeholder }} |
-
- Tenant |
- {{ object.tenant|placeholder|linkify }} |
-
@@ -101,39 +97,39 @@
- Device
+ | Device |
{{ object.peer_b.device|linkify}} |
- Description
+ | Description |
{{ object.peer_b.description }} |
- Local address
+ | Local address |
{{ object.peer_b.local_address|linkify}} |
- Local ASN
+ | Local ASN |
{{ object.peer_b.local_asn|linkify}} |
- Route Policy in
+ | Route Policy in |
{{ object.peer_b.route_policy_in|placeholder}} |
- Route Policy out
+ | Route Policy out |
{{ object.peer_b.route_policy_out|placeholder}} |
- Maximum prefixes
+ | Maximum prefixes |
{{ object.peer_b.maximum_prefixes }} |
- Enforce First AS
+ | Enforce First AS |
{% checkmark object.peer_b.enforce_first_as %} |
- Enabled
+ | Enabled |
{% checkmark object.peer_b.enabled %} |
@@ -169,7 +165,7 @@
PG Name
- | {{ object.peer_a.peer_group.name}} |
+ {{ object.peer_a.peer_group | linkify:"name" }} |
Description
@@ -185,11 +181,11 @@
|
Route Policy in
- | {{ object.peer_a.peer_group.route_policy_in.name|placeholder}} |
+ {{ object.peer_a.peer_group.route_policy_in|placeholder|linkify:"name"}} |
Route Policy out
- | {{ object.peer_a.peer_group.route_policy_out.name|placeholder}} |
+ {{ object.peer_a.peer_group.route_policy_out|placeholder|linkify:"name"}} |
Maximum prefixes
@@ -210,7 +206,7 @@
PG Name
- | {{ object.peer_b.peer_group.name}} |
+ {{ object.peer_b.peer_group | linkify:"name" }} |
Description
@@ -226,11 +222,11 @@
|
Route Policy in
- | {{ object.peer_b.peer_group.route_policy_in.name|placeholder}} |
+ {{ object.peer_b.peer_group.route_policy_in|placeholder|linkify:"name"}} |
Route Policy out
- | {{ object.peer_b.peer_group.route_policy_out.name|placeholder}} |
+ {{ object.peer_b.peer_group.route_policy_out|placeholder|linkify:"name"}} |
Maximum prefixes
diff --git a/netbox_cmdb/netbox_cmdb/templates/netbox_cmdb/routepolicy.html b/netbox_cmdb/netbox_cmdb/templates/netbox_cmdb/routepolicy.html
new file mode 100644
index 0000000..4dd3dda
--- /dev/null
+++ b/netbox_cmdb/netbox_cmdb/templates/netbox_cmdb/routepolicy.html
@@ -0,0 +1,96 @@
+{% extends 'generic/object.html' %} {% block content %}
+
+
+
+
+
+
+
+ Name |
+ {{ object.name }} |
+
+
+ Device |
+ {{ object.device|linkify }} |
+
+
+ Description |
+ {{ object.description }} |
+
+
+
+
+
+
+
+
+
+
+
+
+ Seq |
+ Decision |
+ Conditions |
+ Actions |
+
+
+
+ {% for term in object.route_policy_term.all %}
+
+ {{ term.sequence }} |
+ {{ term.decision }} |
+
+ {% if term.from_bgp_community %}
+ from_bgp_community {{ term.from_bgp_community }}
+ {% endif %}
+ {% if term.from_bgp_community_list %}
+ from_bgp_community_list {{ term.from_bgp_community_list.name }}
+ {% endif %}
+ {% if term.from_prefix_list %}
+ from_prefix_list {{ term.from_prefix_list.name }}
+ {% endif %}
+ {% if term.from_source_protocol %}
+ from_source_protocol {{ term.from_source_protocol }}
+ {% endif %}
+ {% if term.from_route_type %}
+ from_route_type {{ term.from_route_type }}
+ {% endif %}
+ {% if term.from_local_pref %}
+ from_local_pref {{ term.from_local_pref }}
+ {% endif %}
+ |
+
+ {% if term.set_local_pref %}
+ set_local_pref {{ term.set_local_pref }}
+ {% endif %}
+ {% if term.set_community %}
+ set_community {{ term.set_community }}
+ {% endif %}
+ {% if term.set_origin %}
+ set_origin {{ term.set_origin }}
+ {% endif %}
+ {% if term.set_metric %}
+ set_metric {{ term.set_metric }}
+ {% endif %}
+ {% if term.set_large_community %}
+ set_large_community {{ term.set_large_community }}
+ {% endif %}
+ {% if term.set_as_path_prepend_asn %}
+ set_as_path_prepend_asn {{ term.set_as_path_prepend_asn }}
+ {% endif %}
+ {% if term.set_as_path_prepend_repeat %}
+ set_as_path_prepend_repeat {{ term.set_as_path_prepend_repeat }}
+ {% endif %}
+ {% if term.set_next_hop %}
+ set_next_hop {{ term.set_next_hop }}
+ {% endif %}
+ |
+
+ {% endfor %}
+
+
+
+
+
+
+{% endblock %}
diff --git a/netbox_cmdb/netbox_cmdb/urls.py b/netbox_cmdb/netbox_cmdb/urls.py
index f774d62..fced042 100644
--- a/netbox_cmdb/netbox_cmdb/urls.py
+++ b/netbox_cmdb/netbox_cmdb/urls.py
@@ -5,6 +5,7 @@
from netbox_cmdb.models.bgp import *
from netbox_cmdb.models.snmp import SNMP, SNMPCommunity
+from netbox_cmdb.models.route_policy import RoutePolicy
from netbox_cmdb.views import (
ASNDeleteView,
ASNEditView,
@@ -25,6 +26,14 @@
SNMPDeleteView,
SNMPEditView,
SNMPListView,
+ DeviceBGPSessionEditView,
+ DeviceBGPSessionListView,
+ DeviceBGPSessionView,
+ DeviecBGPSessionDeleteView,
+ RoutePolicyDeleteView,
+ RoutePolicyEditView,
+ RoutePolicyListView,
+ RoutePolicyView,
)
urlpatterns = [
@@ -73,6 +82,26 @@
name="bgpsession_journal",
kwargs={"model": BGPSession},
),
+ # Device BGP session
+ path("device-bgp-session/", DeviceBGPSessionListView.as_view(), name="devicebgpsession_list"),
+ path("device-bgp-session/add", DeviceBGPSessionEditView.as_view(), name="devicebgpsession_add"),
+ path("device-bgp-session//", DeviceBGPSessionView.as_view(), name="devicebgpsession"),
+ path(
+ "device-bgp-session//edit",
+ DeviceBGPSessionEditView.as_view(),
+ name="devicebgpsession_edit",
+ ),
+ path(
+ "device-bgp-session//delete",
+ DeviecBGPSessionDeleteView.as_view(),
+ name="devicebgpsession_delete",
+ ),
+ path(
+ "device-bgp-session//changelog/",
+ ObjectChangeLogView.as_view(),
+ name="devicebgpsession_changelog",
+ kwargs={"model": DeviceBGPSession},
+ ),
# Peer Group
path("peer-group/", BGPPeerGroupListView.as_view(), name="bgppeergroup_list"),
path("peer-group/add/", BGPPeerGroupEditView.as_view(), name="bgppeergroup_add"),
@@ -99,6 +128,32 @@
name="bgppeergroup_journal",
kwargs={"model": BGPPeerGroup},
),
+ # Route Policy
+ path("route-policy/", RoutePolicyListView.as_view(), name="routepolicy_list"),
+ path("route-policy/add/", RoutePolicyEditView.as_view(), name="routepolicy_add"),
+ path("route-policy//", RoutePolicyView.as_view(), name="routepolicy"),
+ path(
+ "route-policy//edit/",
+ RoutePolicyEditView.as_view(),
+ name="routepolicy_edit",
+ ),
+ path(
+ "route-policy//delete/",
+ RoutePolicyDeleteView.as_view(),
+ name="routepolicy_delete",
+ ),
+ path(
+ "route-policy//changelog/",
+ ObjectChangeLogView.as_view(),
+ name="routepolicy_changelog",
+ kwargs={"model": RoutePolicy},
+ ),
+ path(
+ "route-policy//journal/",
+ ObjectJournalView.as_view(),
+ name="routepolicy_journal",
+ kwargs={"model": RoutePolicy},
+ ),
# SNMP
path("snmp/", SNMPListView.as_view(), name="snmp_list"),
path("snmp/add/", SNMPEditView.as_view(), name="snmp_add"),
diff --git a/netbox_cmdb/netbox_cmdb/views.py b/netbox_cmdb/netbox_cmdb/views.py
index 4a4521f..5a6de8b 100644
--- a/netbox_cmdb/netbox_cmdb/views.py
+++ b/netbox_cmdb/netbox_cmdb/views.py
@@ -1,5 +1,7 @@
"""Views."""
+from utilities.utils import count_related
+
from netbox.views.generic import (
ObjectDeleteView,
ObjectEditView,
@@ -11,6 +13,8 @@
ASNFilterSet,
BGPPeerGroupFilterSet,
BGPSessionFilterSet,
+ DeviceBGPSessionFilterSet,
+ RoutePolicyFilterSet,
SNMPFilterSet,
)
from netbox_cmdb.forms import (
@@ -18,15 +22,27 @@
BGPPeerGroupForm,
BGPSessionFilterSetForm,
BGPSessionForm,
+ DeviceBGPSessionForm,
+ RoutePolicyFilterSetForm,
+ RoutePolicyForm,
SNMPCommunityGroupForm,
SNMPGroupForm,
)
-from netbox_cmdb.models.bgp import ASN, BGPPeerGroup, BGPSession, DeviceBGPSession
+from netbox_cmdb.models.bgp import (
+ ASN,
+ AfiSafi,
+ BGPPeerGroup,
+ BGPSession,
+ DeviceBGPSession,
+)
+from netbox_cmdb.models.route_policy import RoutePolicy
from netbox_cmdb.models.snmp import SNMP, SNMPCommunity
from netbox_cmdb.tables import (
ASNTable,
BGPPeerGroupTable,
BGPSessionTable,
+ DeviceBGPSessionTable,
+ RoutePolicyTable,
SNMPCommunityTable,
SNMPTable,
)
@@ -86,23 +102,37 @@ class BGPSessionView(ObjectView):
).all()
template_name = "netbox_cmdb/bgpsession.html"
- def get_extra_context(self, request, instance):
- # Get AFI/SAFIS
- peer_a_afi_safis = []
- peer_b_afi_safis = []
- if instance.peer_a.afi_safis is not None:
- peer_a_afi_safis = instance.peer_a.afi_safis.all()
- if instance.peer_b.afi_safis is not None:
- peer_b_afi_safis = instance.peer_b.afi_safis.all()
- return {
- "peer_a_afi_safis": peer_a_afi_safis,
- "peer_b_afi_safis": peer_b_afi_safis,
- }
+
+## DeviceBGPSession views
+class DeviceBGPSessionListView(ObjectListView):
+ queryset = DeviceBGPSession.objects.all()
+ filterset = DeviceBGPSessionFilterSet
+ table = DeviceBGPSessionTable
+
+
+class DeviceBGPSessionView(ObjectView):
+ queryset = DeviceBGPSession.objects.all()
+
+
+class DeviceBGPSessionEditView(ObjectEditView):
+ queryset = DeviceBGPSession.objects.all()
+ form = DeviceBGPSessionForm
+ filterset = DeviceBGPSessionFilterSet
+
+
+class DeviecBGPSessionDeleteView(ObjectDeleteView):
+ queryset = DeviceBGPSession.objects.all()
+
+
+class DeviecBGPSessionBulkDeleteView(BulkDeleteView):
+ queryset = DeviceBGPSession.objects.all()
+ filterset = DeviceBGPSessionFilterSet
+ table = DeviceBGPSessionTable
## Peer groups views
class BGPPeerGroupListView(ObjectListView):
- queryset = BGPPeerGroup.objects.all()
+ queryset = BGPPeerGroup.objects.annotate(refcount=count_related(DeviceBGPSession, "peer_group"))
filterset = BGPPeerGroupFilterSet
table = BGPPeerGroupTable
template_name = "netbox_cmdb/bgppeergroup_list.html"
@@ -122,6 +152,49 @@ class BGPPeerGroupView(ObjectView):
template_name = "netbox_cmdb/bgppeergroup.html"
+## Route policy views
+
+
+class RoutePolicyListView(ObjectListView):
+ queryset = RoutePolicy.objects.annotate(
+ refcount=sum(
+ [
+ count_related(AfiSafi, "route_policy_in"),
+ count_related(AfiSafi, "route_policy_out"),
+ count_related(DeviceBGPSession, "route_policy_in"),
+ count_related(DeviceBGPSession, "route_policy_out"),
+ count_related(BGPPeerGroup, "route_policy_in"),
+ count_related(BGPPeerGroup, "route_policy_out"),
+ ]
+ )
+ )
+ filterset_form = RoutePolicyFilterSetForm
+ filterset = RoutePolicyFilterSet
+ table = RoutePolicyTable
+
+
+class RoutePolicyView(ObjectView):
+ queryset = RoutePolicy.objects.prefetch_related("route_policy_term").all()
+ template_name = "netbox_cmdb/routepolicy.html"
+
+
+class RoutePolicyEditView(ObjectEditView):
+ model = RoutePolicy
+ queryset = RoutePolicy.objects.prefetch_related("route_policy_term").all()
+ form = RoutePolicyForm
+ filterset = RoutePolicyFilterSet
+
+
+class RoutePolicyDeleteView(ObjectDeleteView):
+ queryset = RoutePolicy.objects.all()
+
+
+class RoutePolicyBulkDeleteView(BulkDeleteView):
+ queryset = RoutePolicy.objects.all()
+ filterset = RoutePolicyFilterSet
+ table = RoutePolicyTable
+
+
## Snmp groups views
class SNMPListView(ObjectListView):
queryset = SNMP.objects.all()
| |