More endpoint_location coverage.
diff --git a/openstack/client.go b/openstack/client.go
index bd82690..97556d6 100644
--- a/openstack/client.go
+++ b/openstack/client.go
@@ -134,7 +134,7 @@
client.TokenID = token.ID
client.EndpointLocator = func(opts gophercloud.EndpointOpts) (string, error) {
- return V3EndpointLocator(v3Client, opts)
+ return V3EndpointURL(v3Client, opts)
}
return nil
diff --git a/openstack/endpoint_location.go b/openstack/endpoint_location.go
index bd1d820..5a311e4 100644
--- a/openstack/endpoint_location.go
+++ b/openstack/endpoint_location.go
@@ -52,13 +52,13 @@
return "", gophercloud.ErrEndpointNotFound
}
-// V3EndpointLocator discovers the endpoint URL for a specific service using multiple calls against
+// V3EndpointURL discovers the endpoint URL for a specific service using multiple calls against
// an identity v3 service endpoint. The specified EndpointOpts are used to identify a unique,
// unambiguous endpoint to return. It's an error both when multiple endpoints match the provided
// criteria and when none do. The minimum that can be specified is a Type, but you will also often
// need to specify a Name and/or a Region depending on what's available on your OpenStack
// deployment.
-func V3EndpointLocator(v3Client *gophercloud.ServiceClient, opts gophercloud.EndpointOpts) (string, error) {
+func V3EndpointURL(v3Client *gophercloud.ServiceClient, opts gophercloud.EndpointOpts) (string, error) {
// Discover the service we're interested in.
var services = make([]services3.Service, 0, 1)
servicePager := services3.List(v3Client, services3.ListOpts{ServiceType: opts.Type})
diff --git a/openstack/endpoint_location_test.go b/openstack/endpoint_location_test.go
index 05cecf5..4e0569a 100644
--- a/openstack/endpoint_location_test.go
+++ b/openstack/endpoint_location_test.go
@@ -1,12 +1,15 @@
package openstack
import (
+ "fmt"
+ "net/http"
"strings"
"testing"
"github.com/rackspace/gophercloud"
tokens2 "github.com/rackspace/gophercloud/openstack/identity/v2/tokens"
th "github.com/rackspace/gophercloud/testhelper"
+ fake "github.com/rackspace/gophercloud/testhelper/client"
)
// Service catalog fixtures take too much vertical space!
@@ -106,3 +109,117 @@
})
th.CheckEquals(t, err.Error(), "Unexpected availability in endpoint query: wat")
}
+
+func setupV3Responses(t *testing.T) {
+ // Mock the service query.
+ th.Mux.HandleFunc("/services", func(w http.ResponseWriter, r *http.Request) {
+ th.TestMethod(t, r, "GET")
+ th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
+
+ w.Header().Add("Content-Type", "application/json")
+ fmt.Fprintf(w, `
+ {
+ "links": {
+ "next": null,
+ "previous": null
+ },
+ "services": [
+ {
+ "description": "Correct",
+ "id": "1234",
+ "name": "same",
+ "type": "same"
+ },
+ {
+ "description": "Bad Name",
+ "id": "9876",
+ "name": "different",
+ "type": "same"
+ }
+ ]
+ }
+ `)
+ })
+
+ // Mock the endpoint query.
+ th.Mux.HandleFunc("/endpoints", func(w http.ResponseWriter, r *http.Request) {
+ th.TestMethod(t, r, "GET")
+ th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
+ th.TestFormValues(t, r, map[string]string{
+ "service_id": "1234",
+ "interface": "public",
+ })
+
+ w.Header().Add("Content-Type", "application/json")
+ fmt.Fprintf(w, `
+ {
+ "endpoints": [
+ {
+ "id": "12",
+ "interface": "public",
+ "name": "the-right-one",
+ "region": "same",
+ "service_id": "1234",
+ "url": "https://correct:9000/"
+ },
+ {
+ "id": "14",
+ "interface": "public",
+ "name": "bad-region",
+ "region": "different",
+ "service_id": "1234",
+ "url": "https://bad-region:9001/"
+ }
+ ],
+ "links": {
+ "next": null,
+ "previous": null
+ }
+ }
+ `)
+ })
+}
+
+func TestV3EndpointExact(t *testing.T) {
+ th.SetupHTTP()
+ defer th.TeardownHTTP()
+ setupV3Responses(t)
+
+ actual, err := V3EndpointURL(fake.ServiceClient(), gophercloud.EndpointOpts{
+ Type: "same",
+ Name: "same",
+ Region: "same",
+ Availability: gophercloud.AvailabilityPublic,
+ })
+ th.AssertNoErr(t, err)
+ th.CheckEquals(t, actual, "https://correct:9000/")
+}
+
+func TestV3EndpointNoService(t *testing.T) {
+ th.SetupHTTP()
+ defer th.TeardownHTTP()
+
+ th.Mux.HandleFunc("/services", func(w http.ResponseWriter, r *http.Request) {
+ th.TestMethod(t, r, "GET")
+ th.TestHeader(t, r, "X-Auth-Token", fake.TokenID)
+
+ w.Header().Add("Content-Type", "application/json")
+ fmt.Fprintf(w, `
+ {
+ "links": {
+ "next": null,
+ "previous": null
+ },
+ "services": []
+ }
+ `)
+ })
+
+ _, err := V3EndpointURL(fake.ServiceClient(), gophercloud.EndpointOpts{
+ Type: "nope",
+ Name: "same",
+ Region: "same",
+ Availability: gophercloud.AvailabilityPublic,
+ })
+ th.CheckEquals(t, gophercloud.ErrServiceNotFound, err)
+}