diff --git a/acl_loader/main.py b/acl_loader/main.py index fab46eb90..6a28cb0f8 100644 --- a/acl_loader/main.py +++ b/acl_loader/main.py @@ -173,7 +173,31 @@ def read_tables_info(self): Read ACL_TABLE table from configuration database :return: """ - self.tables_db_info = self.configdb.get_table(self.ACL_TABLE) + # get the acl table info from host config_db + host_acl_table = self.configdb.get_table(self.ACL_TABLE) + # For multi asic get only the control plane acls from the host config_db + if self.per_npu_configdb: + for table, entry in host_acl_table.items(): + if entry.get('type', None) != self.ACL_TABLE_TYPE_CTRLPLANE: + continue + + self.tables_db_info[table] = entry + else: + self.tables_db_info.update(host_acl_table) + + # for DATAACL, EVERFLOW acls. + # update the ports from all the namespaces + if self.per_npu_configdb: + for ns, config_db in self.per_npu_configdb.items(): + acl_table = config_db.get_table(self.ACL_TABLE) + for table, entry in acl_table.items(): + if entry.get('type', None) == self.ACL_TABLE_TYPE_CTRLPLANE: + continue + if table not in self.tables_db_info: + self.tables_db_info[table] = entry + else: + self.tables_db_info[table]['ports'] += entry.get( + 'ports', []) def get_tables_db_info(self): return self.tables_db_info diff --git a/scripts/generate_dump b/scripts/generate_dump index 8af9e8533..6f64e90ec 100755 --- a/scripts/generate_dump +++ b/scripts/generate_dump @@ -1917,7 +1917,7 @@ else rm_lock_and_exit else # Lock is valid and the other instance is active. Exit Now - echo "Accquiring lock failed, PID ${PID_PROG} is active" >&2 + echo "Another instance of techsupport running with PID: ${PID_PROG}, please retry after some time..." >&2 exit $EXT_LOCKFAIL fi fi diff --git a/sfputil/main.py b/sfputil/main.py index d53cf8e3e..753634be7 100644 --- a/sfputil/main.py +++ b/sfputil/main.py @@ -901,9 +901,9 @@ def fetch_error_status_from_platform_api(port): # Code to fetch the error status get_error_status_code = \ "try:\n"\ - " errors=['{}:{}'.format(sfp.index, sfp.get_error_description()) for sfp in sfp_list]\n" \ + " errors=['{}'.format(sfp.get_error_description()) for sfp in sfp_list]\n" \ "except NotImplementedError as e:\n"\ - " errors=['{}:{}'.format(sfp.index, 'OK (Not implemented)') for sfp in sfp_list]\n" \ + " errors=['{}'.format('OK (Not implemented)') for sfp in sfp_list]\n" \ "print(errors)\n" get_error_status_command = "docker exec pmon python3 -c \"{}{}{}\"".format( @@ -917,28 +917,25 @@ def fetch_error_status_from_platform_api(port): output_list = output.split('\n') for output_str in output_list: - # The output of all SFP error status are a list consisting of element with convention of ':' + # The output of all SFP error status are a list consisting of sorted physical port indices # Besides, there can be some logs captured during the platform API executing # So, first of all, we need to skip all the logs until find the output list of SFP error status if output_str[0] == '[' and output_str[-1] == ']': output_list = ast.literal_eval(output_str) break - output_dict = {} - for output in output_list: - sfp_index, error_status = output.split(':') - output_dict[int(sfp_index)] = error_status + physical_port_set = set() + for port in logical_port_list: + physical_port_set.add(logical_port_to_physical_port_index(port)) - output = [] - for logical_port_name in logical_port_list: - physical_port_list = logical_port_name_to_physical_port_list(logical_port_name) - port_name = get_physical_port_name(logical_port_name, 1, False) - - if is_port_type_rj45(logical_port_name): - output.append([port_name, "N/A"]) - else: - output.append([port_name, output_dict.get(physical_port_list[0])]) + physical_port_list = list(physical_port_set) + # Map of + error_map = {physical_port_list[i] : output_list[i] for i in range(len(physical_port_list))} + output = [] + for i in range(len(logical_port_list)): + physical_port = logical_port_to_physical_port_index(logical_port_list[i]) + output.append([logical_port_list[i], error_map[physical_port] if not is_port_type_rj45(logical_port_list[i]) else 'N/A']) return output def fetch_error_status_from_state_db(port, state_db): diff --git a/tests/mock_tables/asic2/config_db.json b/tests/mock_tables/asic2/config_db.json index bfda10a0d..32a524365 100644 --- a/tests/mock_tables/asic2/config_db.json +++ b/tests/mock_tables/asic2/config_db.json @@ -132,7 +132,7 @@ }, "ACL_TABLE|DATAACL_5": { "policy_desc": "DATAACL_5", - "ports@": "Ethernet124", + "ports@": "Ethernet20", "type": "L3", "stage": "ingress" } diff --git a/tests/sfputil_test.py b/tests/sfputil_test.py index c57a5dc61..7b1e99d0b 100644 --- a/tests/sfputil_test.py +++ b/tests/sfputil_test.py @@ -319,14 +319,14 @@ def test_error_status_from_db_RJ45(self): @patch('sfputil.main.logical_port_name_to_physical_port_list', MagicMock(return_value=[1])) @patch('sfputil.main.logical_port_to_physical_port_index', MagicMock(return_value=1)) @patch('sfputil.main.is_port_type_rj45', MagicMock(return_value=False)) - @patch('subprocess.check_output', MagicMock(return_value="['0:OK']")) + @patch('subprocess.check_output', MagicMock(return_value="['OK']")) def test_fetch_error_status_from_platform_api(self): output = sfputil.fetch_error_status_from_platform_api('Ethernet0') - assert output == [['Ethernet0', None]] + assert output == [['Ethernet0', 'OK']] @patch('sfputil.main.logical_port_name_to_physical_port_list', MagicMock(return_value=[1])) @patch('sfputil.main.logical_port_to_physical_port_index', MagicMock(return_value=1)) - @patch('subprocess.check_output', MagicMock(return_value="['0:OK']")) + @patch('subprocess.check_output', MagicMock(return_value="['OK']")) @patch('sfputil.main.is_port_type_rj45', MagicMock(return_value=True)) def test_fetch_error_status_from_platform_api_RJ45(self): output = sfputil.fetch_error_status_from_platform_api('Ethernet0') diff --git a/tests/show_acl_test.py b/tests/show_acl_test.py index 1b2cdc60a..64db81fb9 100644 --- a/tests/show_acl_test.py +++ b/tests/show_acl_test.py @@ -11,6 +11,11 @@ modules_path = os.path.dirname(root_path) scripts_path = os.path.join(modules_path, "scripts") +MASIC_SHOW_ACL_OUTPUT = """Name Type Binding Description Stage Status +--------- ------ ----------- ------------- ------- -------------------------------------- +DATAACL_5 L3 Ethernet20 DATAACL_5 ingress {'asic0': 'Active', 'asic2': 'Active'} + Ethernet124 +""" @pytest.fixture() def setup_teardown_single_asic(): @@ -74,10 +79,7 @@ def test_show_acl_table(self, setup_teardown_multi_asic): } result = runner.invoke(acl_loader_show.cli.commands['show'].commands['table'], ['DATAACL_5'], obj=context) assert result.exit_code == 0 - # We only care about the third line, which contains the 'Active' - result_top = result.output.split('\n')[2] - expected_output = "DATAACL_5 L3 Ethernet124 DATAACL_5 ingress {'asic0': 'Active', 'asic2': 'Active'}" - assert result_top == expected_output + assert result.output == MASIC_SHOW_ACL_OUTPUT def test_show_acl_rule(self, setup_teardown_multi_asic): runner = CliRunner()