Skip to content

Commit

Permalink
Merge pull request #199 from cruse1977/dev
Browse files Browse the repository at this point in the history
Netbox 4.0 Compatibility
  • Loading branch information
cruse1977 authored Jun 7, 2024
2 parents 68f9860 + f15248a commit 79be0d6
Show file tree
Hide file tree
Showing 13 changed files with 147 additions and 60 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
ARG NETBOX_VARIANT=v3.7
ARG NETBOX_VARIANT=v4.0

FROM netboxcommunity/netbox:${NETBOX_VARIANT}

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ Each Plugin Version listed below has been tested with its corresponding NetBox V

| NetBox Version | Plugin Version |
|:--------------:|:--------------:|
| >= 4.0.2 | 1.6.0 |
| 3.7 | 1.5.0 |
| 3.6 | 1.4.0 |
| 3.5 | 1.3.0 |
Expand Down
1 change: 1 addition & 0 deletions netbox_acls/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* @ryanmerolle @abhi1693 @cruse1977 @natm
6 changes: 3 additions & 3 deletions netbox_acls/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Define the NetBox Plugin
"""

from extras.plugins import PluginConfig
from netbox.plugins import PluginConfig

from .version import __version__

Expand All @@ -17,8 +17,8 @@ class NetBoxACLsConfig(PluginConfig):
version = __version__
description = "Manage simple ACLs in NetBox"
base_url = "access-lists"
min_version = "3.7.0"
max_version = "3.7.99"
min_version = "4.0.2"
max_version = "4.0.99"


config = NetBoxACLsConfig
7 changes: 5 additions & 2 deletions netbox_acls/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ class Meta:
"last_updated",
"rule_count",
)
brief_fields = ("id", "url", "name", "display")

@extend_schema_field(serializers.DictField())
def get_assigned_object(self, obj):
Expand Down Expand Up @@ -139,6 +140,7 @@ class Meta:
"created",
"last_updated",
)
brief_fields = ("id", "url", "access_list")

@extend_schema_field(serializers.DictField())
def get_assigned_object(self, obj):
Expand Down Expand Up @@ -212,6 +214,7 @@ class Meta:
"last_updated",
"source_prefix",
)
brief_fields = ("id", "url", "display")

def validate(self, data):
"""
Expand Down Expand Up @@ -284,7 +287,7 @@ class Meta:
"protocol",
"remark",
)

brief_fields = ("id", "url", "display")
def validate(self, data):
"""
Validate the ACLExtendedRule django model's inputs before allowing it to update the instance:
Expand Down Expand Up @@ -328,7 +331,7 @@ def validate(self, data):
if data.get("protocol"):
error_message["protocol"] = [
"Action is set to remark, Protocol CANNOT be set.",
]
]

if error_message:
raise serializers.ValidationError(error_message)
Expand Down
7 changes: 7 additions & 0 deletions netbox_acls/graphql/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,9 @@
from .schema import *
from .types import *

schema = [
schema.NetBoxACLSAccessListQuery,
schema.NetBoxACLSStandardRuleQuery,
schema.NetBoxACLSACLExtendedRuleQuery
]

30 changes: 30 additions & 0 deletions netbox_acls/graphql/filters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import strawberry_django
from .. import filtersets, models
from netbox.graphql.filter_mixins import autotype_decorator, BaseFilterMixin

__all__ = (
'AccessListFilter',
'ACLInterfaceAssignmentFilter',
'ACLExtendedRuleFilter',
'ACLStandardRuleFilter',
)

@strawberry_django.filter(models.AccessList, lookups=True)
@autotype_decorator(filtersets.AccessListFilterSet)
class AccessListFilter(BaseFilterMixin):
pass

@strawberry_django.filter(models.ACLStandardRule, lookups=True)
@autotype_decorator(filtersets.ACLStandardRuleFilterSet)
class ACLStandardRuleFilter(BaseFilterMixin):
pass

@strawberry_django.filter(models.ACLExtendedRule, lookups=True)
@autotype_decorator(filtersets.ACLExtendedRuleFilterSet)
class ACLExtendedRuleFilter(BaseFilterMixin):
pass

@strawberry_django.filter(models.ACLInterfaceAssignment, lookups=True)
@autotype_decorator(filtersets.ACLInterfaceAssignmentFilterSet)
class ACLInterfaceAssignmentFilter(BaseFilterMixin):
pass
34 changes: 22 additions & 12 deletions netbox_acls/graphql/schema.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,32 @@
from graphene import ObjectType
from netbox.graphql.fields import ObjectField, ObjectListField

import strawberry
import strawberry_django
from .types import *
from ..models import *


class Query(ObjectType):
@strawberry.type
class NetBoxACLSAccessListQuery:
"""
Defines the queries available to this plugin via the graphql api.
"""
@strawberry.field
def access_list(self, id: int) -> AccessListType:
return AccessList.objects.get(pk=id)
access_list_list: list[AccessListType] = strawberry_django.field()

@strawberry.type
class NetBoxACLSACLExtendedRuleQuery:
@strawberry.field
def acl_extended_rule(self, id: int) -> ACLExtendedRuleType:
return ACLExtendedRule.objects.get(pk=id)
acl_extended_rule_list: list[ACLExtendedRuleType] = strawberry_django.field()

access_list = ObjectField(AccessListType)
access_list_list = ObjectListField(AccessListType)

acl_extended_rule = ObjectField(ACLExtendedRuleType)
acl_extended_rule_list = ObjectListField(ACLExtendedRuleType)

acl_standard_rule = ObjectField(ACLStandardRuleType)
acl_standard_rule_list = ObjectListField(ACLStandardRuleType)
@strawberry.type
class NetBoxACLSStandardRuleQuery:
@strawberry.field
def acl_standard_rule(self, id: int) -> ACLStandardRuleType:
return ACLStandardRule.objects.get(pk=id)
acl_standard_rule_list: list[ACLStandardRuleType] = strawberry_django.field()


schema = Query
99 changes: 69 additions & 30 deletions netbox_acls/graphql/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,73 +2,112 @@
Define the object types and queries availble via the graphql api.
"""

