From 4d16b52e0658ac8ba09f36f8b429211e09183d00 Mon Sep 17 00:00:00 2001 From: Federico Ressi Date: Fri, 25 Sep 2020 13:42:43 +0200 Subject: [PATCH] Fix topology discovery via proxy clients Change-Id: Ifeae3eb236ef88d8e1ac495568de5018cb441ebd --- tobiko/openstack/topology/_connection.py | 35 ++++++++++++++++++------ tobiko/openstack/topology/_topology.py | 6 +++- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/tobiko/openstack/topology/_connection.py b/tobiko/openstack/topology/_connection.py index 97435e348..80f5eabe0 100644 --- a/tobiko/openstack/topology/_connection.py +++ b/tobiko/openstack/topology/_connection.py @@ -36,9 +36,11 @@ class SSHConnection(object): def __init__(self, address: netaddr.IPAddress, ssh_client: typing.Optional[ssh.SSHClientFixture] = None, + proxy_client: typing.Optional[ssh.SSHClientFixture] = None, failure: typing.Optional[Exception] = None): self.address = address self.ssh_client = ssh_client + self.proxy_client = proxy_client self.failure = failure def __repr__(self) -> str: @@ -50,6 +52,8 @@ class SSHConnection(object): yield 'address', self.address if self.ssh_client is not None: yield 'ssh_client', self.ssh_client + if self.proxy_client is not None: + yield 'proxy_client', self.proxy_client if self.failure is not None: yield 'failure', self.failure @@ -76,11 +80,13 @@ class SSHConnectionManager(tobiko.SharedFixture): def connect(self, addresses: typing.List[netaddr.IPAddress], + proxy_client: typing.Optional[ssh.SSHClientFixture] = None, **connect_parameters) -> ssh.SSHClientFixture: if not addresses: raise ValueError(f"'addresses' list is empty: {addresses}") - connections = tobiko.select(self.list_connections(addresses)) + connections = tobiko.select( + self.list_connections(addresses, proxy_client=proxy_client)) try: return connections.with_attributes(is_valid=True).first.ssh_client except tobiko.ObjectNotFound: @@ -89,14 +95,15 @@ class SSHConnectionManager(tobiko.SharedFixture): for connection in connections.with_attributes(failure=None): # connection not tried yet LOG.debug("Establishing SSH connection to " - f"'{connection.address}'") + f"'{connection.address}' (proxy_client={proxy_client})") try: ssh_client = self.ssh_client(connection.address, + proxy_client=proxy_client, **connect_parameters) ssh_client.connect(retry_count=1, connection_attempts=1) except Exception as ex: LOG.debug("Failed establishing SSH connect to " - f"'{connection.address}'.", exc_info=1) + f"'{connection.address}': {ex}") # avoid re-checking again later the same address connection.failure = ex continue @@ -111,17 +118,27 @@ class SSHConnectionManager(tobiko.SharedFixture): raise UreachableSSHServer(addresses=addresses, failures=failures) - def list_connections(self, addresses: typing.List[netaddr.IPAddress]) -> \ - typing.List[SSHConnection]: + def list_connections( + self, addresses: typing.List[netaddr.IPAddress], + proxy_client: typing.Optional[ssh.SSHClientFixture] = None + ) -> typing.List[SSHConnection]: connections = [] for address in addresses: - connections.append(self.get_connection(address)) + connection = self.get_connection(address, + proxy_client=proxy_client) + connections.append(connection) return connections - def get_connection(self, address: netaddr.IPAddress): + def get_connection( + self, address: netaddr.IPAddress, + proxy_client: typing.Optional[ssh.SSHClientFixture] = None + ) -> SSHConnection: tobiko.check_valid_type(address, netaddr.IPAddress) - return self._connections.setdefault(address, - SSHConnection(address)) + if proxy_client is not None: + tobiko.check_valid_type(proxy_client, ssh.SSHClientFixture) + connection = SSHConnection(address, proxy_client=proxy_client) + return self._connections.setdefault((address, proxy_client), + connection) def ssh_client(self, address, username=None, port=None, key_filename=None, **ssh_parameters): diff --git a/tobiko/openstack/topology/_topology.py b/tobiko/openstack/topology/_topology.py index 26c0580a7..5462a0a46 100644 --- a/tobiko/openstack/topology/_topology.py +++ b/tobiko/openstack/topology/_topology.py @@ -202,7 +202,11 @@ class OpenStackTopology(tobiko.SharedFixture): addresses = set(parse.urlparse(endpoint.url).hostname for endpoint in endpoints) for address in addresses: - self.add_node(address=address, group='controller') + try: + self.add_node(address=address, group='controller') + except _connection.UreachableSSHServer as ex: + LOG.debug(f"Unable to SSH to end point address '{address}'. " + f"{ex}") def discover_compute_nodes(self): for hypervisor in nova.list_hypervisors():