ipfabric_netbox 4.3.2b7__tar.gz → 4.3.2b9__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.3.2b7 → ipfabric_netbox-4.3.2b9}/PKG-INFO +1 -1
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/__init__.py +1 -1
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/exceptions.py +5 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/jobs.py +14 -1
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/utilities/ipfutils.py +94 -66
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/pyproject.toml +1 -1
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/README.md +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/api/__init__.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/api/serializers.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/api/urls.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/api/views.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/choices.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/data/transform_map.json +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/filtersets.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/forms.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/graphql/__init__.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/graphql/enums.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/graphql/filters.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/graphql/schema.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/graphql/types.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/migrations/0001_initial.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/migrations/0001_initial_squashed_0013_switch_to_branching_plugin.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/migrations/0002_ipfabricsnapshot_status.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/migrations/0003_ipfabricsource_type_and_more.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/migrations/0004_ipfabricsync_auto_merge.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/migrations/0005_alter_ipfabricrelationshipfield_source_model_and_more.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/migrations/0006_alter_ipfabrictransformmap_target_model.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/migrations/0007_prepare_custom_fields.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/migrations/0008_prepare_transform_maps.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/migrations/0009_transformmap_changes_for_netbox_v4_2.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/migrations/0010_remove_uuid_from_get_or_create.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/migrations/0011_update_part_number_DCIM_inventory_item_template.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/migrations/0012_remove_status_field.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/migrations/0013_switch_to_branching_plugin.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/migrations/0014_ipfabrictransformmapgroup_ipfabrictransformmap_group.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/migrations/0015_ipfabricingestionissue.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/migrations/0016_tags_and_changelog_for_snapshots.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/migrations/0017_ipfabricsync_update_custom_fields.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/migrations/0018_remove_type_field.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/migrations/0019_alter_ipfabrictransformmap_options_and_more.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/migrations/0020_clean_scheduled_jobs.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/migrations/0021_update_transform_maps.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/migrations/__init__.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/models.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/navigation.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/signals.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/tables.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/template_content.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/templates/ipfabric_netbox/inc/clone_form.html +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/templates/ipfabric_netbox/inc/diff.html +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/templates/ipfabric_netbox/inc/json.html +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/templates/ipfabric_netbox/inc/logs_pending.html +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/templates/ipfabric_netbox/inc/merge_form.html +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/templates/ipfabric_netbox/inc/site_topology_button.html +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/templates/ipfabric_netbox/inc/site_topology_modal.html +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/templates/ipfabric_netbox/inc/snapshotdata.html +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/templates/ipfabric_netbox/inc/transform_map_field_map.html +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/templates/ipfabric_netbox/inc/transform_map_relationship_map.html +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/templates/ipfabric_netbox/ipfabric_table.html +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/templates/ipfabric_netbox/ipfabricingestion.html +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/templates/ipfabric_netbox/ipfabricsnapshot.html +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/templates/ipfabric_netbox/ipfabricsource.html +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/templates/ipfabric_netbox/ipfabricsync.html +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/templates/ipfabric_netbox/ipfabrictransformmap.html +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/templates/ipfabric_netbox/ipfabrictransformmap_list.html +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/templates/ipfabric_netbox/ipfabrictransformmap_restore.html +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/templates/ipfabric_netbox/ipfabrictransformmapgroup.html +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/templates/ipfabric_netbox/partials/ingestion_all.html +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/templates/ipfabric_netbox/partials/ingestion_progress.html +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/templates/ipfabric_netbox/partials/ingestion_statistics.html +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/templates/ipfabric_netbox/partials/ingestion_status.html +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/templates/ipfabric_netbox/partials/job_logs.html +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/templates/ipfabric_netbox/partials/object_tabs.html +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/templates/ipfabric_netbox/partials/sync_last_ingestion.html +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/templates/static/ipfabric_netbox/css/rack.css +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/templatetags/__init__.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/templatetags/ipfabric_netbox_helpers.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/tests/__init__.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/tests/api/__init__.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/tests/api/test_api.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/tests/test_forms.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/tests/test_models.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/tests/test_views.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/urls.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/utilities/__init__.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/utilities/logging.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/utilities/transform_map.py +0 -0
- {ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/views.py +0 -0
|
@@ -46,5 +46,10 @@ class IPAddressPrimaryRemovalError(IngestionIssue, SyncError):
|
|
|
46
46
|
return "Error removing primary IP from other device."
|
|
47
47
|
|
|
48
48
|
|
|
49
|
+
class IPAddressPrimaryAssignmentError(IngestionIssue, SyncError):
|
|
50
|
+
def __str__(self):
|
|
51
|
+
return "Error assigning primary IP to device."
|
|
52
|
+
|
|
53
|
+
|
|
49
54
|
class RequiredDependencyFailedSkip(SearchError):
|
|
50
55
|
"""Raised when a required dependency failed, causing this item to be skipped."""
|
|
@@ -3,6 +3,9 @@ from datetime import timedelta
|
|
|
3
3
|
|
|
4
4
|
from core.choices import JobStatusChoices
|
|
5
5
|
from core.exceptions import SyncError
|
|
6
|
+
from dcim.models import VirtualChassis
|
|
7
|
+
from dcim.signals import assign_virtualchassis_master
|
|
8
|
+
from django.db.models import signals
|
|
6
9
|
from netbox.context_managers import event_tracking
|
|
7
10
|
from rq.timeouts import JobTimeoutException
|
|
8
11
|
from utilities.datetime import local_now
|
|
@@ -116,7 +119,17 @@ def merge_ipfabric_ingestion(job, remove_branch=False, *args, **kwargs):
|
|
|
116
119
|
|
|
117
120
|
job.start()
|
|
118
121
|
with event_tracking(request):
|
|
119
|
-
|
|
122
|
+
try:
|
|
123
|
+
# This signal is disabled on sync, we need to disable it here too
|
|
124
|
+
signals.post_save.disconnect(
|
|
125
|
+
assign_virtualchassis_master, sender=VirtualChassis
|
|
126
|
+
)
|
|
127
|
+
ingestion.sync_merge()
|
|
128
|
+
finally:
|
|
129
|
+
# Re-enable the disabled signal
|
|
130
|
+
signals.post_save.connect(
|
|
131
|
+
assign_virtualchassis_master, sender=VirtualChassis
|
|
132
|
+
)
|
|
120
133
|
if remove_branch:
|
|
121
134
|
branching_branch = ingestion.branch
|
|
122
135
|
ingestion.branch = None
|
|
@@ -14,10 +14,13 @@ from typing import TypeVar
|
|
|
14
14
|
from core.exceptions import SyncError
|
|
15
15
|
from core.signals import clear_events
|
|
16
16
|
from dcim.models import Device
|
|
17
|
+
from dcim.models import VirtualChassis
|
|
18
|
+
from dcim.signals import assign_virtualchassis_master
|
|
17
19
|
from django.conf import settings
|
|
18
20
|
from django.core.exceptions import MultipleObjectsReturned
|
|
19
21
|
from django.core.exceptions import ObjectDoesNotExist
|
|
20
22
|
from django.db.models import Model
|
|
23
|
+
from django.db.models import signals
|
|
21
24
|
from django.utils.text import slugify
|
|
22
25
|
from django_tables2 import Column
|
|
23
26
|
from extras.events import flush_events
|
|
@@ -30,6 +33,7 @@ from netutils.utils import jinja2_convenience_function
|
|
|
30
33
|
from ..choices import IPFabricSourceTypeChoices
|
|
31
34
|
from ..choices import IPFabricSyncStatusChoices
|
|
32
35
|
from ..exceptions import IPAddressDuplicateError
|
|
36
|
+
from ..exceptions import IPAddressPrimaryAssignmentError
|
|
33
37
|
from ..exceptions import IPAddressPrimaryRemovalError
|
|
34
38
|
from ..exceptions import RequiredDependencyFailedSkip
|
|
35
39
|
from ..exceptions import SearchError
|
|
@@ -997,84 +1001,99 @@ class IPFabricSyncRunner(object):
|
|
|
997
1001
|
self.events_clearer.increment()
|
|
998
1002
|
|
|
999
1003
|
@handle_errors
|
|
1000
|
-
def
|
|
1001
|
-
"""
|
|
1002
|
-
|
|
1003
|
-
contain information whether it is primary or not. And it must be done
|
|
1004
|
-
on Device object, so cannot be done via Transform Maps yet since that
|
|
1005
|
-
would require another Transform Map for Device.
|
|
1006
|
-
So we need to do it manually here.
|
|
1004
|
+
def sync_ipaddress(self, ip_address: DataRecord) -> "IPAddress | None":
|
|
1005
|
+
"""Sync a single IP Address to NetBox, separated to use @handle_errors."""
|
|
1006
|
+
connection_name = self.get_db_connection_name()
|
|
1007
1007
|
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1008
|
+
# First remove primary IP from the target object.
|
|
1009
|
+
# It cannot be done using hooks since there is no pre_clean at it fails on full_clean()
|
|
1010
|
+
try:
|
|
1011
|
+
ipv4_address = render_jinja2(
|
|
1012
|
+
ip_address.transform_map.field_maps.get(
|
|
1013
|
+
target_field="address"
|
|
1014
|
+
).template,
|
|
1015
|
+
{"object": ip_address.data},
|
|
1014
1016
|
)
|
|
1017
|
+
other_device = (
|
|
1018
|
+
Device.objects.using(connection_name)
|
|
1019
|
+
.exclude(serial=serial(ip_address.data))
|
|
1020
|
+
.get(primary_ip4__address=ipv4_address)
|
|
1021
|
+
)
|
|
1022
|
+
other_device.snapshot()
|
|
1023
|
+
other_device.primary_ip4 = None
|
|
1024
|
+
other_device.save(using=connection_name)
|
|
1025
|
+
except Device.DoesNotExist:
|
|
1026
|
+
# There is no other device with this IP as primary, all good
|
|
1027
|
+
pass
|
|
1028
|
+
except Exception as err:
|
|
1029
|
+
# The transform maps might be changed, and we fail to resolve the template
|
|
1030
|
+
# Make sure this does not crash the sync and is handled gracefully
|
|
1031
|
+
_, issue = self.create_or_get_sync_issue(
|
|
1032
|
+
exception=err,
|
|
1033
|
+
ingestion=self.ingestion,
|
|
1034
|
+
message="Error removing primary IP from other device.",
|
|
1035
|
+
model=ip_address.model,
|
|
1036
|
+
data=ip_address.data,
|
|
1037
|
+
)
|
|
1038
|
+
self.events_clearer.increment()
|
|
1039
|
+
raise IPAddressPrimaryRemovalError(
|
|
1040
|
+
data=ip_address.data,
|
|
1041
|
+
model=ip_address.model,
|
|
1042
|
+
issue_id=issue.pk,
|
|
1043
|
+
) from err
|
|
1044
|
+
|
|
1045
|
+
ip_address_obj: "IPAddress | None" = self.sync_item(record=ip_address)
|
|
1046
|
+
if ip_address_obj is None or ip_address_obj.assigned_object is None:
|
|
1047
|
+
self.events_clearer.increment()
|
|
1015
1048
|
return
|
|
1016
1049
|
|
|
1017
|
-
|
|
1018
|
-
connection_name = self.get_db_connection_name()
|
|
1050
|
+
parent_device = ip_address_obj.assigned_object.parent_object
|
|
1019
1051
|
|
|
1020
|
-
|
|
1021
|
-
|
|
1052
|
+
# Now assign this IP as primary to the parent device, if not assigned yet or assigned to different IP
|
|
1053
|
+
if ip_address.data.get("is_primary") and (
|
|
1054
|
+
not parent_device.primary_ip4
|
|
1055
|
+
or parent_device.primary_ip4.pk != ip_address_obj.pk
|
|
1056
|
+
):
|
|
1022
1057
|
try:
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
).template,
|
|
1027
|
-
{"object": ip_address.data},
|
|
1028
|
-
)
|
|
1029
|
-
other_device = (
|
|
1030
|
-
Device.objects.using(connection_name)
|
|
1031
|
-
.exclude(serial=serial(ip_address.data))
|
|
1032
|
-
.get(primary_ip4__address=ipv4_address)
|
|
1033
|
-
)
|
|
1034
|
-
other_device.snapshot()
|
|
1035
|
-
other_device.primary_ip4 = None
|
|
1036
|
-
other_device.save(using=connection_name)
|
|
1037
|
-
except Device.DoesNotExist:
|
|
1038
|
-
# There is no other device with this IP as primary, all good
|
|
1039
|
-
pass
|
|
1058
|
+
parent_device.snapshot()
|
|
1059
|
+
parent_device.primary_ip4 = ip_address_obj
|
|
1060
|
+
parent_device.save(using=connection_name)
|
|
1040
1061
|
except Exception as err:
|
|
1041
|
-
# The transform maps might be changed, and we fail to resolve the template
|
|
1042
|
-
# Make sure this does not crash the sync and is handled gracefully
|
|
1043
1062
|
_, issue = self.create_or_get_sync_issue(
|
|
1044
1063
|
exception=err,
|
|
1045
1064
|
ingestion=self.ingestion,
|
|
1046
|
-
message="Error
|
|
1065
|
+
message="Error assigning primary IP to device.",
|
|
1047
1066
|
model=ip_address.model,
|
|
1048
1067
|
data=ip_address.data,
|
|
1049
1068
|
)
|
|
1050
1069
|
self.events_clearer.increment()
|
|
1051
|
-
raise
|
|
1070
|
+
raise IPAddressPrimaryAssignmentError(
|
|
1052
1071
|
data=ip_address.data,
|
|
1053
1072
|
model=ip_address.model,
|
|
1054
1073
|
issue_id=issue.pk,
|
|
1055
1074
|
) from err
|
|
1075
|
+
self.events_clearer.increment()
|
|
1056
1076
|
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1077
|
+
@handle_errors
|
|
1078
|
+
def sync_ip_addresses(self, ip_addresses: set[DataRecord]) -> None:
|
|
1079
|
+
"""
|
|
1080
|
+
We cannot assign primary IP in signals since IPAddress does not
|
|
1081
|
+
contain information whether it is primary or not. And it must be done
|
|
1082
|
+
on Device object, so cannot be done via Transform Maps yet since that
|
|
1083
|
+
would require another Transform Map for Device.
|
|
1084
|
+
So we need to do it manually here.
|
|
1061
1085
|
|
|
1062
|
-
|
|
1086
|
+
Cleaning events queue happens during each cycle to make sure all required
|
|
1087
|
+
operations (primary IP assignment) happen during the same batch.
|
|
1088
|
+
"""
|
|
1089
|
+
if not self.settings.get("ipaddress"):
|
|
1090
|
+
self.logger.log_info(
|
|
1091
|
+
"Did not ask to sync ipaddresses, skipping.", obj=self.sync
|
|
1092
|
+
)
|
|
1093
|
+
return
|
|
1063
1094
|
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
not parent_device.primary_ip4
|
|
1067
|
-
or parent_device.primary_ip4.pk != ip_address_obj.pk
|
|
1068
|
-
):
|
|
1069
|
-
try:
|
|
1070
|
-
parent_device.snapshot()
|
|
1071
|
-
parent_device.primary_ip4 = ip_address_obj
|
|
1072
|
-
parent_device.save(using=connection_name)
|
|
1073
|
-
except (ValueError, AttributeError) as err:
|
|
1074
|
-
self.logger.log_failure(
|
|
1075
|
-
f"Error assigning primary IP to device: {err}", obj=self.sync
|
|
1076
|
-
)
|
|
1077
|
-
self.events_clearer.increment()
|
|
1095
|
+
for ip_address in ip_addresses:
|
|
1096
|
+
self.sync_ipaddress(ip_address)
|
|
1078
1097
|
|
|
1079
1098
|
def collect_and_sync(self, ingestion=None) -> None:
|
|
1080
1099
|
self.logger.log_info("Starting data collection.", obj=self.sync)
|
|
@@ -1092,15 +1111,24 @@ class IPFabricSyncRunner(object):
|
|
|
1092
1111
|
self.sync_items(items=records["devicetype"])
|
|
1093
1112
|
self.sync_items(items=records["platform"])
|
|
1094
1113
|
self.sync_items(items=records["devicerole"])
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1114
|
+
try:
|
|
1115
|
+
# This signal does not call for snapshot(), causing issue with branching plugin
|
|
1116
|
+
signals.post_save.disconnect(
|
|
1117
|
+
assign_virtualchassis_master, sender=VirtualChassis
|
|
1118
|
+
)
|
|
1119
|
+
self.sync_items(items=records["virtualchassis"])
|
|
1120
|
+
self.sync_devices(
|
|
1121
|
+
devices=records["device"],
|
|
1122
|
+
cf=self.sync.update_custom_fields,
|
|
1123
|
+
ingestion=ingestion,
|
|
1124
|
+
)
|
|
1125
|
+
# The Device exists now, so we can update the master of the VC.
|
|
1126
|
+
# The logic is handled in transform maps.
|
|
1127
|
+
self.sync_items(items=records["virtualchassis"], stats=False)
|
|
1128
|
+
finally:
|
|
1129
|
+
signals.post_save.connect(
|
|
1130
|
+
assign_virtualchassis_master, sender=VirtualChassis
|
|
1131
|
+
)
|
|
1104
1132
|
self.sync_items(items=records["interface"])
|
|
1105
1133
|
self.sync_items(items=records["macaddress"])
|
|
1106
1134
|
self.sync_items(items=records["inventoryitem"])
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/migrations/0001_initial.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/templatetags/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ipfabric_netbox-4.3.2b7 → ipfabric_netbox-4.3.2b9}/ipfabric_netbox/utilities/transform_map.py
RENAMED
|
File without changes
|
|
File without changes
|