From dce4d16a27ad5c03e199c01b8ff88d8b8963b217 Mon Sep 17 00:00:00 2001 From: Jingwen Xie Date: Tue, 11 Jan 2022 09:40:27 +0000 Subject: [PATCH 1/4] GCU AAA test --- tests/generic_config_updater/test_aaa.py | 609 +++++++++++++++++++++++ 1 file changed, 609 insertions(+) create mode 100644 tests/generic_config_updater/test_aaa.py diff --git a/tests/generic_config_updater/test_aaa.py b/tests/generic_config_updater/test_aaa.py new file mode 100644 index 00000000000..a026bf61bfc --- /dev/null +++ b/tests/generic_config_updater/test_aaa.py @@ -0,0 +1,609 @@ +import logging +import pytest + +from tests.common.helpers.assertions import pytest_assert +from tests.generic_config_updater.gu_utils import apply_patch, expect_op_success, expect_op_failure +from tests.generic_config_updater.gu_utils import generate_tmpfile, delete_tmpfile +from tests.generic_config_updater.gu_utils import create_checkpoint, delete_checkpoint, rollback_or_reload + +pytestmark = [ + pytest.mark.topology('t0'), +] + +logger = logging.getLogger(__name__) + +AAA_CATEGORY = ["authentication", "authorization", "accounting"] + +@pytest.fixture(autouse=True) +def setup_env(duthosts, rand_one_dut_hostname, tbinfo): + """ + Setup/teardown fixture for each loopback interface test. + rollback to check if it goes back to starting config + + Args: + duthosts: list of DUTs. + rand_selected_dut: The fixture returns a randomly selected DuT. + """ + duthost = duthosts[rand_one_dut_hostname] + + create_checkpoint(duthost) + + yield + + try: + logger.info("Rolled back to original checkpoint") + rollback_or_reload(duthost) + finally: + delete_checkpoint(duthost) + + + +def verify_aaa_sub_options(duthost, aaa_type, option, value): + """ Verify if AAA sub type's options match with expected value + + Sample output: + admin@vlab-01:~/tacacs$ show aaa + AAA authentication login local (default) + AAA authentication failthrough False (default) + AAA authorization login local (default) + AAA accounting login disable (default) + """ + output = duthost.shell('show aaa | grep -Po "AAA {} {} \K.*"'.format(aaa_type, option)) + logger.info("{}".format(output)) + pytest_assert(not output['rc'], + "Failed to grep AAA {}".format(option) + ) + pytest_assert(output['stdout'] == value, + "AAA {} {} failed to apply".format(aaa_type, option) + ) + +def aaa_add_init_config(duthost): + """ Add initial config for AAA + + Though AAA has default value in setup. But the config does not + included in configDB. So to make change on AAA table, the init + config need to be added to config first. + Sample configDB table: + "AAA": { + "accounting": { + "login": "local" + }, + "authentication": { + "login": "local" + }, + "authorization": { + "login": "local" + } + } + """ + cmds = [] + cmds.append("config aaa authentication login local") + cmds.append("config aaa authorization local") + cmds.append("config aaa accounting local") + + output = duthost.shell_cmds(cmds=cmds)['results'] + logger.info(output) + for res in output: + pytest_assert(not res['rc'], + "AAA init config failed" + ) + +def verify_tacacs_global_config(duthost, tacacs_global_type, value): + """ Verify tacacs global config match with expected value + + Sample output in t0: + admin@vlab-01:~/tacacs$ show tacacs + TACPLUS global auth_type pap (default) + TACPLUS global timeout 5 (default) + TACPLUS global passkey (default) + + TACPLUS_SERVER address 10.0.0.8 + priority 1 + tcp_port 49 + + TACPLUS_SERVER address 10.0.0.9 + priority 1 + tcp_port 49 + + """ + output = duthost.shell('show tacacs | grep -Po "TACPLUS global {} \K.*"'.format(tacacs_global_type)) + logger.info("{}".format(output)) + pytest_assert(not output['rc'], + "Failed to grep TACACS {}".format(tacacs_global_type) + ) + pytest_assert(output['stdout'] == value, + "TACACS global {} failed to apply".format(tacacs_global_type) + ) + +def tacacs_add_init_config(duthost): + """ Add initial config for tacacs + + Same with AAA config. The default tacacs config does not + included in configDB. So to make change, the initial + config need to be added to config first. + Sample configDB table: + "TACPLUS": { + "global": { + "auth_type": "pap", + "passkey": "testing123", + "timeout": "5" + } + } + """ + cmds = [] + cmds.append("config tacacs authtype pap") + cmds.append("config tacacs passkey testing123") + cmds.append("config tacacs timeout 5") + + output = duthost.shell_cmds(cmds=cmds)['results'] + logger.info(output) + for res in output: + pytest_assert(not res['rc'], + "TACACS init config failed" + ) + +def parse_tacacs_server(duthost): + """ Parse tacacs server + + Sample output in t0: + {u'10.0.0.9': {u'priority': u'1', u'tcp_port': u'49'}, + u'10.0.0.8': {u'priority': u'1', u'tcp_port': u'49'}} + """ + output = duthost.shell("show tacacs") + pytest_assert(not output['rc']) + lines = output['stdout'] + + tacacs_servers = {} + tacacs_server = {} + address = "" + tacacs_server_found = False + + for line in lines.splitlines(): + + if line.startswith("TACPLUS_SERVER"): + address = line.split(" ")[-1] + tacacs_server_found = True + else: + if not tacacs_server_found: + continue + + if not line: + tacacs_servers[address] = tacacs_server + tacacs_server = {} + address = "" + else: + pytest_assert(len(line.strip().split(" ")) == 2) + k, v = line.strip().split(" ") + tacacs_server[k] = v + + if address: + tacacs_servers[address] = tacacs_server + + return tacacs_servers + +@pytest.mark.parametrize("aaa_type, aaa_sub_options", [ + ( + "authentication", + { + "debug": "True", + "failthrough": "True", + "fallback": "True", + "login": "local,tacacs+", + "trace": "True" + } + ), + ( + "authorization", + { + "login": "tacacs+,local" + } + ), + ( + "accounting", + { + "login": "tacacs+,local" + } + ) +]) +def test_aaa_tc1_add_config(duthost, aaa_type, aaa_sub_options): + """ Test AAA add initial config for its sub type + """ + json_patch = [ + { + "op": "add", + "path": "/AAA", + "value": { + "{}".format(aaa_type): aaa_sub_options + } + } + ] + + tmpfile = generate_tmpfile(duthost) + logger.info("tmpfile {}".format(tmpfile)) + + try: + output = apply_patch(duthost, json_data=json_patch, dest_file=tmpfile) + expect_op_success(duthost, output) + + for option, value in aaa_sub_options.items(): + verify_aaa_sub_options(duthost, aaa_type, option, value) + finally: + delete_tmpfile(duthost, tmpfile) + +def test_aaa_tc2_replace(duthost): + """ Test replace option value in each AAA sub type + """ + aaa_add_init_config(duthost) + json_patch = [ + { + "op": "replace", + "path": "/AAA/authorization/login", + "value": "tacacs+" + }, + { + "op": "replace", + "path": "/AAA/authentication/login", + "value": "tacacs+" + }, + { + "op": "replace", + "path": "/AAA/accounting/login", + "value": "tacacs+" + } + ] + + tmpfile = generate_tmpfile(duthost) + logger.info("tmpfile {}".format(tmpfile)) + + try: + output = apply_patch(duthost, json_data=json_patch, dest_file=tmpfile) + expect_op_success(duthost, output) + + for aaa_type in AAA_CATEGORY: + verify_aaa_sub_options(duthost, aaa_type, "login", "tacacs+") + finally: + delete_tmpfile(duthost, tmpfile) + +def test_aaa_tc3_add_duplicate(duthost): + """ Test add duplicate config in AAA sub type + """ + aaa_add_init_config(duthost) + json_patch = [ + { + "op": "add", + "path": "/AAA/authorization/login", + "value": "local" + }, + { + "op": "add", + "path": "/AAA/authentication/login", + "value": "local" + }, + { + "op": "add", + "path": "/AAA/accounting/login", + "value": "local" + } + ] + + tmpfile = generate_tmpfile(duthost) + logger.info("tmpfile {}".format(tmpfile)) + + try: + output = apply_patch(duthost, json_data=json_patch, dest_file=tmpfile) + expect_op_success(duthost, output) + + for aaa_type in AAA_CATEGORY: + verify_aaa_sub_options(duthost, aaa_type, "login", "local") + finally: + delete_tmpfile(duthost, tmpfile) + +def test_aaa_tc4_remove(duthost): + """ Test remove AAA config check if it returns to default setup + """ + aaa_add_init_config(duthost) + json_patch = [ + { + "op": "remove", + "path": "/AAA" + } + ] + + tmpfile = generate_tmpfile(duthost) + logger.info("tmpfile {}".format(tmpfile)) + + try: + output = apply_patch(duthost, json_data=json_patch, dest_file=tmpfile) + expect_op_success(duthost, output) + + output = duthost.shell('show aaa') + pytest_assert(not output['rc'], + "AAA show command failed" + ) + logger.info("output {}".format(output)) + for line in output['stdout'].splitlines(): + logger.info(line) + pytest_assert(line.endswith("(default)"), + "AAA config deletion failed!" + ) + finally: + delete_tmpfile(duthost, tmpfile) + +def test_tacacs_global_tc5_add_config(duthost): + """ Test add tacacs global config + """ + TACACS_ADD_CONFIG = { + "auth_type": "login", + "passkey": "testing123", + "timeout": "10" + } + json_patch = [ + { + "op": "add", + "path": "/TACPLUS", + "value": { + "global": TACACS_ADD_CONFIG + } + } + ] + tmpfile = generate_tmpfile(duthost) + logger.info("tmpfile {}".format(tmpfile)) + + try: + output = apply_patch(duthost, json_data=json_patch, dest_file=tmpfile) + expect_op_success(duthost, output) + + for tacacs_global_type, value in TACACS_ADD_CONFIG.items(): + verify_tacacs_global_config(duthost, tacacs_global_type, value) + finally: + delete_tmpfile(duthost, tmpfile) + +@pytest.mark.parametrize("tacacs_global_type, invalid_input", [ + ("auth_type", "logout"), + ("passkey", " 123"), ("passkey", "#123"), ("passkey", ",123"), ("passkey", "1"*66), + ("timeout", "61"), ("timeout", "0") +]) +def test_tacacs_global_tc6_invalid_input(duthost, tacacs_global_type, invalid_input): + """ Test tacacs global invalid input + + option restriction: + auth_type:[chap, pap, mschap, login] + passkey: cannot contain space, "#" and "," + timeout: range[1, 60] + """ + json_patch = [ + { + "op": "add", + "path": "/TACPLUS", + "value": { + "global": { + tacacs_global_type: invalid_input + } + } + } + ] + tmpfile = generate_tmpfile(duthost) + logger.info("tmpfile {}".format(tmpfile)) + + try: + output = apply_patch(duthost, json_data=json_patch, dest_file=tmpfile) + expect_op_failure(output) + + finally: + delete_tmpfile(duthost, tmpfile) + +def test_tacacs_global_tc7_duplicate_input(duthost): + """ Test tacacs global duplicate input + """ + tacacs_add_init_config(duthost) + + TACACS_ADD_CONFIG = { + "auth_type": "pap", + "passkey": "testing123", + "timeout": "5" + } + json_patch = [ + { + "op": "add", + "path": "/TACPLUS", + "value": { + "global": TACACS_ADD_CONFIG + } + } + ] + tmpfile = generate_tmpfile(duthost) + logger.info("tmpfile {}".format(tmpfile)) + + try: + output = apply_patch(duthost, json_data=json_patch, dest_file=tmpfile) + expect_op_success(duthost, output) + + for tacacs_global_type, value in TACACS_ADD_CONFIG.items(): + verify_tacacs_global_config(duthost, tacacs_global_type, value) + finally: + delete_tmpfile(duthost, tmpfile) + +def test_tacacs_global_tc8_remove(duthost): + """ Test tacacs global config removal + """ + tacacs_add_init_config(duthost) + + json_patch = [ + { + "op": "remove", + "path": "/TACPLUS" + } + ] + tmpfile = generate_tmpfile(duthost) + logger.info("tmpfile {}".format(tmpfile)) + + try: + output = apply_patch(duthost, json_data=json_patch, dest_file=tmpfile) + expect_op_success(duthost, output) + + output = duthost.shell('show tacacs | grep "TACPLUS global"') + pytest_assert(not output['rc'], + "AAA show command failed" + ) + for line in output['stdout'].splitlines(): + pytest_assert(line.endswith("(default)"), + "AAA config deletion failed!" + ) + finally: + delete_tmpfile(duthost, tmpfile) + +@pytest.mark.parametrize("ip_address", ["10.0.0.10", "fc10::10"]) +def test_tacacs_server_tc9_add(duthost, ip_address): + """ Test tacacs server addition + """ + TACACS_SERVER_ADD = { + "auth_type": "login", + "passkey": "testing123", + "priority": "10", + "tcp_port": "50", + "timeout": "10" + } + json_patch = [ + { + "op": "add", + "path": "/TACPLUS_SERVER/{}".format(ip_address), + "value": TACACS_SERVER_ADD + } + ] + + tmpfile = generate_tmpfile(duthost) + logger.info("tmpfile {}".format(tmpfile)) + + try: + output = apply_patch(duthost, json_data=json_patch, dest_file=tmpfile) + expect_op_success(duthost, output) + + tacacs_servers = parse_tacacs_server(duthost) + pytest_assert(ip_address in tacacs_servers, + "tacacs server failed to add to config." + ) + tacacs_server = tacacs_servers[ip_address] + for opt, value in TACACS_SERVER_ADD.items(): + pytest_assert(opt in tacacs_server and tacacs_server[opt] == value, + "tacacs server failed to add to config completely." + ) + finally: + delete_tmpfile(duthost, tmpfile) + +def test_tacacs_server_tc10_add_max(duthost): + """ Test tacacs server reach maximum 8 servers + + The t0 has two servers 10.0.0.8 and 10.0.0.9. Need to add 7 more + servers to exceed the max. + """ + json_patch = [] + for i in range(10, 17): + server = { + "op": "add", + "path": "/TACPLUS_SERVER/10.0.0.{}".format(i), + "value": { + "priority": "1", + "tcp_port": "49" + } + } + json_patch.append(server) + logger.info(json_patch) + + tmpfile = generate_tmpfile(duthost) + logger.info("tmpfile {}".format(tmpfile)) + + try: + output = apply_patch(duthost, json_data=json_patch, dest_file=tmpfile) + expect_op_failure(output) + + finally: + delete_tmpfile(duthost, tmpfile) + +@pytest.mark.parametrize("tacacs_server_options, invalid_input", [ + ("auth_type", "logout"), + ("passkey", " 123"), ("passkey", "#123"), ("passkey", ",123"), ("passkey", "1"*66), + ("priority", "0"), ("priority", "65"), + ("tcp_port", "65536"), + ("timeout", "61"), ("timeout", "0") +]) +def test_tacacs_server_tc11_add_invalid(duthost, tacacs_server_options, invalid_input): + """ Test invalid input for tacacs server + + valid input restriction: + auth_type:[chap, pap, mschap, login] + passkey: cannot contain space, "#" and "," + priority: range[1, 64] + tcp_port: [0, 65535] + timeout: range[1, 60] + """ + json_patch = [ + { + "op": "add", + "path": "/TACPLUS_SERVER/10.0.0.10", + "value": { + tacacs_server_options: invalid_input + } + } + ] + tmpfile = generate_tmpfile(duthost) + logger.info("tmpfile {}".format(tmpfile)) + + try: + output = apply_patch(duthost, json_data=json_patch, dest_file=tmpfile) + expect_op_failure(output) + + finally: + delete_tmpfile(duthost, tmpfile) + +def test_tacacs_server_tc12_add_duplicate(duthost): + """ Test tacacs server add duplicate server + """ + json_patch = [ + { + "op": "add", + "path": "/TACPLUS_SERVER/10.0.0.8", + "value": { + "priority": "1", + "tcp_port": "49" + } + } + ] + + tmpfile = generate_tmpfile(duthost) + logger.info("tmpfile {}".format(tmpfile)) + + try: + output = apply_patch(duthost, json_data=json_patch, dest_file=tmpfile) + expect_op_success(duthost, output) + + tacacs_servers = parse_tacacs_server(duthost) + pytest_assert('10.0.0.9' in tacacs_servers, + "tacacs server add duplicate failed." + ) + + finally: + delete_tmpfile(duthost, tmpfile) + +def test_tacacs_server_tc13_remove(duthost): + """ Test tacasc server removal + """ + json_patch = [ + { + "op": "remove", + "path": "/TACPLUS_SERVER" + } + ] + + tmpfile = generate_tmpfile(duthost) + logger.info("tmpfile {}".format(tmpfile)) + + try: + output = apply_patch(duthost, json_data=json_patch, dest_file=tmpfile) + expect_op_success(duthost, output) + + tacacs_servers = parse_tacacs_server(duthost) + pytest_assert(not tacacs_servers, + "tacacs server failed to remove." + ) + finally: + delete_tmpfile(duthost, tmpfile) From 4b4715f931f0cd8192c939bf0cfac3f75128f76a Mon Sep 17 00:00:00 2001 From: Jingwen Xie Date: Wed, 19 Jan 2022 07:11:37 +0000 Subject: [PATCH 2/4] resolve comment --- tests/generic_config_updater/test_aaa.py | 125 ++++++++++++++--------- 1 file changed, 79 insertions(+), 46 deletions(-) diff --git a/tests/generic_config_updater/test_aaa.py b/tests/generic_config_updater/test_aaa.py index a026bf61bfc..6d4dad27592 100644 --- a/tests/generic_config_updater/test_aaa.py +++ b/tests/generic_config_updater/test_aaa.py @@ -15,7 +15,7 @@ AAA_CATEGORY = ["authentication", "authorization", "accounting"] @pytest.fixture(autouse=True) -def setup_env(duthosts, rand_one_dut_hostname, tbinfo): +def setup_env(duthosts, rand_one_dut_hostname): """ Setup/teardown fixture for each loopback interface test. rollback to check if it goes back to starting config @@ -36,29 +36,37 @@ def setup_env(duthosts, rand_one_dut_hostname, tbinfo): finally: delete_checkpoint(duthost) - - -def verify_aaa_sub_options(duthost, aaa_type, option, value): +def get_aaa_sub_options_value(duthost, aaa_type, option): """ Verify if AAA sub type's options match with expected value Sample output: - admin@vlab-01:~/tacacs$ show aaa - AAA authentication login local (default) - AAA authentication failthrough False (default) - AAA authorization login local (default) - AAA accounting login disable (default) + admin@vlab-01:~$ show aaa | grep -Po "AAA authentication login \K.*" + local (default) """ output = duthost.shell('show aaa | grep -Po "AAA {} {} \K.*"'.format(aaa_type, option)) - logger.info("{}".format(output)) + pytest_assert(not output['rc'], "Failed to grep AAA {}".format(option) ) - pytest_assert(output['stdout'] == value, - "AAA {} {} failed to apply".format(aaa_type, option) + return output['stdout'] + +def aaa_add_init_config_without_table(duthost): + """ Add initial config not containing AAA table + + Configure to default setting which doesn't contain AAA table + Sample configDB without table: + admin@vlab-01:~$ show run all | grep AAA + admin@vlab-01:~$ + """ + cmds = 'sonic-db-cli CONFIG_DB keys "AAA|*" | xargs -r sonic-db-cli CONFIG_DB del' + + output = duthost.shell(cmds) + pytest_assert(not output['rc'], + "AAA init config failed" ) -def aaa_add_init_config(duthost): - """ Add initial config for AAA +def aaa_add_init_config_with_table(duthost): + """ Add initial config containing AAA table Though AAA has default value in setup. But the config does not included in configDB. So to make change on AAA table, the init @@ -88,35 +96,36 @@ def aaa_add_init_config(duthost): "AAA init config failed" ) -def verify_tacacs_global_config(duthost, tacacs_global_type, value): - """ Verify tacacs global config match with expected value +def get_tacacs_global_type_value(duthost, tacacs_global_type): + """ Get tacacs global config by type Sample output in t0: - admin@vlab-01:~/tacacs$ show tacacs - TACPLUS global auth_type pap (default) - TACPLUS global timeout 5 (default) - TACPLUS global passkey (default) - - TACPLUS_SERVER address 10.0.0.8 - priority 1 - tcp_port 49 - - TACPLUS_SERVER address 10.0.0.9 - priority 1 - tcp_port 49 - + admin@vlab-01:~$ show tacacs | grep -Po "TACPLUS global auth_type \K.*" + pap (default) """ output = duthost.shell('show tacacs | grep -Po "TACPLUS global {} \K.*"'.format(tacacs_global_type)) - logger.info("{}".format(output)) + pytest_assert(not output['rc'], "Failed to grep TACACS {}".format(tacacs_global_type) ) - pytest_assert(output['stdout'] == value, - "TACACS global {} failed to apply".format(tacacs_global_type) + return output['stdout'] + +def tacacs_add_init_config_without_table(duthost): + """ Add initial config not containing tacacs table + + Sample configDB without table: + admin@vlab-01:~/cacl$ show run all | grep -w TACPLUS + admin@vlab-01:~$ + """ + cmds = 'sonic-db-cli CONFIG_DB keys "TACPLUS|*" | xargs -r sonic-db-cli CONFIG_DB del' + + output = duthost.shell(cmds) + pytest_assert(not output['rc'], + "TACACS init config failed" ) -def tacacs_add_init_config(duthost): - """ Add initial config for tacacs +def tacacs_add_init_config_with_table(duthost): + """ Add initial config containing tacacs table Same with AAA config. The default tacacs config does not included in configDB. So to make change, the initial @@ -172,8 +181,9 @@ def parse_tacacs_server(duthost): tacacs_server = {} address = "" else: - pytest_assert(len(line.strip().split(" ")) == 2) - k, v = line.strip().split(" ") + fields = line.strip().split(" ") + pytest_assert(len(fields) == 2) + k, v = fields[0], fields[1] tacacs_server[k] = v if address: @@ -207,7 +217,11 @@ def parse_tacacs_server(duthost): ]) def test_aaa_tc1_add_config(duthost, aaa_type, aaa_sub_options): """ Test AAA add initial config for its sub type + + This test is for default setting when configDB doesn't + contian AAA table. So we remove AAA config at first. """ + aaa_add_init_config_without_table(duthost) json_patch = [ { "op": "add", @@ -226,14 +240,17 @@ def test_aaa_tc1_add_config(duthost, aaa_type, aaa_sub_options): expect_op_success(duthost, output) for option, value in aaa_sub_options.items(): - verify_aaa_sub_options(duthost, aaa_type, option, value) + pytest_assert( + get_aaa_sub_options_value(duthost, aaa_type, option) == value, + "Failed to verify AAA {} {}".format(aaa_type, option) + ) finally: delete_tmpfile(duthost, tmpfile) def test_aaa_tc2_replace(duthost): """ Test replace option value in each AAA sub type """ - aaa_add_init_config(duthost) + aaa_add_init_config_with_table(duthost) json_patch = [ { "op": "replace", @@ -260,14 +277,17 @@ def test_aaa_tc2_replace(duthost): expect_op_success(duthost, output) for aaa_type in AAA_CATEGORY: - verify_aaa_sub_options(duthost, aaa_type, "login", "tacacs+") + pytest_assert( + get_aaa_sub_options_value(duthost, aaa_type, "login") == "tacacs+", + "Failed to verify AAA {} {}".format(aaa_type, "login") + ) finally: delete_tmpfile(duthost, tmpfile) def test_aaa_tc3_add_duplicate(duthost): """ Test add duplicate config in AAA sub type """ - aaa_add_init_config(duthost) + aaa_add_init_config_with_table(duthost) json_patch = [ { "op": "add", @@ -294,14 +314,17 @@ def test_aaa_tc3_add_duplicate(duthost): expect_op_success(duthost, output) for aaa_type in AAA_CATEGORY: - verify_aaa_sub_options(duthost, aaa_type, "login", "local") + pytest_assert( + get_aaa_sub_options_value(duthost, aaa_type, "login") == "local", + "Failed to verify AAA {} {}".format(aaa_type, "login") + ) finally: delete_tmpfile(duthost, tmpfile) def test_aaa_tc4_remove(duthost): """ Test remove AAA config check if it returns to default setup """ - aaa_add_init_config(duthost) + aaa_add_init_config_with_table(duthost) json_patch = [ { "op": "remove", @@ -331,7 +354,11 @@ def test_aaa_tc4_remove(duthost): def test_tacacs_global_tc5_add_config(duthost): """ Test add tacacs global config + + This test is for default setting when configDB doesn't + contian TACACS table. So we remove TACACS config at first. """ + tacacs_add_init_config_without_table(duthost) TACACS_ADD_CONFIG = { "auth_type": "login", "passkey": "testing123", @@ -354,7 +381,10 @@ def test_tacacs_global_tc5_add_config(duthost): expect_op_success(duthost, output) for tacacs_global_type, value in TACACS_ADD_CONFIG.items(): - verify_tacacs_global_config(duthost, tacacs_global_type, value) + pytest_assert( + get_tacacs_global_type_value(duthost, tacacs_global_type) == value, + "TACACS global {} failed to apply".format(tacacs_global_type) + ) finally: delete_tmpfile(duthost, tmpfile) @@ -395,7 +425,7 @@ def test_tacacs_global_tc6_invalid_input(duthost, tacacs_global_type, invalid_in def test_tacacs_global_tc7_duplicate_input(duthost): """ Test tacacs global duplicate input """ - tacacs_add_init_config(duthost) + tacacs_add_init_config_with_table(duthost) TACACS_ADD_CONFIG = { "auth_type": "pap", @@ -419,14 +449,17 @@ def test_tacacs_global_tc7_duplicate_input(duthost): expect_op_success(duthost, output) for tacacs_global_type, value in TACACS_ADD_CONFIG.items(): - verify_tacacs_global_config(duthost, tacacs_global_type, value) + pytest_assert( + get_tacacs_global_type_value(duthost, tacacs_global_type) == value, + "TACACS global {} failed to apply".format(tacacs_global_type) + ) finally: delete_tmpfile(duthost, tmpfile) def test_tacacs_global_tc8_remove(duthost): """ Test tacacs global config removal """ - tacacs_add_init_config(duthost) + tacacs_add_init_config_with_table(duthost) json_patch = [ { From ffd7cd1393fddf4e87ce693446c60ff4213a1810 Mon Sep 17 00:00:00 2001 From: Jingwen Xie Date: Fri, 21 Jan 2022 06:23:24 +0000 Subject: [PATCH 3/4] small issue --- tests/generic_config_updater/test_aaa.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/generic_config_updater/test_aaa.py b/tests/generic_config_updater/test_aaa.py index 6d4dad27592..4e220e9c871 100644 --- a/tests/generic_config_updater/test_aaa.py +++ b/tests/generic_config_updater/test_aaa.py @@ -610,7 +610,7 @@ def test_tacacs_server_tc12_add_duplicate(duthost): expect_op_success(duthost, output) tacacs_servers = parse_tacacs_server(duthost) - pytest_assert('10.0.0.9' in tacacs_servers, + pytest_assert('10.0.0.8' in tacacs_servers, "tacacs server add duplicate failed." ) From 50308799c30f6454a573bd6def7d4013259f6e4c Mon Sep 17 00:00:00 2001 From: Jingwen Xie Date: Mon, 24 Jan 2022 02:45:43 +0000 Subject: [PATCH 4/4] apply aaa test to all topo --- tests/generic_config_updater/test_aaa.py | 94 +++++++++++++++++------- 1 file changed, 68 insertions(+), 26 deletions(-) diff --git a/tests/generic_config_updater/test_aaa.py b/tests/generic_config_updater/test_aaa.py index 4e220e9c871..904ddd88759 100644 --- a/tests/generic_config_updater/test_aaa.py +++ b/tests/generic_config_updater/test_aaa.py @@ -7,12 +7,13 @@ from tests.generic_config_updater.gu_utils import create_checkpoint, delete_checkpoint, rollback_or_reload pytestmark = [ - pytest.mark.topology('t0'), + pytest.mark.topology('any'), ] logger = logging.getLogger(__name__) AAA_CATEGORY = ["authentication", "authorization", "accounting"] +DEFAULT_TACACS_SERVER = "100.127.20.21" @pytest.fixture(autouse=True) def setup_env(duthosts, rand_one_dut_hostname): @@ -151,10 +152,36 @@ def tacacs_add_init_config_with_table(duthost): "TACACS init config failed" ) +def cleanup_tacacs_server(duthost): + """ Clean up tacacs server + """ + cmds = 'sonic-db-cli CONFIG_DB keys "TACPLUS_SERVER|*" | xargs -r sonic-db-cli CONFIG_DB del' + + output = duthost.shell(cmds) + pytest_assert(not output['rc'], + "Cleanup TACPLUS_SERVER failed" + ) + +def add_tacacs_server(duthost, server_ip): + """ tc13 requires at least one existed server to do the removal + + Even the server added is existed, it won't be treated as error. + Sample output: + admin@vlab-01:~$ sudo config tacacs add 100.127.20.21 + server 100.127.20.21 already exists + eadmin@vlab-01:~$ echo $? + 0 + """ + cmds = 'config tacacs add {}'.format(server_ip) + output = duthost.shell(cmds) + pytest_assert(not output['rc'], + "Add tacacs server failed" + ) + def parse_tacacs_server(duthost): """ Parse tacacs server - Sample output in t0: + Sample output in kvm t0: {u'10.0.0.9': {u'priority': u'1', u'tcp_port': u'49'}, u'10.0.0.8': {u'priority': u'1', u'tcp_port': u'49'}} """ @@ -198,7 +225,7 @@ def parse_tacacs_server(duthost): "debug": "True", "failthrough": "True", "fallback": "True", - "login": "local,tacacs+", + "login": "tacacs+", "trace": "True" } ), @@ -485,11 +512,16 @@ def test_tacacs_global_tc8_remove(duthost): finally: delete_tmpfile(duthost, tmpfile) -@pytest.mark.parametrize("ip_address", ["10.0.0.10", "fc10::10"]) -def test_tacacs_server_tc9_add(duthost, ip_address): +@pytest.mark.parametrize("ip_address", ["100.127.20.21", "fc10::21"]) +def test_tacacs_server_tc9_add_init(duthost, ip_address): """ Test tacacs server addition + + Due to kvm t0 and testbed t0 has different tacacs server predefined, + so we cleanup tacacs servers then test on mannual setup. """ - TACACS_SERVER_ADD = { + cleanup_tacacs_server(duthost) + + TACACS_SERVER_OPTION = { "auth_type": "login", "passkey": "testing123", "priority": "10", @@ -499,8 +531,11 @@ def test_tacacs_server_tc9_add(duthost, ip_address): json_patch = [ { "op": "add", - "path": "/TACPLUS_SERVER/{}".format(ip_address), - "value": TACACS_SERVER_ADD + "path": "/TACPLUS_SERVER", + "value": { + ip_address: + TACACS_SERVER_OPTION + } } ] @@ -516,7 +551,7 @@ def test_tacacs_server_tc9_add(duthost, ip_address): "tacacs server failed to add to config." ) tacacs_server = tacacs_servers[ip_address] - for opt, value in TACACS_SERVER_ADD.items(): + for opt, value in TACACS_SERVER_OPTION.items(): pytest_assert(opt in tacacs_server and tacacs_server[opt] == value, "tacacs server failed to add to config completely." ) @@ -525,22 +560,19 @@ def test_tacacs_server_tc9_add(duthost, ip_address): def test_tacacs_server_tc10_add_max(duthost): """ Test tacacs server reach maximum 8 servers - - The t0 has two servers 10.0.0.8 and 10.0.0.9. Need to add 7 more - servers to exceed the max. """ - json_patch = [] - for i in range(10, 17): - server = { + cleanup_tacacs_server(duthost) + + servers = {} + for i in range(10, 19): # Add 9 servers + servers["10.0.0.{}".format(i)] = {} + json_patch = [ + { "op": "add", - "path": "/TACPLUS_SERVER/10.0.0.{}".format(i), - "value": { - "priority": "1", - "tcp_port": "49" - } + "path": "/TACPLUS_SERVER", + "value": servers } - json_patch.append(server) - logger.info(json_patch) + ] tmpfile = generate_tmpfile(duthost) logger.info("tmpfile {}".format(tmpfile)) @@ -569,12 +601,16 @@ def test_tacacs_server_tc11_add_invalid(duthost, tacacs_server_options, invalid_ tcp_port: [0, 65535] timeout: range[1, 60] """ + cleanup_tacacs_server(duthost) + json_patch = [ { "op": "add", - "path": "/TACPLUS_SERVER/10.0.0.10", + "path": "/TACPLUS_SERVER", "value": { - tacacs_server_options: invalid_input + DEFAULT_TACACS_SERVER: { + tacacs_server_options: invalid_input + } } } ] @@ -590,11 +626,15 @@ def test_tacacs_server_tc11_add_invalid(duthost, tacacs_server_options, invalid_ def test_tacacs_server_tc12_add_duplicate(duthost): """ Test tacacs server add duplicate server + + Mannually add DEFAULT_TACACS_SERVER, then add duplicate for test. """ + add_tacacs_server(duthost, DEFAULT_TACACS_SERVER) + json_patch = [ { "op": "add", - "path": "/TACPLUS_SERVER/10.0.0.8", + "path": "/TACPLUS_SERVER/{}".format(DEFAULT_TACACS_SERVER), "value": { "priority": "1", "tcp_port": "49" @@ -610,7 +650,7 @@ def test_tacacs_server_tc12_add_duplicate(duthost): expect_op_success(duthost, output) tacacs_servers = parse_tacacs_server(duthost) - pytest_assert('10.0.0.8' in tacacs_servers, + pytest_assert(DEFAULT_TACACS_SERVER in tacacs_servers, "tacacs server add duplicate failed." ) @@ -620,6 +660,8 @@ def test_tacacs_server_tc12_add_duplicate(duthost): def test_tacacs_server_tc13_remove(duthost): """ Test tacasc server removal """ + add_tacacs_server(duthost, DEFAULT_TACACS_SERVER) + json_patch = [ { "op": "remove",