blob: d8c900218a7686848e8c60909c43c1a2ed6bb120 [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 Ansari115b3f92022-03-28 19:40:01 +00006import os
Shad Ansarid88692c2022-02-01 22:47:43 +00007from datetime import datetime
Shad Ansari6fcfa292022-01-28 00:34:13 +00008
Shad Ansari1dcfdb32022-01-24 23:13:06 +00009from flask import Flask, request
Shad Ansari6fcfa292022-01-28 00:34:13 +000010import logging as log
Shad Ansari5b9d1f52022-01-29 01:42:45 +000011from argparse import ArgumentParser, SUPPRESS
Shad Ansari500f9a02022-02-04 21:15:24 +000012import threading
Shad Ansari5b9d1f52022-01-29 01:42:45 +000013
14from roc import Roc
Shad Ansarid88692c2022-02-01 22:47:43 +000015from prom import Prometheus
16from ping import ping
Shad Ansari1dcfdb32022-01-24 23:13:06 +000017
18app = Flask(__name__)
Shad Ansari1dcfdb32022-01-24 23:13:06 +000019
Shad Ansari0508ddf2022-03-24 03:16:51 +000020devices = {} # dict imsi:device
Shad Ansari500f9a02022-02-04 21:15:24 +000021lock = threading.Lock()
Shad Ansarice3c67b2022-02-10 21:00:25 +000022probe_start = threading.Event()
23probe_stop = threading.Event()
Shad Ansari6fcfa292022-01-28 00:34:13 +000024
Shad Ansari5b9d1f52022-01-29 01:42:45 +000025
Shad Ansari467862f2022-02-08 00:40:40 +000026@app.route("/devices")
27def get_devices():
28 global devices, lock
29 with lock:
30 all = {}
31 for _, device in devices.items():
Shad Ansari0508ddf2022-03-24 03:16:51 +000032 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 +000033 return all
Shad Ansarid88692c2022-02-01 22:47:43 +000034
Shad Ansari0508ddf2022-03-24 03:16:51 +000035
Shad Ansari467862f2022-02-08 00:40:40 +000036@app.route("/devices/reachable")
37def get_devices_reachable():
38 global devices, lock
39 with lock:
40 reachable = {}
41 for _, device in devices.items():
42 if device.reachable is True:
Shad Ansari0508ddf2022-03-24 03:16:51 +000043 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 +000044 return reachable
Shad Ansari5b9d1f52022-01-29 01:42:45 +000045
Shad Ansari0508ddf2022-03-24 03:16:51 +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:
Shad Ansari0508ddf2022-03-24 03:16:51 +000054 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 +000055 return unreachable
Shad Ansari1dcfdb32022-01-24 23:13:06 +000056
Shad Ansari0508ddf2022-03-24 03:16:51 +000057
Shad Ansarice3c67b2022-02-10 21:00:25 +000058@app.route("/probe")
59def probe():
60 update_and_probe()
61 return get_devices_reachable()
62
Shad Ansari0508ddf2022-03-24 03:16:51 +000063
64# curl http://localhost:3333/config?period=0
Shad Ansari0a905032022-02-10 19:37:15 +000065@app.route("/config")
66def config():
Shad Ansarice3c67b2022-02-10 21:00:25 +000067 global args, probe_stop
Shad Ansari0a905032022-02-10 19:37:15 +000068 period = request.args.get('period')
69 if period is not None:
Shad Ansarice3c67b2022-02-10 21:00:25 +000070 period = int(period)
71 if period == 0:
72 log.info("Stopping probes...")
73 args.period = period
74 probe_stop.set()
75 else:
76 log.info("Starting probes...")
77 args.period = period
78 probe_start.set()
Shad Ansari0a905032022-02-10 19:37:15 +000079 config = vars(args)
80 config.pop('token', None)
81 config.pop('user', None)
82 config.pop('password', None)
83 return config
Shad Ansari6fcfa292022-01-28 00:34:13 +000084
Shad Ansari5b9d1f52022-01-29 01:42:45 +000085
86def build_argparser():
87 parser = ArgumentParser(add_help=False)
88 args = parser.add_argument_group('Options')
89 args.add_argument('-h', '--help',
90 action='help',
91 default=SUPPRESS,
92 help='Show this help message and exit.')
93 args.add_argument("--user",
94 help="ROC username",
95 type=str)
96 args.add_argument("--password",
97 help="ROC password",
98 type=str)
Shad Ansarid88692c2022-02-01 22:47:43 +000099 args.add_argument("--token",
100 help="Rancher bearer token",
101 type=str)
Shad Ansari500f9a02022-02-04 21:15:24 +0000102 args.add_argument("--port",
103 help="Service port",
104 type=str,
105 default="3333")
Shad Ansari0a905032022-02-10 19:37:15 +0000106 args.add_argument("--period",
107 help="Probing period in sec",
108 type=int,
109 default=180)
Shad Ansari0508ddf2022-03-24 03:16:51 +0000110 args.add_argument("--url",
111 help="ROC url",
112 type=str,
113 default="https://roc.menlo.aetherproject.org/aether-roc-api/aether/v2.0.0/connectivity-service-v2/")
114 args.add_argument("--enterprise",
115 help="Enterprise Id",
116 type=str,
117 default="aether-onf")
118 args.add_argument("--site",
119 help="Site Id",
120 type=str,
121 default="menlo-4g")
Shad Ansari5b9d1f52022-01-29 01:42:45 +0000122 return parser
123
Shad Ansari0508ddf2022-03-24 03:16:51 +0000124
Shad Ansariae3903e2022-02-05 01:03:01 +0000125def update(roc, prom, old):
126 new = roc.update_devices(old)
Shad Ansari907b7712022-02-07 21:48:04 +0000127 if new is not None:
128 new = prom.update_devices(new)
129 else:
130 new = old
Shad Ansariae3903e2022-02-05 01:03:01 +0000131 return new
Shad Ansarid88692c2022-02-01 22:47:43 +0000132
Shad Ansari0508ddf2022-03-24 03:16:51 +0000133
134def do_probe(devices):
Shad Ansarid88692c2022-02-01 22:47:43 +0000135 for imsi_id, device in devices.items():
136 if device.ip is None:
137 continue
138 if ping(device.ip):
139 device.reachable = True
140 device.last_reachable = datetime.now()
141 log.info("{}/{}/{} - reachable".format(device.imsi_id, device.imsi, device.ip))
142 else:
143 device.reachable = False
144 log.info("{}/{}/{} - unreachable".format(device.imsi_id, device.imsi, device.ip))
145
Shad Ansari0508ddf2022-03-24 03:16:51 +0000146
Shad Ansarice3c67b2022-02-10 21:00:25 +0000147def update_and_probe():
148 global devices, lock
149 new = update(roc, prom, devices)
Shad Ansari0508ddf2022-03-24 03:16:51 +0000150 do_probe(new)
Shad Ansarice3c67b2022-02-10 21:00:25 +0000151 with lock:
152 devices = new
Shad Ansariae3903e2022-02-05 01:03:01 +0000153
Shad Ansari0508ddf2022-03-24 03:16:51 +0000154
Shad Ansarice3c67b2022-02-10 21:00:25 +0000155def work_thread(roc, prom):
156 global args
157 while True:
158 probe_start.wait()
159 probe_start.clear()
160 log.info("Probing started")
161 while True:
162 update_and_probe()
163 if probe_stop.wait(timeout=args.period):
164 log.info("Probing stopped")
165 probe_stop.clear()
166 break
Shad Ansari5b9d1f52022-01-29 01:42:45 +0000167
Shad Ansari0508ddf2022-03-24 03:16:51 +0000168
Shad Ansari500f9a02022-02-04 21:15:24 +0000169if __name__ == '__main__':
170
171 log.basicConfig(
172 format='%(asctime)s %(levelname)-8s %(message)s',
173 level=log.DEBUG,
174 datefmt='%Y-%m-%d %H:%M:%S',
175 stream=sys.stdout)
176
Shad Ansari500f9a02022-02-04 21:15:24 +0000177 log.info("Starting network-diag-app...")
178
179 args = build_argparser().parse_args()
180
Shad Ansari115b3f92022-03-28 19:40:01 +0000181 if not args.user:
182 args.user = os.environ.get('ROCUSER')
183 if not args.password:
184 args.password = os.environ.get('ROCPASSWORD')
185 if not args.token:
186 args.token= os.environ.get('KEYCLOAKTOKEN')
187
Shad Ansari0508ddf2022-03-24 03:16:51 +0000188 roc = Roc(args.url, args.user, args.password, args.enterprise, args.site)
Shad Ansari500f9a02022-02-04 21:15:24 +0000189 prom = Prometheus(args.token.split(':')[0], args.token.split(':')[1])
190
191 t = threading.Thread(target=work_thread, args=(roc, prom,))
192 t.start()
Shad Ansarice3c67b2022-02-10 21:00:25 +0000193 probe_start.set()
Shad Ansari500f9a02022-02-04 21:15:24 +0000194
195 app.run('0.0.0.0', args.port)