ipfabric_netbox 4.3.2b9__py3-none-any.whl → 4.3.2b11__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 (50) hide show
  1. ipfabric_netbox/__init__.py +1 -1
  2. ipfabric_netbox/api/serializers.py +112 -7
  3. ipfabric_netbox/api/urls.py +6 -0
  4. ipfabric_netbox/api/views.py +23 -0
  5. ipfabric_netbox/choices.py +74 -40
  6. ipfabric_netbox/data/endpoint.json +52 -0
  7. ipfabric_netbox/data/filters.json +51 -0
  8. ipfabric_netbox/data/transform_map.json +190 -176
  9. ipfabric_netbox/exceptions.py +7 -5
  10. ipfabric_netbox/filtersets.py +310 -41
  11. ipfabric_netbox/forms.py +330 -80
  12. ipfabric_netbox/graphql/__init__.py +6 -0
  13. ipfabric_netbox/graphql/enums.py +5 -5
  14. ipfabric_netbox/graphql/filters.py +56 -4
  15. ipfabric_netbox/graphql/schema.py +28 -0
  16. ipfabric_netbox/graphql/types.py +61 -1
  17. ipfabric_netbox/jobs.py +12 -1
  18. ipfabric_netbox/migrations/0022_prepare_for_filters.py +182 -0
  19. ipfabric_netbox/migrations/0023_populate_filters_data.py +303 -0
  20. ipfabric_netbox/migrations/0024_finish_filters.py +29 -0
  21. ipfabric_netbox/migrations/0025_add_vss_chassis_endpoint.py +166 -0
  22. ipfabric_netbox/models.py +432 -17
  23. ipfabric_netbox/navigation.py +98 -24
  24. ipfabric_netbox/tables.py +194 -9
  25. ipfabric_netbox/templates/ipfabric_netbox/htmx_list.html +5 -0
  26. ipfabric_netbox/templates/ipfabric_netbox/inc/combined_expressions.html +59 -0
  27. ipfabric_netbox/templates/ipfabric_netbox/inc/combined_expressions_content.html +39 -0
  28. ipfabric_netbox/templates/ipfabric_netbox/inc/endpoint_filters_with_selector.html +54 -0
  29. ipfabric_netbox/templates/ipfabric_netbox/ipfabricendpoint.html +39 -0
  30. ipfabric_netbox/templates/ipfabric_netbox/ipfabricfilter.html +51 -0
  31. ipfabric_netbox/templates/ipfabric_netbox/ipfabricfilterexpression.html +39 -0
  32. ipfabric_netbox/templates/ipfabric_netbox/ipfabricfilterexpression_edit.html +150 -0
  33. ipfabric_netbox/templates/ipfabric_netbox/ipfabricsync.html +1 -1
  34. ipfabric_netbox/templates/ipfabric_netbox/ipfabrictransformmap.html +16 -2
  35. ipfabric_netbox/templatetags/ipfabric_netbox_helpers.py +68 -0
  36. ipfabric_netbox/tests/api/test_api.py +333 -13
  37. ipfabric_netbox/tests/test_filtersets.py +2592 -0
  38. ipfabric_netbox/tests/test_forms.py +1349 -74
  39. ipfabric_netbox/tests/test_models.py +242 -34
  40. ipfabric_netbox/tests/test_views.py +2031 -26
  41. ipfabric_netbox/urls.py +35 -0
  42. ipfabric_netbox/utilities/endpoint.py +83 -0
  43. ipfabric_netbox/utilities/filters.py +88 -0
  44. ipfabric_netbox/utilities/ipfutils.py +393 -377
  45. ipfabric_netbox/utilities/logging.py +7 -7
  46. ipfabric_netbox/utilities/transform_map.py +144 -5
  47. ipfabric_netbox/views.py +719 -5
  48. {ipfabric_netbox-4.3.2b9.dist-info → ipfabric_netbox-4.3.2b11.dist-info}/METADATA +2 -2
  49. {ipfabric_netbox-4.3.2b9.dist-info → ipfabric_netbox-4.3.2b11.dist-info}/RECORD +50 -33
  50. {ipfabric_netbox-4.3.2b9.dist-info → ipfabric_netbox-4.3.2b11.dist-info}/WHEEL +1 -1
