ipfabric_netbox 4.2.0b8__tar.gz → 4.2.1__tar.gz

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.

Potentially problematic release.


This version of ipfabric_netbox might be problematic. Click here for more details.

Files changed (89) hide show
  1. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/PKG-INFO +6 -6
  2. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/__init__.py +1 -1
  3. ipfabric_netbox-4.2.1/ipfabric_netbox/api/__init__.py +2 -0
  4. ipfabric_netbox-4.2.1/ipfabric_netbox/api/nested_serializers.py +78 -0
  5. ipfabric_netbox-4.2.1/ipfabric_netbox/api/serializers.py +189 -0
  6. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/api/urls.py +4 -4
  7. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/api/views.py +19 -18
  8. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/choices.py +12 -0
  9. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/filtersets.py +4 -67
  10. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/forms.py +13 -13
  11. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/models.py +10 -10
  12. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/tables.py +9 -30
  13. ipfabric_netbox-4.2.1/ipfabric_netbox/template_content.py +30 -0
  14. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/templates/ipfabric_netbox/inc/site_topology_button.html +10 -3
  15. ipfabric_netbox-4.2.1/ipfabric_netbox/templates/ipfabric_netbox/ipfabricsync_list.html +71 -0
  16. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/tests/test_models.py +11 -47
  17. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/utilities/ipfutils.py +23 -43
  18. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/views.py +8 -6
  19. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/pyproject.toml +6 -6
  20. ipfabric_netbox-4.2.0b8/ipfabric_netbox/api/__init__.py +0 -1
  21. ipfabric_netbox-4.2.0b8/ipfabric_netbox/api/serializers.py +0 -246
  22. ipfabric_netbox-4.2.0b8/ipfabric_netbox/graphql/__init__.py +0 -23
  23. ipfabric_netbox-4.2.0b8/ipfabric_netbox/graphql/enums.py +0 -35
  24. ipfabric_netbox-4.2.0b8/ipfabric_netbox/graphql/filters.py +0 -317
  25. ipfabric_netbox-4.2.0b8/ipfabric_netbox/graphql/schema.py +0 -101
  26. ipfabric_netbox-4.2.0b8/ipfabric_netbox/graphql/types.py +0 -216
  27. ipfabric_netbox-4.2.0b8/ipfabric_netbox/migrations/0016_tags_and_changelog_for_snapshots.py +0 -31
  28. ipfabric_netbox-4.2.0b8/ipfabric_netbox/migrations/0017_ipfabricsync_update_custom_fields.py +0 -17
  29. ipfabric_netbox-4.2.0b8/ipfabric_netbox/migrations/0018_remove_type_field.py +0 -17
  30. ipfabric_netbox-4.2.0b8/ipfabric_netbox/template_content.py +0 -13
  31. ipfabric_netbox-4.2.0b8/ipfabric_netbox/tests/api/test_api.py +0 -879
  32. ipfabric_netbox-4.2.0b8/ipfabric_netbox/utilities/__init__.py +0 -0
  33. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/README.md +0 -0
  34. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/data/transform_map.json +0 -0
  35. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/exceptions.py +0 -0
  36. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/jobs.py +0 -0
  37. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/migrations/0001_initial.py +0 -0
  38. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/migrations/0001_initial_squashed_0013_switch_to_branching_plugin.py +0 -0
  39. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/migrations/0002_ipfabricsnapshot_status.py +0 -0
  40. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/migrations/0003_ipfabricsource_type_and_more.py +0 -0
  41. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/migrations/0004_ipfabricsync_auto_merge.py +0 -0
  42. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/migrations/0005_alter_ipfabricrelationshipfield_source_model_and_more.py +0 -0
  43. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/migrations/0006_alter_ipfabrictransformmap_target_model.py +0 -0
  44. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/migrations/0007_prepare_custom_fields.py +0 -0
  45. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/migrations/0008_prepare_transform_maps.py +0 -0
  46. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/migrations/0009_transformmap_changes_for_netbox_v4_2.py +0 -0
  47. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/migrations/0010_remove_uuid_from_get_or_create.py +0 -0
  48. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/migrations/0011_update_part_number_DCIM_inventory_item_template.py +0 -0
  49. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/migrations/0012_remove_status_field.py +0 -0
  50. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/migrations/0013_switch_to_branching_plugin.py +0 -0
  51. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/migrations/0014_ipfabrictransformmapgroup_ipfabrictransformmap_group.py +0 -0
  52. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/migrations/0015_ipfabricingestionissue.py +0 -0
  53. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/migrations/__init__.py +0 -0
  54. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/navigation.py +0 -0
  55. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/signals.py +0 -0
  56. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/templates/ipfabric_netbox/inc/clone_form.html +0 -0
  57. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/templates/ipfabric_netbox/inc/diff.html +0 -0
  58. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/templates/ipfabric_netbox/inc/json.html +0 -0
  59. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/templates/ipfabric_netbox/inc/logs_pending.html +0 -0
  60. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/templates/ipfabric_netbox/inc/merge_form.html +0 -0
  61. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/templates/ipfabric_netbox/inc/site_topology_modal.html +0 -0
  62. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/templates/ipfabric_netbox/inc/snapshotdata.html +0 -0
  63. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/templates/ipfabric_netbox/inc/transform_map_field_map.html +0 -0
  64. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/templates/ipfabric_netbox/inc/transform_map_relationship_map.html +0 -0
  65. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/templates/ipfabric_netbox/ipfabric_table.html +0 -0
  66. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/templates/ipfabric_netbox/ipfabricingestion.html +0 -0
  67. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/templates/ipfabric_netbox/ipfabricsnapshot.html +0 -0
  68. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/templates/ipfabric_netbox/ipfabricsource.html +0 -0
  69. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/templates/ipfabric_netbox/ipfabricsync.html +0 -0
  70. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/templates/ipfabric_netbox/ipfabrictransformmap.html +0 -0
  71. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/templates/ipfabric_netbox/ipfabrictransformmap_list.html +0 -0
  72. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/templates/ipfabric_netbox/ipfabrictransformmap_restore.html +0 -0
  73. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/templates/ipfabric_netbox/ipfabrictransformmapgroup.html +0 -0
  74. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/templates/ipfabric_netbox/partials/ingestion_all.html +0 -0
  75. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/templates/ipfabric_netbox/partials/ingestion_progress.html +0 -0
  76. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/templates/ipfabric_netbox/partials/ingestion_statistics.html +0 -0
  77. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/templates/ipfabric_netbox/partials/ingestion_status.html +0 -0
  78. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/templates/ipfabric_netbox/partials/job_logs.html +0 -0
  79. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/templates/ipfabric_netbox/partials/object_tabs.html +0 -0
  80. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/templates/ipfabric_netbox/partials/sync_last_ingestion.html +0 -0
  81. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/templates/static/ipfabric_netbox/css/rack.css +0 -0
  82. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/templatetags/__init__.py +0 -0
  83. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/templatetags/ipfabric_netbox_helpers.py +0 -0
  84. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/tests/__init__.py +0 -0
  85. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/urls.py +0 -0
  86. {ipfabric_netbox-4.2.0b8/ipfabric_netbox/tests/api → ipfabric_netbox-4.2.1/ipfabric_netbox/utilities}/__init__.py +0 -0
  87. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/utilities/logging.py +0 -0
  88. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/utilities/nbutils.py +0 -0
  89. {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.1}/ipfabric_netbox/utilities/transform_map.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: ipfabric_netbox
