Allow project_id in catalog substitutions

We allowed 'tenant_id' in catalog substitutions. The 'tenant' term is
deprecated in favor of 'project'. Also allow 'project_id' so that
users can stop using the deprecated term in one more place.

Change-Id: I4bcfbda1b542f09172f5b53185f063c6bea27205
This commit is contained in:
Brant Knudson 2016-02-12 08:41:55 -06:00
parent 406fbfaa26
commit 0d472c86e3
7 changed files with 62 additions and 12 deletions

View File

@ -282,9 +282,12 @@ class Catalog(catalog.CatalogDriverV8):
substitutions.update({'user_id': user_id})
silent_keyerror_failures = []
if tenant_id:
substitutions.update({'tenant_id': tenant_id})
substitutions.update({
'tenant_id': tenant_id,
'project_id': tenant_id
})
else:
silent_keyerror_failures = ['tenant_id']
silent_keyerror_failures = ['tenant_id', 'project_id', ]
session = sql.get_session()
endpoints = (session.query(Endpoint).
@ -339,9 +342,12 @@ class Catalog(catalog.CatalogDriverV8):
d.update({'user_id': user_id})
silent_keyerror_failures = []
if tenant_id:
d.update({'tenant_id': tenant_id})
d.update({
'tenant_id': tenant_id,
'project_id': tenant_id,
})
else:
silent_keyerror_failures = ['tenant_id']
silent_keyerror_failures = ['tenant_id', 'project_id', ]
session = sql.get_session()
services = (session.query(Service).filter(Service.enabled == true()).

View File

@ -214,9 +214,12 @@ class Catalog(core.Driver):
substitutions.update({'user_id': user_id})
silent_keyerror_failures = []
if tenant_id:
substitutions.update({'tenant_id': tenant_id})
substitutions.update({
'tenant_id': tenant_id,
'project_id': tenant_id,
})
else:
silent_keyerror_failures = ['tenant_id']
silent_keyerror_failures = ['tenant_id', 'project_id', ]
catalog = {}
# TODO(davechen): If there is service with no endpoints, we should

View File

@ -37,7 +37,8 @@ from keystone import notifications
CONF = cfg.CONF
LOG = log.getLogger(__name__)
WHITELISTED_PROPERTIES = [
'tenant_id', 'user_id', 'public_bind_host', 'admin_bind_host',
'tenant_id', 'project_id', 'user_id',
'public_bind_host', 'admin_bind_host',
'compute_host', 'admin_port', 'public_port',
'public_endpoint', 'admin_endpoint', ]

View File

@ -26,7 +26,11 @@ CONF = cfg.CONF
class EndpointFilterCatalog(sql.Catalog):
def get_v3_catalog(self, user_id, project_id):
substitutions = dict(CONF.items())
substitutions.update({'tenant_id': project_id, 'user_id': user_id})
substitutions.update({
'tenant_id': project_id,
'project_id': project_id,
'user_id': user_id,
})
services = {}

View File

@ -10,6 +10,8 @@
# License for the specific language governing permissions and limitations
# under the License.
import uuid
from oslo_config import cfg
from keystone.catalog import core
@ -24,12 +26,13 @@ class FormatUrlTests(unit.BaseTestCase):
def test_successful_formatting(self):
url_template = ('http://$(public_bind_host)s:$(admin_port)d/'
'$(tenant_id)s/$(user_id)s')
'$(tenant_id)s/$(user_id)s/$(project_id)s')
project_id = uuid.uuid4().hex
values = {'public_bind_host': 'server', 'admin_port': 9090,
'tenant_id': 'A', 'user_id': 'B'}
'tenant_id': 'A', 'user_id': 'B', 'project_id': project_id}
actual_url = core.format_url(url_template, values)
expected_url = 'http://server:9090/A/B'
expected_url = 'http://server:9090/A/B/%s' % (project_id,)
self.assertEqual(expected_url, actual_url)
def test_raises_malformed_on_missing_key(self):
@ -73,7 +76,7 @@ class FormatUrlTests(unit.BaseTestCase):
url_template,
values)
def test_substitution_with_allowed_keyerror(self):
def test_substitution_with_allowed_tenant_keyerror(self):
# No value of 'tenant_id' is passed into url_template.
# mod: format_url will return None instead of raising
# "MalformedEndpoint" exception.
@ -86,3 +89,17 @@ class FormatUrlTests(unit.BaseTestCase):
'user_id': 'B'}
self.assertIsNone(core.format_url(url_template, values,
silent_keyerror_failures=['tenant_id']))
def test_substitution_with_allowed_project_keyerror(self):
# No value of 'project_id' is passed into url_template.
# mod: format_url will return None instead of raising
# "MalformedEndpoint" exception.
# This is intentional behavior since we don't want to skip
# all the later endpoints once there is an URL of endpoint
# trying to replace 'project_id' with None.
url_template = ('http://$(public_bind_host)s:$(admin_port)d/'
'$(project_id)s/$(user_id)s')
values = {'public_bind_host': 'server', 'admin_port': 9090,
'user_id': 'B'}
self.assertIsNone(core.format_url(url_template, values,
silent_keyerror_failures=['project_id']))

View File

@ -743,6 +743,16 @@ class CatalogTestCase(test_v3.RestfulTestCase):
url=valid_url)
self.post('/endpoints', body={'endpoint': ref})
def test_endpoint_create_with_valid_url_project_id(self):
"""Create endpoint with valid url should be tested,too."""
valid_url = 'http://127.0.0.1:8774/v1.1/$(project_id)s'
ref = unit.new_endpoint_ref(self.service_id,
interface='public',
region_id=self.region_id,
url=valid_url)
self.post('/endpoints', body={'endpoint': ref})
def test_endpoint_create_with_invalid_url(self):
"""Test the invalid cases: substitutions is not exactly right."""
invalid_urls = [

View File

@ -0,0 +1,9 @@
---
deprecations:
- Use of ``$(tenant_id)s`` in the catalog endpoints is deprecated in favor
of ``$(project_id)s``.
features:
- Keystone supports ``$(project_id)s`` in the catalog. It works the same as
``$(tenant_id)s``. Use of ``$(tenant_id)s`` is deprecated and catalog
endpoints should be updated to use ``$(project_id)s``.