from netbox.graphql.types import NetBoxObjectType
import strawberry
import strawberry_django

from .. import filtersets, models

__all__ = (
"AccessListType",
"ACLInterfaceAssignmentType",
"ACLExtendedRuleType",
"ACLStandardRuleType",
)
from typing import Annotated, List, Union
from .filters import *
from .. import models
from netbox.graphql.types import OrganizationalObjectType

@strawberry_django.type(
models.AccessList,
fields='__all__',
filters=AccessListFilter,
exclude=('assigned_object_type', 'assigned_object_id')
)

class AccessListType(NetBoxObjectType):
class AccessListType(OrganizationalObjectType):
"""
Defines the object type for the django model AccessList.
"""
assigned_object_type: Annotated["ContentTypeType", strawberry.lazy("netbox.graphql.types")]
assigned_object: Annotated[Union[
Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')],
Annotated["VirtualMachineType", strawberry.lazy('virtualization.graphql.types')],
], strawberry.union("ACLAssignmentType")]


class Meta:
"""
Associates the filterset, fields, and model for the django model AccessList.
"""

model = models.AccessList
fields = "__all__"
filterset_class = filtersets.AccessListFilterSet


class ACLInterfaceAssignmentType(NetBoxObjectType):
@strawberry_django.field
def accesslists(self) -> List[Annotated["AccessList", strawberry.lazy('accesslists.graphql.types')]]:
return self.accesslists.all()

@strawberry_django.type(
models.ACLInterfaceAssignment,
fields='__all__',
exclude=('assigned_object_type', 'assigned_object_id'),
filters=ACLInterfaceAssignmentFilter
)
class ACLInterfaceAssignmentType(OrganizationalObjectType):
"""
Defines the object type for the django model AccessList.
"""
access_list: Annotated["AccessListType", strawberry.lazy("netbox_acls.graphql.types")]
assigned_object_type: Annotated["ContentTypeType", strawberry.lazy("netbox.graphql.types")]
assigned_object: Annotated[Union[
Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')],
Annotated["VMInterfaceType", strawberry.lazy('virtualization.graphql.types')],
], strawberry.union("ACLInterfaceAssignmentType")]




class Meta:
"""
Associates the filterset, fields, and model for the django model ACLInterfaceAssignment.
"""
@strawberry_django.field
def aclinterfaceassignments(self) -> List[Annotated["ACLInterfaceAssignment", strawberry.lazy('aclinterfaceassignments.graphql.types')]]:
return self.aclinterfaceassignments.all()

@strawberry_django.type(
models.ACLExtendedRule,
fields='__all__',
filters=ACLExtendedRuleFilter
)

model = models.ACLInterfaceAssignment
fields = "__all__"
filterset_class = filtersets.ACLInterfaceAssignmentFilterSet


class ACLExtendedRuleType(NetBoxObjectType):
class ACLExtendedRuleType(OrganizationalObjectType):
"""
Defines the object type for the django model ACLExtendedRule.
"""
source_ports: List[int]
destination_ports: List[int]
access_list: Annotated["AccessListType", strawberry.lazy("netbox_acls.graphql.types")]
destination_prefix: Annotated["PrefixType", strawberry.lazy("ipam.graphql.types")]
source_prefix: Annotated["PrefixType", strawberry.lazy("ipam.graphql.types")]

