blob: 4bde766ccf70c08e89dbf01c41decd456df37b13 [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
Jeremy Ronquilloe0a8b422021-11-02 12:49:15 -0700583 # Add ping dry_run latency results if available
584 try:
585 if edge['speedtest']['ping']['dry_run']['avg']:
586 ping_dry_run_min.labels(edge['name']).set(edge['speedtest']['ping']['dry_run']['min'])
587 ping_dry_run_avg.labels(edge['name']).set(edge['speedtest']['ping']['dry_run']['avg'])
588 ping_dry_run_max.labels(edge['name']).set(edge['speedtest']['ping']['dry_run']['max'])
589 ping_dry_run_stddev.labels(edge['name']).set(edge['speedtest']['ping']['dry_run']['stddev'])
590 ping_dry_run_transmitted.labels(edge['name']).set(edge['speedtest']['ping']['dry_run']['transmitted'])
591 ping_dry_run_received.labels(edge['name']).set(edge['speedtest']['ping']['dry_run']['received'])
592 ping_dry_run_median.labels(edge['name']).set(edge['speedtest']['ping']['dry_run']['median'])
593 except KeyError:
594 pass
595
Jeremy Ronquillo6e352b72021-06-08 10:33:25 -0700596 # Add ping dns latency results if available
Jeremy Ronquillo5e559a82021-06-09 11:48:35 -0700597 try:
598 if edge['speedtest']['ping']['dns']['avg']:
599 ping_dns_min.labels(edge['name']).set(edge['speedtest']['ping']['dns']['min'])
600 ping_dns_avg.labels(edge['name']).set(edge['speedtest']['ping']['dns']['avg'])
601 ping_dns_max.labels(edge['name']).set(edge['speedtest']['ping']['dns']['max'])
602 ping_dns_stddev.labels(edge['name']).set(edge['speedtest']['ping']['dns']['stddev'])
Jeremy Ronquilloe0a8b422021-11-02 12:49:15 -0700603 ping_dns_transmitted.labels(edge['name']).set(edge['speedtest']['ping']['dns']['transmitted'])
604 ping_dns_received.labels(edge['name']).set(edge['speedtest']['ping']['dns']['received'])
605 ping_dns_median.labels(edge['name']).set(edge['speedtest']['ping']['dns']['median'])
Jeremy Ronquillo5e559a82021-06-09 11:48:35 -0700606 except KeyError:
607 pass
Jeremy Ronquilloc7434622021-04-08 21:06:00 -0700608
Jeremy Ronquillo6e352b72021-06-08 10:33:25 -0700609 # Add ping iperf_server latency results if available
Jeremy Ronquillo5e559a82021-06-09 11:48:35 -0700610 try:
611 if edge['speedtest']['ping']['iperf_server']['avg']:
612 ping_iperf_server_min.labels(edge['name']).set(edge['speedtest']['ping']['iperf_server']['min'])
613 ping_iperf_server_avg.labels(edge['name']).set(edge['speedtest']['ping']['iperf_server']['avg'])
614 ping_iperf_server_max.labels(edge['name']).set(edge['speedtest']['ping']['iperf_server']['max'])
615 ping_iperf_server_stddev.labels(edge['name']).set(edge['speedtest']['ping']['iperf_server']['stddev'])
Jeremy Ronquilloe0a8b422021-11-02 12:49:15 -0700616 ping_iperf_server_transmitted.labels(edge['name']).set(edge['speedtest']['ping']['iperf_server']['transmitted'])
617 ping_iperf_server_received.labels(edge['name']).set(edge['speedtest']['ping']['iperf_server']['received'])
618 ping_iperf_server_median.labels(edge['name']).set(edge['speedtest']['ping']['iperf_server']['median'])
619 except KeyError:
620 pass
621
622 # Add ping management_server latency results if available
623 try:
624 if edge['speedtest']['ping']['management_server']['avg']:
625 ping_management_server_min.labels(edge['name']).set(edge['speedtest']['ping']['management_server']['min'])
626 ping_management_server_avg.labels(edge['name']).set(edge['speedtest']['ping']['management_server']['avg'])
627 ping_management_server_max.labels(edge['name']).set(edge['speedtest']['ping']['management_server']['max'])
628 ping_management_server_stddev.labels(edge['name']).set(edge['speedtest']['ping']['management_server']['stddev'])
629 ping_management_server_transmitted.labels(edge['name']).set(edge['speedtest']['ping']['management_server']['transmitted'])
630 ping_management_server_received.labels(edge['name']).set(edge['speedtest']['ping']['management_server']['received'])
631 ping_management_server_median.labels(edge['name']).set(edge['speedtest']['ping']['management_server']['median'])
Jeremy Ronquillo5e559a82021-06-09 11:48:35 -0700632 except KeyError:
633 pass
Jeremy Ronquillo6e352b72021-06-08 10:33:25 -0700634
635 # Add iperf bandwidth results if available
Jeremy Ronquillo5e559a82021-06-09 11:48:35 -0700636 try:
637 if edge['speedtest']['iperf']['cluster']['downlink']:
638 iperf_cluster_downlink.labels(edge['name']).set(edge['speedtest']['iperf']['cluster']['downlink'])
639 iperf_cluster_uplink.labels(edge['name']).set(edge['speedtest']['iperf']['cluster']['uplink'])
640 except KeyError:
641 pass
Jeremy Ronquillof4200252021-02-13 16:11:04 -0800642
Andy Bavier3c7b78d2021-03-11 14:16:43 -0700643 cp_status.labels(edge['name']).set(status_codes[connect_status])
644 up_status.labels(edge['name']).set(status_codes[ping_status])
Jeremy Ronquillof4200252021-02-13 16:11:04 -0800645
Andy Bavier4021a2f2020-07-29 12:39:47 -0700646 last_update.labels(edge['name']).set(edge['last_update'])
Andy Bavier614af142020-08-07 14:49:56 -0700647 if 'maintenance' in edge:
648 maint_window.labels(edge['name']).set(int(edge['maintenance']['in_window']))
Andy Bavier4021a2f2020-07-29 12:39:47 -0700649
Andy Baviera0c40aa2021-03-10 12:09:12 -0700650 connect_test_ok.labels(edge['name']).set(0)
Andy Baviera0c40aa2021-03-10 12:09:12 -0700651 ping_test_ok.labels(edge['name']).set(0)
Andy Bavier3c7b78d2021-03-11 14:16:43 -0700652 e2e_tests_ok.labels(edge['name']).set(0)
653 e2e_tests_down.labels(edge['name']).set(0)
654
655 if connect_status in ["error", "no result"] or ping_status in ["error", "no result"]:
656 e2e_tests_down.labels(edge['name']).set(1)
657 else:
658 if connect_status == "connected":
659 connect_test_ok.labels(edge['name']).set(1)
660 if ping_status == "connected":
661 ping_test_ok.labels(edge['name']).set(1)
662 if connect_status == "connected" and ping_status == "connected":
663 e2e_tests_ok.labels(edge['name']).set(1)
Andy Bavier5b4e28f2021-03-09 15:48:20 -0700664
Hyunsun Moon200eba52021-04-05 21:31:54 -0700665 if 'signal_quality' in edge.keys():
666 signal_quality_rsrq.labels(edge['name']).set(edge['signal_quality']['rsrq'])
667 signal_quality_rsrp.labels(edge['name']).set(edge['signal_quality']['rsrp'])
Jeremy Ronquillof4200252021-02-13 16:11:04 -0800668
Shad Ansari9faaa962022-03-16 17:35:41 -0700669 if 'counters' in edge.keys():
670 counters_dongle_read_error.labels(edge['name']).set(edge['counters']['dongle_read_error'])
671 counters_dongle_connect_error.labels(edge['name']).set(edge['counters']['dongle_connect_error'])
672 counters_dongle_rsrp_rsrq_error.labels(edge['name']).set(edge['counters']['dongle_rsrp_rsrq_error'])
673 counters_modem_cfun0_error.labels(edge['name']).set(edge['counters']['modem_cfun0_error'])
674 counters_modem_cfun1_error.labels(edge['name']).set(edge['counters']['modem_cfun1_error'])
675 counters_modem_cgatt_error.labels(edge['name']).set(edge['counters']['modem_cgatt_error'])
676 counters_modem_cesq_error.labels(edge['name']).set(edge['counters']['modem_cesq_error'])
677 counters_dry_run_ping_error.labels(edge['name']).set(edge['counters']['dry_run_ping_error'])
678 counters_ping_error.labels(edge['name']).set(edge['counters']['ping_error'])
679 counters_iperf_error.labels(edge['name']).set(edge['counters']['iperf_error'])
680 counters_report_send_error.labels(edge['name']).set(edge['counters']['report_send_error'])
681
Andy Bavier4021a2f2020-07-29 12:39:47 -0700682 res.append(prom.generate_latest(cp_status))
683 res.append(prom.generate_latest(up_status))
Jeremy Ronquilloe0a8b422021-11-02 12:49:15 -0700684
Jeremy Ronquilloc45955a2021-11-09 12:04:57 -0800685 res.append(prom.generate_latest(dongle_stats_imsi))
686 res.append(prom.generate_latest(dongle_stats_cellglobalid))
687 res.append(prom.generate_latest(dongle_stats_plmnstatus))
Jeremy Ronquillo1eaff6a2021-11-16 13:46:46 -0800688 res.append(prom.generate_latest(dongle_stats_phycellid))
Jeremy Ronquilloc45955a2021-11-09 12:04:57 -0800689
Jeremy Ronquilloe0a8b422021-11-02 12:49:15 -0700690 res.append(prom.generate_latest(ping_dry_run_min))
691 res.append(prom.generate_latest(ping_dry_run_avg))
692 res.append(prom.generate_latest(ping_dry_run_max))
693 res.append(prom.generate_latest(ping_dry_run_stddev))
694 res.append(prom.generate_latest(ping_dry_run_transmitted))
695 res.append(prom.generate_latest(ping_dry_run_received))
696 res.append(prom.generate_latest(ping_dry_run_median))
697
Jeremy Ronquillof4200252021-02-13 16:11:04 -0800698 res.append(prom.generate_latest(ping_dns_min))
699 res.append(prom.generate_latest(ping_dns_avg))
700 res.append(prom.generate_latest(ping_dns_max))
701 res.append(prom.generate_latest(ping_dns_stddev))
Jeremy Ronquilloe0a8b422021-11-02 12:49:15 -0700702 res.append(prom.generate_latest(ping_dns_transmitted))
703 res.append(prom.generate_latest(ping_dns_received))
704 res.append(prom.generate_latest(ping_dns_median))
705
Jeremy Ronquillo6e352b72021-06-08 10:33:25 -0700706 res.append(prom.generate_latest(ping_iperf_server_min))
707 res.append(prom.generate_latest(ping_iperf_server_avg))
708 res.append(prom.generate_latest(ping_iperf_server_max))
709 res.append(prom.generate_latest(ping_iperf_server_stddev))
Jeremy Ronquilloe0a8b422021-11-02 12:49:15 -0700710 res.append(prom.generate_latest(ping_iperf_server_transmitted))
711 res.append(prom.generate_latest(ping_iperf_server_received))
712 res.append(prom.generate_latest(ping_iperf_server_median))
713
714 res.append(prom.generate_latest(ping_management_server_min))
715 res.append(prom.generate_latest(ping_management_server_avg))
716 res.append(prom.generate_latest(ping_management_server_max))
717 res.append(prom.generate_latest(ping_management_server_stddev))
718 res.append(prom.generate_latest(ping_management_server_transmitted))
719 res.append(prom.generate_latest(ping_management_server_received))
720 res.append(prom.generate_latest(ping_management_server_median))
721
Jeremy Ronquilloc7434622021-04-08 21:06:00 -0700722 res.append(prom.generate_latest(iperf_cluster_downlink))
723 res.append(prom.generate_latest(iperf_cluster_uplink))
Andy Bavier4021a2f2020-07-29 12:39:47 -0700724 res.append(prom.generate_latest(last_update))
Andy Bavier614af142020-08-07 14:49:56 -0700725 res.append(prom.generate_latest(maint_window))
Andy Baviera0c40aa2021-03-10 12:09:12 -0700726 res.append(prom.generate_latest(connect_test_ok))
Andy Baviera0c40aa2021-03-10 12:09:12 -0700727 res.append(prom.generate_latest(ping_test_ok))
Andy Bavier3c7b78d2021-03-11 14:16:43 -0700728 res.append(prom.generate_latest(e2e_tests_ok))
729 res.append(prom.generate_latest(e2e_tests_down))
Hyunsun Moon200eba52021-04-05 21:31:54 -0700730 res.append(prom.generate_latest(signal_quality_rsrq))
731 res.append(prom.generate_latest(signal_quality_rsrp))
Shad Ansari9faaa962022-03-16 17:35:41 -0700732 res.append(prom.generate_latest(counters_dongle_read_error))
733 res.append(prom.generate_latest(counters_dongle_connect_error))
734 res.append(prom.generate_latest(counters_dongle_rsrp_rsrq_error))
735 res.append(prom.generate_latest(counters_modem_cfun0_error))
736 res.append(prom.generate_latest(counters_modem_cfun1_error))
737 res.append(prom.generate_latest(counters_modem_cgatt_error))
738 res.append(prom.generate_latest(counters_modem_cesq_error))
739 res.append(prom.generate_latest(counters_dry_run_ping_error))
740 res.append(prom.generate_latest(counters_ping_error))
741 res.append(prom.generate_latest(counters_iperf_error))
742 res.append(prom.generate_latest(counters_report_send_error))
Andy Bavier614af142020-08-07 14:49:56 -0700743
Andy Bavier4021a2f2020-07-29 12:39:47 -0700744 return Response(res, mimetype="text/plain")
745
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -0700746
747@app.route('/edges/healthz', methods=['GET'])
748def get_health():
749 return {'message': 'healthy'}
750
751
752@app.route('/edges', methods=['GET'])
753def get_edges():
Andy Bavier4021a2f2020-07-29 12:39:47 -0700754 time_out_stale_results()
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -0700755 return jsonify({'edges': edges})
756
757
758@app.route('/edges/<string:name>', methods=['GET'])
759def get_edge(name):
Andy Bavier4021a2f2020-07-29 12:39:47 -0700760 time_out_stale_results()
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -0700761 edge = [edge for edge in edges if edge['name'] == name]
762 if len(edge) == 0:
763 abort(404)
764 return jsonify({'edge': edge[0]})
765
766
767@app.route('/edges', methods=['POST'])
Andy Bavierf872e9a2021-03-22 12:06:25 -0700768@app.route('/testresults', methods=['POST'])
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -0700769def create_or_update_edge():
Andy Bavier2d60fc52021-05-04 16:13:39 -0700770 try:
771 jsonschema.validate(instance=request.json, schema=edgeSchema)
772 except jsonschema.exceptions.ValidationError as err:
Andy Bavier55dc5872021-05-05 11:31:42 -0700773 app.logger.warn(err)
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -0700774 abort(400)
775
776 req_edge = {
777 'name': request.json['name'],
778 'status': {
779 'control_plane': request.json['status']['control_plane'],
780 'user_plane': request.json['status']['user_plane']
781 },
Jeremy Ronquilloc45955a2021-11-09 12:04:57 -0800782 'dongle_stats': {
Shad Ansari9faaa962022-03-16 17:35:41 -0700783 'SuccessfulFetch': False
Jeremy Ronquilloc45955a2021-11-09 12:04:57 -0800784 },
Jeremy Ronquillof4200252021-02-13 16:11:04 -0800785 'speedtest': {
786 'ping': {
Jeremy Ronquilloe0a8b422021-11-02 12:49:15 -0700787 'dry_run': {
Shad Ansari9faaa962022-03-16 17:35:41 -0700788 'transmitted': 0,
789 'received': 0,
790 'median': 0.0,
Jeremy Ronquilloe0a8b422021-11-02 12:49:15 -0700791 'min': 0.0,
792 'avg': 0.0,
793 'max': 0.0,
794 'stddev': 0.0
795 },
Jeremy Ronquillof4200252021-02-13 16:11:04 -0800796 'dns': {
Jeremy Ronquilloe0a8b422021-11-02 12:49:15 -0700797 'transmitted' : 0,
798 'received' : 0,
799 'median' : 0.0,
Jeremy Ronquilloa944fbc2021-03-30 10:57:45 -0700800 'min': 0.0,
801 'avg': 0.0,
802 'max': 0.0,
803 'stddev': 0.0
Jeremy Ronquillo6e352b72021-06-08 10:33:25 -0700804 },
805 'iperf_server': {
Jeremy Ronquilloe0a8b422021-11-02 12:49:15 -0700806 'transmitted' : 0,
807 'received' : 0,
808 'median' : 0.0,
809 'min': 0.0,
810 'avg': 0.0,
811 'max': 0.0,
812 'stddev': 0.0
813 },
814 'management_server': {
815 'transmitted' : 0,
816 'received' : 0,
817 'median' : 0.0,
Jeremy Ronquillo6e352b72021-06-08 10:33:25 -0700818 'min': 0.0,
819 'avg': 0.0,
820 'max': 0.0,
821 'stddev': 0.0
Jeremy Ronquillof4200252021-02-13 16:11:04 -0800822 }
Jeremy Ronquilloc7434622021-04-08 21:06:00 -0700823 },
824 'iperf': {
825 'cluster': {
826 'downlink': 0.0,
827 'uplink': 0.0
828 }
Jeremy Ronquillof4200252021-02-13 16:11:04 -0800829 }
830 },
Shad Ansari9faaa962022-03-16 17:35:41 -0700831 'counters': {
832 'dongle_read_error': 0,
833 'dongle_connect_error': 0,
834 'dongle_rsrp_rsrq_error': 0,
835 'modem_cfun0_error': 0,
836 'modem_cfun1_error': 0,
837 'modem_cgatt_error': 0,
838 'modem_cesq_error': 0,
839 'dry_run_ping_error': 0,
840 'ping_error': 0,
841 'iperf_error': 0,
842 'report_send_error': 0
843 },
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -0700844 'last_update': time.time()
845 }
846
Jeremy Ronquillof4200252021-02-13 16:11:04 -0800847 if 'speedtest' in request.json:
Jeremy Ronquilloc7434622021-04-08 21:06:00 -0700848 if 'ping' in request.json['speedtest']:
849 req_edge['speedtest']['ping'] = request.json['speedtest']['ping']
850 if 'iperf' in request.json['speedtest']:
851 req_edge['speedtest']['iperf'] = request.json['speedtest']['iperf']
Jeremy Ronquillof4200252021-02-13 16:11:04 -0800852
Hyunsun Moon200eba52021-04-05 21:31:54 -0700853 if 'signal_quality' in request.json:
854 req_edge['signal_quality'] = request.json['signal_quality']
Jeremy Ronquillof4200252021-02-13 16:11:04 -0800855
Jeremy Ronquilloc45955a2021-11-09 12:04:57 -0800856 if 'dongle_stats' in request.json:
857 req_edge['dongle_stats'] = request.json['dongle_stats']
858
Shad Ansari9faaa962022-03-16 17:35:41 -0700859 if 'counters' in request.json:
860 req_edge['counters'] = request.json['counters']
861
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -0700862 edge = [edge for edge in edges if edge['name'] == req_edge['name']]
863 if len(edge) == 0:
Andy Bavier55dc5872021-05-05 11:31:42 -0700864 app.logger.info("new edge request " + req_edge['name'])
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -0700865 edges.append(req_edge)
866 else:
867 edge[0]['status']['control_plane'] = req_edge['status']['control_plane']
868 edge[0]['status']['user_plane'] = req_edge['status']['user_plane']
Jeremy Ronquillof4200252021-02-13 16:11:04 -0800869 edge[0]['speedtest']['ping'] = req_edge['speedtest']['ping']
Jeremy Ronquillo56b0a1e2021-04-09 00:26:18 -0700870 edge[0]['speedtest']['iperf'] = req_edge['speedtest']['iperf']
Jeremy Ronquilloc45955a2021-11-09 12:04:57 -0800871 edge[0]['dongle_stats'] = req_edge['dongle_stats']
Hyunsun Moon200eba52021-04-05 21:31:54 -0700872 if 'signal_quality' in req_edge.keys():
873 edge[0]['signal_quality'] = req_edge['signal_quality']
Shad Ansari9faaa962022-03-16 17:35:41 -0700874 if 'counters' in req_edge.keys():
875 edge[0]['counters'] = req_edge['counters']
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -0700876 edge[0]['last_update'] = req_edge['last_update']
877
878 return jsonify({'edge': req_edge}), 201
879
880
Hyunsun Moon5f237ec2020-09-29 14:45:52 -0700881@app.route('/edges/<string:name>', methods=['DELETE'])
Andy Bavierf872e9a2021-03-22 12:06:25 -0700882@app.route('/testresults/<string:name>', methods=['DELETE'])
Hyunsun Moon5f237ec2020-09-29 14:45:52 -0700883def delete_edge(name):
Andy Bavier55dc5872021-05-05 11:31:42 -0700884 app.logger.info("delete edge request " + name)
Hyunsun Moon5f237ec2020-09-29 14:45:52 -0700885 result = False
886 for i in range(len(edges)):
887 if edges[i]['name'] == name:
888 del edges[i]
Andy Baviere47157d2020-12-11 14:13:12 -0700889 remove_edge_from_metrics(name)
Hyunsun Moon5f237ec2020-09-29 14:45:52 -0700890 result = True
891 break
892 if not result:
893 abort(404)
894 return jsonify({'result': True})
895
896
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -0700897if __name__ == '__main__':
Andy Bavier8a5c9872020-10-21 13:17:53 -0700898 if SECRET_ICAL_URL and AETHER_ENV:
Andy Bavier55dc5872021-05-05 11:31:42 -0700899 app.logger.info(" * Starting maintenance calendar polling thread (Aether env: %s)" % AETHER_ENV)
Andy Bavier614af142020-08-07 14:49:56 -0700900 t = threading.Thread(target=pull_maintenance_events)
901 t.start()
Hyunsun Moonf32ae9a2020-05-28 13:17:45 -0700902 app.run(debug=True, host='0.0.0.0', port=80)