diff --git a/tacker/common/clients.py b/tacker/common/clients.py index a1d592a90..b92ac3294 100644 --- a/tacker/common/clients.py +++ b/tacker/common/clients.py @@ -47,7 +47,7 @@ class OpenstackClients(object): @property def keystone_session(self): - return self.keystone.session + return self.keystone @property def keystone(self): @@ -79,7 +79,7 @@ class OpenstackSdkConnection(object): user_domain_name=access_info['user_domain_name'], project_domain_name=access_info['project_domain_name']) - session = self.keystone_plugin.initialize_client(**auth).session + session = self.keystone_plugin.initialize_client(**auth) conn = connection.Connection( region_name=access_info.get('region'), diff --git a/tacker/mistral/mistral_client.py b/tacker/mistral/mistral_client.py index b77615e8f..232f88389 100644 --- a/tacker/mistral/mistral_client.py +++ b/tacker/mistral/mistral_client.py @@ -17,7 +17,7 @@ class MistralClient(object): """Mistral Client class for NSD""" def __init__(self, keystone, auth_token): - endpoint = keystone.session.get_endpoint( + endpoint = keystone.get_endpoint( service_type='workflowv2', region_name=None) self.client = mistral_client.client(auth_token=auth_token, diff --git a/tacker/nfvo/drivers/vim/openstack_driver.py b/tacker/nfvo/drivers/vim/openstack_driver.py index 1a771a040..39ea9571c 100644 --- a/tacker/nfvo/drivers/vim/openstack_driver.py +++ b/tacker/nfvo/drivers/vim/openstack_driver.py @@ -120,13 +120,13 @@ class OpenStack_Driver(abstract_vim_driver.VimAbstractDriver, """ verify = 'True' == vim_obj['auth_cred'].get('cert_verify', 'True') auth_url = vim_obj['auth_url'] - keystone_version = NfvoPlugin.validate_keystone_auth_url( + NfvoPlugin.validate_keystone_auth_url( auth_url=auth_url, verify=verify) - auth_cred = self._get_auth_creds(vim_obj, keystone_version) + auth_cred = self._get_auth_creds(vim_obj) return self._initialize_keystone(auth_cred) - def _get_auth_creds(self, vim_obj, keystone_version): + def _get_auth_creds(self, vim_obj): auth_cred = vim_obj['auth_cred'] vim_project = vim_obj['vim_project'] auth_cred['project_id'] = vim_project.get('id') @@ -134,9 +134,8 @@ class OpenStack_Driver(abstract_vim_driver.VimAbstractDriver, auth_cred['project_domain_name'] = vim_project.get( 'project_domain_name') auth_cred['auth_url'] = vim_obj['auth_url'] - if keystone_version not in auth_cred['auth_url']: - auth_cred['auth_url'] = auth_cred['auth_url'] + '/' + \ - keystone_version + if 'v3' not in auth_cred['auth_url']: + auth_cred['auth_url'] = f'{auth_cred["auth_url"]}/v3' return auth_cred def _get_auth_plugin(self, **kwargs): @@ -145,13 +144,12 @@ class OpenStack_Driver(abstract_vim_driver.VimAbstractDriver, return auth_plugin def _initialize_keystone(self, auth): - ks_client = self.keystone.initialize_client(**auth) - return ks_client + return self.keystone.initialize_client(**auth) def _find_regions(self, ks_client): - region_info = ks_client.regions.list() - region_list = [region.id for region in region_info] - return region_list + # TODO(h-asahina): implement this method into KeystoneClient module + resp = ks_client.get('/v3/regions') + return [region['id'] for region in resp.json().get('regions', [])] def discover_placement_attr(self, vim_obj, ks_client): """Fetch VIM placement information @@ -159,11 +157,11 @@ class OpenStack_Driver(abstract_vim_driver.VimAbstractDriver, Attributes can include regions, AZ. """ try: - regions_list = self._find_regions(ks_client) + regions = self._find_regions(ks_client) except (exceptions.Unauthorized, exceptions.BadRequest) as e: LOG.warning("Authorization failed for user") raise nfvo.VimUnauthorizedException(message=e.message) - vim_obj['placement_attr'] = {'regions': regions_list} + vim_obj['placement_attr'] = {'regions': regions} return vim_obj @log.log @@ -305,12 +303,12 @@ class OpenStack_Driver(abstract_vim_driver.VimAbstractDriver, :param client_type: openstack client to initialize :return: initialized client """ - verify = 'True' == vim_obj.get('cert_verify', 'True') or False + verify = 'True' == vim_obj.get('cert_verify', 'True') auth_url = vim_obj['auth_url'] - keystone_version = NfvoPlugin.validate_keystone_auth_url( + NfvoPlugin.validate_keystone_auth_url( auth_url=auth_url, verify=verify) - auth_cred = self._get_auth_creds(vim_obj, keystone_version) + auth_cred = self._get_auth_creds(vim_obj) auth_plugin = self._get_auth_plugin(**auth_cred) sess = session.Session(auth=auth_plugin) return client_type(session=sess) diff --git a/tacker/nfvo/nfvo_plugin.py b/tacker/nfvo/nfvo_plugin.py index ce666d836..0c29a0739 100644 --- a/tacker/nfvo/nfvo_plugin.py +++ b/tacker/nfvo/nfvo_plugin.py @@ -91,18 +91,20 @@ class NfvoPlugin(nfvo_db_plugin.NfvoPluginDb, vnffg_db.VnffgPluginDbMixin, @staticmethod def validate_keystone_auth_url(auth_url, verify): + # NOTE(h-asahina): `verify` will be used as an arg of session to + # validate certificate keystone_obj = keystone.Keystone() auth_url = utils.get_auth_url_v3(auth_url) try: - return keystone_obj.get_version(auth_url, verify) + keystone_obj.get_version(auth_url, verify) except Exception as e: - LOG.error('Keystone Auth URL invalid') + LOG.error(f'Validation Failed for Keystone auth_url: {auth_url}') raise nfvo.VimConnectionException(message=str(e)) def get_auth_dict(self, context): auth = CONF.keystone_authtoken auth_url = utils.get_auth_url_v3(auth.auth_url) - self.validate_keystone_auth_url(auth_url, 'True') + self.validate_keystone_auth_url(auth_url=auth_url, verify=True) return { 'auth_url': auth_url, 'token': context.auth_token, diff --git a/tacker/tests/functional/base.py b/tacker/tests/functional/base.py index 8e4bbd04c..3b6ea7296 100644 --- a/tacker/tests/functional/base.py +++ b/tacker/tests/functional/base.py @@ -29,9 +29,9 @@ from oslo_log import log as logging from oslo_serialization import jsonutils from tempest.lib import base +from tacker.common import clients from tacker.plugins.common import constants as evt_constants from tacker.tests import constants -from tacker.tests.functional import clients from tacker.tests.utils import read_file from tacker import version @@ -175,20 +175,18 @@ class BaseTackerTest(base.BaseTestCase): data['project_domain_name'] = domain_name return clients.OpenstackClients(auth_attr=data).heat + @classmethod def blazarclient(cls, vim_conf_file=None): data = cls.get_credentials(vim_conf_file) domain_name = data.pop('domain_name') data['user_domain_name'] = domain_name data['project_domain_name'] = domain_name - auth_ses = clients.OpenstackClients(auth_attr=data).keystone_session - args = { - 'session': auth_ses, - 'service_type': 'reservation', - 'interface': 'public', - 'region_name': 'RegionOne', - } - client = blazar_client.Client(**args) - return client + auth_ses = (clients.OpenstackClients(auth_attr=data) + .keystone_session.session) + return blazar_client.Client(session=auth_ses, + service_type='reservation', + interface='public', + region_name='RegionOne') @classmethod def glanceclient(cls, vim_conf_file=None): diff --git a/tacker/tests/functional/clients.py b/tacker/tests/functional/clients.py deleted file mode 100644 index 1f6c282bf..000000000 --- a/tacker/tests/functional/clients.py +++ /dev/null @@ -1,50 +0,0 @@ -# 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 heatclient import client as heatclient -from tacker.tests.functional import keystone - - -class OpenstackClients(object): - - def __init__(self, auth_attr, region_name=None): - super(OpenstackClients, self).__init__() - self.keystone_plugin = keystone.Keystone() - self.heat_client = None - self.keystone_client = None - self.region_name = region_name - self.auth_attr = auth_attr - - def _keystone_client(self): - return self.keystone_plugin.initialize_client(**self.auth_attr) - - def _heat_client(self): - endpoint = self.keystone_session.get_endpoint( - service_type='orchestration', region_name=self.region_name) - return heatclient.Client('1', endpoint=endpoint, - session=self.keystone_session) - - @property - def keystone_session(self): - return self.keystone.session - - @property - def keystone(self): - if not self.keystone_client: - self.keystone_client = self._keystone_client() - return self.keystone_client - - @property - def heat(self): - if not self.heat_client: - self.heat_client = self._heat_client() - return self.heat_client diff --git a/tacker/tests/unit/nfvo/drivers/vim/test_openstack_driver.py b/tacker/tests/unit/nfvo/drivers/vim/test_openstack_driver.py index d06fcc6f4..fcd5edc19 100644 --- a/tacker/tests/unit/nfvo/drivers/vim/test_openstack_driver.py +++ b/tacker/tests/unit/nfvo/drivers/vim/test_openstack_driver.py @@ -129,13 +129,11 @@ class TestOpenstack_Driver(base.TestCase): 'project_domain_name': 'Default'}} def test_register_keystone_v3(self): - regions = [mock_dict({'id': 'RegionOne'})] - attrs = {'regions.list.return_value': regions} - keystone_version = 'v3' + regions = mock_dict(regions=[{'id': 'RegionOne'}]) + attrs = {'get.return_value.json.return_value': regions} mock_ks_client = mock.Mock(**attrs) - self.keystone.get_version.return_value = keystone_version self._test_register_vim(self.vim_obj, mock_ks_client) - mock_ks_client.regions.list.assert_called_once_with() + mock_ks_client.get.assert_called_once_with('/v3/regions') self.keystone.initialize_client.assert_called_once_with( **self.auth_obj) @@ -195,11 +193,11 @@ class TestOpenstack_Driver(base.TestCase): 'fake-secret-uuid') def test_register_vim_invalid_auth(self): - attrs = {'regions.list.side_effect': exceptions.Unauthorized} + attrs = {'get.side_effect': exceptions.Unauthorized} self._test_register_vim_auth(attrs) def test_register_vim_missing_auth(self): - attrs = {'regions.list.side_effect': exceptions.BadRequest} + attrs = {'get.side_effect': exceptions.BadRequest} self._test_register_vim_auth(attrs) def _test_register_vim_auth(self, attrs): @@ -210,7 +208,7 @@ class TestOpenstack_Driver(base.TestCase): self.assertRaises(nfvo.VimUnauthorizedException, self.openstack_driver.register_vim, self.vim_obj) - mock_ks_client.regions.list.assert_called_once_with() + mock_ks_client.get.assert_called_once_with('/v3/regions') self.keystone.initialize_client.assert_called_once_with( **self.auth_obj) diff --git a/tacker/vnfm/keystone.py b/tacker/vnfm/keystone.py index a1081078c..0aac7283b 100644 --- a/tacker/vnfm/keystone.py +++ b/tacker/vnfm/keystone.py @@ -17,10 +17,9 @@ import os from cryptography import fernet -from keystoneauth1 import exceptions +from keystoneauth1 import adapter from keystoneauth1 import identity from keystoneauth1 import session -from keystoneclient import client from oslo_config import cfg from oslo_log import log as logging @@ -37,17 +36,17 @@ class Keystone(object): instance such as version, session and client """ - def get_version(self, base_url=None, verify=True): - try: - keystone_client = client.Client(auth_url=base_url, - verify=verify) - except exceptions.ConnectionError: - raise - return keystone_client.version + def get_version(self, base_url=None, verify=False): + # TODO(h-asahina): Maybe it's better to add error handling here. In + # that case, defiining common exceptions for this module would be also + # better. + sess = session.Session() + return sess.get(base_url, authenticated=False, verify=verify) def get_session(self, auth_plugin, verify): - ses = session.Session(auth=auth_plugin, verify=verify) - return ses + sess = session.Session(auth=auth_plugin, verify=verify) + return adapter.Adapter(session=sess, + service_type='identity') def get_endpoint(self, ses, service_type, region_name=None): return ses.get_endpoint(service_type, region_name) @@ -58,14 +57,7 @@ class Keystone(object): auth_plugin = identity.v3.Token(**kwargs) else: auth_plugin = identity.v3.Password(**kwargs) - ses = self.get_session(auth_plugin=auth_plugin, verify=verify) - # note: Using `interface` may be an appropriate way to control - # the keystone endpoint, e.g., client.Client(DEFAULT_IDENTITY_VERSION, - # session=ses, interface=interface), but it requires the modification - # in the DB schema. Thus, use `endpoint_override` for now. - cli = client.Client(DEFAULT_IDENTITY_VERSION, session=ses, - endpoint_override=auth_plugin.auth_url) - return cli + return self.get_session(auth_plugin=auth_plugin, verify=verify) @staticmethod def create_key_dir(path):