ipfabric_netbox 4.2.0b8__py3-none-any.whl → 4.2.1__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.

Potentially problematic release.


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

Files changed (30) hide show
  1. ipfabric_netbox/__init__.py +1 -1
  2. ipfabric_netbox/api/__init__.py +1 -0
  3. ipfabric_netbox/api/nested_serializers.py +78 -0
  4. ipfabric_netbox/api/serializers.py +90 -147
  5. ipfabric_netbox/api/urls.py +4 -4
  6. ipfabric_netbox/api/views.py +19 -18
  7. ipfabric_netbox/choices.py +12 -0
  8. ipfabric_netbox/filtersets.py +4 -67
  9. ipfabric_netbox/forms.py +13 -13
  10. ipfabric_netbox/models.py +10 -10
  11. ipfabric_netbox/tables.py +9 -30
  12. ipfabric_netbox/template_content.py +20 -3
  13. ipfabric_netbox/templates/ipfabric_netbox/inc/site_topology_button.html +10 -3
  14. ipfabric_netbox/templates/ipfabric_netbox/ipfabricsync_list.html +71 -0
  15. ipfabric_netbox/tests/test_models.py +11 -47
  16. ipfabric_netbox/utilities/ipfutils.py +23 -43
  17. ipfabric_netbox/views.py +8 -6
  18. {ipfabric_netbox-4.2.0b8.dist-info → ipfabric_netbox-4.2.1.dist-info}/METADATA +6 -6
  19. {ipfabric_netbox-4.2.0b8.dist-info → ipfabric_netbox-4.2.1.dist-info}/RECORD +20 -28
  20. ipfabric_netbox/graphql/__init__.py +0 -23
  21. ipfabric_netbox/graphql/enums.py +0 -35
  22. ipfabric_netbox/graphql/filters.py +0 -317
  23. ipfabric_netbox/graphql/schema.py +0 -101
  24. ipfabric_netbox/graphql/types.py +0 -216
  25. ipfabric_netbox/migrations/0016_tags_and_changelog_for_snapshots.py +0 -31
  26. ipfabric_netbox/migrations/0017_ipfabricsync_update_custom_fields.py +0 -17
  27. ipfabric_netbox/migrations/0018_remove_type_field.py +0 -17
  28. ipfabric_netbox/tests/api/__init__.py +0 -0
  29. ipfabric_netbox/tests/api/test_api.py +0 -879
  30. {ipfabric_netbox-4.2.0b8.dist-info → ipfabric_netbox-4.2.1.dist-info}/WHEEL +0 -0
ipfabric_netbox/forms.py CHANGED
@@ -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>)"
ipfabric_netbox/models.py CHANGED
@@ -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])
ipfabric_netbox/tables.py CHANGED
@@ -142,41 +142,20 @@ class IPFabricSourceTable(NetBoxTable):
142
142
  default_columns = ("pk", "name", "status", "description", "snapshot_count")
143
143
 
144
144
 
145
- class IPFabricSyncTable(NetBoxTable):
146
- name = tables.Column(linkify=True)
145
+ class SyncTable(NetBoxTable):
146
+ actions = None
147
147
  status = columns.ChoiceFieldColumn()
148
148
  snapshot_name = tables.Column(
149
- verbose_name="Snapshot Name",
150
- accessor="snapshot_data",
151
- linkify=True,
152
- )
153
- last_ingestion = tables.Column(
154
- accessor="last_ingestion",
155
- verbose_name="Last Ingestion",
156
- linkify=True,
149
+ verbose_name="Snapshot Name", accessor="snapshot_data"
157
150
  )
158
151
 
159
- def render_last_ingestion(self, value: IPFabricIngestion):
160
- return getattr(value, "name", "---") if value else "---"
161
-
162
- def render_snapshot_name(self, value: IPFabricSnapshot):
163
- return getattr(value, "name", "---") if value else "---"
152
+ def render_snapshot_name(self, value):
153
+ return value.get("name", "---")
164
154
 
165
155
  class Meta(NetBoxTable.Meta):
166
156
  model = IPFabricSync
