diff --git a/connection/base_executor.py b/connection/base_executor.py index f47867e..40564a3 100644 --- a/connection/base_executor.py +++ b/connection/base_executor.py @@ -35,6 +35,9 @@ class BaseExecutor: def wait_for_connection(self, timeout: timedelta = None): pass + def resolve_ip_address(self): + return "127.0.0.1" + def run(self, command, timeout: timedelta = timedelta(minutes=30)): if TestRun.dut and TestRun.dut.env: command = f"{TestRun.dut.env} && {command}" diff --git a/connection/ssh_executor.py b/connection/ssh_executor.py index 9917df7..a05c34f 100644 --- a/connection/ssh_executor.py +++ b/connection/ssh_executor.py @@ -2,13 +2,14 @@ # Copyright(c) 2019-2021 Intel Corporation # SPDX-License-Identifier: BSD-3-Clause # - +import os +import re import socket import subprocess -import paramiko -import os - from datetime import timedelta, datetime + +import paramiko + from connection.base_executor import BaseExecutor from core.test_run import TestRun, Blocked from test_utils.output import Output @@ -177,3 +178,42 @@ class SshExecutor(BaseExecutor): except Exception: return raise ConnectionError("Timeout occurred before ssh connection loss") + + def resolve_ip_address(self): + user, hostname, port = self.user, self.host, self.port + key_file = None + pattern = br"^Authenticated to.+\[(\d+\.\d+\.\d+\.\d+)].*$" + param, command = " -v", "''" + try: + if self.ssh_config: + host = self.ssh_config.lookup(self.host) + if re.fullmatch(r"^\d+\.\d+\.\d+\.\d+$", host['hostname']): + return host['hostname'] + + if host.get('proxyjump', None) is not None: + proxy = self.ssh_config.lookup(host['proxyjump']) + + user = proxy.get('user', user) + hostname = proxy['hostname'] + port = proxy.get('port', port) + key_file = proxy.get('identityfile', key_file) + command = f"nslookup {host['hostname']}" + pattern = br"^Address:\s+(\d+\.\d+\.\d+\.\d+)\s*$" + param = "" + else: + user = host.get('user', user) + port = host.get('port', port) + key_file = host.get('identityfile', key_file) + user_str = f"{user}@" + identity_str = f" -i {os.path.abspath(key_file[0])}" if key_file else "" + + completed_process = subprocess.run( + f"ssh{identity_str} -p {port}{param} {user_str}{hostname} {command}", + shell=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + timeout=30) + matches = re.findall(pattern, completed_process.stdout + completed_process.stderr, re.MULTILINE) + return matches[-1].decode('utf-8') + except: + return None diff --git a/core/test_run_utils.py b/core/test_run_utils.py index ab0c26f..889c490 100644 --- a/core/test_run_utils.py +++ b/core/test_run_utils.py @@ -171,6 +171,7 @@ def __setup(cls): except Exception as ex: raise Exception(f"Failed to setup DUT instance:\n" f"{str(ex)}\n{traceback.format_exc()}") + cls.dut.ip = cls.dut.ip or cls.executor.resolve_ip_address() cls.__setup_disks() TestRun.LOGGER.info(f"Re-seeding random number generator with seed: {cls.random_seed}") diff --git a/test_utils/dut.py b/test_utils/dut.py index 0780dcb..85cd184 100644 --- a/test_utils/dut.py +++ b/test_utils/dut.py @@ -21,7 +21,7 @@ class Dut: self.spider = dut_info['spider'] if 'spider' in dut_info else None self.wps = dut_info['wps'] if 'wps' in dut_info else None self.env = dut_info['env'] if 'env' in dut_info else None - self.ip = dut_info['ip'] if 'ip' in dut_info else "127.0.0.1" + self.ip = dut_info['ip'] if 'ip' in dut_info else None def __str__(self): dut_str = f'ip: {self.ip}\n'