netbox-plugin-interface-sync/netbox_interface_sync/comparison.py
Victor Golovanenko 87d12f05f8
Refactored comparison.py
- Switched to using attrs instead of dataclasses
2022-01-21 11:46:26 +03:00

103 lines
3.6 KiB
Python

import attr
from attrs import fields
from django.conf import settings
config = settings.PLUGINS_CONFIG["netbox_interface_sync"]
COMPARE_DESCRIPTIONS: bool = config["compare_description"]
@attr.s(frozen=True, auto_attribs=True)
class BaseComparison:
"""Common fields of a device component"""
# Do not compare IDs
id: int = attr.ib(eq=False, hash=False, metadata={'printable': False})
# Compare names case-insensitively and spaces-insensitively
name: str = attr.ib(eq=lambda name: name.lower().replace(" ", ""), metadata={'printable': False})
label: str = attr.ib(hash=False)
# Compare descriptions if it is set by the configuration
description: str = attr.ib(eq=COMPARE_DESCRIPTIONS, hash=False)
# Do not compare `is_template` properties
is_template: bool = attr.ib(kw_only=True, default=False, eq=False, hash=False, metadata={'printable': False})
@property
def fields_display(self) -> str:
"""Generate human-readable list of printable fields to display in the comparison table"""
fields_to_display = []
for field in fields(self.__class__):
if not field.metadata.get('printable', True):
continue
field_value = getattr(self, field.name)
if not field_value:
continue
field_caption = field.metadata.get('displayed_caption') or field.name.replace('_', ' ').capitalize()
fields_to_display.append(f'{field_caption}: {field_value}')
return '\n'.join(fields_to_display)
@attr.s(frozen=True, auto_attribs=True)
class BaseTypedComparison(BaseComparison):
"""Common fields of a device typed component"""
type: str = attr.ib(hash=False, metadata={'printable': False})
type_display: str = attr.ib(eq=False, hash=False, metadata={'displayed_caption': 'Type'})
@attr.s(frozen=True, auto_attribs=True)
class DeviceBayComparison(BaseComparison):
"""A unified way to represent the device bay and device bay template"""
pass
@attr.s(frozen=True, auto_attribs=True)
class InterfaceComparison(BaseTypedComparison):
"""A unified way to represent the interface and interface template"""
mgmt_only: bool = attr.ib(hash=False)
@attr.s(frozen=True, auto_attribs=True)
class FrontPortComparison(BaseTypedComparison):
"""A unified way to represent the front port and front port template"""
color: str = attr.ib(hash=False)
# rear_port_id: int
rear_port_position: int = attr.ib(hash=False, metadata={'displayed_caption': 'Position'})
@attr.s(frozen=True, auto_attribs=True)
class RearPortComparison(BaseTypedComparison):
"""A unified way to represent the rear port and rear port template"""
color: str = attr.ib(hash=False)
positions: int = attr.ib(hash=False)
@attr.s(frozen=True, auto_attribs=True)
class ConsolePortComparison(BaseTypedComparison):
"""A unified way to represent the consoleport and consoleport template"""
pass
@attr.s(frozen=True, auto_attribs=True)
class ConsoleServerPortComparison(BaseTypedComparison):
"""A unified way to represent the consoleserverport and consoleserverport template"""
pass
@attr.s(frozen=True, auto_attribs=True)
class PowerPortComparison(BaseTypedComparison):
"""A unified way to represent the power port and power port template"""
maximum_draw: str = attr.ib(hash=False)
allocated_draw: str = attr.ib(hash=False)
@attr.s(frozen=True, auto_attribs=True)
class PowerOutletComparison(BaseTypedComparison):
"""A unified way to represent the power outlet and power outlet template"""
power_port_name: str = attr.ib(hash=False)
feed_leg: str = attr.ib(hash=False)