167
- fields = (
168
- "auto_merge",
169
- "id",
170
- "interval",
171
- "last_synced",
172
- "last_ingestion",
173
- "name",
174
- "scheduled",
175
- "status",
176
- "snapshot_name",
177
- "user",
178
- )
179
- default_columns = ("name", "status", "last_ingestion", "snapshot_name")
157
+ fields = ("id", "status", "snapshot_name")
158
+ default_columns = ("id", "status", "snapshot_name")
180
159
 
181
160
 
182
161
  class IPFabricIngestionChangesTable(NetBoxTable):
@@ -262,5 +241,5 @@ class IPFabricDataTable(NetBoxTable):
262
241
 
263
242
  class Meta(NetBoxTable.Meta):
264
243
  model = IPFabricData
265
- fields = ("snapshot_data", "JSON")
266
- default_columns = ("snapshot_data", "JSON")
244
+ fields = ("snapshot_data", "type", "JSON")
245
+ default_columns = ("snapshot_data", "type", "JSON")
@@ -1,13 +1,30 @@
1
+ import logging
2
+
1
3
  from netbox.plugins import PluginTemplateExtension
2
4
 
5
+ from ipfabric_netbox.models import IPFabricSnapshot
6
+
7
+ logger = logging.getLogger("ipfabric_netbox.template_content")
8
+
3
9
 
4
10
  class SiteTopologyButtons(PluginTemplateExtension):
5
11
  model = "dcim.site"
6
12
 
7
13
  def buttons(self):
8
- return self.render(
9
- "ipfabric_netbox/inc/site_topology_button.html", extra_context={}
10
- )
14
+ try:
15
+ site = self.context.get("object")
16
+ source = None
17
+ for snapshot in IPFabricSnapshot.objects.all():
18
+ # `Site.name` is unique in DB, so we can use it to match against IPF snapshots
19
+ if site.name in snapshot.sites:
20
+ source = snapshot.source
21
+ return self.render(
22
+ "ipfabric_netbox/inc/site_topology_button.html",
23
+ extra_context={"source": source},
24
+ )
25
+ except Exception as e:
26
+ logger.error(f"Could not render topology button: {e}.")
27
+ return "render error"
11
28
 
12
29
 
13
30
  template_extensions = [SiteTopologyButtons]
@@ -6,19 +6,26 @@
6
6
  IP Fabric Topology
7
7
  </button>
8
8
  <ul class="dropdown-menu" aria-labelledby="btnGroupDrop1">
9
+ {% if source is not None %}
9
10
  <li><a href="#"
10
- hx-get="{% url 'plugins:ipfabric_netbox:ipfabricsource_topology' pk=object.pk site=object.site.pk %}?snapshot=$last&source={{ object.custom_field_data.ipfabric_source }}"
11
+ hx-get="{% url 'plugins:ipfabric_netbox:ipfabricsource_topology' pk=source.pk site=object.pk %}?snapshot=$last&source={{ source.id }}"
11
12
  hx-target="#topology-modal-content" data-bs-toggle="modal" data-bs-target="#topology-modal"
12
13
  class="dropdown-item">
13
14
  Last Snapshot
14
15
  </a>
15
16
  </li>
16
17
  <li><a href="#"
17
- hx-get="{% url 'plugins:ipfabric_netbox:ipfabricsource_topology' pk=object.pk site=object.site.pk %}?snapshot=$prev&source={{ object.custom_field_data.ipfabric_source }}"
18
+ hx-get="{% url 'plugins:ipfabric_netbox:ipfabricsource_topology' pk=source.pk site=object.pk %}?snapshot=$prev&source={{ source.id }}"
18
19
  hx-target="#topology-modal-content" data-bs-toggle="modal" data-bs-target="#topology-modal"
19
20
  class="dropdown-item">
20
21
  Previous Snapshot
21
- </a></li>
22
+ </a>
23
+ </li>
24
+ {% else %}
25
+ <li>
26
+ <span class="dropdown-item text-danger">No IP Fabric Source Found for this Site</span>
27
+ </li>
28
+ {% endif %}
22
29
  </ul>
23
30
  </div>
24
31
  </div>
