Commit b11279c1 authored by Pavel Spirek's avatar Pavel Spirek

Removed dependency on pydispatcher

parent 49dfe45d
......@@ -10,9 +10,9 @@ from . import usr_op_handlers, usr_state_data_handlers
from .rest_server import RestServer
from .config import CONFIG, load_config, print_config
from .nacm import NacmConfig
from .data import JsonDatastore, BaseDataListener, SchemaNode, PathFormat, ChangeType, DataChange
from .data import JsonDatastore, BaseDataListener, SchemaNode, PathFormat, ChangeType, DataChange, ConfHandlerResult
from .helpers import DataHelpers
from .handler_list import OP_HANDLERS, STATE_DATA_HANDLES
from .handler_list import OP_HANDLERS, STATE_DATA_HANDLES, CONF_DATA_HANDLES
from .knot_api import KNOT, KnotConfig, SOARecord
......@@ -57,6 +57,7 @@ class KnotConfServerListener(BaseDataListener):
KNOT.set_item(section="server", item="rate-limit-table-size", data=base_nv.get("response-rate-limiting", {}).get("table-size"))
KNOT.commit()
return ConfHandlerResult.OK
class KnotConfLogListener(BaseDataListener):
......@@ -81,6 +82,7 @@ class KnotConfLogListener(BaseDataListener):
KNOT.set_item(section="log", identifier=tgt, item="any", data=logitem.get("any"))
KNOT.commit()
return ConfHandlerResult.OK
class KnotConfZoneListener(BaseDataListener):
......@@ -131,6 +133,7 @@ class KnotConfZoneListener(BaseDataListener):
KNOT.set_item(section="zone", zone=domain, item="semantic-checks", data=zone_nv.get("knot-dns:semantic-checks"))
KNOT.commit()
return ConfHandlerResult.OK
class KnotConfControlListener(BaseDataListener):
......@@ -144,6 +147,7 @@ class KnotConfControlListener(BaseDataListener):
KNOT.begin()
KNOT.set_item(section="control", item="listen", data=base_nv.get("unix"))
KNOT.commit()
return ConfHandlerResult.OK
class KnotConfAclListener(BaseDataListener):
......@@ -188,6 +192,7 @@ class KnotConfAclListener(BaseDataListener):
self._process_list_item(acl_nv)
KNOT.commit()
return ConfHandlerResult.OK
class KnotZoneDataListener(BaseDataListener):
......@@ -227,6 +232,7 @@ class KnotZoneDataListener(BaseDataListener):
soarr.minimum = soa["minimum"]
KNOT.zone_add_record(zone_name, soarr)
KNOT.commit_zone()
return ConfHandlerResult.OK
def main():
......@@ -250,14 +256,12 @@ def main():
nacmc.set_ds(datastore)
# Register schema listeners
# We need to hold references somewhere
sch_lo = []
sch_lo.append(KnotConfServerListener(datastore, "/dns-server:dns-server/server-options"))
sch_lo.append(KnotConfLogListener(datastore, "/dns-server:dns-server/knot-dns:log"))
sch_lo.append(KnotConfZoneListener(datastore, "/dns-server:dns-server/zones/zone"))
sch_lo.append(KnotConfControlListener(datastore, "/dns-server:dns-server/knot-dns:control-socket"))
sch_lo.append(KnotConfAclListener(datastore, "/dns-server:dns-server/access-control-list"))
sch_lo.append(KnotZoneDataListener(datastore, "/dns-zones:zones"))
CONF_DATA_HANDLES.register_handler(KnotConfServerListener(datastore, "/dns-server:dns-server/server-options"))
CONF_DATA_HANDLES.register_handler(KnotConfLogListener(datastore, "/dns-server:dns-server/knot-dns:log"))
CONF_DATA_HANDLES.register_handler(KnotConfZoneListener(datastore, "/dns-server:dns-server/zones/zone"))
CONF_DATA_HANDLES.register_handler(KnotConfControlListener(datastore, "/dns-server:dns-server/knot-dns:control-socket"))
CONF_DATA_HANDLES.register_handler(KnotConfAclListener(datastore, "/dns-server:dns-server/access-control-list"))
CONF_DATA_HANDLES.register_handler(KnotZoneDataListener(datastore, "/dns-zones:zones"))
# Register op handlers
OP_HANDLERS.register_handler("generate-key", usr_op_handlers.sign_op_handler)
......
......@@ -3,7 +3,6 @@ from threading import Lock
from enum import Enum
from colorlog import error, warning as warn, info, debug
from typing import List, Any, Dict, TypeVar, Tuple, Set, Callable
from pydispatch import dispatcher
from yangson.schema import SchemaRoute, SchemaNode, NonexistentSchemaNode, ListNode, LeafListNode
from yangson.datamodel import DataModel, InstancePath
......@@ -72,18 +71,23 @@ class NoHandlerForStateDataError(NoHandlerError):
pass
class ConfHandlerResult(Enum):
PASS = 0,
OK = 1,
ERROR = 2
class BaseDataListener:
def __init__(self, ds: "BaseDatastore", sch_pth: str):
self._ds = ds
self.schema_path = sch_pth # type: str
self.schema_node = ds.get_schema_node(sch_pth) # type: SchemaNode
dispatcher.connect(self.process, str(id(self.schema_node)))
def process(self, sn: SchemaNode, ii: InstancePath, ch: "DataChange"):
def process(self, sn: SchemaNode, ii: InstancePath, ch: "DataChange") -> ConfHandlerResult:
raise NotImplementedError("Not implemented in base class")
def __str__(self):
return self.__class__.__name__ + ": listening at " + str(self.schema_paths)
return self.__class__.__name__ + ": listening at " + self.schema_path
class RpcInfo:
......@@ -245,7 +249,19 @@ class BaseDatastore:
sn = self.get_schema_node(sch_pth)
while sn is not None:
dispatcher.send(str(id(sn)), **{'sn': sn, 'ii': ii, 'ch': ch})
h = CONF_DATA_HANDLES.get_handler(str(id(sn)))
if h is not None:
h_res = h.process(sn, ii, ch)
if h_res == ConfHandlerResult.OK:
# Edit successfully handled
break
elif h_res == ConfHandlerResult.ERROR:
# Error occured in handler
warn("Error occured in handler for sch_node \"{}\"".format(sch_pth))
break
else:
# Pass edit to superior handler
pass
sn = sn.parent
except NonexistentInstance:
warn("Cannnot notify {}, parent container removed".format(ii))
......@@ -587,4 +603,4 @@ def test():
from .nacm import NacmConfig, Permission, Action
from .handler_list import OP_HANDLERS, STATE_DATA_HANDLES
from .handler_list import OP_HANDLERS, STATE_DATA_HANDLES, CONF_DATA_HANDLES
from typing import List, Tuple, Callable, Any
from .data import BaseDatastore, PathFormat
from .data import BaseDatastore, PathFormat, BaseDataListener
from .usr_state_data_handlers import StateNodeHandlerBase
from yangson.context import Context
from yangson.schema import SchemaNode
HandlerSelectorT = Any
......@@ -10,54 +12,50 @@ class BaseHandlerList:
self.handlers = [] # type: List[Tuple[HandlerSelectorT, Callable]]
self.default_handler = None # type: Callable
def register_handler(self, name: str, handler: Callable):
def register_handler(self, identifier: str, handler: Callable):
raise NotImplementedError("Not implemented in base class")
def register_default_handler(self, handler: Callable):
self.default_handler = handler
def get_handler(self, name: str) -> Callable:
def get_handler(self, identifier: str) -> Callable:
raise NotImplementedError("Not implemented in base class")
class OpHandlerList(BaseHandlerList):
def register_handler(self, name: str, handler: Callable):
self.handlers.append((name, handler))
def register_handler(self, op_name: str, handler: Callable):
self.handlers.append((op_name, handler))
def get_handler(self, name: str) -> Callable:
def get_handler(self, op_name: str) -> Callable:
for h in self.handlers:
if h[0] == name:
if h[0] == op_name:
return h[1]
return self.default_handler
class ConfDataHandlerList:
def __init__(self):
self.handlers = [] # type: List[Tuple[HandlerSelectorT, BaseDataListener]]
def register_handler(self, handler: BaseDataListener):
schema_node = handler.schema_node # type: SchemaNode
sch_node_id = str(id(schema_node))
self.handlers.append((sch_node_id, handler))
def get_handler(self, sch_node_id: str) -> Callable:
for h in self.handlers:
if h[0] == sch_node_id:
return h[1]
return None
class StateDataHandlerList:
def __init__(self):
self.handlers = []
self.ds = None # type: BaseDatastore
# def register_handler(self, ii_str: str, handler: Callable):
# ii = self.ds.parse_ii(ii_str, PathFormat.XPATH)
# self.handlers.append((ii, handler))
#
# def get_handler(self, ii: InstanceIdentifier, allow_superior: bool=True) -> Callable:
# if allow_superior:
# ii_local = ii.copy()
# while ii_local:
# dn = self.ds.get_node(ii_local)
# for h in self.handlers:
# if self.ds.get_node(h[0]).value is dn.value:
# return h[1]
# ii_local.pop()
# else:
# for h in self.handlers:
# if h[0] == ii:
# return h[1]
#
# return self.default_handler
def register_handler(self, handler):
def register_handler(self, handler: "StateNodeHandlerBase"):
saddr = Context.path2route(handler.sch_pth)
self.handlers.append((saddr, handler))
......@@ -76,9 +74,7 @@ class StateDataHandlerList:
return None
# def set_ds(self, ds: BaseDatastore):
# self.ds = ds
OP_HANDLERS = OpHandlerList()
STATE_DATA_HANDLES = StateDataHandlerList()
CONF_DATA_HANDLES = ConfDataHandlerList()
......@@ -13,6 +13,8 @@ JsonNodeT = Dict[str, Any]
class StateNodeHandlerBase:
def __init__(self, data_model: DataModel, ctl: KnotCtl):
self.data_model = data_model
self.sch_pth = None
self.schema_node = None
self.knotctl = ctl
self.member_handlers = {} # type: Dict[str, StateNodeHandlerBase]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment