Skip to content

Commit 98c8dd6

Browse files
committed
Handle JSON API errors and edge cases with error code 0 and 1
Signed-off-by: Tarun <tarunkumar.madabathula@candelatech.com>
1 parent a634192 commit 98c8dd6

2 files changed

Lines changed: 469 additions & 184 deletions

File tree

py-json/realm.py

Lines changed: 87 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -388,50 +388,45 @@ def port_exists(self, port_eid, debug=None):
388388
return False
389389

390390
def admin_up(self, port_eid):
391-
# logger.info("186 admin_up port_eid: "+port_eid)
392391
eid = self.name_to_eid(port_eid)
393392
resource = eid[1]
394393
port = eid[2]
395394
request = LFUtils.port_up_request(resource_id=resource, port_name=port, debug_on=self.debug)
396-
# logger.info("192.admin_up request: resource: %s port_name %s"%(resource, port))
397395
dbg_param = ""
398396
if logger.getEffectiveLevel() == logging.DEBUG:
399-
# logger.info("enabling url debugging")
400397
dbg_param = "?__debug=1"
401398
collected_responses = list()
402-
self.json_post("/cli-json/set_port%s" % dbg_param, request, debug_=self.debug,
403-
response_json_list_=collected_responses)
404-
# TODO: when doing admin-up ath10k radios, want a LF complaint about a license exception
405-
# if len(collected_responses) > 0: ...
399+
return self.json_post("/cli-json/set_port%s" % dbg_param, request, debug_=self.debug,
400+
response_json_list_=collected_responses)
406401

407402
def admin_down(self, port_eid):
408403
eid = self.name_to_eid(port_eid)
409404
resource = eid[1]
410405
port = eid[2]
411406
request = LFUtils.port_down_request(resource_id=resource, port_name=port)
412-
self.json_post("/cli-json/set_port", request)
407+
return self.json_post("/cli-json/set_port", request)
413408

414409
def reset_port(self, port_eid):
415410
eid = self.name_to_eid(port_eid)
416411
resource = eid[1]
417412
port = eid[2]
418413
request = LFUtils.port_reset_request(resource_id=resource, port_name=port)
419-
self.json_post("cli-json/reset_port", request)
414+
return self.json_post("cli-json/reset_port", request)
420415

421416
def rm_cx(self, cx_name):
422417
req_url = "cli-json/rm_cx"
423418
data = {
424419
"test_mgr": "ALL",
425420
"cx_name": cx_name
426421
}
427-
self.json_post(req_url, data)
422+
return self.json_post(req_url, data)
428423

429424
def rm_endp(self, ename, debug_=False, suppress_related_commands_=True):
430425
req_url = "cli-json/rm_endp"
431426
data = {
432427
"endp_name": ename
433428
}
434-
self.json_post(req_url, data, debug_=debug_, suppress_related_commands_=suppress_related_commands_)
429+
return self.json_post(req_url, data, debug_=debug_, suppress_related_commands_=suppress_related_commands_)
435430

436431
def add_vrcx_(self, vr_name, local_dev, dhcp_min, dhcp_max, resource=1, debug_=False,
437432
suppress_related_commands_=True):
@@ -444,16 +439,15 @@ def add_vrcx_(self, vr_name, local_dev, dhcp_min, dhcp_max, resource=1, debug_=F
444439
"dhcp_min": dhcp_min,
445440
"dhcp_max": dhcp_max}
446441
logger.info("Modifying Connection...")
447-
self.json_post(req_url, data, debug_=debug_, suppress_related_commands_=suppress_related_commands_)
442+
return self.json_post(req_url, data, debug_=debug_, suppress_related_commands_=suppress_related_commands_)
448443

449444
def netsmith_apply(self, resource, debug_=False, suppress_related_commands_=True):
450445
data = {
451446
"shelf": 1,
452447
"resource": resource}
453448
logger.info("Applying the Netsmith Config")
454-
self.json_post("/cli-json/apply_vr_cfg", data, debug_=debug_,
455-
suppress_related_commands_=suppress_related_commands_)
456-
time.sleep(1)
449+
return self.json_post("/cli-json/apply_vr_cfg", data, debug_=debug_,
450+
suppress_related_commands_=suppress_related_commands_)
457451

458452
def set_endp_details(self, ename, pkt_to_send, debug_=False, suppress_related_commands_=True):
459453
req_url = "cli-json/set_endp_details"
@@ -463,7 +457,7 @@ def set_endp_details(self, ename, pkt_to_send, debug_=False, suppress_related_co
463457
"name": ename,
464458
"pkts_to_send": pkt_to_send
465459
}
466-
self.json_post(req_url, data, debug_=debug_, suppress_related_commands_=suppress_related_commands_)
460+
return self.json_post(req_url, data, debug_=debug_, suppress_related_commands_=suppress_related_commands_)
467461

468462
def set_endp_tos(self, ename, _tos, debug_=False, suppress_related_commands_=True):
469463
req_url = "cli-json/set_endp_tos"
@@ -485,25 +479,25 @@ def set_endp_tos(self, ename, _tos, debug_=False, suppress_related_commands_=Tru
485479
"name": ename,
486480
"tos": tos
487481
}
488-
self.json_post(req_url, data, debug_=debug_, suppress_related_commands_=suppress_related_commands_)
482+
return self.json_post(req_url, data, debug_=debug_, suppress_related_commands_=suppress_related_commands_)
489483

