From 79aa4134a976aef93fcf5c024a95e96db808f1df Mon Sep 17 00:00:00 2001 From: agadia-cisco Date: Tue, 5 Nov 2024 19:32:21 -0800 Subject: [PATCH] [PR:14926] Configuring Community SNMP Credentials for SNMP TCs (#15359) * Configuring Community SNMP Credentials for SNMP TCs (#14926) Description of PR Summary: The PR contains changes to snmp/conftest.py with logic to configure snmp credentials stored in snmp.yml for every host before running any test script. Approach What is the motivation for this PR? If credentials in snmp.yml isn't configured, then the changes in PR configures them before running the tests and restores the original configuration after the TC execution. How did you do it? snmp/conftest.py will now copy the snmp.yml from DUT to UCS (if DUT has snmp.yml) & then it will configure the SNMP credentials for every host via sudo config snmp command. The logic it configures is same as in snmp_yml_to_configdb.py script; where it checks whether the credentials in yml are configured in config_db or not, if the keys are configured but the values are different / the keys are not configured - then it will configure them. Before the test script execution, SNMP is configured, once the execution completes, it reverts the configuration that existed before. How did you verify/test it? Run changes with 202405 image on a T0 setup without snmp credentials configured / with different credentials configured in image and snmp tests passed as expected in all scenarios. co-authorized by: jianquanye@microsoft.com * update gu_utils location from one used in master to 202405 --- tests/snmp/conftest.py | 84 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-) diff --git a/tests/snmp/conftest.py b/tests/snmp/conftest.py index 930ecb35cb2..45b71c83e49 100644 --- a/tests/snmp/conftest.py +++ b/tests/snmp/conftest.py @@ -1,13 +1,95 @@ import pytest from tests.common.utilities import wait_until +import shutil +import yaml + +from tests.generic_config_updater.gu_utils import create_checkpoint, rollback + +SETUP_ENV_CP = "test_setup_checkpoint" @pytest.fixture(scope="module", autouse=True) -def setup_check_snmp_ready(duthosts): +def setup_check_snmp_ready(duthosts, localhost): for duthost in duthosts: assert wait_until(300, 20, 0, duthost.is_service_fully_started, "snmp"), "SNMP service is not running" + # creating checkpoint before any configuration changes + create_checkpoint(duthost, SETUP_ENV_CP) + + snmp_config_path = "/etc/sonic/snmp.yml" + + # copy snmp.yml to ucs + output = duthost.shell("sudo find /etc/sonic -name 'snmp.yml'") + filename = output["stdout"].split("\n") + + if snmp_config_path in filename: + ret = duthost.fetch(src=snmp_config_path, dest=".") + ret_bin = ret.get("dest", None) + shutil.copyfile(ret_bin, "snmp/snmp.yml") + else: + assert False, f'{snmp_config_path} does not exist' + + # configure snmp for every host + full_snmp_comm_list = ['snmp_rocommunity', 'snmp_rocommunities', 'snmp_rwcommunity', 'snmp_rwcommunities'] + with open('./snmp/snmp.yml', 'r') as yaml_file: + yaml_snmp_info = yaml.load(yaml_file, Loader=yaml.FullLoader) + + # get redis output for SNMP_COMMUNITY & SNMP_LOCATION + snmp_comm_redis_keys = check_redis_output(duthost, 'SNMP_COMMUNITY') + snmp_comm_redis_vals = list(map(extract_redis_keys, snmp_comm_redis_keys)) + snmp_location_redis_keys = check_redis_output(duthost, 'SNMP|LOCATION') + snmp_location_redis_vals = list(map(extract_redis_keys, snmp_location_redis_keys)) + + for comm_type in full_snmp_comm_list: + if comm_type in yaml_snmp_info.keys(): + if comm_type.startswith('snmp_rocommunities'): + for community in yaml_snmp_info[comm_type]: + if community not in snmp_comm_redis_vals: + duthost.shell(f"sudo config snmp community add {community} 'ro'") # set snmp cli + + elif comm_type.startswith('snmp_rocommunity'): + community = yaml_snmp_info[comm_type] + if community not in snmp_comm_redis_vals: + duthost.shell(f"sudo config snmp community add {community} 'ro'") # set snmp cli + + elif comm_type.startswith('snmp_rwcommunities'): + for community in yaml_snmp_info[comm_type]: + if community not in snmp_comm_redis_vals: + duthost.shell(f"sudo config snmp community add {community} 'rw'") # set snmp cli + + elif comm_type.startswith('snmp_rwcommunity'): + community = yaml_snmp_info[comm_type] + if community not in snmp_comm_redis_vals: + duthost.shell(f"sudo config snmp community add {community} 'rw'") # set snmp cli + + yaml_snmp_location = yaml_snmp_info.get('snmp_location') + if yaml_snmp_location: + if 'LOCATION' not in snmp_location_redis_vals: + duthost.shell(f'sudo config snmp location add {yaml_snmp_location}') # set snmp cli + + yield + + # rollback configuration + rollback(duthost, SETUP_ENV_CP) + + # remove snmp files downloaded + local_command = "find ./snmp/ -type f -name 'snmp.yml' -exec rm -f {} +" + localhost.shell(local_command) + + +def extract_redis_keys(item): + return item.split('|')[1] + + +def check_redis_output(duthost, key): + snmp_redis_keys = duthost.shell(f"redis-cli -n 4 keys '{key}*'") + if snmp_redis_keys["stdout"] == "": + return [] + else: + snmp_redis_keys = snmp_redis_keys["stdout"].split("\n") + return snmp_redis_keys + @pytest.fixture(scope="module", autouse=True) def enable_queue_counterpoll_type(duthosts):