3
- Version: 4.2.0b8
3
+ Version: 4.2.1
4
4
  Summary: NetBox plugin to sync IP Fabric data into NetBox
5
5
  License: MIT
6
6
  Keywords: netbox,ipfabric,plugin,sync
@@ -18,11 +18,11 @@ Provides-Extra: ipfabric-6-10
18
18
  Provides-Extra: ipfabric-7-0
19
19
  Provides-Extra: ipfabric-7-2
20
20
  Provides-Extra: ipfabric-7-3
21
- Requires-Dist: ipfabric (>=6.10.0,<6.11.0) ; extra == "ipfabric_6_10" and extra != "ipfabric_7_0" and extra != "ipfabric_7_2" and extra != "ipfabric_7_3"
22
- Requires-Dist: ipfabric (>=6.6.4) ; extra != "ipfabric_6_10" and extra != "ipfabric_7_0" and extra != "ipfabric_7_2" and extra != "ipfabric_7_3"
23
- Requires-Dist: ipfabric (>=7.0.0,<7.1.0) ; extra != "ipfabric_6_10" and extra == "ipfabric_7_0" and extra != "ipfabric_7_2" and extra != "ipfabric_7_3"
24
- Requires-Dist: ipfabric (>=7.2.0,<7.3.0) ; extra != "ipfabric_6_10" and extra != "ipfabric_7_0" and extra == "ipfabric_7_2" and extra != "ipfabric_7_3"
25
- Requires-Dist: ipfabric (>=7.3.0,<7.4.0) ; extra != "ipfabric_6_10" and extra != "ipfabric_7_0" and extra != "ipfabric_7_2" and extra == "ipfabric_7_3"
21
+ Requires-Dist: ipfabric (>=6.10.0,<6.11.0) ; extra == "ipfabric_6_10" and extra != "ipfabric_7_0" and extra != "ipfabric_7_2"
22
+ Requires-Dist: ipfabric (>=6.6.4) ; extra != "ipfabric_6_10" and extra != "ipfabric_7_0" and extra != "ipfabric_7_2"
23
+ Requires-Dist: ipfabric (>=7.0.0,<7.1.0) ; extra != "ipfabric_6_10" and extra == "ipfabric_7_0" and extra != "ipfabric_7_2"
24
+ Requires-Dist: ipfabric (>=7.2.0,<7.3.0) ; extra == "ipfabric-6-10" or extra == "ipfabric-7-0" or extra == "ipfabric-7-2" or extra == "ipfabric-7-3"
25
+ Requires-Dist: ipfabric (>=7.3.0,<7.4.0) ; extra == "ipfabric-6-10" or extra == "ipfabric-7-0" or extra == "ipfabric-7-2" or extra == "ipfabric-7-3"
26
26
  Requires-Dist: netboxlabs-netbox-branching (>=0.5.5,<0.6.0)
