Identity v2 endpoint location.
diff --git a/openstack/client.go b/openstack/client.go
index 96b0b06..b058823 100644
--- a/openstack/client.go
+++ b/openstack/client.go
@@ -84,7 +84,7 @@
client.TokenID = token.ID
client.EndpointLocator = func(opts gophercloud.EndpointOpts) (string, error) {
- return v2endpointLocator(v2Client, opts)
+ return v2endpointLocator(result, opts)
}
return nil
@@ -113,7 +113,59 @@
}
}
-func v2endpointLocator(v2Client *gophercloud.ServiceClient, opts gophercloud.EndpointOpts) (string, error) {
+func v2endpointLocator(authResults identity2.AuthResults, opts gophercloud.EndpointOpts) (string, error) {
+ catalog, err := identity2.GetServiceCatalog(authResults)
+ if err != nil {
+ return "", err
+ }
+
+ entries, err := catalog.CatalogEntries()
+ if err != nil {
+ return "", err
+ }
+
+ // Extract Endpoints from the catalog entries that match the requested Type, Name if provided, and Region if provided.
+ var endpoints = make([]identity2.Endpoint, 0, 6)
+ for _, entry := range entries {
+ matched := true
+
+ if entry.Type != opts.Type {
+ matched = false
+ }
+
+ if opts.Name != "" && entry.Name != opts.Name {
+ matched = false
+ }
+
+ if matched {
+ for _, endpoint := range entry.Endpoints {
+ if opts.Region == "" || endpoint.Region == opts.Region {
+ endpoints = append(endpoints, endpoint)
+ }
+ }
+ }
+ }
+
+ // Report an error if the options were ambiguous.
+ if len(endpoints) == 0 {
+ return "", gophercloud.ErrEndpointNotFound
+ }
+ if len(endpoints) > 1 {
+ return "", fmt.Errorf("Discovered %d matching endpoints: %#v", len(endpoints), endpoints)
+ }
+
+ // Extract the appropriate URL from the matching Endpoint.
+ for _, endpoint := range endpoints {
+ switch opts.URLType {
+ case "public", "":
+ return endpoint.PublicURL, nil
+ case "private":
+ return endpoint.InternalURL, nil
+ default:
+ return "", fmt.Errorf("Unexpected URLType in endpoint query: %s", opts.URLType)
+ }
+ }
+
return "", gophercloud.ErrEndpointNotFound
}