@@ -4,47 +4,58 @@
4
4
  "created": null,
5
5
  "last_updated": null,
6
6
  "custom_field_data": {},
7
- "name": "IP Address Transform Map",
8
- "source_model": "ipaddress",
7
+ "name": "Site Transform Map",
8
+ "source_endpoint": "/inventory/sites/overview",
9
9
  "target_model": {
10
- "app_label": "ipam",
11
- "model": "ipaddress"
12
- }
10
+ "app_label": "dcim",
11
+ "model": "site"
12
+ },
13
+ "parents": null
13
14
  },
14
15
  "field_maps": [
15
16
  {
16
- "source_field": "sn",
17
- "target_field": "assigned_object_id",
18
- "coalesce": false,
19
- "template": "{% if object.nameOriginal %}{{ dcim.Interface.objects.filter(device__serial=object.sn, name=object.nameOriginal).first().pk }}{% else %}{{ dcim.Interface.objects.filter(device__serial=object.sn, name=object.intName).first().pk }}{% endif %}"
17
+ "source_field": "siteName",
18
+ "target_field": "slug",
19
+ "coalesce": true,
20
+ "template": "{{ object.siteName | slugify }}"
20
21
  },
21
22
  {
22
- "source_field": "net",
23
- "target_field": "address",
24
- "coalesce": true,
25
- "template": "{% if object.net %}{% set MASK = object.net.split('/')[1] %}{% else %}{% set MASK = 32 %}{% endif %}{{ object.ip }}/{{MASK}}"
23
+ "source_field": "siteName",
24
+ "target_field": "name",
25
+ "coalesce": false,
26
+ "template": ""
26
27
  }
27
28
  ],
28
- "relationship_maps": [
29
- {
30
- "source_model": {
31
- "app_label": "contenttypes",
32
- "model": "contenttype"
33
- },
34
- "target_field": "assigned_object_type",
35
- "coalesce": false,
36
- "template": "{{ contenttypes.ContentType.objects.get(app_label=\"dcim\", model=\"interface\").pk }}"
29
+ "relationship_maps": []
30
+ },
31
+ {
32
+ "data": {
33
+ "created": null,
34
+ "last_updated": null,
35
+ "custom_field_data": {},
36
+ "name": "Manufacturer Transform Map",
37
+ "source_endpoint": "/inventory/devices",
38
+ "target_model": {
39
+ "app_label": "dcim",
40
+ "model": "manufacturer"
37
41
  },
42
+ "parents": "dcim.site"
43
+ },
44
+ "field_maps": [
38
45
  {
39
- "source_model": {
40
- "app_label": "ipam",
41
- "model": "vrf"
42
- },
43
- "target_field": "vrf",
46
+ "source_field": "vendor",
47
+ "target_field": "slug",
44
48
  "coalesce": true,
45
- "template": "{% if object.vrf is defined and object.vrf | string not in [\"\", \"system\", \"0\", \"global\"] %}{{ ipam.VRF.objects.filter(name=object.vrf).first().pk }}{% else %}None{% endif %}"
49
+ "template": "{{ object.vendor | slugify }}"
50
+ },
51
+ {
52
+ "source_field": "vendor",
53
+ "target_field": "name",
54
+ "coalesce": false,
55
+ "template": ""
46
56
  }
47
- ]
57
+ ],
58
+ "relationship_maps": []
48
59
  },
49
60
  {
50
61
  "data": {
@@ -52,11 +63,12 @@
52
63
  "last_updated": null,
53
64
  "custom_field_data": {},
54
65
  "name": "Platform Transform Map",
55
- "source_model": "device",
66
+ "source_endpoint": "/inventory/devices",
56
67
  "target_model": {
57
68
  "app_label": "dcim",
58
69
  "model": "platform"
59
- }
70
+ },
71
+ "parents": "dcim.manufacturer"
60
72
  },
61
73
  "field_maps": [
62
74
  {
@@ -89,50 +101,101 @@
89
101
  "created": null,
90
102
  "last_updated": null,
91
103
  "custom_field_data": {},
92
- "name": "Site Transform Map",
93
- "source_model": "site",
104
+ "name": "Device Type Transform Map",
105
+ "source_endpoint": "/inventory/devices",
94
106
  "target_model": {
95
107
  "app_label": "dcim",
96
- "model": "site"
97
- }
108
+ "model": "devicetype"
109
+ },
110
+ "parents": "dcim.manufacturer"
98
111
  },
99
112
  "field_maps": [
100
113
  {
101
- "source_field": "siteName",
114
+ "source_field": "model",
102
115
  "target_field": "slug",
103
116
  "coalesce": true,
104
- "template": "{{ object.siteName | slugify }}"
117
+ "template": "{% if object.model %}{{ object.model | string | slugify }}{% else %}{{ object.vendor | slugify }}-{{ object.family | slugify}}-{{ object.platform | slugify }}{% endif %}"
105
118
  },
106
119
  {
107
- "source_field": "siteName",
108
- "target_field": "name",
120
+ "source_field": "model",
121
+ "target_field": "model",
109
122
  "coalesce": false,
110
- "template": ""
123
+ "template": "{% if object.model %}{{ object.model | string }}{% else %}{{ object.vendor }} - {{ object.family }} - {{ object.platform }}{% endif %}"
111
124
  }
112
125
  ],
113
- "relationship_maps": []
126
+ "relationship_maps": [
127
+ {
128
+ "source_model": {
129
+ "app_label": "dcim",
130
+ "model": "manufacturer"
131
+ },
132
+ "target_field": "manufacturer",
133
+ "coalesce": false,
134
+ "template": "{% set SLUG = object.vendor | slugify %}\n{{ dcim.Manufacturer.objects.get(slug=SLUG).pk }}"
135
+ }
136
+ ]
114
137
  },
115
138
  {
116
139
  "data": {
117
140
  "created": null,
118
141
  "last_updated": null,
119
142
  "custom_field_data": {},
120
- "name": "Manufacturer Transform Map",
121
- "source_model": "device",
143
+ "name": "Virtual Chassis Transform Map",
144
+ "source_endpoint": "/technology/platforms/stack/members",
122
145
  "target_model": {
123
146
  "app_label": "dcim",
124
- "model": "manufacturer"
147
+ "model": "virtualchassis"
148
+ },
149
+ "parents": "dcim.manufacturer"
150
+ },
151
+ "field_maps": [
152
+ {
153
+ "source_field": "master",
154
+ "target_field": "name",
155
+ "coalesce": true,
156
+ "template": "{% if object.master is defined and object.master %}{{ object.master }}{% else %}{{ object.hostname }}{% endif %}"
157
+ }
158
+ ],
159
+ "relationship_maps": [
160
+ {
161
+ "source_model": {
162
+ "app_label": "dcim",
163
+ "model": "device"
164
+ },
165
+ "target_field": "master",
166
+ "coalesce": false,
167
+ "template": "{% set DEVICE = dcim.Device.objects.filter(serial=object.sn).first() %}{% if DEVICE %}{{ DEVICE.pk }}{% endif %}"
125
168
  }
169
+ ]
170
+ },
171
+ {
172
+ "data": {
173
+ "created": null,
174
+ "last_updated": null,
175
+ "custom_field_data": {},
176
+ "name": "Device Role Transform Map",
177
+ "source_endpoint": "/inventory/devices",
178
+ "target_model": {
179
+ "app_label": "dcim",
180
+ "model": "devicerole"
181
+ },
182
+ "parents": "dcim.site"
126
183
  },
127
184
  "field_maps": [
128
185
  {
129
- "source_field": "vendor",
186
+ "source_field": "devType",
130
187
  "target_field": "slug",
131
188
  "coalesce": true,
132
- "template": "{{ object.vendor | slugify }}"
189
+ "template": "{{ object.devType | slugify }}"
133
190
  },
134
191
  {
135
- "source_field": "vendor",
192
+ "source_field": "devType",
193
+ "target_field": "vm_role",
194
+ "coalesce": true,
195
+ "template": "False"
196
+ },
197
+ {
198
+ "source_field": "devType",
136
199
  "target_field": "name",
137
200
  "coalesce": false,
138
201
  "template": ""
@@ -146,11 +209,12 @@
146
209
  "last_updated": null,
147
210
  "custom_field_data": {},
148
211
  "name": "Device Transform Map",
149
- "source_model": "device",
212
+ "source_endpoint": "/inventory/devices",
150
213
  "target_model": {
151
214
  "app_label": "dcim",
152
215
  "model": "device"
153
- }
216
+ },
217
+ "parents": "dcim.devicetype"
154
218
  },
155
219
  "field_maps": [
156
220
  {
@@ -169,7 +233,7 @@
169
233
  "source_field": "hostname",
170
234
  "target_field": "vc_position",
171
235
  "coalesce": false,
172
- "template": "{% if object.virtual_chassis %}{{ object.virtual_chassis.member }}{% else %}None{% endif %}"
236
+ "template": "{% if object.virtual_chassis %}{% if object.virtual_chassis.member is defined and object.virtual_chassis.member %}{{ object.virtual_chassis.member }}{% else %}{{ object.virtual_chassis.chassisId }}{% endif %}{% else %}None{% endif %}"
173
237
  }
174
238
  ],
175
239
  "relationship_maps": [
@@ -180,7 +244,7 @@
180
244
  },
181
245
  "target_field": "virtual_chassis",
182
246
  "coalesce": false,
183
- "template": "{% if object.virtual_chassis %}{{ dcim.VirtualChassis.objects.filter(name=object.virtual_chassis.master).first().pk }}{% endif %}"
247
+ "template": "{% if object.virtual_chassis %}{% if object.virtual_chassis.master is defined and object.virtual_chassis.master %}{{ dcim.VirtualChassis.objects.filter(name=object.virtual_chassis.master).first().pk }}{% else %}{{ dcim.VirtualChassis.objects.filter(name=object.virtual_chassis.hostname).first().pk }}{% endif %}{% endif %}"
184
248
  },
