Add os-client-config support

This patch adds os-client-config[1] support to python-tempestconf.
Further documentation on usage has been added to the included release
note. In addition, all args from os-client-config are supported.

[1] https://github.com/openstack/os-client-config

Co-Authored-By: Martin Kopec <mkopec@redhat.com>
Closes Issue: #2
Change-Id: I79e7ffb42071abcf1744f21265660fd5cfe0c6a0
This commit is contained in:
Daniel Mellado 2017-01-31 14:14:11 +00:00 committed by Luigi Toscano
parent 3deb8061aa
commit 723f92d022
7 changed files with 169 additions and 16 deletions

2
.gitignore vendored
View File

@ -1,5 +1,7 @@
*.py[cod]
*.pyc
cirros*
tempest.conf
# Packages
*.egg*

View File

@ -83,3 +83,27 @@ RPM Installation (RDO)
``config_tempest.py`` script and it **accepts the same parameters.**
More about new features can be found
`here <https://www.rdoproject.org/blog/2017/02/testing-rdo-with-tempest-new-features-in-ocata/>`__
os-client-config support
~~~~~~~~~~~~~~~~~~~~~~~~
python-tempestconf supports `os-client-config <https://github.com/openstack/os-client-config>`__
so instead of sourcing openstackrc files you can use clouds.yml files. Location where
these files should be stored and syntax which is used to specify cloud.yaml files
can be found `here <https://github.com/openstack/os-client-config#config-files>`__
In case of git usage:
.. code-block:: shell-session
(py27) $ python config_tempest/config_tempest.py --debug --create --os-cloud <name of cloud>
In case of RPM:
.. code-block:: shell-session
$ tempest init testingdir
$ cd testingdir
$ discover-tempest-config --debug --create --os-cloud <name of cloud>

View File