27
27
  Requires-Dist: netutils
28
28
  Project-URL: Bug Tracker, https://gitlab.com/ip-fabric/integrations/ipfabric-netbox-sync/-/issues
@@ -6,7 +6,7 @@ class NetboxIPFabricConfig(PluginConfig):
6
6
  name = "ipfabric_netbox"
7
7
  verbose_name = "NetBox IP Fabric SoT Plugin"
8
8
  description = "Sync IP Fabric into NetBox"
9
- version = "4.2.0b8"
9
+ version = "4.2.1"
10
10
  base_url = "ipfabric"
11
11
  min_version = "4.2.4"
12
12
 
@@ -0,0 +1,2 @@
1
+ from .nested_serializers import * # noqa: F401, F403
2
+ from .serializers import * # noqa: F401, F403
@@ -0,0 +1,78 @@
1
+ from drf_spectacular.types import OpenApiTypes
2
+ from drf_spectacular.utils import extend_schema_field
3
+ from netbox.api.fields import ContentTypeField
4
+ from netbox.api.serializers import NetBoxModelSerializer
5
+ from netbox.api.serializers import WritableNestedSerializer
6
+ from rest_framework import serializers
7
+
8
+ from ipfabric_netbox.models import IPFabricSnapshot
9
+ from ipfabric_netbox.models import IPFabricSource
10
+ from ipfabric_netbox.models import IPFabricSync
11
+ from ipfabric_netbox.models import IPFabricTransformMap
12
+
13
+
14
+ __all__ = (
15
+ "NestedIPFabricSourceSerializer",
16
+ "NestedIPFabricSnapshotSerializer",
17
+ "NestedIPFabricTransformMapSerializer",
18
+ "NestedIPFabricSyncSerializer",
19
+ )
20
+
21
+
22
+ class NestedIPFabricSourceSerializer(WritableNestedSerializer):
23
+ url = serializers.URLField()
24
+
25
+ class Meta:
26
+ model = IPFabricSource
27
+ fields = ["id", "url", "display", "name", "type"]
28
+
29
+
30
+ class NestedIPFabricSnapshotSerializer(NetBoxModelSerializer):
31
+ source = NestedIPFabricSourceSerializer(read_only=True)
32
+ display = serializers.SerializerMethodField(read_only=True)
33
+
34
+ class Meta:
35
+ model = IPFabricSnapshot
36
+ fields = [
37
+ "id",
38
+ "name",
39
+ "source",
40
+ "snapshot_id",
41
+ "status",
42
+ "date",
43
+ "display",
44
+ "sites",
45
+ ]
46
+
47
+ @extend_schema_field(OpenApiTypes.STR)
48
+ def get_display(self, obj):
49
+ return f"{obj.name} ({obj.snapshot_id})"
50
+
51
+
52
+ class NestedIPFabricSyncSerializer(NetBoxModelSerializer):
53
+ snapshot_data = NestedIPFabricSnapshotSerializer(read_only=True)
54
+
55
+ class Meta:
56
+ model = IPFabricSync
57
+ fields = [
58
+ "id",
59
+ "name",
60
+ "display",
61
+ "snapshot_data",
62
+ "type",
63
+ "status",
64
+ "parameters",
65
+ "last_synced",
66
+ ]
67
+
68
+
69
+ class NestedIPFabricTransformMapSerializer(NetBoxModelSerializer):
70
+ target_model = ContentTypeField(read_only=True)
71
+
72
+ class Meta:
73
+ model = IPFabricTransformMap
74
+ fields = [
75
+ "id",
76
+ "source_model",
77
+ "target_model",
78
+ ]
@@ -0,0 +1,189 @@
1
+ from core.choices import DataSourceStatusChoices
2
+ from netbox.api.fields import ChoiceField
3
+ from netbox.api.fields import ContentTypeField
4
+ from netbox.api.serializers import NetBoxModelSerializer
5
+ from netbox_branching.api.serializers import BranchSerializer
6
+ from rest_framework import serializers
7
+
8
+ from .nested_serializers import NestedIPFabricSnapshotSerializer
9
+ from .nested_serializers import NestedIPFabricSourceSerializer
10
+ from .nested_serializers import NestedIPFabricSyncSerializer
11
+ from .nested_serializers import NestedIPFabricTransformMapSerializer
12
+ from ipfabric_netbox.models import IPFabricIngestion
13
+ from ipfabric_netbox.models import IPFabricIngestionIssue
14
+ from ipfabric_netbox.models import IPFabricRelationshipField
15
+ from ipfabric_netbox.models import IPFabricSnapshot
16
+ from ipfabric_netbox.models import IPFabricSource
17
+ from ipfabric_netbox.models import IPFabricSync
18
+ from ipfabric_netbox.models import IPFabricTransformField
19
+ from ipfabric_netbox.models import IPFabricTransformMap
20
+ from ipfabric_netbox.models import IPFabricTransformMapGroup
21
+
22
+ __all__ = (
23
+ "IPFabricSyncSerializer",
24
+ "IPFabricSnapshotSerializer",
25
+ "IPFabricRelationshipFieldSerializer",
26
+ "IPFabricTransformFieldSerializer",
27
+ "IPFabricTransformMapSerializer",
28
+ "IPFabricTransformMapGroupSerializer",
29
+ "IPFabricIngestionSerializer",
30
+ "IPFabricIngestionIssueSerializer",
31
+ "IPFabricSourceSerializer",
32
+ )
33
+
34
+
35
+ class IPFabricSyncSerializer(NetBoxModelSerializer):
36
+ snapshot_data = NestedIPFabricSnapshotSerializer(read_only=True)
37
+
38
+ class Meta:
39
+ model = IPFabricSync
40
+ fields = [
41
+ "id",
42
+ "name",
43
+ "display",
44
+ "snapshot_data",
45
+ "type",
46
+ "status",
47
+ "parameters",
48
+ "last_synced",
49
+ "created",
50
+ "last_updated",
51
+ ]
52
+
53
+
54
+ class IPFabricSnapshotSerializer(NetBoxModelSerializer):
55
+ source = NestedIPFabricSourceSerializer()
56
+ data = serializers.JSONField()
57
+ date = serializers.DateTimeField()
58
+ last_updated = serializers.DateTimeField()
59
+
60
+ class Meta:
61
+ model = IPFabricSnapshot
62
+ fields = [
63
+ "id",
64
+ "name",
65
+ "source",
66
+ "snapshot_id",
67
+ "status",
68
+ "date",
69
+ "display",
70
+ "sites",
71
+ "data",
72
+ "created",
73
+ "last_updated",
74
+ ]
75
+
76
+ extra_kwargs = {
77
+ "raw_data": {"write_only": True},
78
+ }
79
+
80
+
81
+ class IPFabricRelationshipFieldSerializer(NetBoxModelSerializer):
82
+ transform_map = NestedIPFabricTransformMapSerializer(read_only=True)
83
+ source_model = ContentTypeField(read_only=True)
84
+
85
+ class Meta:
86
+ model = IPFabricRelationshipField
87
+ fields = [
88
+ "id",
89
+ "transform_map",
90
+ "source_model",
91
+ "target_field",
92
+ "coalesce",
93
+ "template",
94
+ ]
95
+
96
+
97
+ class IPFabricTransformMapGroupSerializer(NetBoxModelSerializer):
98
+ class Meta:
99
+ model = IPFabricTransformMapGroup
100
+ fields = [
101
+ "name",
102
+ "description",
103
+ "transform_maps",
104
+ "created",
105
+ "last_updated",
106
+ ]
107
+
108
+
109
+ class IPFabricTransformMapSerializer(NetBoxModelSerializer):
110
+ target_model = ContentTypeField(read_only=True)
111
+
112
+ class Meta:
113
+ model = IPFabricTransformMap
114
+ fields = [
115
+ "id",
116
+ "source_model",
117
+ "target_model",
118
+ "created",
119
+ "last_updated",
120
+ ]
121
+
122
+
123
+ class IPFabricTransformFieldSerializer(NetBoxModelSerializer):
124
+ transform_map = NestedIPFabricTransformMapSerializer(read_only=True)
125
+
126
+ class Meta:
127
+ model = IPFabricTransformField
128
+ fields = [
129
+ "id",
130
+ "transform_map",
131
+ "source_field",
132
+ "target_field",
133
+ "coalesce",
134
+ "template",
135
+ ]
136
+
137
+
138
+ class IPFabricIngestionSerializer(NetBoxModelSerializer):
139
+ branch = BranchSerializer(read_only=True)
140
+ sync = NestedIPFabricSyncSerializer(read_only=True)
141
+
142
+ class Meta:
143
+ model = IPFabricIngestion
144
+ fields = [
145
+ "id",
146
+ "name",
147
+ "branch",
148
+ "sync",
149
+ ]
150
+
151
+
152
+ class IPFabricIngestionIssueSerializer(NetBoxModelSerializer):
153
+ ingestion = IPFabricIngestionSerializer(read_only=True)
154
+
155
+ class Meta:
156
+ model = IPFabricIngestionIssue
157
+ fields = [
158
+ "id",
159
+ "ingestion",
160
+ "timestamp",
161
+ "model",
162
+ "message",
163
+ "raw_data",
164
+ "coalesce_fields",
165
+ "defaults",
166
+ "exception",
167
+ ]
168
+
169
+
170
+ class IPFabricSourceSerializer(NetBoxModelSerializer):
171
+ status = ChoiceField(choices=DataSourceStatusChoices)
172
+ url = serializers.URLField()
173
+
174
+ class Meta:
175
+ model = IPFabricSource
176
+ fields = [
177
+ "id",
178
+ "url",
179
+ "display",
180
+ "name",
181
+ "type",
182
+ "status",
183
+ "last_synced",
184
+ "description",
185
+ "comments",
186
+ "parameters",
187
+ "created",
188
+ "last_updated",
189
+ ]
@@ -3,11 +3,11 @@ from netbox.api.routers import NetBoxRouter
3
3
 
