Skip to content

Commit

Permalink
Merge pull request #29 from fdomain/bgp-ui
Browse files Browse the repository at this point in the history
refactor: rework BGP sessions pages
  • Loading branch information
fdomain authored Mar 27, 2024
2 parents 21c3003 + 8d5e60c commit 8f4bcc0
Show file tree
Hide file tree
Showing 18 changed files with 377 additions and 31 deletions.
1 change: 1 addition & 0 deletions netbox_cmdb/netbox_cmdb/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Netbox CMDB plugin."""

from extras.plugins import PluginConfig


Expand Down
1 change: 1 addition & 0 deletions netbox_cmdb/netbox_cmdb/admin.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Admin module."""

from dcim.models import Device
from django.contrib import admin
from django.contrib.admin.options import StackedInline
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Route Policy serializers."""

from netbox_cmdb.api.common_serializers import CommonDeviceSerializer
from netbox_cmdb.models.bgp_community_list import BGPCommunityList, BGPCommunityListTerm
from rest_framework.serializers import ModelSerializer, ValidationError
Expand Down
1 change: 1 addition & 0 deletions netbox_cmdb/netbox_cmdb/api/bgp_community_list/views.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Route Policy views."""

from netbox_cmdb import filtersets
from netbox_cmdb.api.bgp_community_list.serializers import BGPCommunityListSerializer
from netbox_cmdb.api.viewsets import CustomNetBoxModelViewSet
Expand Down
1 change: 1 addition & 0 deletions netbox_cmdb/netbox_cmdb/api/prefix_list/serializers.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Prefix list serializers."""

from rest_framework.serializers import ModelSerializer, ValidationError

from netbox_cmdb.api.common_serializers import CommonDeviceSerializer
Expand Down
1 change: 1 addition & 0 deletions netbox_cmdb/netbox_cmdb/api/prefix_list/views.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Route Policy views."""

