blob: 86d564f9db70d44eafcd5fed3791294d7fdbcd12 [file] [log] [blame]
"""
SPDX-FileCopyrightText: 2022-present Intel Corporation
SPDX-FileCopyrightText: 2020-present Open Networking Foundation <info@opennetworking.org>
SPDX-License-Identifier: Apache-2.0
"""
import sys
import os
from datetime import datetime
from flask import Flask, request
import logging as log
from argparse import ArgumentParser, SUPPRESS
import threading
from roc import Roc
from prom import Prometheus
from ping import ping
app = Flask(__name__)
devices = {} # dict imsi:device
lock = threading.Lock()
probe_start = threading.Event()
probe_stop = threading.Event()
@app.route("/devices")
def get_devices():
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
@app.route("/devices/reachable")
def get_devices_reachable():
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
@app.route("/devices/unreachable")
def get_devices_unreachable():
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
@app.route("/probe")
def probe():
update_and_probe()
return get_devices_reachable()
# curl http://localhost:3333/config?period=0
@app.route("/config")
def config():
global args, probe_stop
period = request.args.get('period')
if period is not None:
period = int(period)
if period == 0:
log.info("Stopping probes...")
args.period = period
probe_stop.set()
else:
log.info("Starting probes...")
args.period = period
probe_start.set()
config = vars(args)
config.pop('token', None)
config.pop('user', None)
config.pop('password', None)
return config
def build_argparser():
parser = ArgumentParser(add_help=False)
args = parser.add_argument_group('Options')
args.add_argument('-h', '--help',
action='help',
default=SUPPRESS,
help='Show this help message and exit.')
args.add_argument("--user",
help="ROC username",
type=str)
args.add_argument("--password",
help="ROC password",
type=str)
args.add_argument("--token",
help="Rancher bearer token",
type=str)
args.add_argument("--port",
help="Service port",
type=str,
default="3333")
args.add_argument("--period",
help="Probing period in sec",
type=int,
default=180)
args.add_argument("--url",
help="ROC url",
type=str,
default="https://roc.menlo.aetherproject.org/aether-roc-api/aether/v2.0.0/connectivity-service-v2/")
args.add_argument("--enterprise",
help="Enterprise Id",
type=str,
default="aether-onf")
args.add_argument("--site",
help="Site Id",
type=str,
default="menlo-4g")
return parser
def update(roc, prom, old):
new = roc.update_devices(old)
if new is not None:
new = prom.update_devices(new)
else:
new = old
return new
def do_probe(devices):
for imsi_id, device in devices.items():
if device.ip is None:
continue
if ping(device.ip):
device.reachable = True
device.last_reachable = datetime.now()
log.info("{}/{}/{} - reachable".format(device.imsi_id, device.imsi, device.ip))
else:
device.reachable = False
log.info("{}/{}/{} - unreachable".format(device.imsi_id, device.imsi, device.ip))
def update_and_probe():
global devices, lock
new = update(roc, prom, devices)
do_probe(new)
with lock:
devices = new
def work_thread(roc, prom):
global args
while True:
probe_start.wait()
probe_start.clear()
log.info("Probing started")
while True:
update_and_probe()
if probe_stop.wait(timeout=args.period):
log.info("Probing stopped")
probe_stop.clear()
break
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()
if not args.user:
args.user = os.environ.get('ROCUSER')
if not args.password:
args.password = os.environ.get('ROCPASSWORD')
if not args.token:
args.token= os.environ.get('KEYCLOAKTOKEN')
roc = Roc(args.url, args.user, args.password, args.enterprise, args.site)
prom = Prometheus(args.token.split(':')[0], args.token.split(':')[1])
t = threading.Thread(target=work_thread, args=(roc, prom,))
t.start()
probe_start.set()
app.run('0.0.0.0', args.port)