blob: 7d469905255efe9515d44f64b8235424f19699d4 [file] [log] [blame]
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -07001#!/usr/bin/env python
2
3# Copyright 2020-present Open Networking Foundation
4#
Hyunsun Moon200eba52021-04-05 21:31:54 -07005# SPDX-License-Identifier: LicenseRef-ONF-Member-Only-1.0
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -07006
Andy Bavier614af142020-08-07 14:49:56 -07007import os
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -07008import time
Andy Bavier614af142020-08-07 14:49:56 -07009import datetime
10import pytz
11import threading
12from icalevents.icalevents import events
Andy Bavier4021a2f2020-07-29 12:39:47 -070013from flask import Flask, jsonify, abort, request, Response
14import prometheus_client as prom
Andy Bavier2d60fc52021-05-04 16:13:39 -070015import jsonschema
Andy Bavier55dc5872021-05-05 11:31:42 -070016from logging.config import dictConfig
Andy Bavier4021a2f2020-07-29 12:39:47 -070017
Andy Bavier8a5c9872020-10-21 13:17:53 -070018# URL of maintenance calendar
Andy Bavier614af142020-08-07 14:49:56 -070019SECRET_ICAL_URL = os.environ.get("SECRET_ICAL_URL")
Andy Bavier8a5c9872020-10-21 13:17:53 -070020
21# Aether environment that the server is monitoring (e.g., "production")
22# To schedule downtime, postfix the cluster name with the env: "ace-tucson-production"
23AETHER_ENV = os.environ.get("AETHER_ENV", "production")
24
25# Move to "no result" status if we don't hear from agent for this many seconds
Jeremy Ronquillo56d23b12021-12-02 14:57:42 -080026NO_RESULT_THRESHOLD = 360
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -070027
Andy Bavier55dc5872021-05-05 11:31:42 -070028dictConfig({
29 'version': 1,
30 'formatters': {'default': {
Andy Bavier41fef772021-05-12 13:48:42 -070031 'format': '%(levelname)s %(message)s',
Andy Bavier55dc5872021-05-05 11:31:42 -070032 }},
33 'handlers': {'wsgi': {
34 'class': 'logging.StreamHandler',
35 'stream': 'ext://flask.logging.wsgi_errors_stream',
36 'formatter': 'default'
37 }},
38 'root': {
39 'level': 'INFO',
40 'handlers': ['wsgi']
41 }
42})
43
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -070044app = Flask(__name__)
Andy Bavier2d60fc52021-05-04 16:13:39 -070045
46edgeSchema = {
47 "type": "object",
48 "properties": {
49 "name": {"type": "string"},
50 "status": {
51 "type": "object",
52 "properties": {
53 "control_plane": {"type": "string"},
54 "user_plane": {"type": "string"}
55 },
56 "required": ["control_plane", "user_plane"]
57 },
Jeremy Ronquilloc45955a2021-11-09 12:04:57 -080058 "dongle_stats": {
59 "type": "object",
60 "properties": {
61 "SuccessfulFetch": {"type": "boolean"},
62 "MAC": {"type": "string"},
63 "PLMNStatus": {"type": "string"},
64 "UICCStatus": {"type": "string"},
65 "IMEI": {"type": "string"},
66 "IMSI": {"type": "string"},
67 "PLMNSelected": {"type": "string"},
68 "MCC": {"type": "string"},
69 "MNC": {"type": "string"},
70 "PhyCellID": {"type": "string"},
71 "CellGlobalID": {"type": "string"},
72 "Band": {"type": "string"},
73 "EARFCN": {"type": "string"},
74 "BandWidth": {"type": "string"},
75 "ServCellState": {"type": "string"},
76 "Connection": {"type": "string"},
77 "IPv4Addr": {"type": "string"}
78 }
79 },
Andy Bavier2d60fc52021-05-04 16:13:39 -070080 "speedtest": {
81 "type": "object",
82 "properties": {
83 "ping": {
84 "type": "object",
85 "properties": {
Jeremy Ronquilloe0a8b422021-11-02 12:49:15 -070086 "dry_run": {
87 "type": "object",
88 "properties": {
89 "transmitted": {"type": "number"},
90 "received": {"type": "number"},
91 "median": {"type": "number"},
92 "min": {"type": "number"},
93 "avg": {"type": "number"},
94 "max": {"type": "number"},
95 "stddev": {"type": "number"}
96 },
97 "required": ["min", "avg", "max", "stddev"]
98 },
Andy Bavier2d60fc52021-05-04 16:13:39 -070099 "dns": {
100 "type": "object",
101 "properties": {
Jeremy Ronquilloe0a8b422021-11-02 12:49:15 -0700102 "transmitted": {"type": "number"},
103 "received": {"type": "number"},
104 "median": {"type": "number"},
Andy Bavier2d60fc52021-05-04 16:13:39 -0700105 "min": {"type": "number"},
106 "avg": {"type": "number"},
107 "max": {"type": "number"},
108 "stddev": {"type": "number"}
109 },
110 "required": ["min", "avg", "max", "stddev"]
Jeremy Ronquillo6e352b72021-06-08 10:33:25 -0700111 },
112 "iperf_server": {
113 "type": "object",
114 "properties": {
Jeremy Ronquilloe0a8b422021-11-02 12:49:15 -0700115 "transmitted": {"type": "number"},
116 "received": {"type": "number"},
117 "median": {"type": "number"},
Jeremy Ronquillo6e352b72021-06-08 10:33:25 -0700118 "min": {"type": "number"},
119 "avg": {"type": "number"},
120 "max": {"type": "number"},
121 "stddev": {"type": "number"}
122 },
123 "required": ["min", "avg", "max", "stddev"]
Jeremy Ronquilloe0a8b422021-11-02 12:49:15 -0700124 },
125 "management_server": {
126 "type": "object",
127 "properties": {
128 "transmitted": {"type": "number"},
129 "received": {"type": "number"},
130 "median": {"type": "number"},
131 "min": {"type": "number"},
132 "avg": {"type": "number"},
133 "max": {"type": "number"},
134 "stddev": {"type": "number"}
135 },
136 "required": ["min", "avg", "max", "stddev"]
137 },
Andy Bavier2d60fc52021-05-04 16:13:39 -0700138 }
139 },
140 "iperf": {
141 "type": "object",
142 "properties": {
143 "cluster": {
144 "type": "object",
145 "properties": {
146 "downlink": {"type": "number"},
147 "uplink": {"type": "number"}
148 },
149 "required": ["downlink", "uplink"]
150 }
151 }
152 }
153 }
154 },
155 "signal_quality": {
156 "type": "object",
157 "properties": {
158 "rsrq": {"type": "number"},
159 "rsrp": {"type": "number"}
160 },
161 "required": ["rsrq", "rsrp"]
Shad Ansari9faaa962022-03-16 17:35:41 -0700162 },
163 "counters": {
164 "type": "object",
165 "properties": {
166 'dongle_read_error': {"type": "number"},
167 'dongle_connect_error': {"type": "number"},
168 'dongle_rsrp_rsrq_error': {"type": "number"},
169 'modem_cfun0_error': {"type": "number"},
170 'modem_cfun1_error': {"type": "number"},
171 'modem_cgatt_error': {"type": "number"},
172 'modem_cesq_error': {"type": "number"},
173 'dry_run_ping_error': {"type": "number"},
174 'ping_error': {"type": "number"},
175 'iperf_error': {"type": "number"},
176 'report_send_error': {"type": "number"}
177 }
Andy Bavier2d60fc52021-05-04 16:13:39 -0700178 }
179 },
180 "required": ["name", "status"]
181}
182
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -0700183edges = [
184 {
Andy Bavier8a5c9872020-10-21 13:17:53 -0700185 'name': 'ace-example',
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -0700186 'status': {
187 'control_plane': 'connected',
188 'user_plane': 'connected'
189 },
Jeremy Ronquilloc45955a2021-11-09 12:04:57 -0800190 'dongle_stats': {
Shad Ansari9faaa962022-03-16 17:35:41 -0700191 'SuccessfulFetch': False
Jeremy Ronquilloc45955a2021-11-09 12:04:57 -0800192 },
Jeremy Ronquillof4200252021-02-13 16:11:04 -0800193 'speedtest': {
194 'ping': {
Jeremy Ronquilloe0a8b422021-11-02 12:49:15 -0700195 'dry_run': {
196 'transmitted': 0,
197 'received': 0,
198 'median': 0.0,
199 'min': 0.0,
200 'avg': 0.0,
201 'max': 0.0,
202 'stddev': 0.0
203 },
Jeremy Ronquillof4200252021-02-13 16:11:04 -0800204 'dns': {
Jeremy Ronquilloe0a8b422021-11-02 12:49:15 -0700205 'transmitted': 0,
206 'received': 0,
207 'median': 0.0,
Jeremy Ronquilloa944fbc2021-03-30 10:57:45 -0700208 'min': 0.0,
209 'avg': 0.0,
210 'max': 0.0,
211 'stddev': 0.0
Jeremy Ronquillo6e352b72021-06-08 10:33:25 -0700212 },
213 'iperf_server': {
Jeremy Ronquilloe0a8b422021-11-02 12:49:15 -0700214 'transmitted': 0,
215 'received': 0,
216 'median': 0.0,
217 'min': 0.0,
218 'avg': 0.0,
219 'max': 0.0,
220 'stddev': 0.0
221 },
222 'management_server': {
223 'transmitted': 0,
224 'received': 0,
225 'median': 0.0,
Jeremy Ronquillo6e352b72021-06-08 10:33:25 -0700226 'min': 0.0,
227 'avg': 0.0,
228 'max': 0.0,
229 'stddev': 0.0
Jeremy Ronquillof4200252021-02-13 16:11:04 -0800230 }
Jeremy Ronquilloc7434622021-04-08 21:06:00 -0700231 },
232 'iperf': {
233 'cluster': {
234 'downlink': 0.0,
235 'uplink': 0.0
236 }
Jeremy Ronquillof4200252021-02-13 16:11:04 -0800237 }
238 },
Hyunsun Moon200eba52021-04-05 21:31:54 -0700239 'signal_quality': {
240 'rsrq': 0,
241 'rsrp': 0
242 },
Shad Ansari9faaa962022-03-16 17:35:41 -0700243 'counters': {
244 'dongle_read_error': 0,
245 'dongle_connect_error': 0,
246 'dongle_rsrp_rsrq_error': 0,
247 'modem_cfun0_error': 0,
248 'modem_cfun1_error': 0,
249 'modem_cgatt_error': 0,
250 'modem_cesq_error': 0,
251 'dry_run_ping_error': 0,
252 'ping_error': 0,
253 'iperf_error': 0,
254 'report_send_error': 0
255 },
Hyunsun Moon200eba52021-04-05 21:31:54 -0700256 'last_update': time.time()
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -0700257 }
258]
259
Andy Bavier4021a2f2020-07-29 12:39:47 -0700260status_codes = {
261 "no result": -2,
262 "error": -1,
263 "disconnected": 0,
264 "connecting": 1,
265 "connected": 2
266}
267
Andy Bavier614af142020-08-07 14:49:56 -0700268room_mapping = {
Andy Baviere4591222021-07-07 12:44:19 -0700269 "ace-menlo-rasp-pi-production": "(Compute)-MP-1-Aether Production",
Andy Bavier0423cbd2020-10-23 10:50:29 -0700270 "ace-menlo-staging": "(Compute)-MP-1-Aether Staging"
Andy Bavier614af142020-08-07 14:49:56 -0700271}
272
Jeremy Ronquillo1eaff6a2021-11-16 13:46:46 -0800273plmnstatus_mapping = {
274 "Not Searching": 1,
275 "Searching": 2,
276 "Success": 3
277}
278
Andy Bavier5b4e28f2021-03-09 15:48:20 -0700279# Legacy test status metrics, reporting a status code between -2 and 2
Andy Bavier4021a2f2020-07-29 12:39:47 -0700280cp_status = prom.Gauge("aetheredge_status_control_plane", "Control plane status code", ["name"])
281up_status = prom.Gauge("aetheredge_status_user_plane", "User plane status code", ["name"])
Andy Bavier5b4e28f2021-03-09 15:48:20 -0700282
283# Simplified binary test result metrics
Andy Bavier3c7b78d2021-03-11 14:16:43 -0700284e2e_tests_ok = prom.Gauge("aetheredge_e2e_tests_ok", "Last connect and ping test both passed", ["name"])
Andy Baviera0c40aa2021-03-10 12:09:12 -0700285connect_test_ok = prom.Gauge("aetheredge_connect_test_ok", "Last connect test passed", ["name"])
Andy Baviera0c40aa2021-03-10 12:09:12 -0700286ping_test_ok = prom.Gauge("aetheredge_ping_test_ok", "Last ping test passed", ["name"])
Andy Bavier3c7b78d2021-03-11 14:16:43 -0700287e2e_tests_down = prom.Gauge("aetheredge_e2e_tests_down", "E2E tests not reporting", ["name"])
Andy Bavier5b4e28f2021-03-09 15:48:20 -0700288
Jeremy Ronquilloc45955a2021-11-09 12:04:57 -0800289# Dongle Stats (strings can't be stored in Prometheus)
290dongle_stats_imsi = prom.Gauge("aetheredge_dongle_stats_imsi", "IMSI of the UE", ["name"])
Jeremy Ronquillo1eaff6a2021-11-16 13:46:46 -0800291dongle_stats_cellglobalid = prom.Gauge("aetheredge_dongle_stats_cellglobalid", "CellGlobalID of the UE", ["name"])
292dongle_stats_plmnstatus = prom.Gauge("aetheredge_dongle_stats_plmnstatus", "PLMNStatus of the UE", ["name"])
293dongle_stats_phycellid = prom.Gauge("aetheredge_dongle_stats_phycellid", "PhyCellID of the UE", ["name"])
Jeremy Ronquilloc45955a2021-11-09 12:04:57 -0800294
Jeremy Ronquilloe0a8b422021-11-02 12:49:15 -0700295# Ping dry_run metrics
Shad Ansari9faaa962022-03-16 17:35:41 -0700296ping_dry_run_transmitted = prom.Gauge("aetheredge_ping_dry_run_test_transmitted", "Last ping test to dry_run number of transmitted packets", ["name"])
297ping_dry_run_received = prom.Gauge("aetheredge_ping_dry_run_test_received", "Last ping test to dry_run number of received packets",["name"])
298ping_dry_run_median = prom.Gauge("aetheredge_ping_dry_run_test_median", "Last ping test to dry_run median value", ["name"])
299ping_dry_run_min = prom.Gauge("aetheredge_ping_dry_run_test_min", "Last ping test to dry_run minimum value", ["name"])
300ping_dry_run_avg = prom.Gauge("aetheredge_ping_dry_run_test_avg", "Last ping test to dry_run average", ["name"])
301ping_dry_run_max = prom.Gauge("aetheredge_ping_dry_run_test_max", "Last ping test to dry_run maximum value", ["name"])
302ping_dry_run_stddev = prom.Gauge("aetheredge_ping_dry_run_test_stddev", "Last ping test to dry_run standard deviation", ["name"])
Jeremy Ronquilloe0a8b422021-11-02 12:49:15 -0700303
304# Ping dns metrics
Shad Ansari9faaa962022-03-16 17:35:41 -0700305ping_dns_transmitted = prom.Gauge("aetheredge_ping_dns_test_transmitted", "Last ping test to dns number of transmitted packets", ["name"])
306ping_dns_received = prom.Gauge("aetheredge_ping_dns_test_received", "Last ping test to dns number of received packets", ["name"])
307ping_dns_median = prom.Gauge("aetheredge_ping_dns_test_median", "Last ping test to dns median value",["name"])
308ping_dns_min = prom.Gauge("aetheredge_ping_dns_test_min", "Last ping test to dns minimum value",["name"])
309ping_dns_avg = prom.Gauge("aetheredge_ping_dns_test_avg", "Last ping test to dns average",["name"])
310ping_dns_max = prom.Gauge("aetheredge_ping_dns_test_max", "Last ping test to dns maximum value",["name"])
311ping_dns_stddev = prom.Gauge("aetheredge_ping_dns_test_stddev", "Last ping test to dns standard deviation",["name"])
Jeremy Ronquillo6e352b72021-06-08 10:33:25 -0700312
Jeremy Ronquilloe0a8b422021-11-02 12:49:15 -0700313# Ping iperf server metrics
Shad Ansari9faaa962022-03-16 17:35:41 -0700314ping_iperf_server_transmitted = prom.Gauge("aetheredge_ping_iperf_server_test_transmitted","Last ping test to iperf_server number of transmitted packets", ["name"])
315ping_iperf_server_received = prom.Gauge("aetheredge_ping_iperf_server_test_received","Last ping test to iperf_server number of received packets", ["name"])
316ping_iperf_server_median = prom.Gauge("aetheredge_ping_iperf_server_test_median","Last ping test to iperf_server median value", ["name"])
317ping_iperf_server_min = prom.Gauge("aetheredge_ping_iperf_server_test_min","Last ping test to iperf_server minimum value", ["name"])
318ping_iperf_server_avg = prom.Gauge("aetheredge_ping_iperf_server_test_avg","Last ping test to iperf_server average", ["name"])
319ping_iperf_server_max = prom.Gauge("aetheredge_ping_iperf_server_test_max","Last ping test to iperf_server maximum value", ["name"])
320ping_iperf_server_stddev = prom.Gauge("aetheredge_ping_iperf_server_test_stddev","Last ping test to iperf_server standard deviation", ["name"])
Jeremy Ronquillof4200252021-02-13 16:11:04 -0800321
Jeremy Ronquilloe0a8b422021-11-02 12:49:15 -0700322# Ping management_server metrics
Shad Ansari9faaa962022-03-16 17:35:41 -0700323ping_management_server_transmitted = prom.Gauge("aetheredge_ping_management_server_test_transmitted","Last ping test to management_server number of transmitted packets", ["name"])
324ping_management_server_received = prom.Gauge("aetheredge_ping_management_server_test_received","Last ping test to management_server number of received packets", ["name"])
325ping_management_server_median = prom.Gauge("aetheredge_ping_management_server_test_median","Last ping test to management_server median value", ["name"])
Jeremy Ronquilloe0a8b422021-11-02 12:49:15 -0700326ping_management_server_min = prom.Gauge("aetheredge_ping_management_server_test_min","Last ping test to management_server minimum value",["name"])
Shad Ansari9faaa962022-03-16 17:35:41 -0700327ping_management_server_avg = prom.Gauge("aetheredge_ping_management_server_test_avg","Last ping test to management_server average", ["name"])
328ping_management_server_max = prom.Gauge("aetheredge_ping_management_server_test_max","Last ping test to management_server maximum value", ["name"])
329ping_management_server_stddev = prom.Gauge("aetheredge_ping_management_server_test_stddev","Last ping test to management_server standard deviation", ["name"])
Jeremy Ronquilloe0a8b422021-11-02 12:49:15 -0700330
Jeremy Ronquilloc7434622021-04-08 21:06:00 -0700331# Speedtest iperf metrics
332iperf_cluster_downlink = prom.Gauge("aetheredge_iperf_cluster_downlink_test","Last iperf test downlink result",["name"])
333iperf_cluster_uplink = prom.Gauge("aetheredge_iperf_cluster_uplink_test","Last iperf test downlink result",["name"])
334
Hyunsun Moon200eba52021-04-05 21:31:54 -0700335# Signal quality metrics in CESQ format not dB
336# RSRQ: >=53 excellent, 43 ~ 53 good, 33 ~ 43 mid, <=33 bad, 0 no signal
337# RSRP: >=20 excellent, 10 ~ 20 good, 0 ~ 10 mid, 0 no signal
338signal_quality_rsrq = prom.Gauge("aetheredge_signal_quality_rsrq", "Quality of the received signal", ["name"])
339signal_quality_rsrp = prom.Gauge("aetheredge_signal_quality_rsrp", "Power of the received signal", ["name"])
340
Shad Ansari9faaa962022-03-16 17:35:41 -0700341counters_dongle_read_error = prom.Gauge("aetheredge_counters_dongle_read_error", "Dongle read error counter", ["name"])
342counters_dongle_connect_error = prom.Gauge("aetheredge_counters_dongle_connect_error", "Dongle connect error counter", ["name"])
343counters_dongle_rsrp_rsrq_error = prom.Gauge("aetheredge_counters_dongle_rsrp_rsrq_error", "Dongle rsrp/rsrq error counter", ["name"])
344counters_modem_cfun0_error = prom.Gauge("aetheredge_counters_modem_cfun0_error", "Modem cfun0 error counter", ["name"])
345counters_modem_cfun1_error = prom.Gauge("aetheredge_counters_modem_cfun1_error", "Modem cfun1 error counter", ["name"])
346counters_modem_cgatt_error = prom.Gauge("aetheredge_counters_modem_cgatt_error", "Modem cgatt error counter", ["name"])
347counters_modem_cesq_error = prom.Gauge("aetheredge_counters_modem_cesq_error", "Modem cesq error counter", ["name"])
348counters_dry_run_ping_error = prom.Gauge("aetheredge_counters_dry_run_ping_error", "Dry run ping error counter", ["name"])
349counters_ping_error = prom.Gauge("aetheredge_counters_ping_error", "Ping error counter", ["name"])
350counters_iperf_error = prom.Gauge("aetheredge_counters_iperf_error", "Iperf error counter", ["name"])
351counters_report_send_error = prom.Gauge("aetheredge_counters_report_send_error", "Report send error counter", ["name"])
352
Andy Bavier5b4e28f2021-03-09 15:48:20 -0700353# Other metrics
Andy Bavier4021a2f2020-07-29 12:39:47 -0700354last_update = prom.Gauge("aetheredge_last_update", "Last reported test result", ["name"])
Andy Bavier614af142020-08-07 14:49:56 -0700355maint_window = prom.Gauge("aetheredge_in_maintenance_window", "Currently in a maintenance window", ["name"])
356
357def is_my_event(event, name):
358 for field in ["summary", "location", "description"]:
Andy Bavier8a5c9872020-10-21 13:17:53 -0700359 fullname = name
360 if name.startswith("ace-"):
361 fullname = "%s-%s" % (name, AETHER_ENV)
362 if fullname in getattr(event, field, ""):
Andy Bavier614af142020-08-07 14:49:56 -0700363 return True
Andy Bavier0423cbd2020-10-23 10:50:29 -0700364 if fullname in room_mapping and room_mapping[fullname] in getattr(event, field, ""):
365 return True
Andy Bavier614af142020-08-07 14:49:56 -0700366 return False
367
Andy Bavierc41cf0c2020-09-02 14:49:21 -0700368def is_naive_datetime(d):
369 return d.tzinfo is None or d.tzinfo.utcoffset(d) is None
370
371def process_all_day_events(es):
372 for event in es:
373 if event.all_day:
374 # All day events have naive datetimes, which breaks comparisons
375 pacific = pytz.timezone('US/Pacific')
376 if is_naive_datetime(event.start):
377 event.start = pacific.localize(event.start)
378 if is_naive_datetime(event.end):
379 event.end = pacific.localize(event.end)
380
Andy Bavier614af142020-08-07 14:49:56 -0700381def in_maintenance_window(events, name, now):
382 for event in events:
383 if event.start < now and event.end > now:
384 if is_my_event(event, name):
385 return True
Andy Bavier614af142020-08-07 14:49:56 -0700386 return False
387
388def pull_maintenance_events():
389 while(True):
390 now = datetime.datetime.now(pytz.utc)
391 try:
392 es = events(SECRET_ICAL_URL, start = now)
Andy Bavierc41cf0c2020-09-02 14:49:21 -0700393 process_all_day_events(es)
Andy Bavier614af142020-08-07 14:49:56 -0700394 except Exception as e:
Andy Bavier55dc5872021-05-05 11:31:42 -0700395 app.logger.error(e)
Andy Bavier614af142020-08-07 14:49:56 -0700396 else:
397 for edge in edges:
398 if 'maintenance' not in edge:
399 edge['maintenance'] = {}
400 edge['maintenance']['in_window'] = in_maintenance_window(es, edge['name'], now)
401 edge['maintenance']['last_update'] = time.time()
402 time.sleep(60)
Andy Bavier4021a2f2020-07-29 12:39:47 -0700403
404def time_out_stale_results():
405 for edge in edges:
406 time_elapsed = time.time() - edge["last_update"]
407 if time_elapsed > NO_RESULT_THRESHOLD:
408 edge['status']['control_plane'] = "no result"
409 edge['status']['user_plane'] = "no result"
Shad Ansari9faaa962022-03-16 17:35:41 -0700410 edge['dongle_stats'] = {'SuccessfulFetch': False}
Jeremy Ronquilloe0a8b422021-11-02 12:49:15 -0700411 edge['speedtest']['ping']['dry_run'] = {'transmitted': 0,
412 'received': 0,
413 'median': 0.0,
414 'min': 0.0,
415 'avg': 0.0,
416 'max': 0.0,
417 'stddev': 0.0}
418 edge['speedtest']['ping']['dns'] = {'transmitted': 0,
419 'received': 0,
420 'median': 0.0,
421 'min': 0.0,
Jeremy Ronquilloa944fbc2021-03-30 10:57:45 -0700422 'avg': 0.0,
423 'max': 0.0,
424 'stddev': 0.0}
Jeremy Ronquilloe0a8b422021-11-02 12:49:15 -0700425 edge['speedtest']['ping']['iperf_server'] = {'transmitted': 0,
426 'received': 0,
427 'median': 0.0,
428 'min': 0.0,
Jeremy Ronquillo6e352b72021-06-08 10:33:25 -0700429 'avg': 0.0,
430 'max': 0.0,
431 'stddev': 0.0}
Jeremy Ronquilloe0a8b422021-11-02 12:49:15 -0700432 edge['speedtest']['ping']['management_server'] = {'transmitted': 0,
433 'received': 0,
434 'median': 0.0,
435 'min': 0.0,
436 'avg': 0.0,
437 'max': 0.0,
438 'stddev': 0.0}
Jeremy Ronquillo56b0a1e2021-04-09 00:26:18 -0700439 edge['speedtest']['iperf'] = {'cluster': {
440 'downlink': 0.0,
441 'uplink': 0.0
442 }
443 }
Hyunsun Moon200eba52021-04-05 21:31:54 -0700444 edge.pop('signal_quality', None)
Andy Bavier4021a2f2020-07-29 12:39:47 -0700445
Andy Baviere47157d2020-12-11 14:13:12 -0700446def remove_edge_from_metrics(name):
447 try:
448 cp_status.remove(name)
449 up_status.remove(name)
450 last_update.remove(name)
Andy Bavier3c7b78d2021-03-11 14:16:43 -0700451 e2e_tests_ok.remove(name)
Andy Baviera0c40aa2021-03-10 12:09:12 -0700452 connect_test_ok.remove(name)
Andy Baviera0c40aa2021-03-10 12:09:12 -0700453 ping_test_ok.remove(name)
Andy Bavier3c7b78d2021-03-11 14:16:43 -0700454 e2e_tests_down.remove(name)
Andy Bavier5b4e28f2021-03-09 15:48:20 -0700455 except:
456 pass
457
458 try:
Jeremy Ronquilloc45955a2021-11-09 12:04:57 -0800459 dongle_stats_imsi.remove(name)
Jeremy Ronquillo1eaff6a2021-11-16 13:46:46 -0800460 dongle_stats_cellglobalid.remove(name)
461 dongle_stats_plmnstatus.remove(name)
462 dongle_stats_phycellid.remove(name)
Jeremy Ronquilloc45955a2021-11-09 12:04:57 -0800463 except:
464 pass
465
466 try:
Jeremy Ronquilloe0a8b422021-11-02 12:49:15 -0700467 ping_dry_run_min.remove(name)
468 ping_dry_run_avg.remove(name)
469 ping_dry_run_max.remove(name)
470 ping_dry_run_stddev.remove(name)
471 ping_dry_run_transmitted.remove(name)
472 ping_dry_run_received.remove(name)
473 ping_dry_run_median.remove(name)
474 except:
475 pass
476
477 try:
Hyunsun Moon200eba52021-04-05 21:31:54 -0700478 ping_dns_min.remove(name)
479 ping_dns_avg.remove(name)
480 ping_dns_max.remove(name)
481 ping_dns_stddev.remove(name)
Jeremy Ronquilloe0a8b422021-11-02 12:49:15 -0700482 ping_dns_transmitted.remove(name)
483 ping_dns_received.remove(name)
484 ping_dns_median.remove(name)
Hyunsun Moon200eba52021-04-05 21:31:54 -0700485 except:
486 pass
487
488 try:
Jeremy Ronquillo6e352b72021-06-08 10:33:25 -0700489 ping_iperf_server_min.remove(name)
490 ping_iperf_server_avg.remove(name)
491 ping_iperf_server_max.remove(name)
492 ping_iperf_server_stddev.remove(name)
Jeremy Ronquilloe0a8b422021-11-02 12:49:15 -0700493 ping_iperf_server_transmitted.remove(name)
494 ping_iperf_server_received.remove(name)
495 ping_iperf_server_median.remove(name)
496 except:
497 pass
498
499 try:
500 ping_management_server_min.remove(name)
501 ping_management_server_avg.remove(name)
502 ping_management_server_max.remove(name)
503 ping_management_server_stddev.remove(name)
504 ping_management_server_transmitted.remove(name)
505 ping_management_server_received.remove(name)
506 ping_management_server_median.remove(name)
Jeremy Ronquillo6e352b72021-06-08 10:33:25 -0700507 except:
508 pass
509
510 try:
Jeremy Ronquilloc7434622021-04-08 21:06:00 -0700511 iperf_cluster_downlink.remove(name)
512 iperf_cluster_uplink.remove(name)
513 except:
514 pass
515
516 try:
Hyunsun Moon200eba52021-04-05 21:31:54 -0700517 signal_quality_rsrq.remove(name)
518 signal_quality_rsrp.remove(name)
519 except:
520 pass
521
522 try:
Shad Ansari9faaa962022-03-16 17:35:41 -0700523 counters_dongle_read_error.remove(name)
524 counters_dongle_connect_error.remove(name)
525 counters_dongle_rsrp_rsrq_error.remove(name)
526 counters_modem_cfun0_error.remove(name)
527 counters_modem_cfun1_error.remove(name)
528 counters_modem_cgatt_error.remove(name)
529 counters_modem_cesq_error.remove(name)
530 counters_dry_run_ping_error.remove(name)
531 counters_ping_error.remove(name)
532 counters_iperf_error.remove(name)
533 counters_report_send_error.remove(name)
534 except:
535 pass
536
537 try:
Andy Baviere47157d2020-12-11 14:13:12 -0700538 maint_window.remove(name)
539 except:
540 pass
Andy Bavier4021a2f2020-07-29 12:39:47 -0700541
542@app.route('/edges/metrics', methods=['GET'])
543def get_prometheus_metrics():
544 res = []
545 time_out_stale_results()
546 for edge in edges:
Andy Bavier8a5c9872020-10-21 13:17:53 -0700547 if edge['name'] == "ace-example":
Andy Bavier4021a2f2020-07-29 12:39:47 -0700548 continue
549
Andy Bavier3c7b78d2021-03-11 14:16:43 -0700550 connect_status = edge['status']['control_plane']
551 ping_status = edge['status']['user_plane']
552
Jeremy Ronquillocd711a22021-11-18 10:37:56 -0800553 # Add PLMN Status
Jeremy Ronquilloc45955a2021-11-09 12:04:57 -0800554 try:
Jeremy Ronquillocd711a22021-11-18 10:37:56 -0800555 if edge['dongle_stats']['PLMNStatus'] and edge['dongle_stats']['PLMNStatus'] in plmnstatus_mapping:
Jeremy Ronquillo1eaff6a2021-11-16 13:46:46 -0800556 dongle_stats_plmnstatus.labels(edge['name']).set(plmnstatus_mapping[edge['dongle_stats']['PLMNStatus']])
557 else:
Jeremy Ronquillocd711a22021-11-18 10:37:56 -0800558 pass
559 except:
560 pass
561
562 # Add IMSI
563 try:
564 if edge['dongle_stats']['IMSI']:
565 dongle_stats_imsi.labels(edge['name']).set(float(edge['dongle_stats']['IMSI']))
566 except:
567 pass
568
569 # Add CellGlobalID
570 try:
571 if edge['dongle_stats']['CellGlobalID']:
572 dongle_stats_cellglobalid.labels(edge['name']).set(int(edge['dongle_stats']['CellGlobalID'], 16))
573 except:
574 pass
575
576 # Add PhyCellID
577 try:
578 if edge['dongle_stats']['PhyCellID']:
579 dongle_stats_phycellid.labels(edge['name']).set(edge['dongle_stats']['PhyCellID'])
580 except:
Jeremy Ronquilloc45955a2021-11-09 12:04:57 -0800581 pass
582
Shad Ansari5e0d59a2022-03-17 21:31:02 -0700583 # Add ping dry_run latency results
584 ping_dry_run_min.labels(edge['name']).set(edge['speedtest']['ping']['dry_run']['min'])
585 ping_dry_run_avg.labels(edge['name']).set(edge['speedtest']['ping']['dry_run']['avg'])
586 ping_dry_run_max.labels(edge['name']).set(edge['speedtest']['ping']['dry_run']['max'])
587 ping_dry_run_stddev.labels(edge['name']).set(edge['speedtest']['ping']['dry_run']['stddev'])
588 ping_dry_run_transmitted.labels(edge['name']).set(edge['speedtest']['ping']['dry_run']['transmitted'])
589 ping_dry_run_received.labels(edge['name']).set(edge['speedtest']['ping']['dry_run']['received'])
590 ping_dry_run_median.labels(edge['name']).set(edge['speedtest']['ping']['dry_run']['median'])
Jeremy Ronquilloe0a8b422021-11-02 12:49:15 -0700591
Shad Ansari5e0d59a2022-03-17 21:31:02 -0700592 # Add ping dns latency results
593 ping_dns_min.labels(edge['name']).set(edge['speedtest']['ping']['dns']['min'])
594 ping_dns_avg.labels(edge['name']).set(edge['speedtest']['ping']['dns']['avg'])
595 ping_dns_max.labels(edge['name']).set(edge['speedtest']['ping']['dns']['max'])
596 ping_dns_stddev.labels(edge['name']).set(edge['speedtest']['ping']['dns']['stddev'])
597 ping_dns_transmitted.labels(edge['name']).set(edge['speedtest']['ping']['dns']['transmitted'])
598 ping_dns_received.labels(edge['name']).set(edge['speedtest']['ping']['dns']['received'])
599 ping_dns_median.labels(edge['name']).set(edge['speedtest']['ping']['dns']['median'])
Jeremy Ronquilloc7434622021-04-08 21:06:00 -0700600
Shad Ansari5e0d59a2022-03-17 21:31:02 -0700601 # Add ping iperf_server latency results
602 ping_iperf_server_min.labels(edge['name']).set(edge['speedtest']['ping']['iperf_server']['min'])
603 ping_iperf_server_avg.labels(edge['name']).set(edge['speedtest']['ping']['iperf_server']['avg'])
604 ping_iperf_server_max.labels(edge['name']).set(edge['speedtest']['ping']['iperf_server']['max'])
605 ping_iperf_server_stddev.labels(edge['name']).set(edge['speedtest']['ping']['iperf_server']['stddev'])
606 ping_iperf_server_transmitted.labels(edge['name']).set(edge['speedtest']['ping']['iperf_server']['transmitted'])
607 ping_iperf_server_received.labels(edge['name']).set(edge['speedtest']['ping']['iperf_server']['received'])
608 ping_iperf_server_median.labels(edge['name']).set(edge['speedtest']['ping']['iperf_server']['median'])
Jeremy Ronquilloe0a8b422021-11-02 12:49:15 -0700609
Shad Ansari5e0d59a2022-03-17 21:31:02 -0700610 # Add ping management_server latency results
611 ping_management_server_min.labels(edge['name']).set(edge['speedtest']['ping']['management_server']['min'])
612 ping_management_server_avg.labels(edge['name']).set(edge['speedtest']['ping']['management_server']['avg'])
613 ping_management_server_max.labels(edge['name']).set(edge['speedtest']['ping']['management_server']['max'])
614 ping_management_server_stddev.labels(edge['name']).set(edge['speedtest']['ping']['management_server']['stddev'])
615 ping_management_server_transmitted.labels(edge['name']).set(edge['speedtest']['ping']['management_server']['transmitted'])
616 ping_management_server_received.labels(edge['name']).set(edge['speedtest']['ping']['management_server']['received'])
617 ping_management_server_median.labels(edge['name']).set(edge['speedtest']['ping']['management_server']['median'])
Jeremy Ronquillo6e352b72021-06-08 10:33:25 -0700618
Shad Ansari5e0d59a2022-03-17 21:31:02 -0700619 # Add iperf bandwidth results
620 iperf_cluster_downlink.labels(edge['name']).set(edge['speedtest']['iperf']['cluster']['downlink'])
621 iperf_cluster_uplink.labels(edge['name']).set(edge['speedtest']['iperf']['cluster']['uplink'])
Jeremy Ronquillof4200252021-02-13 16:11:04 -0800622
Andy Bavier3c7b78d2021-03-11 14:16:43 -0700623 cp_status.labels(edge['name']).set(status_codes[connect_status])
624 up_status.labels(edge['name']).set(status_codes[ping_status])
Jeremy Ronquillof4200252021-02-13 16:11:04 -0800625
Andy Bavier4021a2f2020-07-29 12:39:47 -0700626 last_update.labels(edge['name']).set(edge['last_update'])
Andy Bavier614af142020-08-07 14:49:56 -0700627 if 'maintenance' in edge:
628 maint_window.labels(edge['name']).set(int(edge['maintenance']['in_window']))
Andy Bavier4021a2f2020-07-29 12:39:47 -0700629
Andy Baviera0c40aa2021-03-10 12:09:12 -0700630 connect_test_ok.labels(edge['name']).set(0)
Andy Baviera0c40aa2021-03-10 12:09:12 -0700631 ping_test_ok.labels(edge['name']).set(0)
Andy Bavier3c7b78d2021-03-11 14:16:43 -0700632 e2e_tests_ok.labels(edge['name']).set(0)
633 e2e_tests_down.labels(edge['name']).set(0)
634
635 if connect_status in ["error", "no result"] or ping_status in ["error", "no result"]:
636 e2e_tests_down.labels(edge['name']).set(1)
637 else:
638 if connect_status == "connected":
639 connect_test_ok.labels(edge['name']).set(1)
640 if ping_status == "connected":
641 ping_test_ok.labels(edge['name']).set(1)
642 if connect_status == "connected" and ping_status == "connected":
643 e2e_tests_ok.labels(edge['name']).set(1)
Andy Bavier5b4e28f2021-03-09 15:48:20 -0700644
Hyunsun Moon200eba52021-04-05 21:31:54 -0700645 if 'signal_quality' in edge.keys():
646 signal_quality_rsrq.labels(edge['name']).set(edge['signal_quality']['rsrq'])
647 signal_quality_rsrp.labels(edge['name']).set(edge['signal_quality']['rsrp'])
Jeremy Ronquillof4200252021-02-13 16:11:04 -0800648
Shad Ansari9faaa962022-03-16 17:35:41 -0700649 if 'counters' in edge.keys():
650 counters_dongle_read_error.labels(edge['name']).set(edge['counters']['dongle_read_error'])
651 counters_dongle_connect_error.labels(edge['name']).set(edge['counters']['dongle_connect_error'])
652 counters_dongle_rsrp_rsrq_error.labels(edge['name']).set(edge['counters']['dongle_rsrp_rsrq_error'])
653 counters_modem_cfun0_error.labels(edge['name']).set(edge['counters']['modem_cfun0_error'])
654 counters_modem_cfun1_error.labels(edge['name']).set(edge['counters']['modem_cfun1_error'])
655 counters_modem_cgatt_error.labels(edge['name']).set(edge['counters']['modem_cgatt_error'])
656 counters_modem_cesq_error.labels(edge['name']).set(edge['counters']['modem_cesq_error'])
657 counters_dry_run_ping_error.labels(edge['name']).set(edge['counters']['dry_run_ping_error'])
658 counters_ping_error.labels(edge['name']).set(edge['counters']['ping_error'])
659 counters_iperf_error.labels(edge['name']).set(edge['counters']['iperf_error'])
660 counters_report_send_error.labels(edge['name']).set(edge['counters']['report_send_error'])
661
Andy Bavier4021a2f2020-07-29 12:39:47 -0700662 res.append(prom.generate_latest(cp_status))
663 res.append(prom.generate_latest(up_status))
Jeremy Ronquilloe0a8b422021-11-02 12:49:15 -0700664
Jeremy Ronquilloc45955a2021-11-09 12:04:57 -0800665 res.append(prom.generate_latest(dongle_stats_imsi))
666 res.append(prom.generate_latest(dongle_stats_cellglobalid))
667 res.append(prom.generate_latest(dongle_stats_plmnstatus))
Jeremy Ronquillo1eaff6a2021-11-16 13:46:46 -0800668 res.append(prom.generate_latest(dongle_stats_phycellid))
Jeremy Ronquilloc45955a2021-11-09 12:04:57 -0800669
Jeremy Ronquilloe0a8b422021-11-02 12:49:15 -0700670 res.append(prom.generate_latest(ping_dry_run_min))
671 res.append(prom.generate_latest(ping_dry_run_avg))
672 res.append(prom.generate_latest(ping_dry_run_max))
673 res.append(prom.generate_latest(ping_dry_run_stddev))
674 res.append(prom.generate_latest(ping_dry_run_transmitted))
675 res.append(prom.generate_latest(ping_dry_run_received))
676 res.append(prom.generate_latest(ping_dry_run_median))
677
Jeremy Ronquillof4200252021-02-13 16:11:04 -0800678 res.append(prom.generate_latest(ping_dns_min))
679 res.append(prom.generate_latest(ping_dns_avg))
680 res.append(prom.generate_latest(ping_dns_max))
681 res.append(prom.generate_latest(ping_dns_stddev))
Jeremy Ronquilloe0a8b422021-11-02 12:49:15 -0700682 res.append(prom.generate_latest(ping_dns_transmitted))
683 res.append(prom.generate_latest(ping_dns_received))
684 res.append(prom.generate_latest(ping_dns_median))
685
Jeremy Ronquillo6e352b72021-06-08 10:33:25 -0700686 res.append(prom.generate_latest(ping_iperf_server_min))
687 res.append(prom.generate_latest(ping_iperf_server_avg))
688 res.append(prom.generate_latest(ping_iperf_server_max))
689 res.append(prom.generate_latest(ping_iperf_server_stddev))
Jeremy Ronquilloe0a8b422021-11-02 12:49:15 -0700690 res.append(prom.generate_latest(ping_iperf_server_transmitted))
691 res.append(prom.generate_latest(ping_iperf_server_received))
692 res.append(prom.generate_latest(ping_iperf_server_median))
693
694 res.append(prom.generate_latest(ping_management_server_min))
695 res.append(prom.generate_latest(ping_management_server_avg))
696 res.append(prom.generate_latest(ping_management_server_max))
697 res.append(prom.generate_latest(ping_management_server_stddev))
698 res.append(prom.generate_latest(ping_management_server_transmitted))
699 res.append(prom.generate_latest(ping_management_server_received))
700 res.append(prom.generate_latest(ping_management_server_median))
701
Jeremy Ronquilloc7434622021-04-08 21:06:00 -0700702 res.append(prom.generate_latest(iperf_cluster_downlink))
703 res.append(prom.generate_latest(iperf_cluster_uplink))
Andy Bavier4021a2f2020-07-29 12:39:47 -0700704 res.append(prom.generate_latest(last_update))
Andy Bavier614af142020-08-07 14:49:56 -0700705 res.append(prom.generate_latest(maint_window))
Andy Baviera0c40aa2021-03-10 12:09:12 -0700706 res.append(prom.generate_latest(connect_test_ok))
Andy Baviera0c40aa2021-03-10 12:09:12 -0700707 res.append(prom.generate_latest(ping_test_ok))
Andy Bavier3c7b78d2021-03-11 14:16:43 -0700708 res.append(prom.generate_latest(e2e_tests_ok))
709 res.append(prom.generate_latest(e2e_tests_down))
Hyunsun Moon200eba52021-04-05 21:31:54 -0700710 res.append(prom.generate_latest(signal_quality_rsrq))
711 res.append(prom.generate_latest(signal_quality_rsrp))
Shad Ansari9faaa962022-03-16 17:35:41 -0700712 res.append(prom.generate_latest(counters_dongle_read_error))
713 res.append(prom.generate_latest(counters_dongle_connect_error))
714 res.append(prom.generate_latest(counters_dongle_rsrp_rsrq_error))
715 res.append(prom.generate_latest(counters_modem_cfun0_error))
716 res.append(prom.generate_latest(counters_modem_cfun1_error))
717 res.append(prom.generate_latest(counters_modem_cgatt_error))
718 res.append(prom.generate_latest(counters_modem_cesq_error))
719 res.append(prom.generate_latest(counters_dry_run_ping_error))
720 res.append(prom.generate_latest(counters_ping_error))
721 res.append(prom.generate_latest(counters_iperf_error))
722 res.append(prom.generate_latest(counters_report_send_error))
Andy Bavier614af142020-08-07 14:49:56 -0700723
Andy Bavier4021a2f2020-07-29 12:39:47 -0700724 return Response(res, mimetype="text/plain")
725
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -0700726
727@app.route('/edges/healthz', methods=['GET'])
728def get_health():
729 return {'message': 'healthy'}
730
731
732@app.route('/edges', methods=['GET'])
733def get_edges():
Andy Bavier4021a2f2020-07-29 12:39:47 -0700734 time_out_stale_results()
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -0700735 return jsonify({'edges': edges})
736
737
738@app.route('/edges/<string:name>', methods=['GET'])
739def get_edge(name):
Andy Bavier4021a2f2020-07-29 12:39:47 -0700740 time_out_stale_results()
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -0700741 edge = [edge for edge in edges if edge['name'] == name]
742 if len(edge) == 0:
743 abort(404)
744 return jsonify({'edge': edge[0]})
745
746
747@app.route('/edges', methods=['POST'])
Andy Bavierf872e9a2021-03-22 12:06:25 -0700748@app.route('/testresults', methods=['POST'])
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -0700749def create_or_update_edge():
Andy Bavier2d60fc52021-05-04 16:13:39 -0700750 try:
751 jsonschema.validate(instance=request.json, schema=edgeSchema)
752 except jsonschema.exceptions.ValidationError as err:
Andy Bavier55dc5872021-05-05 11:31:42 -0700753 app.logger.warn(err)
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -0700754 abort(400)
755
756 req_edge = {
757 'name': request.json['name'],
758 'status': {
759 'control_plane': request.json['status']['control_plane'],
760 'user_plane': request.json['status']['user_plane']
761 },
Jeremy Ronquilloc45955a2021-11-09 12:04:57 -0800762 'dongle_stats': {
Shad Ansari9faaa962022-03-16 17:35:41 -0700763 'SuccessfulFetch': False
Jeremy Ronquilloc45955a2021-11-09 12:04:57 -0800764 },
Jeremy Ronquillof4200252021-02-13 16:11:04 -0800765 'speedtest': {
766 'ping': {
Jeremy Ronquilloe0a8b422021-11-02 12:49:15 -0700767 'dry_run': {
Shad Ansari9faaa962022-03-16 17:35:41 -0700768 'transmitted': 0,
769 'received': 0,
770 'median': 0.0,
Jeremy Ronquilloe0a8b422021-11-02 12:49:15 -0700771 'min': 0.0,
772 'avg': 0.0,
773 'max': 0.0,
774 'stddev': 0.0
775 },
Jeremy Ronquillof4200252021-02-13 16:11:04 -0800776 'dns': {
Jeremy Ronquilloe0a8b422021-11-02 12:49:15 -0700777 'transmitted' : 0,
778 'received' : 0,
779 'median' : 0.0,
Jeremy Ronquilloa944fbc2021-03-30 10:57:45 -0700780 'min': 0.0,
781 'avg': 0.0,
782 'max': 0.0,
783 'stddev': 0.0
Jeremy Ronquillo6e352b72021-06-08 10:33:25 -0700784 },
785 'iperf_server': {
Jeremy Ronquilloe0a8b422021-11-02 12:49:15 -0700786 'transmitted' : 0,
787 'received' : 0,
788 'median' : 0.0,
789 'min': 0.0,
790 'avg': 0.0,
791 'max': 0.0,
792 'stddev': 0.0
793 },
794 'management_server': {
795 'transmitted' : 0,
796 'received' : 0,
797 'median' : 0.0,
Jeremy Ronquillo6e352b72021-06-08 10:33:25 -0700798 'min': 0.0,
799 'avg': 0.0,
800 'max': 0.0,
801 'stddev': 0.0
Jeremy Ronquillof4200252021-02-13 16:11:04 -0800802 }
Jeremy Ronquilloc7434622021-04-08 21:06:00 -0700803 },
804 'iperf': {
805 'cluster': {
806 'downlink': 0.0,
807 'uplink': 0.0
808 }
Jeremy Ronquillof4200252021-02-13 16:11:04 -0800809 }
810 },
Shad Ansari9faaa962022-03-16 17:35:41 -0700811 'counters': {
812 'dongle_read_error': 0,
813 'dongle_connect_error': 0,
814 'dongle_rsrp_rsrq_error': 0,
815 'modem_cfun0_error': 0,
816 'modem_cfun1_error': 0,
817 'modem_cgatt_error': 0,
818 'modem_cesq_error': 0,
819 'dry_run_ping_error': 0,
820 'ping_error': 0,
821 'iperf_error': 0,
822 'report_send_error': 0
823 },
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -0700824 'last_update': time.time()
825 }
826
Jeremy Ronquillof4200252021-02-13 16:11:04 -0800827 if 'speedtest' in request.json:
Jeremy Ronquilloc7434622021-04-08 21:06:00 -0700828 if 'ping' in request.json['speedtest']:
829 req_edge['speedtest']['ping'] = request.json['speedtest']['ping']
830 if 'iperf' in request.json['speedtest']:
831 req_edge['speedtest']['iperf'] = request.json['speedtest']['iperf']
Jeremy Ronquillof4200252021-02-13 16:11:04 -0800832
Hyunsun Moon200eba52021-04-05 21:31:54 -0700833 if 'signal_quality' in request.json:
834 req_edge['signal_quality'] = request.json['signal_quality']
Jeremy Ronquillof4200252021-02-13 16:11:04 -0800835
Jeremy Ronquilloc45955a2021-11-09 12:04:57 -0800836 if 'dongle_stats' in request.json:
837 req_edge['dongle_stats'] = request.json['dongle_stats']
838
Shad Ansari9faaa962022-03-16 17:35:41 -0700839 if 'counters' in request.json:
840 req_edge['counters'] = request.json['counters']
841
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -0700842 edge = [edge for edge in edges if edge['name'] == req_edge['name']]
843 if len(edge) == 0:
Andy Bavier55dc5872021-05-05 11:31:42 -0700844 app.logger.info("new edge request " + req_edge['name'])
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -0700845 edges.append(req_edge)
846 else:
847 edge[0]['status']['control_plane'] = req_edge['status']['control_plane']
848 edge[0]['status']['user_plane'] = req_edge['status']['user_plane']
Jeremy Ronquillof4200252021-02-13 16:11:04 -0800849 edge[0]['speedtest']['ping'] = req_edge['speedtest']['ping']
Jeremy Ronquillo56b0a1e2021-04-09 00:26:18 -0700850 edge[0]['speedtest']['iperf'] = req_edge['speedtest']['iperf']
Jeremy Ronquilloc45955a2021-11-09 12:04:57 -0800851 edge[0]['dongle_stats'] = req_edge['dongle_stats']
Hyunsun Moon200eba52021-04-05 21:31:54 -0700852 if 'signal_quality' in req_edge.keys():
853 edge[0]['signal_quality'] = req_edge['signal_quality']
Shad Ansari9faaa962022-03-16 17:35:41 -0700854 if 'counters' in req_edge.keys():
855 edge[0]['counters'] = req_edge['counters']
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -0700856 edge[0]['last_update'] = req_edge['last_update']
857
858 return jsonify({'edge': req_edge}), 201
859
860
Hyunsun Moon5f237ec2020-09-29 14:45:52 -0700861@app.route('/edges/<string:name>', methods=['DELETE'])
Andy Bavierf872e9a2021-03-22 12:06:25 -0700862@app.route('/testresults/<string:name>', methods=['DELETE'])
Hyunsun Moon5f237ec2020-09-29 14:45:52 -0700863def delete_edge(name):
Andy Bavier55dc5872021-05-05 11:31:42 -0700864 app.logger.info("delete edge request " + name)
Hyunsun Moon5f237ec2020-09-29 14:45:52 -0700865 result = False
866 for i in range(len(edges)):
867 if edges[i]['name'] == name:
868 del edges[i]
Andy Baviere47157d2020-12-11 14:13:12 -0700869 remove_edge_from_metrics(name)
Hyunsun Moon5f237ec2020-09-29 14:45:52 -0700870 result = True
871 break
872 if not result:
873 abort(404)
874 return jsonify({'result': True})
875
876
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -0700877if __name__ == '__main__':
Andy Bavier8a5c9872020-10-21 13:17:53 -0700878 if SECRET_ICAL_URL and AETHER_ENV:
Andy Bavier55dc5872021-05-05 11:31:42 -0700879 app.logger.info(" * Starting maintenance calendar polling thread (Aether env: %s)" % AETHER_ENV)
Andy Bavier614af142020-08-07 14:49:56 -0700880 t = threading.Thread(target=pull_maintenance_events)
881 t.start()
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -0700882 app.run(debug=True, host='0.0.0.0', port=80)