185
249
  {
186
250
  "source_model": {
@@ -225,62 +289,44 @@
225
289
  "created": null,
226
290
  "last_updated": null,
227
291
  "custom_field_data": {},
228
- "name": "Device Role Transform Map",
229
- "source_model": "device",
292
+ "name": "Inventory Transform Map",
293
+ "source_endpoint": "/inventory/part-numbers",
230
294
  "target_model": {
231
295
  "app_label": "dcim",
232
- "model": "devicerole"
233
- }
296
+ "model": "inventoryitem"
297
+ },
298
+ "parents": "dcim.device"
234
299
  },
235
300
  "field_maps": [
236
301
  {
237
- "source_field": "devType",
238
- "target_field": "slug",
239
- "coalesce": true,
240
- "template": "{{ object.devType | slugify }}"
302
+ "source_field": "pid",
303
+ "target_field": "part_id",
304
+ "coalesce": false,
305
+ "template": "{% if object.pid and object.pid != \"None\" %}{{ object.pid }}{% else %}unknown{% endif %}"
241
306
  },
242
307
  {
243
- "source_field": "devType",
244
- "target_field": "vm_role",
308
+ "source_field": "sn",
309
+ "target_field": "serial",
245
310
  "coalesce": true,
246
- "template": "False"
311
+ "template": ""
247
312
  },
248
313
  {
249
- "source_field": "devType",
314
+ "source_field": "name",
250
315
  "target_field": "name",
251
- "coalesce": false,
252
- "template": ""
316
+ "coalesce": true,
317
+ "template": "{% if object.name is not none %}{{ object.name | string | truncate(64, True) }}{% elif object.dscr is not none %}{{ object.dscr | string | truncate(64, True) }}{% else %}Default Name{% endif %}"
253
318
  }
254
319
  ],
