Skip to content

Commit 471e1ca

Browse files
committed
Add V2Endpoint, V3Endpoint helpers
For now these are exact duplicates of the V2EndpointURL and V3EndpointURL helpers but with different names. diff -u openstack/endpoint_location.go openstack/endpoint.go This is done to ease review. We will introduce further differences shortly. Signed-off-by: Stephen Finucane <stephenfin@redhat.com> (cherry picked from commit ed23d9b)
1 parent 7db8ba0 commit 471e1ca

File tree

1 file changed

+101
-0
lines changed

1 file changed

+101
-0
lines changed

openstack/endpoint.go

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package openstack
2+
3+
import (
4+
"slices"
5+
6+
"github.com/gophercloud/gophercloud/v2"
7+
tokens2 "github.com/gophercloud/gophercloud/v2/openstack/identity/v2/tokens"
8+
tokens3 "github.com/gophercloud/gophercloud/v2/openstack/identity/v3/tokens"
9+
)
10+
11+
/*
12+
V2Endpoint discovers the endpoint URL for a specific service from a
13+
ServiceCatalog acquired during the v2 identity service.
14+
15+
The specified EndpointOpts are used to identify a unique, unambiguous endpoint
16+
to return. It's an error both when multiple endpoints match the provided
17+
criteria and when none do. The minimum that can be specified is a Type, but you
18+
will also often need to specify a Name and/or a Region depending on what's
19+
available on your OpenStack deployment.
20+
*/
21+
func V2Endpoint(catalog *tokens2.ServiceCatalog, opts gophercloud.EndpointOpts) (string, error) {
22+
// Extract Endpoints from the catalog entries that match the requested Type, Name if provided, and Region if provided.
23+
//
24+
// If multiple endpoints are found, we return the first result and disregard the rest.
25+
// This behavior matches the Python library. See GH-1764.
26+
for _, entry := range catalog.Entries {
27+
if (slices.Contains(opts.Types(), entry.Type)) && (opts.Name == "" || entry.Name == opts.Name) {
28+
for _, endpoint := range entry.Endpoints {
29+
if opts.Region != "" && endpoint.Region != opts.Region {
30+
continue
31+
}
32+
33+
var endpointURL string
34+
switch opts.Availability {
35+
case gophercloud.AvailabilityPublic:
36+
endpointURL = gophercloud.NormalizeURL(endpoint.PublicURL)
37+
case gophercloud.AvailabilityInternal:
38+
endpointURL = gophercloud.NormalizeURL(endpoint.InternalURL)
39+
case gophercloud.AvailabilityAdmin:
40+
endpointURL = gophercloud.NormalizeURL(endpoint.AdminURL)
41+
default:
42+
err := &ErrInvalidAvailabilityProvided{}
43+
err.Argument = "Availability"
44+
err.Value = opts.Availability
45+
return "", err
46+
}
47+
48+
return endpointURL, nil
49+
}
50+
}
51+
}
52+
53+
// Report an error if there were no matching endpoints.
54+
err := &gophercloud.ErrEndpointNotFound{}
55+
return "", err
56+
}
57+
58+
/*
59+
V3Endpoint discovers the endpoint URL for a specific service from a Catalog
60+
acquired during the v3 identity service.
61+
62+
The specified EndpointOpts are used to identify a unique, unambiguous endpoint
63+
to return. It's an error both when multiple endpoints match the provided
64+
criteria and when none do. The minimum that can be specified is a Type, but you
65+
will also often need to specify a Name and/or a Region depending on what's
66+
available on your OpenStack deployment.
67+
*/
68+
func V3Endpoint(catalog *tokens3.ServiceCatalog, opts gophercloud.EndpointOpts) (string, error) {
69+
if opts.Availability != gophercloud.AvailabilityAdmin &&
70+
opts.Availability != gophercloud.AvailabilityPublic &&
71+
opts.Availability != gophercloud.AvailabilityInternal {
72+
err := &ErrInvalidAvailabilityProvided{}
73+
err.Argument = "Availability"
74+
err.Value = opts.Availability
75+
return "", err
76+
}
77+
78+
// Extract Endpoints from the catalog entries that match the requested Type, Interface,
79+
// Name if provided, and Region if provided.
80+
//
81+
// If multiple endpoints are found, we return the first result and disregard the rest.
82+
// This behavior matches the Python library. See GH-1764.
83+
for _, entry := range catalog.Entries {
84+
if (slices.Contains(opts.Types(), entry.Type)) && (opts.Name == "" || entry.Name == opts.Name) {
85+
for _, endpoint := range entry.Endpoints {
86+
if opts.Availability != gophercloud.Availability(endpoint.Interface) {
87+
continue
88+
}
89+
if opts.Region != "" && endpoint.Region != opts.Region && endpoint.RegionID != opts.Region {
90+
continue
91+
}
92+
93+
return gophercloud.NormalizeURL(endpoint.URL), nil
94+
}
95+
}
96+
}
97+
98+
// Report an error if there were no matching endpoints.
99+
err := &gophercloud.ErrEndpointNotFound{}
100+
return "", err
101+
}

0 commit comments

Comments
 (0)