aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jonas Gunz <himself@jonasgunz.de> 2023-06-14 12:27:54 +0200
committerGravatar Jonas Gunz <himself@jonasgunz.de> 2023-06-14 12:27:54 +0200
commit4f1e0e9b26ac00548112ed3da022a5012c9810e3 (patch)
treea31502686fe6842ebdd78501657215a9807cc6db
parent676b2dcc8e4dba19b703818f7355658f237c4d60 (diff)
downloadautomato-4f1e0e9b26ac00548112ed3da022a5012c9810e3.tar.gz
replace metaTransport with enpoint info object
-rw-r--r--automato/command.py15
-rw-r--r--automato/endpoint.py33
-rw-r--r--automato/state.py28
-rw-r--r--automato/transport.py18
4 files changed, 54 insertions, 40 deletions
diff --git a/automato/command.py b/automato/command.py
index 1926c2e..e9361f6 100644
--- a/automato/command.py
+++ b/automato/command.py
@@ -13,20 +13,25 @@ MUST implement:
execute(self, **kwargs)
CAN implement:
- __init__(self, transport)
+ _init(self, ...)
SHOULDNT implement:
- ./.
+ __init__(self, endpoint_info: dict, **kwargs):
'''
class Command:
- def __init__(self, transport: transport.Transport):
+ # TODO do we need config for commands?
+ def __init__(self, endpoint_info: dict, **kwargs):
+ self._endpoint_info = endpoint_info
+ self._init(**kwargs)
+
+ def _init(self, transport: transport.Transport):
self._transport = transport
def execute(self, **kwargs):
raise NotImplemented
class NotifyCommand(Command):
- def __init__(self, transport: transport.SshTransport):
+ def _init(self, transport: transport.SshTransport):
self._transport = transport
def execute(self, msg: str):
@@ -40,7 +45,7 @@ MAC Address in the standard XX:XX:XX:XX:XX:XX format.
'''
class WakeOnLanCommand(Command):
- def __init__(self, transport: transport.MetaDataTransport):
+ def _init(self, transport: transport.MetaDataTransport):
self._transport = transport
def execute(self):
diff --git a/automato/endpoint.py b/automato/endpoint.py
index 2099017..c1abe4e 100644
--- a/automato/endpoint.py
+++ b/automato/endpoint.py
@@ -11,11 +11,13 @@ def import_class(cl):
# Master object
class Endpoint:
- def __init__(self, name, config):
+ def __init__(self, name: str, config: dict):
transports = {}
commands = {}
states = {}
+ endpoint_info = config.get('info', {})
+
# sweet mother of jesus, you are ugly
for tp_key in config['transports']:
tp_cfg = config['transports'][tp_key]
@@ -25,7 +27,7 @@ class Endpoint:
tp_class = import_class(tp_cfg['class'])
del tp_cfg['class']
- transports[tp_key] = tp_class(**tp_cfg)
+ transports[tp_key] = tp_class(endpoint_info, **tp_cfg)
for cmd_key in config['commands']:
cmd_cfg = config['commands'][cmd_key]
@@ -35,15 +37,17 @@ class Endpoint:
cmd_class = import_class(cmd_cfg['class'])
del cmd_cfg['class']
- if cmd_cfg['transport'] not in transports:
- # TODO should we be lenient with errors?
- logger.error(f'transport "{cmd_cfg["transport"]}" for command "{cmd_key}" was not found.')
- continue
+ if 'transport' in cmd_cfg:
+ if cmd_cfg['transport'] not in transports:
+ # TODO should we be lenient with errors?
+ logger.error(f'transport "{cmd_cfg["transport"]}" for command "{cmd_key}" was not found.')
+ continue
- tp = transports[cmd_cfg['transport']]
- del cmd_cfg['transport']
+ tp = transports[cmd_cfg['transport']]
+ del cmd_cfg['transport']
+ cmd_cfg['transport'] = tp
- commands[cmd_key] = cmd_class(tp, **cmd_cfg)
+ commands[cmd_key] = cmd_class(endpoint_info, **cmd_cfg)
# you look familiar
for stt_key in config['states']:
@@ -59,10 +63,12 @@ class Endpoint:
logger.error(f'transport "{stt_cfg["transport"]}" for command "{stt_key}" was not found.')
continue
- tp = transports[stt_cfg['transport']]
- del stt_cfg['transport']
+ if 'transport' in stt_cfg:
+ tp = transports[stt_cfg['transport']]
+ del stt_cfg['transport']
+ stt_cfg['transport'] = tp
- states[stt_key] = stt_class(tp, **stt_cfg)
+ states[stt_key] = stt_class(endpoint_info, **stt_cfg)
# TODO How does the init step look like? Do it here?
# transports prbly need to be connected here
@@ -102,6 +108,7 @@ class Endpoint:
def executeCommand(self, cmd: str, **kwargs):
if cmd not in self._commands:
- raise Exception(f'Command "{cmd}" is not defined for "{self._name}"')
+ logger.error(f'Command "{cmd}" is not defined for "{self._name}"')
+ #raise Exception(f'Command "{cmd}" is not defined for "{self._name}"')
self._commands[cmd].execute(**kwargs)
diff --git a/automato/state.py b/automato/state.py
index dd08e1b..5d2789c 100644
--- a/automato/state.py
+++ b/automato/state.py
@@ -12,10 +12,12 @@ MUST implement:
CAN implement:
_get(self, key: str)
+ init(self, [transport], <other options you might need>)
SHOULDNT implement:
get(self, key)
collect(self)
+ __init__(self, endpoint_info: dict, ttl: int = 30, **kwargs)
Data is stored in self._data as a dictionary.
By default, _get(key) retrieves the returns self._data[key].
@@ -26,13 +28,19 @@ the self._data dictionary. If an own _get() is implemented,
this does not need to be the case.
'''
class State:
- def __init__(self, transport: transport.Transport, ttl: int = 30):
- self._transport = transport
+ # TODO set default TTL in child classes
+ def __init__(self, endpoint_info: dict, ttl: int = 30, **kwargs):
self._ttl = ttl
+ self._endpoint_info = endpoint_info
self._data = {}
self._last_collected = 0
+ self._init(**kwargs)
+
+ def _init(self):
+ pass
+
def _collect(self):
raise NotImplemented
@@ -62,10 +70,7 @@ class State:
self._last_collected = time.time()
class UserSessionState(State):
- def __init__(self, transport: transport.SshTransport, ttl: int = 30):
- super().__init__(transport, ttl)
-
- # this is not needed. it's here to shut up pylint
+ def _init(self, transport: transport.SshTransport):
self._transport = transport
def _get(self, key: str):
@@ -92,15 +97,13 @@ class UserSessionState(State):
self._data[name] += 1
class LinuxMemoryState(State):
- def __init__(self, transport: transport.SshTransport, ttl: int = 60):
- super().__init__(transport, ttl)
-
- # this is not needed. it's here to shut up pylint
+ def _init(self, transport: transport.SshTransport):
self._transport = transport
def _collect(self):
mem_data = self._transport.execHandleStderror('cat /proc/meminfo').decode('utf-8')
+ # TODO We prbly don't wan't raw values. Process them!
self._data['mem'] = {}
for l in mem_data.splitlines():
arr = l.split()
@@ -112,10 +115,7 @@ class LinuxMemoryState(State):
logger.debug(f'Memory: {key} = {val}')
class LinuxLoadState(State):
- def __init__(self, transport: transport.SshTransport, ttl: int = 30):
- super().__init__(transport, ttl)
-
- # this is not needed. it's here to shut up pylint
+ def _init(self, transport: transport.SshTransport):
self._transport = transport
def _collect(self):
diff --git a/automato/transport.py b/automato/transport.py
index 327946e..6d849ce 100644
--- a/automato/transport.py
+++ b/automato/transport.py
@@ -31,18 +31,23 @@ MUST implement:
rather than at runtime in case of misconfiguration.
CAN implement:
- __init__(self, <other settings you might need>)
+ _init(self, <other settings you might need>)
isConnected(self) -> bool
SHOULDNT implement:
- ./.
+ __init__(self, endpoint_info: dict, **kwargs)
'''
class Transport:
CONNECTION = HOLD
#CONNECTION = THROWAWAY
- def __init__(self):
+ def __init__(self, endpoint_info: dict, **kwargs):
+ self._endpoint_info = endpoint_info
self._connected = False
+ self._init(**kwargs)
+
+ def _init(self):
+ pass
# Connects to the transport, if CONNECTION == HOLD
def connect(self):
@@ -68,7 +73,7 @@ require a connection, such as Wake on Lan.
class MetaDataTransport(Transport):
CONNECTION=THROWAWAY
- def __init__(self, **kwargs):
+ def _init(self, **kwargs):
self._metadata = kwargs
def __getattr__(self, attr):
@@ -81,8 +86,7 @@ class MetaDataTransport(Transport):
class SshTransport(Transport):
CONNECTION=HOLD
- def __init__(self, hostname: str, port=22, username='root', password = None, id_file = None, allow_agent = False):
- super().__init__()
+ def _init(self, hostname: str, port=22, username='root', password = None, id_file = None, allow_agent = False):
self._hostname = hostname
self._port = port
self._username = username
@@ -90,8 +94,6 @@ class SshTransport(Transport):
self._id_file = id_file
self._allow_agent = allow_agent
- self._connected = False
-
self._client = None
def connect(self):