4
4
  from ipfabric_netbox.api.views import IPFabricIngestionIssueViewSet
5
5
  from ipfabric_netbox.api.views import IPFabricIngestionViewSet
6
- from ipfabric_netbox.api.views import IPFabricRelationshipFieldViewSet
6
+ from ipfabric_netbox.api.views import IPFabricRelationshipFieldiewSet
7
7
  from ipfabric_netbox.api.views import IPFabricSnapshotViewSet
8
8
  from ipfabric_netbox.api.views import IPFabricSourceViewSet
9
9
  from ipfabric_netbox.api.views import IPFabricSyncViewSet
10
- from ipfabric_netbox.api.views import IPFabricTransformFieldViewSet
10
+ from ipfabric_netbox.api.views import IPFabricTransformFieldiewSet
11
11
  from ipfabric_netbox.api.views import IPFabricTransformMapGroupViewSet
12
12
  from ipfabric_netbox.api.views import IPFabricTransformMapViewSet
13
13
 
@@ -20,6 +20,6 @@ router.register("transform-map", IPFabricTransformMapViewSet)
20
20
  router.register("sync", IPFabricSyncViewSet)
21
21
  router.register("ingestion", IPFabricIngestionViewSet)
22
22
  router.register("ingestion-issues", IPFabricIngestionIssueViewSet)
