blob: 78e74d5499854539a4fa1ed33a683288fdc5f1c9 [file] [log] [blame]
Shad Ansari6fcfa292022-01-28 00:34:13 +00001"""
Shad Ansarib046c152022-06-07 14:34:14 -07002SPDX-FileCopyrightText: 2022-present Intel Corporation
Shad Ansari6fcfa292022-01-28 00:34:13 +00003SPDX-FileCopyrightText: 2020-present Open Networking Foundation <info@opennetworking.org>
Shad Ansarib046c152022-06-07 14:34:14 -07004SPDX-License-Identifier: Apache-2.0
Shad Ansari6fcfa292022-01-28 00:34:13 +00005"""
6import sys
Shad Ansari115b3f92022-03-28 19:40:01 +00007import os
Shad Ansarid88692c2022-02-01 22:47:43 +00008from datetime import datetime
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
Shad Ansari1dcfdb32022-01-24 23:13:06 +000018
19app = Flask(__name__)
Shad Ansari1dcfdb32022-01-24 23:13:06 +000020
Shad Ansari0508ddf2022-03-24 03:16:51 +000021devices = {} # dict imsi:device
Shad Ansari500f9a02022-02-04 21:15:24 +000022lock = threading.Lock()
Shad Ansarice3c67b2022-02-10 21:00:25 +000023probe_start = threading.Event()
24probe_stop = threading.Event()
Shad Ansari6fcfa292022-01-28 00:34:13 +000025
Shad Ansari5b9d1f52022-01-29 01:42:45 +000026
Shad Ansari467862f2022-02-08 00:40:40 +000027@app.route("/devices")
28def get_devices():
29 global devices, lock
30 with lock:
31 all = {}
32 for _, device in devices.items():
Shad Ansari0508ddf2022-03-24 03:16:51 +000033 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 +000034 return all
Shad Ansarid88692c2022-02-01 22:47:43 +000035
Shad Ansari0508ddf2022-03-24 03:16:51 +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:
Shad Ansari0508ddf2022-03-24 03:16:51 +000044 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 +000045 return reachable
Shad Ansari5b9d1f52022-01-29 01:42:45 +000046
Shad Ansari0508ddf2022-03-24 03:16:51 +000047
Shad Ansari467862f2022-02-08 00:40:40 +000048@app.route("/devices/unreachable")
49def get_devices_unreachable():
50 global devices, lock
51 with lock:
52 unreachable = {}
53 for _, device in devices.items():
54 if device.reachable is False:
Shad Ansari0508ddf2022-03-24 03:16:51 +000055 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 +000056 return unreachable
Shad Ansari1dcfdb32022-01-24 23:13:06 +000057
Shad Ansari0508ddf2022-03-24 03:16:51 +000058
Shad Ansarice3c67b2022-02-10 21:00:25 +000059@app.route("/probe")
60def probe():
61 update_and_probe()
62 return get_devices_reachable()
63
Shad Ansari0508ddf2022-03-24 03:16:51 +000064
65# curl http://localhost:3333/config?period=0
Shad Ansari0a905032022-02-10 19:37:15 +000066@app.route("/config")
67def config():
Shad Ansarice3c67b2022-02-10 21:00:25 +000068 global args, probe_stop
Shad Ansari0a905032022-02-10 19:37:15 +000069 period = request.args.get('period')
70 if period is not None:
Shad Ansarice3c67b2022-02-10 21:00:25 +000071 period = int(period)
72 if period == 0:
73 log.info("Stopping probes...")
74 args.period = period
75 probe_stop.set()
76 else:
77 log.info("Starting probes...")
78 args.period = period
79 probe_start.set()
Shad Ansari0a905032022-02-10 19:37:15 +000080 config = vars(args)
81 config.pop('token', None)
82 config.pop('user', None)
83 config.pop('password', None)
84 return config
Shad Ansari6fcfa292022-01-28 00:34:13 +000085
Shad Ansari5b9d1f52022-01-29 01:42:45 +000086
87def build_argparser():
88 parser = ArgumentParser(add_help=False)
89 args = parser.add_argument_group('Options')
90 args.add_argument('-h', '--help',
91 action='help',
92 default=SUPPRESS,
93 help='Show this help message and exit.')
94 args.add_argument("--user",
95 help="ROC username",
96 type=str)
97 args.add_argument("--password",
98 help="ROC password",
99 type=str)
Shad Ansarid88692c2022-02-01 22:47:43 +0000100 args.add_argument("--token",
101 help="Rancher bearer token",
102 type=str)
Shad Ansari500f9a02022-02-04 21:15:24 +0000103 args.add_argument("--port",
104 help="Service port",
105 type=str,
106 default="3333")
Shad Ansari0a905032022-02-10 19:37:15 +0000107 args.add_argument("--period",
108 help="Probing period in sec",
109 type=int,
110 default=180)
Shad Ansari0508ddf2022-03-24 03:16:51 +0000111 args.add_argument("--url",
112 help="ROC url",
113 type=str,
114 default="https://roc.menlo.aetherproject.org/aether-roc-api/aether/v2.0.0/connectivity-service-v2/")
115 args.add_argument("--enterprise",
116 help="Enterprise Id",
117 type=str,
118 default="aether-onf")
119 args.add_argument("--site",
120 help="Site Id",
121 type=str,
122 default="menlo-4g")
Shad Ansari5b9d1f52022-01-29 01:42:45 +0000123 return parser
124
Shad Ansari0508ddf2022-03-24 03:16:51 +0000125
Shad Ansariae3903e2022-02-05 01:03:01 +0000126def update(roc, prom, old):
127 new = roc.update_devices(old)
Shad Ansari907b7712022-02-07 21:48:04 +0000128 if new is not None:
129 new = prom.update_devices(new)
130 else:
131 new = old
Shad Ansariae3903e2022-02-05 01:03:01 +0000132 return new
Shad Ansarid88692c2022-02-01 22:47:43 +0000133
Shad Ansari0508ddf2022-03-24 03:16:51 +0000134
135def do_probe(devices):
Arrobo, Gabriel5b16e3b2022-08-25 10:01:04 -0700136 for _, device in devices.items():
Shad Ansarid88692c2022-02-01 22:47:43 +0000137 if device.ip is None:
138 continue
139 if ping(device.ip):
140 device.reachable = True
141 device.last_reachable = datetime.now()
142 log.info("{}/{}/{} - reachable".format(device.imsi_id, device.imsi, device.ip))
143 else:
144 device.reachable = False
145 log.info("{}/{}/{} - unreachable".format(device.imsi_id, device.imsi, device.ip))
146
Shad Ansari0508ddf2022-03-24 03:16:51 +0000147
Shad Ansarice3c67b2022-02-10 21:00:25 +0000148def update_and_probe():
149 global devices, lock
150 new = update(roc, prom, devices)
Shad Ansari0508ddf2022-03-24 03:16:51 +0000151 do_probe(new)
Shad Ansarice3c67b2022-02-10 21:00:25 +0000152 with lock:
153 devices = new
Shad Ansariae3903e2022-02-05 01:03:01 +0000154
Shad Ansari0508ddf2022-03-24 03:16:51 +0000155
Shad Ansarice3c67b2022-02-10 21:00:25 +0000156def work_thread(roc, prom):
157 global args
158 while True:
159 probe_start.wait()
160 probe_start.clear()
161 log.info("Probing started")
162 while True:
163 update_and_probe()
164 if probe_stop.wait(timeout=args.period):
165 log.info("Probing stopped")
166 probe_stop.clear()
167 break
Shad Ansari5b9d1f52022-01-29 01:42:45 +0000168
Shad Ansari0508ddf2022-03-24 03:16:51 +0000169
Shad Ansari500f9a02022-02-04 21:15:24 +0000170if __name__ == '__main__':
171
172 log.basicConfig(
173 format='%(asctime)s %(levelname)-8s %(message)s',
174 level=log.DEBUG,
175 datefmt='%Y-%m-%d %H:%M:%S',
176 stream=sys.stdout)
177
Shad Ansari500f9a02022-02-04 21:15:24 +0000178 log.info("Starting network-diag-app...")
179
180 args = build_argparser().parse_args()
181
Shad Ansari115b3f92022-03-28 19:40:01 +0000182 if not args.user:
183 args.user = os.environ.get('ROCUSER')
184 if not args.password:
185 args.password = os.environ.get('ROCPASSWORD')
186 if not args.token:
187 args.token= os.environ.get('KEYCLOAKTOKEN')
188
Shad Ansari0508ddf2022-03-24 03:16:51 +0000189 roc = Roc(args.url, args.user, args.password, args.enterprise, args.site)
Shad Ansari500f9a02022-02-04 21:15:24 +0000190 prom = Prometheus(args.token.split(':')[0], args.token.split(':')[1])
191
192 t = threading.Thread(target=work_thread, args=(roc, prom,))
193 t.start()
Shad Ansarice3c67b2022-02-10 21:00:25 +0000194 probe_start.set()
Shad Ansari500f9a02022-02-04 21:15:24 +0000195
196 app.run('0.0.0.0', args.port)