diff --git a/lower-constraints.txt b/lower-constraints.txt index 2ee76f28..0af56b54 100644 --- a/lower-constraints.txt +++ b/lower-constraints.txt @@ -39,7 +39,7 @@ munch==2.1.0 netaddr==0.7.18 netifaces==0.10.4 openstackdocstheme==1.18.1 -openstacksdk==0.11.2 +openstacksdk==0.12.0 os-client-config==1.28.0 os-service-types==1.2.0 os-testr==1.0.0 diff --git a/requirements.txt b/requirements.txt index 8de9f272..36974c09 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,7 +6,7 @@ Babel!=2.4.0,>=2.3.4 # BSD pbr!=2.1.0,>=2.0.0 # Apache-2.0 PrettyTable<0.8,>=0.7.2 # BSD keystoneauth1>=3.4.0 # Apache-2.0 -openstacksdk>=0.11.2 # Apache-2.0 +openstacksdk>=0.12.0 # Apache-2.0 osc-lib>=1.8.0 # Apache-2.0 oslo.i18n>=3.15.3 # Apache-2.0 oslo.serialization!=2.19.1,>=2.18.0 # Apache-2.0 diff --git a/senlinclient/plugin.py b/senlinclient/plugin.py index 3a4a08be..ae3caa8b 100644 --- a/senlinclient/plugin.py +++ b/senlinclient/plugin.py @@ -14,8 +14,9 @@ import logging +from openstack.config import cloud_region +from openstack.config import defaults as config_defaults from openstack import connection -from openstack import profile from osc_lib import utils LOG = logging.getLogger(__name__) @@ -26,35 +27,81 @@ API_NAME = 'clustering' CURRENT_API_VERSION = '1.10' -def create_connection(prof=None, **kwargs): - interface = kwargs.pop('interface', None) - region_name = kwargs.pop('region_name', None) +def _make_key(service_type, key): + if not service_type: + return key + else: + service_type = service_type.lower().replace('-', '_') + return "_".join([service_type, key]) + + +def _get_config_from_profile(profile, **kwargs): + # Deal with clients still trying to use legacy profile objects + region_name = None + for service in profile.get_services(): + if service.region: + region_name = service.region + service_type = service.service_type + if service.interface: + key = _make_key('interface', service_type) + kwargs[key] = service.interface + if service.version: + version = service.version + if version.startswith('v'): + version = version[1:] + key = _make_key('api_version', service_type) + kwargs[key] = version + if service.api_version: + version = service.api_version + key = _make_key('default_microversion', service_type) + kwargs[key] = version + + config_kwargs = config_defaults.get_defaults() + config_kwargs.update(kwargs) + config = cloud_region.CloudRegion( + region_name=region_name, config=config_kwargs) + return config + + +def create_connection(prof=None, cloud_region=None, **kwargs): + version_key = _make_key(API_NAME, 'api_version') + kwargs[version_key] = CURRENT_API_VERSION + + if not cloud_region: + if prof: + cloud_region = _get_config_from_profile(prof, **kwargs) + else: + # If we got the CloudRegion from python-openstackclient and it doesn't + # already have a default microversion set, set it here. + microversion_key = _make_key(API_NAME, 'default_microversion') + cloud_region.config.setdefault(microversion_key, CURRENT_API_VERSION) + user_agent = kwargs.pop('user_agent', None) + app_name = kwargs.pop('app_name', None) + app_version = kwargs.pop('app_version', None) + if user_agent is not None and (not app_name and not app_version): + app_name, app_version = user_agent.split('/', 1) - if not prof: - prof = profile.Profile() - prof.set_api_version(API_NAME, CURRENT_API_VERSION) - - if interface: - prof.set_interface(API_NAME, interface) - if region_name: - prof.set_region(API_NAME, region_name) - - return connection.Connection(profile=prof, user_agent=user_agent, **kwargs) + return connection.Connection( + config=cloud_region, + app_name=app_name, + app_version=app_version, **kwargs) def make_client(instance): """Returns a clustering proxy""" + # TODO(mordred) the ClientManager already has an OpenStackSDK connection, + # but it only has it once setup_auth has been called. For things that + # don't require auth, this is problematic, so we have to make our own. + # Use the CloudRegion stored on the ClientManager for now. conn = create_connection( - region_name=instance.region_name, - interface=instance.interface, - authenticator=instance.session.auth + cloud_region=instance._cli_options, ) LOG.debug('Connection: %s', conn) LOG.debug('Clustering client initialized using OpenStackSDK: %s', - conn.cluster) - return conn.cluster + conn.clustering) + return conn.clustering def build_option_parser(parser): diff --git a/senlinclient/tests/unit/test_plugin.py b/senlinclient/tests/unit/test_plugin.py index 0750a6be..b95e7ea7 100644 --- a/senlinclient/tests/unit/test_plugin.py +++ b/senlinclient/tests/unit/test_plugin.py @@ -12,7 +12,6 @@ import mock from openstack import connection as sdk_connection -from openstack import profile as sdk_profile import testtools from senlinclient import plugin @@ -22,7 +21,15 @@ class TestPlugin(testtools.TestCase): @mock.patch.object(sdk_connection, 'Connection') def test_create_connection_with_profile(self, mock_connection): + class FakeService(object): + interface = 'public' + region = 'a_region' + version = '1' + api_version = None + service_type = 'clustering' + mock_prof = mock.Mock() + mock_prof.get_services.return_value = [FakeService()] mock_conn = mock.Mock() mock_connection.return_value = mock_conn kwargs = { @@ -31,20 +38,17 @@ class TestPlugin(testtools.TestCase): 'auth_url': 'test_url' } res = plugin.create_connection(mock_prof, **kwargs) - mock_connection.assert_called_once_with(profile=mock_prof, - user_agent=None, - user_id='123', - password='abc', - auth_url='test_url') + mock_connection.assert_called_once_with( + app_name=None, app_version=None, + config=mock.ANY, + clustering_api_version='1.10', + **kwargs + ) self.assertEqual(mock_conn, res) @mock.patch.object(sdk_connection, 'Connection') - @mock.patch.object(sdk_profile, 'Profile') - def test_create_connection_without_profile(self, mock_profile, - mock_connection): - mock_prof = mock.Mock() + def test_create_connection_without_profile(self, mock_connection): mock_conn = mock.Mock() - mock_profile.return_value = mock_prof mock_connection.return_value = mock_conn kwargs = { 'interface': 'public', @@ -55,11 +59,14 @@ class TestPlugin(testtools.TestCase): } res = plugin.create_connection(**kwargs) - mock_prof.set_interface.assert_called_once_with('clustering', 'public') - mock_prof.set_region.assert_called_once_with('clustering', 'RegionOne') - mock_connection.assert_called_once_with(profile=mock_prof, - user_agent=None, - user_id='123', - password='abc', - auth_url='test_url') + mock_connection.assert_called_once_with( + app_name=None, app_version=None, + auth_url='test_url', + clustering_api_version='1.10', + config=None, + interface='public', + password='abc', + region_name='RegionOne', + user_id='123' + ) self.assertEqual(mock_conn, res)