from netbox_cmdb import filtersets
from netbox_cmdb.api.prefix_list.serializers import PrefixListSerializer
from netbox_cmdb.api.viewsets import CustomNetBoxModelViewSet
Expand Down
1 change: 1 addition & 0 deletions netbox_cmdb/netbox_cmdb/api/route_policy/serializers.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Route Policy serializers."""

from django.core.exceptions import ValidationError
from netbox.api.serializers import WritableNestedSerializer
from rest_framework import serializers
Expand Down
6 changes: 3 additions & 3 deletions netbox_cmdb/netbox_cmdb/choices.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ class AssetMonitoringStateChoices(ChoiceSet):
DISABLED = "disabled"

CHOICES = (
(CRITICAL, "Critical"),
(WARNING, "Warning"),
(DISABLED, "Disabled"),
(CRITICAL, "Critical", "red"),
(WARNING, "Warning", "orange"),
(DISABLED, "Disabled", "gray"),
)


Expand Down
41 changes: 37 additions & 4 deletions netbox_cmdb/netbox_cmdb/filtersets.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import django_filters
from django.db.models import Q
from netbox.filtersets import ChangeLoggedModelFilterSet
from tenancy.filtersets import TenancyFilterSet
from tenancy.models import Tenant
from utilities.filters import MultiValueCharFilter

from netbox.filtersets import ChangeLoggedModelFilterSet
from netbox_cmdb.models.bgp import ASN, BGPPeerGroup, BGPSession

device_location_filterset = [
Expand All @@ -13,6 +12,8 @@
"device__site__group__name",
"device__site__region__name",
"device__rack__name",
"device__site__group_id",
"device__device_type_id",
]


Expand Down Expand Up @@ -69,11 +70,21 @@ class BGPSessionFilterSet(ChangeLoggedModelFilterSet, TenancyFilterSet):
label="device__site__group__name",
)

device__site__group_id = MultiValueCharFilter(
method="filter_device_location",
label="device__site__group",
)

device__site__region__name = MultiValueCharFilter(
method="filter_device_location",
label="device__site__region__name",
)

device__device_type_id = MultiValueCharFilter(
method="filter_device_type",
label="device__device_type",
)

local_address = MultiValueCharFilter(
method="filter_peer_address",
label="local_address",
Expand All @@ -82,7 +93,13 @@ class BGPSessionFilterSet(ChangeLoggedModelFilterSet, TenancyFilterSet):
class Meta:
model = BGPSession
exclude = ["__all__"]
fields = ["id", "device", "local_address"] + device_location_filterset
fields = [
"id",
"device",
"local_address",
"state",
"monitoring_state",
] + device_location_filterset

def filter_peer_address(self, queryset, name, value):
if len(value) > 2:
Expand Down Expand Up @@ -120,11 +137,27 @@ def filter_device_location(self, queryset, name, value):
queryset = queryset.filter(Q(**peer_a_lookup) | Q(**peer_b_lookup))
return queryset

def filter_device_type(self, queryset, name, value):
if len(value) > 2:
# a BGP session can't have more than 2 devices
return queryset.none()

for val in value:
# we chain the querysets to get a single BGP session when 2 values are passed
peer_a_lookup = {f"peer_a__{name}": val}
peer_b_lookup = {f"peer_b__{name}": val}

queryset = queryset.filter(Q(**peer_a_lookup) | Q(**peer_b_lookup)).distinct()
return queryset

def search(self, queryset, name, value):
if not value.strip():
return queryset
return queryset.filter(
Q(peer_a__device__name__icontains=value) | Q(peer_b__device__name__icontains=value)
Q(peer_a__device__name__icontains=value)
| Q(peer_a__description__icontains=value)
| Q(peer_b__device__name__icontains=value)
| Q(peer_b__description__icontains=value)
).distinct()


Expand Down
35 changes: 24 additions & 11 deletions netbox_cmdb/netbox_cmdb/forms.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
"""Forms."""

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.forms import NetBoxModelForm
from utilities.forms import DynamicModelMultipleChoiceField
from utilities.forms.fields import DynamicModelChoiceField
from utilities.forms.fields import DynamicModelChoiceField, MultipleChoiceField

from netbox.forms import NetBoxModelFilterSetForm, NetBoxModelForm
from netbox_cmdb.choices import AssetMonitoringStateChoices, AssetStateChoices
from netbox_cmdb.models.bgp import ASN, BGPPeerGroup, BGPSession


Expand All @@ -18,18 +23,26 @@ class Meta:


class BGPSessionForm(NetBoxModelForm):
tags = DynamicModelMultipleChoiceField(
queryset=Tag.objects.all(),
class Meta:
model = BGPSession
fields = ["peer_a", "peer_b", "state", "monitoring_state"]


class BGPSessionFilterSetForm(NetBoxModelFilterSetForm):
device__site__group_id = DynamicModelMultipleChoiceField(
queryset=SiteGroup.objects.all(),
label=_("Site"),
required=False,
)
device__device_type_id = DynamicModelMultipleChoiceField(
queryset=DeviceType.objects.all(),
label=_("Device type"),
required=False,
)
state = MultipleChoiceField(choices=AssetStateChoices, required=False)
monitoring_state = MultipleChoiceField(choices=AssetMonitoringStateChoices, required=False)

class Meta:
model = BGPSession
fields = [
"peer_a",
"peer_b",
"tags",
]
model = BGPSession


class BGPPeerGroupForm(NetBoxModelForm):
Expand Down
13 changes: 11 additions & 2 deletions netbox_cmdb/netbox_cmdb/models/bgp.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
from django.db import models
from django.db.models import Q
from django.urls import reverse
from netbox.models import ChangeLoggedModel
from utilities.choices import ChoiceSet
from utilities.querysets import RestrictedQuerySet

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.choices import AssetStateChoices, AssetMonitoringStateChoices
from netbox_cmdb.models.circuit import Circuit


Expand Down Expand Up @@ -357,3 +357,12 @@ def validate_unique(self, exclude=None):
)

super().validate_unique(exclude)

def get_state_color(self):
return AssetStateChoices.colors.get(self.state)

def get_monitoring_state_color(self):
return AssetMonitoringStateChoices.colors.get(self.monitoring_state)

def get_absolute_url(self):
return reverse("plugins:netbox_cmdb:bgpsession", args=[self.pk])
1 change: 1 addition & 0 deletions netbox_cmdb/netbox_cmdb/models/prefix_list.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Prefix list models."""

from django.core.exceptions import ValidationError
from django.db import models
from django.urls import reverse
Expand Down
1 change: 1 addition & 0 deletions netbox_cmdb/netbox_cmdb/navigation.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Navigation (menu)."""

from extras.plugins import PluginMenuButton, PluginMenuItem
from utilities.choices import ButtonColorChoices

Expand Down
26 changes: 20 additions & 6 deletions netbox_cmdb/netbox_cmdb/tables.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
"""Tables."""

import django_tables2 as tables
from netbox.tables import NetBoxTable

from netbox.tables import NetBoxTable, columns
from netbox_cmdb.models.bgp import ASN, BGPPeerGroup, BGPSession


Expand All @@ -15,15 +16,28 @@ class Meta(NetBoxTable.Meta):


class BGPSessionTable(NetBoxTable):
peer_a = tables.Column()
peer_b = tables.Column()
id = tables.Column(linkify=True)
peer_a__device = tables.Column(verbose_name="Device A")
peer_a__description = tables.Column(verbose_name="Device A description")
peer_a__local_address = tables.Column(verbose_name="Device A local address")
peer_b__device = tables.Column(verbose_name="Device B")
peer_b__description = tables.Column(verbose_name="Device B description")
peer_b__local_address = tables.Column(verbose_name="Device B local address")
state = columns.ChoiceFieldColumn()
monitoring_state = columns.ChoiceFieldColumn()

class Meta(NetBoxTable.Meta):
model = BGPSession
fields = (
"pk",
"peer_a",
"peer_b",
"id",
"peer_a__device",
"peer_a__description",
"peer_a__local_address",
"peer_b__device",
"peer_b__description",
"peer_b__local_address",
"state",
"monitoring_state",
)


Expand Down
Loading

0 comments on commit 8f4bcc0

Please sign in to comment.