@@ -0,0 +1,71 @@
1
+ {% extends 'base/layout.html' %}
2
+ {% load buttons %}
3
+ {% load helpers %}
4
+ {% load perms %}
5
+
6
+ {% block title %}Ingestion{% endblock %}
7
+
8
+ {% block tabs %}
9
+ <ul class="nav nav-tabs px-3">
10
+ <li class="nav-item" role="presentation">
11
+ <a class="nav-link active" role="tab">Ingestion</a>
12
+ </li>
13
+ </ul>
14
+ {% endblock tabs %}
15
+
16
+ {% block controls %}
17
+ <div class="controls">
18
+ <div class="control-group">
19
+ {% block extra_controls %}{% endblock %}
20
+ {% add_button model %}
21
+ </div>
22
+ </div>
23
+ {% endblock controls %}
24
+
25
+ {% block content %}
26
+ <div class="tab-content">
27
+ {% for sync in syncs %}
28
+ <div class="card">
29
+ <h5 class="card-header d-flex justify-content-between" id="module{{ module.pk }}">
30
+ <div>
31
+ <i class="mdi mdi-cloud-sync"></i><i class="mdi mdi-sync"></i> <a href="{% url 'plugins:ipfabric_netbox:ipfabricsync' pk=sync.pk %}">{{ sync.name}}</a>
32
+ </div>
33
+ {% if perms.ipfabric_netbox.delete_ipfabricsync %}
34
+ <a href="{% url 'plugins:ipfabric_netbox:ipfabricsync_delete' pk=sync.pk %}" class="btn btn-danger btn-sm">
35
+ <i class="mdi mdi-trash-can-outline" aria-hidden="true"></i> Delete
36
+ </a>
37
+ {% endif %}
38
+
39
+ </h5>
40
+ <div class="card-body">
41
+ {% include 'inc/sync_warning.html' with object=module %}
42
+ <table class="table table-hover table-headings reports">
43
+ <thead>
44
+ <tr>
45
+ <th width="200">Source</th>
46
+ <th width="400">Snapshot</th>
47
+ <th>Status</th>
48
+ <th>Last Run</th>
49
+ </tr>
50
+ </thead>
51
+ <tbody>
52
+ <tr>
53
+ <td><a href="{% url 'plugins:ipfabric_netbox:ipfabricsource' pk=sync.snapshot_data.source.pk %}">{{ sync.snapshot_data.source.name }}</a></td>
54
+ <td><a href="{% url 'plugins:ipfabric_netbox:ipfabricsnapshot' pk=sync.snapshot_data.pk %}">{{ sync.snapshot_data.name}}</a></td>
55
+ <td>{% badge sync.get_status_display last_job.get_status_color %}</td>
56
+ <td>{{sync.last_synced}}</td>
57
+ </tr>
58
+ </tbody>
59
+ </table>
60
+ </div>
61
+ </div>
62
+ {% empty %}
63
+ <div class="alert alert-info" role="alert">
64
+ <h4 class="alert-heading">Sync Jobs Settings Found</h4>
65
+ {% if perms.extras.add_reportmodule %}
66
+ Get started by <a href="{% url 'plugins:ipfabric_netbox:ipfabricsync_add' %}">creating a sync</a> from an IP Fabric source.
67
+ {% endif %}
68
+ </div>
69
+ {% endfor %}
70
+ </div>
71
+ {% endblock content %}
@@ -8,7 +8,6 @@ from django.test import TestCase
8
8
  from django.utils import timezone
9
9
 
10
10
  from ipfabric_netbox.choices import IPFabricSnapshotStatusModelChoices
11
- from ipfabric_netbox.models import IPFabricIngestion
12
11
  from ipfabric_netbox.models import IPFabricSnapshot
13
12
  from ipfabric_netbox.models import IPFabricSource
14
13
  from ipfabric_netbox.models import IPFabricSync
@@ -119,9 +118,9 @@ class IPFabricTransformMapModelTestCase(TestCase):
119
118
  )
120
119
  sync = IPFabricSync.objects.create(
121
120
  name="ingest",
121
+ type="dcim",
122
122
  status="new",
123
123
  snapshot_data=snapshot,
124
- update_custom_fields=True,
125
124
  parameters={
126
125
  "vrf": False,
127
126
  "site": True,
@@ -139,8 +138,6 @@ class IPFabricTransformMapModelTestCase(TestCase):
139
138
  },
140
139
  )
141
140
 