23
- router.register("transform-field", IPFabricTransformFieldViewSet)
24
- router.register("relationship-field", IPFabricRelationshipFieldViewSet)
23
+ router.register("transform-field", IPFabricTransformFieldiewSet)
24
+ router.register("relationship-field", IPFabricRelationshipFieldiewSet)
25
25
  urlpatterns = router.urls
@@ -14,7 +14,6 @@ from .serializers import IPFabricSyncSerializer
14
14
  from .serializers import IPFabricTransformFieldSerializer
15
15
  from .serializers import IPFabricTransformMapGroupSerializer
16
16
  from .serializers import IPFabricTransformMapSerializer
17
- from ipfabric_netbox.filtersets import IPFabricRelationshipFieldFilterSet
18
17
  from ipfabric_netbox.filtersets import IPFabricSnapshotFilterSet
19
18
  from ipfabric_netbox.filtersets import IPFabricSourceFilterSet
20
19
  from ipfabric_netbox.filtersets import IPFabricTransformFieldFilterSet
@@ -30,29 +29,29 @@ from ipfabric_netbox.models import IPFabricTransformMap
30
29
  from ipfabric_netbox.models import IPFabricTransformMapGroup
31
30
 
32
31
 
33
- class IPFabricTransformMapGroupViewSet(NetBoxModelViewSet):
32
+ class IPFabricTransformMapGroupViewSet(NetBoxReadOnlyModelViewSet):
34
33
  queryset = IPFabricTransformMapGroup.objects.all()
35
34
  serializer_class = IPFabricTransformMapGroupSerializer
36
35
 
37
36
 
38
- class IPFabricTransformMapViewSet(NetBoxModelViewSet):
37
+ class IPFabricTransformMapViewSet(NetBoxReadOnlyModelViewSet):
39
38
  queryset = IPFabricTransformMap.objects.all()
40
39
  serializer_class = IPFabricTransformMapSerializer
41
40
 
42
41
 
