Files
network-diagrams-tool/src_old/old/structures.py
T
2026-02-16 01:35:03 +03:00

183 lines
5.4 KiB
Python

from dataclasses import dataclass, field
from typing import List, Optional, Dict
# ===========================
# Interface Classes
# ===========================
@dataclass
class Interface:
name: str
ip_address: Optional[str] = None
mac_address: Optional[str] = None
speed: Optional[str] = None
duplex: Optional[str] = None
def __init__(self, fields):
self.name = fields.get("name")
self.ip_address = fields.get("ip")
self.mac_address = fields.get("mac")
self.speed = fields.get("speed")
self.duplex = fields.get("duplex")
self.__post_init__()
def __post_init__(self):
if not isinstance(self.name, str) or not self.name:
raise ValueError("Interface 'name' must be a non-empty string")
@dataclass
class VirtualInterface(Interface):
vlan_id: int = 0
parent_physical: Optional[Interface] = None
def __init__(self, fields):
super().__init__(fields)
self.vlan_id = fields.get("vlanID", fields.get("vlan_id", 0))
self.parent_physical = fields.get(
"parent_physical", fields.get("parentPhysical", fields.get("parent"))
)
self.__post_init__()
def __post_init__(self):
super().__post_init__()
if not isinstance(self.vlan_id, int) or self.vlan_id < 0:
raise ValueError(
"VirtualInterface 'vlan_id' must be a non-negative integer"
)
if not isinstance(self.parent_physical, Interface):
raise TypeError(
"VirtualInterface 'parent_physical' must reference an Interface"
)
# ===========================
# Network / Subnet
# ===========================
@dataclass
class Network:
cidr: str
gateway: Optional[str] = None
interfaces: List[Interface] = field(default_factory=list)
def __init__(self, fields):
self.cidr = fields.get("cidr")
self.gateway = fields.get("gateway")
interfaces = fields.get("interfaces", [])
if isinstance(interfaces, str):
interfaces = [iface for iface in interfaces.split(",") if iface]
self.interfaces = interfaces
self.__post_init__()
def __post_init__(self):
if not isinstance(self.cidr, str) or not self.cidr:
raise ValueError("Network 'cidr' must be a non-empty string")
if self.gateway is not None and not isinstance(self.gateway, str):
raise ValueError("Network 'gateway' must be a string")
# ===========================
# Device Base Class (Abstract)
# ===========================
@dataclass
class Device:
name: str
mgmt_ip: Optional[str] = None
interfaces: List[Interface] = field(default_factory=list)
def __init__(self, fields):
self.name = fields.get("name")
self.mgmt_ip = fields.get("mgmtIP")
self.interfaces = [f for f in fields.get("interfaces").split(",") if f]
self.__post_init__()
def __post_init__(self):
if not isinstance(self.name, str) or not self.name:
raise ValueError("Device 'name' must be a non-empty string")
if self.mgmt_ip is not None and not isinstance(self.mgmt_ip, str):
raise ValueError("Device 'mgmtIP' must be a string")
# ===========================
# Host / Router / Switch
# ===========================
@dataclass
class Host(Device):
operating_system: Optional[str] = None
def __init__(self, fields):
super().__init__(fields)
self.operating_system = fields.get("operatingSystem")
self.__post_init__()
def __post_init__(self):
super().__post_init__()
if not isinstance(self.operating_system, str):
raise ValueError("Host 'operatingSystem' must be a string")
@dataclass
class Router(Device):
routing_table: Dict[str, str] = field(default_factory=dict)
routing_protocols: List[str] = field(default_factory=list)
def __init__(self, fields):
super().__init__(fields)
self.routing_table = fields.get("routingTable", {})
self.routing_protocols = fields.get("routingProtocols", [])
self.__post_init__()
def __post_init__(self):
super().__post_init__()
@dataclass
class Switch(Device):
mac_table: Dict[str, str] = field(default_factory=dict)
vlan_database: Dict[int, str] = field(default_factory=dict)
def __init__(self, fields):
super().__init__(fields)
self.mac_table = fields.get("macTable", {})
self.vlan_database = fields.get("vlanDatabase", {})
self.__post_init__()
def __post_init__(self):
super().__post_init__()
# ===========================
# Physical Link (Wire)
# ===========================
@dataclass
class Wire:
id: str
endpoints: List[Interface] # Must contain exactly 2 interfaces
bandwidth: Optional[str] = None
def __init__(self, fields):
self.id = fields.get("name")
self.endpoints = [ep for ep in fields.get("endpoints").split(",") if ep]
self.bandwidth = fields.get("bandwidth")
self.__post_init__()
def __post_init__(self):
if not isinstance(self.id, str) or not self.id:
raise ValueError("Wire 'id' must be a non-empty string")
if len(self.endpoints) != 2:
raise ValueError(
"Wire 'endpoints' must contain exactly 2 Interface objects"
)
if not all(isinstance(i, Interface) for i in self.endpoints):
raise TypeError("Wire 'endpoints' must be Interface objects")