@ -42,6 +42,8 @@ import sys
import tempest.config
import urllib2
import os_client_config
from oslo_config import cfg
from tempest.common import identity
from tempest.lib import auth
from tempest.lib import exceptions
@ -131,7 +133,11 @@ def main():
conf.set(section, key, value, priority=True)
for section, key, value in args.overrides:
conf.set(section, key, value, priority=True)
uri = conf.get("identity", "uri")
if conf.has_option("identity", "uri"):
uri = conf.get("identity", "uri")
else:
uri = args.config['auth'].get('auth_url')
conf.set("identity", "uri", uri)
api_version = 2
v3_only = False
if "v3" in uri and v3_only:
@ -149,7 +155,7 @@ def main():
conf.set("auth", "allow_tenant_isolation", "False")
if args.use_test_accounts:
conf.set("auth", "allow_tenant_isolation", "True")
clients = ClientManager(conf, not args.non_admin)
clients = ClientManager(conf, not args.non_admin, args)
swift_discover = conf.get_defaulted('object-storage-feature-enabled',
'discoverability')
services = api_discovery.discover(
@ -189,7 +195,9 @@ def main():
def parse_arguments():
# TODO(tkammer): add mutual exclusion groups
cloud_config = os_client_config.OpenStackConfig()
parser = argparse.ArgumentParser(__doc__)
cloud_config.register_argparse_arguments(parser, sys.argv)
parser.add_argument('--create', action='store_true', default=False,
help='create default tempest resources')
parser.add_argument('--out', default="etc/tempest.conf",
@ -235,14 +243,14 @@ def parse_arguments():
--remove feature-enabled.api_ext=http,https""")
args = parser.parse_args()
if args.create and args.non_admin:
raise Exception("Options '--create' and '--non-admin' cannot be used"
" together, since creating" " resources requires"
" admin rights")
args.overrides = parse_overrides(args.overrides)
args.remove = parse_values_to_remove(args.remove)
return args
cloud = cloud_config.get_one_cloud(argparse=args)
return cloud
def parse_values_to_remove(options):
@ -343,16 +351,40 @@ class ClientManager(object):
else:
return "v2"
def __init__(self, conf, admin):
def __init__(self, conf, admin, args):
self.identity_version = self.get_identity_version(conf)
username = None
password = None
tenant_name = None
os_client_creds = args.config.get('auth')
if os_client_creds:
username = os_client_creds.get('username')
password = os_client_creds.get('password')
tenant_name = os_client_creds.get('project_name')
if admin:
username = conf.get_defaulted('identity', 'admin_username')
password = conf.get_defaulted('identity', 'admin_password')
tenant_name = conf.get_defaulted('identity', 'admin_tenant_name')
try:
username = conf.get_defaulted('identity', 'admin_username')
password = conf.get_defaulted('identity', 'admin_password')
tenant_name = conf.get_defaulted('identity',
'admin_tenant_name')
except cfg.NoSuchOptError:
LOG.warning(
'Could not load some identity admin options from %s',
DEFAULTS_FILE)
else:
username = conf.get_defaulted('identity', 'username')
password = conf.get_defaulted('identity', 'password')
tenant_name = conf.get_defaulted('identity', 'tenant_name')
try:
# override values only when were set in CLI
if conf.has_option('identity', 'username'):
username = conf.get_defaulted('identity', 'username')
if conf.has_option('identity', 'password'):
password = conf.get_defaulted('identity', 'password')
if conf.has_option('identity', 'tenant_name'):
tenant_name = conf.get_defaulted('identity', 'tenant_name')
except cfg.NoSuchOptError:
LOG.warning(
'Could not load some identity options from %s',
DEFAULTS_FILE)
self.identity_region = conf.get_defaulted('identity', 'region')
default_params = {

View File

@ -19,7 +19,7 @@ from config_tempest import api_discovery as api
from config_tempest import config_tempest as tool
from fixtures import MonkeyPatch
import json
from mock import Mock
import mock
from oslotest import base
@ -44,9 +44,13 @@ class BaseConfigTempestTest(base.BaseTestCase):
conf.set("auth", "allow_tenant_isolation", "False")
return conf
def _get_clients(self, conf, admin=False):
@mock.patch('os_client_config.cloud_config.CloudConfig')
def _get_clients(self, conf, mock_args, admin=False):
"""Returns ClientManager instance"""
return tool.ClientManager(conf, admin=admin)
mock_function = mock.Mock(return_value=False)
func2mock = 'os_client_config.cloud_config.CloudConfig.config.get'
self.useFixture(MonkeyPatch(func2mock, mock_function))
return tool.ClientManager(conf, admin=admin, args=mock_args)
class BaseServiceTest(base.BaseTestCase):
@ -176,7 +180,7 @@ class BaseServiceTest(base.BaseTestCase):
def _fake_service_do_get_method(self, fake_data):
function2mock = 'config_tempest.api_discovery.Service.do_get'
do_get_output = json.dumps(fake_data)
mocked_do_get = Mock()
mocked_do_get = mock.Mock()
mocked_do_get.return_value = do_get_output
self.useFixture(MonkeyPatch(function2mock, mocked_do_get))

View File

@ -102,7 +102,7 @@ class TestClientManager(BaseConfigTempestTest):
mock_function = mock.Mock(return_value={"id": "my_fake_id"})
func2mock = 'config_tempest.config_tempest.identity.get_tenant_by_name'
self.useFixture(MonkeyPatch(func2mock, mock_function))
tool.ClientManager(self.conf, admin=True)
self._get_clients(self.conf, admin=True)
# check if admin credentials were set
admin_tenant = self.conf.get("identity", "admin_tenant_name")
admin_password = self.conf.get("identity", "admin_password")
@ -114,6 +114,87 @@ class TestClientManager(BaseConfigTempestTest):
self.assertEqual(admin_tenant_id, "my_fake_id")
class TestOsClientConfigSupport(BaseConfigTempestTest):
def setUp(self):
super(TestOsClientConfigSupport, self).setUp()
self.conf = self._get_conf("v2.0", "v3")
def _check_credentials(self, manager, username, password, tenant_name):
exp_user = manager.auth_provider.credentials._initial['username']
exp_pass = manager.auth_provider.credentials._initial['password']
exp_tenant = manager.auth_provider.credentials._initial['tenant_name']
self.assertEqual(exp_user, username)
self.assertEqual(exp_pass, password)
self.assertEqual(exp_tenant, tenant_name)
def _override_setup(self):
cloud_args = {
'username': 'cloud_user',
'password': 'cloud_pass',
'project_name': 'cloud_project'
}
mock_function = mock.Mock(return_value=cloud_args)
func2mock = 'os_client_config.cloud_config.CloudConfig.config.get'
self.useFixture(MonkeyPatch(func2mock, mock_function))
mock_function = mock.Mock(return_value={"id": "my_fake_id"})
func2mock = 'config_tempest.config_tempest.identity.get_tenant_by_name'
self.useFixture(MonkeyPatch(func2mock, mock_function))
@mock.patch('os_client_config.cloud_config.CloudConfig')
def test_init_manager_client_config(self, mock_args):
cloud_args = {
'username': 'cloud_user',
'password': 'cloud_pass',
'project_name': 'cloud_project'
}
mock_function = mock.Mock(return_value=cloud_args)
func2mock = 'os_client_config.cloud_config.CloudConfig.config.get'
self.useFixture(MonkeyPatch(func2mock, mock_function))
# remove options, pretend like they aren't set in CLI
self.conf.remove_option('identity', 'username')
self.conf.remove_option('identity', 'password')
self.conf.remove_option('identity', 'tenant_name')
manager = tool.ClientManager(self.conf, admin=False, args=mock_args)
# check if cloud_args credentials were used
self._check_credentials(manager,
cloud_args['username'],
cloud_args['password'],
cloud_args['project_name'])
@mock.patch('os_client_config.cloud_config.CloudConfig')
def test_init_manager_client_config_get_default(self, mock_args):
mock_function = mock.Mock(return_value={})
func2mock = 'os_client_config.cloud_config.CloudConfig.config.get'
self.useFixture(MonkeyPatch(func2mock, mock_function))
manager = tool.ClientManager(self.conf, admin=False, args=mock_args)
# cloud_args is empty => check if default credentials were used
self._check_credentials(manager,
self.conf.get('identity', 'username'),
self.conf.get('identity', 'password'),
self.conf.get('identity', 'tenant_name'))
@mock.patch('os_client_config.cloud_config.CloudConfig')
def test_init_manager_client_config_override(self, mock_args):
self._override_setup()
manager = tool.ClientManager(self.conf, admin=False, args=mock_args)
# check if cloud_args credentials were overrided by the ones set in CLI
self._check_credentials(manager,
self.conf.get('identity', 'username'),
self.conf.get('identity', 'password'),
self.conf.get('identity', 'tenant_name'))
@mock.patch('os_client_config.cloud_config.CloudConfig')
def test_init_manager_client_config_admin_override(self, mock_args):
self._override_setup()
manager = tool.ClientManager(self.conf, admin=True, args=mock_args)
# check if cloud_args credentials were overrided by admin ones
self._check_credentials(manager,
self.conf.get('identity', 'admin_username'),
self.conf.get('identity', 'admin_password'),
self.conf.get('identity', 'admin_tenant_name'))
class TestTempestConf(BaseConfigTempestTest):
def setUp(self):
super(TestTempestConf, self).setUp()

View File

@ -0,0 +1,8 @@
---
features:
- |
Enable os-client-config support [1].
The tempest config tool now is able to support os-client-config env vars
and cloud.yaml support.
[1] https://github.com/openstack/os-client-config

View File

@ -6,3 +6,5 @@ pbr>=1.8 # Apache-2.0
tempest>=14.0.0 # Apache-2.0
requests>=2.10.0,!=2.12.2 # Apache-2.0
os-testr>=0.8.0 # Apache-2.0
os-client-config>=1.26.0 # Apache-2.0
oslo_config>=3.23.0 # Apache-2.0