class Meta:
"""
Associates the filterset, fields, and model for the django model ACLExtendedRule.
"""
@strawberry_django.field
def aclextendedrules(self) -> List[Annotated["ACLExtendedRule", strawberry.lazy('aclextendedrule.graphql.types')]]:
return self.aclextendedrules.all()

model = models.ACLExtendedRule
fields = "__all__"
filterset_class = filtersets.ACLExtendedRuleFilterSet

@strawberry_django.type(
models.ACLStandardRule,
fields='__all__',
filters=ACLStandardRuleFilter
)

class ACLStandardRuleType(NetBoxObjectType):
class ACLStandardRuleType(OrganizationalObjectType):
"""
Defines the object type for the django model ACLStandardRule.
"""
access_list: Annotated["AccessListType", strawberry.lazy("netbox_acls.graphql.types")]
source_prefix: Annotated["PrefixType", strawberry.lazy("ipam.graphql.types")]

class Meta:
"""
Associates the filterset, fields, and model for the django model ACLStandardRule.
Associates the filterset, fields, and model for the django model ACLExtendedRule.
"""
@strawberry_django.field
def aclstandardrules(self) -> List[Annotated["ACLStandardRule", strawberry.lazy('aclstandardrule.graphql.types')]]:
return self.aclstandardrules.all()

model = models.ACLStandardRule
fields = "__all__"
filterset_class = filtersets.ACLStandardRuleFilterSet
8 changes: 2 additions & 6 deletions netbox_acls/navigation.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
"""

from django.conf import settings
from extras.plugins import PluginMenu, PluginMenuButton, PluginMenuItem
from utilities.choices import ButtonColorChoices
from netbox.plugins import PluginMenu, PluginMenuButton, PluginMenuItem


plugin_settings = settings.PLUGINS_CONFIG["netbox_acls"]

Expand All @@ -21,7 +21,6 @@
link="plugins:netbox_acls:accesslist_add",
title="Add",
icon_class="mdi mdi-plus-thick",
color=ButtonColorChoices.GREEN,
permissions=["netbox_acls.add_accesslist"],
),
),
Expand All @@ -35,7 +34,6 @@
link="plugins:netbox_acls:aclstandardrule_add",
title="Add",
icon_class="mdi mdi-plus-thick",
color=ButtonColorChoices.GREEN,
permissions=["netbox_acls.add_aclstandardrule"],
),
),
Expand All @@ -49,7 +47,6 @@
link="plugins:netbox_acls:aclextendedrule_add",
title="Add",
icon_class="mdi mdi-plus-thick",
color=ButtonColorChoices.GREEN,
permissions=["netbox_acls.add_aclextendedrule"],
),
),
Expand All @@ -63,7 +60,6 @@
link="plugins:netbox_acls:aclinterfaceassignment_add",
title="Add",
icon_class="mdi mdi-plus-thick",
color=ButtonColorChoices.GREEN,
permissions=["netbox_acls.add_aclinterfaceassignment"],
),
),
Expand Down
2 changes: 1 addition & 1 deletion netbox_acls/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def setUpTestData(cls):
name="Device 1",
site=site,
device_type=devicetype,
device_role=devicerole,
role=devicerole,
)

access_lists = (
Expand Down
2 changes: 1 addition & 1 deletion netbox_acls/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "1.5.0"
__version__ = "1.6.0"
8 changes: 4 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
script_dir = os.path.abspath(os.path.dirname(__file__))

with open(os.path.join(script_dir, "README.md"), encoding="utf-8") as fh:
long_description = fh.read().replace("(docs/img/", "(https://raw.githubusercontent.com/ryanmerolle/netbox-acls/release/docs/img/")
long_description = fh.read().replace("(docs/img/", "(https://raw.githubusercontent.com/netbox-community/netbox-acls/release/docs/img/")


def read(relative_path):
Expand Down Expand Up @@ -37,7 +37,7 @@ def get_version(relative_path):
description="A NetBox plugin for Access List management",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://github.com/ryanmerolle/netbox-acls",
url="https://github.com/netbox-community/netbox-acls",
license="Apache 2.0",
install_requires=[],
python_requires=">=3.10",
Expand All @@ -61,7 +61,7 @@ def get_version(relative_path):
"Topic :: Internet",
],
project_urls={
"Issues": "https://github.com/ryanmerolle/netbox-acls/issues",
"Source": "https://github.com/ryanmerolle/netbox-acls",
"Issues": "https://github.com/netbox-community/netbox-acls/issues",
"Source": "https://github.com/netbox-community/netbox-acls",
},
)

0 comments on commit 79be0d6

Please sign in to comment.