43
- class IPFabricTransformFieldViewSet(NetBoxModelViewSet):
42
+ class IPFabricTransformFieldiewSet(NetBoxReadOnlyModelViewSet):
44
43
  queryset = IPFabricTransformField.objects.all()
45
44
  serializer_class = IPFabricTransformFieldSerializer
46
45
  filterset_class = IPFabricTransformFieldFilterSet
47
46
 
48
47
 
49
- class IPFabricRelationshipFieldViewSet(NetBoxModelViewSet):
48
+ class IPFabricRelationshipFieldiewSet(NetBoxReadOnlyModelViewSet):
50
49
  queryset = IPFabricRelationshipField.objects.all()
51
50
  serializer_class = IPFabricRelationshipFieldSerializer
52
- filterset_class = IPFabricRelationshipFieldFilterSet
51
+ filterset_class = IPFabricTransformFieldFilterSet
53
52
 
54
53
 
55
- class IPFabricSyncViewSet(NetBoxModelViewSet):
54
+ class IPFabricSyncViewSet(NetBoxReadOnlyModelViewSet):
56
55
  queryset = IPFabricSync.objects.all()
57
56
  serializer_class = IPFabricSyncSerializer
58
57
 
@@ -67,7 +66,7 @@ class IPFabricIngestionIssueViewSet(NetBoxReadOnlyModelViewSet):
67
66
  serializer_class = IPFabricIngestionIssueSerializer
68
67
 
69
68
 
70
- class IPFabricSnapshotViewSet(NetBoxReadOnlyModelViewSet):
69
+ class IPFabricSnapshotViewSet(NetBoxModelViewSet):
71
70
  queryset = IPFabricSnapshot.objects.all()
72
71
  serializer_class = IPFabricSnapshotSerializer
73
72
  filterset_class = IPFabricSnapshotFilterSet
@@ -80,21 +79,24 @@ class IPFabricSnapshotViewSet(NetBoxReadOnlyModelViewSet):
80
79
  raw_data._raw_delete(raw_data.db)
81
80
  return Response({"status": "success"})
82
81
  elif request.method == "PATCH":
83
- with transaction.atomic():
84
- IPFabricData.objects.bulk_create(
85
- [
86
- IPFabricData(snapshot_data=snapshot, data=item["data"])
87
- for item in request.data["data"]
88
- ],
89
- batch_size=5000,
90
- )
82
+ transaction.set_autocommit(False)
83
+ IPFabricData.objects.bulk_create(
84
+ [
85
+ IPFabricData(
86
+ snapshot_data=snapshot, data=item["data"], type=item["type"]
87
+ )
88
+ for item in request.data["data"]
89
+ ],
90
+ batch_size=5000,
91
+ )
92
+ transaction.commit()
91
93
  return Response({"status": "success"})
92
94
 
93
95
  @action(detail=True, methods=["get"], url_path="sites")
94
96
  def sites(self, request, pk):
95
97
  q = request.GET.get("q", None)
96
98
  snapshot = IPFabricSnapshot.objects.get(pk=pk)
97
- new_sites = {"count": 0, "results": []}
99
+ new_sites = {"results": []}
98
100
  if snapshot.data:
99
101
  sites = snapshot.data.get("sites", None)
100
102
  num = 0
@@ -110,7 +112,6 @@ class IPFabricSnapshotViewSet(NetBoxReadOnlyModelViewSet):
110
112
  {"display": site, "name": site, "id": site}
111
113
  )
112
114
  num += 1
113
- new_sites["count"] = num
114
115
  return Response(new_sites)
115
116
  else:
116
117
  return Response([])
@@ -198,6 +198,18 @@ class IPFabricSnapshotStatusModelChoices(ChoiceSet):
198
198
  ]
199
199
 
200
200
 
201
+ class IPFabricSyncTypeChoices(ChoiceSet):
202
+ ALL = "all"
203
+ DCIM = "dcim"
204
+ IPAM = "ipam"
205
+
206
+ CHOICES = (
207
+ (ALL, _("All"), "gray"),
208
+ (DCIM, _("DCIM"), "blue"),
209
+ (IPAM, _("IPAM"), "blue"),
210
+ )
211
+
212
+
201
213
  class IPFabricSourceTypeChoices(ChoiceSet):
202
214
  LOCAL = "local"
203
215
  REMOTE = "remote"
@@ -11,11 +11,9 @@ from netbox_branching.models import ChangeDiff
11
11
  from .models import IPFabricData
12
12
  from .models import IPFabricIngestion
13
13
  from .models import IPFabricIngestionIssue
14
- from .models import IPFabricRelationshipField
15
14
  from .models import IPFabricSnapshot
16
15
  from .models import IPFabricSource
17
16
  from .models import IPFabricSync
18
- from .models import IPFabricTransformField
19
17
  from .models import IPFabricTransformMap
