Use tobiko.conf directory as starting directory for relative paths

Change-Id: I3b3ed64936cacb7e21420943732caa339ebbbdf9
This commit is contained in:
Federico Ressi 2020-01-28 15:41:39 +01:00
parent 2045ba38fb
commit 710146be61
8 changed files with 79 additions and 17 deletions

2
.gitignore vendored
View File

@ -38,3 +38,5 @@ Pipfile.lock
# Tobiko configuration file # Tobiko configuration file
tobiko.conf tobiko.conf
clouds.yaml
ssh_config

View File

@ -14,6 +14,7 @@
from __future__ import absolute_import from __future__ import absolute_import
from tobiko.common import _asserts from tobiko.common import _asserts
from tobiko.common import _config
from tobiko.common import _detail from tobiko.common import _detail
from tobiko.common import _exception from tobiko.common import _exception
from tobiko.common import _fixture from tobiko.common import _fixture
@ -31,6 +32,10 @@ details_content = _detail.details_content
FailureException = _asserts.FailureException FailureException = _asserts.FailureException
fail = _asserts.fail fail = _asserts.fail
tobiko_config = _config.tobiko_config
tobiko_config_dir = _config.tobiko_config_dir
tobiko_config_path = _config.tobiko_config_path
TobikoException = _exception.TobikoException TobikoException = _exception.TobikoException
check_valid_type = _exception.check_valid_type check_valid_type = _exception.check_valid_type
exc_info = _exception.exc_info exc_info = _exception.exc_info

43
tobiko/common/_config.py Normal file
View File

@ -0,0 +1,43 @@
# Copyright 2020 Red Hat
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from __future__ import absolute_import
import os
from tobiko.common import _fixture
class TobikoConfigFicture(_fixture.SharedFixture):
config = None
def setup_fixture(self):
from tobiko import config
self.config = config.CONF.tobiko
def tobiko_config():
return _fixture.setup_fixture(TobikoConfigFicture).config
def tobiko_config_dir():
return tobiko_config().config_dir
def tobiko_config_path(path):
path = os.path.expanduser(path)
if not os.path.isabs(path):
path = os.path.join(tobiko_config_dir(), path)
return os.path.realpath(path)

View File

@ -160,8 +160,9 @@ def init_tobiko_config(default_config_dirs=None, default_config_files=None,
CONF.set_source('tobiko', conf) CONF.set_source('tobiko', conf)
# expand and normalize log_file and log_dir names # expand and normalize log_file and log_dir names
conf.config_dir = os.path.realpath(conf.find_file('.'))
log_dir = conf.log_dir or conf.config_dir
log_file = conf.log_file or 'tobiko.log' log_file = conf.log_file or 'tobiko.log'
log_dir = conf.log_dir or conf.find_file('.')
log_path = os.path.realpath(os.path.expanduser( log_path = os.path.realpath(os.path.expanduser(
os.path.join(log_dir, log_file))) os.path.join(log_dir, log_file)))
conf.log_dir = os.path.dirname(log_path) conf.log_dir = os.path.dirname(log_path)

View File

@ -42,23 +42,21 @@ class DefaultCloudsFileConfig(tobiko.SharedFixture):
clouds_files = None clouds_files = None
def setup_fixture(self): def setup_fixture(self):
from tobiko import config keystone_conf = tobiko.tobiko_config().keystone
CONF = config.CONF
keystone_conf = CONF.tobiko.keystone
self.cloud_name = keystone_conf.cloud_name self.cloud_name = keystone_conf.cloud_name
self.clouds_file_dirs = [ self.clouds_file_dirs = keystone_conf.clouds_file_dirs
os.path.realpath(os.path.expanduser(d))
for d in keystone_conf.clouds_file_dirs]
self.clouds_file_names = keystone_conf.clouds_file_names self.clouds_file_names = keystone_conf.clouds_file_names
self.clouds_files = self.list_cloud_files() self.clouds_files = self.list_cloud_files()
def list_cloud_files(self): def list_cloud_files(self):
cloud_files = [] cloud_files = []
for directory in self.clouds_file_dirs: for directory in self.clouds_file_dirs:
directory = os.path.realpath(os.path.expanduser(directory)) directory = tobiko.tobiko_config_path(directory)
for file_name in self.clouds_file_names: if os.path.isdir(directory):
file_name = os.path.join(directory, file_name) for file_name in self.clouds_file_names:
cloud_files.append(file_name) file_name = os.path.join(directory, file_name)
if os.path.isfile(file_name):
cloud_files.append(file_name)
return cloud_files return cloud_files

View File

@ -21,6 +21,7 @@ from oslo_log import log
import yaml import yaml
import tobiko import tobiko
import testtools
LOG = log.getLogger(__name__) LOG = log.getLogger(__name__)
@ -267,17 +268,30 @@ class DefaultKeystoneCredentialsFixture(KeystoneCredentialsFixture):
fixtures = DEFAULT_KEYSTONE_CREDENTIALS_FIXTURES fixtures = DEFAULT_KEYSTONE_CREDENTIALS_FIXTURES
def get_credentials(self): def get_credentials(self):
errors = []
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:
LOG.exception("Error setting up fixture %r", fixture) LOG.debug("Error getting cretentials from %r", fixture)
errors.append(tobiko.exc_info())
continue continue
if credentials: if credentials:
LOG.info("Got default credentials from fixture %r: %r", LOG.info("Got default credentials from fixture %r: %r",
fixture, credentials) fixture, credentials)
return credentials return credentials
else:
LOG.debug('Got no credentials from %r', fixture)
if len(errors) == 1:
errors[0].reraise()
elif errors:
raise testtools.MultipleExceptions(errors)
raise ValueError("No such credentials from any of: \n " +
'\n '.join(tobiko.get_fixture_name(fixture)
for fixture in self.fixtures))
def api_version_from_url(auth_url): def api_version_from_url(auth_url):

View File

@ -44,9 +44,7 @@ class SSHDefaultConfigFixture(tobiko.SharedFixture):
conf = None conf = None
def setup_fixture(self): def setup_fixture(self):
from tobiko import config self.conf = tobiko.tobiko_config().ssh
CONF = config.CONF
self.conf = CONF.tobiko.ssh
def __getattr__(self, name): def __getattr__(self, name):
return getattr(self.conf, name) return getattr(self.conf, name)
@ -72,7 +70,7 @@ class SSHConfigFixture(tobiko.SharedFixture):
def setup_ssh_config(self): def setup_ssh_config(self):
self.config = paramiko.SSHConfig() self.config = paramiko.SSHConfig()
for config_file in self.config_files: for config_file in self.config_files:
config_file = os.path.expanduser(config_file) config_file = tobiko.tobiko_config_path(config_file)
if os.path.exists(config_file): if os.path.exists(config_file):
LOG.debug("Parsing %r config file...", config_file) LOG.debug("Parsing %r config file...", config_file)
with open(config_file) as f: with open(config_file) as f:

View File

@ -34,7 +34,8 @@ OPTIONS = [
default=None, default=None,
help=('Default SSH username')), help=('Default SSH username')),
cfg.ListOpt('config_files', cfg.ListOpt('config_files',
default=['/etc/ssh/ssh_config', '~/.ssh/config'], default=['/etc/ssh/ssh_config', '~/.ssh/config',
'./ssh_config'],
help="Default user SSH configuration files"), help="Default user SSH configuration files"),
cfg.StrOpt('key_file', cfg.StrOpt('key_file',
default='~/.ssh/id_rsa', default='~/.ssh/id_rsa',