Skip to content

Commit f28c963

Browse files
committed
Add endpoint discovery support
This is simpler than expected. Effectively, for each potential endpoint, we retrieve the version document from the root URL and parse the version information, if any, from it, comparing it against the version expected. Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
1 parent ed23d9b commit f28c963

File tree

1 file changed

+42
-3
lines changed

1 file changed

+42
-3
lines changed

openstack/endpoint.go

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,34 @@
11
package openstack
22

33
import (
4+
"context"
45
"slices"
56

67
"github.com/gophercloud/gophercloud/v2"
78
tokens2 "github.com/gophercloud/gophercloud/v2/openstack/identity/v2/tokens"
89
tokens3 "github.com/gophercloud/gophercloud/v2/openstack/identity/v3/tokens"
10+
"github.com/gophercloud/gophercloud/v2/openstack/utils"
911
)
1012

13+
func endpointSupportsVersion(ctx context.Context, client *gophercloud.ProviderClient, serviceType, endpointURL string, expectedVersion int) (bool, error) {
14+
// Swift doesn't support version discovery :(
15+
if expectedVersion == 0 || serviceType == "object-store" {
16+
return true, nil
17+
}
18+
19+
endpointURL, err := utils.BaseVersionedEndpoint(endpointURL)
20+
if err != nil {
21+
return false, err
22+
}
23+
24+
supportedMicroversions, err := utils.GetServiceVersions(ctx, client, endpointURL)
25+
if err != nil {
26+
return false, err
27+
}
28+
29+
return supportedMicroversions.MinMajor == 0 || supportedMicroversions.MinMajor == expectedVersion, nil
30+
}
31+
1132
/*
1233
V2Endpoint discovers the endpoint URL for a specific service from a
1334
ServiceCatalog acquired during the v2 identity service.
@@ -18,7 +39,7 @@ criteria and when none do. The minimum that can be specified is a Type, but you
1839
will also often need to specify a Name and/or a Region depending on what's
1940
available on your OpenStack deployment.
2041
*/
21-
func V2Endpoint(catalog *tokens2.ServiceCatalog, opts gophercloud.EndpointOpts) (string, error) {
42+
func V2Endpoint(ctx context.Context, client *gophercloud.ProviderClient, catalog *tokens2.ServiceCatalog, opts gophercloud.EndpointOpts) (string, error) {
2243
// Extract Endpoints from the catalog entries that match the requested Type, Name if provided, and Region if provided.
2344
//
2445
// If multiple endpoints are found, we return the first result and disregard the rest.
@@ -45,6 +66,14 @@ func V2Endpoint(catalog *tokens2.ServiceCatalog, opts gophercloud.EndpointOpts)
4566
return "", err
4667
}
4768

69+
endpointSupportsVersion, err := endpointSupportsVersion(ctx, client, entry.Type, endpointURL, opts.Version)
70+
if err != nil {
71+
return "", err
72+
}
73+
if !endpointSupportsVersion {
74+
continue
75+
}
76+
4877
return endpointURL, nil
4978
}
5079
}
@@ -65,7 +94,7 @@ criteria and when none do. The minimum that can be specified is a Type, but you
6594
will also often need to specify a Name and/or a Region depending on what's
6695
available on your OpenStack deployment.
6796
*/
68-
func V3Endpoint(catalog *tokens3.ServiceCatalog, opts gophercloud.EndpointOpts) (string, error) {
97+
func V3Endpoint(ctx context.Context, client *gophercloud.ProviderClient, catalog *tokens3.ServiceCatalog, opts gophercloud.EndpointOpts) (string, error) {
6998
if opts.Availability != gophercloud.AvailabilityAdmin &&
7099
opts.Availability != gophercloud.AvailabilityPublic &&
71100
opts.Availability != gophercloud.AvailabilityInternal {
@@ -90,7 +119,17 @@ func V3Endpoint(catalog *tokens3.ServiceCatalog, opts gophercloud.EndpointOpts)
90119
continue
91120
}
92121

93-
return gophercloud.NormalizeURL(endpoint.URL), nil
122+
endpointURL := gophercloud.NormalizeURL(endpoint.URL)
123+
124+
endpointSupportsVersion, err := endpointSupportsVersion(ctx, client, entry.Type, endpointURL, opts.Version)
125+
if err != nil {
126+
return "", err
127+
}
128+
if !endpointSupportsVersion {
129+
continue
130+
}
131+
132+
return endpointURL, nil
94133
}
95134
}
96135
}

0 commit comments

Comments
 (0)