255
- "relationship_maps": []
256
- },
257
- {
258
- "data": {
259
- "created": null,
260
- "last_updated": null,
261
- "custom_field_data": {},
262
- "name": "Device Type Transform Map",
263
- "source_model": "device",
264
- "target_model": {
265
- "app_label": "dcim",
266
- "model": "devicetype"
267
- }
268
- },
269
- "field_maps": [
320
+ "relationship_maps": [
270
321
  {
271
- "source_field": "model",
272
- "target_field": "slug",
322
+ "source_model": {
323
+ "app_label": "dcim",
324
+ "model": "device"
325
+ },
326
+ "target_field": "device",
273
327
  "coalesce": true,
274
- "template": "{% if object.model %}{{ object.model | string | slugify }}{% else %}{{ object.vendor | slugify }}-{{ object.family | slugify}}-{{ object.platform | slugify }}{% endif %}"
328
+ "template": "{{ dcim.Device.objects.get(serial=object.deviceSn).pk }}"
275
329
  },
276
- {
277
- "source_field": "model",
278
- "target_field": "model",
279
- "coalesce": false,
280
- "template": "{% if object.model %}{{ object.model | string }}{% else %}{{ object.vendor }} - {{ object.family }} - {{ object.platform }}{% endif %}"
281
- }
282
- ],
283
- "relationship_maps": [
284
330
  {
285
331
  "source_model": {
286
332
  "app_label": "dcim",
@@ -288,7 +334,7 @@
288
334
  },
289
335
  "target_field": "manufacturer",
290
336
  "coalesce": false,
291
- "template": "{% set SLUG = object.vendor | slugify %}\n{{ dcim.Manufacturer.objects.get(slug=SLUG).pk }}"
337
+ "template": "{% if object.vendor is defined %}{% set SLUG = object.vendor | slugify %}\n{{ dcim.Manufacturer.objects.get(slug=SLUG).pk }}{% endif %}"
292
338
  }
293
339
  ]
294
340
  },
@@ -298,11 +344,12 @@
298
344
  "last_updated": null,
299
345
  "custom_field_data": {},
300
346
  "name": "Interface Transform Map",
301
- "source_model": "interface",
347
+ "source_endpoint": "/inventory/interfaces",
302
348
  "target_model": {
303
349
  "app_label": "dcim",
304
350
  "model": "interface"
305
- }
351
+ },
352
+ "parents": "dcim.device"
306
353
  },
307
354
  "field_maps": [
308
355
  {
@@ -372,88 +419,36 @@
372
419
  "last_updated": "2025-02-12T21:43:50.322Z",
373
420
  "custom_field_data": {},
374
421
  "name": "MAC Address Transform Map",
375
- "source_model": "interface",
422
+ "source_endpoint": "/inventory/interfaces",
376
423
  "target_model": {
377
424
  "app_label": "dcim",
378
425
  "model": "macaddress"
379
- }
426
+ },
427
+ "parents": "dcim.interface"
380
428
  },
