Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: rework BGP sessions pages #29

Merged
merged 2 commits into from
Mar 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading