diff --git a/.azure-pipelines/recover_testbed/dut_connection.py b/.azure-pipelines/recover_testbed/dut_connection.py index ca810fdad1d..856ac604b2a 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 bc858ced210..7abb424b6bd 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/ansible/files/sonic_lab_devices.csv b/ansible/files/sonic_lab_devices.csv index a4c8c2dadd5..fec09f681c2 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 4f6b33832d6..c482b0e5320 100644 --- a/ansible/group_vars/lab/secrets.yml +++ b/ansible/group_vars/lab/secrets.yml @@ -19,3 +19,18 @@ console_login: console_conserver: 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"] diff --git a/tests/common/helpers/dut_utils.py b/tests/common/helpers/dut_utils.py index 5954a85e574..0a9d5fc9a8e 100644 --- a/tests/common/helpers/dut_utils.py +++ b/tests/common/helpers/dut_utils.py @@ -13,7 +13,7 @@ from collections import defaultdict from tests.common.connections.console_host import ConsoleHost, CONSOLE_LINECARD from tests.common.connections.linecard_console_conn import UnsupportedPlatformError -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, @@ -559,11 +559,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_device = conn_graph_facts['device_console_link'][dut_hostname]['ConsolePort']['peerdevice'] console_type = f"console_{console_type}" + update_console_creds(creds, console_auth_type) if console_menu_type and console_menu_type.lower() != "n/a": console_menu_type = f"{console_type}_{console_menu_type}" @@ -655,7 +657,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 7faaf9211e0..3bb63dbb294 100644 --- a/tests/common/utilities.py +++ b/tests/common/utilities.py @@ -1362,6 +1362,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