blob: e1ddf6b5a7129e49d58b9ba74052df17470b5898 [file] [log] [blame]
Ash Wilsonc4360202014-08-29 14:14:24 -04001package utils
2
3import (
4 "fmt"
5
6 "github.com/racker/perigee"
7)
8
9// Version is a supported API version, corresponding to a vN package within the appropriate service.
10type Version struct {
11 ID string
12 Priority int
13}
14
15// ChooseVersion queries the base endpoint of a API to choose the most recent non-experimental alternative from a service's
16// published versions.
17// It returns the highest-Priority Version among the alternatives that are provided, as well as its corresponding endpoint.
18func ChooseVersion(baseEndpoint string, recognized []*Version) (*Version, string, error) {
19 type linkResp struct {
20 Href string `json:"href"`
21 Rel string `json:"rel"`
22 }
23
24 type valueResp struct {
25 ID string `json:"id"`
26 Status string `json:"status"`
27 Links []linkResp `json:"links"`
28 }
29
30 type versionsResp struct {
31 Values []valueResp `json:"values"`
32 }
33
34 type response struct {
35 Versions versionsResp `json:"versions"`
36 }
37
38 var resp response
39 _, err := perigee.Request("GET", baseEndpoint, perigee.Options{
40 Results: &resp,
41 OkCodes: []int{200},
42 })
43
44 if err != nil {
45 return nil, "", err
46 }
47
48 byID := make(map[string]*Version)
49 for _, version := range recognized {
50 byID[version.ID] = version
51 }
52
53 var highest *Version
54 var endpoint string
55
56 for _, value := range resp.Versions.Values {
57 if matching, ok := byID[value.ID]; ok {
58 if highest == nil || matching.Priority > highest.Priority {
59 highest = matching
60
61 found := false
62 for _, link := range value.Links {
63 if link.Rel == "self" {
64 found = true
65 endpoint = link.Href
66 }
67 }
68
69 if !found {
70 return nil, "", fmt.Errorf("Endpoint missing in version %s response from %s", value.ID, baseEndpoint)
71 }
72 }
73 }
74 }
75
76 if highest == nil || endpoint == "" {
77 return nil, "", fmt.Errorf("No supported version available from endpoint %s", baseEndpoint)
78 }
79
80 return highest, endpoint, nil
81}