I sent this a couple of weeks ago, but never saw it come across in the
archives. Maybe because I didn't subscribe to the mailing list until after
I sent it? Anyway, resending...
I'm in the process of migrating from Apache Libcloud 0.15.0 to 1.0.0-pre1
and ran into a bug. Here's a trivial script to reproduce it:
#!/usr/bin/env python3
from libcloud.common.types import LibcloudError
from libcloud.storage.drivers.cloudfiles import OpenStackSwiftStorageDriver
driver = OpenStackSwiftStorageDriver(
'some_userid', 'secret_key',
ex_force_auth_version='1.0',
ex_force_auth_url='http://10.110.2.10/auth/v1.0',
ex_force_service_name='cloudFiles')
try:
container = driver.get_container('rolette')
print(container)
except LibcloudError as why:
print(why)
Output from running the script:
$ ./swift-driver-v1-auth-bug.py
<LibcloudError in None 'Could not find specified endpoint'>
The scripts works fine against Libcloud 0.15.0.
The root of the problem is
in OpenStackServiceCatalog._parse_service_catalog_auth_v1().
When it creates the OpenStackServiceCatalogEntry, it doesn't specify the
'service_name' parameter:
entry = OpenStackServiceCatalogEntry(service_type=service,
endpoints=entry_endpoints)
This eventually causes a failure when trying to resolve the endpoint
in OpenStackBaseConnection._populate_hosts_and_request_paths() on this line:
url = self._ex_force_base_url or self.get_endpoint()
In OpenStackSwiftConnection.get_endpoint(), it throws the error here:
elif ('1.1' in self._auth_version) or ('1.0' in self._auth_version):
endpoint = self.service_catalog.get_endpoint(
name=self._service_name, region=self._service_region)
if endpoint:
return endpoint.url
else:
raise LibcloudError('Could not find specified endpoint')
OpenStackServiceCatalog.get_endpoint() fails to find a match because the
service name wasn't set when the catalog was created.
The following patch fixes this for my environment, but I don't claim to
know the Swift driver well enough to know if this is the right fix
generally:
$ hg diff openstack_identity.py
diff -r 4f3e9d5151b3 libcloud/common/openstack_identity.py
--- a/libcloud/common/openstack_identity.py Mon Mar 21 19:20:18 2016 +0000
+++ b/libcloud/common/openstack_identity.py Tue Mar 22 15:20:47 2016 +0000
@@ -355,7 +355,7 @@
def _parse_service_catalog_auth_v1(self, service_catalog):
entries = []
- for service, endpoints in service_catalog.items():
+ for service_name, endpoints in service_catalog.items():
entry_endpoints = []
for endpoint in endpoints:
region = endpoint.get('region', None)
@@ -375,8 +375,19 @@
endpoint_type=OpenStackIdentityEndpointType.INTERNAL)
entry_endpoints.append(entry_endpoint)
- entry = OpenStackServiceCatalogEntry(service_type=service,
- endpoints=entry_endpoints)
+ # original code was not specifying service_name when it created
+ # the entry, but get_endpoint() was failing to find the
service because
+ # it was searching based on the service_name
+ #
+ # TODO: check with libcloud folks to find out right way to fix
this.
+ # can't just set service_type=None because it blows up
later when
+ # the caller tries to sort based on service_type
+ #
+ # entry =
OpenStackServiceCatalogEntry(service_type=service_name,
+ #
endpoints=entry_endpoints)
+ entry = OpenStackServiceCatalogEntry(service_type=service_name,
+ endpoints=entry_endpoints,
+ service_name=service_name)
entries.append(entry)
return entries
Thanks,
Jay