ipfabric_netbox 4.2.0b8__tar.gz → 4.2.0b9__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.
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/PKG-INFO +1 -1
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/__init__.py +1 -1
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/forms.py +83 -131
- ipfabric_netbox-4.2.0b9/ipfabric_netbox/tests/test_forms.py +1440 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/pyproject.toml +1 -1
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/README.md +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/api/__init__.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/api/serializers.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/api/urls.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/api/views.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/choices.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/data/transform_map.json +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/exceptions.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/filtersets.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/graphql/__init__.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/graphql/enums.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/graphql/filters.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/graphql/schema.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/graphql/types.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/jobs.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/migrations/0001_initial.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/migrations/0001_initial_squashed_0013_switch_to_branching_plugin.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/migrations/0002_ipfabricsnapshot_status.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/migrations/0003_ipfabricsource_type_and_more.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/migrations/0004_ipfabricsync_auto_merge.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/migrations/0005_alter_ipfabricrelationshipfield_source_model_and_more.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/migrations/0006_alter_ipfabrictransformmap_target_model.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/migrations/0007_prepare_custom_fields.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/migrations/0008_prepare_transform_maps.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/migrations/0009_transformmap_changes_for_netbox_v4_2.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/migrations/0010_remove_uuid_from_get_or_create.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/migrations/0011_update_part_number_DCIM_inventory_item_template.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/migrations/0012_remove_status_field.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/migrations/0013_switch_to_branching_plugin.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/migrations/0014_ipfabrictransformmapgroup_ipfabrictransformmap_group.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/migrations/0015_ipfabricingestionissue.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/migrations/0016_tags_and_changelog_for_snapshots.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/migrations/0017_ipfabricsync_update_custom_fields.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/migrations/0018_remove_type_field.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/migrations/__init__.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/models.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/navigation.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/signals.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/tables.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/template_content.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/templates/ipfabric_netbox/inc/clone_form.html +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/templates/ipfabric_netbox/inc/diff.html +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/templates/ipfabric_netbox/inc/json.html +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/templates/ipfabric_netbox/inc/logs_pending.html +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/templates/ipfabric_netbox/inc/merge_form.html +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/templates/ipfabric_netbox/inc/site_topology_button.html +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/templates/ipfabric_netbox/inc/site_topology_modal.html +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/templates/ipfabric_netbox/inc/snapshotdata.html +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/templates/ipfabric_netbox/inc/transform_map_field_map.html +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/templates/ipfabric_netbox/inc/transform_map_relationship_map.html +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/templates/ipfabric_netbox/ipfabric_table.html +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/templates/ipfabric_netbox/ipfabricingestion.html +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/templates/ipfabric_netbox/ipfabricsnapshot.html +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/templates/ipfabric_netbox/ipfabricsource.html +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/templates/ipfabric_netbox/ipfabricsync.html +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/templates/ipfabric_netbox/ipfabrictransformmap.html +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/templates/ipfabric_netbox/ipfabrictransformmap_list.html +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/templates/ipfabric_netbox/ipfabrictransformmap_restore.html +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/templates/ipfabric_netbox/ipfabrictransformmapgroup.html +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/templates/ipfabric_netbox/partials/ingestion_all.html +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/templates/ipfabric_netbox/partials/ingestion_progress.html +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/templates/ipfabric_netbox/partials/ingestion_statistics.html +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/templates/ipfabric_netbox/partials/ingestion_status.html +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/templates/ipfabric_netbox/partials/job_logs.html +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/templates/ipfabric_netbox/partials/object_tabs.html +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/templates/ipfabric_netbox/partials/sync_last_ingestion.html +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/templates/static/ipfabric_netbox/css/rack.css +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/templatetags/__init__.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/templatetags/ipfabric_netbox_helpers.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/tests/__init__.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/tests/api/__init__.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/tests/api/test_api.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/tests/test_models.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/urls.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/utilities/__init__.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/utilities/ipfutils.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/utilities/logging.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/utilities/nbutils.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/utilities/transform_map.py +0 -0
- {ipfabric_netbox-4.2.0b8 → ipfabric_netbox-4.2.0b9}/ipfabric_netbox/views.py +0 -0
|
@@ -46,22 +46,6 @@ exclude_fields = [
|
|
|
46
46
|
"status",
|
|
47
47
|
]
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
class IPFSiteChoiceField(forms.MultipleChoiceField):
|
|
51
|
-
def valid_value(self, value):
|
|
52
|
-
"""Check to see if the provided value is a valid choice."""
|
|
53
|
-
text_value = str(value)
|
|
54
|
-
for k, v in self.choices:
|
|
55
|
-
if isinstance(v, (list, tuple)):
|
|
56
|
-
for k2, v2 in v:
|
|
57
|
-
if value == k2 or text_value == str(k2):
|
|
58
|
-
return True
|
|
59
|
-
else:
|
|
60
|
-
if value == k or text_value == str(k):
|
|
61
|
-
return True
|
|
62
|
-
return False
|
|
63
|
-
|
|
64
|
-
|
|
65
49
|
dcim_parameters = {
|
|
66
50
|
"site": forms.BooleanField(required=False, label=_("Sites"), initial=True),
|
|
67
51
|
"manufacturer": forms.BooleanField(
|
|
@@ -78,43 +62,45 @@ dcim_parameters = {
|
|
|
78
62
|
"virtualchassis": forms.BooleanField(
|
|
79
63
|
required=False, label=_("Virtual Chassis"), initial=True
|
|
80
64
|
),
|
|
81
|
-
"interface": forms.BooleanField(
|
|
82
|
-
|
|
83
|
-
|
|
65
|
+
"interface": forms.BooleanField(
|
|
66
|
+
required=False, label=_("Interfaces"), initial=False
|
|
67
|
+
),
|
|
68
|
+
"macaddress": forms.BooleanField(
|
|
69
|
+
required=False, label=_("MAC Addresses"), initial=False
|
|
70
|
+
),
|
|
71
|
+
"inventoryitem": forms.BooleanField(
|
|
72
|
+
required=False, label=_("Part Numbers"), initial=False
|
|
73
|
+
),
|
|
84
74
|
}
|
|
85
75
|
ipam_parameters = {
|
|
86
|
-
"vlan": forms.BooleanField(required=False, label=_("VLANs")),
|
|
87
|
-
"vrf": forms.BooleanField(required=False, label=_("VRFs")),
|
|
88
|
-
"prefix": forms.BooleanField(required=False, label=_("Prefixes")),
|
|
89
|
-
"ipaddress": forms.BooleanField(
|
|
76
|
+
"vlan": forms.BooleanField(required=False, label=_("VLANs"), initial=False),
|
|
77
|
+
"vrf": forms.BooleanField(required=False, label=_("VRFs"), initial=False),
|
|
78
|
+
"prefix": forms.BooleanField(required=False, label=_("Prefixes"), initial=False),
|
|
79
|
+
"ipaddress": forms.BooleanField(
|
|
80
|
+
required=False, label=_("IP Addresses"), initial=False
|
|
81
|
+
),
|
|
90
82
|
}
|
|
91
83
|
sync_parameters = {"dcim": dcim_parameters, "ipam": ipam_parameters}
|
|
92
84
|
|
|
93
85
|
|
|
94
|
-
def source_column_choices(model):
|
|
86
|
+
def source_column_choices(model: str) -> list[tuple[str, str]]:
|
|
95
87
|
columns = transform_field_source_columns.get(model, None)
|
|
96
88
|
if columns:
|
|
97
89
|
choices = [(f, f) for f in transform_field_source_columns.get(model)]
|
|
98
90
|
else:
|
|
99
|
-
|
|
91
|
+
# This should never happen, but better be safe than sorry
|
|
92
|
+
choices = [] # pragma: no cover
|
|
100
93
|
return choices
|
|
101
94
|
|
|
102
95
|
|
|
103
|
-
def
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
"""
|
|
107
|
-
return ((None, "All Sites"),) + tuple(choices)
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
def str_to_list(str):
|
|
111
|
-
if not isinstance(str, list):
|
|
112
|
-
return [str]
|
|
96
|
+
def str_to_list(_str: str | list) -> list[str]:
|
|
97
|
+
if not isinstance(_str, list):
|
|
98
|
+
return [_str]
|
|
113
99
|
else:
|
|
114
|
-
return
|
|
100
|
+
return _str
|
|
115
101
|
|
|
116
102
|
|
|
117
|
-
def list_to_choices(choices):
|
|
103
|
+
def list_to_choices(choices: list[str]) -> tuple[tuple[str, str], ...]:
|
|
118
104
|
new_choices = ()
|
|
119
105
|
for choice in choices:
|
|
120
106
|
new_choices = new_choices + ((choice, choice),)
|
|
@@ -176,7 +162,7 @@ class IPFabricRelationshipFieldForm(NetBoxModelForm):
|
|
|
176
162
|
)
|
|
177
163
|
self.fields["target_field"].widget.initial = self.instance.target_field
|
|
178
164
|
else:
|
|
179
|
-
if kwargs
|
|
165
|
+
if kwargs.get("initial", {}).get("transform_map", None):
|
|
180
166
|
transform_map_id = kwargs["initial"]["transform_map"]
|
|
181
167
|
transform_map = IPFabricTransformMap.objects.get(
|
|
182
168
|
pk=transform_map_id
|
|
@@ -258,7 +244,7 @@ class IPFabricTransformFieldForm(NetBoxModelForm):
|
|
|
258
244
|
source_column_choices(source_fields)
|
|
259
245
|
)
|
|
260
246
|
else:
|
|
261
|
-
if kwargs
|
|
247
|
+
if kwargs.get("initial", {}).get("transform_map", None):
|
|
262
248
|
transform_map_id = kwargs["initial"]["transform_map"]
|
|
263
249
|
transform_map = IPFabricTransformMap.objects.get(
|
|
264
250
|
pk=transform_map_id
|
|
@@ -375,22 +361,22 @@ class IPFabricSourceForm(NetBoxModelForm):
|
|
|
375
361
|
"type": HTMXSelect(),
|
|
376
362
|
}
|
|
377
363
|
|
|
378
|
-
@property
|
|
379
|
-
def fieldsets(self):
|
|
380
|
-
fieldsets = [
|
|
381
|
-
FieldSet("name", "type", "url", name=_("Source")),
|
|
382
|
-
FieldSet("timeout", name=_("Parameters")),
|
|
383
|
-
]
|
|
384
|
-
|
|
385
|
-
if self.source_type == "local":
|
|
386
|
-
fieldsets[1] = FieldSet("auth", "verify", "timeout", name=_("Parameters"))
|
|
387
|
-
|
|
388
|
-
return fieldsets
|
|
389
|
-
|
|
390
364
|
def __init__(self, *args, **kwargs):
|
|
391
365
|
super().__init__(*args, **kwargs)
|
|
392
366
|
self.source_type = get_field_value(self, "type")
|
|
393
367
|
|
|
368
|
+
# Set fieldsets dynamically based on source_type
|
|
369
|
+
if self.source_type == "local":
|
|
370
|
+
self.fieldsets = [
|
|
371
|
+
FieldSet("name", "type", "url", name=_("Source")),
|
|
372
|
+
FieldSet("auth", "verify", "timeout", name=_("Parameters")),
|
|
373
|
+
]
|
|
374
|
+
else:
|
|
375
|
+
self.fieldsets = [
|
|
376
|
+
FieldSet("name", "type", "url", name=_("Source")),
|
|
377
|
+
FieldSet("timeout", name=_("Parameters")),
|
|
378
|
+
]
|
|
379
|
+
|
|
394
380
|
self.fields["timeout"] = forms.IntegerField(
|
|
395
381
|
required=False,
|
|
396
382
|
label=_("Timeout"),
|
|
@@ -451,6 +437,9 @@ class OrderedModelMultipleChoiceField(forms.ModelMultipleChoiceField):
|
|
|
451
437
|
|
|
452
438
|
def clean(self, value):
|
|
453
439
|
qs = super().clean(value)
|
|
440
|
+
# Handle None or empty values
|
|
441
|
+
if not value:
|
|
442
|
+
return qs
|
|
454
443
|
clauses = " ".join(
|
|
455
444
|
["WHEN id=%s THEN %s" % (pk, i) for i, pk in enumerate(value)]
|
|
456
445
|
)
|
|
@@ -534,32 +523,6 @@ class IPFabricSyncForm(NetBoxModelForm):
|
|
|
534
523
|
)
|
|
535
524
|
widgets = {"source": HTMXSelect()}
|
|
536
525
|
|
|
537
|
-
@property
|
|
538
|
-
def fieldsets(self):
|
|
539
|
-
fieldsets = [
|
|
540
|
-
FieldSet("name", "source", "groups", name=_("IP Fabric Source")),
|
|
541
|
-
]
|
|
542
|
-
if self.source_type == "local":
|
|
543
|
-
fieldsets.append(
|
|
544
|
-
FieldSet("snapshot_data", "sites", name=_("Snapshot Information")),
|
|
545
|
-
)
|
|
546
|
-
else:
|
|
547
|
-
fieldsets.append(
|
|
548
|
-
FieldSet("snapshot_data", name=_("Snapshot Information")),
|
|
549
|
-
)
|
|
550
|
-
if self.backend_fields:
|
|
551
|
-
for k, v in self.backend_fields.items():
|
|
552
|
-
fieldsets.append(FieldSet(*v, name=f"{k.upper()} Parameters"))
|
|
553
|
-
fieldsets.append(
|
|
554
|
-
FieldSet("scheduled", "interval", name=_("Ingestion Execution Parameters"))
|
|
555
|
-
)
|
|
556
|
-
fieldsets.append(
|
|
557
|
-
FieldSet("auto_merge", "update_custom_fields", name=_("Extras"))
|
|
558
|
-
)
|
|
559
|
-
fieldsets.append(FieldSet("tags", name=_("Tags")))
|
|
560
|
-
|
|
561
|
-
return fieldsets
|
|
562
|
-
|
|
563
526
|
def __init__(self, *args, **kwargs):
|
|
564
527
|
super().__init__(*args, **kwargs)
|
|
565
528
|
self.source_type = None
|
|
@@ -590,15 +553,13 @@ class IPFabricSyncForm(NetBoxModelForm):
|
|
|
590
553
|
self.initial["sites"] = self.instance.parameters.get("sites", [])
|
|
591
554
|
self.initial["groups"] = self.instance.parameters.get("groups", [])
|
|
592
555
|
|
|
593
|
-
backend = sync_parameters
|
|
594
|
-
|
|
595
556
|
now = local_now().strftime("%Y-%m-%d %H:%M:%S")
|
|
596
557
|
self.fields["scheduled"].help_text += f" (current time: <strong>{now}</strong>)"
|
|
597
558
|
|
|
598
559
|
# Add backend-specific form fields
|
|
599
560
|
self.backend_fields = {}
|
|
600
561
|
|
|
601
|
-
for k, v in
|
|
562
|
+
for k, v in sync_parameters.items():
|
|
602
563
|
self.backend_fields[k] = []
|
|
603
564
|
for name, form_field in v.items():
|
|
604
565
|
field_name = f"ipf_{name}"
|
|
@@ -607,17 +568,52 @@ class IPFabricSyncForm(NetBoxModelForm):
|
|
|
607
568
|
if self.instance and self.instance.parameters:
|
|
608
569
|
self.fields[field_name].initial = self.instance.parameters.get(name)
|
|
609
570
|
|
|
571
|
+
# Set fieldsets dynamically based and backend_fields
|
|
572
|
+
fieldsets = [
|
|
573
|
+
FieldSet("name", "source", "groups", name=_("IP Fabric Source")),
|
|
574
|
+
]
|
|
575
|
+
if self.source_type == "local":
|
|
576
|
+
fieldsets.append(
|
|
577
|
+
FieldSet("snapshot_data", "sites", name=_("Snapshot Information")),
|
|
578
|
+
)
|
|
579
|
+
else:
|
|
580
|
+
fieldsets.append(
|
|
581
|
+
FieldSet("snapshot_data", name=_("Snapshot Information")),
|
|
582
|
+
)
|
|
583
|
+
for k, v in self.backend_fields.items():
|
|
584
|
+
fieldsets.append(FieldSet(*v, name=f"{k.upper()} Parameters"))
|
|
585
|
+
fieldsets.append(
|
|
586
|
+
FieldSet("scheduled", "interval", name=_("Ingestion Execution Parameters"))
|
|
587
|
+
)
|
|
588
|
+
fieldsets.append(
|
|
589
|
+
FieldSet("auto_merge", "update_custom_fields", name=_("Extras"))
|
|
590
|
+
)
|
|
591
|
+
fieldsets.append(FieldSet("tags", name=_("Tags")))
|
|
592
|
+
|
|
593
|
+
self.fieldsets = fieldsets
|
|
594
|
+
|
|
610
595
|
def clean(self):
|
|
611
596
|
super().clean()
|
|
612
|
-
snapshot = self.cleaned_data["snapshot_data"]
|
|
613
597
|
|
|
614
598
|
sites = self.data.get("sites")
|
|
615
|
-
choices = list_to_choices(str_to_list(sites))
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
if not
|
|
620
|
-
|
|
599
|
+
self.fields["sites"].choices = list_to_choices(str_to_list(sites))
|
|
600
|
+
if sites and "snapshot_data" in self.cleaned_data:
|
|
601
|
+
snapshot = self.cleaned_data["snapshot_data"]
|
|
602
|
+
# Check if all sites are valid - fail if any site is not found in snapshot.sites
|
|
603
|
+
if not all(
|
|
604
|
+
any(site in snapshot_site for snapshot_site in snapshot.sites)
|
|
605
|
+
for site in sites
|
|
606
|
+
):
|
|
607
|
+
invalid_sites = [
|
|
608
|
+
site
|
|
609
|
+
for site in sites
|
|
610
|
+
if not any(
|
|
611
|
+
site in snapshot_site for snapshot_site in snapshot.sites
|
|
612
|
+
)
|
|
613
|
+
]
|
|
614
|
+
raise ValidationError(
|
|
615
|
+
{"sites": f"Sites {invalid_sites} not part of the snapshot."}
|
|
616
|
+
)
|
|
621
617
|
|
|
622
618
|
scheduled_time = self.cleaned_data.get("scheduled")
|
|
623
619
|
if scheduled_time and scheduled_time < local_now():
|
|
@@ -665,50 +661,6 @@ class IPFabricSyncForm(NetBoxModelForm):
|
|
|
665
661
|
return object
|
|
666
662
|
|
|
667
663
|
|
|
668
|
-
# class SyncForm(forms.Form):
|
|
669
|
-
# def __init__(self, *args, **kwargs):
|
|
670
|
-
# self.snapshots = kwargs.pop("snapshot_choices", None)
|
|
671
|
-
# self.sites = kwargs.pop("site_choices", None)
|
|
672
|
-
# super(SyncForm, self).__init__(*args, **kwargs)
|
|
673
|
-
# if self.snapshots:
|
|
674
|
-
# snapshot_choices = [
|
|
675
|
-
# (snapshot_id, snapshot_name)
|
|
676
|
-
# for snapshot_name, snapshot_id in self.snapshots.values()
|
|
677
|
-
# ]
|
|
678
|
-
# self.fields["snapshot"] = forms.ChoiceField(
|
|
679
|
-
# label="Snapshot",
|
|
680
|
-
# required=True,
|
|
681
|
-
# choices=snapshot_choices,
|
|
682
|
-
# help_text="IPFabric snapshot to sync from. Defaults to $last",
|
|
683
|
-
# widget=forms.Select(
|
|
684
|
-
# attrs={
|
|
685
|
-
# "hx-get": reverse("plugins:ipfabric_netbox:ipfabricsync_add"),
|
|
686
|
-
# "hx-trigger": "change",
|
|
687
|
-
# "hx-target": "#modules",
|
|
688
|
-
# "class": "form-control",
|
|
689
|
-
# }
|
|
690
|
-
# ),
|
|
691
|
-
# )
|
|
692
|
-
# if self.sites:
|
|
693
|
-
# site_choices = [(site, site) for site in self.sites]
|
|
694
|
-
# self.fields["site"] = forms.ChoiceField(
|
|
695
|
-
# label="Site",
|
|
696
|
-
# required=False,
|
|
697
|
-
# choices=add_blank_choice(site_choices),
|
|
698
|
-
# help_text="Sites available within snapshot",
|
|
699
|
-
# widget=forms.Select(attrs={"class": "form-control"}),
|
|
700
|
-
# )
|
|
701
|
-
# else:
|
|
702
|
-
# self.fields["site"] = forms.ChoiceField(
|
|
703
|
-
# label="Site",
|
|
704
|
-
# required=False,
|
|
705
|
-
# choices=add_blank_choice([]),
|
|
706
|
-
# help_text="Sites available within snapshot",
|
|
707
|
-
# widget=forms.Select(
|
|
708
|
-
# attrs={"class": "form-control", "disabled": "disabled"}
|
|
709
|
-
# ),
|
|
710
|
-
# )
|
|
711
|
-
|
|
712
664
|
tableChoices = [
|
|
713
665
|
("eol_details", "Inventory - EOL_DETAILS"),
|
|
714
666
|
("fans", "Inventory - FANS"),
|