Skip to content

Commit

Permalink
Merge pull request #1 from DanSheps/develop
Browse files Browse the repository at this point in the history
Static Routing
  • Loading branch information
DanSheps authored Apr 4, 2022
2 parents 53ecfd9 + 5aaeec0 commit d3c1e60
Show file tree
Hide file tree
Showing 44 changed files with 1,404 additions and 5 deletions.
7 changes: 3 additions & 4 deletions netbox_routing/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from extras.plugins import PluginConfig


try:
from importlib.metadata import metadata
except ModuleNotFoundError:
Expand All @@ -16,11 +15,11 @@ class NetboxRouting(PluginConfig):
version = plugin.get('Version')
author = plugin.get('Author')
author_email = plugin.get('Author-email')
base_url = 'netbox-plugin-extensions'
min_version = '3.2'
base_url = 'routing'
min_version = '3.2.0b1'
required_settings = []
caching_config = {}
default_settings = {}


config = NetboxPluginExtensions
config = NetboxRouting
Empty file added netbox_routing/api/__init__.py
Empty file.
12 changes: 12 additions & 0 deletions netbox_routing/api/nested_serializers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from .static import NestedStaticRouteSerializer
from .objects import NestedPrefixListSerializer, NestedPrefixListEntrySerializer, NestedRouteMapSerializer,\
NestedRouteMapEntrySerializer

__all__ = (
'NestedStaticRouteSerializer',

'NestedPrefixListSerializer',
'NestedPrefixListEntrySerializer',
'NestedRouteMapSerializer',
'NestedRouteMapEntrySerializer',
)
43 changes: 43 additions & 0 deletions netbox_routing/api/nested_serializers/objects.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
from rest_framework import serializers

from netbox.api import WritableNestedSerializer
from netbox_routing.models import PrefixList, PrefixListEntry, RouteMap, RouteMapEntry


__all__ = (
'NestedStaticRouteSerializer'
)


class NestedPrefixListSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='plugins-api:netbox_routing-api:prefixlist-detail')

class Meta:
model = PrefixList
fields = ('url', 'id', 'name')


class NestedPrefixListEntrySerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='plugins-api:netbox_routing-api:prefixlist-detail')
prefix_list = NestedPrefixListSerializer

class Meta:
model = PrefixListEntry
fields = ('url', 'id', 'prefix_list')


class NestedRouteMapSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='plugins-api:netbox_routing-api:prefixlist-detail')

class Meta:
model = RouteMap
fields = ('url', 'id', 'name')


class NestedRouteMapEntrySerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='plugins-api:netbox_routing-api:prefixlist-detail')
route_map = NestedRouteMapSerializer

class Meta:
model = RouteMapEntry
fields = ('url', 'id', 'route_map')
17 changes: 17 additions & 0 deletions netbox_routing/api/nested_serializers/static.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from rest_framework import serializers

from netbox.api import WritableNestedSerializer
from netbox_routing.models import StaticRoute


__all__ = (
'NestedStaticRouteSerializer'
)


class NestedStaticRouteSerializer(WritableNestedSerializer):
url = serializers.HyperlinkedIdentityField(view_name='plugins-api:netbox_routing-api:staticroute-detail')

class Meta:
model = StaticRoute
fields = ('url', 'id', 'prefix', 'next_hop', 'name', 'metric', 'permanent')
11 changes: 11 additions & 0 deletions netbox_routing/api/serializers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from .static import StaticRouteSerializer
from .objects import PrefixListSerializer, PrefixListEntrySerializer, RouteMapSerializer, RouteMapEntrySerializer

__all__ = (
'StaticRouteSerializer',

'PrefixListSerializer',
'PrefixListEntrySerializer',
'RouteMapSerializer',
'RouteMapEntrySerializer',
)
45 changes: 45 additions & 0 deletions netbox_routing/api/serializers/objects.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from rest_framework import serializers

from netbox_routing.api.nested_serializers import NestedPrefixListSerializer, NestedRouteMapSerializer
from netbox.api.serializers import NetBoxModelSerializer
from netbox_routing.models import PrefixList, PrefixListEntry, RouteMap, RouteMapEntry


__all__ = (
'StaticRouteSerializer'
)


class PrefixListSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='plugins-api:netbox_routing-api:prefixlist-detail')

class Meta:
model = PrefixList
fields = ('url', 'id', 'name')


class PrefixListEntrySerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='plugins-api:netbox_routing-api:prefixlistentry-detail')
prefix_list = NestedPrefixListSerializer()

class Meta:
model = PrefixListEntry
fields = ('url', 'id', 'prefix_list', 'sequence', 'type', 'prefix', 'le', 'ge')


class RouteMapSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='plugins-api:netbox_routing-api:prefixlist-detail')

class Meta:
model = RouteMap
fields = ('url', 'id', 'name')


class RouteMapEntrySerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='plugins-api:netbox_routing-api:prefixlistentry-detail')
route_map = NestedRouteMapSerializer()


class Meta:
model = RouteMapEntry
fields = ('url', 'id', 'route_map', 'sequence', 'type')
21 changes: 21 additions & 0 deletions netbox_routing/api/serializers/static.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from rest_framework import serializers

from dcim.api.nested_serializers import NestedDeviceSerializer
from ipam.api.nested_serializers import NestedVRFSerializer
from netbox.api.serializers import NetBoxModelSerializer
from netbox_routing.models import StaticRoute


__all__ = (
'StaticRouteSerializer'
)


class StaticRouteSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='plugins-api:netbox_routing-api:staticroute-detail')
devices = NestedDeviceSerializer(many=True)
vrf = NestedVRFSerializer()

class Meta:
model = StaticRoute
fields = ('url', 'id', 'devices', 'vrf', 'prefix', 'next_hop', 'name', 'metric', 'permanent')
10 changes: 10 additions & 0 deletions netbox_routing/api/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from netbox.api.routers import NetBoxRouter
from .views import StaticRouteViewSet, PrefixListViewSet, RouteMapViewSet, PrefixListEntryViewSet, RouteMapEntryViewSet

router = NetBoxRouter()
router.register('staticroute', StaticRouteViewSet)
router.register('prefix-list', PrefixListViewSet)
router.register('prefix-list-entry', PrefixListEntryViewSet)
router.register('route-map', RouteMapViewSet)
router.register('route-map-entry', RouteMapEntryViewSet)
urlpatterns = router.urls
10 changes: 10 additions & 0 deletions netbox_routing/api/views/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from .static import StaticRouteViewSet
from .objects import PrefixListViewSet, PrefixListEntryViewSet, RouteMapViewSet, RouteMapEntryViewSet

__all__ = (
'StaticRouteViewSet',
'PrefixListViewSet',
'PrefixListEntryViewSet',
'RouteMapViewSet',
'RouteMapEntryViewSet',
)
24 changes: 24 additions & 0 deletions netbox_routing/api/views/objects.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from netbox.api.viewsets import ModelViewSet
from netbox_routing.api.serializers import PrefixListSerializer, PrefixListEntrySerializer, RouteMapSerializer, \
RouteMapEntrySerializer
from netbox_routing.models import PrefixList, PrefixListEntry, RouteMap, RouteMapEntry


class PrefixListViewSet(ModelViewSet):
queryset = PrefixList.objects.all()
serializer_class = PrefixListSerializer


class PrefixListEntryViewSet(ModelViewSet):
queryset = PrefixListEntry.objects.all()
serializer_class = PrefixListEntrySerializer


class RouteMapViewSet(ModelViewSet):
queryset = RouteMap.objects.all()
serializer_class = RouteMapSerializer


class RouteMapEntryViewSet(ModelViewSet):
queryset = RouteMapEntry.objects.all()
serializer_class = RouteMapEntrySerializer
8 changes: 8 additions & 0 deletions netbox_routing/api/views/static.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from netbox.api.viewsets import ModelViewSet
from netbox_routing.api.serializers import StaticRouteSerializer
from netbox_routing.models import StaticRoute


class StaticRouteViewSet(ModelViewSet):
queryset = StaticRoute.objects.all()
serializer_class = StaticRouteSerializer
1 change: 1 addition & 0 deletions netbox_routing/choices/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .bgp import *
65 changes: 65 additions & 0 deletions netbox_routing/choices/bgp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
from utilities.choices import ChoiceSet


class BGPAdditionalPathSelectChoices(ChoiceSet):
ALL = 'all'
BACKUP = 'backup'
BEST_EXTERNAL = 'best-external'
GROUP_BEST = 'group-best'

CHOICES = [
(ALL, 'All'),
(BACKUP, 'Backup'),
(BEST_EXTERNAL, 'Best External'),
(GROUP_BEST, 'Group Best')
]


class BGPBestPathASPath(ChoiceSet):
IGNORE = 'ignore'
MULTIPATH = 'multipath-relax'

CHOICES = [
(IGNORE, 'Ignore'),
(MULTIPATH, 'Multipath Relax Comparison')
]


class BGPAddressFamilies(ChoiceSet):
IPV4_UNICAST = 'ipv4-unicast'
IPV6_UNICAST = 'ipv6-unicast'
VPNV4_UNICAST = 'vpnv4-unicast'
VPNV6_UNICAST = 'vpnv6-unicast'
IPV4_MULTICAST = 'ipv4-multicast'
IPV6_MULTICAST = 'ipv6-multicast'
VPNV4_MULTICAST = 'vpnv4-multicast'
VPNV6_MULTICAST = 'vpnv6-multicast'
IPV4_FLOWSPEC = 'ipv4-flowspec'
IPV6_FLOWSPEC = 'ipv6-flowspec'
VPNV4_FLOWSPEC = 'vpnv4-flowspec'
VPNV6_FLOWSPEC = 'vpnv6-flowspec'
NSAP = 'nsap'
L2VPNVPLS = 'l2vpn-vpls'
L2VPSEVPN = 'l2vpn-evpn'
LINKSTATE = 'link-state'
RTFILTER_UNICAST = 'rtfilter-unicast'

