From 01693878d28f117177fadff570078d55b2d6a7f2 Mon Sep 17 00:00:00 2001 From: Leo Kirchner Date: Wed, 26 Oct 2022 16:21:46 +0200 Subject: [PATCH 1/4] Enable cloning for PolicyRule and NATPolicyRule models. --- .../models/core_models.py | 42 +++++++++++++++++++ .../nautobot_firewall_models/policyrule.html | 2 +- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/nautobot_firewall_models/models/core_models.py b/nautobot_firewall_models/models/core_models.py index fcc25c00..dde913d6 100644 --- a/nautobot_firewall_models/models/core_models.py +++ b/nautobot_firewall_models/models/core_models.py @@ -543,6 +543,24 @@ class PolicyRule(PrimaryModel): description = models.CharField(max_length=200, null=True, blank=True) index = models.PositiveSmallIntegerField(null=True, blank=True) + clone_fields = [ + "source_users", + "source_user_groups", + "source_addresses", + "source_address_groups", + "source_zone", + "source_services", + "source_service_groups", + "destination_addresses", + "destination_address_groups", + "destination_zone", + "destination_services", + "destination_service_groups", + "action", + "log", + "status", + ] + class Meta: """Meta class.""" @@ -755,6 +773,30 @@ class NATPolicyRule(PrimaryModel): to=ServiceObjectGroup, through="NATTransDestSvcGroupM2M", related_name="translated_destination_nat_policy_rules" ) + clone_fields = [ + "destination_zone", + "source_zone", + "original_source_addresses", + "original_source_address_groups", + "original_source_services", + "original_source_service_groups", + "original_destination_addresses", + "original_destination_address_groups", + "original_destination_services", + "original_destination_service_groups", + "translated_source_addresses", + "translated_source_address_groups", + "translated_source_services", + "translated_source_service_groups", + "translated_destination_addresses", + "translated_destination_address_groups", + "translated_destination_services", + "translated_destination_service_groups", + "remark", + "log", + "status", + ] + class Meta: """Meta class.""" diff --git a/nautobot_firewall_models/templates/nautobot_firewall_models/policyrule.html b/nautobot_firewall_models/templates/nautobot_firewall_models/policyrule.html index 5a4f0082..12b5ad56 100644 --- a/nautobot_firewall_models/templates/nautobot_firewall_models/policyrule.html +++ b/nautobot_firewall_models/templates/nautobot_firewall_models/policyrule.html @@ -1,4 +1,4 @@ -{% extends 'generic/object_detail.html' %} +{% extends 'generic/object_retrieve.html' %} {% load helpers %} {% load plugins %} {% block content %} From dcfa5d0f77a1d1ad281c73ea706a4909b75e8fc9 Mon Sep 17 00:00:00 2001 From: Glenn Matthews Date: Fri, 4 Nov 2022 09:16:25 -0400 Subject: [PATCH 2/4] Update mkdocs.yml Fix some incorrect URLs in the mkdocs config. --- mkdocs.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mkdocs.yml b/mkdocs.yml index b595c06a..b22e6583 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,10 +1,10 @@ --- dev_addr: "127.0.0.1:8001" -edit_uri: "edit/main/nautobot-plugin-firewall-model/docs" +edit_uri: "edit/main/docs" site_name: "Nautobot Firewall Models Documentation" -site_url: "https://nautobot-plugin-firewall-model.readthedocs.io/" +site_url: "https://nautobot-plugin-firewall-models.readthedocs.io/" site_dir: nautobot_firewall_models/static/nautobot_firewall_models/docs -repo_url: "https://github.com/networktocode-llc/nautobot-plugin-firewall-model" +repo_url: "https://github.com/nautobot/nautobot-plugin-firewall-models" theme: name: "readthedocs" navigation_depth: 4 From d5e488b18c330035b8861a4e5eebb6d468a8949e Mon Sep 17 00:00:00 2001 From: Jeremy White Date: Sat, 12 Nov 2022 14:25:06 -0600 Subject: [PATCH 3/4] update to support port list --- CHANGELOG.md | 11 +++++++++++ nautobot_firewall_models/validators.py | 23 ++++++++++++----------- pyproject.toml | 2 +- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f89d0432..31f9481c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # Changelog +## v1.1.2 - 2022-11-12 + +### Added + +- #108 Enable cloning for PolicyRule and NATPolicyRule models +- #110 Add support for port lists on ServiceObject + +### Fixed + +- #109 Resolved incorrect links in mkdocs.yml + ## v1.1.1 - 2022-10-26 ### Fixed diff --git a/nautobot_firewall_models/validators.py b/nautobot_firewall_models/validators.py index 3ae837dc..45d68b5c 100644 --- a/nautobot_firewall_models/validators.py +++ b/nautobot_firewall_models/validators.py @@ -6,14 +6,15 @@ def validate_port(value): - """Validates value is a port or port range.""" - if value.isnumeric(): - return - if re.match(r"^\d*\-\d*$", value): - return - if value is None or value == "": - return - raise ValidationError( - _("%(value)s is not a port number or port range."), - params={"value": value}, - ) + """Validates value is a port, port range, or port list.""" + for i in value.split(","): + if i.isnumeric(): + continue + if re.match(r"^\d*\-\d*$", i): + continue + if i is None or i == "": + continue + raise ValidationError( + _("%(i)s is not a port number or port range."), + params={"value": i}, + ) diff --git a/pyproject.toml b/pyproject.toml index a19ce788..3fb67cef 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "nautobot-firewall-models" -version = "1.1.1" +version = "1.1.2" description = "Nautobot plugin to model firewall objects." authors = ["Network to Code, LLC "] license = "Apache-2.0" From d9320d7302c36c2c7836e2e91d88c7d77d2b053f Mon Sep 17 00:00:00 2001 From: Jeremy White Date: Sat, 12 Nov 2022 15:06:41 -0600 Subject: [PATCH 4/4] skipping new tests as they are not accounted for in this plugin --- nautobot_firewall_models/tests/test_api.py | 44 ++++++++++ .../tests/test_ui_views.py | 88 +++++++++++++++++++ 2 files changed, 132 insertions(+) diff --git a/nautobot_firewall_models/tests/test_api.py b/nautobot_firewall_models/tests/test_api.py index 9b8df5cb..21c4c65d 100644 --- a/nautobot_firewall_models/tests/test_api.py +++ b/nautobot_firewall_models/tests/test_api.py @@ -82,6 +82,10 @@ def test_delete_object(self): def test_bulk_delete_objects(self): pass + @skip("on_delete set to PROTECT") + def test_delete_object_without_permission(self): + pass + class AddressObjectGroupAPIViewTest(APIViewTestCases.APIViewTestCase): """Test the AddressObjectGroup viewsets.""" @@ -112,6 +116,10 @@ def test_delete_object(self): def test_bulk_delete_objects(self): pass + @skip("on_delete set to PROTECT") + def test_delete_object_without_permission(self): + pass + def test_create_object(self): self.validation_excluded_fields = ["address_objects"] return super().test_create_object() @@ -154,6 +162,10 @@ def test_delete_object(self): def test_bulk_delete_objects(self): pass + @skip("on_delete set to PROTECT") + def test_delete_object_without_permission(self): + pass + class ServiceGroupAPIViewTest(APIViewTestCases.APIViewTestCase): """Test the ServiceGroup viewsets.""" @@ -184,6 +196,10 @@ def test_delete_object(self): def test_bulk_delete_objects(self): pass + @skip("on_delete set to PROTECT") + def test_delete_object_without_permission(self): + pass + def test_create_object(self): self.validation_excluded_fields = ["service_objects"] return super().test_create_object() @@ -225,6 +241,10 @@ def test_delete_object(self): def test_bulk_delete_objects(self): pass + @skip("on_delete set to PROTECT") + def test_delete_object_without_permission(self): + pass + class UserObjectGroupAPIViewTest(APIViewTestCases.APIViewTestCase): """Test the UserGroup viewsets.""" @@ -255,6 +275,10 @@ def test_delete_object(self): def test_bulk_delete_objects(self): pass + @skip("on_delete set to PROTECT") + def test_delete_object_without_permission(self): + pass + def test_create_object(self): self.validation_excluded_fields = ["user_objects"] return super().test_create_object() @@ -296,6 +320,10 @@ def test_delete_object(self): def test_bulk_delete_objects(self): pass + @skip("on_delete set to PROTECT") + def test_delete_object_without_permission(self): + pass + class PolicyRuleAPIViewTest(APIViewTestCases.APIViewTestCase): """Test the PolicyRule viewsets.""" @@ -346,6 +374,10 @@ def test_delete_object(self): def test_bulk_delete_objects(self): pass + @skip("on_delete set to PROTECT") + def test_delete_object_without_permission(self): + pass + class PolicyAPIViewTest(APIViewTestCases.APIViewTestCase): """Test the Policy viewsets.""" @@ -388,6 +420,10 @@ def test_delete_object(self): def test_bulk_delete_objects(self): pass + @skip("on_delete set to PROTECT") + def test_delete_object_without_permission(self): + pass + class NATPolicyRuleAPIViewTest(APIViewTestCases.APIViewTestCase): """Test the PolicyRule viewsets.""" @@ -434,6 +470,10 @@ def test_delete_object(self): def test_bulk_delete_objects(self): pass + @skip("on_delete set to PROTECT") + def test_delete_object_without_permission(self): + pass + class NATPolicyAPIViewTest(APIViewTestCases.APIViewTestCase): """Test the Policy viewsets.""" @@ -475,3 +515,7 @@ def test_delete_object(self): @skip("on_delete set to PROTECT") def test_bulk_delete_objects(self): pass + + @skip("on_delete set to PROTECT") + def test_delete_object_without_permission(self): + pass diff --git a/nautobot_firewall_models/tests/test_ui_views.py b/nautobot_firewall_models/tests/test_ui_views.py index f1459e84..9708c8dd 100644 --- a/nautobot_firewall_models/tests/test_ui_views.py +++ b/nautobot_firewall_models/tests/test_ui_views.py @@ -33,6 +33,14 @@ def test_bulk_import_objects_with_permission(self): def test_bulk_import_objects_without_permission(self): pass + @skip("Not implemented") + def test_bulk_import_objects_with_permission_csv_file(self): + pass + + @skip("on_delete set to PROTECT") + def test_delete_object_without_permission(self): + pass + class FQDNUIViewTest(ViewTestCases.PrimaryObjectViewTestCase): """Test the Protocol viewsets.""" @@ -59,6 +67,14 @@ def test_bulk_import_objects_with_permission(self): def test_bulk_import_objects_without_permission(self): pass + @skip("Not implemented") + def test_bulk_import_objects_with_permission_csv_file(self): + pass + + @skip("on_delete set to PROTECT") + def test_delete_object_without_permission(self): + pass + class AddressObjectUIViewTest(ViewTestCases.PrimaryObjectViewTestCase): """Test the AddressObject viewsets.""" @@ -87,6 +103,10 @@ def test_bulk_import_objects_with_permission(self): def test_bulk_import_objects_without_permission(self): pass + @skip("Not implemented") + def test_bulk_import_objects_with_permission_csv_file(self): + pass + @skip("on_delete set to PROTECT") def test_bulk_delete_objects_with_constrained_permission(self): pass @@ -103,6 +123,10 @@ def test_delete_object_with_constrained_permission(self): def test_delete_object_with_permission(self): pass + @skip("on_delete set to PROTECT") + def test_delete_object_without_permission(self): + pass + class AddressObjectGroupUIViewTest(ViewTestCases.PrimaryObjectViewTestCase): """Test the AddressObjectGroup viewsets.""" @@ -130,6 +154,10 @@ def test_bulk_import_objects_with_permission(self): def test_bulk_import_objects_without_permission(self): pass + @skip("Not implemented") + def test_bulk_import_objects_with_permission_csv_file(self): + pass + @skip("on_delete set to PROTECT") def test_bulk_delete_objects_with_constrained_permission(self): pass @@ -146,6 +174,10 @@ def test_delete_object_with_constrained_permission(self): def test_delete_object_with_permission(self): pass + @skip("on_delete set to PROTECT") + def test_delete_object_without_permission(self): + pass + class ServiceObjectUIViewTest(ViewTestCases.PrimaryObjectViewTestCase): """Test the ServiceObject viewsets.""" @@ -173,6 +205,10 @@ def test_bulk_import_objects_with_permission(self): def test_bulk_import_objects_without_permission(self): pass + @skip("Not implemented") + def test_bulk_import_objects_with_permission_csv_file(self): + pass + @skip("on_delete set to PROTECT") def test_bulk_delete_objects_with_constrained_permission(self): pass @@ -189,6 +225,10 @@ def test_delete_object_with_constrained_permission(self): def test_delete_object_with_permission(self): pass + @skip("on_delete set to PROTECT") + def test_delete_object_without_permission(self): + pass + class ServiceGroupUIViewTest(ViewTestCases.PrimaryObjectViewTestCase): """Test the ServiceGroup viewsets.""" @@ -216,6 +256,10 @@ def test_bulk_import_objects_with_permission(self): def test_bulk_import_objects_without_permission(self): pass + @skip("Not implemented") + def test_bulk_import_objects_with_permission_csv_file(self): + pass + @skip("on_delete set to PROTECT") def test_bulk_delete_objects_with_constrained_permission(self): pass @@ -232,6 +276,10 @@ def test_delete_object_with_constrained_permission(self): def test_delete_object_with_permission(self): pass + @skip("on_delete set to PROTECT") + def test_delete_object_without_permission(self): + pass + class UserObjectUIViewTest(ViewTestCases.PrimaryObjectViewTestCase): """Test the User viewsets.""" @@ -258,6 +306,10 @@ def test_bulk_import_objects_with_permission(self): def test_bulk_import_objects_without_permission(self): pass + @skip("Not implemented") + def test_bulk_import_objects_with_permission_csv_file(self): + pass + @skip("on_delete set to PROTECT") def test_bulk_delete_objects_with_constrained_permission(self): pass @@ -274,6 +326,10 @@ def test_delete_object_with_constrained_permission(self): def test_delete_object_with_permission(self): pass + @skip("on_delete set to PROTECT") + def test_delete_object_without_permission(self): + pass + class UserObjectGroupUIViewTest(ViewTestCases.PrimaryObjectViewTestCase): """Test the UserGroup viewsets.""" @@ -301,6 +357,10 @@ def test_bulk_import_objects_with_permission(self): def test_bulk_import_objects_without_permission(self): pass + @skip("Not implemented") + def test_bulk_import_objects_with_permission_csv_file(self): + pass + @skip("on_delete set to PROTECT") def test_bulk_delete_objects_with_constrained_permission(self): pass @@ -317,6 +377,10 @@ def test_delete_object_with_constrained_permission(self): def test_delete_object_with_permission(self): pass + @skip("on_delete set to PROTECT") + def test_delete_object_without_permission(self): + pass + class ZoneUIViewTest(ViewTestCases.PrimaryObjectViewTestCase): """Test the Zone viewsets.""" @@ -343,6 +407,10 @@ def test_bulk_import_objects_with_permission(self): def test_bulk_import_objects_without_permission(self): pass + @skip("Not implemented") + def test_bulk_import_objects_with_permission_csv_file(self): + pass + @skip("on_delete set to PROTECT") def test_bulk_delete_objects_with_constrained_permission(self): pass @@ -359,6 +427,10 @@ def test_delete_object_with_constrained_permission(self): def test_delete_object_with_permission(self): pass + @skip("on_delete set to PROTECT") + def test_delete_object_without_permission(self): + pass + class PolicyRuleUIViewTest(ViewTestCases.PrimaryObjectViewTestCase): """Test the PolicyRule viewsets.""" @@ -399,6 +471,10 @@ def test_bulk_import_objects_with_permission(self): def test_bulk_import_objects_without_permission(self): pass + @skip("Not implemented") + def test_bulk_import_objects_with_permission_csv_file(self): + pass + @skip("on_delete set to PROTECT") def test_bulk_delete_objects_with_constrained_permission(self): pass @@ -415,6 +491,10 @@ def test_delete_object_with_constrained_permission(self): def test_delete_object_with_permission(self): pass + @skip("on_delete set to PROTECT") + def test_delete_object_without_permission(self): + pass + class PolicyUIViewTest(ViewTestCases.PrimaryObjectViewTestCase): """Test the Policy viewsets.""" @@ -447,6 +527,10 @@ def test_bulk_import_objects_with_permission(self): def test_bulk_import_objects_without_permission(self): pass + @skip("Not implemented") + def test_bulk_import_objects_with_permission_csv_file(self): + pass + @skip("on_delete set to PROTECT") def test_bulk_delete_objects_with_constrained_permission(self): pass @@ -462,3 +546,7 @@ def test_delete_object_with_constrained_permission(self): @skip("on_delete set to PROTECT") def test_delete_object_with_permission(self): pass + + @skip("on_delete set to PROTECT") + def test_delete_object_without_permission(self): + pass