381
429
  "field_maps": [
382
- {
383
- "source_field": "mac",
384
- "target_field": "mac_address",
385
- "coalesce": true,
386
- "template": "{% if object.mac %}{{ object.mac | mac_to_format(frmt=\"MAC_COLON_TWO\") | upper }}{% else %}{{ \"00:00:00:00:00:01\" | mac_to_format(frmt=\"MAC_COLON_TWO\") | upper }}{% endif %}"
387
- },
388
- {
389
- "source_field": "sn",
390
- "target_field": "assigned_object_id",
391
- "coalesce": true,
392
- "template": "{% if object.nameOriginal %}{{ dcim.Interface.objects.filter(device__serial=object.sn, name=object.nameOriginal).first().pk }}{% else %}{{ dcim.Interface.objects.filter(device__serial=object.sn, name=object.intName).first().pk }}{% endif %}"
393
- }
394
- ],
395
- "relationship_maps": [
396
430
  {
397
- "source_model": {
398
- "app_label": "contenttypes",
399
- "model": "contenttype"
400
- },
401
- "target_field": "assigned_object_type",
431
+ "source_field": "mac",
432
+ "target_field": "mac_address",
402
433
  "coalesce": true,
403
- "template": "{{ contenttypes.ContentType.objects.get(app_label=\"dcim\", model=\"interface\").pk }}"
404
- }
405
- ]
406
- },
407
- {
408
- "data": {
409
- "created": null,
410
- "last_updated": null,
411
- "custom_field_data": {},
412
- "name": "Inventory Transform Map",
413
- "source_model": "part_number",
414
- "target_model": {
415
- "app_label": "dcim",
416
- "model": "inventoryitem"
417
- }
418
- },
419
- "field_maps": [
420
- {
421
- "source_field": "pid",
422
- "target_field": "part_id",
423
- "coalesce": false,
424
- "template": "{% if object.pid and object.pid != \"None\" %}{{ object.pid }}{% else %}unknown{% endif %}"
434
+ "template": "{% if object.mac %}{{ object.mac | mac_to_format(frmt=\"MAC_COLON_TWO\") | upper }}{% else %}{{ \"00:00:00:00:00:01\" | mac_to_format(frmt=\"MAC_COLON_TWO\") | upper }}{% endif %}"
425
435
  },
426
436
  {
427
437
  "source_field": "sn",
428
- "target_field": "serial",
429
- "coalesce": true,
430
- "template": ""
431
- },
432
- {
433
- "source_field": "name",
434
- "target_field": "name",
438
+ "target_field": "assigned_object_id",
435
439
  "coalesce": true,
436
- "template": "{% if object.name is not none %}{{ object.name | string | truncate(64, True) }}{% elif object.dscr is not none %}{{ object.dscr | string | truncate(64, True) }}{% else %}Default Name{% endif %}"
440
+ "template": "{% if object.nameOriginal %}{{ dcim.Interface.objects.filter(device__serial=object.sn, name=object.nameOriginal).first().pk }}{% else %}{{ dcim.Interface.objects.filter(device__serial=object.sn, name=object.intName).first().pk }}{% endif %}"
437
441
  }
438
442
  ],
439
443
  "relationship_maps": [
440
444
  {
441
445
  "source_model": {
442
- "app_label": "dcim",
443
- "model": "device"
446
+ "app_label": "contenttypes",
447
+ "model": "contenttype"
444
448
  },
445
- "target_field": "device",
449
+ "target_field": "assigned_object_type",
446
450
  "coalesce": true,
447
- "template": "{{ dcim.Device.objects.get(serial=object.deviceSn).pk }}"
448
- },
449
- {
450
- "source_model": {
451
- "app_label": "dcim",
452
- "model": "manufacturer"
453
- },
454
- "target_field": "manufacturer",
455
- "coalesce": false,
456
- "template": "{% if object.vendor is defined %}{% set SLUG = object.vendor | slugify %}\n{{ dcim.Manufacturer.objects.get(slug=SLUG).pk }}{% endif %}"
451
+ "template": "{{ contenttypes.ContentType.objects.get(app_label=\"dcim\", model=\"interface\").pk }}"
457
452
  }
458
453
  ]
459
454
  },
@@ -463,11 +458,12 @@
463
458
  "last_updated": null,
464
459
  "custom_field_data": {},
465
460
  "name": "VLAN Transform Map",
466
- "source_model": "vlan",
461
+ "source_endpoint": "/technology/vlans/site-summary",
467
462
  "target_model": {
468
463
  "app_label": "ipam",
469
464
  "model": "vlan"
470
- }
465
+ },
466
+ "parents": "dcim.site"
471
467
  },
472
468
  "field_maps": [
473
469
  {
@@ -507,11 +503,12 @@
507
503
  "last_updated": null,
508
504
  "custom_field_data": {},
509
505
  "name": "VRF Transform Map",
510
- "source_model": "vrf",
506
+ "source_endpoint": "/technology/routing/vrf/detail",
511
507
  "target_model": {
512
508
  "app_label": "ipam",
513
509
  "model": "vrf"
514
- }
510
+ },
511
+ "parents": "ipam.vlan"
515
512
  },
516
513
  "field_maps": [
517
514
  {
@@ -535,11 +532,12 @@
535
532
  "last_updated": null,
536
533
  "custom_field_data": {},
537
534
  "name": "Prefix Transform Map",
538
- "source_model": "prefix",
535
+ "source_endpoint": "/technology/networks/managed-networks",
539
536
  "target_model": {
540
537
  "app_label": "ipam",
541
538
  "model": "prefix"
542
- }
539
+ },
540
+ "parents": "ipam.vrf"
543
541
  },
