Handle missing endpoint, region, service

SDK will not return 'ResourceNotFound' for a list operation (like
'services'): it will only do that for a fetch operation (like
'get_service'):

  >>> import openstack
  >>> conn = openstack.connect(cloud='devstack-admin')
  >>> set(conn.identity.services(name='foo'))
  []
  >>> conn.identity.get_service('foo')
  Traceback (most recent call last):
    ...
  openstack.exceptions.NotFoundException: No Service found for foo: Client Error for url: http://example.com/identity/v3/services/foo, Could not find service: foo.

Correct our assumptions here.

Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
Change-Id: I21bfa283c95ace092bc154e28f5d584d027c29f9
This commit is contained in:
Stephen Finucane
2025-11-26 12:13:50 +00:00
parent ebfae62773
commit f1ce4022d6
2 changed files with 43 additions and 30 deletions

View File

@@ -366,57 +366,70 @@ class _EnforcerUtils:
endpoint = self.connection.get_endpoint(endpoint_id) # type: ignore
except os_exceptions.ResourceNotFound:
raise ValueError(f"Can't find endpoint for {endpoint_id}")
return cast(_endpoint.Endpoint, endpoint)
def _get_endpoint_by_service_lookup(self) -> _endpoint.Endpoint:
service_type = CONF.oslo_limit.endpoint_service_type
service_name = CONF.oslo_limit.endpoint_service_name
if not service_type and not service_name:
raise ValueError(
"Either service_type or service_name should be set"
)
try:
# find service
services = self.connection.services( # type: ignore
type=service_type, name=service_name
)
services = list(services)
if len(services) > 1:
raise ValueError("Multiple services found")
service_id = services[0].id
except os_exceptions.ResourceNotFound:
if len(services) == 0:
raise ValueError("Service not found")
service_id = services[0].id
# find region (if any)
if CONF.oslo_limit.endpoint_region_name is not None:
try:
regions = self.connection.regions( # type: ignore
name=CONF.oslo_limit.endpoint_region_name
)
regions = list(regions)
if len(regions) > 1:
raise ValueError("Multiple regions found")
region_id = regions[0].id
except os_exceptions.ResourceNotFound:
if len(regions) == 0:
raise ValueError("Region not found")
region_id = regions[0].id
else:
region_id = None
# find endpoint
interface = CONF.oslo_limit.endpoint_interface
if interface.endswith('URL'):
interface = interface[:-3]
try:
endpoints = self.connection.endpoints( # type: ignore
service_id=service_id,
region_id=region_id,
interface=interface,
)
endpoints = list(endpoints)
except os_exceptions.ResourceNotFound:
raise ValueError("Endpoint not found")
if len(endpoints) > 1:
raise ValueError("Multiple endpoints found")
if len(endpoints) == 0:
raise ValueError("Endpoint not found")
return cast(_endpoint.Endpoint, endpoints[0])
@staticmethod

View File

@@ -468,7 +468,7 @@ class TestEnforcerUtils(base.BaseTestCase):
)
fake_service = service.Service(id='SERVICE_ID')
self.mock_conn.services.return_value = [fake_service]
self.mock_conn.endpoints.side_effect = os_exceptions.ResourceNotFound
self.mock_conn.endpoints.return_value = []
self.assertRaises(ValueError, limit._EnforcerUtils)
@@ -509,7 +509,7 @@ class TestEnforcerUtils(base.BaseTestCase):
self.config_fixture.config(
group='oslo_limit', endpoint_service_name='SERVICE_NAME'
)
self.mock_conn.services.side_effect = os_exceptions.ResourceNotFound
self.mock_conn.services.return_value = []
self.assertRaises(ValueError, limit._EnforcerUtils)
@@ -564,7 +564,7 @@ class TestEnforcerUtils(base.BaseTestCase):
self.mock_conn.services.return_value = [fake_service]
fake_endpoint = endpoint.Endpoint()
self.mock_conn.endpoints.return_value = [fake_endpoint]
self.mock_conn.regions.side_effect = os_exceptions.ResourceNotFound
self.mock_conn.regions.return_value = []
self.assertRaises(ValueError, limit._EnforcerUtils)