Allow to configure undercloud via ssh_config file

This reverts commit 6bebf49459.

Change-Id: If8c218d7fa29414d6af13d2adcf6f0e3bfda24de
This commit is contained in:
Federico Ressi 2020-02-13 08:05:23 +00:00
parent 63ce79daee
commit 8c33b9ac28
8 changed files with 66 additions and 61 deletions

1
.gitignore vendored
View File

@ -40,3 +40,4 @@ Pipfile.lock
tobiko.conf tobiko.conf
clouds.yaml clouds.yaml
ssh_config ssh_config
ssh_id*

View File

@ -272,8 +272,8 @@ class DefaultKeystoneCredentialsFixture(KeystoneCredentialsFixture):
for fixture in self.fixtures: for fixture in self.fixtures:
try: try:
credentials = tobiko.setup_fixture(fixture).credentials credentials = tobiko.setup_fixture(fixture).credentials
except Exception: except Exception as ex:
LOG.debug("Error getting cretentials from %r", fixture) LOG.debug("Error getting cretentials from %r: %s", fixture, ex)
errors.append(tobiko.exc_info()) errors.append(tobiko.exc_info())
continue continue

View File

@ -75,7 +75,10 @@ def positive_int(value):
def get_key_filename(value): def get_key_filename(value):
if isinstance(value, six.string_types): if isinstance(value, six.string_types):
value = [value] value = [value]
return [os.path.realpath(os.path.expanduser(v)) for v in value] key_filename = [tobiko.tobiko_config_path(v) for v in value]
return [f
for f in key_filename
if os.path.isfile(f)]
SSH_CONNECT_PARAMETERS = { SSH_CONNECT_PARAMETERS = {

View File

@ -27,38 +27,43 @@ import tobiko
LOG = log.getLogger(__name__) LOG = log.getLogger(__name__)
def ssh_config(config_files=None): def ssh_config(config_files=None, **defaults):
if config_files: if config_files or defaults:
fixture = SSHConfigFixture(config_files=config_files) fixture = SSHConfigFixture(config_files=config_files, **defaults)
else: else:
fixture = SSHConfigFixture fixture = SSHConfigFixture
return tobiko.setup_fixture(fixture) return tobiko.setup_fixture(fixture)
def ssh_host_config(host=None, config_files=None): def ssh_host_config(host=None, config_files=None, **defaults):
return ssh_config(config_files=config_files).lookup(host) return ssh_config(config_files=config_files, **defaults).lookup(host)
class SSHDefaultConfigFixture(tobiko.SharedFixture): class SSHDefaultConfigFixture(tobiko.SharedFixture):
conf = None def __init__(self, **defaults):
super(SSHDefaultConfigFixture, self).__init__()
def setup_fixture(self): self.__dict__.update((key, value)
self.conf = tobiko.tobiko_config().ssh for key, value in defaults.items()
if value is not None)
def __getattr__(self, name): def __getattr__(self, name):
return getattr(self.conf, name) config = tobiko.tobiko_config().ssh
value = getattr(config, name)
self.__dict__[name] = value
return value
class SSHConfigFixture(tobiko.SharedFixture): class SSHConfigFixture(tobiko.SharedFixture):
default = tobiko.required_setup_fixture(SSHDefaultConfigFixture) default = None
config_files = None config_files = None
config = None config = None
def __init__(self, config_files=None): def __init__(self, config_files=None, **defaults):
super(SSHConfigFixture, self).__init__() super(SSHConfigFixture, self).__init__()
self.default = tobiko.setup_fixture(
SSHDefaultConfigFixture(**defaults))
if config_files: if config_files:
self.config_files = tuple(config_files) self.config_files = tuple(config_files)
else: else:
@ -87,7 +92,8 @@ class SSHConfigFixture(tobiko.SharedFixture):
return SSHHostConfig(host=host, return SSHHostConfig(host=host,
ssh_config=self, ssh_config=self,
host_config=host_config, host_config=host_config,
config_files=self.config_files) config_files=self.config_files,
default=self.default)
def __repr__(self): def __repr__(self):
return "{class_name!s}(config_files={config_files!r})".format( return "{class_name!s}(config_files={config_files!r})".format(
@ -97,9 +103,8 @@ class SSHConfigFixture(tobiko.SharedFixture):
class SSHHostConfig(collections.namedtuple('SSHHostConfig', ['host', class SSHHostConfig(collections.namedtuple('SSHHostConfig', ['host',
'ssh_config', 'ssh_config',
'host_config', 'host_config',
'config_files'])): 'config_files',
'default'])):
default = tobiko.required_setup_fixture(SSHDefaultConfigFixture)
@property @property
def hostname(self): def hostname(self):

View File

@ -37,9 +37,9 @@ OPTIONS = [
default=['/etc/ssh/ssh_config', '~/.ssh/config', default=['/etc/ssh/ssh_config', '~/.ssh/config',
'./ssh_config'], './ssh_config'],
help="Default user SSH configuration files"), help="Default user SSH configuration files"),
cfg.StrOpt('key_file', cfg.ListOpt('key_file',
default='~/.ssh/id_rsa', default=['ssh_identity', '~/.ssh/id_rsa', '~/.ssh/id_dsa'],
help="Default SSH private key file"), help="Default SSH private key file"),
cfg.BoolOpt('allow_agent', cfg.BoolOpt('allow_agent',
default=False, default=False,
help=("Set to False to disable connecting to the " help=("Set to False to disable connecting to the "

View File

@ -23,15 +23,14 @@ CONF = config.CONF
TIPLEO_CONF = CONF.tobiko.tripleo TIPLEO_CONF = CONF.tobiko.tripleo
class TripleoConfigTest(unit.TobikoUnitTest):
def test_ssh_key_filename(self):
self.assertIsInstance(TIPLEO_CONF.undercloud_ssh_key_filename,
six.string_types)
class UndercloudConfigTest(unit.TobikoUnitTest): class UndercloudConfigTest(unit.TobikoUnitTest):
def test_undercloud_ssh_key_filename(self):
value = TIPLEO_CONF.undercloud_ssh_key_filename
if value is not None:
self.assertIsInstance(value,
six.string_types)
def test_undercloud_ssh_hostname(self): def test_undercloud_ssh_hostname(self):
value = TIPLEO_CONF.undercloud_ssh_hostname value = TIPLEO_CONF.undercloud_ssh_hostname
if value is not None: if value is not None:

View File

@ -21,7 +21,7 @@ GROUP_NAME = 'tripleo'
OPTIONS = [ OPTIONS = [
# Undercloud options # Undercloud options
cfg.StrOpt('undercloud_ssh_hostname', cfg.StrOpt('undercloud_ssh_hostname',
default=None, default='undercloud-0',
help="hostname or IP address to be used to connect to " help="hostname or IP address to be used to connect to "
"undercloud host"), "undercloud host"),
cfg.IntOpt('undercloud_ssh_port', cfg.IntOpt('undercloud_ssh_port',
@ -30,9 +30,9 @@ OPTIONS = [
cfg.StrOpt('undercloud_ssh_username', cfg.StrOpt('undercloud_ssh_username',
default='stack', default='stack',
help="Username with access to stackrc and overcloudrc files"), help="Username with access to stackrc and overcloudrc files"),
cfg.StrOpt('undercloud_ssh_key_filename', cfg.ListOpt('undercloud_ssh_key_filename',
default='~/.ssh/id_rsa', default=None,
help="SSH key filename used to login to Undercloud node"), help="SSH key filename used to login to Undercloud node"),
cfg.StrOpt('undercloud_rcfile', cfg.StrOpt('undercloud_rcfile',
default='~/stackrc', default='~/stackrc',
help="Undercloud RC filename"), help="Undercloud RC filename"),

View File

@ -13,6 +13,10 @@
# under the License. # under the License.
from __future__ import absolute_import from __future__ import absolute_import
import socket
import netaddr
import tobiko import tobiko
from tobiko import config from tobiko import config
from tobiko.openstack import keystone from tobiko.openstack import keystone
@ -28,7 +32,12 @@ def undercloud_ssh_client():
def undercloud_host_config(): def undercloud_host_config():
return tobiko.setup_fixture(UndecloudHostConfig) tripleo_config = tobiko.tobiko_config().tripleo
return ssh.ssh_host_config(
host=tripleo_config.undercloud_ssh_hostname,
username=tripleo_config.undercloud_ssh_username,
port=tripleo_config.undercloud_ssh_port,
key_file=tripleo_config.undercloud_ssh_key_filename)
def fetch_os_env(rcfile): def fetch_os_env(rcfile):
@ -51,40 +60,28 @@ class UndercloudKeystoneCredentialsFixture(
return load_undercloud_rcfile() return load_undercloud_rcfile()
def gethost_by_name(hostname):
try:
return netaddr.IPAddress(hostname)
except Exception:
ip_address = socket.gethostbyname(hostname)
return netaddr.IPAddress(ip_address)
def has_undercloud(): def has_undercloud():
host_config = undercloud_host_config() host_config = undercloud_host_config()
return bool(host_config.hostname) try:
gethost_by_name(host_config.hostname)
except Exception:
return False
else:
return True
skip_if_missing_undercloud = tobiko.skip_unless( skip_if_missing_undercloud = tobiko.skip_unless(
'TripleO undercloud hostname not configured', has_undercloud) 'TripleO undercloud hostname not configured', has_undercloud)
class UndecloudHostConfig(tobiko.SharedFixture):
host = 'undercloud-0'
hostname = None
port = None
username = None
key_filename = None
def __init__(self, **kwargs):
super(UndecloudHostConfig, self).__init__()
self._connect_parameters = ssh.gather_ssh_connect_parameters(**kwargs)
def setup_fixture(self):
self.hostname = CONF.tobiko.tripleo.undercloud_ssh_hostname
self.port = CONF.tobiko.tripleo.undercloud_ssh_port
self.username = CONF.tobiko.tripleo.undercloud_ssh_username
self.key_filename = CONF.tobiko.tripleo.undercloud_ssh_key_filename
@property
def connect_parameters(self):
parameters = ssh.gather_ssh_connect_parameters(self)
parameters.update(self._connect_parameters)
return parameters
def undercloud_keystone_client(): def undercloud_keystone_client():
session = undercloud_keystone_session() session = undercloud_keystone_session()
return keystone.get_keystone_client(session=session) return keystone.get_keystone_client(session=session)