544
542
  "field_maps": [
545
543
  {
@@ -581,30 +579,46 @@
581
579
  "created": null,
582
580
  "last_updated": null,
583
581
  "custom_field_data": {},
584
- "name": "Virtual Chassis Transform Map",
585
- "source_model": "virtualchassis",
582
+ "name": "IP Address Transform Map",
583
+ "source_endpoint": "/technology/addressing/managed-ip/ipv4",
586
584
  "target_model": {
587
- "app_label": "dcim",
588
- "model": "virtualchassis"
589
- }
585
+ "app_label": "ipam",
586
+ "model": "ipaddress"
587
+ },
588
+ "parents": ["dcim.interface", "ipam.vrf"]
590
589
  },
591
590
  "field_maps": [
592
591
  {
593
- "source_field": "master",
594
- "target_field": "name",
592
+ "source_field": "sn",
593
+ "target_field": "assigned_object_id",
594
+ "coalesce": false,
595
+ "template": "{% if object.nameOriginal %}{{ dcim.Interface.objects.filter(device__serial=object.sn, name=object.nameOriginal).first().pk }}{% else %}{{ dcim.Interface.objects.filter(device__serial=object.sn, name=object.intName).first().pk }}{% endif %}"
596
+ },
597
+ {
598
+ "source_field": "net",
599
+ "target_field": "address",
595
600
  "coalesce": true,
596
- "template": ""
601
+ "template": "{% if object.net %}{% set MASK = object.net.split('/')[1] %}{% else %}{% set MASK = 32 %}{% endif %}{{ object.ip }}/{{MASK}}"
597
602
  }
598
603
  ],
599
604
  "relationship_maps": [
600
605
  {
601
606
  "source_model": {
602
- "app_label": "dcim",
603
- "model": "device"
607
+ "app_label": "contenttypes",
608
+ "model": "contenttype"
604
609
  },
605
- "target_field": "master",
610
+ "target_field": "assigned_object_type",
606
611
  "coalesce": false,
607
- "template": "{% set DEVICE = dcim.Device.objects.filter(serial=object.sn).first() %}{% if DEVICE %}{{ DEVICE.pk }}{% endif %}"
612
+ "template": "{{ contenttypes.ContentType.objects.get(app_label=\"dcim\", model=\"interface\").pk }}"
613
+ },
614
+ {
615
+ "source_model": {
616
+ "app_label": "ipam",
617
+ "model": "vrf"
618
+ },
619
+ "target_field": "vrf",
620
+ "coalesce": true,
621
+ "template": "{% if object.vrf is defined and object.vrf | string not in [\"\", \"system\", \"0\", \"global\"] %}{{ ipam.VRF.objects.filter(name=object.vrf).first().pk }}{% else %}None{% endif %}"
608
622
  }
609
623
  ]
610
624
  }
@@ -8,13 +8,15 @@ class IngestionIssue(Exception):
8
8
 
9
9
  # Store created issue object ID if it exists for this exception
10
10
  issue_id = None
11
- model: str = ""
11
+ model_string: str = ""
12
12
  defaults: dict[str, str] = {}
13
13
  coalesce_fields: dict[str, str] = {}
14
14
 
15
- def __init__(self, model: str, data: dict, context: dict = None, issue_id=None):
15
+ def __init__(
16
+ self, model_string: str, data: dict, context: dict = None, issue_id=None
17
+ ):
16
18
  super().__init__()
17
- self.model = model
19
+ self.model_string = model_string
18
20
  self.data = data
19
21
  context = context or {}
20
22
  self.defaults = context.pop("defaults", {})
@@ -33,12 +35,12 @@ class SearchError(IngestionIssue, LookupError):
33
35
 
34
36
  class SyncDataError(IngestionIssue, SyncError):
35
37
  def __str__(self):
36
- return f"Sync failed for {self.model}: coalesce_fields={self.coalesce_fields} defaults={self.defaults}."
38
+ return f"Sync failed for {self.model_string}: coalesce_fields={self.coalesce_fields} defaults={self.defaults}."
37
39
 
38
40
 
39
41
  class IPAddressDuplicateError(IngestionIssue, SyncError):
40
42
  def __str__(self):
41
- return f"IP address {self.data.get('address')} already exists in {self.model} with coalesce_fields={self.coalesce_fields}."
43
+ return f"IP address {self.data.get('address')} already exists in {self.model_string} with coalesce_fields={self.coalesce_fields}."
42
44
 
43
45
 
44
46
  class IPAddressPrimaryRemovalError(IngestionIssue, SyncError):