Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[code sync] Merge code from sonic-net/sonic-utilities:202205 to 202205 #27

Merged
merged 4 commits into from
Sep 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion acl_loader/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion scripts/generate_dump
Original file line number Diff line number Diff line change
Expand Up @@ -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
29 changes: 13 additions & 16 deletions sfputil/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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 '<sfp no>:<error status>'
# The output of all SFP error status are a list consisting of <error status> 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 <physical port# : error status>
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):
Expand Down
2 changes: 1 addition & 1 deletion tests/mock_tables/asic2/config_db.json
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@
},
"ACL_TABLE|DATAACL_5": {
"policy_desc": "DATAACL_5",
"ports@": "Ethernet124",
"ports@": "Ethernet20",
"type": "L3",
"stage": "ingress"
}
Expand Down
6 changes: 3 additions & 3 deletions tests/sfputil_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand Down
10 changes: 6 additions & 4 deletions tests/show_acl_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -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():
Expand Down Expand Up @@ -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()
Expand Down
Loading