7 "github.com/gophercloud/gophercloud"
10 // Version is a supported API version, corresponding to a vN package within the appropriate service.
17 var goodStatus = map[string]bool{
23 // ChooseVersion queries the base endpoint of an API to choose the most recent non-experimental alternative from a service's
24 // published versions.
25 // It returns the highest-Priority Version among the alternatives that are provided, as well as its corresponding endpoint.
26 func ChooseVersion(client *gophercloud.ProviderClient, recognized []*Version) (*Version, string, error) {
27 type linkResp struct {
28 Href string `json:"href"`
29 Rel string `json:"rel"`
32 type valueResp struct {
34 Status string `json:"status"`
35 Links []linkResp `json:"links"`
38 type versionsResp struct {
39 Values []valueResp `json:"values"`
42 type response struct {
43 Versions versionsResp `json:"versions"`
46 normalize := func(endpoint string) string {
47 if !strings.HasSuffix(endpoint, "/") {
52 identityEndpoint := normalize(client.IdentityEndpoint)
54 // If a full endpoint is specified, check version suffixes for a match first.
55 for _, v := range recognized {
56 if strings.HasSuffix(identityEndpoint, v.Suffix) {
57 return v, identityEndpoint, nil
62 _, err := client.Request("GET", client.IdentityBase, &gophercloud.RequestOpts{
64 OkCodes: []int{200, 300},
74 for _, value := range resp.Versions.Values {
76 for _, link := range value.Links {
77 if link.Rel == "self" {
78 href = normalize(link.Href)
82 for _, version := range recognized {
83 if strings.Contains(value.ID, version.ID) {
84 // Prefer a version that exactly matches the provided endpoint.
85 if href == identityEndpoint {
87 return nil, "", fmt.Errorf("Endpoint missing in version %s response from %s", value.ID, client.IdentityBase)
89 return version, href, nil
92 // Otherwise, find the highest-priority version with a whitelisted status.
93 if goodStatus[strings.ToLower(value.Status)] {
94 if highest == nil || version.Priority > highest.Priority {
104 return nil, "", fmt.Errorf("No supported version available from endpoint %s", client.IdentityBase)
107 return nil, "", fmt.Errorf("Endpoint missing in version %s response from %s", highest.ID, client.IdentityBase)
110 return highest, endpoint, nil