diff options
-rw-r--r-- | src/leap/bitmask/vpn/_status.py | 79 |
1 files changed, 38 insertions, 41 deletions
diff --git a/src/leap/bitmask/vpn/_status.py b/src/leap/bitmask/vpn/_status.py index c408883..7cd4896 100644 --- a/src/leap/bitmask/vpn/_status.py +++ b/src/leap/bitmask/vpn/_status.py @@ -4,13 +4,16 @@ from ._human import bytes2human from leap.common.events import catalog, emit_async -# TODO implement a state machine in this class +# TODO implement a more explicit state machine +# TODO check good transitions +# TODO check valid states class VPNStatus(object): """ A class containing different patterns in the openvpn output that - we can react upon. + we can react upon. The patterns drive an internal state machine that can be + queried through the ``status`` property. """ _events = { @@ -21,25 +24,31 @@ class VPNStatus(object): 'INITIALIZATION_COMPLETED': ( "Initialization Sequence Completed",), } + _STARTING = ('AUTH', 'WAIT', 'CONNECTING', 'GET_CONFIG', + 'ASSIGN_IP', 'ADD_ROUTES', 'RECONNECTING') + _STOPPING = ("EXITING",) + _CONNECTED = ("CONNECTED",) def __init__(self): self._status = 'off' self.errcode = None self._traffic_down = None self._traffic_up = None - - def watch(self, line): - """ - Inspects line searching for the different patterns. If a match - is found, try to emit the corresponding signal. - - :param line: a line of openvpn output - :type line: str - """ - chained_iter = chain(*[ + self._chained_iter = chain(*[ zip(repeat(key, len(l)), l) for key, l in self._events.iteritems()]) - for event, pattern in chained_iter: + + def _status_codes(self, event): + + _table = { + "network_unreachable": ('off', 'network unreachable'), + "process_restart_tls": ('starting', 'restart tls'), + "initialization_completed": ('on', None) + } + return _table.get(event.lower()) + + def watch(self, line): + for event, pattern in self._chained_iter: if pattern in line: break else: @@ -48,24 +57,27 @@ class VPNStatus(object): status, errcode = self._status_codes(event) self.set_status(status, errcode) + @property + def status(self): + status = self.get_traffic_status() + status.update({ + 'status': self._status, + 'error': self.errcode + }) + return status + def set_status(self, status, errcode): - if status in ("AUTH", "WAIT", "CONNECTING", "GET_CONFIG", - "ASSIGN_IP", "ADD_ROUTES", "RECONNECTING"): + if status in self._STARTING: status = "starting" - elif status == "EXITING": + elif status in self._STOPPING: status = "stopping" - elif status == "CONNECTED": + elif status in self._CONNECTED: status = "on" self._status = status self.errcode = errcode emit_async(catalog.VPN_STATUS_CHANGED) - def set_traffic_status(self, status): - up, down = status - self._traffic_up = up - self._traffic_down = down - def get_traffic_status(self): down = None up = None @@ -75,22 +87,7 @@ class VPNStatus(object): up = bytes2human(self._traffic_up) return {'down': down, 'up': up} - @property - def status(self): - status = self.get_traffic_status() - status.update({ - 'status': self._status, - 'error': self.errcode - }) - return status - - def _status_codes(self, event): - # TODO check good transitions - # TODO check valid states - - _table = { - "network_unreachable": ('off', 'network unreachable'), - "process_restart_tls": ('starting', 'restart tls'), - "initialization_completed": ('on', None) - } - return _table.get(event.lower()) + def set_traffic_status(self, status): + up, down = status + self._traffic_up = up + self._traffic_down = down |