From 0a6692bd45343218aacb0a66250ec67fbf3beee2 Mon Sep 17 00:00:00 2001 From: Dashuai Zhang Date: Tue, 3 Mar 2026 00:38:33 +1100 Subject: [PATCH 1/2] add authType Signed-off-by: Dashuai Zhang # Conflicts: # tests/common/helpers/dut_utils.py --- .azure-pipelines/recover_testbed/dut_connection.py | 9 +++++++-- ansible/devutils | 5 ++++- tests/common/helpers/dut_utils.py | 9 +++++++-- tests/common/utilities.py | 11 +++++++++++ 4 files changed, 29 insertions(+), 5 deletions(-) diff --git a/.azure-pipelines/recover_testbed/dut_connection.py b/.azure-pipelines/recover_testbed/dut_connection.py index ca810fdad1..856ac604b2 100644 --- a/.azure-pipelines/recover_testbed/dut_connection.py +++ b/.azure-pipelines/recover_testbed/dut_connection.py @@ -14,6 +14,7 @@ from tests.common.connections.console_host import ConsoleHost from paramiko.ssh_exception import AuthenticationException from constants import RC_SSH_FAILED, RC_PASSWORD_FAILED +from tests.common.utilities import update_console_creds _self_dir = os.path.dirname(os.path.abspath(__file__)) base_path = os.path.realpath(os.path.join(_self_dir, "../..")) @@ -71,6 +72,8 @@ def creds_on_dut(sonichost): if cred_var in creds: creds[cred_var] = jinja2.Template(creds[cred_var]).render(**hostvars) + creds["console_login_options"] = hostvars.get("console_login_options", {}) + if "console_login" not in list(hostvars.keys()): console_login_creds = {} else: @@ -86,10 +89,11 @@ def creds_on_dut(sonichost): def get_console_info(sonichost, conn_graph_facts): console_host = conn_graph_facts['device_console_info'][sonichost.hostname]['ManagementIp'] + auth_type = conn_graph_facts['device_console_info'][sonichost.hostname].get('AuthType', "") console_port = conn_graph_facts['device_console_link'][sonichost.hostname]['ConsolePort']['peerport'] console_type = conn_graph_facts['device_console_link'][sonichost.hostname]['ConsolePort']['type'] - return console_host, console_port, console_type + return console_host, console_port, console_type, auth_type def get_ssh_info(sonichost): @@ -103,7 +107,7 @@ def get_ssh_info(sonichost): def duthost_console(sonichost, conn_graph_facts): - console_host, console_port, console_type = get_console_info(sonichost, conn_graph_facts) + console_host, console_port, console_type, auth_type = get_console_info(sonichost, conn_graph_facts) console_type = "console_" + console_type if "/" in console_host: console_host = console_host.split("/")[0] @@ -112,6 +116,7 @@ def duthost_console(sonichost, conn_graph_facts): sonicadmin_alt_password = sonichost.vm.get_vars( host=sonichost.im.get_hosts(pattern='sonic')[0]).get("ansible_altpassword") creds = creds_on_dut(sonichost) + update_console_creds(creds, auth_type) host = ConsoleHost(console_type=console_type, console_host=console_host, diff --git a/ansible/devutils b/ansible/devutils index 821b4b81aa..8bba56823a 100755 --- a/ansible/devutils +++ b/ansible/devutils @@ -18,6 +18,7 @@ sys.path.append("..") from tests.common.plugins.pdu_controller.pdu_manager import pdu_manager_factory # noqa E402 from tests.common.connections.console_host import ConsoleHost # noqa E402 +from tests.common.utilities import update_console_creds # noqa: E402 g_inv_mgr = None g_task_runner = None @@ -161,6 +162,7 @@ def get_console_info_from_conn_graph(hostname): console_info = {} if hostname in g_conn_graph_facts['device_console_info'] and g_conn_graph_facts['device_console_info'][hostname]: console_info['console_type'] = g_conn_graph_facts['device_console_info'][hostname]['Protocol'] + console_info['auth_type'] = g_conn_graph_facts['device_console_info'][hostname].get('AuthType', '') console_info['console_host'] = g_conn_graph_facts['device_console_info'][hostname]['ManagementIp'] console_info['console_port'] = g_conn_graph_facts['device_console_link'][hostname]['ConsolePort']['peerport'] return console_info @@ -171,7 +173,7 @@ def get_console_info_from_inventory(attrs): Read console info from inventory file. This should be a fallback of get_console_info_from_conn_graph. """ console_info = {} - keys = ['console_type', 'console_host', 'console_port'] + keys = ['console_type', 'console_host', 'console_port', 'auth_type'] for k in keys: if k in attrs: console_info[k] = attrs[k] @@ -270,6 +272,7 @@ def action_console(parameters): hosts = parameters['hosts'] for hostname, vars in hosts.items(): console_info = get_console_info(hostname, vars) + update_console_creds(vars['creds'], console_info.get('auth_type', '')) if not console_info: continue console_host = ConsoleHost(console_type=console_info['console_type'], diff --git a/tests/common/helpers/dut_utils.py b/tests/common/helpers/dut_utils.py index f4d8d0142d..5f86e8d0c8 100644 --- a/tests/common/helpers/dut_utils.py +++ b/tests/common/helpers/dut_utils.py @@ -11,7 +11,7 @@ from tests.common.errors import RunAnsibleModuleFail from collections import defaultdict from tests.common.connections.console_host import ConsoleHost -from tests.common.utilities import get_dut_current_passwd +from tests.common.utilities import get_dut_current_passwd, update_console_creds from tests.common.connections.base_console_conn import ( CONSOLE_SSH_CISCO_CONFIG, CONSOLE_SSH_DIGI_CONFIG, @@ -428,11 +428,13 @@ def create_duthost_console(duthost, localhost, conn_graph_facts, creds): # noqa console_host = console_host.split("/")[0] console_port = conn_graph_facts['device_console_link'][dut_hostname]['ConsolePort']['peerport'] console_type = conn_graph_facts['device_console_link'][dut_hostname]['ConsolePort']['type'] + console_auth_type = conn_graph_facts['device_console_info'][dut_hostname].get('AuthType', "") console_menu_type = conn_graph_facts['device_console_link'][dut_hostname]['ConsolePort']['menu_type'] console_username = conn_graph_facts['device_console_link'][dut_hostname]['ConsolePort']['proxy'] console_type = f"console_{console_type}" console_menu_type = f"{console_type}_{console_menu_type}" + update_console_creds(creds, console_auth_type) # console password and sonic_password are lists, which may contain more than one password sonicadmin_alt_password = localhost.host.options['variable_manager']._hostvars[dut_hostname].get( @@ -518,7 +520,10 @@ def creds_on_dut(duthost): for cred_var in cred_vars: if cred_var in creds: creds[cred_var] = jinja2.Template(creds[cred_var]).render(**hostvars) - # load creds for console + + creds["console_login_options"] = hostvars.get("console_login_options", {}) + + # load default creds for console if "console_login" not in list(hostvars.keys()): console_login_creds = {} else: diff --git a/tests/common/utilities.py b/tests/common/utilities.py index 01e34f87a6..13bd24f546 100644 --- a/tests/common/utilities.py +++ b/tests/common/utilities.py @@ -1221,6 +1221,17 @@ def get_dut_current_passwd(ipv4_address, ipv6_address, username, passwords): return passwd +def update_console_creds(creds, console_auth_type): + # Load creds for console based on auth type (e.g. tacacs, xpme) + if console_auth_type and console_auth_type in creds.get("console_login_options", {}): + console_login_creds = creds["console_login_options"][console_auth_type] + creds["console_user"] = {} + creds["console_password"] = {} + for k, v in list(console_login_creds.items()): + creds["console_user"][k] = v["user"] + creds["console_password"][k] = v["passwd"] + + def check_msg_in_syslog(duthost, log_msg): """ Checks for a given log message after the last start-LogAnalyzer message in syslog From c8077fee498c3ad9f16f290d31c6fe5e52c1d6f0 Mon Sep 17 00:00:00 2001 From: Dashuai Zhang Date: Fri, 6 Mar 2026 20:42:53 +1100 Subject: [PATCH 2/2] add lab examples Signed-off-by: Dashuai Zhang --- ansible/files/sonic_lab_devices.csv | 6 +++--- ansible/group_vars/lab/secrets.yml | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/ansible/files/sonic_lab_devices.csv b/ansible/files/sonic_lab_devices.csv index a4c8c2dadd..fec09f681c 100644 --- a/ansible/files/sonic_lab_devices.csv +++ b/ansible/files/sonic_lab_devices.csv @@ -1,10 +1,10 @@ -Hostname,ManagementIp,HwSku,Type,Protocol,Os +Hostname,ManagementIp,HwSku,Type,Protocol,Os,AuthType str-msn2700-01,10.251.0.188/23,Mellanox-2700,DevSonic,,sonic str-7260-10,10.251.0.13/23,Arista-7260QX-64,FanoutLeaf,,sonic str-7260-11,10.251.0.234/23,Arista-7260QX-64,FanoutRoot,,eos str-acs-serv-01,10.251.0.245/23,TestServ,Server,,ubuntu pdu-1,192.168.9.2,Apc,Pdu,snmp, pdu-2,192.168.9.3,Sentry,Pdu,snmp, -console-1,192.168.10.1/23,Cisco,ConsoleServer,ssh,sonic -console-2,192.168.10.2/23,Sonic,ConsoleServer,ssh,cisco +console-1,192.168.10.1/23,Cisco,ConsoleServer,ssh,sonic,tacacs +console-2,192.168.10.2/23,Sonic,ConsoleServer,ssh,cisco, management-1,192.168.10.3/23,Sonic,MgmtTsToRRouter,,sonic diff --git a/ansible/group_vars/lab/secrets.yml b/ansible/group_vars/lab/secrets.yml index 2632e59814..2a26dc03d4 100644 --- a/ansible/group_vars/lab/secrets.yml +++ b/ansible/group_vars/lab/secrets.yml @@ -14,3 +14,18 @@ console_login: console_ssh_menu_ports: user: "root" passwd: ["password1", "password2"] + +console_login_options: + 'tacacs': + console_telnet: + user: "root" + passwd: ["password1", "password2"] + console_ssh: + user: "root" + passwd: ["password1", "password2"] + console_ssh_menu_ports: + user: "root" + passwd: ["password1", "password2"] + console_conserver: + user: "root" + passwd: ["password1", "password2"]