0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2025-01-09 18:41:55 +00:00
bird/python/BIRD/__init__.py

133 lines
3.7 KiB
Python
Raw Normal View History

2023-04-03 15:52:03 +00:00
import asyncio
from pathlib import Path
from datetime import datetime
2023-04-03 15:52:03 +00:00
from BIRD.Basic import BIRDException
from BIRD.Socket import Socket
from BIRD.Status import Status, Version
from BIRD.Protocol import ProtocolList
from BIRD.Actions import Actions
2023-04-03 15:52:03 +00:00
from BIRD.Config import Timestamp, ProtocolConfig, DeviceProtocolConfig
class Config:
def __init__(self, auto_device=True):
self._items = []
self.symbols = {}
self.auto_device = auto_device
self.add(Timestamp("Config object created"))
class FinalizedConfig:
def __init__(self, config):
self.config = config
self.auto_device = None
def __enter__(self):
if self.config.auto_device:
self.auto_device = DeviceProtocolConfig(comment="Default device protocol; set Config(auto_device=False) to remove")
self.begin = Timestamp("Config dump started")
self.config.add(self.begin)
return self
def dump(self, _file):
for i in self.config._items:
if i is None:
continue
if isinstance(i, DeviceProtocolConfig):
self.auto_device = None
i.writelines(_file)
if self.auto_device is not None:
self.auto_device.writelines(_file)
Timestamp("Config dump finished").writelines(_file)
def __exit__(self, *args):
self.config.remove(self.begin)
def finalized(self):
return self.FinalizedConfig(self)
def write(self, _file):
with self.finalized() as sf:
with open(_file, "w") as f:
sf.dump(f)
def add(self, item):
# Merge defined symbols
for s in item.symbols:
if s in self.symbols:
# Found: rollback and fail
for s in item.symbols:
if s in self.symbols:
del self.symbols[s]
raise BIRDException("Can't add item to config: symbol {s} already exists")
self.symbols[s] = item.symbols[s]
# Store backref (weak)
item.config[self] = len(self._items)
# Fwdref
self._items.append(item)
def remove(self, item):
# Check backref existence
if self not in item.config:
raise BIRDException("Can't remove item from config: isn't there")
# Remove fwdref and cleanup Nones
self._items[item.config[self]] = None
while self._items[-1] is None:
self._items.pop()
# Remove backref
del item.config[self]
2023-04-03 15:52:03 +00:00
class CLI:
def __init__(self, name):
self.socket = Socket(name)
self.connected = False
self.hello = None
async def open(self):
if self.hello is not None:
return
h = await self.socket.open()
if len(h) != 1:
raise BIRDException("CLI hello should have 1 line, has {len(h)} lines: {h}")
self.hello = h[0]
async def close(self):
if self.hello is None:
return
await self.socket.close()
self.hello = None
class BIRD:
def __init__(self, socket=Path("bird.ctl")):
self.cli = CLI(socket)
self.version = Version(bird=self)
self.status = Status(bird=self)
self.protocols = ProtocolList(bird=self)
self.actions = Actions(bird=self)
2023-04-03 15:52:03 +00:00
self.within = False
async def __aenter__(self):
if self.within:
raise BIRDException("Tried to enter BIRD context (async with) more than once")
self.within = True
return self
async def __aexit__(self, *args):
await self.cli.close()
self.within = False