20
18
  from .models import IPFabricTransformMapGroup
21
19
 
@@ -74,12 +72,14 @@ class IPFabricDataFilterSet(BaseFilterSet):
74
72
 
75
73
  class Meta:
76
74
  model = IPFabricData
77
- fields = ["snapshot_data"]
75
+ fields = ["snapshot_data", "type"]
78
76
 
79
77
  def search(self, queryset, name, value):
80
78
  if not value.strip():
81
79
  return queryset
82
- return queryset.filter(Q(snapshot_data__icontains=value))
80
+ return queryset.filter(
81
+ Q(snapshot_data__icontains=value) | Q(type__icontains=value)
82
+ )
83
83
 
84
84
 
85
85
  class IPFabricSnapshotFilterSet(ChangeLoggedModelFilterSet):
@@ -193,66 +193,3 @@ class IPFabricTransformFieldFilterSet(BaseFilterSet):
193
193
  transform_map = django_filters.ModelMultipleChoiceFilter(
194
194
  queryset=IPFabricTransformMap.objects.all(), label=_("Transform Map")
195
195
  )
196
-
197
- class Meta:
198
- model = IPFabricTransformField
199
- fields = (
200
- "id",
201
- "transform_map",
202
- "source_field",
203
- "target_field",
204
- "coalesce",
205
- "template",
206
- )
207
-
208
-
209
- class IPFabricRelationshipFieldFilterSet(BaseFilterSet):
210
- transform_map = django_filters.ModelMultipleChoiceFilter(
211
- queryset=IPFabricTransformMap.objects.all(), label=_("Transform Map")
212
- )
213
-
214
- class Meta:
215
- model = IPFabricRelationshipField
216
- fields = (
217
- "id",
218
- "transform_map",
219
- "source_model",
220
- "target_field",
221
- "coalesce",
222
- "template",
223
- )
224
-
225
-
226
- class IPFabricSyncFilterSet(ChangeLoggedModelFilterSet):
227
- q = django_filters.CharFilter(method="search")
228
- snapshot_data_id = django_filters.ModelMultipleChoiceFilter(
229
- queryset=IPFabricSnapshot.objects.all(),
230
- label=_("Snapshot (ID)"),
231
- )
232
- snapshot_data = django_filters.ModelMultipleChoiceFilter(
233
- field_name="snapshot_data__name",
234
- queryset=IPFabricSnapshot.objects.all(),
235
- to_field_name="name",
236
- label=_("Snapshot (name)"),
237
- )
238
-
239
- class Meta:
240
- model = IPFabricSync
241
- fields = (
242
- "id",
243
- "name",
244
- "snapshot_data",
245
- "snapshot_data_id",
246
- "status",
247
- "auto_merge",
248
- "last_synced",
249
- "scheduled",
250
- "interval",
251
- )
252
-
253
- def search(self, queryset, name, value):
254
- if not value.strip():
255
- return queryset
256
- return queryset.filter(
257
- Q(name__icontains=value) | Q(snapshot_data__name__icontains=value)
258
- )
@@ -488,18 +488,11 @@ class IPFabricSyncForm(NetBoxModelForm):
488
488
  sites = forms.MultipleChoiceField(
489
489
  required=False,
490
490
  label=_("Sites"),
491
- help_text=_("Defaults to all sites if none selected."),
492
491
  widget=APISelectMultiple(
493
492
  api_url="/api/plugins/ipfabric/snapshot/{{snapshot_data}}/sites/",
494
493
  ),
495
494
  )
496
495
 
497
- update_custom_fields = forms.BooleanField(
498
- required=False,
499
- label=_("Custom Fields Updating"),
500
- help_text=_("Update object custom fields where applicable."),
501
- )
502
-
503
496
  scheduled = forms.DateTimeField(
504
497
  required=False,
505
498
  widget=DateTimePicker(),
@@ -526,13 +519,16 @@ class IPFabricSyncForm(NetBoxModelForm):
526
519
  "source",
527
520
  "snapshot_data",
528
521
  "auto_merge",
529
- "update_custom_fields",
530
522
  "sites",
523
+ "type",
531
524
  "tags",
532
525
  "scheduled",
533
526
  "interval",
534
527
  )
535
- widgets = {"source": HTMXSelect()}
528
+ widgets = {
529
+ "source": HTMXSelect(),
530
+ "type": HTMXSelect(),
531
+ }
536
532
 
537
533
  @property
538
534
  def fieldsets(self):
@@ -547,15 +543,14 @@ class IPFabricSyncForm(NetBoxModelForm):
547
543
  fieldsets.append(
548
544
  FieldSet("snapshot_data", name=_("Snapshot Information")),
549
545
  )
546
+ fieldsets.append(FieldSet("type", name=_("Ingestion Type")))
550
547
  if self.backend_fields:
