@@ -2,20 +2,64 @@ package openstack
22
33import (
44 "context"
5+ "regexp"
56 "slices"
7+ "strconv"
68
79 "github.com/gophercloud/gophercloud/v2"
810 tokens2 "github.com/gophercloud/gophercloud/v2/openstack/identity/v2/tokens"
911 tokens3 "github.com/gophercloud/gophercloud/v2/openstack/identity/v3/tokens"
1012 "github.com/gophercloud/gophercloud/v2/openstack/utils"
1113)
1214
15+ var versionedServiceTypeAliasRegexp = regexp .MustCompile (`^.*v(\d)$` )
16+
17+ func extractServiceTypeVersion (serviceType string ) int {
18+ matches := versionedServiceTypeAliasRegexp .FindAllStringSubmatch (serviceType , 1 )
19+ if matches != nil {
20+ // no point converting to an int
21+ ret , err := strconv .Atoi (matches [0 ][1 ])
22+ if err != nil {
23+ return 0
24+ }
25+ return ret
26+ }
27+ return 0
28+ }
29+
1330func endpointSupportsVersion (ctx context.Context , client * gophercloud.ProviderClient , serviceType , endpointURL string , expectedVersion int ) (bool , error ) {
1431 // Swift doesn't support version discovery :(
1532 if expectedVersion == 0 || serviceType == "object-store" {
1633 return true , nil
1734 }
1835
36+ // Repeating verbatim from keystoneauth1 [1]:
37+ //
38+ // > The sins of our fathers become the blood on our hands.
39+ // > If a user requests an old-style service type such as volumev2, then they
40+ // > are inherently requesting the major API version 2. It's not a good
41+ // > interface, but it's the one that was imposed on the world years ago
42+ // > because the client libraries all hid the version discovery document.
43+ // > In order to be able to ensure that a user who requests volumev2 does not
44+ // > get a block-storage endpoint that only provides v3 of the block-storage
45+ // > service, we need to pull the version out of the service_type. The
46+ // > service-types-authority will prevent the growth of new monstrosities such
47+ // > as this, but in order to move forward without breaking people, we have
48+ // > to just cry in the corner while striking ourselves with thorned branches.
49+ // > That said, for sure only do this hack for officially known service_types.
50+ //
51+ // So yeah, what mordred said.
52+ //
53+ // https://github.com/openstack/keystoneauth/blob/5.10.0/keystoneauth1/discover.py#L270-L290
54+ impliedVersion := extractServiceTypeVersion (serviceType )
55+ if impliedVersion != 0 && impliedVersion != expectedVersion {
56+ return false , nil
57+ }
58+
59+ // NOTE(stephenfin) In addition to the above, keystoneauth also supports a URL
60+ // hack whereby it will extract the version from the URL. We may wish to
61+ // implement this too.
62+
1963 endpointURL , err := utils .BaseVersionedEndpoint (endpointURL )
2064 if err != nil {
2165 return false , err
0 commit comments