ipfabric_netbox 4.3.2b9__py3-none-any.whl → 4.3.2b10__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. ipfabric_netbox/__init__.py +2 -2
  2. ipfabric_netbox/api/serializers.py +112 -7
  3. ipfabric_netbox/api/urls.py +6 -0
  4. ipfabric_netbox/api/views.py +23 -0
  5. ipfabric_netbox/choices.py +72 -40
  6. ipfabric_netbox/data/endpoint.json +47 -0
  7. ipfabric_netbox/data/filters.json +51 -0
  8. ipfabric_netbox/data/transform_map.json +188 -174
  9. ipfabric_netbox/exceptions.py +7 -5
  10. ipfabric_netbox/filtersets.py +310 -41
  11. ipfabric_netbox/forms.py +324 -79
  12. ipfabric_netbox/graphql/__init__.py +6 -0
  13. ipfabric_netbox/graphql/enums.py +5 -5
  14. ipfabric_netbox/graphql/filters.py +56 -4
  15. ipfabric_netbox/graphql/schema.py +28 -0
  16. ipfabric_netbox/graphql/types.py +61 -1
  17. ipfabric_netbox/jobs.py +5 -1
  18. ipfabric_netbox/migrations/0022_prepare_for_filters.py +182 -0
  19. ipfabric_netbox/migrations/0023_populate_filters_data.py +279 -0
  20. ipfabric_netbox/migrations/0024_finish_filters.py +29 -0
  21. ipfabric_netbox/models.py +384 -12
  22. ipfabric_netbox/navigation.py +98 -24
  23. ipfabric_netbox/tables.py +194 -9
  24. ipfabric_netbox/templates/ipfabric_netbox/htmx_list.html +5 -0
  25. ipfabric_netbox/templates/ipfabric_netbox/inc/combined_expressions.html +59 -0
  26. ipfabric_netbox/templates/ipfabric_netbox/inc/combined_expressions_content.html +39 -0
  27. ipfabric_netbox/templates/ipfabric_netbox/inc/endpoint_filters_with_selector.html +54 -0
  28. ipfabric_netbox/templates/ipfabric_netbox/ipfabricendpoint.html +39 -0
  29. ipfabric_netbox/templates/ipfabric_netbox/ipfabricfilter.html +51 -0
  30. ipfabric_netbox/templates/ipfabric_netbox/ipfabricfilterexpression.html +39 -0
  31. ipfabric_netbox/templates/ipfabric_netbox/ipfabricfilterexpression_edit.html +150 -0
  32. ipfabric_netbox/templates/ipfabric_netbox/ipfabricsync.html +1 -1
  33. ipfabric_netbox/templates/ipfabric_netbox/ipfabrictransformmap.html +16 -2
  34. ipfabric_netbox/templatetags/ipfabric_netbox_helpers.py +65 -0
  35. ipfabric_netbox/tests/api/test_api.py +333 -13
  36. ipfabric_netbox/tests/test_filtersets.py +2592 -0
  37. ipfabric_netbox/tests/test_forms.py +1256 -74
  38. ipfabric_netbox/tests/test_models.py +242 -34
  39. ipfabric_netbox/tests/test_views.py +2030 -25
  40. ipfabric_netbox/urls.py +35 -0
  41. ipfabric_netbox/utilities/endpoint.py +30 -0
  42. ipfabric_netbox/utilities/filters.py +88 -0
  43. ipfabric_netbox/utilities/ipfutils.py +254 -316
  44. ipfabric_netbox/utilities/logging.py +7 -7
  45. ipfabric_netbox/utilities/transform_map.py +126 -0
  46. ipfabric_netbox/views.py +719 -5
  47. {ipfabric_netbox-4.3.2b9.dist-info → ipfabric_netbox-4.3.2b10.dist-info}/METADATA +3 -2
  48. {ipfabric_netbox-4.3.2b9.dist-info → ipfabric_netbox-4.3.2b10.dist-info}/RECORD +49 -33
  49. {ipfabric_netbox-4.3.2b9.dist-info → ipfabric_netbox-4.3.2b10.dist-info}/WHEEL +1 -1
ipfabric_netbox/urls.py CHANGED
@@ -46,6 +46,41 @@ urlpatterns = (
46
46
  "ingestion/<int:pk>/",
47
47
  include(get_model_urls("ipfabric_netbox", "ipfabricingestion")),
48
48
  ),
49
+ # Endpoint
50
+ path(
51
+ "filter/",
52
+ include(get_model_urls("ipfabric_netbox", "ipfabricfilter", detail=False)),
53
+ ),
54
+ path(
55
+ "filter/<int:pk>/",
56
+ include(get_model_urls("ipfabric_netbox", "ipfabricfilter")),
57
+ ),
58
+ # Endpoint
59
+ path(
60
+ "filter-expression/",
61
+ include(
62
+ get_model_urls("ipfabric_netbox", "ipfabricfilterexpression", detail=False)
63
+ ),
64
+ ),
65
+ # Test endpoint for unsaved expressions (no pk required)
66
+ path(
67
+ "filter-expression/test/",
68
+ views.IPFabricFilterExpressionTestView.as_view(),
69
+ name="ipfabricfilterexpression_test_no_pk",
70
+ ),
71
+ path(
72
+ "filter-expression/<int:pk>/",
73
+ include(get_model_urls("ipfabric_netbox", "ipfabricfilterexpression")),
74
+ ),
75
+ # Endpoint
76
+ path(
77
+ "endpoint/",
78
+ include(get_model_urls("ipfabric_netbox", "ipfabricendpoint", detail=False)),
79
+ ),
80
+ path(
81
+ "endpoint/<int:pk>/",
82
+ include(get_model_urls("ipfabric_netbox", "ipfabricendpoint")),
83
+ ),
49
84
  # Transform Map Group
