|
| 1 | +from dump.match_infra import MatchRequest |
| 2 | +from dump.helper import create_template_dict |
| 3 | +from .executor import Executor |
| 4 | + |
| 5 | + |
| 6 | +class Portchannel(Executor): |
| 7 | + """ |
| 8 | + Debug Dump Plugin for PortChannel/LAG Module |
| 9 | + """ |
| 10 | + ARG_NAME = "portchannel_name" |
| 11 | + |
| 12 | + def __init__(self, match_engine=None): |
| 13 | + super().__init__(match_engine) |
| 14 | + self.ret_temp = {} |
| 15 | + self.ns = '' |
| 16 | + self.lag_members = set() |
| 17 | + |
| 18 | + def get_all_args(self, ns=""): |
| 19 | + req = MatchRequest(db="CONFIG_DB", table="PORTCHANNEL", key_pattern="*", ns=ns) |
| 20 | + ret = self.match_engine.fetch(req) |
| 21 | + all_lags = ret["keys"] |
| 22 | + return [key.split("|")[-1] for key in all_lags] |
| 23 | + |
| 24 | + def execute(self, params_dict): |
| 25 | + self.ret_temp = create_template_dict(dbs=["CONFIG_DB", "APPL_DB", "ASIC_DB", "STATE_DB"]) |
| 26 | + self.lag_name = params_dict[Portchannel.ARG_NAME] |
| 27 | + self.ns = params_dict["namespace"] |
| 28 | + # CONFIG_DB |
| 29 | + lag_found = self.init_lag_config_info() |
| 30 | + if lag_found: |
| 31 | + self.init_lag_member_config_info() |
| 32 | + # APPL_DB |
| 33 | + self.init_lag_appl_info() |
| 34 | + # STATE_DB |
| 35 | + self.init_lag_state_info() |
| 36 | + # ASIC_DB |
| 37 | + lag_type_objs_asic = self.init_lag_member_type_obj_asic_info() |
| 38 | + self.init_lag_asic_info(lag_type_objs_asic) |
| 39 | + return self.ret_temp |
| 40 | + |
| 41 | + def add_to_ret_template(self, table, db, keys, err): |
| 42 | + if not err and keys: |
| 43 | + self.ret_temp[db]["keys"].extend(keys) |
| 44 | + return True |
| 45 | + else: |
| 46 | + self.ret_temp[db]["tables_not_found"].extend([table]) |
| 47 | + return False |
| 48 | + |
| 49 | + def init_lag_config_info(self): |
| 50 | + req = MatchRequest(db="CONFIG_DB", table="PORTCHANNEL", key_pattern=self.lag_name, ns=self.ns) |
| 51 | + ret = self.match_engine.fetch(req) |
| 52 | + return self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"]) |
| 53 | + |
| 54 | + def init_lag_member_config_info(self): |
| 55 | + req = MatchRequest(db="CONFIG_DB", table="PORTCHANNEL_MEMBER", key_pattern=self.lag_name + "|*", ns=self.ns) |
| 56 | + ret = self.match_engine.fetch(req) |
| 57 | + for key in ret["keys"]: |
| 58 | + self.lag_members.add(key.split("|")[-1]) |
| 59 | + |
| 60 | + def init_lag_appl_info(self): |
| 61 | + req = MatchRequest(db="APPL_DB", table="LAG_TABLE", key_pattern=self.lag_name, ns=self.ns) |
| 62 | + ret = self.match_engine.fetch(req) |
| 63 | + return self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"]) |
| 64 | + |
| 65 | + def init_lag_state_info(self): |
| 66 | + req = MatchRequest(db="STATE_DB", table="LAG_TABLE", key_pattern=self.lag_name, ns=self.ns) |
| 67 | + ret = self.match_engine.fetch(req) |
| 68 | + return self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"]) |
| 69 | + |
| 70 | + def init_lag_asic_info(self, lag_type_objs_asic): |
| 71 | + if len(lag_type_objs_asic) == 0: |
| 72 | + self.ret_temp["ASIC_DB"]["tables_not_found"].extend(["ASIC_STATE:SAI_OBJECT_TYPE_LAG"]) |
| 73 | + return |
| 74 | + for lag_asic_obj in lag_type_objs_asic: |
| 75 | + req = MatchRequest(db="ASIC_DB", table="ASIC_STATE:SAI_OBJECT_TYPE_LAG", key_pattern=lag_asic_obj, ns=self.ns) |
| 76 | + ret = self.match_engine.fetch(req) |
| 77 | + self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"]) |
| 78 | + |
| 79 | + def init_lag_member_type_obj_asic_info(self): |
| 80 | + """ |
| 81 | + Finding the relevant SAI_OBJECT_TYPE_LAG key directly from the ASIC is not possible given a LAG name |
| 82 | + Thus, using the members to find SAI_LAG_MEMBER_ATTR_LAG_ID |
| 83 | + """ |
| 84 | + lag_type_objs_asic = set() |
| 85 | + for port_name in self.lag_members: |
| 86 | + port_asic_obj = self.get_port_asic_obj(port_name) |
| 87 | + if port_asic_obj: |
| 88 | + lag_member_key, lag_oid = self.get_lag_and_member_obj(port_asic_obj) |
| 89 | + lag_type_objs_asic.add(lag_oid) |
| 90 | + return lag_type_objs_asic |
| 91 | + |
| 92 | + def get_port_asic_obj(self, port_name): |
| 93 | + req = MatchRequest(db="ASIC_DB", table="ASIC_STATE:SAI_OBJECT_TYPE_HOSTIF", key_pattern="*", field="SAI_HOSTIF_ATTR_NAME", |
| 94 | + value=port_name, return_fields=["SAI_HOSTIF_ATTR_OBJ_ID"], ns=self.ns) |
| 95 | + ret = self.match_engine.fetch(req) |
| 96 | + asic_port_obj_id = "" |
| 97 | + if not ret["error"] and ret["keys"]: |
| 98 | + sai_hostif_obj_key = ret["keys"][-1] |
| 99 | + if sai_hostif_obj_key in ret["return_values"] and "SAI_HOSTIF_ATTR_OBJ_ID" in ret["return_values"][sai_hostif_obj_key]: |
| 100 | + asic_port_obj_id = ret["return_values"][sai_hostif_obj_key]["SAI_HOSTIF_ATTR_OBJ_ID"] |
| 101 | + return asic_port_obj_id |
| 102 | + |
| 103 | + def get_lag_and_member_obj(self, port_asic_obj): |
| 104 | + req = MatchRequest(db="ASIC_DB", table="ASIC_STATE:SAI_OBJECT_TYPE_LAG_MEMBER", key_pattern="*", field="SAI_LAG_MEMBER_ATTR_PORT_ID", |
| 105 | + value=port_asic_obj, return_fields=["SAI_LAG_MEMBER_ATTR_LAG_ID"], ns=self.ns) |
| 106 | + ret = self.match_engine.fetch(req) |
| 107 | + lag_member_key = "" |
| 108 | + lag_oid = "" |
| 109 | + if not ret["error"] and ret["keys"]: |
| 110 | + lag_member_key = ret["keys"][-1] |
| 111 | + if lag_member_key in ret["return_values"] and "SAI_LAG_MEMBER_ATTR_LAG_ID" in ret["return_values"][lag_member_key]: |
| 112 | + lag_oid = ret["return_values"][lag_member_key]["SAI_LAG_MEMBER_ATTR_LAG_ID"] |
| 113 | + return lag_member_key, lag_oid |
0 commit comments