142
- ingestion = IPFabricIngestion.objects.create(sync=sync)
143
-
144
141
  runner = IPFabricSyncRunner(
145
142
  settings={
146
143
  "site": True,
@@ -155,11 +152,7 @@ class IPFabricTransformMapModelTestCase(TestCase):
155
152
  "snapshot_id": "12dd8c61-129c-431a-b98b-4c9211571f89",
156
153
  },
157
154
  sync=sync,
158
- ingestion=ingestion,
159
155
  )
160
- # Need to monkeypatch since we are not in active Branch (different schema)
161
- # Using default schema "default" here since we are in "test_netbox" DB
162
- runner.get_db_connection_name = lambda: "default"
163
156
 
164
157
  site_data = {
165
158
  "siteName": "MPLS",
@@ -173,9 +166,7 @@ class IPFabricTransformMapModelTestCase(TestCase):
173
166
  "networksCount": 6,
174
167
  }
175
168
 
176
- self.site = runner.sync_item(
177
- item=site_data, app_label="dcim", model="site", cf=sync.update_custom_fields
178
- )
169
+ self.site = runner.get_model_or_update("dcim", "site", site_data)
179
170
 
180
171
  device_data = {
181
172
  "id": "961251111",
@@ -213,36 +204,14 @@ class IPFabricTransformMapModelTestCase(TestCase):
213
204
  "slug": None,
214
205
  }
215
206
 
216
- self.mf_obj = runner.sync_item(
217
- item=device_data,
218
- app_label="dcim",
219
- model="manufacturer",
220
- cf=sync.update_custom_fields,
221
- )
222
- self.dt_obj = runner.sync_item(
223
- item=device_data,
224
- app_label="dcim",
225
- model="devicetype",
226
- cf=sync.update_custom_fields,
227
- )
228
- self.platform = runner.sync_item(
229
- item=device_data,
230
- app_label="dcim",
231
- model="platform",
232
- cf=sync.update_custom_fields,
233
- )
234
- self.role = runner.sync_item(
235
- item=device_data,
236
- app_label="dcim",
237
- model="devicerole",
238
- cf=sync.update_custom_fields,
239
- )
240
- self.device_object = runner.sync_item(
241
- item=device_data,
242
- app_label="dcim",
243
- model="device",
244
- cf=sync.update_custom_fields,
245
- )
207
+ self.mf_obj = runner.get_model_or_update("dcim", "manufacturer", device_data)
208
+ self.dt_obj = runner.get_model_or_update("dcim", "devicetype", device_data)
209
+
210
+ self.platform = runner.get_model_or_update("dcim", "platform", device_data)
211
+
212
+ self.role = runner.get_model_or_update("dcim", "devicerole", device_data)
213
+
214
+ self.device_object = runner.get_model_or_update("dcim", "device", device_data)
246
215
 
247
216
  def test_transform_map(self):
248
217
  site_transform_map = IPFabricTransformMap.objects.get(name="Site Transform Map")
@@ -414,10 +383,5 @@ class IPFabricTransformMapModelTestCase(TestCase):
414
383
  )
415
384
  transform_field.template = "{{ object.hostname }} - test"
416
385
  transform_field.save()
417
- device_object = runner.sync_item(
418
- item=device_data,
419
- app_label="dcim",
420
- model="device",
421
- cf=sync.update_custom_fields,
422
- )
386
+ device_object = runner.get_model_or_update("dcim", "device", device_data)
423
387
  self.assertEqual(device_object.name, "L21PE152 - test")
@@ -589,35 +589,6 @@ class IPFabricSyncRunner(object):
589
589
 
590
590
  return instance
591
591
 
