blob: 4a53c3198dc5fddc941e275dc4f23c7e6ecac06a [file] [log] [blame]
Shad Ansari6fcfa292022-01-28 00:34:13 +00001"""
2SPDX-FileCopyrightText: 2020-present Open Networking Foundation <info@opennetworking.org>
3SPDX-License-Identifier: LicenseRef-ONF-Member-1.01
4"""
5import sys
Shad Ansarid88692c2022-02-01 22:47:43 +00006import re
7from datetime import datetime
Shad Ansari500f9a02022-02-04 21:15:24 +00008import time
Shad Ansari6fcfa292022-01-28 00:34:13 +00009
Shad Ansari1dcfdb32022-01-24 23:13:06 +000010from flask import Flask, request
Shad Ansari6fcfa292022-01-28 00:34:13 +000011import logging as log
Shad Ansari5b9d1f52022-01-29 01:42:45 +000012from argparse import ArgumentParser, SUPPRESS
Shad Ansari500f9a02022-02-04 21:15:24 +000013import threading
Shad Ansari5b9d1f52022-01-29 01:42:45 +000014
15from roc import Roc
Shad Ansarid88692c2022-02-01 22:47:43 +000016from prom import Prometheus
17from ping import ping
18import device
Shad Ansari1dcfdb32022-01-24 23:13:06 +000019
20app = Flask(__name__)
Shad Ansari1dcfdb32022-01-24 23:13:06 +000021
Shad Ansarid88692c2022-02-01 22:47:43 +000022devices = {} # dict imsi:device
Shad Ansari500f9a02022-02-04 21:15:24 +000023lock = threading.Lock()
Shad Ansarice3c67b2022-02-10 21:00:25 +000024probe_start = threading.Event()
25probe_stop = threading.Event()
Shad Ansari6fcfa292022-01-28 00:34:13 +000026
Shad Ansari5b9d1f52022-01-29 01:42:45 +000027
Shad Ansari467862f2022-02-08 00:40:40 +000028@app.route("/devices")
29def get_devices():
30 global devices, lock
31 with lock:
32 all = {}
33 for _, device in devices.items():
34 all[device.imsi_id] = {'ip':device.ip, 'imsi':device.imsi, 'last_reachable':'{:%Y-%m-%d %H:%M:%S}'.format(device.last_reachable)}
35 return all
Shad Ansarid88692c2022-02-01 22:47:43 +000036
Shad Ansari467862f2022-02-08 00:40:40 +000037@app.route("/devices/reachable")
38def get_devices_reachable():
39 global devices, lock
40 with lock:
41 reachable = {}
42 for _, device in devices.items():
43 if device.reachable is True:
44 reachable[device.imsi_id] = {'ip':device.ip, 'imsi':device.imsi, 'last_reachable':'{:%Y-%m-%d %H:%M:%S}'.format(device.last_reachable)}
45 return reachable
Shad Ansari5b9d1f52022-01-29 01:42:45 +000046
Shad Ansari467862f2022-02-08 00:40:40 +000047@app.route("/devices/unreachable")
48def get_devices_unreachable():
49 global devices, lock
50 with lock:
51 unreachable = {}
52 for _, device in devices.items():
53 if device.reachable is False:
54 unreachable[device.imsi_id] = {'ip':device.ip, 'imsi':device.imsi, 'last_reachable':'{:%Y-%m-%d %H:%M:%S}'.format(device.last_reachable)}
55 return unreachable
Shad Ansari1dcfdb32022-01-24 23:13:06 +000056
Shad Ansarice3c67b2022-02-10 21:00:25 +000057@app.route("/probe")
58def probe():
59 update_and_probe()
60 return get_devices_reachable()
61
Shad Ansari0a905032022-02-10 19:37:15 +000062@app.route("/config")
63def config():
Shad Ansarice3c67b2022-02-10 21:00:25 +000064 global args, probe_stop
Shad Ansari0a905032022-02-10 19:37:15 +000065 period = request.args.get('period')
66 if period is not None:
Shad Ansarice3c67b2022-02-10 21:00:25 +000067 period = int(period)
68 if period == 0:
69 log.info("Stopping probes...")
70 args.period = period
71 probe_stop.set()
72 else:
73 log.info("Starting probes...")
74 args.period = period
75 probe_start.set()
Shad Ansari0a905032022-02-10 19:37:15 +000076 config = vars(args)
77 config.pop('token', None)
78 config.pop('user', None)
79 config.pop('password', None)
80 return config
Shad Ansari6fcfa292022-01-28 00:34:13 +000081
Shad Ansari5b9d1f52022-01-29 01:42:45 +000082
83def build_argparser():
84 parser = ArgumentParser(add_help=False)
85 args = parser.add_argument_group('Options')
86 args.add_argument('-h', '--help',
87 action='help',
88 default=SUPPRESS,
89 help='Show this help message and exit.')
90 args.add_argument("--user",
91 help="ROC username",
92 type=str)
93 args.add_argument("--password",
94 help="ROC password",
95 type=str)
Shad Ansarid88692c2022-02-01 22:47:43 +000096 args.add_argument("--token",
97 help="Rancher bearer token",
98 type=str)
Shad Ansari500f9a02022-02-04 21:15:24 +000099 args.add_argument("--port",
100 help="Service port",
101 type=str,
102 default="3333")
Shad Ansari0a905032022-02-10 19:37:15 +0000103 args.add_argument("--period",
104 help="Probing period in sec",
105 type=int,
106 default=180)
Shad Ansari5b9d1f52022-01-29 01:42:45 +0000107 return parser
108
Shad Ansariae3903e2022-02-05 01:03:01 +0000109def update(roc, prom, old):
110 new = roc.update_devices(old)
Shad Ansari907b7712022-02-07 21:48:04 +0000111 if new is not None:
112 new = prom.update_devices(new)
113 else:
114 new = old
Shad Ansariae3903e2022-02-05 01:03:01 +0000115 return new
Shad Ansarid88692c2022-02-01 22:47:43 +0000116
Shad Ansari500f9a02022-02-04 21:15:24 +0000117def probe(devices):
Shad Ansarid88692c2022-02-01 22:47:43 +0000118 for imsi_id, device in devices.items():
119 if device.ip is None:
120 continue
121 if ping(device.ip):
122 device.reachable = True
123 device.last_reachable = datetime.now()
124 log.info("{}/{}/{} - reachable".format(device.imsi_id, device.imsi, device.ip))
125 else:
126 device.reachable = False
127 log.info("{}/{}/{} - unreachable".format(device.imsi_id, device.imsi, device.ip))
128
Shad Ansarice3c67b2022-02-10 21:00:25 +0000129def update_and_probe():
130 global devices, lock
131 new = update(roc, prom, devices)
132 probe(new)
133 with lock:
134 devices = new
Shad Ansariae3903e2022-02-05 01:03:01 +0000135
Shad Ansarice3c67b2022-02-10 21:00:25 +0000136def work_thread(roc, prom):
137 global args
138 while True:
139 probe_start.wait()
140 probe_start.clear()
141 log.info("Probing started")
142 while True:
143 update_and_probe()
144 if probe_stop.wait(timeout=args.period):
145 log.info("Probing stopped")
146 probe_stop.clear()
147 break
Shad Ansari5b9d1f52022-01-29 01:42:45 +0000148
Shad Ansari500f9a02022-02-04 21:15:24 +0000149if __name__ == '__main__':
150
151 log.basicConfig(
152 format='%(asctime)s %(levelname)-8s %(message)s',
153 level=log.DEBUG,
154 datefmt='%Y-%m-%d %H:%M:%S',
155 stream=sys.stdout)
156
Shad Ansari500f9a02022-02-04 21:15:24 +0000157 log.info("Starting network-diag-app...")
158
159 args = build_argparser().parse_args()
160
161 roc = Roc(args.user, args.password)
162 prom = Prometheus(args.token.split(':')[0], args.token.split(':')[1])
163
164 t = threading.Thread(target=work_thread, args=(roc, prom,))
165 t.start()
Shad Ansarice3c67b2022-02-10 21:00:25 +0000166 probe_start.set()
Shad Ansari500f9a02022-02-04 21:15:24 +0000167
168 app.run('0.0.0.0', args.port)