diff --git a/keystoneauth1/loading/adapter.py b/keystoneauth1/loading/adapter.py index 256c4282..a0e73237 100644 --- a/keystoneauth1/loading/adapter.py +++ b/keystoneauth1/loading/adapter.py @@ -42,6 +42,10 @@ class Adapter(base.BaseLoader): :service_type: The default service_type for URL discovery. :service_name: The default service_name for URL discovery. :interface: The default interface for URL discovery. + (deprecated) + :valid_interfaces: List of acceptable interfaces for URL + discovery. Can be a list of any of + 'public', 'internal' or 'admin'. :region_name: The default region_name for URL discovery. :endpoint_override: Always use this endpoint URL for requests for this client. @@ -71,7 +75,15 @@ class Adapter(base.BaseLoader): 'discovery.'), cfg.StrOpt('interface', help='The default interface for endpoint URL ' - 'discovery.'), + 'discovery.', + deprecated_for_removal=True, + deprecated_since='3.0', + deprecated_reason='interface can be requested as a ' + 'list. Please use ' + 'valid-interfaces instead.'), + cfg.ListOpt('valid-interfaces', + help='List of interfaces, in order of preference, ' + 'for endpoint URL.'), cfg.StrOpt('region-name', help='The default region_name for endpoint URL ' 'discovery.'), @@ -104,6 +116,10 @@ class Adapter(base.BaseLoader): :service_type: The default service_type for URL discovery. :service_name: The default service_name for URL discovery. :interface: The default interface for URL discovery. + (deprecated) + :valid_interfaces: List of acceptable interfaces for URL + discovery. Can be a list of any of + 'public', 'internal' or 'admin'. :region_name: The default region_name for URL discovery. :endpoint_override: Always use this endpoint URL for requests for this client. @@ -145,9 +161,20 @@ class Adapter(base.BaseLoader): """ c = conf[group] + if c.valid_interfaces and c.interface: + raise TypeError("interface and valid_interfaces are mutually" + " exclusive. Please use valid_interfaces.") + if c.valid_interfaces: + for iface in c.valid_interfaces: + if iface not in ('public', 'internal', 'admin'): + raise TypeError("'{iface}' is not a valid value for" + " valid_interfaces. Valid valies are" + " public, internal or admin") + kwargs.setdefault('interface', c.valid_interfaces) + else: + kwargs.setdefault('interface', c.interface) kwargs.setdefault('service_type', c.service_type) kwargs.setdefault('service_name', c.service_name) - kwargs.setdefault('interface', c.interface) kwargs.setdefault('region_name', c.region_name) kwargs.setdefault('endpoint_override', c.endpoint_override) kwargs.setdefault('version', c.version) diff --git a/keystoneauth1/tests/unit/loading/test_adapter.py b/keystoneauth1/tests/unit/loading/test_adapter.py index aa4bf929..3c7d008b 100644 --- a/keystoneauth1/tests/unit/loading/test_adapter.py +++ b/keystoneauth1/tests/unit/loading/test_adapter.py @@ -29,14 +29,15 @@ class ConfLoadingTests(utils.TestCase): def test_load(self): self.conf_fx.config( - service_type='type', service_name='name', interface='iface', + service_type='type', service_name='name', + valid_interfaces='internal', region_name='region', endpoint_override='endpoint', version='2.0', group=self.GROUP) adap = loading.load_adapter_from_conf_options( self.conf_fx.conf, self.GROUP, session='session', auth='auth') self.assertEqual('type', adap.service_type) self.assertEqual('name', adap.service_name) - self.assertEqual('iface', adap.interface) + self.assertEqual(['internal'], adap.interface) self.assertEqual('region', adap.region_name) self.assertEqual('endpoint', adap.endpoint_override) self.assertEqual('session', adap.session) @@ -45,16 +46,85 @@ class ConfLoadingTests(utils.TestCase): self.assertIsNone(adap.min_version) self.assertIsNone(adap.max_version) + def test_load_valid_interfaces_list(self): + self.conf_fx.config( + service_type='type', service_name='name', + valid_interfaces=['internal', 'public'], + region_name='region', endpoint_override='endpoint', + version='2.0', group=self.GROUP) + adap = loading.load_adapter_from_conf_options( + self.conf_fx.conf, self.GROUP, session='session', auth='auth') + self.assertEqual('type', adap.service_type) + self.assertEqual('name', adap.service_name) + self.assertEqual(['internal', 'public'], adap.interface) + self.assertEqual('region', adap.region_name) + self.assertEqual('endpoint', adap.endpoint_override) + self.assertEqual('session', adap.session) + self.assertEqual('auth', adap.auth) + self.assertEqual('2.0', adap.version) + self.assertIsNone(adap.min_version) + self.assertIsNone(adap.max_version) + + def test_load_valid_interfaces_comma_list(self): + self.conf_fx.config( + service_type='type', service_name='name', + valid_interfaces='internal,public', + region_name='region', endpoint_override='endpoint', + version='2.0', group=self.GROUP) + adap = loading.load_adapter_from_conf_options( + self.conf_fx.conf, self.GROUP, session='session', auth='auth') + self.assertEqual('type', adap.service_type) + self.assertEqual('name', adap.service_name) + self.assertEqual(['internal', 'public'], adap.interface) + self.assertEqual('region', adap.region_name) + self.assertEqual('endpoint', adap.endpoint_override) + self.assertEqual('session', adap.session) + self.assertEqual('auth', adap.auth) + self.assertEqual('2.0', adap.version) + self.assertIsNone(adap.min_version) + self.assertIsNone(adap.max_version) + + def test_load_old_interface(self): + self.conf_fx.config( + service_type='type', service_name='name', + interface='internal', + region_name='region', endpoint_override='endpoint', + version='2.0', group=self.GROUP) + adap = loading.load_adapter_from_conf_options( + self.conf_fx.conf, self.GROUP, session='session', auth='auth') + self.assertEqual('type', adap.service_type) + self.assertEqual('name', adap.service_name) + self.assertEqual('internal', adap.interface) + self.assertEqual('region', adap.region_name) + self.assertEqual('endpoint', adap.endpoint_override) + self.assertEqual('session', adap.session) + self.assertEqual('auth', adap.auth) + self.assertEqual('2.0', adap.version) + self.assertIsNone(adap.min_version) + self.assertIsNone(adap.max_version) + + def test_load_bad_valid_interfaces_value(self): + self.conf_fx.config( + service_type='type', service_name='name', + valid_interfaces='bad', + region_name='region', endpoint_override='endpoint', + version='2.0', group=self.GROUP) + self.assertRaises( + TypeError, + loading.load_adapter_from_conf_options, + self.conf_fx.conf, self.GROUP, session='session', auth='auth') + def test_load_version_range(self): self.conf_fx.config( - service_type='type', service_name='name', interface='iface', + service_type='type', service_name='name', + valid_interfaces='internal', region_name='region', endpoint_override='endpoint', min_version='2.0', max_version='3.0', group=self.GROUP) adap = loading.load_adapter_from_conf_options( self.conf_fx.conf, self.GROUP, session='session', auth='auth') self.assertEqual('type', adap.service_type) self.assertEqual('name', adap.service_name) - self.assertEqual('iface', adap.interface) + self.assertEqual(['internal'], adap.interface) self.assertEqual('region', adap.region_name) self.assertEqual('endpoint', adap.endpoint_override) self.assertEqual('session', adap.session) @@ -63,9 +133,22 @@ class ConfLoadingTests(utils.TestCase): self.assertEqual('2.0', adap.min_version) self.assertEqual('3.0', adap.max_version) - def test_load_bad_version(self): + def test_interface_conflict(self): self.conf_fx.config( service_type='type', service_name='name', interface='iface', + valid_interfaces='internal,public', + region_name='region', endpoint_override='endpoint', + group=self.GROUP) + + self.assertRaises( + TypeError, + loading.load_adapter_from_conf_options, + self.conf_fx.conf, self.GROUP, session='session', auth='auth') + + def test_load_bad_version(self): + self.conf_fx.config( + service_type='type', service_name='name', + valid_interfaces='iface', region_name='region', endpoint_override='endpoint', version='2.0', min_version='2.0', max_version='3.0', group=self.GROUP) @@ -78,8 +161,12 @@ class ConfLoadingTests(utils.TestCase): def test_get_conf_options(self): opts = loading.get_adapter_conf_options() for opt in opts: - self.assertIsInstance(opt, cfg.StrOpt) - self.assertEqual({'service-type', 'service-name', 'interface', + if opt.name != 'valid-interfaces': + self.assertIsInstance(opt, cfg.StrOpt) + else: + self.assertIsInstance(opt, cfg.ListOpt) + self.assertEqual({'service-type', 'service-name', + 'interface', 'valid-interfaces', 'region-name', 'endpoint-override', 'version', 'min-version', 'max-version'}, {opt.name for opt in opts})