Files
NetBox-Concept/netbox_rack_concept/__init__.py
T
MrBlakeandClaude Sonnet 5 b289bc5aeb Mirror device cabling 1:1 (per-type tabs) and copy cables on rack import
- Split the device detail page's single "Components" table into the
  same seven tabs a real dcim.Device has, in the same order: Console
  Ports, Console Server Ports, Power Ports, Power Outlets, Interfaces,
  Front Ports, Rear Ports. Each tab is its own ObjectChildrenView
  filtered by component_type (one ConceptComponent model backs all of
  them, so this only needed the view/URL layer, not a schema change),
  hidden when empty, exactly like core NetBox. Replace the ad hoc "Add
  component" button with the same "Add Components" dropdown real
  device pages use, one entry per type, each landing back on its own
  tab.
- When copying a real rack into a concept (or merging two real racks
  into one), automatically sync every copied device's components and
  recreate, as ConceptCables, every real cable whose both ends land on
  one of those devices - reading the same CableTermination data dcim
  itself uses, so the copy comes out cabled internally the same as the
  source. Cables reaching outside the copied rack(s), or multi-
  termination trunk cables, are skipped and reported as a count in the
  success message - the other end isn't part of the concept, so it
  can't be represented. copy_rack_to_concept() and
  merge_racks_to_concept() now return an extra cable_summary value;
  updated all their callers (views and API).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 10:34:26 +02:00

50 lines
1.7 KiB
Python

from netbox.plugins import PluginConfig
__version__ = '0.1.0'
class RackConceptConfig(PluginConfig):
name = 'netbox_rack_concept'
verbose_name = 'NetBox Rack Concepts'
description = 'Rack blueprints: plan racks and their equipment without creating real racks or devices'
version = __version__
author = 'Claude'
base_url = 'rack-concepts'
min_version = '4.6.0'
max_version = '4.6.99'
# These paths are relative to this module (NetBox prepends self.__module__),
# so they must NOT be prefixed with 'netbox_rack_concept.' again.
menu = 'navigation.menu'
template_extensions = 'template_content.template_extensions'
default_settings = {
# Defaults used when a concept is created from scratch.
'default_u_height': 42,
'default_width': 19,
# Show the "Copy to concept" button on the dcim.Rack detail page.
'enable_rack_tab': True,
# Status assigned to the objects created when a concept is deployed.
'deployed_rack_status': 'planned',
'deployed_device_status': 'planned',
# Mapping onto the partial-width implementation of netbox_utilities.
# Adjust these if that plugin renames its fields; set 'enabled' to False
# to never write partial-width data during deployment.
'partial_width': {
'enabled': True,
'model': 'netbox_utilities.RackDevicePosition',
'device_field': 'device',
'fraction_field': 'width_fraction',
'position_field': 'horizontal_position',
},
}
def ready(self):
super().ready()
from . import search # noqa: F401
config = RackConceptConfig