Continuous ping

Change-Id: Ieed8bd152819705586e06445df597c68da83722f
diff --git a/app.py b/app.py
index c3e3238..44c91ec 100644
--- a/app.py
+++ b/app.py
@@ -5,11 +5,13 @@
 import sys
 import re
 from datetime import datetime
+import time
 
 from flask import Flask, request
 from flask_restful import Resource, Api
 import logging as log
 from argparse import ArgumentParser, SUPPRESS
+import threading
 
 from roc import Roc
 from prom import Prometheus
@@ -20,23 +22,39 @@
 api = Api(app)
 
 devices = {} # dict imsi:device
+lock = threading.Lock()
 
 
+class Devices(Resource):
+    def get(self):
+        global devices, lock
+        with lock:
+            all = {}
+            for _, device in devices.items():
+                all[device.imsi_id] = {'ip':device.ip, 'imsi':device.imsi, 'last_reachable':'{:%Y-%m-%d %H:%M:%S}'.format(device.last_reachable)}
+        return all
 
 class ReachableDevices(Resource):
     def get(self):
-        global devices
-        return device.get_reachable(devices)
+        global devices, lock
+        with lock:
+            reachable = {}
+            for _, device in devices.items():
+                if device.reachable is True:
+                    reachable[device.imsi_id] = {'ip':device.ip, 'imsi':device.imsi, 'last_reachable':'{:%Y-%m-%d %H:%M:%S}'.format(device.last_reachable)}
+        return reachable
 
 class UnreachableDevices(Resource):
     def get(self):
-        global devices
-        return device.get_unreachable(devices)
+        global devices, lock
+        with lock:
+            unreachable = {}
+            for _, device in devices.items():
+                if device.reachable is False:
+                    unreachable[device.imsi_id] = {'ip':device.ip, 'imsi':device.imsi, 'last_reachable':'{:%Y-%m-%d %H:%M:%S}'.format(device.last_reachable)}
+        return unreachable
 
 
-api.add_resource(ReachableDevices, '/reachable-devices')
-api.add_resource(UnreachableDevices, '/unreachable-devices')
-
 
 def build_argparser():
     parser = ArgumentParser(add_help=False)
@@ -54,27 +72,17 @@
     args.add_argument("--token",
                       help="Rancher bearer token",
                       type=str)
+    args.add_argument("--port",
+                      help="Service port",
+                      type=str,
+                      default="3333")
     return parser
 
-
-if __name__ == '__main__':
-    log.basicConfig(
-        format='%(asctime)s %(levelname)-8s %(message)s',
-        level=log.DEBUG,
-        datefmt='%Y-%m-%d %H:%M:%S',
-        stream=sys.stdout)
-
-    log.info("Starting network-diag-app...")
-
-    args = build_argparser().parse_args()
-
-    roc = Roc(args.user, args.password)
-    prom = Prometheus(args.token.split(':')[0], args.token.split(':')[1])
-
+def update(roc, prom, devices):
     roc.update_devices(devices)
-
     prom.update_devices(devices)
 
+def probe(devices):
     for imsi_id, device in devices.items():
         if device.ip is None:
             continue
@@ -86,5 +94,36 @@
             device.reachable = False
             log.info("{}/{}/{} - unreachable".format(device.imsi_id, device.imsi, device.ip))
 
+def work_thread(roc, prom):
+    global devices, lock
+    while True:
+        temp_devices = {}
+        update(roc, prom, temp_devices)
+        probe(temp_devices)
+        with lock:
+            devices = temp_devices
+        time.sleep(5)
 
-    app.run('0.0.0.0', '3333')
+if __name__ == '__main__':
+
+    log.basicConfig(
+        format='%(asctime)s %(levelname)-8s %(message)s',
+        level=log.DEBUG,
+        datefmt='%Y-%m-%d %H:%M:%S',
+        stream=sys.stdout)
+
+    api.add_resource(Devices, '/devices')
+    api.add_resource(ReachableDevices, '/devices/reachable')
+    api.add_resource(UnreachableDevices, '/devices/unreachable')
+
+    log.info("Starting network-diag-app...")
+
+    args = build_argparser().parse_args()
+
+    roc = Roc(args.user, args.password)
+    prom = Prometheus(args.token.split(':')[0], args.token.split(':')[1])
+
+    t = threading.Thread(target=work_thread, args=(roc, prom,))
+    t.start()
+
+    app.run('0.0.0.0', args.port)
diff --git a/device.py b/device.py
index 767180e..2b1ffcd 100644
--- a/device.py
+++ b/device.py
@@ -8,7 +8,6 @@
 
 
 class Device(object):
-
     def __init__(self, imsi_id, imsi, ip=None):
         # log.debug("creating device, imsi_id={}, imsi={}, ip={}".format(imsi_id, imsi, ip))
         self.imsi_id = imsi_id
@@ -16,26 +15,3 @@
         self.ip = ip
         self.reachable = False
         self.last_reachable = datetime.min
-
-    @classmethod
-    def get_reachable(cls, devices):
-        reachable = {}
-        for _, device in devices.items():
-            if device.reachable is True:
-                reachable[device.imsi_id] = {'ip':device.ip, 'imsi':device.imsi, 'last_reachable':'{:%Y-%m-%d %H:%M:%S}'.format(device.last_reachable)}
-                last_reachable = datetime(1, 1, 1, 0, 0)
-
-        return reachable
-
-    @classmethod
-    def get_unreachable(cls, devices):
-        unreachable = {}
-        for _, device in devices.items():
-            if device.reachable is False:
-                unreachable[device.imsi_id] = {'ip':device.ip, 'imsi':device.imsi, 'last_reachable':'{:%Y-%m-%d %H:%M:%S}'.format(device.last_reachable)}
-
-        return unreachable
-
-
-
-
diff --git a/ping.py b/ping.py
index 5903fd9..acd7911 100644
--- a/ping.py
+++ b/ping.py
@@ -11,7 +11,7 @@
 def ping(host):
     #log.debug("Pinging {}".format(host))
     if host != None:
-        return subprocess.call(["ping", "-c", "1", "-W", "1", host],
+        return subprocess.call(["ping", "-c", "1", "-W", "2", host],
                 stdout=subprocess.DEVNULL,
                 stderr=subprocess.STDOUT) == 0
     else:
diff --git a/roc.py b/roc.py
index ede71f7..fe328aa 100644
--- a/roc.py
+++ b/roc.py
@@ -113,12 +113,11 @@
         return json.loads(response.text)['ip-domain']
 
     def get_devices(self):
-        imsis = {}
-        devicegroups = self.get_devicegroups()
-        for devicegroup in devicegroups:
-            for device in devicegroup['imsis']:
-                imsis[device['imsi-id']] = device['imsi-range-from']
-        return imsis
+        devices = {}
+        for dg in self.get_devicegroups():
+            for d in dg['imsis']:
+                devices[d['imsi-id']] = d['imsi-range-from']
+        return devices
 
     def update_devices(self, devices):
         dgs = self.get_devicegroups()