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:
parent
3deb8061aa
commit
723f92d022
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,5 +1,7 @@
|
||||
*.py[cod]
|
||||
*.pyc
|
||||
cirros*
|
||||
tempest.conf
|
||||
|
||||
# Packages
|
||||
*.egg*
|
||||
|
24
README.rst
24
README.rst
@ -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>
|
||||
|
||||
|
@ -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 = {
|
||||
|
@ -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))
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user