592
- def sync_item(
593
- self,
594
- item,
595
- app_label: str,
596
- model: str,
597
- cf: bool = False,
598
- ingestion: "IPFabricIngestion" = None,
599
- ) -> ModelTypeVar | None:
600
- """Sync a single item to NetBox."""
601
- synced_object = self.sync_model(
602
- app_label=app_label,
603
- model=model,
604
- data=item,
605
- sync=self.settings.get(model),
606
- )
607
- if synced_object is None:
608
- return None
609
-
610
- if cf:
611
- synced_object.snapshot()
612
- synced_object.custom_field_data[
613
- "ipfabric_source"
614
- ] = self.sync.snapshot_data.source.pk
615
- if ingestion:
616
- synced_object.custom_field_data["ipfabric_ingestion"] = ingestion.pk
617
- synced_object.save()
618
-
619
- return synced_object
620
-
621
592
  def sync_items(
622
593
  self,
623
594
  items,
@@ -634,7 +605,23 @@ class IPFabricSyncRunner(object):
634
605
  return
635
606
 
636
607
  for item in items:
637
- self.sync_item(item, app_label, model, cf, ingestion)
608
+ synced_object = self.sync_model(
609
+ app_label=app_label,
610
+ model=model,
611
+ data=item,
612
+ sync=self.settings.get(model),
613
+ )
614
+ if synced_object is None:
615
+ continue
616
+
617
+ if cf:
618
+ synced_object.snapshot()
619
+ synced_object.custom_field_data[
620
+ "ipfabric_source"
621
+ ] = self.sync.snapshot_data.source.pk
622
+ if ingestion:
623
+ synced_object.custom_field_data["ipfabric_ingestion"] = ingestion.pk
624
+ synced_object.save()
638
625
 
639
626
  @handle_errors
640
627
  def sync_devices(
@@ -697,14 +684,11 @@ class IPFabricSyncRunner(object):
697
684
 
698
685
  if device_object and self.settings.get("device"):
699
686
  device_object.snapshot()
700
- if self.sync.update_custom_fields:
701
- device_object.custom_field_data[
702
- "ipfabric_source"
703
- ] = self.sync.snapshot_data.source.pk
704
- if ingestion:
705
- device_object.custom_field_data[
706
- "ipfabric_ingestion"
707
- ] = ingestion.pk
687
+ device_object.custom_field_data[
688
+ "ipfabric_source"
689
+ ] = self.sync.snapshot_data.source.pk
690
+ if ingestion:
691
+ device_object.custom_field_data["ipfabric_ingestion"] = ingestion.pk
708
692
  device_object.save()
709
693
 
710
694
  self.logger.increment_statistics(model="device")
@@ -845,11 +829,7 @@ class IPFabricSyncRunner(object):
845
829
  ) = self.collect_data()
846
830
 
847
831
  self.sync_items(
848
- app_label="dcim",
849
- model="site",
850
- items=sites,
851
- cf=self.sync.update_custom_fields,
852
- ingestion=ingestion,
832
+ app_label="dcim", model="site", items=sites, cf=True, ingestion=ingestion
853
833
  )
854
834
  self.sync_devices(
855
835
  ingestion,
ipfabric_netbox/views.py CHANGED
@@ -37,7 +37,6 @@ from .filtersets import IPFabricIngestionFilterSet
37
37
  from .filtersets import IPFabricIngestionIssueFilterSet
38
38
  from .filtersets import IPFabricSnapshotFilterSet
39
39
  from .filtersets import IPFabricSourceFilterSet
40
- from .filtersets import IPFabricSyncFilterSet
41
40
  from .filtersets import IPFabricTransformMapFilterSet
42
41
  from .filtersets import IPFabricTransformMapGroupFilterSet
43
42
  from .forms import IPFabricIngestionFilterForm
@@ -70,7 +69,6 @@ from .tables import IPFabricIngestionTable
70
69
  from .tables import IPFabricRelationshipFieldTable
71
70
  from .tables import IPFabricSnapshotTable
72
71
  from .tables import IPFabricSourceTable
73
- from .tables import IPFabricSyncTable
74
72
  from .tables import IPFabricTransformFieldTable
75
73
  from .tables import IPFabricTransformMapGroupTable
76
74
  from .tables import IPFabricTransformMapTable
@@ -530,10 +528,14 @@ class IPFabricSourceBulkDeleteView(generic.BulkDeleteView):
530
528
 
531
529
 
532
530
  # Sync
533
- class IPFabricSyncListView(generic.ObjectListView):
534
- queryset = IPFabricSync.objects.all()
535
- table = IPFabricSyncTable
536
- filterset = IPFabricSyncFilterSet
531
+ class IPFabricSyncListView(View):
532
+ def get(self, request):
533
+ syncs = IPFabricSync.objects.prefetch_related("snapshot_data")
534
+ return render(
535
+ request,
536
+ "ipfabric_netbox/ipfabricsync_list.html",
537
+ {"model": IPFabricSync, "syncs": syncs},
538
+ )
537
539
 
538
540
 
539
541
  @register_model_view(IPFabricSync, "edit")
@@ -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