diff --git a/.gitignore b/.gitignore index 6c0957ce2..42bca0b41 100644 --- a/.gitignore +++ b/.gitignore @@ -40,4 +40,3 @@ Pipfile.lock tobiko.conf clouds.yaml ssh_config -ssh_id* diff --git a/tobiko/openstack/keystone/_credentials.py b/tobiko/openstack/keystone/_credentials.py index 37d4582ec..4a7032ff2 100644 --- a/tobiko/openstack/keystone/_credentials.py +++ b/tobiko/openstack/keystone/_credentials.py @@ -272,8 +272,8 @@ class DefaultKeystoneCredentialsFixture(KeystoneCredentialsFixture): for fixture in self.fixtures: try: credentials = tobiko.setup_fixture(fixture).credentials - except Exception as ex: - LOG.debug("Error getting cretentials from %r: %s", fixture, ex) + except Exception: + LOG.debug("Error getting cretentials from %r", fixture) errors.append(tobiko.exc_info()) continue diff --git a/tobiko/shell/ssh/_client.py b/tobiko/shell/ssh/_client.py index 3bedd9093..c7bd67d31 100644 --- a/tobiko/shell/ssh/_client.py +++ b/tobiko/shell/ssh/_client.py @@ -75,10 +75,7 @@ def positive_int(value): def get_key_filename(value): if isinstance(value, six.string_types): value = [value] - key_filename = [tobiko.tobiko_config_path(v) for v in value] - return [f - for f in key_filename - if os.path.isfile(f)] + return [os.path.realpath(os.path.expanduser(v)) for v in value] SSH_CONNECT_PARAMETERS = { diff --git a/tobiko/shell/ssh/_config.py b/tobiko/shell/ssh/_config.py index b8d9d6888..7613b454c 100644 --- a/tobiko/shell/ssh/_config.py +++ b/tobiko/shell/ssh/_config.py @@ -27,43 +27,38 @@ import tobiko LOG = log.getLogger(__name__) -def ssh_config(config_files=None, **defaults): - if config_files or defaults: - fixture = SSHConfigFixture(config_files=config_files, **defaults) +def ssh_config(config_files=None): + if config_files: + fixture = SSHConfigFixture(config_files=config_files) else: fixture = SSHConfigFixture return tobiko.setup_fixture(fixture) -def ssh_host_config(host=None, config_files=None, **defaults): - return ssh_config(config_files=config_files, **defaults).lookup(host) +def ssh_host_config(host=None, config_files=None): + return ssh_config(config_files=config_files).lookup(host) class SSHDefaultConfigFixture(tobiko.SharedFixture): - def __init__(self, **defaults): - super(SSHDefaultConfigFixture, self).__init__() - self.__dict__.update((key, value) - for key, value in defaults.items() - if value is not None) + conf = None + + def setup_fixture(self): + self.conf = tobiko.tobiko_config().ssh def __getattr__(self, name): - config = tobiko.tobiko_config().ssh - value = getattr(config, name) - self.__dict__[name] = value - return value + return getattr(self.conf, name) class SSHConfigFixture(tobiko.SharedFixture): - default = None + default = tobiko.required_setup_fixture(SSHDefaultConfigFixture) + config_files = None config = None - def __init__(self, config_files=None, **defaults): + def __init__(self, config_files=None): super(SSHConfigFixture, self).__init__() - self.default = tobiko.setup_fixture( - SSHDefaultConfigFixture(**defaults)) if config_files: self.config_files = tuple(config_files) else: @@ -92,8 +87,7 @@ class SSHConfigFixture(tobiko.SharedFixture): return SSHHostConfig(host=host, ssh_config=self, host_config=host_config, - config_files=self.config_files, - default=self.default) + config_files=self.config_files) def __repr__(self): return "{class_name!s}(config_files={config_files!r})".format( @@ -103,8 +97,9 @@ class SSHConfigFixture(tobiko.SharedFixture): class SSHHostConfig(collections.namedtuple('SSHHostConfig', ['host', 'ssh_config', 'host_config', - 'config_files', - 'default'])): + 'config_files'])): + + default = tobiko.required_setup_fixture(SSHDefaultConfigFixture) @property def hostname(self): diff --git a/tobiko/shell/ssh/config.py b/tobiko/shell/ssh/config.py index 4e2e9df77..1c08d13f1 100644 --- a/tobiko/shell/ssh/config.py +++ b/tobiko/shell/ssh/config.py @@ -37,9 +37,9 @@ OPTIONS = [ default=['/etc/ssh/ssh_config', '~/.ssh/config', './ssh_config'], help="Default user SSH configuration files"), - cfg.ListOpt('key_file', - default=['ssh_identity', '~/.ssh/id_rsa', '~/.ssh/id_dsa'], - help="Default SSH private key file"), + cfg.StrOpt('key_file', + default='~/.ssh/id_rsa', + help="Default SSH private key file"), cfg.BoolOpt('allow_agent', default=False, help=("Set to False to disable connecting to the " diff --git a/tobiko/tests/unit/tripleo/test_config.py b/tobiko/tests/unit/tripleo/test_config.py index 4582859aa..a25c107e4 100644 --- a/tobiko/tests/unit/tripleo/test_config.py +++ b/tobiko/tests/unit/tripleo/test_config.py @@ -23,13 +23,14 @@ CONF = config.CONF TIPLEO_CONF = CONF.tobiko.tripleo -class UndercloudConfigTest(unit.TobikoUnitTest): +class TripleoConfigTest(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_ssh_key_filename(self): + self.assertIsInstance(TIPLEO_CONF.undercloud_ssh_key_filename, + six.string_types) + + +class UndercloudConfigTest(unit.TobikoUnitTest): def test_undercloud_ssh_hostname(self): value = TIPLEO_CONF.undercloud_ssh_hostname diff --git a/tobiko/tripleo/config.py b/tobiko/tripleo/config.py index 611573ddb..7a7899165 100644 --- a/tobiko/tripleo/config.py +++ b/tobiko/tripleo/config.py @@ -21,7 +21,7 @@ GROUP_NAME = 'tripleo' OPTIONS = [ # Undercloud options cfg.StrOpt('undercloud_ssh_hostname', - default='undercloud-0', + default=None, help="hostname or IP address to be used to connect to " "undercloud host"), cfg.IntOpt('undercloud_ssh_port', @@ -30,9 +30,9 @@ OPTIONS = [ cfg.StrOpt('undercloud_ssh_username', default='stack', help="Username with access to stackrc and overcloudrc files"), - cfg.ListOpt('undercloud_ssh_key_filename', - default=None, - help="SSH key filename used to login to Undercloud node"), + cfg.StrOpt('undercloud_ssh_key_filename', + default='~/.ssh/id_rsa', + help="SSH key filename used to login to Undercloud node"), cfg.StrOpt('undercloud_rcfile', default='~/stackrc', help="Undercloud RC filename"), diff --git a/tobiko/tripleo/undercloud.py b/tobiko/tripleo/undercloud.py index b37c98be0..e736d3b59 100644 --- a/tobiko/tripleo/undercloud.py +++ b/tobiko/tripleo/undercloud.py @@ -13,10 +13,6 @@ # under the License. from __future__ import absolute_import -import socket - -import netaddr - import tobiko from tobiko import config from tobiko.openstack import keystone @@ -32,12 +28,7 @@ def undercloud_ssh_client(): def undercloud_host_config(): - 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) + return tobiko.setup_fixture(UndecloudHostConfig) def fetch_os_env(rcfile): @@ -60,28 +51,40 @@ class UndercloudKeystoneCredentialsFixture( 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(): host_config = undercloud_host_config() - try: - gethost_by_name(host_config.hostname) - except Exception: - return False - else: - return True + return bool(host_config.hostname) skip_if_missing_undercloud = tobiko.skip_unless( '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(): session = undercloud_keystone_session() return keystone.get_keystone_client(session=session)