490484
def start_cx(self, cx_name):
491-
self.json_post("/cli-json/set_cx_state", {
485+
return self.json_post("/cli-json/set_cx_state", {
492486
"test_mgr": "ALL",
493487
"cx_name": cx_name,
494488
"cx_state": "RUNNING"
495489
}, debug_=self.debug)
496490

497491
def stop_cx(self, cx_name):
498-
self.json_post("/cli-json/set_cx_state", {
492+
return self.json_post("/cli-json/set_cx_state", {
499493
"test_mgr": "ALL",
500494
"cx_name": cx_name,
501495
"cx_state": "STOPPED"
502496
}, debug_=self.debug)
503497

504498
# def quiesce_cx(self, cx_name):
505499
def drain_stop_cx(self, cx_name):
506-
self.json_post("/cli-json/set_cx_state", {
500+
return self.json_post("/cli-json/set_cx_state", {
507501
"test_mgr": "ALL",
508502
"cx_name": cx_name,
509503
"cx_state": "QUIESCE"
@@ -515,35 +509,97 @@ def get_all_cxs(self):
515509
ignore_keys = {'handler', 'uri', 'warnings'}
516510

517511
cx_json = self.json_get("cx")
518-
if cx_json and 'empty' not in cx_json and isinstance(cx_json, dict):
512+
if cx_json is None:
513+
return None
514+
515+
if 'empty' not in cx_json and isinstance(cx_json, dict):
519516
for key in cx_json.keys():
520517
if key not in ignore_keys:
521518
cx_names.append(key)
522519

523520
return cx_names
524521

525-
def get_all_stations(self, prefix="sta"):
526-
"""Get all station names with a specific prefix.
522+
def get_all_ports(self, port_type=None, prefix=None):
523+
"""Get all port names/EIDs on LANforge manager, optionally filtering by port type or prefix.
524+
525+
Args:
526+
port_type: Optional port type filter (e.g., "station", "sta", "eth", "wlan", or None for all ports).
527+
prefix: Optional port prefix to filter (e.g. "sta", "wlan", "eth").
528+
529+
Returns:
530+
List of port EIDs/names or None if API error occurs.
531+
"""
532+
port_names = []
533+
try:
534+
response = self.json_get("/port/?fields=alias,port+type")
535+
if response is None:
536+
return None
537+
if 'interfaces' in response and isinstance(response['interfaces'], list):
538+
for interface_item in response['interfaces']:
539+
if isinstance(interface_item, dict):
540+
for alias, details in interface_item.items():
541+
info = self.name_to_eid(alias)
542+
if len(info) >= 3:
543+
port_name = str(info[2])
544+
ptype = ""
545+
if isinstance(details, dict):
546+
ptype = str(details.get('port type', details.get('type', ''))).upper()
547+
548+
# Check port type filter if specified
549+
if port_type and str(port_type).lower() in {'station', 'sta', 'wifi-sta', 'wireless'}:
550+
ptype_clean = ptype.replace(' ', '-').replace('_', '-')
551+
is_station = (ptype_clean == 'WIFI-STA') or ('WIFI-STA' in ptype_clean) or (ptype_clean == 'WIFI-STATION') or (ptype_clean == 'STA')
552+
if is_station:
553+
port_names.append(alias)
554+
elif prefix and str(prefix).lower() != "all":
555+
if port_name.startswith(str(prefix)) or (str(prefix) in port_name) or (str(prefix).upper() in ptype):
556+
port_names.append(alias)
557+
else:
558+
port_names.append(alias)
559+
else:
560+
port_names.append(alias)
561+
except Exception as e:
562+
logger.warning("Error querying ports from LANforge: %s", e)
563+
return None
564+
565+
return port_names
566+
567+
def get_all_stations(self, prefix=None):
568+
"""Get all station port names based on LANforge port-type 'WIFI-STA' or 'STA' (not assuming 'sta' name prefix).
527569
528570
Args:
529-
prefix: Station prefix.
571+
prefix: Optional prefix filter if user explicitly specifies a prefix. If None or 'sta' or 'all', matches all WIFI-STA ports.
530572
531573
Returns:
532-
List of station names with the specified prefix.
574+
List of station port names or None if API error occurs.
533575
"""
534576
sta_names = []
535577
try:
536-
response = self.json_get("/port/?fields=alias")
537-
if response and 'interfaces' in response and isinstance(response['interfaces'], list):
578+
response = self.json_get("/port/?fields=alias,port+type")
579+
if response is None:
580+
return None
581+
if 'interfaces' in response and isinstance(response['interfaces'], list):
538582
for interface_item in response['interfaces']:
539583
if isinstance(interface_item, dict):
540-
for alias in interface_item.keys():
584+
for alias, details in interface_item.items():
541585
info = self.name_to_eid(alias)
542-
port_name = str(info[2])
543-
if port_name.startswith(prefix) or ('sta' in port_name):
586+
port_name = str(info[2]) if len(info) >= 3 else str(alias)
587+
ptype = ""
588+
if isinstance(details, dict):
589+
ptype = str(details.get('port type', details.get('type', ''))).strip().upper().replace(' ', '-').replace('_', '-')
590+
591+
is_sta_type = ('WIFI-STA' in ptype) or (ptype == 'STA') or ('WIFI-STATION' in ptype)
592+
if is_sta_type:
593+
if prefix and str(prefix).lower() not in ("sta", "all"):
594+
if port_name.startswith(str(prefix)) or str(prefix) in port_name:
595+
sta_names.append(alias)
596+
else:
597+
sta_names.append(alias)
598+
elif prefix and str(prefix).lower() not in ("sta", "all") and (port_name.startswith(str(prefix)) or str(prefix) in port_name):
544599
sta_names.append(alias)
545600
except Exception as e:
546-
logger.warning("Error querying stations from LANforge: %s", e)
601+
logger.warning("Error querying station ports from LANforge: %s", e)
602+
return None
547603

548604
return sta_names
549605

0 commit comments

Comments
 (0)