blob: fded67e72e1bbc7911716046d3acef85a1be05bb [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 +00006from datetime import datetime
Shad Ansari6fcfa292022-01-28 00:34:13 +00007
Shad Ansari1dcfdb32022-01-24 23:13:06 +00008from flask import Flask, request
Shad Ansari6fcfa292022-01-28 00:34:13 +00009import logging as log
Shad Ansari5b9d1f52022-01-29 01:42:45 +000010from argparse import ArgumentParser, SUPPRESS
Shad Ansari500f9a02022-02-04 21:15:24 +000011import threading
Shad Ansari5b9d1f52022-01-29 01:42:45 +000012
13from roc import Roc
Shad Ansarid88692c2022-02-01 22:47:43 +000014from prom import Prometheus
15from ping import ping
Shad Ansari1dcfdb32022-01-24 23:13:06 +000016
17app = Flask(__name__)
Shad Ansari1dcfdb32022-01-24 23:13:06 +000018
Shad Ansari0508ddf2022-03-24 03:16:51 +000019devices = {} # dict imsi:device
Shad Ansari500f9a02022-02-04 21:15:24 +000020lock = threading.Lock()
Shad Ansarice3c67b2022-02-10 21:00:25 +000021probe_start = threading.Event()
22probe_stop = threading.Event()
Shad Ansari6fcfa292022-01-28 00:34:13 +000023
Shad Ansari5b9d1f52022-01-29 01:42:45 +000024
Shad Ansari467862f2022-02-08 00:40:40 +000025@app.route("/devices")
26def get_devices():
27 global devices, lock
28 with lock:
29 all = {}
30 for _, device in devices.items():
Shad Ansari0508ddf2022-03-24 03:16:51 +000031 all[device.imsi_id] = {'ip': device.ip, 'imsi': device.imsi, 'last_reachable': '{:%Y-%m-%d %H:%M:%S}'.format(device.last_reachable)}
Shad Ansari467862f2022-02-08 00:40:40 +000032 return all
Shad Ansarid88692c2022-02-01 22:47:43 +000033
Shad Ansari0508ddf2022-03-24 03:16:51 +000034
Shad Ansari467862f2022-02-08 00:40:40 +000035@app.route("/devices/reachable")
36def get_devices_reachable():
37 global devices, lock
38 with lock:
39 reachable = {}
40 for _, device in devices.items():
41 if device.reachable is True:
Shad Ansari0508ddf2022-03-24 03:16:51 +000042 reachable[device.imsi_id] = {'ip': device.ip, 'imsi': device.imsi, 'last_reachable': '{:%Y-%m-%d %H:%M:%S}'.format(device.last_reachable)}
Shad Ansari467862f2022-02-08 00:40:40 +000043 return reachable
Shad Ansari5b9d1f52022-01-29 01:42:45 +000044
Shad Ansari0508ddf2022-03-24 03:16:51 +000045
Shad Ansari467862f2022-02-08 00:40:40 +000046@app.route("/devices/unreachable")
47def get_devices_unreachable():
48 global devices, lock
49 with lock:
50 unreachable = {}
51 for _, device in devices.items():
52 if device.reachable is False:
Shad Ansari0508ddf2022-03-24 03:16:51 +000053 unreachable[device.imsi_id] = {'ip': device.ip, 'imsi': device.imsi, 'last_reachable': '{:%Y-%m-%d %H:%M:%S}'.format(device.last_reachable)}
Shad Ansari467862f2022-02-08 00:40:40 +000054 return unreachable
Shad Ansari1dcfdb32022-01-24 23:13:06 +000055
Shad Ansari0508ddf2022-03-24 03:16:51 +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 Ansari0508ddf2022-03-24 03:16:51 +000062
63# curl http://localhost:3333/config?period=0
Shad Ansari0a905032022-02-10 19:37:15 +000064@app.route("/config")
65def config():
Shad Ansarice3c67b2022-02-10 21:00:25 +000066 global args, probe_stop
Shad Ansari0a905032022-02-10 19:37:15 +000067 period = request.args.get('period')
68 if period is not None:
Shad Ansarice3c67b2022-02-10 21:00:25 +000069 period = int(period)
70 if period == 0:
71 log.info("Stopping probes...")
72 args.period = period
73 probe_stop.set()
74 else:
75 log.info("Starting probes...")
76 args.period = period
77 probe_start.set()
Shad Ansari0a905032022-02-10 19:37:15 +000078 config = vars(args)
79 config.pop('token', None)
80 config.pop('user', None)
81 config.pop('password', None)
82 return config
Shad Ansari6fcfa292022-01-28 00:34:13 +000083
Shad Ansari5b9d1f52022-01-29 01:42:45 +000084
85def build_argparser():
86 parser = ArgumentParser(add_help=False)
87 args = parser.add_argument_group('Options')
88 args.add_argument('-h', '--help',
89 action='help',
90 default=SUPPRESS,
91 help='Show this help message and exit.')
92 args.add_argument("--user",
93 help="ROC username",
94 type=str)
95 args.add_argument("--password",
96 help="ROC password",
97 type=str)
Shad Ansarid88692c2022-02-01 22:47:43 +000098 args.add_argument("--token",
99 help="Rancher bearer token",
100 type=str)
Shad Ansari500f9a02022-02-04 21:15:24 +0000101 args.add_argument("--port",
102 help="Service port",
103 type=str,
104 default="3333")
Shad Ansari0a905032022-02-10 19:37:15 +0000105 args.add_argument("--period",
106 help="Probing period in sec",
107 type=int,
108 default=180)
Shad Ansari0508ddf2022-03-24 03:16:51 +0000109 args.add_argument("--url",
110 help="ROC url",
111 type=str,
112 default="https://roc.menlo.aetherproject.org/aether-roc-api/aether/v2.0.0/connectivity-service-v2/")
113 args.add_argument("--enterprise",
114 help="Enterprise Id",
115 type=str,
116 default="aether-onf")
117 args.add_argument("--site",
118 help="Site Id",
119 type=str,
120 default="menlo-4g")
Shad Ansari5b9d1f52022-01-29 01:42:45 +0000121 return parser
122
Shad Ansari0508ddf2022-03-24 03:16:51 +0000123
Shad Ansariae3903e2022-02-05 01:03:01 +0000124def update(roc, prom, old):
125 new = roc.update_devices(old)
Shad Ansari907b7712022-02-07 21:48:04 +0000126 if new is not None:
127 new = prom.update_devices(new)
128 else:
129 new = old
Shad Ansariae3903e2022-02-05 01:03:01 +0000130 return new
Shad Ansarid88692c2022-02-01 22:47:43 +0000131
Shad Ansari0508ddf2022-03-24 03:16:51 +0000132
133def do_probe(devices):
Shad Ansarid88692c2022-02-01 22:47:43 +0000134 for imsi_id, device in devices.items():
135 if device.ip is None:
136 continue
137 if ping(device.ip):
138 device.reachable = True
139 device.last_reachable = datetime.now()
140 log.info("{}/{}/{} - reachable".format(device.imsi_id, device.imsi, device.ip))
141 else:
142 device.reachable = False
143 log.info("{}/{}/{} - unreachable".format(device.imsi_id, device.imsi, device.ip))
144
Shad Ansari0508ddf2022-03-24 03:16:51 +0000145
Shad Ansarice3c67b2022-02-10 21:00:25 +0000146def update_and_probe():
147 global devices, lock
148 new = update(roc, prom, devices)
Shad Ansari0508ddf2022-03-24 03:16:51 +0000149 do_probe(new)
Shad Ansarice3c67b2022-02-10 21:00:25 +0000150 with lock:
151 devices = new
Shad Ansariae3903e2022-02-05 01:03:01 +0000152
Shad Ansari0508ddf2022-03-24 03:16:51 +0000153
Shad Ansarice3c67b2022-02-10 21:00:25 +0000154def work_thread(roc, prom):
155 global args
156 while True:
157 probe_start.wait()
158 probe_start.clear()
159 log.info("Probing started")
160 while True:
161 update_and_probe()
162 if probe_stop.wait(timeout=args.period):
163 log.info("Probing stopped")
164 probe_stop.clear()
165 break
Shad Ansari5b9d1f52022-01-29 01:42:45 +0000166
Shad Ansari0508ddf2022-03-24 03:16:51 +0000167
Shad Ansari500f9a02022-02-04 21:15:24 +0000168if __name__ == '__main__':
169
170 log.basicConfig(
171 format='%(asctime)s %(levelname)-8s %(message)s',
172 level=log.DEBUG,
173 datefmt='%Y-%m-%d %H:%M:%S',
174 stream=sys.stdout)
175
Shad Ansari500f9a02022-02-04 21:15:24 +0000176 log.info("Starting network-diag-app...")
177
178 args = build_argparser().parse_args()
179
Shad Ansari0508ddf2022-03-24 03:16:51 +0000180 roc = Roc(args.url, args.user, args.password, args.enterprise, args.site)
Shad Ansari500f9a02022-02-04 21:15:24 +0000181 prom = Prometheus(args.token.split(':')[0], args.token.split(':')[1])
182
183 t = threading.Thread(target=work_thread, args=(roc, prom,))
184 t.start()
Shad Ansarice3c67b2022-02-10 21:00:25 +0000185 probe_start.set()
Shad Ansari500f9a02022-02-04 21:15:24 +0000186
187 app.run('0.0.0.0', args.port)