CHOICES = [
(IPV4_UNICAST, 'IPv4 Unicast'),
(IPV6_UNICAST, 'IPv6 Unicast'),
(VPNV4_UNICAST, 'VPNv4 Unicast'),
(VPNV6_UNICAST, 'VPNv6 Unicast'),
(IPV4_MULTICAST, 'IPv4 Multicast'),
(IPV6_MULTICAST, 'IPv6 Multicast'),
(VPNV4_UNICAST, 'VPNv4 Multicast'),
(VPNV6_MULTICAST, 'VPNv6 Multicast'),
(IPV4_FLOWSPEC, 'IPv4 Flowspec'),
(IPV6_FLOWSPEC, 'IPv6 Flowspec'),
(VPNV4_FLOWSPEC, 'VPNv4 Flowspec'),
(VPNV6_FLOWSPEC, 'VPNv6 Flowspec'),
(NSAP, 'NSAP'),
(L2VPNVPLS, 'L2VPN VPLS'),
(L2VPSEVPN, 'L2VPN EVPN'),
(LINKSTATE, 'LINK-STATE'),
(RTFILTER_UNICAST, 'RTFILTER')
]
11 changes: 11 additions & 0 deletions netbox_routing/choices/objects.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from utilities.choices import ChoiceSet


class PermitDenyChoices(ChoiceSet):
PERMIT = 'permit'
DENY = 'deny'

CHOICES = [
(PERMIT, 'Permit'),
(DENY, 'Deny')
]
Empty file.
26 changes: 26 additions & 0 deletions netbox_routing/constants/bgp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from django.db.models import Q

BGPSETTING_ASSIGNMENT_MODELS = Q(
Q(app_label='netbox_routing', model='bgprouter') |
Q(app_label='netbox_routing', model='bgpscope')
)

BGPAF_ASSIGNMENT_MODELS = Q(
Q(app_label='netbox_routing', model='bgprouter') |
Q(app_label='netbox_routing', model='bgpscope') |
Q(app_label='netbox_routing', model='bgpneighbor') |
Q(app_label='ipam', model='VRF')
)

BGPPEER_ASSIGNMENT_MODELS = Q(
Q(app_label='netbox_routing', model='bgprouter') |
Q(app_label='netbox_routing', model='bgpscope') |
Q(app_label='netbox_routing', model='bgpaddressfamily')
)

BGPPEERAF_ASSIGNMENT_MODELS = Q(
Q(app_label='netbox_routing', model='bgppeer') |
Q(app_label='netbox_routing', model='bgppeergroup') |
Q(app_label='netbox_routing', model='bgptemplatepeer') |
Q(app_label='netbox_routing', model='bgptemplatepeerpolicy')
)
Empty file.
40 changes: 40 additions & 0 deletions netbox_routing/fields/ip.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from django.core.exceptions import ValidationError
from django.db import models
from netaddr import AddrFormatError, IPAddress

from ipam.formfields import IPAddressFormField


class IPAddressField(models.Field):

def python_type(self):
return IPAddress

def from_db_value(self, value, expression, connection):
return self.to_python(value)

def to_python(self, value):
if not value:
return value
try:
# Always return a netaddr.IPNetwork object. (netaddr.IPAddress does not provide a mask.)
return IPAddress(value)
except AddrFormatError:
raise ValidationError("Invalid IP address format: {}".format(value))
except (TypeError, ValueError) as e:
raise ValidationError(e)

def get_prep_value(self, value):
if not value:
return None
if isinstance(value, list):
return [str(self.to_python(v)) for v in value]
return str(self.to_python(value))

def form_class(self):
return IPAddressFormField

def formfield(self, **kwargs):
defaults = {'form_class': self.form_class()}
defaults.update(kwargs)
return super().formfield(**defaults)
11 changes: 11 additions & 0 deletions netbox_routing/filtersets/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from .static import StaticRouteFilterSet
from .objects import PrefixListFilterSet, PrefixListEntryFilterSet, RouteMapFilterSet, RouteMapEntryFilterSet

__all__ = (
'StaticRouteFilterSet',

'PrefixListFilterSet',
'PrefixListEntryFilterSet',
'RouteMapFilterSet',
'RouteMapEntryFilterSet'
)
Loading

0 comments on commit d3c1e60

Please sign in to comment.