50
85
  path(
51
86
  "transform-map-group/",
@@ -0,0 +1,30 @@
1
+ import importlib.resources
2
+ import json
3
+
4
+ from netbox.settings import django_apps
5
+
6
+
7
+ # region Endpoint Creation
8
+
9
+ # These functions are used in the migration file to prepare the endpoints
10
+ # Because of this we have to use historical models
11
+ # see https://docs.djangoproject.com/en/5.1/topics/migrations/#historical-models
12
+
13
+
14
+ def build_endpoints(data, apps: django_apps = None, db_alias: str = "default") -> None:
15
+ apps = apps or django_apps
16
+ IPFabricEndpoint = apps.get_model("ipfabric_netbox", "IPFabricEndpoint")
17
+ for endpoint_data in data:
18
+ IPFabricEndpoint.objects.using(db_alias).create(**endpoint_data)
19
+
20
+
21
+ def get_endpoint_data() -> dict:
22
+ for data_file in importlib.resources.files("ipfabric_netbox.data").iterdir():
23
+ if data_file.name != "endpoint.json":
24
+ continue
25
+ with open(data_file, "rb") as data_file:
26
+ return json.load(data_file)
27
+ raise FileNotFoundError("'endpoint.json' not found in installed package")
28
+
29
+
30
+ # endregion Endpoint Creation
@@ -0,0 +1,88 @@
1
+ import importlib.resources
2
+ import json
3
+
4
+ from netbox.settings import django_apps
5
+
6
+ from ..choices import IPFabricSourceTypeChoices
7
+
8
+ # region Filter Expression
9
+
10
+
11
+ def get_filter_expression_test_candidates(expression_instance):
12
+ """
13
+ Get potential LOCAL sources and endpoints from filters associated with a filter expression.
14
+
15
+ Args:
16
+ expression_instance: An IPFabricFilterExpression instance
17
+
18
+ Returns:
19
+ tuple: (sources_set, endpoints_set) - Sets of IPFabricSource and IPFabricEndpoint objects
20
+ """
21
+ if not expression_instance or not expression_instance.pk:
22
+ return set(), set()
23
+
24
+ sources = set()
25
+ endpoints = set()
26
+
27
+ # Query all filters that use this expression
28
+ for filter_obj in expression_instance.filters.all():
29
+ # Get LOCAL sources from syncs
30
+ for sync in filter_obj.syncs.all():
31
+ if (
32
+ sync.snapshot_data
33
+ and sync.snapshot_data.source
34
+ and sync.snapshot_data.source.type == IPFabricSourceTypeChoices.LOCAL
35
+ ):
36
+ sources.add(sync.snapshot_data.source)
37
+
38
+ # Get endpoints
39
+ for endpoint in filter_obj.endpoints.all():
40
+ endpoints.add(endpoint)
41
+
42
+ return sources, endpoints
43
+
44
+
45
+ # endregion Filter Expression
46
+
47
+
48
+ # region Filter Creation
49
+
50
+ # These functions are used in the migration file to prepare the filters
51
+ # Because of this we have to use historical models
52
+ # see https://docs.djangoproject.com/en/5.1/topics/migrations/#historical-models
53
+
54
+
55
+ def build_filters(data, apps: django_apps = None, db_alias: str = "default") -> None:
56
+ apps = apps or django_apps
57
+ IPFabricEndpoint = apps.get_model("ipfabric_netbox", "IPFabricEndpoint")
58
+ IPFabricFilter = apps.get_model("ipfabric_netbox", "IPFabricFilter")
59
+ IPFabricFilterExpression = apps.get_model(
60
+ "ipfabric_netbox", "IPFabricFilterExpression"
61
+ )
62
+ for expressions_data in data["expressions"]:
63
+ IPFabricFilterExpression.objects.using(db_alias).create(**expressions_data)
64
+ for filter_data in data["filters"]:
65
+ filter_data["filter_type"] = "and"
66
+ endpoints = [
67
+ IPFabricEndpoint.objects.filter(endpoint=endpoint).first()
68
+ for endpoint in filter_data.pop("endpoints", [])
69
+ ]
70
+ expressions = [
71
+ IPFabricFilterExpression.objects.filter(name=expr).first()
72
+ for expr in filter_data.pop("expressions", [])
73
+ ]
74
+ _filter = IPFabricFilter.objects.using(db_alias).create(**filter_data)
75
+ _filter.endpoints.set(endpoints)
76
+ _filter.expressions.set(expressions)
77
+
78
+
79
+ def get_filter_data() -> dict:
80
+ for data_file in importlib.resources.files("ipfabric_netbox.data").iterdir():
81
+ if data_file.name != "filters.json":
82
+ continue
83
+ with open(data_file, "rb") as data_file:
84
+ return json.load(data_file)
85
+ raise FileNotFoundError("'filters.json' not found in installed package")
86
+
87
+
88
+ # endregion Filter Creation