mirror of
https://github.com/lucaspalomodevelop/netbox-acls.git
synced 2026-03-12 23:27:23 +00:00
lint fixes
This commit is contained in:
parent
df1e3d34f9
commit
41a3f29217
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
PLUGINS = [
|
PLUGINS = [
|
||||||
"netbox_access_lists",
|
"netbox_access_lists",
|
||||||
]
|
]
|
||||||
|
|
||||||
PLUGINS_CONFIG = {
|
PLUGINS_CONFIG = {
|
||||||
"netbox_access_lists": {},
|
"netbox_access_lists": {},
|
||||||
|
|||||||
@ -9,4 +9,5 @@ pycodestyle
|
|||||||
pydocstyle
|
pydocstyle
|
||||||
pylint
|
pylint
|
||||||
pylint-django
|
pylint-django
|
||||||
|
wily
|
||||||
yapf
|
yapf
|
||||||
|
|||||||
@ -17,7 +17,7 @@ repos:
|
|||||||
args:
|
args:
|
||||||
- '--py36-plus'
|
- '--py36-plus'
|
||||||
- repo: 'https://github.com/asottile/pyupgrade'
|
- repo: 'https://github.com/asottile/pyupgrade'
|
||||||
rev: v2.34.0
|
rev: v2.37.3
|
||||||
hooks:
|
hooks:
|
||||||
- id: pyupgrade
|
- id: pyupgrade
|
||||||
args:
|
args:
|
||||||
@ -42,11 +42,9 @@ repos:
|
|||||||
hooks:
|
hooks:
|
||||||
- id: black
|
- id: black
|
||||||
- repo: 'https://github.com/igorshubovych/markdownlint-cli'
|
- repo: 'https://github.com/igorshubovych/markdownlint-cli'
|
||||||
rev: v0.31.1
|
rev: v0.32.1
|
||||||
hooks:
|
hooks:
|
||||||
- id: markdownlint
|
- id: markdownlint
|
||||||
- repo: local
|
|
||||||
hooks:
|
|
||||||
- repo: local
|
- repo: local
|
||||||
hooks:
|
hooks:
|
||||||
- id: wily
|
- id: wily
|
||||||
|
|||||||
@ -6,10 +6,11 @@ from extras.plugins import PluginConfig
|
|||||||
|
|
||||||
|
|
||||||
class NetBoxAccessListsConfig(PluginConfig):
|
class NetBoxAccessListsConfig(PluginConfig):
|
||||||
name = 'netbox_access_lists'
|
name = "netbox_access_lists"
|
||||||
verbose_name = 'Access Lists'
|
verbose_name = "Access Lists"
|
||||||
description = 'Manage simple ACLs in NetBox'
|
description = "Manage simple ACLs in NetBox"
|
||||||
version = '0.1'
|
version = "0.1"
|
||||||
base_url = 'access-lists'
|
base_url = "access-lists"
|
||||||
|
|
||||||
|
|
||||||
config = NetBoxAccessListsConfig
|
config = NetBoxAccessListsConfig
|
||||||
|
|||||||
@ -6,75 +6,88 @@ while Django itself handles the database abstraction.
|
|||||||
from netbox.api.serializers import WritableNestedSerializer
|
from netbox.api.serializers import WritableNestedSerializer
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
from ..models import (AccessList, ACLExtendedRule, ACLInterfaceAssignment,
|
from ..models import (
|
||||||
ACLStandardRule)
|
AccessList,
|
||||||
|
ACLExtendedRule,
|
||||||
|
ACLInterfaceAssignment,
|
||||||
|
ACLStandardRule,
|
||||||
|
)
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'NestedAccessListSerializer',
|
"NestedAccessListSerializer",
|
||||||
'NestedACLInterfaceAssignmentSerializer',
|
"NestedACLInterfaceAssignmentSerializer",
|
||||||
'NestedACLStandardRuleSerializer',
|
"NestedACLStandardRuleSerializer",
|
||||||
'NestedACLExtendedRuleSerializer'
|
"NestedACLExtendedRuleSerializer",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class NestedAccessListSerializer(WritableNestedSerializer):
|
class NestedAccessListSerializer(WritableNestedSerializer):
|
||||||
"""
|
"""
|
||||||
Defines the nested serializer for the django AccessList model & associates it to a view.
|
Defines the nested serializer for the django AccessList model & associates it to a view.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
url = serializers.HyperlinkedIdentityField(
|
url = serializers.HyperlinkedIdentityField(
|
||||||
view_name='plugins-api:netbox_access_lists-api:accesslist-detail'
|
view_name="plugins-api:netbox_access_lists-api:accesslist-detail",
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""
|
"""
|
||||||
Associates the django model ACLStandardRule & fields to the nested serializer.
|
Associates the django model ACLStandardRule & fields to the nested serializer.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
model = AccessList
|
model = AccessList
|
||||||
fields = ('id', 'url', 'display', 'name')
|
fields = ("id", "url", "display", "name")
|
||||||
|
|
||||||
|
|
||||||
class NestedACLInterfaceAssignmentSerializer(WritableNestedSerializer):
|
class NestedACLInterfaceAssignmentSerializer(WritableNestedSerializer):
|
||||||
"""
|
"""
|
||||||
Defines the nested serializer for the django ACLInterfaceAssignment model & associates it to a view.
|
Defines the nested serializer for the django ACLInterfaceAssignment model & associates it to a view.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
url = serializers.HyperlinkedIdentityField(
|
url = serializers.HyperlinkedIdentityField(
|
||||||
view_name='plugins-api:netbox_access_lists-api:aclinterfaceassignment-detail'
|
view_name="plugins-api:netbox_access_lists-api:aclinterfaceassignment-detail",
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""
|
"""
|
||||||
Associates the django model ACLInterfaceAssignment & fields to the nested serializer.
|
Associates the django model ACLInterfaceAssignment & fields to the nested serializer.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
model = ACLInterfaceAssignment
|
model = ACLInterfaceAssignment
|
||||||
fields = ('id', 'url', 'display', 'access_list')
|
fields = ("id", "url", "display", "access_list")
|
||||||
|
|
||||||
|
|
||||||
class NestedACLStandardRuleSerializer(WritableNestedSerializer):
|
class NestedACLStandardRuleSerializer(WritableNestedSerializer):
|
||||||
"""
|
"""
|
||||||
Defines the nested serializer for the django ACLStandardRule model & associates it to a view.
|
Defines the nested serializer for the django ACLStandardRule model & associates it to a view.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
url = serializers.HyperlinkedIdentityField(
|
url = serializers.HyperlinkedIdentityField(
|
||||||
view_name='plugins-api:netbox_access_lists-api:aclstandardrule-detail'
|
view_name="plugins-api:netbox_access_lists-api:aclstandardrule-detail",
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""
|
"""
|
||||||
Associates the django model ACLStandardRule & fields to the nested serializer.
|
Associates the django model ACLStandardRule & fields to the nested serializer.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
model = ACLStandardRule
|
model = ACLStandardRule
|
||||||
fields = ('id', 'url', 'display', 'index')
|
fields = ("id", "url", "display", "index")
|
||||||
|
|
||||||
|
|
||||||
class NestedACLExtendedRuleSerializer(WritableNestedSerializer):
|
class NestedACLExtendedRuleSerializer(WritableNestedSerializer):
|
||||||
"""
|
"""
|
||||||
Defines the nested serializer for the django ACLExtendedRule model & associates it to a view.
|
Defines the nested serializer for the django ACLExtendedRule model & associates it to a view.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
url = serializers.HyperlinkedIdentityField(
|
url = serializers.HyperlinkedIdentityField(
|
||||||
view_name='plugins-api:netbox_access_lists-api:aclextendedrule-detail'
|
view_name="plugins-api:netbox_access_lists-api:aclextendedrule-detail",
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""
|
"""
|
||||||
Associates the django model ACLExtendedRule & fields to the nested serializer.
|
Associates the django model ACLExtendedRule & fields to the nested serializer.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
model = ACLExtendedRule
|
model = ACLExtendedRule
|
||||||
fields = ('id', 'url', 'display', 'index')
|
fields = ("id", "url", "display", "index")
|
||||||
|
|||||||
@ -4,50 +4,60 @@ while Django itself handles the database abstraction.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
|
from django.core.exceptions import ObjectDoesNotExist
|
||||||
from drf_yasg.utils import swagger_serializer_method
|
from drf_yasg.utils import swagger_serializer_method
|
||||||
from ipam.api.serializers import NestedPrefixSerializer
|
from ipam.api.serializers import NestedPrefixSerializer
|
||||||
from django.core.exceptions import ObjectDoesNotExist
|
|
||||||
from netbox.api import ContentTypeField
|
from netbox.api import ContentTypeField
|
||||||
from netbox.api.serializers import NetBoxModelSerializer
|
from netbox.api.serializers import NetBoxModelSerializer
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from utilities.api import get_serializer_for_model
|
from utilities.api import get_serializer_for_model
|
||||||
|
|
||||||
from ..constants import (ACL_HOST_ASSIGNMENT_MODELS,
|
from ..constants import ACL_HOST_ASSIGNMENT_MODELS, ACL_INTERFACE_ASSIGNMENT_MODELS
|
||||||
ACL_INTERFACE_ASSIGNMENT_MODELS)
|
from ..models import (
|
||||||
from ..models import (AccessList, ACLExtendedRule, ACLInterfaceAssignment,
|
AccessList,
|
||||||
ACLStandardRule)
|
ACLExtendedRule,
|
||||||
from .nested_serializers import (NestedAccessListSerializer,
|
ACLInterfaceAssignment,
|
||||||
NestedACLExtendedRuleSerializer,
|
ACLStandardRule,
|
||||||
NestedACLInterfaceAssignmentSerializer,
|
)
|
||||||
NestedACLStandardRuleSerializer)
|
from .nested_serializers import (
|
||||||
|
NestedAccessListSerializer,
|
||||||
|
NestedACLExtendedRuleSerializer,
|
||||||
|
NestedACLInterfaceAssignmentSerializer,
|
||||||
|
NestedACLStandardRuleSerializer,
|
||||||
|
)
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'AccessListSerializer',
|
"AccessListSerializer",
|
||||||
'ACLInterfaceAssignmentSerializer',
|
"ACLInterfaceAssignmentSerializer",
|
||||||
'ACLStandardRuleSerializer',
|
"ACLStandardRuleSerializer",
|
||||||
'ACLExtendedRuleSerializer'
|
"ACLExtendedRuleSerializer",
|
||||||
]
|
]
|
||||||
|
|
||||||
# Sets a standard error message for ACL rules with an action of remark, but no remark set.
|
# Sets a standard error message for ACL rules with an action of remark, but no remark set.
|
||||||
error_message_no_remark = 'Action is set to remark, you MUST add a remark.'
|
error_message_no_remark = "Action is set to remark, you MUST add a remark."
|
||||||
# Sets a standard error message for ACL rules with an action of remark, but no source_prefix is set.
|
# Sets a standard error message for ACL rules with an action of remark, but no source_prefix is set.
|
||||||
error_message_action_remark_source_prefix_set = 'Action is set to remark, Source Prefix CANNOT be set.'
|
error_message_action_remark_source_prefix_set = (
|
||||||
|
"Action is set to remark, Source Prefix CANNOT be set."
|
||||||
|
)
|
||||||
# Sets a standard error message for ACL rules with an action not set to remark, but no remark is set.
|
# Sets a standard error message for ACL rules with an action not set to remark, but no remark is set.
|
||||||
error_message_remark_without_action_remark = 'CANNOT set remark unless action is set to remark.'
|
error_message_remark_without_action_remark = (
|
||||||
|
"CANNOT set remark unless action is set to remark."
|
||||||
|
)
|
||||||
# Sets a standard error message for ACL rules no associated to an ACL of the same type.
|
# Sets a standard error message for ACL rules no associated to an ACL of the same type.
|
||||||
error_message_acl_type = 'Provided parent Access List is not of right type.'
|
error_message_acl_type = "Provided parent Access List is not of right type."
|
||||||
|
|
||||||
|
|
||||||
class AccessListSerializer(NetBoxModelSerializer):
|
class AccessListSerializer(NetBoxModelSerializer):
|
||||||
"""
|
"""
|
||||||
Defines the serializer for the django AccessList model & associates it to a view.
|
Defines the serializer for the django AccessList model & associates it to a view.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
url = serializers.HyperlinkedIdentityField(
|
url = serializers.HyperlinkedIdentityField(
|
||||||
view_name='plugins-api:netbox_access_lists-api:accesslist-detail'
|
view_name="plugins-api:netbox_access_lists-api:accesslist-detail",
|
||||||
)
|
)
|
||||||
rule_count = serializers.IntegerField(read_only=True)
|
rule_count = serializers.IntegerField(read_only=True)
|
||||||
assigned_object_type = ContentTypeField(
|
assigned_object_type = ContentTypeField(
|
||||||
queryset=ContentType.objects.filter(ACL_HOST_ASSIGNMENT_MODELS)
|
queryset=ContentType.objects.filter(ACL_HOST_ASSIGNMENT_MODELS),
|
||||||
)
|
)
|
||||||
assigned_object = serializers.SerializerMethodField(read_only=True)
|
assigned_object = serializers.SerializerMethodField(read_only=True)
|
||||||
|
|
||||||
@ -55,16 +65,30 @@ class AccessListSerializer(NetBoxModelSerializer):
|
|||||||
"""
|
"""
|
||||||
Associates the django model AccessList & fields to the serializer.
|
Associates the django model AccessList & fields to the serializer.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
model = AccessList
|
model = AccessList
|
||||||
fields = (
|
fields = (
|
||||||
'id', 'url', 'display', 'name', 'assigned_object_type', 'assigned_object_id', 'assigned_object', 'type', 'default_action', 'comments', 'tags', 'custom_fields', 'created',
|
"id",
|
||||||
'last_updated', 'rule_count'
|
"url",
|
||||||
|
"display",
|
||||||
|
"name",
|
||||||
|
"assigned_object_type",
|
||||||
|
"assigned_object_id",
|
||||||
|
"assigned_object",
|
||||||
|
"type",
|
||||||
|
"default_action",
|
||||||
|
"comments",
|
||||||
|
"tags",
|
||||||
|
"custom_fields",
|
||||||
|
"created",
|
||||||
|
"last_updated",
|
||||||
|
"rule_count",
|
||||||
)
|
)
|
||||||
|
|
||||||
@swagger_serializer_method(serializer_or_field=serializers.DictField)
|
@swagger_serializer_method(serializer_or_field=serializers.DictField)
|
||||||
def get_assigned_object(self, obj):
|
def get_assigned_object(self, obj):
|
||||||
serializer = get_serializer_for_model(obj.assigned_object, prefix='Nested')
|
serializer = get_serializer_for_model(obj.assigned_object, prefix="Nested")
|
||||||
context = {'request': self.context['request']}
|
context = {"request": self.context["request"]}
|
||||||
return serializer(obj.assigned_object, context=context).data
|
return serializer(obj.assigned_object, context=context).data
|
||||||
|
|
||||||
def validate(self, data):
|
def validate(self, data):
|
||||||
@ -76,18 +100,26 @@ class AccessListSerializer(NetBoxModelSerializer):
|
|||||||
error_message = {}
|
error_message = {}
|
||||||
|
|
||||||
# Check that the GFK object is valid.
|
# Check that the GFK object is valid.
|
||||||
if 'assigned_object_type' in data and 'assigned_object_id' in data:
|
if "assigned_object_type" in data and "assigned_object_id" in data:
|
||||||
try:
|
try:
|
||||||
assigned_object = data['assigned_object_type'].get_object_for_this_type(id=data['assigned_object_id'])
|
assigned_object = data["assigned_object_type"].get_object_for_this_type(
|
||||||
|
id=data["assigned_object_id"]
|
||||||
|
)
|
||||||
except ObjectDoesNotExist:
|
except ObjectDoesNotExist:
|
||||||
# Sets a standard error message for invalid GFK
|
# Sets a standard error message for invalid GFK
|
||||||
error_message_invalid_gfk = f"Invalid assigned_object {data['assigned_object_type']} ID {data['assigned_object_id']}"
|
error_message_invalid_gfk = f"Invalid assigned_object {data['assigned_object_type']} ID {data['assigned_object_id']}"
|
||||||
error_message['assigned_object_type'] = [error_message_invalid_gfk]
|
error_message["assigned_object_type"] = [error_message_invalid_gfk]
|
||||||
error_message['assigned_object_id'] = [error_message_invalid_gfk]
|
error_message["assigned_object_id"] = [error_message_invalid_gfk]
|
||||||
|
|
||||||
# Check if Access List has no existing rules before change the Access List's type.
|
# Check if Access List has no existing rules before change the Access List's type.
|
||||||
if self.instance and self.instance.type != data.get('type') and self.instance.rule_count > 0:
|
if (
|
||||||
error_message['type'] = ['This ACL has ACL rules associated, CANNOT change ACL type.']
|
self.instance
|
||||||
|
and self.instance.type != data.get("type")
|
||||||
|
and self.instance.rule_count > 0
|
||||||
|
):
|
||||||
|
error_message["type"] = [
|
||||||
|
"This ACL has ACL rules associated, CANNOT change ACL type."
|
||||||
|
]
|
||||||
|
|
||||||
if error_message:
|
if error_message:
|
||||||
raise serializers.ValidationError(error_message)
|
raise serializers.ValidationError(error_message)
|
||||||
@ -99,11 +131,12 @@ class ACLInterfaceAssignmentSerializer(NetBoxModelSerializer):
|
|||||||
"""
|
"""
|
||||||
Defines the serializer for the django ACLInterfaceAssignment model & associates it to a view.
|
Defines the serializer for the django ACLInterfaceAssignment model & associates it to a view.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
url = serializers.HyperlinkedIdentityField(
|
url = serializers.HyperlinkedIdentityField(
|
||||||
view_name='plugins-api:netbox_access_lists-api:aclinterfaceassignment-detail'
|
view_name="plugins-api:netbox_access_lists-api:aclinterfaceassignment-detail",
|
||||||
)
|
)
|
||||||
assigned_object_type = ContentTypeField(
|
assigned_object_type = ContentTypeField(
|
||||||
queryset=ContentType.objects.filter(ACL_INTERFACE_ASSIGNMENT_MODELS)
|
queryset=ContentType.objects.filter(ACL_INTERFACE_ASSIGNMENT_MODELS),
|
||||||
)
|
)
|
||||||
assigned_object = serializers.SerializerMethodField(read_only=True)
|
assigned_object = serializers.SerializerMethodField(read_only=True)
|
||||||
|
|
||||||
@ -111,16 +144,27 @@ class ACLInterfaceAssignmentSerializer(NetBoxModelSerializer):
|
|||||||
"""
|
"""
|
||||||
Associates the django model ACLInterfaceAssignment & fields to the serializer.
|
Associates the django model ACLInterfaceAssignment & fields to the serializer.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
model = ACLInterfaceAssignment
|
model = ACLInterfaceAssignment
|
||||||
fields = (
|
fields = (
|
||||||
'id', 'url', 'access_list', 'direction', 'assigned_object_type', 'assigned_object_id', 'assigned_object', 'comments', 'tags', 'custom_fields', 'created',
|
"id",
|
||||||
'last_updated'
|
"url",
|
||||||
|
"access_list",
|
||||||
|
"direction",
|
||||||
|
"assigned_object_type",
|
||||||
|
"assigned_object_id",
|
||||||
|
"assigned_object",
|
||||||
|
"comments",
|
||||||
|
"tags",
|
||||||
|
"custom_fields",
|
||||||
|
"created",
|
||||||
|
"last_updated",
|
||||||
)
|
)
|
||||||
|
|
||||||
@swagger_serializer_method(serializer_or_field=serializers.DictField)
|
@swagger_serializer_method(serializer_or_field=serializers.DictField)
|
||||||
def get_assigned_object(self, obj):
|
def get_assigned_object(self, obj):
|
||||||
serializer = get_serializer_for_model(obj.assigned_object, prefix='Nested')
|
serializer = get_serializer_for_model(obj.assigned_object, prefix="Nested")
|
||||||
context = {'request': self.context['request']}
|
context = {"request": self.context["request"]}
|
||||||
return serializer(obj.assigned_object, context=context).data
|
return serializer(obj.assigned_object, context=context).data
|
||||||
|
|
||||||
def validate(self, data):
|
def validate(self, data):
|
||||||
@ -130,56 +174,81 @@ class ACLInterfaceAssignmentSerializer(NetBoxModelSerializer):
|
|||||||
- Check that the associated interface's parent host has the selected ACL defined.
|
- Check that the associated interface's parent host has the selected ACL defined.
|
||||||
"""
|
"""
|
||||||
error_message = {}
|
error_message = {}
|
||||||
acl_host = data['access_list'].assigned_object
|
acl_host = data["access_list"].assigned_object
|
||||||
|
|
||||||
# Check that the GFK object is vlaid.
|
# Check that the GFK object is vlaid.
|
||||||
if 'assigned_object_type' in data and 'assigned_object_id' in data:
|
if "assigned_object_type" in data and "assigned_object_id" in data:
|
||||||
try:
|
try:
|
||||||
assigned_object = data['assigned_object_type'].get_object_for_this_type(id=data['assigned_object_id'])
|
assigned_object = data["assigned_object_type"].get_object_for_this_type(
|
||||||
|
id=data["assigned_object_id"]
|
||||||
|
)
|
||||||
except ObjectDoesNotExist:
|
except ObjectDoesNotExist:
|
||||||
# Sets a standard error message for invalid GFK
|
# Sets a standard error message for invalid GFK
|
||||||
error_message_invalid_gfk = f"Invalid assigned_object {data['assigned_object_type']} ID {data['assigned_object_id']}"
|
error_message_invalid_gfk = f"Invalid assigned_object {data['assigned_object_type']} ID {data['assigned_object_id']}"
|
||||||
error_message['assigned_object_type'] = [error_message_invalid_gfk]
|
error_message["assigned_object_type"] = [error_message_invalid_gfk]
|
||||||
error_message['assigned_object_id'] = [error_message_invalid_gfk]
|
error_message["assigned_object_id"] = [error_message_invalid_gfk]
|
||||||
|
|
||||||
|
if data["assigned_object_type"].model == "interface":
|
||||||
if data['assigned_object_type'].model == 'interface':
|
interface_host = (
|
||||||
interface_host = data['assigned_object_type'].get_object_for_this_type(id=data['assigned_object_id']).device
|
data["assigned_object_type"]
|
||||||
elif data['assigned_object_type'].model == 'vminterface':
|
.get_object_for_this_type(id=data["assigned_object_id"])
|
||||||
interface_host = data['assigned_object_type'].get_object_for_this_type(id=data['assigned_object_id']).virtual_machine
|
.device
|
||||||
|
)
|
||||||
|
elif data["assigned_object_type"].model == "vminterface":
|
||||||
|
interface_host = (
|
||||||
|
data["assigned_object_type"]
|
||||||
|
.get_object_for_this_type(id=data["assigned_object_id"])
|
||||||
|
.virtual_machine
|
||||||
|
)
|
||||||
# Check that the associated interface's parent host has the selected ACL defined.
|
# Check that the associated interface's parent host has the selected ACL defined.
|
||||||
if acl_host != interface_host:
|
if acl_host != interface_host:
|
||||||
error_acl_not_assigned_to_host = "Access List not present on the selected interface's host."
|
error_acl_not_assigned_to_host = (
|
||||||
error_message['access_list'] = [error_acl_not_assigned_to_host]
|
"Access List not present on the selected interface's host."
|
||||||
error_message['assigned_object_id'] = [error_acl_not_assigned_to_host]
|
)
|
||||||
|
error_message["access_list"] = [error_acl_not_assigned_to_host]
|
||||||
|
error_message["assigned_object_id"] = [error_acl_not_assigned_to_host]
|
||||||
|
|
||||||
if error_message:
|
if error_message:
|
||||||
raise serializers.ValidationError(error_message)
|
raise serializers.ValidationError(error_message)
|
||||||
|
|
||||||
return super().validate(data)
|
return super().validate(data)
|
||||||
|
|
||||||
|
|
||||||
class ACLStandardRuleSerializer(NetBoxModelSerializer):
|
class ACLStandardRuleSerializer(NetBoxModelSerializer):
|
||||||
"""
|
"""
|
||||||
Defines the serializer for the django ACLStandardRule model & associates it to a view.
|
Defines the serializer for the django ACLStandardRule model & associates it to a view.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
url = serializers.HyperlinkedIdentityField(
|
url = serializers.HyperlinkedIdentityField(
|
||||||
view_name='plugins-api:netbox_access_lists-api:aclstandardrule-detail'
|
view_name="plugins-api:netbox_access_lists-api:aclstandardrule-detail",
|
||||||
)
|
)
|
||||||
access_list = NestedAccessListSerializer()
|
access_list = NestedAccessListSerializer()
|
||||||
source_prefix = NestedPrefixSerializer(
|
source_prefix = NestedPrefixSerializer(
|
||||||
required=False,
|
required=False,
|
||||||
allow_null=True,
|
allow_null=True,
|
||||||
default=None
|
default=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""
|
"""
|
||||||
Associates the django model ACLStandardRule & fields to the serializer.
|
Associates the django model ACLStandardRule & fields to the serializer.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
model = ACLStandardRule
|
model = ACLStandardRule
|
||||||
fields = (
|
fields = (
|
||||||
'id', 'url', 'display', 'access_list', 'index', 'action', 'tags', 'description',
|
"id",
|
||||||
'remark', 'created', 'custom_fields', 'last_updated', 'source_prefix'
|
"url",
|
||||||
|
"display",
|
||||||
|
"access_list",
|
||||||
|
"index",
|
||||||
|
"action",
|
||||||
|
"tags",
|
||||||
|
"description",
|
||||||
|
"remark",
|
||||||
|
"created",
|
||||||
|
"custom_fields",
|
||||||
|
"last_updated",
|
||||||
|
"source_prefix",
|
||||||
)
|
)
|
||||||
|
|
||||||
def validate(self, data):
|
def validate(self, data):
|
||||||
@ -191,11 +260,13 @@ class ACLStandardRuleSerializer(NetBoxModelSerializer):
|
|||||||
error_message = {}
|
error_message = {}
|
||||||
|
|
||||||
# Check if action set to remark, but no remark set.
|
# Check if action set to remark, but no remark set.
|
||||||
if data.get('action') == 'remark' and data.get('remark') is None:
|
if data.get("action") == "remark" and data.get("remark") is None:
|
||||||
error_message['remark'] = [error_message_no_remark]
|
error_message["remark"] = [error_message_no_remark]
|
||||||
# Check if action set to remark, but source_prefix set.
|
# Check if action set to remark, but source_prefix set.
|
||||||
if data.get('source_prefix'):
|
if data.get("source_prefix"):
|
||||||
error_message['source_prefix'] = [error_message_action_remark_source_prefix_set]
|
error_message["source_prefix"] = [
|
||||||
|
error_message_action_remark_source_prefix_set
|
||||||
|
]
|
||||||
|
|
||||||
if error_message:
|
if error_message:
|
||||||
raise serializers.ValidationError(error_message)
|
raise serializers.ValidationError(error_message)
|
||||||
@ -207,30 +278,46 @@ class ACLExtendedRuleSerializer(NetBoxModelSerializer):
|
|||||||
"""
|
"""
|
||||||
Defines the serializer for the django ACLExtendedRule model & associates it to a view.
|
Defines the serializer for the django ACLExtendedRule model & associates it to a view.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
url = serializers.HyperlinkedIdentityField(
|
url = serializers.HyperlinkedIdentityField(
|
||||||
view_name='plugins-api:netbox_access_lists-api:aclextendedrule-detail'
|
view_name="plugins-api:netbox_access_lists-api:aclextendedrule-detail",
|
||||||
)
|
)
|
||||||
access_list = NestedAccessListSerializer()
|
access_list = NestedAccessListSerializer()
|
||||||
source_prefix = NestedPrefixSerializer(
|
source_prefix = NestedPrefixSerializer(
|
||||||
required=False,
|
required=False,
|
||||||
allow_null=True,
|
allow_null=True,
|
||||||
default=None
|
default=None,
|
||||||
)
|
)
|
||||||
destination_prefix = NestedPrefixSerializer(
|
destination_prefix = NestedPrefixSerializer(
|
||||||
required=False,
|
required=False,
|
||||||
allow_null=True,
|
allow_null=True,
|
||||||
default=None
|
default=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""
|
"""
|
||||||
Associates the django model ACLExtendedRule & fields to the serializer.
|
Associates the django model ACLExtendedRule & fields to the serializer.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
model = ACLExtendedRule
|
model = ACLExtendedRule
|
||||||
fields = (
|
fields = (
|
||||||
'id', 'url', 'display', 'access_list', 'index', 'action', 'tags', 'description',
|
"id",
|
||||||
'created', 'custom_fields', 'last_updated', 'source_prefix', 'source_ports',
|
"url",
|
||||||
'destination_prefix', 'destination_ports', 'protocol', 'remark',
|
"display",
|
||||||
|
"access_list",
|
||||||
|
"index",
|
||||||
|
"action",
|
||||||
|
"tags",
|
||||||
|
"description",
|
||||||
|
"created",
|
||||||
|
"custom_fields",
|
||||||
|
"last_updated",
|
||||||
|
"source_prefix",
|
||||||
|
"source_ports",
|
||||||
|
"destination_prefix",
|
||||||
|
"destination_ports",
|
||||||
|
"protocol",
|
||||||
|
"remark",
|
||||||
)
|
)
|
||||||
|
|
||||||
def validate(self, data):
|
def validate(self, data):
|
||||||
@ -247,23 +334,33 @@ class ACLExtendedRuleSerializer(NetBoxModelSerializer):
|
|||||||
error_message = {}
|
error_message = {}
|
||||||
|
|
||||||
# Check if action set to remark, but no remark set.
|
# Check if action set to remark, but no remark set.
|
||||||
if data.get('action') == 'remark' and data.get('remark') is None:
|
if data.get("action") == "remark" and data.get("remark") is None:
|
||||||
error_message['remark'] = [error_message_no_remark]
|
error_message["remark"] = [error_message_no_remark]
|
||||||
# Check if action set to remark, but source_prefix set.
|
# Check if action set to remark, but source_prefix set.
|
||||||
if data.get('source_prefix'):
|
if data.get("source_prefix"):
|
||||||
error_message['source_prefix'] = [error_message_action_remark_source_prefix_set]
|
error_message["source_prefix"] = [
|
||||||
|
error_message_action_remark_source_prefix_set
|
||||||
|
]
|
||||||
# Check if action set to remark, but source_ports set.
|
# Check if action set to remark, but source_ports set.
|
||||||
if data.get('source_ports'):
|
if data.get("source_ports"):
|
||||||
error_message['source_ports'] = ['Action is set to remark, Source Ports CANNOT be set.']
|
error_message["source_ports"] = [
|
||||||
|
"Action is set to remark, Source Ports CANNOT be set."
|
||||||
|
]
|
||||||
# Check if action set to remark, but destination_prefix set.
|
# Check if action set to remark, but destination_prefix set.
|
||||||
if data.get('destination_prefix'):
|
if data.get("destination_prefix"):
|
||||||
error_message['destination_prefix'] = ['Action is set to remark, Destination Prefix CANNOT be set.']
|
error_message["destination_prefix"] = [
|
||||||
|
"Action is set to remark, Destination Prefix CANNOT be set."
|
||||||
|
]
|
||||||
# Check if action set to remark, but destination_ports set.
|
# Check if action set to remark, but destination_ports set.
|
||||||
if data.get('destination_ports'):
|
if data.get("destination_ports"):
|
||||||
error_message['destination_ports'] = ['Action is set to remark, Destination Ports CANNOT be set.']
|
error_message["destination_ports"] = [
|
||||||
|
"Action is set to remark, Destination Ports CANNOT be set."
|
||||||
|
]
|
||||||
# Check if action set to remark, but protocol set.
|
# Check if action set to remark, but protocol set.
|
||||||
if data.get('protocol'):
|
if data.get("protocol"):
|
||||||
error_message['protocol'] = ['Action is set to remark, Protocol CANNOT be set.']
|
error_message["protocol"] = [
|
||||||
|
"Action is set to remark, Protocol CANNOT be set."
|
||||||
|
]
|
||||||
|
|
||||||
if error_message:
|
if error_message:
|
||||||
raise serializers.ValidationError(error_message)
|
raise serializers.ValidationError(error_message)
|
||||||
|
|||||||
@ -6,12 +6,12 @@ from netbox.api.routers import NetBoxRouter
|
|||||||
|
|
||||||
from . import views
|
from . import views
|
||||||
|
|
||||||
app_name = 'netbox_access_list'
|
app_name = "netbox_access_list"
|
||||||
|
|
||||||
router = NetBoxRouter()
|
router = NetBoxRouter()
|
||||||
router.register('access-lists', views.AccessListViewSet)
|
router.register("access-lists", views.AccessListViewSet)
|
||||||
router.register('interface-assignments', views.ACLInterfaceAssignmentViewSet)
|
router.register("interface-assignments", views.ACLInterfaceAssignmentViewSet)
|
||||||
router.register('standard-acl-rules', views.ACLStandardRuleViewSet)
|
router.register("standard-acl-rules", views.ACLStandardRuleViewSet)
|
||||||
router.register('extended-acl-rules', views.ACLExtendedRuleViewSet)
|
router.register("extended-acl-rules", views.ACLExtendedRuleViewSet)
|
||||||
|
|
||||||
urlpatterns = router.urls
|
urlpatterns = router.urls
|
||||||
|
|||||||
@ -8,15 +8,17 @@ from django.db.models import Count
|
|||||||
from netbox.api.viewsets import NetBoxModelViewSet
|
from netbox.api.viewsets import NetBoxModelViewSet
|
||||||
|
|
||||||
from .. import filtersets, models
|
from .. import filtersets, models
|
||||||
from .serializers import (AccessListSerializer, ACLExtendedRuleSerializer,
|
from .serializers import (
|
||||||
ACLInterfaceAssignmentSerializer,
|
AccessListSerializer,
|
||||||
ACLStandardRuleSerializer)
|
ACLExtendedRuleSerializer,
|
||||||
|
ACLInterfaceAssignmentSerializer,
|
||||||
|
ACLStandardRuleSerializer,
|
||||||
|
)
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
'AccessListViewSet',
|
"AccessListViewSet",
|
||||||
'ACLStandardRuleViewSet',
|
"ACLStandardRuleViewSet",
|
||||||
'ACLInterfaceAssignmentViewSet'
|
"ACLInterfaceAssignmentViewSet" "ACLExtendedRuleViewSet",
|
||||||
'ACLExtendedRuleViewSet',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@ -24,8 +26,9 @@ class AccessListViewSet(NetBoxModelViewSet):
|
|||||||
"""
|
"""
|
||||||
Defines the view set for the django AccessList model & associates it to a view.
|
Defines the view set for the django AccessList model & associates it to a view.
|
||||||
"""
|
"""
|
||||||
queryset = models.AccessList.objects.prefetch_related('tags').annotate(
|
|
||||||
rule_count=Count('aclextendedrules') + Count('aclstandardrules')
|
queryset = models.AccessList.objects.prefetch_related("tags").annotate(
|
||||||
|
rule_count=Count("aclextendedrules") + Count("aclstandardrules"),
|
||||||
)
|
)
|
||||||
serializer_class = AccessListSerializer
|
serializer_class = AccessListSerializer
|
||||||
filterset_class = filtersets.AccessListFilterSet
|
filterset_class = filtersets.AccessListFilterSet
|
||||||
@ -35,7 +38,10 @@ class ACLInterfaceAssignmentViewSet(NetBoxModelViewSet):
|
|||||||
"""
|
"""
|
||||||
Defines the view set for the django ACLInterfaceAssignment model & associates it to a view.
|
Defines the view set for the django ACLInterfaceAssignment model & associates it to a view.
|
||||||
"""
|
"""
|
||||||
queryset = models.ACLInterfaceAssignment.objects.prefetch_related('access_list', 'tags')
|
|
||||||
|
queryset = models.ACLInterfaceAssignment.objects.prefetch_related(
|
||||||
|
"access_list", "tags"
|
||||||
|
)
|
||||||
serializer_class = ACLInterfaceAssignmentSerializer
|
serializer_class = ACLInterfaceAssignmentSerializer
|
||||||
filterset_class = filtersets.ACLInterfaceAssignmentFilterSet
|
filterset_class = filtersets.ACLInterfaceAssignmentFilterSet
|
||||||
|
|
||||||
@ -44,8 +50,11 @@ class ACLStandardRuleViewSet(NetBoxModelViewSet):
|
|||||||
"""
|
"""
|
||||||
Defines the view set for the django ACLStandardRule model & associates it to a view.
|
Defines the view set for the django ACLStandardRule model & associates it to a view.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = models.ACLStandardRule.objects.prefetch_related(
|
queryset = models.ACLStandardRule.objects.prefetch_related(
|
||||||
'access_list', 'tags', 'source_prefix'
|
"access_list",
|
||||||
|
"tags",
|
||||||
|
"source_prefix",
|
||||||
)
|
)
|
||||||
serializer_class = ACLStandardRuleSerializer
|
serializer_class = ACLStandardRuleSerializer
|
||||||
filterset_class = filtersets.ACLStandardRuleFilterSet
|
filterset_class = filtersets.ACLStandardRuleFilterSet
|
||||||
@ -55,8 +64,12 @@ class ACLExtendedRuleViewSet(NetBoxModelViewSet):
|
|||||||
"""
|
"""
|
||||||
Defines the view set for the django ACLExtendedRule model & associates it to a view.
|
Defines the view set for the django ACLExtendedRule model & associates it to a view.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = models.ACLExtendedRule.objects.prefetch_related(
|
queryset = models.ACLExtendedRule.objects.prefetch_related(
|
||||||
'access_list', 'tags', 'source_prefix', 'destination_prefix',
|
"access_list",
|
||||||
|
"tags",
|
||||||
|
"source_prefix",
|
||||||
|
"destination_prefix",
|
||||||
)
|
)
|
||||||
serializer_class = ACLExtendedRuleSerializer
|
serializer_class = ACLExtendedRuleSerializer
|
||||||
filterset_class = filtersets.ACLExtendedRuleFilterSet
|
filterset_class = filtersets.ACLExtendedRuleFilterSet
|
||||||
|
|||||||
@ -5,12 +5,12 @@ Defines the various choices to be used by the models, forms, and other plugin sp
|
|||||||
from utilities.choices import ChoiceSet
|
from utilities.choices import ChoiceSet
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'ACLActionChoices',
|
"ACLActionChoices",
|
||||||
'ACLAssignmentDirectionChoices',
|
"ACLAssignmentDirectionChoices",
|
||||||
'ACLProtocolChoices',
|
"ACLProtocolChoices",
|
||||||
'ACLRuleActionChoices',
|
"ACLRuleActionChoices",
|
||||||
'ACLTypeChoices',
|
"ACLTypeChoices",
|
||||||
'ACLProtocolChoices',
|
"ACLProtocolChoices",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -18,14 +18,15 @@ class ACLActionChoices(ChoiceSet):
|
|||||||
"""
|
"""
|
||||||
Defines the choices availble for the Access Lists plugin specific to ACL default_action.
|
Defines the choices availble for the Access Lists plugin specific to ACL default_action.
|
||||||
"""
|
"""
|
||||||
ACTION_DENY = 'deny'
|
|
||||||
ACTION_PERMIT = 'permit'
|
ACTION_DENY = "deny"
|
||||||
ACTION_REJECT = 'reject'
|
ACTION_PERMIT = "permit"
|
||||||
|
ACTION_REJECT = "reject"
|
||||||
|
|
||||||
CHOICES = [
|
CHOICES = [
|
||||||
(ACTION_DENY, 'Deny', 'red'),
|
(ACTION_DENY, "Deny", "red"),
|
||||||
(ACTION_PERMIT, 'Permit', 'green'),
|
(ACTION_PERMIT, "Permit", "green"),
|
||||||
(ACTION_REJECT, 'Reject (Reset)', 'orange'),
|
(ACTION_REJECT, "Reject (Reset)", "orange"),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@ -33,14 +34,15 @@ class ACLRuleActionChoices(ChoiceSet):
|
|||||||
"""
|
"""
|
||||||
Defines the choices availble for the Access Lists plugin specific to ACL rule actions.
|
Defines the choices availble for the Access Lists plugin specific to ACL rule actions.
|
||||||
"""
|
"""
|
||||||
ACTION_DENY = 'deny'
|
|
||||||
ACTION_PERMIT = 'permit'
|
ACTION_DENY = "deny"
|
||||||
ACTION_REMARK = 'remark'
|
ACTION_PERMIT = "permit"
|
||||||
|
ACTION_REMARK = "remark"
|
||||||
|
|
||||||
CHOICES = [
|
CHOICES = [
|
||||||
(ACTION_DENY, 'Deny', 'red'),
|
(ACTION_DENY, "Deny", "red"),
|
||||||
(ACTION_PERMIT, 'Permit', 'green'),
|
(ACTION_PERMIT, "Permit", "green"),
|
||||||
(ACTION_REMARK, 'Remark', 'blue'),
|
(ACTION_REMARK, "Remark", "blue"),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@ -50,8 +52,8 @@ class ACLAssignmentDirectionChoices(ChoiceSet):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
CHOICES = [
|
CHOICES = [
|
||||||
('ingress', 'Ingress', 'blue'),
|
("ingress", "Ingress", "blue"),
|
||||||
('egress', 'Egress', 'purple'),
|
("egress", "Egress", "purple"),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@ -59,9 +61,10 @@ class ACLTypeChoices(ChoiceSet):
|
|||||||
"""
|
"""
|
||||||
Defines the choices availble for the Access Lists plugin specific to ACL type.
|
Defines the choices availble for the Access Lists plugin specific to ACL type.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
CHOICES = [
|
CHOICES = [
|
||||||
('extended', 'Extended', 'purple'),
|
("extended", "Extended", "purple"),
|
||||||
('standard', 'Standard', 'blue'),
|
("standard", "Standard", "blue"),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@ -69,8 +72,9 @@ class ACLProtocolChoices(ChoiceSet):
|
|||||||
"""
|
"""
|
||||||
Defines the choices availble for the Access Lists plugin specific to ACL Rule protocol.
|
Defines the choices availble for the Access Lists plugin specific to ACL Rule protocol.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
CHOICES = [
|
CHOICES = [
|
||||||
('icmp', 'ICMP', 'purple'),
|
("icmp", "ICMP", "purple"),
|
||||||
('tcp', 'TCP', 'blue'),
|
("tcp", "TCP", "blue"),
|
||||||
('udp', 'UDP', 'orange'),
|
("udp", "UDP", "orange"),
|
||||||
]
|
]
|
||||||
|
|||||||
@ -4,12 +4,12 @@ Constants for filters
|
|||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
|
|
||||||
ACL_HOST_ASSIGNMENT_MODELS = Q(
|
ACL_HOST_ASSIGNMENT_MODELS = Q(
|
||||||
Q(app_label='dcim', model='device') |
|
Q(app_label="dcim", model="device")
|
||||||
Q(app_label='dcim', model='virtualchassis') |
|
| Q(app_label="dcim", model="virtualchassis")
|
||||||
Q(app_label='virtualization', model='virtualmachine')
|
| Q(app_label="virtualization", model="virtualmachine"),
|
||||||
)
|
)
|
||||||
|
|
||||||
ACL_INTERFACE_ASSIGNMENT_MODELS = Q(
|
ACL_INTERFACE_ASSIGNMENT_MODELS = Q(
|
||||||
Q(app_label='dcim', model='interface') |
|
Q(app_label="dcim", model="interface")
|
||||||
Q(app_label='virtualization', model='vminterface')
|
| Q(app_label="virtualization", model="vminterface"),
|
||||||
)
|
)
|
||||||
@ -10,10 +10,10 @@ from virtualization.models import VirtualMachine, VMInterface
|
|||||||
from .models import *
|
from .models import *
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'AccessListFilterSet',
|
"AccessListFilterSet",
|
||||||
'ACLStandardRuleFilterSet',
|
"ACLStandardRuleFilterSet",
|
||||||
'ACLInterfaceAssignmentFilterSet',
|
"ACLInterfaceAssignmentFilterSet",
|
||||||
'ACLExtendedRuleFilterSet',
|
"ACLExtendedRuleFilterSet",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -21,46 +21,60 @@ class AccessListFilterSet(NetBoxModelFilterSet):
|
|||||||
"""
|
"""
|
||||||
Define the filter set for the django model AccessList.
|
Define the filter set for the django model AccessList.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
device = django_filters.ModelMultipleChoiceFilter(
|
device = django_filters.ModelMultipleChoiceFilter(
|
||||||
field_name='device__name',
|
field_name="device__name",
|
||||||
queryset=Device.objects.all(),
|
queryset=Device.objects.all(),
|
||||||
to_field_name='name',
|
to_field_name="name",
|
||||||
label='Device (name)',
|
label="Device (name)",
|
||||||
)
|
)
|
||||||
device_id = django_filters.ModelMultipleChoiceFilter(
|
device_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
field_name='device',
|
field_name="device",
|
||||||
queryset=Device.objects.all(),
|
queryset=Device.objects.all(),
|
||||||
label='Device (ID)',
|
label="Device (ID)",
|
||||||
)
|
)
|
||||||
virtual_chassis = django_filters.ModelMultipleChoiceFilter(
|
virtual_chassis = django_filters.ModelMultipleChoiceFilter(
|
||||||
field_name='virtual_chassis__name',
|
field_name="virtual_chassis__name",
|
||||||
queryset=VirtualChassis.objects.all(),
|
queryset=VirtualChassis.objects.all(),
|
||||||
to_field_name='name',
|
to_field_name="name",
|
||||||
label='Virtual Chassis (name)',
|
label="Virtual Chassis (name)",
|
||||||
)
|
)
|
||||||
virtual_chassis_id = django_filters.ModelMultipleChoiceFilter(
|
virtual_chassis_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
field_name='virtual_chassis',
|
field_name="virtual_chassis",
|
||||||
queryset=VirtualChassis.objects.all(),
|
queryset=VirtualChassis.objects.all(),
|
||||||
label='Virtual Chassis (ID)',
|
label="Virtual Chassis (ID)",
|
||||||
)
|
)
|
||||||
virtual_machine = django_filters.ModelMultipleChoiceFilter(
|
virtual_machine = django_filters.ModelMultipleChoiceFilter(
|
||||||
field_name='virtual_machine__name',
|
field_name="virtual_machine__name",
|
||||||
queryset=VirtualMachine.objects.all(),
|
queryset=VirtualMachine.objects.all(),
|
||||||
to_field_name='name',
|
to_field_name="name",
|
||||||
label='Virtual Machine (name)',
|
label="Virtual Machine (name)",
|
||||||
)
|
)
|
||||||
virtual_machine_id = django_filters.ModelMultipleChoiceFilter(
|
virtual_machine_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
field_name='virtual_machine',
|
field_name="virtual_machine",
|
||||||
queryset=VirtualMachine.objects.all(),
|
queryset=VirtualMachine.objects.all(),
|
||||||
label='Virtual machine (ID)',
|
label="Virtual machine (ID)",
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""
|
"""
|
||||||
Associates the django model AccessList & fields to the filter set.
|
Associates the django model AccessList & fields to the filter set.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
model = AccessList
|
model = AccessList
|
||||||
fields = ('id', 'name', 'device', 'device_id', 'virtual_chassis', 'virtual_chassis_id', 'virtual_machine', 'virtual_machine_id', 'type', 'default_action', 'comments')
|
fields = (
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"device",
|
||||||
|
"device_id",
|
||||||
|
"virtual_chassis",
|
||||||
|
"virtual_chassis_id",
|
||||||
|
"virtual_machine",
|
||||||
|
"virtual_machine_id",
|
||||||
|
"type",
|
||||||
|
"default_action",
|
||||||
|
"comments",
|
||||||
|
)
|
||||||
|
|
||||||
def search(self, queryset, name, value):
|
def search(self, queryset, name, value):
|
||||||
"""
|
"""
|
||||||
@ -73,35 +87,45 @@ class ACLInterfaceAssignmentFilterSet(NetBoxModelFilterSet):
|
|||||||
"""
|
"""
|
||||||
Define the filter set for the django model ACLInterfaceAssignment.
|
Define the filter set for the django model ACLInterfaceAssignment.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
interface = django_filters.ModelMultipleChoiceFilter(
|
interface = django_filters.ModelMultipleChoiceFilter(
|
||||||
field_name='interface__name',
|
field_name="interface__name",
|
||||||
queryset=Interface.objects.all(),
|
queryset=Interface.objects.all(),
|
||||||
to_field_name='name',
|
to_field_name="name",
|
||||||
label='Interface (name)',
|
label="Interface (name)",
|
||||||
)
|
)
|
||||||
interface_id = django_filters.ModelMultipleChoiceFilter(
|
interface_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
field_name='interface',
|
field_name="interface",
|
||||||
queryset=Interface.objects.all(),
|
queryset=Interface.objects.all(),
|
||||||
label='Interface (ID)',
|
label="Interface (ID)",
|
||||||
)
|
)
|
||||||
vminterface = django_filters.ModelMultipleChoiceFilter(
|
vminterface = django_filters.ModelMultipleChoiceFilter(
|
||||||
field_name='vminterface__name',
|
field_name="vminterface__name",
|
||||||
queryset=VMInterface.objects.all(),
|
queryset=VMInterface.objects.all(),
|
||||||
to_field_name='name',
|
to_field_name="name",
|
||||||
label='VM Interface (name)',
|
label="VM Interface (name)",
|
||||||
)
|
)
|
||||||
vminterface_id = django_filters.ModelMultipleChoiceFilter(
|
vminterface_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
field_name='vminterface',
|
field_name="vminterface",
|
||||||
queryset=VMInterface.objects.all(),
|
queryset=VMInterface.objects.all(),
|
||||||
label='VM Interface (ID)',
|
label="VM Interface (ID)",
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""
|
"""
|
||||||
Associates the django model ACLInterfaceAssignment & fields to the filter set.
|
Associates the django model ACLInterfaceAssignment & fields to the filter set.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
model = ACLInterfaceAssignment
|
model = ACLInterfaceAssignment
|
||||||
fields = ('id', 'access_list', 'direction', 'interface', 'interface_id', 'vminterface', 'vminterface_id')
|
fields = (
|
||||||
|
"id",
|
||||||
|
"access_list",
|
||||||
|
"direction",
|
||||||
|
"interface",
|
||||||
|
"interface_id",
|
||||||
|
"vminterface",
|
||||||
|
"vminterface_id",
|
||||||
|
)
|
||||||
|
|
||||||
def search(self, queryset, name, value):
|
def search(self, queryset, name, value):
|
||||||
"""
|
"""
|
||||||
@ -119,8 +143,9 @@ class ACLStandardRuleFilterSet(NetBoxModelFilterSet):
|
|||||||
"""
|
"""
|
||||||
Associates the django model ACLStandardRule & fields to the filter set.
|
Associates the django model ACLStandardRule & fields to the filter set.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
model = ACLStandardRule
|
model = ACLStandardRule
|
||||||
fields = ('id', 'access_list', 'index', 'action')
|
fields = ("id", "access_list", "index", "action")
|
||||||
|
|
||||||
def search(self, queryset, name, value):
|
def search(self, queryset, name, value):
|
||||||
"""
|
"""
|
||||||
@ -138,8 +163,9 @@ class ACLExtendedRuleFilterSet(NetBoxModelFilterSet):
|
|||||||
"""
|
"""
|
||||||
Associates the django model ACLExtendedRule & fields to the filter set.
|
Associates the django model ACLExtendedRule & fields to the filter set.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
model = ACLExtendedRule
|
model = ACLExtendedRule
|
||||||
fields = ('id', 'access_list', 'index', 'action', 'protocol')
|
fields = ("id", "access_list", "index", "action", "protocol")
|
||||||
|
|
||||||
def search(self, queryset, name, value):
|
def search(self, queryset, name, value):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@ -2,13 +2,15 @@
|
|||||||
Import each of the directory's scripts.
|
Import each of the directory's scripts.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#from .bulk_create import *
|
# from .bulk_create import *
|
||||||
from .bulk_edit import *
|
from .bulk_edit import *
|
||||||
#from .bulk_import import *
|
|
||||||
#from .connections import *
|
# from .bulk_import import *
|
||||||
|
# from .connections import *
|
||||||
from .filtersets import *
|
from .filtersets import *
|
||||||
#from .formsets import *
|
|
||||||
|
# from .formsets import *
|
||||||
from .models import *
|
from .models import *
|
||||||
|
|
||||||
#from .object_create import *
|
# from .object_create import *
|
||||||
#from .object_import import *
|
# from .object_import import *
|
||||||
|
|||||||
@ -7,19 +7,23 @@ from django import forms
|
|||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.utils.safestring import mark_safe
|
from django.utils.safestring import mark_safe
|
||||||
from netbox.forms import NetBoxModelBulkEditForm
|
from netbox.forms import NetBoxModelBulkEditForm
|
||||||
from utilities.forms import (ChoiceField, DynamicModelChoiceField,
|
from utilities.forms import (
|
||||||
StaticSelect, add_blank_choice)
|
ChoiceField,
|
||||||
|
DynamicModelChoiceField,
|
||||||
|
StaticSelect,
|
||||||
|
add_blank_choice,
|
||||||
|
)
|
||||||
from virtualization.models import VirtualMachine
|
from virtualization.models import VirtualMachine
|
||||||
|
|
||||||
from ..choices import ACLActionChoices, ACLTypeChoices
|
from ..choices import ACLActionChoices, ACLTypeChoices
|
||||||
from ..models import AccessList
|
from ..models import AccessList
|
||||||
|
|
||||||
#__all__ = (
|
# __all__ = (
|
||||||
# 'AccessListBulkEditForm',
|
# 'AccessListBulkEditForm',
|
||||||
#)
|
# )
|
||||||
|
|
||||||
|
|
||||||
#class AccessListBulkEditForm(NetBoxModelBulkEditForm):
|
# class AccessListBulkEditForm(NetBoxModelBulkEditForm):
|
||||||
# model = AccessList
|
# model = AccessList
|
||||||
#
|
#
|
||||||
# region = DynamicModelChoiceField(
|
# region = DynamicModelChoiceField(
|
||||||
|
|||||||
@ -2,27 +2,39 @@
|
|||||||
Defines each django model's GUI filter/search options.
|
Defines each django model's GUI filter/search options.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from dcim.models import (Device, Interface, Region, Site, SiteGroup,
|
from dcim.models import Device, Interface, Region, Site, SiteGroup, VirtualChassis
|
||||||
VirtualChassis)
|
|
||||||
from django import forms
|
from django import forms
|
||||||
from ipam.models import Prefix
|
from ipam.models import Prefix
|
||||||
from netbox.forms import NetBoxModelFilterSetForm
|
from netbox.forms import NetBoxModelFilterSetForm
|
||||||
from utilities.forms import (ChoiceField, DynamicModelChoiceField,
|
from utilities.forms import (
|
||||||
StaticSelect, StaticSelectMultiple,
|
ChoiceField,
|
||||||
TagFilterField, add_blank_choice)
|
DynamicModelChoiceField,
|
||||||
|
StaticSelect,
|
||||||
|
StaticSelectMultiple,
|
||||||
|
TagFilterField,
|
||||||
|
add_blank_choice,
|
||||||
|
)
|
||||||
from virtualization.models import VirtualMachine, VMInterface
|
from virtualization.models import VirtualMachine, VMInterface
|
||||||
|
|
||||||
from ..choices import (ACLActionChoices, ACLAssignmentDirectionChoices,
|
from ..choices import (
|
||||||
ACLProtocolChoices, ACLRuleActionChoices,
|
ACLActionChoices,
|
||||||
ACLTypeChoices)
|
ACLAssignmentDirectionChoices,
|
||||||
from ..models import (AccessList, ACLExtendedRule, ACLInterfaceAssignment,
|
ACLProtocolChoices,
|
||||||
ACLStandardRule)
|
ACLRuleActionChoices,
|
||||||
|
ACLTypeChoices,
|
||||||
|
)
|
||||||
|
from ..models import (
|
||||||
|
AccessList,
|
||||||
|
ACLExtendedRule,
|
||||||
|
ACLInterfaceAssignment,
|
||||||
|
ACLStandardRule,
|
||||||
|
)
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'AccessListFilterForm',
|
"AccessListFilterForm",
|
||||||
'ACLInterfaceAssignmentFilterForm',
|
"ACLInterfaceAssignmentFilterForm",
|
||||||
'ACLStandardRuleFilterForm',
|
"ACLStandardRuleFilterForm",
|
||||||
'ACLExtendedRuleFilterForm',
|
"ACLExtendedRuleFilterForm",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -30,6 +42,7 @@ class AccessListFilterForm(NetBoxModelFilterSetForm):
|
|||||||
"""
|
"""
|
||||||
GUI filter form to search the django AccessList model.
|
GUI filter form to search the django AccessList model.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
model = AccessList
|
model = AccessList
|
||||||
region = DynamicModelChoiceField(
|
region = DynamicModelChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
@ -38,40 +51,40 @@ class AccessListFilterForm(NetBoxModelFilterSetForm):
|
|||||||
site_group = DynamicModelChoiceField(
|
site_group = DynamicModelChoiceField(
|
||||||
queryset=SiteGroup.objects.all(),
|
queryset=SiteGroup.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label='Site Group'
|
label="Site Group",
|
||||||
)
|
)
|
||||||
site = DynamicModelChoiceField(
|
site = DynamicModelChoiceField(
|
||||||
queryset=Site.objects.all(),
|
queryset=Site.objects.all(),
|
||||||
required=False
|
required=False,
|
||||||
)
|
)
|
||||||
device = DynamicModelChoiceField(
|
device = DynamicModelChoiceField(
|
||||||
queryset=Device.objects.all(),
|
queryset=Device.objects.all(),
|
||||||
query_params={
|
query_params={
|
||||||
'region': '$region',
|
"region": "$region",
|
||||||
'group_id': '$site_group',
|
"group_id": "$site_group",
|
||||||
'site_id': '$site',
|
"site_id": "$site",
|
||||||
},
|
},
|
||||||
required=False
|
required=False,
|
||||||
)
|
)
|
||||||
type = ChoiceField(
|
type = ChoiceField(
|
||||||
choices=add_blank_choice(ACLTypeChoices),
|
choices=add_blank_choice(ACLTypeChoices),
|
||||||
required=False,
|
required=False,
|
||||||
initial='',
|
initial="",
|
||||||
widget=StaticSelect(),
|
widget=StaticSelect(),
|
||||||
)
|
)
|
||||||
default_action = ChoiceField(
|
default_action = ChoiceField(
|
||||||
choices=add_blank_choice(ACLActionChoices),
|
choices=add_blank_choice(ACLActionChoices),
|
||||||
required=False,
|
required=False,
|
||||||
initial='',
|
initial="",
|
||||||
widget=StaticSelect(),
|
widget=StaticSelect(),
|
||||||
label='Default Action',
|
label="Default Action",
|
||||||
)
|
)
|
||||||
tag = TagFilterField(model)
|
tag = TagFilterField(model)
|
||||||
|
|
||||||
fieldsets = (
|
fieldsets = (
|
||||||
(None, ('q', 'tag')),
|
(None, ("q", "tag")),
|
||||||
('Host Details', ('region', 'site_group', 'site', 'device')),
|
("Host Details", ("region", "site_group", "site", "device")),
|
||||||
('ACL Details', ('type', 'default_action')),
|
("ACL Details", ("type", "default_action")),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -79,6 +92,7 @@ class ACLInterfaceAssignmentFilterForm(NetBoxModelFilterSetForm):
|
|||||||
"""
|
"""
|
||||||
GUI filter form to search the django AccessList model.
|
GUI filter form to search the django AccessList model.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
model = ACLInterfaceAssignment
|
model = ACLInterfaceAssignment
|
||||||
region = DynamicModelChoiceField(
|
region = DynamicModelChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
@ -87,84 +101,85 @@ class ACLInterfaceAssignmentFilterForm(NetBoxModelFilterSetForm):
|
|||||||
site_group = DynamicModelChoiceField(
|
site_group = DynamicModelChoiceField(
|
||||||
queryset=SiteGroup.objects.all(),
|
queryset=SiteGroup.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label='Site Group'
|
label="Site Group",
|
||||||
)
|
)
|
||||||
site = DynamicModelChoiceField(
|
site = DynamicModelChoiceField(
|
||||||
queryset=Site.objects.all(),
|
queryset=Site.objects.all(),
|
||||||
required=False
|
required=False,
|
||||||
)
|
)
|
||||||
device = DynamicModelChoiceField(
|
device = DynamicModelChoiceField(
|
||||||
queryset=Device.objects.all(),
|
queryset=Device.objects.all(),
|
||||||
query_params={
|
query_params={
|
||||||
'region': '$region',
|
"region": "$region",
|
||||||
'group_id': '$site_group',
|
"group_id": "$site_group",
|
||||||
'site_id': '$site',
|
"site_id": "$site",
|
||||||
},
|
},
|
||||||
required=False
|
required=False,
|
||||||
)
|
)
|
||||||
interface = DynamicModelChoiceField(
|
interface = DynamicModelChoiceField(
|
||||||
queryset=Interface.objects.all(),
|
queryset=Interface.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
query_params={
|
query_params={
|
||||||
'device_id': '$device'
|
"device_id": "$device",
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
virtual_machine = DynamicModelChoiceField(
|
virtual_machine = DynamicModelChoiceField(
|
||||||
queryset=VirtualMachine.objects.all(),
|
queryset=VirtualMachine.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label='Virtual Machine',
|
label="Virtual Machine",
|
||||||
)
|
)
|
||||||
vminterface = DynamicModelChoiceField(
|
vminterface = DynamicModelChoiceField(
|
||||||
queryset=VMInterface.objects.all(),
|
queryset=VMInterface.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
query_params={
|
query_params={
|
||||||
'virtual_machine_id': '$virtual_machine'
|
"virtual_machine_id": "$virtual_machine",
|
||||||
},
|
},
|
||||||
label='Interface'
|
label="Interface",
|
||||||
)
|
)
|
||||||
access_list = DynamicModelChoiceField(
|
access_list = DynamicModelChoiceField(
|
||||||
queryset=AccessList.objects.all(),
|
queryset=AccessList.objects.all(),
|
||||||
query_params={
|
query_params={
|
||||||
'assigned_object': '$device',
|
"assigned_object": "$device",
|
||||||
},
|
},
|
||||||
label='Access List',
|
label="Access List",
|
||||||
)
|
)
|
||||||
direction = ChoiceField(
|
direction = ChoiceField(
|
||||||
choices=add_blank_choice(ACLAssignmentDirectionChoices),
|
choices=add_blank_choice(ACLAssignmentDirectionChoices),
|
||||||
required=False,
|
required=False,
|
||||||
initial='',
|
initial="",
|
||||||
widget=StaticSelect(),
|
widget=StaticSelect(),
|
||||||
)
|
)
|
||||||
tag = TagFilterField(model)
|
tag = TagFilterField(model)
|
||||||
|
|
||||||
#fieldsets = (
|
# fieldsets = (
|
||||||
# (None, ('q', 'tag')),
|
# (None, ('q', 'tag')),
|
||||||
# ('Host Details', ('region', 'site_group', 'site', 'device')),
|
# ('Host Details', ('region', 'site_group', 'site', 'device')),
|
||||||
# ('ACL Details', ('type', 'default_action')),
|
# ('ACL Details', ('type', 'default_action')),
|
||||||
#)
|
# )
|
||||||
|
|
||||||
|
|
||||||
class ACLStandardRuleFilterForm(NetBoxModelFilterSetForm):
|
class ACLStandardRuleFilterForm(NetBoxModelFilterSetForm):
|
||||||
"""
|
"""
|
||||||
GUI filter form to search the django ACLStandardRule model.
|
GUI filter form to search the django ACLStandardRule model.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
model = ACLStandardRule
|
model = ACLStandardRule
|
||||||
tag = TagFilterField(model)
|
tag = TagFilterField(model)
|
||||||
source_prefix = forms.ModelMultipleChoiceField(
|
source_prefix = forms.ModelMultipleChoiceField(
|
||||||
queryset=Prefix.objects.all(),
|
queryset=Prefix.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
widget=StaticSelectMultiple(),
|
widget=StaticSelectMultiple(),
|
||||||
label='Source Prefix',
|
label="Source Prefix",
|
||||||
)
|
)
|
||||||
action = forms.ChoiceField(
|
action = forms.ChoiceField(
|
||||||
choices=add_blank_choice(ACLRuleActionChoices),
|
choices=add_blank_choice(ACLRuleActionChoices),
|
||||||
required=False,
|
required=False,
|
||||||
initial='',
|
initial="",
|
||||||
widget=StaticSelect(),
|
widget=StaticSelect(),
|
||||||
)
|
)
|
||||||
fieldsets = (
|
fieldsets = (
|
||||||
(None, ('q', 'tag')),
|
(None, ("q", "tag")),
|
||||||
('Rule Details', ('action', 'source_prefix',)),
|
("Rule Details", ("action", "source_prefix")),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -172,37 +187,38 @@ class ACLExtendedRuleFilterForm(NetBoxModelFilterSetForm):
|
|||||||
"""
|
"""
|
||||||
GUI filter form to search the django ACLExtendedRule model.
|
GUI filter form to search the django ACLExtendedRule model.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
model = ACLExtendedRule
|
model = ACLExtendedRule
|
||||||
index = forms.IntegerField(
|
index = forms.IntegerField(
|
||||||
required=False
|
required=False,
|
||||||
)
|
)
|
||||||
tag = TagFilterField(model)
|
tag = TagFilterField(model)
|
||||||
action = forms.ChoiceField(
|
action = forms.ChoiceField(
|
||||||
choices=add_blank_choice(ACLRuleActionChoices),
|
choices=add_blank_choice(ACLRuleActionChoices),
|
||||||
required=False,
|
required=False,
|
||||||
widget=StaticSelect(),
|
widget=StaticSelect(),
|
||||||
initial='',
|
initial="",
|
||||||
)
|
)
|
||||||
source_prefix = forms.ModelMultipleChoiceField(
|
source_prefix = forms.ModelMultipleChoiceField(
|
||||||
queryset=Prefix.objects.all(),
|
queryset=Prefix.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
widget=StaticSelectMultiple(),
|
widget=StaticSelectMultiple(),
|
||||||
label='Source Prefix',
|
label="Source Prefix",
|
||||||
)
|
)
|
||||||
desintation_prefix = forms.ModelMultipleChoiceField(
|
desintation_prefix = forms.ModelMultipleChoiceField(
|
||||||
queryset=Prefix.objects.all(),
|
queryset=Prefix.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
widget=StaticSelectMultiple(),
|
widget=StaticSelectMultiple(),
|
||||||
label='Destination Prefix',
|
label="Destination Prefix",
|
||||||
)
|
)
|
||||||
protocol = ChoiceField(
|
protocol = ChoiceField(
|
||||||
choices=add_blank_choice(ACLProtocolChoices),
|
choices=add_blank_choice(ACLProtocolChoices),
|
||||||
required=False,
|
required=False,
|
||||||
widget=StaticSelect(),
|
widget=StaticSelect(),
|
||||||
initial='',
|
initial="",
|
||||||
)
|
)
|
||||||
|
|
||||||
fieldsets = (
|
fieldsets = (
|
||||||
(None, ('q', 'tag')),
|
(None, ("q", "tag")),
|
||||||
('Rule Details', ('action', 'source_prefix', 'desintation_prefix', 'protocol')),
|
("Rule Details", ("action", "source_prefix", "desintation_prefix", "protocol")),
|
||||||
)
|
)
|
||||||
|
|||||||
@ -2,41 +2,55 @@
|
|||||||
Defines each django model's GUI form to add or edit objects for each django model.
|
Defines each django model's GUI form to add or edit objects for each django model.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from dcim.models import (Device, Interface, Region, Site, SiteGroup,
|
from dcim.models import Device, Interface, Region, Site, SiteGroup, VirtualChassis
|
||||||
VirtualChassis)
|
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.utils.safestring import mark_safe
|
from django.utils.safestring import mark_safe
|
||||||
from extras.models import Tag
|
from extras.models import Tag
|
||||||
from ipam.models import Prefix
|
from ipam.models import Prefix
|
||||||
from netbox.forms import NetBoxModelForm
|
from netbox.forms import NetBoxModelForm
|
||||||
from utilities.forms import (CommentField, DynamicModelChoiceField,
|
from utilities.forms import (
|
||||||
DynamicModelMultipleChoiceField)
|
CommentField,
|
||||||
|
DynamicModelChoiceField,
|
||||||
|
DynamicModelMultipleChoiceField,
|
||||||
|
)
|
||||||
from virtualization.models import VirtualMachine, VMInterface
|
from virtualization.models import VirtualMachine, VMInterface
|
||||||
|
|
||||||
from ..models import (AccessList, ACLExtendedRule, ACLInterfaceAssignment,
|
from ..models import (
|
||||||
ACLStandardRule)
|
AccessList,
|
||||||
|
ACLExtendedRule,
|
||||||
|
ACLInterfaceAssignment,
|
||||||
|
ACLStandardRule,
|
||||||
|
)
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'AccessListForm',
|
"AccessListForm",
|
||||||
'ACLInterfaceAssignmentForm',
|
"ACLInterfaceAssignmentForm",
|
||||||
'ACLStandardRuleForm',
|
"ACLStandardRuleForm",
|
||||||
'ACLExtendedRuleForm',
|
"ACLExtendedRuleForm",
|
||||||
)
|
)
|
||||||
|
|
||||||
# Sets a standard mark_safe help_text value to be used by the various classes
|
# Sets a standard mark_safe help_text value to be used by the various classes
|
||||||
help_text_acl_rule_logic = mark_safe('<b>*Note:</b> CANNOT be set if action is set to remark.')
|
help_text_acl_rule_logic = mark_safe(
|
||||||
|
"<b>*Note:</b> CANNOT be set if action is set to remark."
|
||||||
|
)
|
||||||
# Sets a standard help_text value to be used by the various classes for acl action
|
# Sets a standard help_text value to be used by the various classes for acl action
|
||||||
help_text_acl_action = 'Action the rule will take (remark, deny, or allow).'
|
help_text_acl_action = "Action the rule will take (remark, deny, or allow)."
|
||||||
# Sets a standard help_text value to be used by the various classes for acl index
|
# Sets a standard help_text value to be used by the various classes for acl index
|
||||||
help_text_acl_rule_index = 'Determines the order of the rule in the ACL processing. AKA Sequence Number.'
|
help_text_acl_rule_index = (
|
||||||
|
"Determines the order of the rule in the ACL processing. AKA Sequence Number."
|
||||||
|
)
|
||||||
|
|
||||||
# Sets a standard error message for ACL rules with an action of remark, but no remark set.
|
# Sets a standard error message for ACL rules with an action of remark, but no remark set.
|
||||||
error_message_no_remark = 'Action is set to remark, you MUST add a remark.'
|
error_message_no_remark = "Action is set to remark, you MUST add a remark."
|
||||||
# Sets a standard error message for ACL rules with an action of remark, but no source_prefix is set.
|
# Sets a standard error message for ACL rules with an action of remark, but no source_prefix is set.
|
||||||
error_message_action_remark_source_prefix_set = 'Action is set to remark, Source Prefix CANNOT be set.'
|
error_message_action_remark_source_prefix_set = (
|
||||||
|
"Action is set to remark, Source Prefix CANNOT be set."
|
||||||
|
)
|
||||||
# Sets a standard error message for ACL rules with an action not set to remark, but no remark is set.
|
# Sets a standard error message for ACL rules with an action not set to remark, but no remark is set.
|
||||||
error_message_remark_without_action_remark = 'CANNOT set remark unless action is set to remark.'
|
error_message_remark_without_action_remark = (
|
||||||
|
"CANNOT set remark unless action is set to remark."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class AccessListForm(NetBoxModelForm):
|
class AccessListForm(NetBoxModelForm):
|
||||||
@ -44,6 +58,7 @@ class AccessListForm(NetBoxModelForm):
|
|||||||
GUI form to add or edit an AccessList.
|
GUI form to add or edit an AccessList.
|
||||||
Requires a device, a name, a type, and a default_action.
|
Requires a device, a name, a type, and a default_action.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
region = DynamicModelChoiceField(
|
region = DynamicModelChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
@ -51,59 +66,73 @@ class AccessListForm(NetBoxModelForm):
|
|||||||
site_group = DynamicModelChoiceField(
|
site_group = DynamicModelChoiceField(
|
||||||
queryset=SiteGroup.objects.all(),
|
queryset=SiteGroup.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label='Site Group'
|
label="Site Group",
|
||||||
)
|
)
|
||||||
site = DynamicModelChoiceField(
|
site = DynamicModelChoiceField(
|
||||||
queryset=Site.objects.all(),
|
queryset=Site.objects.all(),
|
||||||
required=False
|
required=False,
|
||||||
)
|
)
|
||||||
device = DynamicModelChoiceField(
|
device = DynamicModelChoiceField(
|
||||||
queryset=Device.objects.all(),
|
queryset=Device.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
query_params={
|
query_params={
|
||||||
'region': '$region',
|
"region": "$region",
|
||||||
'group_id': '$site_group',
|
"group_id": "$site_group",
|
||||||
'site_id': '$site',
|
"site_id": "$site",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
virtual_chassis = DynamicModelChoiceField(
|
virtual_chassis = DynamicModelChoiceField(
|
||||||
queryset=VirtualChassis.objects.all(),
|
queryset=VirtualChassis.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label='Virtual Chassis',
|
label="Virtual Chassis",
|
||||||
)
|
)
|
||||||
virtual_machine = DynamicModelChoiceField(
|
virtual_machine = DynamicModelChoiceField(
|
||||||
queryset=VirtualMachine.objects.all(),
|
queryset=VirtualMachine.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label='Virtual Machine',
|
label="Virtual Machine",
|
||||||
)
|
)
|
||||||
comments = CommentField()
|
comments = CommentField()
|
||||||
tags = DynamicModelMultipleChoiceField(
|
tags = DynamicModelMultipleChoiceField(
|
||||||
queryset=Tag.objects.all(),
|
queryset=Tag.objects.all(),
|
||||||
required=False
|
required=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = AccessList
|
model = AccessList
|
||||||
fields = ('region', 'site_group', 'site', 'device', 'virtual_machine', 'virtual_chassis', 'name', 'type', 'default_action', 'comments', 'tags')
|
fields = (
|
||||||
|
"region",
|
||||||
|
"site_group",
|
||||||
|
"site",
|
||||||
|
"device",
|
||||||
|
"virtual_machine",
|
||||||
|
"virtual_chassis",
|
||||||
|
"name",
|
||||||
|
"type",
|
||||||
|
"default_action",
|
||||||
|
"comments",
|
||||||
|
"tags",
|
||||||
|
)
|
||||||
help_texts = {
|
help_texts = {
|
||||||
'default_action': 'The default behavior of the ACL.',
|
"default_action": "The default behavior of the ACL.",
|
||||||
'name': 'The name uniqueness per device is case insensitive.',
|
"name": "The name uniqueness per device is case insensitive.",
|
||||||
'type': mark_safe('<b>*Note:</b> CANNOT be changed if ACL Rules are assoicated to this Access List.'),
|
"type": mark_safe(
|
||||||
|
"<b>*Note:</b> CANNOT be changed if ACL Rules are assoicated to this Access List."
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
|
||||||
# Initialize helper selectors
|
# Initialize helper selectors
|
||||||
instance = kwargs.get('instance')
|
instance = kwargs.get("instance")
|
||||||
initial = kwargs.get('initial', {}).copy()
|
initial = kwargs.get("initial", {}).copy()
|
||||||
if instance:
|
if instance:
|
||||||
if type(instance.assigned_object) is Device:
|
if type(instance.assigned_object) is Device:
|
||||||
initial['device'] = instance.assigned_object
|
initial["device"] = instance.assigned_object
|
||||||
elif type(instance.assigned_object) is VirtualChassis:
|
elif type(instance.assigned_object) is VirtualChassis:
|
||||||
initial['virtual_chassis'] = instance.assigned_object
|
initial["virtual_chassis"] = instance.assigned_object
|
||||||
elif type(instance.assigned_object) is VirtualMachine:
|
elif type(instance.assigned_object) is VirtualMachine:
|
||||||
initial['virtual_machine'] = instance.assigned_object
|
initial["virtual_machine"] = instance.assigned_object
|
||||||
kwargs['initial'] = initial
|
kwargs["initial"] = initial
|
||||||
|
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
@ -117,40 +146,62 @@ class AccessListForm(NetBoxModelForm):
|
|||||||
"""
|
"""
|
||||||
cleaned_data = super().clean()
|
cleaned_data = super().clean()
|
||||||
error_message = {}
|
error_message = {}
|
||||||
if self.errors.get('name'):
|
if self.errors.get("name"):
|
||||||
return cleaned_data
|
return cleaned_data
|
||||||
name = cleaned_data.get('name')
|
name = cleaned_data.get("name")
|
||||||
acl_type = cleaned_data.get('type')
|
acl_type = cleaned_data.get("type")
|
||||||
device = cleaned_data.get('device')
|
device = cleaned_data.get("device")
|
||||||
virtual_chassis = cleaned_data.get('virtual_chassis')
|
virtual_chassis = cleaned_data.get("virtual_chassis")
|
||||||
virtual_machine = cleaned_data.get('virtual_machine')
|
virtual_machine = cleaned_data.get("virtual_machine")
|
||||||
|
|
||||||
|
|
||||||
# Check if more than one host type selected.
|
# Check if more than one host type selected.
|
||||||
if (device and virtual_chassis) or (device and virtual_machine) or (virtual_chassis and virtual_machine):
|
if (
|
||||||
raise forms.ValidationError('Access Lists must be assigned to one host (either a device, virtual chassis or virtual machine) at a time.')
|
(device and virtual_chassis)
|
||||||
|
or (device and virtual_machine)
|
||||||
|
or (virtual_chassis and virtual_machine)
|
||||||
|
):
|
||||||
|
raise forms.ValidationError(
|
||||||
|
"Access Lists must be assigned to one host (either a device, virtual chassis or virtual machine) at a time."
|
||||||
|
)
|
||||||
# Check if no hosts selected.
|
# Check if no hosts selected.
|
||||||
if not device and not virtual_chassis and not virtual_machine:
|
if not device and not virtual_chassis and not virtual_machine:
|
||||||
raise forms.ValidationError('Access Lists must be assigned to a device, virtual chassis or virtual machine.')
|
raise forms.ValidationError(
|
||||||
|
"Access Lists must be assigned to a device, virtual chassis or virtual machine."
|
||||||
|
)
|
||||||
|
|
||||||
if device:
|
if device:
|
||||||
host_type = 'device'
|
host_type = "device"
|
||||||
existing_acls = AccessList.objects.filter(name=name, device=device).exists()
|
existing_acls = AccessList.objects.filter(name=name, device=device).exists()
|
||||||
elif virtual_chassis:
|
elif virtual_chassis:
|
||||||
host_type = 'virtual_chassis'
|
host_type = "virtual_chassis"
|
||||||
existing_acls = AccessList.objects.filter(name=name, virtual_chassis=virtual_chassis).exists()
|
existing_acls = AccessList.objects.filter(
|
||||||
|
name=name, virtual_chassis=virtual_chassis
|
||||||
|
).exists()
|
||||||
elif virtual_machine:
|
elif virtual_machine:
|
||||||
host_type = 'virtual_machine'
|
host_type = "virtual_machine"
|
||||||
existing_acls = AccessList.objects.filter(name=name, virtual_machine=virtual_machine).exists()
|
existing_acls = AccessList.objects.filter(
|
||||||
|
name=name, virtual_machine=virtual_machine
|
||||||
|
).exists()
|
||||||
host = cleaned_data.get(host_type)
|
host = cleaned_data.get(host_type)
|
||||||
|
|
||||||
# Check if duplicate entry.
|
# Check if duplicate entry.
|
||||||
if ('name' in self.changed_data or host_type in self.changed_data) and existing_acls:
|
if (
|
||||||
error_same_acl_name = 'An ACL with this name is already associated to this host.'
|
"name" in self.changed_data or host_type in self.changed_data
|
||||||
error_message |= {host_type: [error_same_acl_name], 'name': [error_same_acl_name]}
|
) and existing_acls:
|
||||||
|
error_same_acl_name = (
|
||||||
|
"An ACL with this name is already associated to this host."
|
||||||
|
)
|
||||||
|
error_message |= {
|
||||||
|
host_type: [error_same_acl_name],
|
||||||
|
"name": [error_same_acl_name],
|
||||||
|
}
|
||||||
# Check if Access List has no existing rules before change the Access List's type.
|
# Check if Access List has no existing rules before change the Access List's type.
|
||||||
if (acl_type == 'extended' and self.instance.aclstandardrules.exists()) or (acl_type == 'standard' and self.instance.aclextendedrules.exists()):
|
if (acl_type == "extended" and self.instance.aclstandardrules.exists()) or (
|
||||||
error_message['type'] = ['This ACL has ACL rules associated, CANNOT change ACL type.']
|
acl_type == "standard" and self.instance.aclextendedrules.exists()
|
||||||
|
):
|
||||||
|
error_message["type"] = [
|
||||||
|
"This ACL has ACL rules associated, CANNOT change ACL type."
|
||||||
|
]
|
||||||
|
|
||||||
if error_message:
|
if error_message:
|
||||||
raise forms.ValidationError(error_message)
|
raise forms.ValidationError(error_message)
|
||||||
@ -159,7 +210,11 @@ class AccessListForm(NetBoxModelForm):
|
|||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
# Set assigned object
|
# Set assigned object
|
||||||
self.instance.assigned_object = self.cleaned_data.get('device') or self.cleaned_data.get('virtual_chassis') or self.cleaned_data.get('virtual_machine')
|
self.instance.assigned_object = (
|
||||||
|
self.cleaned_data.get("device")
|
||||||
|
or self.cleaned_data.get("virtual_chassis")
|
||||||
|
or self.cleaned_data.get("virtual_machine")
|
||||||
|
)
|
||||||
|
|
||||||
return super().save(*args, **kwargs)
|
return super().save(*args, **kwargs)
|
||||||
|
|
||||||
@ -169,78 +224,88 @@ class ACLInterfaceAssignmentForm(NetBoxModelForm):
|
|||||||
GUI form to add or edit ACL Host Object assignments
|
GUI form to add or edit ACL Host Object assignments
|
||||||
Requires an access_list, a name, a type, and a default_action.
|
Requires an access_list, a name, a type, and a default_action.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
device = DynamicModelChoiceField(
|
device = DynamicModelChoiceField(
|
||||||
queryset=Device.objects.all(),
|
queryset=Device.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
query_params={
|
query_params={
|
||||||
# Need to pass ACL device to it
|
# Need to pass ACL device to it
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
interface = DynamicModelChoiceField(
|
interface = DynamicModelChoiceField(
|
||||||
queryset=Interface.objects.all(),
|
queryset=Interface.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
query_params={
|
query_params={
|
||||||
'device_id': '$device'
|
"device_id": "$device",
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
virtual_machine = DynamicModelChoiceField(
|
virtual_machine = DynamicModelChoiceField(
|
||||||
queryset=VirtualMachine.objects.all(),
|
queryset=VirtualMachine.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
label='Virtual Machine',
|
label="Virtual Machine",
|
||||||
)
|
)
|
||||||
vminterface = DynamicModelChoiceField(
|
vminterface = DynamicModelChoiceField(
|
||||||
queryset=VMInterface.objects.all(),
|
queryset=VMInterface.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
query_params={
|
query_params={
|
||||||
'virtual_machine_id': '$virtual_machine'
|
"virtual_machine_id": "$virtual_machine",
|
||||||
},
|
},
|
||||||
label='VM Interface'
|
label="VM Interface",
|
||||||
)
|
)
|
||||||
#virtual_chassis = DynamicModelChoiceField(
|
# virtual_chassis = DynamicModelChoiceField(
|
||||||
# queryset=VirtualChassis.objects.all(),
|
# queryset=VirtualChassis.objects.all(),
|
||||||
# required=False,
|
# required=False,
|
||||||
# label='Virtual Chassis',
|
# label='Virtual Chassis',
|
||||||
#)
|
# )
|
||||||
access_list = DynamicModelChoiceField(
|
access_list = DynamicModelChoiceField(
|
||||||
queryset=AccessList.objects.all(),
|
queryset=AccessList.objects.all(),
|
||||||
#query_params={
|
# query_params={
|
||||||
# 'assigned_object': '$device',
|
# 'assigned_object': '$device',
|
||||||
# 'assigned_object': '$virtual_machine',
|
# 'assigned_object': '$virtual_machine',
|
||||||
#},
|
# },
|
||||||
label='Access List',
|
label="Access List",
|
||||||
help_text=mark_safe('<b>*Note:</b> Access List must be present on the device already.')
|
help_text=mark_safe(
|
||||||
|
"<b>*Note:</b> Access List must be present on the device already."
|
||||||
|
),
|
||||||
)
|
)
|
||||||
comments = CommentField()
|
comments = CommentField()
|
||||||
tags = DynamicModelMultipleChoiceField(
|
tags = DynamicModelMultipleChoiceField(
|
||||||
queryset=Tag.objects.all(),
|
queryset=Tag.objects.all(),
|
||||||
required=False
|
required=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
|
||||||
# Initialize helper selectors
|
# Initialize helper selectors
|
||||||
instance = kwargs.get('instance')
|
instance = kwargs.get("instance")
|
||||||
initial = kwargs.get('initial', {}).copy()
|
initial = kwargs.get("initial", {}).copy()
|
||||||
if instance:
|
if instance:
|
||||||
if type(instance.assigned_object) is Interface:
|
if type(instance.assigned_object) is Interface:
|
||||||
initial['interface'] = instance.assigned_object
|
initial["interface"] = instance.assigned_object
|
||||||
initial['device'] = 'device'
|
initial["device"] = "device"
|
||||||
elif type(instance.assigned_object) is VMInterface:
|
elif type(instance.assigned_object) is VMInterface:
|
||||||
initial['vminterface'] = instance.assigned_object
|
initial["vminterface"] = instance.assigned_object
|
||||||
initial['virtual_machine'] = 'virtual_machine'
|
initial["virtual_machine"] = "virtual_machine"
|
||||||
kwargs['initial'] = initial
|
kwargs["initial"] = initial
|
||||||
|
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = ACLInterfaceAssignment
|
model = ACLInterfaceAssignment
|
||||||
fields = (
|
fields = (
|
||||||
'access_list', 'direction', 'device', 'interface', 'virtual_machine',
|
"access_list",
|
||||||
'vminterface', 'comments', 'tags',
|
"direction",
|
||||||
|
"device",
|
||||||
|
"interface",
|
||||||
|
"virtual_machine",
|
||||||
|
"vminterface",
|
||||||
|
"comments",
|
||||||
|
"tags",
|
||||||
)
|
)
|
||||||
help_texts = {
|
help_texts = {
|
||||||
'direction': mark_safe('<b>*Note:</b> CANNOT assign 2 ACLs to the same interface & direction.'),
|
"direction": mark_safe(
|
||||||
|
"<b>*Note:</b> CANNOT assign 2 ACLs to the same interface & direction."
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
@ -255,47 +320,81 @@ class ACLInterfaceAssignmentForm(NetBoxModelForm):
|
|||||||
"""
|
"""
|
||||||
cleaned_data = super().clean()
|
cleaned_data = super().clean()
|
||||||
error_message = {}
|
error_message = {}
|
||||||
access_list = cleaned_data.get('access_list')
|
access_list = cleaned_data.get("access_list")
|
||||||
direction = cleaned_data.get('direction')
|
direction = cleaned_data.get("direction")
|
||||||
interface = cleaned_data.get('interface')
|
interface = cleaned_data.get("interface")
|
||||||
vminterface = cleaned_data.get('vminterface')
|
vminterface = cleaned_data.get("vminterface")
|
||||||
assigned_object = cleaned_data.get('assigned_object')
|
assigned_object = cleaned_data.get("assigned_object")
|
||||||
if interface:
|
if interface:
|
||||||
assigned_object = interface
|
assigned_object = interface
|
||||||
assigned_object_type = 'interface'
|
assigned_object_type = "interface"
|
||||||
host_type = 'device'
|
host_type = "device"
|
||||||
host = Interface.objects.get(pk=assigned_object.pk).device
|
host = Interface.objects.get(pk=assigned_object.pk).device
|
||||||
elif vminterface:
|
elif vminterface:
|
||||||
assigned_object = vminterface
|
assigned_object = vminterface
|
||||||
assigned_object_type = 'vminterface'
|
assigned_object_type = "vminterface"
|
||||||
host_type = 'virtual_machine'
|
host_type = "virtual_machine"
|
||||||
host = VMInterface.objects.get(pk=assigned_object.pk).virtual_machine
|
host = VMInterface.objects.get(pk=assigned_object.pk).virtual_machine
|
||||||
if interface or vminterface:
|
if interface or vminterface:
|
||||||
assigned_object_id = VMInterface.objects.get(pk=assigned_object.pk).pk
|
assigned_object_id = VMInterface.objects.get(pk=assigned_object.pk).pk
|
||||||
assigned_object_type_id = ContentType.objects.get_for_model(assigned_object).pk
|
assigned_object_type_id = ContentType.objects.get_for_model(
|
||||||
|
assigned_object
|
||||||
|
).pk
|
||||||
access_list_host = AccessList.objects.get(pk=access_list.pk).assigned_object
|
access_list_host = AccessList.objects.get(pk=access_list.pk).assigned_object
|
||||||
|
|
||||||
# Check if both interface and vminterface are set.
|
# Check if both interface and vminterface are set.
|
||||||
if interface and vminterface:
|
if interface and vminterface:
|
||||||
error_too_many_interfaces = 'Access Lists must be assigned to one type of interface at a time (VM interface or physical interface)'
|
error_too_many_interfaces = "Access Lists must be assigned to one type of interface at a time (VM interface or physical interface)"
|
||||||
error_too_many_hosts = 'Access Lists must be assigned to one type of device at a time (VM or physical device).'
|
error_too_many_hosts = "Access Lists must be assigned to one type of device at a time (VM or physical device)."
|
||||||
error_message |= {'device': [error_too_many_hosts], 'interface': [error_too_many_interfaces], 'virtual_machine': [error_too_many_hosts], 'vminterface': [error_too_many_interfaces]}
|
error_message |= {
|
||||||
|
"device": [error_too_many_hosts],
|
||||||
|
"interface": [error_too_many_interfaces],
|
||||||
|
"virtual_machine": [error_too_many_hosts],
|
||||||
|
"vminterface": [error_too_many_interfaces],
|
||||||
|
}
|
||||||
# Check if neither interface or vminterface are set.
|
# Check if neither interface or vminterface are set.
|
||||||
elif not (interface or vminterface):
|
elif not (interface or vminterface):
|
||||||
error_no_interface = 'An Access List assignment but specify an Interface or VM Interface.'
|
error_no_interface = (
|
||||||
error_message |= {'interface': [error_no_interface], 'vminterface': [error_no_interface]}
|
"An Access List assignment but specify an Interface or VM Interface."
|
||||||
|
)
|
||||||
|
error_message |= {
|
||||||
|
"interface": [error_no_interface],
|
||||||
|
"vminterface": [error_no_interface],
|
||||||
|
}
|
||||||
# Check that an interface's parent device/virtual_machine is assigned to the Access List.
|
# Check that an interface's parent device/virtual_machine is assigned to the Access List.
|
||||||
elif access_list_host != host:
|
elif access_list_host != host:
|
||||||
error_acl_not_assigned_to_host = 'Access List not present on selected host.'
|
error_acl_not_assigned_to_host = "Access List not present on selected host."
|
||||||
error_message |= {'access_list': [error_acl_not_assigned_to_host], assigned_object_type: [error_acl_not_assigned_to_host], host_type: [error_acl_not_assigned_to_host]}
|
error_message |= {
|
||||||
|
"access_list": [error_acl_not_assigned_to_host],
|
||||||
|
assigned_object_type: [error_acl_not_assigned_to_host],
|
||||||
|
host_type: [error_acl_not_assigned_to_host],
|
||||||
|
}
|
||||||
# Check for duplicate entry.
|
# Check for duplicate entry.
|
||||||
elif ACLInterfaceAssignment.objects.filter(access_list=access_list, assigned_object_id=assigned_object_id, assigned_object_type=assigned_object_type_id, direction=direction).exists():
|
elif ACLInterfaceAssignment.objects.filter(
|
||||||
error_duplicate_entry = 'An ACL with this name is already associated to this interface & direction.'
|
access_list=access_list,
|
||||||
error_message |= {'access_list': [error_duplicate_entry], 'direction': [error_duplicate_entry], assigned_object_type: [error_duplicate_entry]}
|
assigned_object_id=assigned_object_id,
|
||||||
|
assigned_object_type=assigned_object_type_id,
|
||||||
|
direction=direction,
|
||||||
|
).exists():
|
||||||
|
error_duplicate_entry = "An ACL with this name is already associated to this interface & direction."
|
||||||
|
error_message |= {
|
||||||
|
"access_list": [error_duplicate_entry],
|
||||||
|
"direction": [error_duplicate_entry],
|
||||||
|
assigned_object_type: [error_duplicate_entry],
|
||||||
|
}
|
||||||
# Check that the interface does not have an existing ACL applied in the direction already.
|
# Check that the interface does not have an existing ACL applied in the direction already.
|
||||||
elif ACLInterfaceAssignment.objects.filter(assigned_object_id=assigned_object_id, assigned_object_type=assigned_object_type_id, direction=direction).exists():
|
elif ACLInterfaceAssignment.objects.filter(
|
||||||
error_interface_already_assigned = 'Interfaces can only have 1 Access List assigned in each direction.'
|
assigned_object_id=assigned_object_id,
|
||||||
error_message |= {'direction': [error_interface_already_assigned], assigned_object_type: [error_interface_already_assigned]}
|
assigned_object_type=assigned_object_type_id,
|
||||||
|
direction=direction,
|
||||||
|
).exists():
|
||||||
|
error_interface_already_assigned = (
|
||||||
|
"Interfaces can only have 1 Access List assigned in each direction."
|
||||||
|
)
|
||||||
|
error_message |= {
|
||||||
|
"direction": [error_interface_already_assigned],
|
||||||
|
assigned_object_type: [error_interface_already_assigned],
|
||||||
|
}
|
||||||
|
|
||||||
if error_message:
|
if error_message:
|
||||||
raise forms.ValidationError(error_message)
|
raise forms.ValidationError(error_message)
|
||||||
@ -303,7 +402,9 @@ class ACLInterfaceAssignmentForm(NetBoxModelForm):
|
|||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
# Set assigned object
|
# Set assigned object
|
||||||
self.instance.assigned_object = self.cleaned_data.get('interface') or self.cleaned_data.get('vminterface')
|
self.instance.assigned_object = self.cleaned_data.get(
|
||||||
|
"interface"
|
||||||
|
) or self.cleaned_data.get("vminterface")
|
||||||
|
|
||||||
return super().save(*args, **kwargs)
|
return super().save(*args, **kwargs)
|
||||||
|
|
||||||
@ -314,40 +415,50 @@ class ACLStandardRuleForm(NetBoxModelForm):
|
|||||||
Requires an access_list, an index, and ACL rule type.
|
Requires an access_list, an index, and ACL rule type.
|
||||||
See the clean function for logic on other field requirements.
|
See the clean function for logic on other field requirements.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
access_list = DynamicModelChoiceField(
|
access_list = DynamicModelChoiceField(
|
||||||
queryset=AccessList.objects.all(),
|
queryset=AccessList.objects.all(),
|
||||||
query_params={
|
query_params={
|
||||||
'type': 'standard'
|
"type": "standard",
|
||||||
},
|
},
|
||||||
help_text=mark_safe('<b>*Note:</b> This field will only display Standard ACLs.'),
|
help_text=mark_safe(
|
||||||
label='Access List',
|
"<b>*Note:</b> This field will only display Standard ACLs."
|
||||||
|
),
|
||||||
|
label="Access List",
|
||||||
)
|
)
|
||||||
source_prefix = DynamicModelChoiceField(
|
source_prefix = DynamicModelChoiceField(
|
||||||
queryset=Prefix.objects.all(),
|
queryset=Prefix.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
help_text=help_text_acl_rule_logic,
|
help_text=help_text_acl_rule_logic,
|
||||||
label='Source Prefix',
|
label="Source Prefix",
|
||||||
)
|
)
|
||||||
tags = DynamicModelMultipleChoiceField(
|
tags = DynamicModelMultipleChoiceField(
|
||||||
queryset=Tag.objects.all(),
|
queryset=Tag.objects.all(),
|
||||||
required=False
|
required=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
fieldsets = (
|
fieldsets = (
|
||||||
('Access List Details', ('access_list', 'description', 'tags')),
|
("Access List Details", ("access_list", "description", "tags")),
|
||||||
('Rule Definition', ('index', 'action', 'remark', 'source_prefix')),
|
("Rule Definition", ("index", "action", "remark", "source_prefix")),
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = ACLStandardRule
|
model = ACLStandardRule
|
||||||
fields = (
|
fields = (
|
||||||
'access_list', 'index', 'action', 'remark', 'source_prefix',
|
"access_list",
|
||||||
'tags', 'description'
|
"index",
|
||||||
|
"action",
|
||||||
|
"remark",
|
||||||
|
"source_prefix",
|
||||||
|
"tags",
|
||||||
|
"description",
|
||||||
)
|
)
|
||||||
help_texts = {
|
help_texts = {
|
||||||
'index': help_text_acl_rule_index,
|
"index": help_text_acl_rule_index,
|
||||||
'action': help_text_acl_action,
|
"action": help_text_acl_action,
|
||||||
'remark': mark_safe('<b>*Note:</b> CANNOT be set if source prefix OR action is set.'),
|
"remark": mark_safe(
|
||||||
|
"<b>*Note:</b> CANNOT be set if source prefix OR action is set."
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
@ -362,16 +473,18 @@ class ACLStandardRuleForm(NetBoxModelForm):
|
|||||||
|
|
||||||
# No need to check for unique_together since there is no usage of GFK
|
# No need to check for unique_together since there is no usage of GFK
|
||||||
|
|
||||||
if cleaned_data.get('action') == 'remark':
|
if cleaned_data.get("action") == "remark":
|
||||||
# Check if action set to remark, but no remark set.
|
# Check if action set to remark, but no remark set.
|
||||||
if not cleaned_data.get('remark'):
|
if not cleaned_data.get("remark"):
|
||||||
error_message['remark'] = [error_message_no_remark]
|
error_message["remark"] = [error_message_no_remark]
|
||||||
# Check if action set to remark, but source_prefix set.
|
# Check if action set to remark, but source_prefix set.
|
||||||
if cleaned_data.get('source_prefix'):
|
if cleaned_data.get("source_prefix"):
|
||||||
error_message['source_prefix'] = [error_message_action_remark_source_prefix_set]
|
error_message["source_prefix"] = [
|
||||||
|
error_message_action_remark_source_prefix_set
|
||||||
|
]
|
||||||
# Check remark set, but action not set to remark.
|
# Check remark set, but action not set to remark.
|
||||||
elif cleaned_data.get('remark'):
|
elif cleaned_data.get("remark"):
|
||||||
error_message['remark'] = [error_message_remark_without_action_remark]
|
error_message["remark"] = [error_message_remark_without_action_remark]
|
||||||
|
|
||||||
if error_message:
|
if error_message:
|
||||||
raise forms.ValidationError(error_message)
|
raise forms.ValidationError(error_message)
|
||||||
@ -384,49 +497,74 @@ class ACLExtendedRuleForm(NetBoxModelForm):
|
|||||||
Requires an access_list, an index, and ACL rule type.
|
Requires an access_list, an index, and ACL rule type.
|
||||||
See the clean function for logic on other field requirements.
|
See the clean function for logic on other field requirements.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
access_list = DynamicModelChoiceField(
|
access_list = DynamicModelChoiceField(
|
||||||
queryset=AccessList.objects.all(),
|
queryset=AccessList.objects.all(),
|
||||||
query_params={
|
query_params={
|
||||||
'type': 'extended'
|
"type": "extended",
|
||||||
},
|
},
|
||||||
help_text=mark_safe('<b>*Note:</b> This field will only display Extended ACLs.'),
|
help_text=mark_safe(
|
||||||
label='Access List',
|
"<b>*Note:</b> This field will only display Extended ACLs."
|
||||||
|
),
|
||||||
|
label="Access List",
|
||||||
)
|
)
|
||||||
tags = DynamicModelMultipleChoiceField(
|
tags = DynamicModelMultipleChoiceField(
|
||||||
queryset=Tag.objects.all(),
|
queryset=Tag.objects.all(),
|
||||||
required=False
|
required=False,
|
||||||
)
|
)
|
||||||
source_prefix = DynamicModelChoiceField(
|
source_prefix = DynamicModelChoiceField(
|
||||||
queryset=Prefix.objects.all(),
|
queryset=Prefix.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
help_text=help_text_acl_rule_logic,
|
help_text=help_text_acl_rule_logic,
|
||||||
label='Source Prefix',
|
label="Source Prefix",
|
||||||
)
|
)
|
||||||
destination_prefix = DynamicModelChoiceField(
|
destination_prefix = DynamicModelChoiceField(
|
||||||
queryset=Prefix.objects.all(),
|
queryset=Prefix.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
help_text=help_text_acl_rule_logic,
|
help_text=help_text_acl_rule_logic,
|
||||||
label='Destination Prefix',
|
label="Destination Prefix",
|
||||||
)
|
)
|
||||||
fieldsets = (
|
fieldsets = (
|
||||||
('Access List Details', ('access_list', 'description', 'tags')),
|
("Access List Details", ("access_list", "description", "tags")),
|
||||||
('Rule Definition', ('index', 'action', 'remark', 'source_prefix', 'source_ports', 'destination_prefix', 'destination_ports', 'protocol',)),
|
(
|
||||||
|
"Rule Definition",
|
||||||
|
(
|
||||||
|
"index",
|
||||||
|
"action",
|
||||||
|
"remark",
|
||||||
|
"source_prefix",
|
||||||
|
"source_ports",
|
||||||
|
"destination_prefix",
|
||||||
|
"destination_ports",
|
||||||
|
"protocol",
|
||||||
|
),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = ACLExtendedRule
|
model = ACLExtendedRule
|
||||||
fields = (
|
fields = (
|
||||||
'access_list', 'index', 'action', 'remark', 'source_prefix',
|
"access_list",
|
||||||
'source_ports', 'destination_prefix', 'destination_ports', 'protocol',
|
"index",
|
||||||
'tags', 'description'
|
"action",
|
||||||
|
"remark",
|
||||||
|
"source_prefix",
|
||||||
|
"source_ports",
|
||||||
|
"destination_prefix",
|
||||||
|
"destination_ports",
|
||||||
|
"protocol",
|
||||||
|
"tags",
|
||||||
|
"description",
|
||||||
)
|
)
|
||||||
help_texts = {
|
help_texts = {
|
||||||
'action': help_text_acl_action,
|
"action": help_text_acl_action,
|
||||||
'destination_ports': help_text_acl_rule_logic,
|
"destination_ports": help_text_acl_rule_logic,
|
||||||
'index': help_text_acl_rule_index,
|
"index": help_text_acl_rule_index,
|
||||||
'protocol': help_text_acl_rule_logic,
|
"protocol": help_text_acl_rule_logic,
|
||||||
'remark': mark_safe('<b>*Note:</b> CANNOT be set if action is not set to remark.'),
|
"remark": mark_safe(
|
||||||
'source_ports': help_text_acl_rule_logic,
|
"<b>*Note:</b> CANNOT be set if action is not set to remark."
|
||||||
|
),
|
||||||
|
"source_ports": help_text_acl_rule_logic,
|
||||||
}
|
}
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
@ -446,28 +584,38 @@ class ACLExtendedRuleForm(NetBoxModelForm):
|
|||||||
|
|
||||||
# No need to check for unique_together since there is no usage of GFK
|
# No need to check for unique_together since there is no usage of GFK
|
||||||
|
|
||||||
if cleaned_data.get('action') == 'remark':
|
if cleaned_data.get("action") == "remark":
|
||||||
# Check if action set to remark, but no remark set.
|
# Check if action set to remark, but no remark set.
|
||||||
if not cleaned_data.get('remark'):
|
if not cleaned_data.get("remark"):
|
||||||
error_message['remark'] = [error_message_no_remark]
|
error_message["remark"] = [error_message_no_remark]
|
||||||
# Check if action set to remark, but source_prefix set.
|
# Check if action set to remark, but source_prefix set.
|
||||||
if cleaned_data.get('source_prefix'):
|
if cleaned_data.get("source_prefix"):
|
||||||
error_message['source_prefix'] = [error_message_action_remark_source_prefix_set]
|
error_message["source_prefix"] = [
|
||||||
|
error_message_action_remark_source_prefix_set
|
||||||
|
]
|
||||||
# Check if action set to remark, but source_ports set.
|
# Check if action set to remark, but source_ports set.
|
||||||
if cleaned_data.get('source_ports'):
|
if cleaned_data.get("source_ports"):
|
||||||
error_message['source_ports'] = ['Action is set to remark, Source Ports CANNOT be set.']
|
error_message["source_ports"] = [
|
||||||
|
"Action is set to remark, Source Ports CANNOT be set."
|
||||||
|
]
|
||||||
# Check if action set to remark, but destination_prefix set.
|
# Check if action set to remark, but destination_prefix set.
|
||||||
if cleaned_data.get('destination_prefix'):
|
if cleaned_data.get("destination_prefix"):
|
||||||
error_message['destination_prefix'] = ['Action is set to remark, Destination Prefix CANNOT be set.']
|
error_message["destination_prefix"] = [
|
||||||
|
"Action is set to remark, Destination Prefix CANNOT be set."
|
||||||
|
]
|
||||||
# Check if action set to remark, but destination_ports set.
|
# Check if action set to remark, but destination_ports set.
|
||||||
if cleaned_data.get('destination_ports'):
|
if cleaned_data.get("destination_ports"):
|
||||||
error_message['destination_ports'] = ['Action is set to remark, Destination Ports CANNOT be set.']
|
error_message["destination_ports"] = [
|
||||||
|
"Action is set to remark, Destination Ports CANNOT be set."
|
||||||
|
]
|
||||||
# Check if action set to remark, but protocol set.
|
# Check if action set to remark, but protocol set.
|
||||||
if cleaned_data.get('protocol'):
|
if cleaned_data.get("protocol"):
|
||||||
error_message['protocol'] = ['Action is set to remark, Protocol CANNOT be set.']
|
error_message["protocol"] = [
|
||||||
|
"Action is set to remark, Protocol CANNOT be set."
|
||||||
|
]
|
||||||
# Check if action not set to remark, but remark set.
|
# Check if action not set to remark, but remark set.
|
||||||
elif cleaned_data.get('remark'):
|
elif cleaned_data.get("remark"):
|
||||||
error_message['remark'] = [error_message_remark_without_action_remark]
|
error_message["remark"] = [error_message_remark_without_action_remark]
|
||||||
|
|
||||||
if error_message:
|
if error_message:
|
||||||
raise forms.ValidationError(error_message)
|
raise forms.ValidationError(error_message)
|
||||||
|
|||||||
@ -9,10 +9,10 @@ from netbox.graphql.types import NetBoxObjectType
|
|||||||
from . import filtersets, models
|
from . import filtersets, models
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'AccessListType',
|
"AccessListType",
|
||||||
'ACLInterfaceAssignmentType',
|
"ACLInterfaceAssignmentType",
|
||||||
'ACLExtendedRuleType',
|
"ACLExtendedRuleType",
|
||||||
'ACLStandardRuleType',
|
"ACLStandardRuleType",
|
||||||
)
|
)
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -29,8 +29,9 @@ class AccessListType(NetBoxObjectType):
|
|||||||
"""
|
"""
|
||||||
Associates the filterset, fields, and model for the django model AccessList.
|
Associates the filterset, fields, and model for the django model AccessList.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
model = models.AccessList
|
model = models.AccessList
|
||||||
fields = '__all__'
|
fields = "__all__"
|
||||||
filterset_class = filtersets.AccessListFilterSet
|
filterset_class = filtersets.AccessListFilterSet
|
||||||
|
|
||||||
|
|
||||||
@ -43,8 +44,9 @@ class ACLInterfaceAssignmentType(NetBoxObjectType):
|
|||||||
"""
|
"""
|
||||||
Associates the filterset, fields, and model for the django model ACLInterfaceAssignment.
|
Associates the filterset, fields, and model for the django model ACLInterfaceAssignment.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
model = models.ACLInterfaceAssignment
|
model = models.ACLInterfaceAssignment
|
||||||
fields = '__all__'
|
fields = "__all__"
|
||||||
filterset_class = filtersets.ACLInterfaceAssignmentFilterSet
|
filterset_class = filtersets.ACLInterfaceAssignmentFilterSet
|
||||||
|
|
||||||
|
|
||||||
@ -57,8 +59,9 @@ class ACLExtendedRuleType(NetBoxObjectType):
|
|||||||
"""
|
"""
|
||||||
Associates the filterset, fields, and model for the django model ACLExtendedRule.
|
Associates the filterset, fields, and model for the django model ACLExtendedRule.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
model = models.ACLExtendedRule
|
model = models.ACLExtendedRule
|
||||||
fields = '__all__'
|
fields = "__all__"
|
||||||
filterset_class = filtersets.ACLExtendedRuleFilterSet
|
filterset_class = filtersets.ACLExtendedRuleFilterSet
|
||||||
|
|
||||||
|
|
||||||
@ -71,10 +74,12 @@ class ACLStandardRuleType(NetBoxObjectType):
|
|||||||
"""
|
"""
|
||||||
Associates the filterset, fields, and model for the django model ACLStandardRule.
|
Associates the filterset, fields, and model for the django model ACLStandardRule.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
model = models.ACLStandardRule
|
model = models.ACLStandardRule
|
||||||
fields = '__all__'
|
fields = "__all__"
|
||||||
filterset_class = filtersets.ACLStandardRuleFilterSet
|
filterset_class = filtersets.ACLStandardRuleFilterSet
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Queries
|
# Queries
|
||||||
#
|
#
|
||||||
@ -94,4 +99,5 @@ class Query(ObjectType):
|
|||||||
acl_standard_rule = ObjectField(ACLStandardRuleType)
|
acl_standard_rule = ObjectField(ACLStandardRuleType)
|
||||||
acl_standard_rule_list = ObjectListField(ACLStandardRuleType)
|
acl_standard_rule_list = ObjectListField(ACLStandardRuleType)
|
||||||
|
|
||||||
|
|
||||||
schema = Query
|
schema = Query
|
||||||
|
|||||||
@ -8,9 +8,8 @@ import django.db.models.deletion
|
|||||||
import taggit.managers
|
import taggit.managers
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
__all__ = (
|
__all__ = ("Migration",)
|
||||||
'Migration',
|
|
||||||
)
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
"""
|
"""
|
||||||
@ -20,100 +19,258 @@ class Migration(migrations.Migration):
|
|||||||
initial = True
|
initial = True
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
('extras', '0072_created_datetimefield'),
|
("extras", "0072_created_datetimefield"),
|
||||||
('ipam', '0057_created_datetimefield'),
|
("ipam", "0057_created_datetimefield"),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='AccessList',
|
name="AccessList",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
|
(
|
||||||
('created', models.DateTimeField(auto_now_add=True, null=True)),
|
"id",
|
||||||
('last_updated', models.DateTimeField(auto_now=True, null=True)),
|
models.BigAutoField(
|
||||||
('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
|
auto_created=True, primary_key=True, serialize=False
|
||||||
('name', models.CharField(max_length=500)),
|
),
|
||||||
('assigned_object_id', models.PositiveIntegerField()),
|
),
|
||||||
('assigned_object_type', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='contenttypes.contenttype')),
|
("created", models.DateTimeField(auto_now_add=True, null=True)),
|
||||||
('type', models.CharField(max_length=100)),
|
("last_updated", models.DateTimeField(auto_now=True, null=True)),
|
||||||
('default_action', models.CharField(default='deny', max_length=30)),
|
(
|
||||||
('comments', models.TextField(blank=True)),
|
"custom_field_data",
|
||||||
('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')),
|
models.JSONField(
|
||||||
|
blank=True,
|
||||||
|
default=dict,
|
||||||
|
encoder=django.core.serializers.json.DjangoJSONEncoder,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("name", models.CharField(max_length=500)),
|
||||||
|
("assigned_object_id", models.PositiveIntegerField()),
|
||||||
|
(
|
||||||
|
"assigned_object_type",
|
||||||
|
models.ForeignKey(
|
||||||
|
on_delete=django.db.models.deletion.PROTECT,
|
||||||
|
to="contenttypes.contenttype",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("type", models.CharField(max_length=100)),
|
||||||
|
("default_action", models.CharField(default="deny", max_length=30)),
|
||||||
|
("comments", models.TextField(blank=True)),
|
||||||
|
(
|
||||||
|
"tags",
|
||||||
|
taggit.managers.TaggableManager(
|
||||||
|
through="extras.TaggedItem", to="extras.Tag"
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
'ordering': ('name', 'device'),
|
"ordering": ("name", "device"),
|
||||||
'unique_together': {('assigned_object_type', 'assigned_object_id', 'name')},
|
"unique_together": {
|
||||||
'verbose_name': 'Access List',
|
("assigned_object_type", "assigned_object_id", "name")
|
||||||
|
},
|
||||||
|
"verbose_name": "Access List",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='ACLInterfaceAssignment',
|
name="ACLInterfaceAssignment",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
|
(
|
||||||
('created', models.DateTimeField(auto_now_add=True, null=True)),
|
"id",
|
||||||
('last_updated', models.DateTimeField(auto_now=True, null=True)),
|
models.BigAutoField(
|
||||||
('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
|
auto_created=True, primary_key=True, serialize=False
|
||||||
('access_list', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='aclinterfaceassignment', to='netbox_access_lists.accesslist')),
|
),
|
||||||
('direction', models.CharField(max_length=100)),
|
),
|
||||||
('assigned_object_id', models.PositiveIntegerField()),
|
("created", models.DateTimeField(auto_now_add=True, null=True)),
|
||||||
('assigned_object_type', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='contenttypes.contenttype')),
|
("last_updated", models.DateTimeField(auto_now=True, null=True)),
|
||||||
('comments', models.TextField(blank=True)),
|
(
|
||||||
('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')),
|
"custom_field_data",
|
||||||
|
models.JSONField(
|
||||||
|
blank=True,
|
||||||
|
default=dict,
|
||||||
|
encoder=django.core.serializers.json.DjangoJSONEncoder,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"access_list",
|
||||||
|
models.ForeignKey(
|
||||||
|
on_delete=django.db.models.deletion.PROTECT,
|
||||||
|
related_name="aclinterfaceassignment",
|
||||||
|
to="netbox_access_lists.accesslist",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("direction", models.CharField(max_length=100)),
|
||||||
|
("assigned_object_id", models.PositiveIntegerField()),
|
||||||
|
(
|
||||||
|
"assigned_object_type",
|
||||||
|
models.ForeignKey(
|
||||||
|
on_delete=django.db.models.deletion.PROTECT,
|
||||||
|
to="contenttypes.contenttype",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("comments", models.TextField(blank=True)),
|
||||||
|
(
|
||||||
|
"tags",
|
||||||
|
taggit.managers.TaggableManager(
|
||||||
|
through="extras.TaggedItem", to="extras.Tag"
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
'ordering': ('access_list', 'assigned_object_type', 'assigned_object_id', 'direction'),
|
"ordering": (
|
||||||
'unique_together': {('assigned_object_type', 'assigned_object_id', 'access_list', 'direction')},
|
"access_list",
|
||||||
'verbose_name': 'ACL Interface Assignment',
|
"assigned_object_type",
|
||||||
|
"assigned_object_id",
|
||||||
|
"direction",
|
||||||
|
),
|
||||||
|
"unique_together": {
|
||||||
|
(
|
||||||
|
"assigned_object_type",
|
||||||
|
"assigned_object_id",
|
||||||
|
"access_list",
|
||||||
|
"direction",
|
||||||
|
)
|
||||||
|
},
|
||||||
|
"verbose_name": "ACL Interface Assignment",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='ACLStandardRule',
|
name="ACLStandardRule",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
|
(
|
||||||
('created', models.DateTimeField(auto_now_add=True, null=True)),
|
"id",
|
||||||
('last_updated', models.DateTimeField(auto_now=True, null=True)),
|
models.BigAutoField(
|
||||||
('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
|
auto_created=True, primary_key=True, serialize=False
|
||||||
('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')),
|
),
|
||||||
('access_list', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='aclstandardrules', to='netbox_access_lists.accesslist')),
|
),
|
||||||
('index', models.PositiveIntegerField()),
|
("created", models.DateTimeField(auto_now_add=True, null=True)),
|
||||||
('description', models.CharField(blank=True, max_length=500)),
|
("last_updated", models.DateTimeField(auto_now=True, null=True)),
|
||||||
('action', models.CharField(max_length=30)),
|
(
|
||||||
('remark', models.CharField(blank=True, null=True, max_length=500)),
|
"custom_field_data",
|
||||||
('source_prefix', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='ipam.prefix')),
|
models.JSONField(
|
||||||
|
blank=True,
|
||||||
|
default=dict,
|
||||||
|
encoder=django.core.serializers.json.DjangoJSONEncoder,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"tags",
|
||||||
|
taggit.managers.TaggableManager(
|
||||||
|
through="extras.TaggedItem", to="extras.Tag"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"access_list",
|
||||||
|
models.ForeignKey(
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
related_name="aclstandardrules",
|
||||||
|
to="netbox_access_lists.accesslist",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("index", models.PositiveIntegerField()),
|
||||||
|
("description", models.CharField(blank=True, max_length=500)),
|
||||||
|
("action", models.CharField(max_length=30)),
|
||||||
|
("remark", models.CharField(blank=True, null=True, max_length=500)),
|
||||||
|
(
|
||||||
|
"source_prefix",
|
||||||
|
models.ForeignKey(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.PROTECT,
|
||||||
|
related_name="+",
|
||||||
|
to="ipam.prefix",
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
'ordering': ('access_list', 'index'),
|
"ordering": ("access_list", "index"),
|
||||||
'unique_together': {('access_list', 'index')},
|
"unique_together": {("access_list", "index")},
|
||||||
'verbose_name': 'ACL Standard Rule',
|
"verbose_name": "ACL Standard Rule",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='ACLExtendedRule',
|
name="ACLExtendedRule",
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
|
(
|
||||||
('created', models.DateTimeField(auto_now_add=True, null=True)),
|
"id",
|
||||||
('last_updated', models.DateTimeField(auto_now=True, null=True)),
|
models.BigAutoField(
|
||||||
('custom_field_data', models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder)),
|
auto_created=True, primary_key=True, serialize=False
|
||||||
('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')),
|
),
|
||||||
('access_list', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='aclstandardrules', to='netbox_access_lists.accesslist')),
|
),
|
||||||
('index', models.PositiveIntegerField()),
|
("created", models.DateTimeField(auto_now_add=True, null=True)),
|
||||||
('description', models.CharField(blank=True, max_length=500)),
|
("last_updated", models.DateTimeField(auto_now=True, null=True)),
|
||||||
('action', models.CharField(max_length=30)),
|
(
|
||||||
('remark', models.CharField(blank=True, null=True, max_length=500)),
|
"custom_field_data",
|
||||||
('source_prefix', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='ipam.prefix')),
|
models.JSONField(
|
||||||
('source_ports', django.contrib.postgres.fields.ArrayField(base_field=models.PositiveIntegerField(), blank=True, null=True, size=None)),
|
blank=True,
|
||||||
('destination_prefix', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='ipam.prefix')),
|
default=dict,
|
||||||
('destination_ports', django.contrib.postgres.fields.ArrayField(base_field=models.PositiveIntegerField(), blank=True, null=True, size=None)),
|
encoder=django.core.serializers.json.DjangoJSONEncoder,
|
||||||
('protocol', models.CharField(blank=True, max_length=30)),
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"tags",
|
||||||
|
taggit.managers.TaggableManager(
|
||||||
|
through="extras.TaggedItem", to="extras.Tag"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"access_list",
|
||||||
|
models.ForeignKey(
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
related_name="aclstandardrules",
|
||||||
|
to="netbox_access_lists.accesslist",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("index", models.PositiveIntegerField()),
|
||||||
|
("description", models.CharField(blank=True, max_length=500)),
|
||||||
|
("action", models.CharField(max_length=30)),
|
||||||
|
("remark", models.CharField(blank=True, null=True, max_length=500)),
|
||||||
|
(
|
||||||
|
"source_prefix",
|
||||||
|
models.ForeignKey(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.PROTECT,
|
||||||
|
related_name="+",
|
||||||
|
to="ipam.prefix",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"source_ports",
|
||||||
|
django.contrib.postgres.fields.ArrayField(
|
||||||
|
base_field=models.PositiveIntegerField(),
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
size=None,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"destination_prefix",
|
||||||
|
models.ForeignKey(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.PROTECT,
|
||||||
|
related_name="+",
|
||||||
|
to="ipam.prefix",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"destination_ports",
|
||||||
|
django.contrib.postgres.fields.ArrayField(
|
||||||
|
base_field=models.PositiveIntegerField(),
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
size=None,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("protocol", models.CharField(blank=True, max_length=30)),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
'ordering': ('access_list', 'index'),
|
"ordering": ("access_list", "index"),
|
||||||
'unique_together': {('access_list', 'index')},
|
"unique_together": {("access_list", "index")},
|
||||||
'verbose_name': 'ACL Extended Rule',
|
"verbose_name": "ACL Extended Rule",
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
#migrations.AddConstraint(
|
# migrations.AddConstraint(
|
||||||
# model_name='accesslist',
|
# model_name='accesslist',
|
||||||
# constraint=models.UniqueConstraint(fields=('assigned_object_type', 'assigned_object_id'), name='accesslist_assigned_object'),
|
# constraint=models.UniqueConstraint(fields=('assigned_object_type', 'assigned_object_id'), name='accesslist_assigned_object'),
|
||||||
#),
|
# ),
|
||||||
]
|
]
|
||||||
|
|||||||
@ -11,9 +11,9 @@ from ..choices import *
|
|||||||
from .access_lists import AccessList
|
from .access_lists import AccessList
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'ACLRule',
|
"ACLRule",
|
||||||
'ACLStandardRule',
|
"ACLStandardRule",
|
||||||
'ACLExtendedRule',
|
"ACLExtendedRule",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -22,20 +22,21 @@ class ACLRule(NetBoxModel):
|
|||||||
Abstract model for ACL Rules.
|
Abstract model for ACL Rules.
|
||||||
Inherrited by both ACLStandardRule and ACLExtendedRule.
|
Inherrited by both ACLStandardRule and ACLExtendedRule.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
access_list = models.ForeignKey(
|
access_list = models.ForeignKey(
|
||||||
on_delete=models.CASCADE,
|
on_delete=models.CASCADE,
|
||||||
to=AccessList,
|
to=AccessList,
|
||||||
verbose_name='Access List',
|
verbose_name="Access List",
|
||||||
related_name='rules',
|
related_name="rules",
|
||||||
)
|
)
|
||||||
index = models.PositiveIntegerField()
|
index = models.PositiveIntegerField()
|
||||||
remark = models.CharField(
|
remark = models.CharField(
|
||||||
max_length=500,
|
max_length=500,
|
||||||
blank=True
|
blank=True,
|
||||||
)
|
)
|
||||||
description = models.CharField(
|
description = models.CharField(
|
||||||
max_length=500,
|
max_length=500,
|
||||||
blank=True
|
blank=True,
|
||||||
)
|
)
|
||||||
action = models.CharField(
|
action = models.CharField(
|
||||||
choices=ACLRuleActionChoices,
|
choices=ACLRuleActionChoices,
|
||||||
@ -45,13 +46,13 @@ class ACLRule(NetBoxModel):
|
|||||||
blank=True,
|
blank=True,
|
||||||
null=True,
|
null=True,
|
||||||
on_delete=models.PROTECT,
|
on_delete=models.PROTECT,
|
||||||
related_name='+',
|
related_name="+",
|
||||||
to='ipam.Prefix',
|
to="ipam.Prefix",
|
||||||
verbose_name='Source Prefix'
|
verbose_name="Source Prefix",
|
||||||
)
|
)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f'{self.access_list}: Rule {self.index}'
|
return f"{self.access_list}: Rule {self.index}"
|
||||||
|
|
||||||
def get_action_color(self):
|
def get_action_color(self):
|
||||||
return ACLRuleActionChoices.colors.get(self.action)
|
return ACLRuleActionChoices.colors.get(self.action)
|
||||||
@ -63,21 +64,23 @@ class ACLRule(NetBoxModel):
|
|||||||
- ordering
|
- ordering
|
||||||
- unique together
|
- unique together
|
||||||
"""
|
"""
|
||||||
|
|
||||||
abstract = True
|
abstract = True
|
||||||
ordering = ['access_list', 'index']
|
ordering = ["access_list", "index"]
|
||||||
unique_together = ['access_list', 'index']
|
unique_together = ["access_list", "index"]
|
||||||
|
|
||||||
|
|
||||||
class ACLStandardRule(ACLRule):
|
class ACLStandardRule(ACLRule):
|
||||||
"""
|
"""
|
||||||
Inherits ACLRule.
|
Inherits ACLRule.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
access_list = models.ForeignKey(
|
access_list = models.ForeignKey(
|
||||||
on_delete=models.CASCADE,
|
on_delete=models.CASCADE,
|
||||||
to=AccessList,
|
to=AccessList,
|
||||||
verbose_name='Standard Access List',
|
verbose_name="Standard Access List",
|
||||||
limit_choices_to={'type': 'standard'},
|
limit_choices_to={"type": "standard"},
|
||||||
related_name='aclstandardrules',
|
related_name="aclstandardrules",
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
@ -85,7 +88,7 @@ class ACLStandardRule(ACLRule):
|
|||||||
The method is a Django convention; although not strictly required,
|
The method is a Django convention; although not strictly required,
|
||||||
it conveniently returns the absolute URL for any particular object.
|
it conveniently returns the absolute URL for any particular object.
|
||||||
"""
|
"""
|
||||||
return reverse('plugins:netbox_access_lists:aclstandardrule', args=[self.pk])
|
return reverse("plugins:netbox_access_lists:aclstandardrule", args=[self.pk])
|
||||||
|
|
||||||
class Meta(ACLRule.Meta):
|
class Meta(ACLRule.Meta):
|
||||||
"""
|
"""
|
||||||
@ -94,40 +97,43 @@ class ACLStandardRule(ACLRule):
|
|||||||
- verbose name (for displaying in the GUI)
|
- verbose name (for displaying in the GUI)
|
||||||
- verbose name plural (for displaying in the GUI)
|
- verbose name plural (for displaying in the GUI)
|
||||||
"""
|
"""
|
||||||
verbose_name='ACL Standard Rule'
|
|
||||||
verbose_name_plural='ACL Standard Rules'
|
verbose_name = "ACL Standard Rule"
|
||||||
|
verbose_name_plural = "ACL Standard Rules"
|
||||||
|
|
||||||
|
|
||||||
class ACLExtendedRule(ACLRule):
|
class ACLExtendedRule(ACLRule):
|
||||||
"""
|
"""
|
||||||
Inherits ACLRule.
|
Inherits ACLRule.
|
||||||
Add ACLExtendedRule specific fields: source_ports, desintation_prefix, destination_ports, and protocol
|
Add ACLExtendedRule specific fields: source_ports, desintation_prefix, destination_ports, and protocol
|
||||||
"""
|
"""
|
||||||
|
|
||||||
access_list = models.ForeignKey(
|
access_list = models.ForeignKey(
|
||||||
on_delete=models.CASCADE,
|
on_delete=models.CASCADE,
|
||||||
to=AccessList,
|
to=AccessList,
|
||||||
verbose_name='Extended Access List',
|
verbose_name="Extended Access List",
|
||||||
limit_choices_to={'type': 'extended'},
|
limit_choices_to={"type": "extended"},
|
||||||
related_name='aclextendedrules',
|
related_name="aclextendedrules",
|
||||||
)
|
)
|
||||||
source_ports = ArrayField(
|
source_ports = ArrayField(
|
||||||
base_field=models.PositiveIntegerField(),
|
base_field=models.PositiveIntegerField(),
|
||||||
blank=True,
|
blank=True,
|
||||||
null=True,
|
null=True,
|
||||||
verbose_name='Soure Ports'
|
verbose_name="Soure Ports",
|
||||||
)
|
)
|
||||||
destination_prefix = models.ForeignKey(
|
destination_prefix = models.ForeignKey(
|
||||||
blank=True,
|
blank=True,
|
||||||
null=True,
|
null=True,
|
||||||
on_delete=models.PROTECT,
|
on_delete=models.PROTECT,
|
||||||
related_name='+',
|
related_name="+",
|
||||||
to='ipam.Prefix',
|
to="ipam.Prefix",
|
||||||
verbose_name='Destination Prefix'
|
verbose_name="Destination Prefix",
|
||||||
)
|
)
|
||||||
destination_ports = ArrayField(
|
destination_ports = ArrayField(
|
||||||
base_field=models.PositiveIntegerField(),
|
base_field=models.PositiveIntegerField(),
|
||||||
blank=True,
|
blank=True,
|
||||||
null=True,
|
null=True,
|
||||||
verbose_name='Destination Ports'
|
verbose_name="Destination Ports",
|
||||||
)
|
)
|
||||||
protocol = models.CharField(
|
protocol = models.CharField(
|
||||||
blank=True,
|
blank=True,
|
||||||
@ -140,7 +146,7 @@ class ACLExtendedRule(ACLRule):
|
|||||||
The method is a Django convention; although not strictly required,
|
The method is a Django convention; although not strictly required,
|
||||||
it conveniently returns the absolute URL for any particular object.
|
it conveniently returns the absolute URL for any particular object.
|
||||||
"""
|
"""
|
||||||
return reverse('plugins:netbox_access_lists:aclextendedrule', args=[self.pk])
|
return reverse("plugins:netbox_access_lists:aclextendedrule", args=[self.pk])
|
||||||
|
|
||||||
def get_protocol_color(self):
|
def get_protocol_color(self):
|
||||||
return ACLProtocolChoices.colors.get(self.protocol)
|
return ACLProtocolChoices.colors.get(self.protocol)
|
||||||
@ -152,5 +158,6 @@ class ACLExtendedRule(ACLRule):
|
|||||||
- verbose name (for displaying in the GUI)
|
- verbose name (for displaying in the GUI)
|
||||||
- verbose name plural (for displaying in the GUI)
|
- verbose name plural (for displaying in the GUI)
|
||||||
"""
|
"""
|
||||||
verbose_name='ACL Extended Rule'
|
|
||||||
verbose_name_plural='ACL Extended Rules'
|
verbose_name = "ACL Extended Rule"
|
||||||
|
verbose_name_plural = "ACL Extended Rules"
|
||||||
|
|||||||
@ -3,8 +3,7 @@ Define the django models for this plugin.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from dcim.models import Device, Interface, VirtualChassis
|
from dcim.models import Device, Interface, VirtualChassis
|
||||||
from django.contrib.contenttypes.fields import (GenericForeignKey,
|
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
|
||||||
GenericRelation)
|
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.core.validators import RegexValidator
|
from django.core.validators import RegexValidator
|
||||||
from django.db import models
|
from django.db import models
|
||||||
@ -13,54 +12,58 @@ from netbox.models import NetBoxModel
|
|||||||
from virtualization.models import VirtualMachine, VMInterface
|
from virtualization.models import VirtualMachine, VMInterface
|
||||||
|
|
||||||
from ..choices import *
|
from ..choices import *
|
||||||
from ..constants import (ACL_HOST_ASSIGNMENT_MODELS,
|
from ..constants import ACL_HOST_ASSIGNMENT_MODELS, ACL_INTERFACE_ASSIGNMENT_MODELS
|
||||||
ACL_INTERFACE_ASSIGNMENT_MODELS)
|
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'AccessList',
|
"AccessList",
|
||||||
'ACLInterfaceAssignment',
|
"ACLInterfaceAssignment",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
alphanumeric_plus = RegexValidator(r'^[0-9a-zA-Z,-,_]*$', 'Only alphanumeric, hyphens, and underscores characters are allowed.')
|
alphanumeric_plus = RegexValidator(
|
||||||
|
r"^[0-9a-zA-Z,-,_]*$",
|
||||||
|
"Only alphanumeric, hyphens, and underscores characters are allowed.",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class AccessList(NetBoxModel):
|
class AccessList(NetBoxModel):
|
||||||
"""
|
"""
|
||||||
Model defintion for Access Lists.
|
Model defintion for Access Lists.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
name = models.CharField(
|
name = models.CharField(
|
||||||
max_length=500,
|
max_length=500,
|
||||||
validators=[alphanumeric_plus]
|
validators=[alphanumeric_plus],
|
||||||
)
|
)
|
||||||
assigned_object_type = models.ForeignKey(
|
assigned_object_type = models.ForeignKey(
|
||||||
to=ContentType,
|
to=ContentType,
|
||||||
limit_choices_to=ACL_HOST_ASSIGNMENT_MODELS,
|
limit_choices_to=ACL_HOST_ASSIGNMENT_MODELS,
|
||||||
on_delete=models.PROTECT
|
on_delete=models.PROTECT,
|
||||||
)
|
)
|
||||||
assigned_object_id = models.PositiveBigIntegerField()
|
assigned_object_id = models.PositiveBigIntegerField()
|
||||||
assigned_object = GenericForeignKey(
|
assigned_object = GenericForeignKey(
|
||||||
ct_field='assigned_object_type',
|
ct_field="assigned_object_type",
|
||||||
fk_field='assigned_object_id'
|
fk_field="assigned_object_id",
|
||||||
)
|
)
|
||||||
type = models.CharField(
|
type = models.CharField(
|
||||||
max_length=30,
|
max_length=30,
|
||||||
choices=ACLTypeChoices
|
choices=ACLTypeChoices,
|
||||||
)
|
)
|
||||||
default_action = models.CharField(
|
default_action = models.CharField(
|
||||||
default=ACLActionChoices.ACTION_DENY,
|
default=ACLActionChoices.ACTION_DENY,
|
||||||
max_length=30,
|
max_length=30,
|
||||||
choices=ACLActionChoices,
|
choices=ACLActionChoices,
|
||||||
verbose_name='Default Action'
|
verbose_name="Default Action",
|
||||||
)
|
)
|
||||||
comments = models.TextField(
|
comments = models.TextField(
|
||||||
blank=True
|
blank=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = ['assigned_object_type', 'assigned_object_id', 'name']
|
unique_together = ["assigned_object_type", "assigned_object_id", "name"]
|
||||||
ordering = ['assigned_object_type', 'assigned_object_id', 'name']
|
ordering = ["assigned_object_type", "assigned_object_id", "name"]
|
||||||
verbose_name = 'Access List'
|
verbose_name = "Access List"
|
||||||
verbose_name_plural = 'Access Lists'
|
verbose_name_plural = "Access Lists"
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
@ -70,7 +73,7 @@ class AccessList(NetBoxModel):
|
|||||||
The method is a Django convention; although not strictly required,
|
The method is a Django convention; although not strictly required,
|
||||||
it conveniently returns the absolute URL for any particular object.
|
it conveniently returns the absolute URL for any particular object.
|
||||||
"""
|
"""
|
||||||
return reverse('plugins:netbox_access_lists:accesslist', args=[self.pk])
|
return reverse("plugins:netbox_access_lists:accesslist", args=[self.pk])
|
||||||
|
|
||||||
def get_default_action_color(self):
|
def get_default_action_color(self):
|
||||||
return ACLActionChoices.colors.get(self.default_action)
|
return ACLActionChoices.colors.get(self.default_action)
|
||||||
@ -90,38 +93,50 @@ class ACLInterfaceAssignment(NetBoxModel):
|
|||||||
access_list = models.ForeignKey(
|
access_list = models.ForeignKey(
|
||||||
on_delete=models.CASCADE,
|
on_delete=models.CASCADE,
|
||||||
to=AccessList,
|
to=AccessList,
|
||||||
verbose_name='Access List',
|
verbose_name="Access List",
|
||||||
)
|
)
|
||||||
direction = models.CharField(
|
direction = models.CharField(
|
||||||
max_length=30,
|
max_length=30,
|
||||||
choices=ACLAssignmentDirectionChoices
|
choices=ACLAssignmentDirectionChoices,
|
||||||
)
|
)
|
||||||
assigned_object_type = models.ForeignKey(
|
assigned_object_type = models.ForeignKey(
|
||||||
to=ContentType,
|
to=ContentType,
|
||||||
limit_choices_to=ACL_INTERFACE_ASSIGNMENT_MODELS,
|
limit_choices_to=ACL_INTERFACE_ASSIGNMENT_MODELS,
|
||||||
on_delete=models.PROTECT
|
on_delete=models.PROTECT,
|
||||||
)
|
)
|
||||||
assigned_object_id = models.PositiveBigIntegerField()
|
assigned_object_id = models.PositiveBigIntegerField()
|
||||||
assigned_object = GenericForeignKey(
|
assigned_object = GenericForeignKey(
|
||||||
ct_field='assigned_object_type',
|
ct_field="assigned_object_type",
|
||||||
fk_field='assigned_object_id'
|
fk_field="assigned_object_id",
|
||||||
)
|
)
|
||||||
comments = models.TextField(
|
comments = models.TextField(
|
||||||
blank=True
|
blank=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = ['assigned_object_type', 'assigned_object_id', 'access_list', 'direction']
|
unique_together = [
|
||||||
ordering = ['assigned_object_type', 'assigned_object_id', 'access_list', 'direction']
|
"assigned_object_type",
|
||||||
verbose_name = 'ACL Interface Assignment'
|
"assigned_object_id",
|
||||||
verbose_name_plural = 'ACL Interface Assignments'
|
"access_list",
|
||||||
|
"direction",
|
||||||
|
]
|
||||||
|
ordering = [
|
||||||
|
"assigned_object_type",
|
||||||
|
"assigned_object_id",
|
||||||
|
"access_list",
|
||||||
|
"direction",
|
||||||
|
]
|
||||||
|
verbose_name = "ACL Interface Assignment"
|
||||||
|
verbose_name_plural = "ACL Interface Assignments"
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
"""
|
"""
|
||||||
The method is a Django convention; although not strictly required,
|
The method is a Django convention; although not strictly required,
|
||||||
it conveniently returns the absolute URL for any particular object.
|
it conveniently returns the absolute URL for any particular object.
|
||||||
"""
|
"""
|
||||||
return reverse('plugins:netbox_access_lists:aclinterfaceassignment', args=[self.pk])
|
return reverse(
|
||||||
|
"plugins:netbox_access_lists:aclinterfaceassignment", args=[self.pk]
|
||||||
|
)
|
||||||
|
|
||||||
def get_direction_color(self):
|
def get_direction_color(self):
|
||||||
return ACLAssignmentDirectionChoices.colors.get(self.direction)
|
return ACLAssignmentDirectionChoices.colors.get(self.direction)
|
||||||
@ -129,35 +144,35 @@ class ACLInterfaceAssignment(NetBoxModel):
|
|||||||
|
|
||||||
GenericRelation(
|
GenericRelation(
|
||||||
to=ACLInterfaceAssignment,
|
to=ACLInterfaceAssignment,
|
||||||
content_type_field='assigned_object_type',
|
content_type_field="assigned_object_type",
|
||||||
object_id_field='assigned_object_id',
|
object_id_field="assigned_object_id",
|
||||||
related_query_name='interface'
|
related_query_name="interface",
|
||||||
).contribute_to_class(Interface, 'accesslistassignments')
|
).contribute_to_class(Interface, "accesslistassignments")
|
||||||
|
|
||||||
GenericRelation(
|
GenericRelation(
|
||||||
to=ACLInterfaceAssignment,
|
to=ACLInterfaceAssignment,
|
||||||
content_type_field='assigned_object_type',
|
content_type_field="assigned_object_type",
|
||||||
object_id_field='assigned_object_id',
|
object_id_field="assigned_object_id",
|
||||||
related_query_name='vminterface'
|
related_query_name="vminterface",
|
||||||
).contribute_to_class(VMInterface, 'accesslistassignments')
|
).contribute_to_class(VMInterface, "accesslistassignments")
|
||||||
|
|
||||||
GenericRelation(
|
GenericRelation(
|
||||||
to=AccessList,
|
to=AccessList,
|
||||||
content_type_field='assigned_object_type',
|
content_type_field="assigned_object_type",
|
||||||
object_id_field='assigned_object_id',
|
object_id_field="assigned_object_id",
|
||||||
related_query_name='device'
|
related_query_name="device",
|
||||||
).contribute_to_class(Device, 'accesslists')
|
).contribute_to_class(Device, "accesslists")
|
||||||
|
|
||||||
GenericRelation(
|
GenericRelation(
|
||||||
to=AccessList,
|
to=AccessList,
|
||||||
content_type_field='assigned_object_type',
|
content_type_field="assigned_object_type",
|
||||||
object_id_field='assigned_object_id',
|
object_id_field="assigned_object_id",
|
||||||
related_query_name='virtual_chassis'
|
related_query_name="virtual_chassis",
|
||||||
).contribute_to_class(VirtualChassis, 'accesslists')
|
).contribute_to_class(VirtualChassis, "accesslists")
|
||||||
|
|
||||||
GenericRelation(
|
GenericRelation(
|
||||||
to=AccessList,
|
to=AccessList,
|
||||||
content_type_field='assigned_object_type',
|
content_type_field="assigned_object_type",
|
||||||
object_id_field='assigned_object_id',
|
object_id_field="assigned_object_id",
|
||||||
related_query_name='virtual_machine'
|
related_query_name="virtual_machine",
|
||||||
).contribute_to_class(VirtualMachine, 'accesslists')
|
).contribute_to_class(VirtualMachine, "accesslists")
|
||||||
|
|||||||
@ -11,38 +11,38 @@ from utilities.choices import ButtonColorChoices
|
|||||||
|
|
||||||
accesslist_buttons = [
|
accesslist_buttons = [
|
||||||
PluginMenuButton(
|
PluginMenuButton(
|
||||||
link='plugins:netbox_access_lists:accesslist_add',
|
link="plugins:netbox_access_lists:accesslist_add",
|
||||||
title='Add',
|
title="Add",
|
||||||
icon_class='mdi mdi-plus-thick',
|
icon_class="mdi mdi-plus-thick",
|
||||||
color=ButtonColorChoices.GREEN
|
color=ButtonColorChoices.GREEN,
|
||||||
)
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
aclstandardrule_butons = [
|
aclstandardrule_butons = [
|
||||||
PluginMenuButton(
|
PluginMenuButton(
|
||||||
link='plugins:netbox_access_lists:aclstandardrule_add',
|
link="plugins:netbox_access_lists:aclstandardrule_add",
|
||||||
title='Add',
|
title="Add",
|
||||||
icon_class='mdi mdi-plus-thick',
|
icon_class="mdi mdi-plus-thick",
|
||||||
color=ButtonColorChoices.GREEN
|
color=ButtonColorChoices.GREEN,
|
||||||
)
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
aclextendedrule_butons = [
|
aclextendedrule_butons = [
|
||||||
PluginMenuButton(
|
PluginMenuButton(
|
||||||
link='plugins:netbox_access_lists:aclextendedrule_add',
|
link="plugins:netbox_access_lists:aclextendedrule_add",
|
||||||
title='Add',
|
title="Add",
|
||||||
icon_class='mdi mdi-plus-thick',
|
icon_class="mdi mdi-plus-thick",
|
||||||
color=ButtonColorChoices.GREEN
|
color=ButtonColorChoices.GREEN,
|
||||||
)
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
accesslistassignment_buttons = [
|
accesslistassignment_buttons = [
|
||||||
PluginMenuButton(
|
PluginMenuButton(
|
||||||
link='plugins:netbox_access_lists:aclinterfaceassignment_add',
|
link="plugins:netbox_access_lists:aclinterfaceassignment_add",
|
||||||
title='Add',
|
title="Add",
|
||||||
icon_class='mdi mdi-plus-thick',
|
icon_class="mdi mdi-plus-thick",
|
||||||
color=ButtonColorChoices.GREEN
|
color=ButtonColorChoices.GREEN,
|
||||||
)
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -51,25 +51,25 @@ accesslistassignment_buttons = [
|
|||||||
|
|
||||||
menu_items = (
|
menu_items = (
|
||||||
PluginMenuItem(
|
PluginMenuItem(
|
||||||
link='plugins:netbox_access_lists:accesslist_list',
|
link="plugins:netbox_access_lists:accesslist_list",
|
||||||
link_text='Access Lists',
|
link_text="Access Lists",
|
||||||
buttons=accesslist_buttons
|
buttons=accesslist_buttons,
|
||||||
),
|
),
|
||||||
# Comment out Standard Access List rule to force creation in the ACL view
|
# Comment out Standard Access List rule to force creation in the ACL view
|
||||||
PluginMenuItem(
|
PluginMenuItem(
|
||||||
link='plugins:netbox_access_lists:aclstandardrule_list',
|
link="plugins:netbox_access_lists:aclstandardrule_list",
|
||||||
link_text='ACL Standard Rules',
|
link_text="ACL Standard Rules",
|
||||||
buttons=aclstandardrule_butons
|
buttons=aclstandardrule_butons,
|
||||||
),
|
),
|
||||||
# Comment out Extended Access List rule to force creation in the ACL view
|
# Comment out Extended Access List rule to force creation in the ACL view
|
||||||
PluginMenuItem(
|
PluginMenuItem(
|
||||||
link='plugins:netbox_access_lists:aclextendedrule_list',
|
link="plugins:netbox_access_lists:aclextendedrule_list",
|
||||||
link_text='ACL Extended Rules',
|
link_text="ACL Extended Rules",
|
||||||
buttons=aclextendedrule_butons
|
buttons=aclextendedrule_butons,
|
||||||
),
|
),
|
||||||
PluginMenuItem(
|
PluginMenuItem(
|
||||||
link='plugins:netbox_access_lists:aclinterfaceassignment_list',
|
link="plugins:netbox_access_lists:aclinterfaceassignment_list",
|
||||||
link_text='ACL Interface Assignments',
|
link_text="ACL Interface Assignments",
|
||||||
buttons=accesslistassignment_buttons
|
buttons=accesslistassignment_buttons,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
@ -3,17 +3,15 @@ Define the object lists / table view for each of the plugin models.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import django_tables2 as tables
|
import django_tables2 as tables
|
||||||
from netbox.tables import (ChoiceFieldColumn, NetBoxTable, TemplateColumn,
|
from netbox.tables import ChoiceFieldColumn, NetBoxTable, TemplateColumn, columns
|
||||||
columns)
|
|
||||||
|
|
||||||
from .models import (AccessList, ACLExtendedRule, ACLInterfaceAssignment,
|
from .models import AccessList, ACLExtendedRule, ACLInterfaceAssignment, ACLStandardRule
|
||||||
ACLStandardRule)
|
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'AccessListTable',
|
"AccessListTable",
|
||||||
'ACLInterfaceAssignmentTable',
|
"ACLInterfaceAssignmentTable",
|
||||||
'ACLStandardRuleTable',
|
"ACLStandardRuleTable",
|
||||||
'ACLExtendedRuleTable',
|
"ACLExtendedRuleTable",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -25,93 +23,144 @@ COL_HOST_ASSIGNMENT = """
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class AccessListTable(NetBoxTable):
|
class AccessListTable(NetBoxTable):
|
||||||
"""
|
"""
|
||||||
Defines the table view for the AccessList model.
|
Defines the table view for the AccessList model.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
pk = columns.ToggleColumn()
|
pk = columns.ToggleColumn()
|
||||||
id = tables.Column(
|
id = tables.Column(
|
||||||
linkify=True
|
linkify=True,
|
||||||
)
|
)
|
||||||
assigned_object = tables.Column(
|
assigned_object = tables.Column(
|
||||||
linkify=True,
|
linkify=True,
|
||||||
orderable=False,
|
orderable=False,
|
||||||
verbose_name='Assigned Host'
|
verbose_name="Assigned Host",
|
||||||
)
|
)
|
||||||
name = tables.Column(
|
name = tables.Column(
|
||||||
linkify=True
|
linkify=True,
|
||||||
)
|
)
|
||||||
device = tables.Column(
|
device = tables.Column(
|
||||||
linkify=True
|
linkify=True,
|
||||||
)
|
)
|
||||||
type = ChoiceFieldColumn()
|
type = ChoiceFieldColumn()
|
||||||
default_action = ChoiceFieldColumn()
|
default_action = ChoiceFieldColumn()
|
||||||
rule_count = tables.Column(
|
rule_count = tables.Column(
|
||||||
verbose_name='Rule Count'
|
verbose_name="Rule Count",
|
||||||
)
|
)
|
||||||
tags = columns.TagColumn(
|
tags = columns.TagColumn(
|
||||||
url_name='plugins:netbox_access_lists:accesslist_list'
|
url_name="plugins:netbox_access_lists:accesslist_list",
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta(NetBoxTable.Meta):
|
class Meta(NetBoxTable.Meta):
|
||||||
model = AccessList
|
model = AccessList
|
||||||
fields = ('pk', 'id', 'name', 'assigned_object', 'type', 'rule_count', 'default_action', 'comments', 'actions', 'tags')
|
fields = (
|
||||||
default_columns = ('name', 'assigned_object', 'type', 'rule_count', 'default_action', 'tags')
|
"pk",
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"assigned_object",
|
||||||
|
"type",
|
||||||
|
"rule_count",
|
||||||
|
"default_action",
|
||||||
|
"comments",
|
||||||
|
"actions",
|
||||||
|
"tags",
|
||||||
|
)
|
||||||
|
default_columns = (
|
||||||
|
"name",
|
||||||
|
"assigned_object",
|
||||||
|
"type",
|
||||||
|
"rule_count",
|
||||||
|
"default_action",
|
||||||
|
"tags",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ACLInterfaceAssignmentTable(NetBoxTable):
|
class ACLInterfaceAssignmentTable(NetBoxTable):
|
||||||
"""
|
"""
|
||||||
Defines the table view for the AccessList model.
|
Defines the table view for the AccessList model.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
pk = columns.ToggleColumn()
|
pk = columns.ToggleColumn()
|
||||||
id = tables.Column(
|
id = tables.Column(
|
||||||
linkify=True
|
linkify=True,
|
||||||
)
|
)
|
||||||
access_list = tables.Column(
|
access_list = tables.Column(
|
||||||
linkify=True
|
linkify=True,
|
||||||
)
|
)
|
||||||
direction = ChoiceFieldColumn()
|
direction = ChoiceFieldColumn()
|
||||||
host = tables.TemplateColumn(
|
host = tables.TemplateColumn(
|
||||||
template_code=COL_HOST_ASSIGNMENT
|
template_code=COL_HOST_ASSIGNMENT,
|
||||||
|
|
||||||
)
|
)
|
||||||
assigned_object = tables.Column(
|
assigned_object = tables.Column(
|
||||||
linkify=True,
|
linkify=True,
|
||||||
orderable=False,
|
orderable=False,
|
||||||
verbose_name='Assigned Interface'
|
verbose_name="Assigned Interface",
|
||||||
)
|
)
|
||||||
tags = columns.TagColumn(
|
tags = columns.TagColumn(
|
||||||
url_name='plugins:netbox_access_lists:aclinterfaceassignment_list'
|
url_name="plugins:netbox_access_lists:aclinterfaceassignment_list",
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta(NetBoxTable.Meta):
|
class Meta(NetBoxTable.Meta):
|
||||||
model = ACLInterfaceAssignment
|
model = ACLInterfaceAssignment
|
||||||
fields = ('pk', 'id', 'access_list', 'direction', 'host', 'assigned_object', 'tags')
|
fields = (
|
||||||
default_columns = ('id', 'access_list', 'direction', 'host', 'assigned_object', 'tags')
|
"pk",
|
||||||
|
"id",
|
||||||
|
"access_list",
|
||||||
|
"direction",
|
||||||
|
"host",
|
||||||
|
"assigned_object",
|
||||||
|
"tags",
|
||||||
|
)
|
||||||
|
default_columns = (
|
||||||
|
"id",
|
||||||
|
"access_list",
|
||||||
|
"direction",
|
||||||
|
"host",
|
||||||
|
"assigned_object",
|
||||||
|
"tags",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ACLStandardRuleTable(NetBoxTable):
|
class ACLStandardRuleTable(NetBoxTable):
|
||||||
"""
|
"""
|
||||||
Defines the table view for the ACLStandardRule model.
|
Defines the table view for the ACLStandardRule model.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
access_list = tables.Column(
|
access_list = tables.Column(
|
||||||
linkify=True
|
linkify=True,
|
||||||
)
|
)
|
||||||
index = tables.Column(
|
index = tables.Column(
|
||||||
linkify=True
|
linkify=True,
|
||||||
)
|
)
|
||||||
action = ChoiceFieldColumn()
|
action = ChoiceFieldColumn()
|
||||||
tags = columns.TagColumn(
|
tags = columns.TagColumn(
|
||||||
url_name='plugins:netbox_access_lists:aclstandardrule_list'
|
url_name="plugins:netbox_access_lists:aclstandardrule_list",
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta(NetBoxTable.Meta):
|
class Meta(NetBoxTable.Meta):
|
||||||
model = ACLStandardRule
|
model = ACLStandardRule
|
||||||
fields = (
|
fields = (
|
||||||
'pk', 'id', 'access_list', 'index', 'action', 'actions', 'remark', 'tags', 'description', 'source_prefix',
|
"pk",
|
||||||
|
"id",
|
||||||
|
"access_list",
|
||||||
|
"index",
|
||||||
|
"action",
|
||||||
|
"actions",
|
||||||
|
"remark",
|
||||||
|
"tags",
|
||||||
|
"description",
|
||||||
|
"source_prefix",
|
||||||
)
|
)
|
||||||
default_columns = (
|
default_columns = (
|
||||||
'access_list', 'index', 'action', 'actions', 'remark', 'source_prefix', 'tags'
|
"access_list",
|
||||||
|
"index",
|
||||||
|
"action",
|
||||||
|
"actions",
|
||||||
|
"remark",
|
||||||
|
"source_prefix",
|
||||||
|
"tags",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -119,25 +168,47 @@ class ACLExtendedRuleTable(NetBoxTable):
|
|||||||
"""
|
"""
|
||||||
Defines the table view for the ACLExtendedRule model.
|
Defines the table view for the ACLExtendedRule model.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
access_list = tables.Column(
|
access_list = tables.Column(
|
||||||
linkify=True
|
linkify=True,
|
||||||
)
|
)
|
||||||
index = tables.Column(
|
index = tables.Column(
|
||||||
linkify=True
|
linkify=True,
|
||||||
)
|
)
|
||||||
action = ChoiceFieldColumn()
|
action = ChoiceFieldColumn()
|
||||||
tags = columns.TagColumn(
|
tags = columns.TagColumn(
|
||||||
url_name='plugins:netbox_access_lists:aclextendedrule_list'
|
url_name="plugins:netbox_access_lists:aclextendedrule_list",
|
||||||
)
|
)
|
||||||
protocol = ChoiceFieldColumn()
|
protocol = ChoiceFieldColumn()
|
||||||
|
|
||||||
class Meta(NetBoxTable.Meta):
|
class Meta(NetBoxTable.Meta):
|
||||||
model = ACLExtendedRule
|
model = ACLExtendedRule
|
||||||
fields = (
|
fields = (
|
||||||
'pk', 'id', 'access_list', 'index', 'action', 'actions', 'remark', 'tags', 'description',
|
"pk",
|
||||||
'source_prefix', 'source_ports', 'destination_prefix', 'destination_ports', 'protocol'
|
"id",
|
||||||
|
"access_list",
|
||||||
|
"index",
|
||||||
|
"action",
|
||||||
|
"actions",
|
||||||
|
"remark",
|
||||||
|
"tags",
|
||||||
|
"description",
|
||||||
|
"source_prefix",
|
||||||
|
"source_ports",
|
||||||
|
"destination_prefix",
|
||||||
|
"destination_ports",
|
||||||
|
"protocol",
|
||||||
)
|
)
|
||||||
default_columns = (
|
default_columns = (
|
||||||
'access_list', 'index', 'action', 'actions', 'remark', 'tags',
|
"access_list",
|
||||||
'source_prefix', 'source_ports', 'destination_prefix', 'destination_ports', 'protocol'
|
"index",
|
||||||
|
"action",
|
||||||
|
"actions",
|
||||||
|
"remark",
|
||||||
|
"tags",
|
||||||
|
"source_prefix",
|
||||||
|
"source_ports",
|
||||||
|
"destination_prefix",
|
||||||
|
"destination_ports",
|
||||||
|
"protocol",
|
||||||
)
|
)
|
||||||
|
|||||||
@ -1,70 +1,87 @@
|
|||||||
|
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from extras.plugins import PluginTemplateExtension
|
from extras.plugins import PluginTemplateExtension
|
||||||
|
|
||||||
from .models import AccessList, ACLInterfaceAssignment
|
from .models import AccessList, ACLInterfaceAssignment
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'AccessLists',
|
"AccessLists",
|
||||||
"ACLInterfaceAssignments",
|
"ACLInterfaceAssignments",
|
||||||
'DeviceAccessLists',
|
"DeviceAccessLists",
|
||||||
'VirtualChassisAccessLists',
|
"VirtualChassisAccessLists",
|
||||||
'VMAccessLists',
|
"VMAccessLists",
|
||||||
'DeviceACLInterfaceAssignments',
|
"DeviceACLInterfaceAssignments",
|
||||||
'VMAACLInterfaceAssignments',
|
"VMAACLInterfaceAssignments",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class ACLInterfaceAssignments(PluginTemplateExtension):
|
class ACLInterfaceAssignments(PluginTemplateExtension):
|
||||||
|
|
||||||
def right_page(self):
|
def right_page(self):
|
||||||
obj = self.context['object']
|
obj = self.context["object"]
|
||||||
|
|
||||||
acl_interface_assignments = None
|
acl_interface_assignments = None
|
||||||
ctype = ContentType.objects.get_for_model(obj)
|
ctype = ContentType.objects.get_for_model(obj)
|
||||||
if ctype.model in ['interface', 'vminterface']:
|
if ctype.model in ["interface", "vminterface"]:
|
||||||
acl_interface_assignments = ACLInterfaceAssignment.objects.filter(assigned_object_id=obj.pk, assigned_object_type=ctype)
|
acl_interface_assignments = ACLInterfaceAssignment.objects.filter(
|
||||||
|
assigned_object_id=obj.pk, assigned_object_type=ctype
|
||||||
|
)
|
||||||
|
|
||||||
return self.render('inc/assigned_interface/access_lists.html', extra_context={
|
return self.render(
|
||||||
'acl_interface_assignments': acl_interface_assignments,
|
"inc/assigned_interface/access_lists.html",
|
||||||
'type': ctype.model if ctype.model == 'device' else ctype.name.replace(' ', '_'),
|
extra_context={
|
||||||
})
|
"acl_interface_assignments": acl_interface_assignments,
|
||||||
|
"type": ctype.model
|
||||||
|
if ctype.model == "device"
|
||||||
|
else ctype.name.replace(" ", "_"),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class AccessLists(PluginTemplateExtension):
|
class AccessLists(PluginTemplateExtension):
|
||||||
|
|
||||||
def right_page(self):
|
def right_page(self):
|
||||||
obj = self.context['object']
|
obj = self.context["object"]
|
||||||
|
|
||||||
access_lists = None
|
access_lists = None
|
||||||
ctype = ContentType.objects.get_for_model(obj)
|
ctype = ContentType.objects.get_for_model(obj)
|
||||||
if ctype.model in ['device', 'virtualchassis', 'virtualmachine']:
|
if ctype.model in ["device", "virtualchassis", "virtualmachine"]:
|
||||||
access_lists = AccessList.objects.filter(assigned_object_id=obj.pk, assigned_object_type=ctype)
|
access_lists = AccessList.objects.filter(
|
||||||
|
assigned_object_id=obj.pk, assigned_object_type=ctype
|
||||||
|
)
|
||||||
|
|
||||||
return self.render('inc/assigned_host/access_lists.html', extra_context={
|
return self.render(
|
||||||
'access_lists': access_lists,
|
"inc/assigned_host/access_lists.html",
|
||||||
'type': ctype.model if ctype.model == 'device' else ctype.name.replace(' ', '_'),
|
extra_context={
|
||||||
})
|
"access_lists": access_lists,
|
||||||
|
"type": ctype.model
|
||||||
|
if ctype.model == "device"
|
||||||
|
else ctype.name.replace(" ", "_"),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class DeviceAccessLists(AccessLists):
|
class DeviceAccessLists(AccessLists):
|
||||||
model = 'dcim.device'
|
model = "dcim.device"
|
||||||
|
|
||||||
|
|
||||||
class VirtualChassisAccessLists(AccessLists):
|
class VirtualChassisAccessLists(AccessLists):
|
||||||
model = 'dcim.virtualchassis'
|
model = "dcim.virtualchassis"
|
||||||
|
|
||||||
|
|
||||||
class VMAccessLists(AccessLists):
|
class VMAccessLists(AccessLists):
|
||||||
model = 'virtualization.virtualmachine'
|
model = "virtualization.virtualmachine"
|
||||||
|
|
||||||
|
|
||||||
class DeviceACLInterfaceAssignments(ACLInterfaceAssignments):
|
class DeviceACLInterfaceAssignments(ACLInterfaceAssignments):
|
||||||
model = 'dcim.interface'
|
model = "dcim.interface"
|
||||||
|
|
||||||
|
|
||||||
class VMAACLInterfaceAssignments(ACLInterfaceAssignments):
|
class VMAACLInterfaceAssignments(ACLInterfaceAssignments):
|
||||||
model = 'virtualization.vminterface'
|
model = "virtualization.vminterface"
|
||||||
|
|
||||||
|
|
||||||
template_extensions = [DeviceAccessLists, VirtualChassisAccessLists, VMAccessLists, DeviceACLInterfaceAssignments, VMAACLInterfaceAssignments]
|
template_extensions = [
|
||||||
|
DeviceAccessLists,
|
||||||
|
VirtualChassisAccessLists,
|
||||||
|
VMAccessLists,
|
||||||
|
DeviceACLInterfaceAssignments,
|
||||||
|
VMAACLInterfaceAssignments,
|
||||||
|
]
|
||||||
|
|||||||
@ -8,51 +8,152 @@ from netbox.views.generic import ObjectChangeLogView
|
|||||||
from . import models, views
|
from . import models, views
|
||||||
|
|
||||||
urlpatterns = (
|
urlpatterns = (
|
||||||
|
|
||||||
# Access Lists
|
# Access Lists
|
||||||
path('access-lists/', views.AccessListListView.as_view(), name='accesslist_list'),
|
path("access-lists/", views.AccessListListView.as_view(), name="accesslist_list"),
|
||||||
path('access-lists/add/', views.AccessListEditView.as_view(), name='accesslist_add'),
|
path(
|
||||||
#path('access-lists/edit/', views.AccessListBulkEditView.as_view(), name='accesslist_bulk_edit'),
|
"access-lists/add/", views.AccessListEditView.as_view(), name="accesslist_add"
|
||||||
path('access-lists/delete/', views.AccessListBulkDeleteView.as_view(), name='accesslist_bulk_delete'),
|
),
|
||||||
path('access-lists/<int:pk>/', views.AccessListView.as_view(), name='accesslist'),
|
# path('access-lists/edit/', views.AccessListBulkEditView.as_view(), name='accesslist_bulk_edit'),
|
||||||
path('access-lists/<int:pk>/edit/', views.AccessListEditView.as_view(), name='accesslist_edit'),
|
path(
|
||||||
path('access-lists/<int:pk>/delete/', views.AccessListDeleteView.as_view(), name='accesslist_delete'),
|
"access-lists/delete/",
|
||||||
path('access-lists/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='accesslist_changelog', kwargs={
|
views.AccessListBulkDeleteView.as_view(),
|
||||||
'model': models.AccessList
|
name="accesslist_bulk_delete",
|
||||||
}),
|
),
|
||||||
|
path("access-lists/<int:pk>/", views.AccessListView.as_view(), name="accesslist"),
|
||||||
|
path(
|
||||||
|
"access-lists/<int:pk>/edit/",
|
||||||
|
views.AccessListEditView.as_view(),
|
||||||
|
name="accesslist_edit",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"access-lists/<int:pk>/delete/",
|
||||||
|
views.AccessListDeleteView.as_view(),
|
||||||
|
name="accesslist_delete",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"access-lists/<int:pk>/changelog/",
|
||||||
|
ObjectChangeLogView.as_view(),
|
||||||
|
name="accesslist_changelog",
|
||||||
|
kwargs={
|
||||||
|
"model": models.AccessList,
|
||||||
|
},
|
||||||
|
),
|
||||||
# Access List Interface Assignments
|
# Access List Interface Assignments
|
||||||
path('interface-assignments/', views.ACLInterfaceAssignmentListView.as_view(), name='aclinterfaceassignment_list'),
|
path(
|
||||||
path('interface-assignments/add/', views.ACLInterfaceAssignmentEditView.as_view(), name='aclinterfaceassignment_add'),
|
"interface-assignments/",
|
||||||
#path('interface-assignments/edit/', views.ACLInterfaceAssignmentBulkEditView.as_view(), name='aclinterfaceassignment_bulk_edit'),
|
views.ACLInterfaceAssignmentListView.as_view(),
|
||||||
path('interface-assignments/delete/', views.ACLInterfaceAssignmentBulkDeleteView.as_view(), name='aclinterfaceassignment_bulk_delete'),
|
name="aclinterfaceassignment_list",
|
||||||
path('interface-assignments/<int:pk>/', views.ACLInterfaceAssignmentView.as_view(), name='aclinterfaceassignment'),
|
),
|
||||||
path('interface-assignments/<int:pk>/edit/', views.ACLInterfaceAssignmentEditView.as_view(), name='aclinterfaceassignment_edit'),
|
path(
|
||||||
path('interface-assignments/<int:pk>/delete/', views.ACLInterfaceAssignmentDeleteView.as_view(), name='aclinterfaceassignment_delete'),
|
"interface-assignments/add/",
|
||||||
path('interface-assignments/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='aclinterfaceassignment_changelog', kwargs={
|
views.ACLInterfaceAssignmentEditView.as_view(),
|
||||||
'model': models.ACLInterfaceAssignment
|
name="aclinterfaceassignment_add",
|
||||||
}),
|
),
|
||||||
|
# path('interface-assignments/edit/', views.ACLInterfaceAssignmentBulkEditView.as_view(), name='aclinterfaceassignment_bulk_edit'),
|
||||||
|
path(
|
||||||
|
"interface-assignments/delete/",
|
||||||
|
views.ACLInterfaceAssignmentBulkDeleteView.as_view(),
|
||||||
|
name="aclinterfaceassignment_bulk_delete",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"interface-assignments/<int:pk>/",
|
||||||
|
views.ACLInterfaceAssignmentView.as_view(),
|
||||||
|
name="aclinterfaceassignment",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"interface-assignments/<int:pk>/edit/",
|
||||||
|
views.ACLInterfaceAssignmentEditView.as_view(),
|
||||||
|
name="aclinterfaceassignment_edit",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"interface-assignments/<int:pk>/delete/",
|
||||||
|
views.ACLInterfaceAssignmentDeleteView.as_view(),
|
||||||
|
name="aclinterfaceassignment_delete",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"interface-assignments/<int:pk>/changelog/",
|
||||||
|
ObjectChangeLogView.as_view(),
|
||||||
|
name="aclinterfaceassignment_changelog",
|
||||||
|
kwargs={
|
||||||
|
"model": models.ACLInterfaceAssignment,
|
||||||
|
},
|
||||||
|
),
|
||||||
# Standard Access List Rules
|
# Standard Access List Rules
|
||||||
path('standard-rules/', views.ACLStandardRuleListView.as_view(), name='aclstandardrule_list'),
|
path(
|
||||||
path('standard-rules/add/', views.ACLStandardRuleEditView.as_view(), name='aclstandardrule_add'),
|
"standard-rules/",
|
||||||
path('standard-rules/delete/', views.ACLStandardRuleBulkDeleteView.as_view(), name='aclstandardrule_bulk_delete'),
|
views.ACLStandardRuleListView.as_view(),
|
||||||
path('standard-rules/<int:pk>/', views.ACLStandardRuleView.as_view(), name='aclstandardrule'),
|
name="aclstandardrule_list",
|
||||||
path('standard-rules/<int:pk>/edit/', views.ACLStandardRuleEditView.as_view(), name='aclstandardrule_edit'),
|
),
|
||||||
path('standard-rules/<int:pk>/delete/', views.ACLStandardRuleDeleteView.as_view(), name='aclstandardrule_delete'),
|
path(
|
||||||
path('standard-rules/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='aclstandardrule_changelog', kwargs={
|
"standard-rules/add/",
|
||||||
'model': models.ACLStandardRule
|
views.ACLStandardRuleEditView.as_view(),
|
||||||
}),
|
name="aclstandardrule_add",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"standard-rules/delete/",
|
||||||
|
views.ACLStandardRuleBulkDeleteView.as_view(),
|
||||||
|
name="aclstandardrule_bulk_delete",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"standard-rules/<int:pk>/",
|
||||||
|
views.ACLStandardRuleView.as_view(),
|
||||||
|
name="aclstandardrule",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"standard-rules/<int:pk>/edit/",
|
||||||
|
views.ACLStandardRuleEditView.as_view(),
|
||||||
|
name="aclstandardrule_edit",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"standard-rules/<int:pk>/delete/",
|
||||||
|
views.ACLStandardRuleDeleteView.as_view(),
|
||||||
|
name="aclstandardrule_delete",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"standard-rules/<int:pk>/changelog/",
|
||||||
|
ObjectChangeLogView.as_view(),
|
||||||
|
name="aclstandardrule_changelog",
|
||||||
|
kwargs={
|
||||||
|
"model": models.ACLStandardRule,
|
||||||
|
},
|
||||||
|
),
|
||||||
# Extended Access List Rules
|
# Extended Access List Rules
|
||||||
path('extended-rules/', views.ACLExtendedRuleListView.as_view(), name='aclextendedrule_list'),
|
path(
|
||||||
path('extended-rules/add/', views.ACLExtendedRuleEditView.as_view(), name='aclextendedrule_add'),
|
"extended-rules/",
|
||||||
path('extended-rules/delete/', views.ACLExtendedRuleBulkDeleteView.as_view(), name='aclextendedrule_bulk_delete'),
|
views.ACLExtendedRuleListView.as_view(),
|
||||||
path('extended-rules/<int:pk>/', views.ACLExtendedRuleView.as_view(), name='aclextendedrule'),
|
name="aclextendedrule_list",
|
||||||
path('extended-rules/<int:pk>/edit/', views.ACLExtendedRuleEditView.as_view(), name='aclextendedrule_edit'),
|
),
|
||||||
path('extended-rules/<int:pk>/delete/', views.ACLExtendedRuleDeleteView.as_view(), name='aclextendedrule_delete'),
|
path(
|
||||||
path('extended-rules/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='aclextendedrule_changelog', kwargs={
|
"extended-rules/add/",
|
||||||
'model': models.ACLExtendedRule
|
views.ACLExtendedRuleEditView.as_view(),
|
||||||
}),
|
name="aclextendedrule_add",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"extended-rules/delete/",
|
||||||
|
views.ACLExtendedRuleBulkDeleteView.as_view(),
|
||||||
|
name="aclextendedrule_bulk_delete",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"extended-rules/<int:pk>/",
|
||||||
|
views.ACLExtendedRuleView.as_view(),
|
||||||
|
name="aclextendedrule",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"extended-rules/<int:pk>/edit/",
|
||||||
|
views.ACLExtendedRuleEditView.as_view(),
|
||||||
|
name="aclextendedrule_edit",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"extended-rules/<int:pk>/delete/",
|
||||||
|
views.ACLExtendedRuleDeleteView.as_view(),
|
||||||
|
name="aclextendedrule_delete",
|
||||||
|
),
|
||||||
|
path(
|
||||||
|
"extended-rules/<int:pk>/changelog/",
|
||||||
|
ObjectChangeLogView.as_view(),
|
||||||
|
name="aclextendedrule_changelog",
|
||||||
|
kwargs={
|
||||||
|
"model": models.ACLExtendedRule,
|
||||||
|
},
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
@ -9,26 +9,26 @@ from netbox.views import generic
|
|||||||
from . import filtersets, forms, models, tables
|
from . import filtersets, forms, models, tables
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'AccessListView',
|
"AccessListView",
|
||||||
'AccessListListView',
|
"AccessListListView",
|
||||||
'AccessListEditView',
|
"AccessListEditView",
|
||||||
'AccessListDeleteView',
|
"AccessListDeleteView",
|
||||||
'AccessListBulkDeleteView',
|
"AccessListBulkDeleteView",
|
||||||
'ACLInterfaceAssignmentView',
|
"ACLInterfaceAssignmentView",
|
||||||
'ACLInterfaceAssignmentListView',
|
"ACLInterfaceAssignmentListView",
|
||||||
'ACLInterfaceAssignmentEditView',
|
"ACLInterfaceAssignmentEditView",
|
||||||
'ACLInterfaceAssignmentDeleteView',
|
"ACLInterfaceAssignmentDeleteView",
|
||||||
'ACLInterfaceAssignmentBulkDeleteView',
|
"ACLInterfaceAssignmentBulkDeleteView",
|
||||||
'ACLStandardRuleView',
|
"ACLStandardRuleView",
|
||||||
'ACLStandardRuleListView',
|
"ACLStandardRuleListView",
|
||||||
'ACLStandardRuleEditView',
|
"ACLStandardRuleEditView",
|
||||||
'ACLStandardRuleDeleteView',
|
"ACLStandardRuleDeleteView",
|
||||||
'ACLStandardRuleBulkDeleteView',
|
"ACLStandardRuleBulkDeleteView",
|
||||||
'ACLExtendedRuleView',
|
"ACLExtendedRuleView",
|
||||||
'ACLExtendedRuleListView',
|
"ACLExtendedRuleListView",
|
||||||
'ACLExtendedRuleEditView',
|
"ACLExtendedRuleEditView",
|
||||||
'ACLExtendedRuleDeleteView',
|
"ACLExtendedRuleDeleteView",
|
||||||
'ACLExtendedRuleBulkDeleteView',
|
"ACLExtendedRuleBulkDeleteView",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -36,24 +36,26 @@ __all__ = (
|
|||||||
# AccessList views
|
# AccessList views
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
class AccessListView(generic.ObjectView):
|
class AccessListView(generic.ObjectView):
|
||||||
"""
|
"""
|
||||||
Defines the view for the AccessLists django model.
|
Defines the view for the AccessLists django model.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = models.AccessList.objects.all()
|
queryset = models.AccessList.objects.all()
|
||||||
|
|
||||||
def get_extra_context(self, request, instance):
|
def get_extra_context(self, request, instance):
|
||||||
"""
|
"""
|
||||||
Depending on the Access List type, the list view will return the required ACL Rule using the previous defined tables in tables.py.
|
Depending on the Access List type, the list view will return the required ACL Rule using the previous defined tables in tables.py.
|
||||||
"""
|
"""
|
||||||
if instance.type == 'extended':
|
if instance.type == "extended":
|
||||||
table = tables.ACLExtendedRuleTable(instance.aclextendedrules.all())
|
table = tables.ACLExtendedRuleTable(instance.aclextendedrules.all())
|
||||||
elif instance.type == 'standard':
|
elif instance.type == "standard":
|
||||||
table = tables.ACLStandardRuleTable(instance.aclstandardrules.all())
|
table = tables.ACLStandardRuleTable(instance.aclstandardrules.all())
|
||||||
table.configure(request)
|
table.configure(request)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'rules_table': table
|
"rules_table": table,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -61,8 +63,9 @@ class AccessListListView(generic.ObjectListView):
|
|||||||
"""
|
"""
|
||||||
Defines the list view for the AccessLists django model.
|
Defines the list view for the AccessLists django model.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = models.AccessList.objects.annotate(
|
queryset = models.AccessList.objects.annotate(
|
||||||
rule_count=Count('aclextendedrules') + Count('aclstandardrules')
|
rule_count=Count("aclextendedrules") + Count("aclstandardrules"),
|
||||||
)
|
)
|
||||||
table = tables.AccessListTable
|
table = tables.AccessListTable
|
||||||
filterset = filtersets.AccessListFilterSet
|
filterset = filtersets.AccessListFilterSet
|
||||||
@ -73,15 +76,17 @@ class AccessListEditView(generic.ObjectEditView):
|
|||||||
"""
|
"""
|
||||||
Defines the edit view for the AccessLists django model.
|
Defines the edit view for the AccessLists django model.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = models.AccessList.objects.all()
|
queryset = models.AccessList.objects.all()
|
||||||
form = forms.AccessListForm
|
form = forms.AccessListForm
|
||||||
template_name = 'netbox_access_lists/accesslist_edit.html'
|
template_name = "netbox_access_lists/accesslist_edit.html"
|
||||||
|
|
||||||
|
|
||||||
class AccessListDeleteView(generic.ObjectDeleteView):
|
class AccessListDeleteView(generic.ObjectDeleteView):
|
||||||
"""
|
"""
|
||||||
Defines the delete view for the AccessLists django model.
|
Defines the delete view for the AccessLists django model.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = models.AccessList.objects.all()
|
queryset = models.AccessList.objects.all()
|
||||||
|
|
||||||
|
|
||||||
@ -90,14 +95,17 @@ class AccessListBulkDeleteView(generic.BulkDeleteView):
|
|||||||
filterset = filtersets.AccessListFilterSet
|
filterset = filtersets.AccessListFilterSet
|
||||||
table = tables.AccessListTable
|
table = tables.AccessListTable
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# ACLInterfaceAssignment views
|
# ACLInterfaceAssignment views
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
class ACLInterfaceAssignmentView(generic.ObjectView):
|
class ACLInterfaceAssignmentView(generic.ObjectView):
|
||||||
"""
|
"""
|
||||||
Defines the view for the ACLInterfaceAssignments django model.
|
Defines the view for the ACLInterfaceAssignments django model.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = models.ACLInterfaceAssignment.objects.all()
|
queryset = models.ACLInterfaceAssignment.objects.all()
|
||||||
|
|
||||||
|
|
||||||
@ -105,6 +113,7 @@ class ACLInterfaceAssignmentListView(generic.ObjectListView):
|
|||||||
"""
|
"""
|
||||||
Defines the list view for the ACLInterfaceAssignments django model.
|
Defines the list view for the ACLInterfaceAssignments django model.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = models.ACLInterfaceAssignment.objects.all()
|
queryset = models.ACLInterfaceAssignment.objects.all()
|
||||||
table = tables.ACLInterfaceAssignmentTable
|
table = tables.ACLInterfaceAssignmentTable
|
||||||
filterset = filtersets.ACLInterfaceAssignmentFilterSet
|
filterset = filtersets.ACLInterfaceAssignmentFilterSet
|
||||||
@ -115,15 +124,17 @@ class ACLInterfaceAssignmentEditView(generic.ObjectEditView):
|
|||||||
"""
|
"""
|
||||||
Defines the edit view for the ACLInterfaceAssignments django model.
|
Defines the edit view for the ACLInterfaceAssignments django model.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = models.ACLInterfaceAssignment.objects.all()
|
queryset = models.ACLInterfaceAssignment.objects.all()
|
||||||
form = forms.ACLInterfaceAssignmentForm
|
form = forms.ACLInterfaceAssignmentForm
|
||||||
template_name = 'netbox_access_lists/aclinterfaceassignment_edit.html'
|
template_name = "netbox_access_lists/aclinterfaceassignment_edit.html"
|
||||||
|
|
||||||
|
|
||||||
class ACLInterfaceAssignmentDeleteView(generic.ObjectDeleteView):
|
class ACLInterfaceAssignmentDeleteView(generic.ObjectDeleteView):
|
||||||
"""
|
"""
|
||||||
Defines the delete view for the ACLInterfaceAssignments django model.
|
Defines the delete view for the ACLInterfaceAssignments django model.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = models.ACLInterfaceAssignment.objects.all()
|
queryset = models.ACLInterfaceAssignment.objects.all()
|
||||||
|
|
||||||
|
|
||||||
@ -142,6 +153,7 @@ class ACLStandardRuleView(generic.ObjectView):
|
|||||||
"""
|
"""
|
||||||
Defines the view for the ACLStandardRule django model.
|
Defines the view for the ACLStandardRule django model.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = models.ACLStandardRule.objects.all()
|
queryset = models.ACLStandardRule.objects.all()
|
||||||
|
|
||||||
|
|
||||||
@ -149,6 +161,7 @@ class ACLStandardRuleListView(generic.ObjectListView):
|
|||||||
"""
|
"""
|
||||||
Defines the list view for the ACLStandardRule django model.
|
Defines the list view for the ACLStandardRule django model.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = models.ACLStandardRule.objects.all()
|
queryset = models.ACLStandardRule.objects.all()
|
||||||
table = tables.ACLStandardRuleTable
|
table = tables.ACLStandardRuleTable
|
||||||
filterset = filtersets.ACLStandardRuleFilterSet
|
filterset = filtersets.ACLStandardRuleFilterSet
|
||||||
@ -159,6 +172,7 @@ class ACLStandardRuleEditView(generic.ObjectEditView):
|
|||||||
"""
|
"""
|
||||||
Defines the edit view for the ACLStandardRule django model.
|
Defines the edit view for the ACLStandardRule django model.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = models.ACLStandardRule.objects.all()
|
queryset = models.ACLStandardRule.objects.all()
|
||||||
form = forms.ACLStandardRuleForm
|
form = forms.ACLStandardRuleForm
|
||||||
|
|
||||||
@ -167,6 +181,7 @@ class ACLStandardRuleDeleteView(generic.ObjectDeleteView):
|
|||||||
"""
|
"""
|
||||||
Defines the delete view for the ACLStandardRules django model.
|
Defines the delete view for the ACLStandardRules django model.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = models.ACLStandardRule.objects.all()
|
queryset = models.ACLStandardRule.objects.all()
|
||||||
|
|
||||||
|
|
||||||
@ -175,6 +190,7 @@ class ACLStandardRuleBulkDeleteView(generic.BulkDeleteView):
|
|||||||
filterset = filtersets.ACLStandardRuleFilterSet
|
filterset = filtersets.ACLStandardRuleFilterSet
|
||||||
table = tables.ACLStandardRuleTable
|
table = tables.ACLStandardRuleTable
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# ACLExtendedRule views
|
# ACLExtendedRule views
|
||||||
#
|
#
|
||||||
@ -184,6 +200,7 @@ class ACLExtendedRuleView(generic.ObjectView):
|
|||||||
"""
|
"""
|
||||||
Defines the view for the ACLExtendedRule django model.
|
Defines the view for the ACLExtendedRule django model.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = models.ACLExtendedRule.objects.all()
|
queryset = models.ACLExtendedRule.objects.all()
|
||||||
|
|
||||||
|
|
||||||
@ -191,6 +208,7 @@ class ACLExtendedRuleListView(generic.ObjectListView):
|
|||||||
"""
|
"""
|
||||||
Defines the list view for the ACLExtendedRule django model.
|
Defines the list view for the ACLExtendedRule django model.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = models.ACLExtendedRule.objects.all()
|
queryset = models.ACLExtendedRule.objects.all()
|
||||||
table = tables.ACLExtendedRuleTable
|
table = tables.ACLExtendedRuleTable
|
||||||
filterset = filtersets.ACLExtendedRuleFilterSet
|
filterset = filtersets.ACLExtendedRuleFilterSet
|
||||||
@ -201,6 +219,7 @@ class ACLExtendedRuleEditView(generic.ObjectEditView):
|
|||||||
"""
|
"""
|
||||||
Defines the edit view for the ACLExtendedRule django model.
|
Defines the edit view for the ACLExtendedRule django model.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = models.ACLExtendedRule.objects.all()
|
queryset = models.ACLExtendedRule.objects.all()
|
||||||
form = forms.ACLExtendedRuleForm
|
form = forms.ACLExtendedRuleForm
|
||||||
|
|
||||||
@ -209,8 +228,10 @@ class ACLExtendedRuleDeleteView(generic.ObjectDeleteView):
|
|||||||
"""
|
"""
|
||||||
Defines the delete view for the ACLExtendedRules django model.
|
Defines the delete view for the ACLExtendedRules django model.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = models.ACLExtendedRule.objects.all()
|
queryset = models.ACLExtendedRule.objects.all()
|
||||||
|
|
||||||
|
|
||||||
class ACLExtendedRuleBulkDeleteView(generic.BulkDeleteView):
|
class ACLExtendedRuleBulkDeleteView(generic.BulkDeleteView):
|
||||||
queryset = models.ACLExtendedRule.objects.all()
|
queryset = models.ACLExtendedRule.objects.all()
|
||||||
filterset = filtersets.ACLExtendedRuleFilterSet
|
filterset = filtersets.ACLExtendedRuleFilterSet
|
||||||
|
|||||||
24
setup.py
24
setup.py
@ -1,20 +1,20 @@
|
|||||||
#import codecs
|
# import codecs
|
||||||
#import os.path
|
# import os.path
|
||||||
#
|
#
|
||||||
from setuptools import find_packages, setup
|
from setuptools import find_packages, setup
|
||||||
|
|
||||||
#
|
#
|
||||||
#with open("README.md", "r") as fh:
|
# with open("README.md", "r") as fh:
|
||||||
# long_description = fh.read()
|
# long_description = fh.read()
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
#def read(rel_path):
|
# def read(rel_path):
|
||||||
# here = os.path.abspath(os.path.dirname(__file__))
|
# here = os.path.abspath(os.path.dirname(__file__))
|
||||||
# with codecs.open(os.path.join(here, rel_path), 'r') as fp:
|
# with codecs.open(os.path.join(here, rel_path), "r") as fp:
|
||||||
# return fp.read()
|
# return fp.read()
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
#def get_version(rel_path):
|
# def get_version(rel_path):
|
||||||
# for line in read(rel_path).splitlines():
|
# for line in read(rel_path).splitlines():
|
||||||
# if line.startswith('__version__'):
|
# if line.startswith('__version__'):
|
||||||
# delim = '"' if '"' in line else "'"
|
# delim = '"' if '"' in line else "'"
|
||||||
@ -24,13 +24,13 @@ from setuptools import find_packages, setup
|
|||||||
#
|
#
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='netbox-access-lists',
|
name="netbox-access-lists",
|
||||||
version='0.1.0',
|
version="0.1.0",
|
||||||
#version=get_version('netbox_access_lists/version.py'),
|
# version=get_version("netbox_access_lists/version.py"),
|
||||||
description='A NetBox plugin for Access List management',
|
description="A NetBox plugin for Access List management",
|
||||||
#long_description=long_description,
|
# long_description=long_description,
|
||||||
long_description_content_type="text/markdown",
|
long_description_content_type="text/markdown",
|
||||||
url='https://github.com/ryanmerolle/netbox-access-lists',
|
url="https://github.com/ryanmerolle/netbox-access-lists",
|
||||||
install_requires=[],
|
install_requires=[],
|
||||||
packages=find_packages(),
|
packages=find_packages(),
|
||||||
include_package_data=True,
|
include_package_data=True,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user