551
548
  for k, v in self.backend_fields.items():
552
549
  fieldsets.append(FieldSet(*v, name=f"{k.upper()} Parameters"))
553
550
  fieldsets.append(
554
551
  FieldSet("scheduled", "interval", name=_("Ingestion Execution Parameters"))
555
552
  )
556
- fieldsets.append(
557
- FieldSet("auto_merge", "update_custom_fields", name=_("Extras"))
558
- )
553
+ fieldsets.append(FieldSet("auto_merge", name=_("Extras")))
559
554
  fieldsets.append(FieldSet("tags", name=_("Tags")))
560
555
 
561
556
  return fieldsets
@@ -590,7 +585,12 @@ class IPFabricSyncForm(NetBoxModelForm):
590
585
  self.initial["sites"] = self.instance.parameters.get("sites", [])
591
586
  self.initial["groups"] = self.instance.parameters.get("groups", [])
592
587
 
593
- backend = sync_parameters
588
+ backend_type = get_field_value(self, "type")
589
+ backend = {}
590
+ if backend_type == "all":
591
+ backend = sync_parameters
592
+ else:
593
+ backend[backend_type] = sync_parameters.get(backend_type)
594
594
 
595
595
  now = local_now().strftime("%Y-%m-%d %H:%M:%S")
596
596
  self.fields["scheduled"].help_text += f" (current time: <strong>{now}</strong>)"
@@ -44,6 +44,7 @@ from utilities.request import NetBoxFakeRequest
44
44
  from .choices import IPFabricRawDataTypeChoices
45
45
  from .choices import IPFabricSnapshotStatusModelChoices
46
46
  from .choices import IPFabricSourceTypeChoices
47
+ from .choices import IPFabricSyncTypeChoices
47
48
  from .choices import IPFabricTransformMapSourceModelChoices
48
49
  from .choices import required_transform_map_contenttypes
49
50
  from .signals import clear_other_primary_ip
@@ -544,7 +545,9 @@ class IPFabricSource(IPFabricClient, JobsMixin, PrimaryModel):
544
545
  # post_sync.send(sender=self.__class__, instance=self)
545
546
 
546
547
 
547
- class IPFabricSnapshot(TagsMixin, ChangeLoggedModel):
548
+ class IPFabricSnapshot(models.Model):
549
+ created = models.DateTimeField(auto_now_add=True)
550
+ last_updated = models.DateTimeField(editable=False)
548
551
  source = models.ForeignKey(
549
552
  to=IPFabricSource,
550
553
  on_delete=models.CASCADE,
@@ -597,6 +600,11 @@ class IPFabricSync(IPFabricClient, JobsMixin, TagsMixin, ChangeLoggedModel):
597
600
  on_delete=models.CASCADE,
598
601
  related_name="snapshots",
599
602
  )
603
+ type = models.CharField(
604
+ max_length=50,
605
+ choices=IPFabricSyncTypeChoices,
606
+ default=IPFabricSyncTypeChoices.DCIM,
607
+ )
600
608
  status = models.CharField(
601
609
  max_length=50,
602
610
  choices=DataSourceStatusChoices,
@@ -605,7 +613,6 @@ class IPFabricSync(IPFabricClient, JobsMixin, TagsMixin, ChangeLoggedModel):
605
613
  )
606
614
  parameters = models.JSONField(blank=True, null=True)
607
615
  auto_merge = models.BooleanField(default=False)
608
- update_custom_fields = models.BooleanField(default=True)
609
616
  last_synced = models.DateTimeField(blank=True, null=True, editable=False)
610
617
  scheduled = models.DateTimeField(null=True, blank=True)
611
618
  interval = models.PositiveIntegerField(
@@ -661,10 +668,6 @@ class IPFabricSync(IPFabricClient, JobsMixin, TagsMixin, ChangeLoggedModel):
661
668
  else:
662
669
  return False
663
670
 
664
- @property
665
- def last_ingestion(self):
666
- return self.ipfabricingestion_set.last()
667
-
668
671
  @staticmethod
669
672
  def get_transform_maps(group_ids=None):
670
673
  """
@@ -886,10 +889,7 @@ class IPFabricIngestion(JobsMixin, models.Model):
886
889
  def name(self):
887
890
  if self.branch:
888
891
  return self.branch.name
889
- try:
890
- return f"{self.sync.name} (Ingestion {self.pk})"
891
- except IPFabricIngestion.sync.RelatedObjectDoesNotExist:
892
- return f"Ingestion {self.pk} (No Sync)"
892
+ return f"{self.sync.name} (Ingestion {self.pk})"
893
893
 
894
894
  def get_absolute_url(self):
895
895
  return reverse("plugins:ipfabric_netbox:ipfabricingestion", args=[self.pk])