Coverage for netbox_data_import/template_content.py: 100%
16 statements
« prev ^ index » next coverage.py v7.16.0, created at 2026-09-09 20:50 +0000
« prev ^ index » next coverage.py v7.16.0, created at 2026-09-09 20:50 +0000
1# SPDX-License-Identifier: Apache-2.0
2# Copyright (C) 2025 Marcin Zieba <marcinpsk@gmail.com>
3from netbox.plugins import PluginTemplateExtension
5from .models import stored_import_source
7IP_FIELD_LABELS = {
8 "primary_ip4": "Primary IPv4",
9 "primary_ip6": "Primary IPv6",
10 "oob_ip": "Out-of-band IP",
11}
14class DeviceImportDataExtension(PluginTemplateExtension):
15 """Adds an import data card to the Device detail page.
17 NetBox appends plugin content to the end of a column, so the closest supported position to
18 the Tags panel is the left column, below the rack elevation drawing that ends the right one.
19 """
21 models = ["dcim.device"]
23 def left_page(self):
24 """Render import data card for the Device detail page left column."""
25 obj = self.context.get("object")
26 import_source = stored_import_source(obj)
27 if import_source is None:
28 return ""
30 # Show which of the stored IPs NetBox now holds natively.
31 ip_status = {}
32 for field, value in import_source.unassigned_ips.items():
33 native = getattr(obj, field, None)
34 ip_status[field] = {
35 "label": IP_FIELD_LABELS.get(field, field),
36 "value": value,
37 "in_netbox": bool(native),
38 "native_value": str(native.address) if native is not None and hasattr(native, "address") else "",
39 }
41 return self.render(
42 "netbox_data_import/device_import_data.html",
43 extra_context={
44 "import_source": import_source,
45 "extra_columns": import_source.extra_columns,
46 "ip_status": ip_status,
47 "device": obj,
48 },
49 )
52template_extensions = [DeviceImportDataExtension]