summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/leap/bitmask/vpn/_status.py79
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