"""Subnet and VLAN models for network plugin.""" from shopdb.extensions import db from shopdb.core.models.base import BaseModel class VLAN(BaseModel): """ VLAN definition. Represents a virtual LAN for network segmentation. """ __tablename__ = 'vlans' vlanid = db.Column(db.Integer, primary_key=True) vlannumber = db.Column(db.Integer, unique=True, nullable=False, comment='VLAN ID number') name = db.Column(db.String(100), nullable=False, comment='VLAN name') description = db.Column(db.Text, nullable=True) # Optional classification vlantype = db.Column( db.String(50), nullable=True, comment='Type: data, voice, management, guest, etc.' ) # Relationships subnets = db.relationship('Subnet', backref='vlan', lazy='dynamic') __table_args__ = ( db.Index('idx_vlan_number', 'vlannumber'), ) def __repr__(self): return f"" def to_dict(self): """Convert to dictionary.""" result = super().to_dict() result['subnetcount'] = self.subnets.count() if self.subnets else 0 return result class Subnet(BaseModel): """ Subnet/IP network definition. Represents an IP subnet with optional VLAN association. """ __tablename__ = 'subnets' subnetid = db.Column(db.Integer, primary_key=True) # Network definition cidr = db.Column( db.String(18), unique=True, nullable=False, comment='CIDR notation (e.g., 10.1.1.0/24)' ) name = db.Column(db.String(100), nullable=False, comment='Subnet name') description = db.Column(db.Text, nullable=True) # Network details gatewayip = db.Column( db.String(15), nullable=True, comment='Default gateway IP address' ) subnetmask = db.Column( db.String(15), nullable=True, comment='Subnet mask (e.g., 255.255.255.0)' ) networkaddress = db.Column( db.String(15), nullable=True, comment='Network address (e.g., 10.1.1.0)' ) broadcastaddress = db.Column( db.String(15), nullable=True, comment='Broadcast address (e.g., 10.1.1.255)' ) # VLAN association vlanid = db.Column( db.Integer, db.ForeignKey('vlans.vlanid'), nullable=True ) # Classification subnettype = db.Column( db.String(50), nullable=True, comment='Type: production, development, management, dmz, etc.' ) # Location association locationid = db.Column( db.Integer, db.ForeignKey('locations.locationid'), nullable=True ) # DHCP settings dhcpenabled = db.Column(db.Boolean, default=True, comment='DHCP enabled for this subnet') dhcprangestart = db.Column(db.String(15), nullable=True, comment='DHCP range start IP') dhcprangeend = db.Column(db.String(15), nullable=True, comment='DHCP range end IP') # DNS settings dns1 = db.Column(db.String(15), nullable=True, comment='Primary DNS server') dns2 = db.Column(db.String(15), nullable=True, comment='Secondary DNS server') # Relationships location = db.relationship('Location', backref='subnets') __table_args__ = ( db.Index('idx_subnet_cidr', 'cidr'), db.Index('idx_subnet_vlan', 'vlanid'), db.Index('idx_subnet_location', 'locationid'), ) def __repr__(self): return f"" @property def vlan_number(self): """Get the VLAN number.""" return self.vlan.vlannumber if self.vlan else None def to_dict(self): """Convert to dictionary with related data.""" result = super().to_dict() # Add VLAN info if self.vlan: result['vlannumber'] = self.vlan.vlannumber result['vlanname'] = self.vlan.name # Add location info if self.location: result['locationname'] = self.location.locationname return result