|
1 | 1 | package clientcmd
|
2 | 2 |
|
3 | 3 | import (
|
4 |
| - "encoding/json" |
5 | 4 | "fmt"
|
6 | 5 |
|
7 |
| - "github.com/blang/semver" |
| 6 | + "k8s.io/apimachinery/pkg/api/errors" |
| 7 | + "k8s.io/apimachinery/pkg/apis/meta/v1" |
| 8 | + "k8s.io/apimachinery/pkg/runtime/schema" |
| 9 | + "k8s.io/client-go/discovery" |
8 | 10 |
|
9 |
| - "github.com/openshift/origin/pkg/client" |
10 |
| - "github.com/openshift/origin/pkg/version" |
| 11 | + "github.com/openshift/origin/pkg/authorization/apis/authorization" |
11 | 12 | )
|
12 | 13 |
|
13 |
| -// Gate returns an error if the server is below minServerVersion or above/equal maxServerVersion. |
14 |
| -// To test only for min or only max version, set the other string to the empty value. |
15 |
| -func Gate(ocClient *client.Client, minServerVersion, maxServerVersion string) error { |
16 |
| - if len(minServerVersion) == 0 && len(maxServerVersion) == 0 { |
17 |
| - return fmt.Errorf("No version info passed to gate command") |
18 |
| - } |
| 14 | +// LegacyPolicyResourceGate returns err if the server does not support the set of legacy policy objects (< 3.7) |
| 15 | +func LegacyPolicyResourceGate(client discovery.ServerResourcesInterface) error { |
| 16 | + // The server must support the 4 legacy policy objects in either of the GV schemes. |
| 17 | + _, all, err := DiscoverGroupVersionResources(client, |
| 18 | + schema.GroupVersionResource{ |
| 19 | + Group: authorization.LegacySchemeGroupVersion.Group, |
| 20 | + Version: authorization.LegacySchemeGroupVersion.Version, |
| 21 | + Resource: "clusterpolicies", |
| 22 | + }, |
| 23 | + schema.GroupVersionResource{ |
| 24 | + Group: authorization.LegacySchemeGroupVersion.Group, |
| 25 | + Version: authorization.LegacySchemeGroupVersion.Version, |
| 26 | + Resource: "clusterpolicybindings", |
| 27 | + }, |
| 28 | + schema.GroupVersionResource{ |
| 29 | + Group: authorization.LegacySchemeGroupVersion.Group, |
| 30 | + Version: authorization.LegacySchemeGroupVersion.Version, |
| 31 | + Resource: "policies", |
| 32 | + }, |
| 33 | + schema.GroupVersionResource{ |
| 34 | + Group: authorization.LegacySchemeGroupVersion.Group, |
| 35 | + Version: authorization.LegacySchemeGroupVersion.Version, |
| 36 | + Resource: "policybindings", |
| 37 | + }, |
| 38 | + ) |
19 | 39 |
|
20 |
| - ocVersionBody, err := ocClient.Get().AbsPath("/version/openshift").Do().Raw() |
21 | 40 | if err != nil {
|
22 | 41 | return err
|
23 | 42 | }
|
24 |
| - ocServerInfo := &version.Info{} |
25 |
| - if err := json.Unmarshal(ocVersionBody, ocServerInfo); err != nil { |
26 |
| - return err |
| 43 | + if all { |
| 44 | + return nil |
27 | 45 | }
|
28 |
| - ocVersion := ocServerInfo.String() |
29 |
| - // skip first chracter as Openshift returns a 'v' preceding the actual |
30 |
| - // version string which semver does not grok |
31 |
| - semVersion, err := semver.Parse(ocVersion[1:]) |
| 46 | + _, all, err = DiscoverGroupVersionResources(client, |
| 47 | + schema.GroupVersionResource{ |
| 48 | + Group: authorization.SchemeGroupVersion.Group, |
| 49 | + Version: authorization.SchemeGroupVersion.Version, |
| 50 | + Resource: "clusterpolicies", |
| 51 | + }, |
| 52 | + schema.GroupVersionResource{ |
| 53 | + Group: authorization.SchemeGroupVersion.Group, |
| 54 | + Version: authorization.SchemeGroupVersion.Version, |
| 55 | + Resource: "clusterpolicybindings", |
| 56 | + }, |
| 57 | + schema.GroupVersionResource{ |
| 58 | + Group: authorization.SchemeGroupVersion.Group, |
| 59 | + Version: authorization.SchemeGroupVersion.Version, |
| 60 | + Resource: "policies", |
| 61 | + }, |
| 62 | + schema.GroupVersionResource{ |
| 63 | + Group: authorization.SchemeGroupVersion.Group, |
| 64 | + Version: authorization.SchemeGroupVersion.Version, |
| 65 | + Resource: "policybindings", |
| 66 | + }, |
| 67 | + ) |
| 68 | + |
32 | 69 | if err != nil {
|
33 |
| - return fmt.Errorf("Failed to parse server version %s: %v", ocVersion, err) |
| 70 | + return err |
| 71 | + } |
| 72 | + if all { |
| 73 | + return nil |
34 | 74 | }
|
35 |
| - // ignore pre-release version info |
36 |
| - semVersion.Pre = nil |
37 | 75 |
|
38 |
| - if len(minServerVersion) > 0 { |
39 |
| - min, err := semver.Parse(minServerVersion) |
40 |
| - if err != nil { |
41 |
| - return fmt.Errorf("Failed to parse min gate version %s: %v", minServerVersion, err) |
42 |
| - } |
43 |
| - // ignore pre-release version info |
44 |
| - min.Pre = nil |
45 |
| - if semVersion.LT(min) { |
46 |
| - return fmt.Errorf("This command works only with server versions > %s, found %s", minServerVersion, ocVersion) |
47 |
| - } |
| 76 | + return fmt.Errorf("the server does not support legacy policy resources") |
| 77 | +} |
| 78 | + |
| 79 | +// DiscoverGroupVersionResources performs a server resource discovery for each filterGVR, returning a slice of |
| 80 | +// GVRs for the matching Resources, and a bool for "all" indicating that each item in filterGVR was found. |
| 81 | +func DiscoverGroupVersionResources(client discovery.ServerResourcesInterface, filterGVR ...schema.GroupVersionResource) ([]schema.GroupVersionResource, bool, error) { |
| 82 | + if len(filterGVR) == 0 { |
| 83 | + return nil, false, fmt.Errorf("at least one GroupVersionResource must be provided") |
48 | 84 | }
|
49 | 85 |
|
50 |
| - if len(maxServerVersion) > 0 { |
51 |
| - max, err := semver.Parse(maxServerVersion) |
52 |
| - if err != nil { |
53 |
| - return fmt.Errorf("Failed to parse max gate version %s: %v", maxServerVersion, err) |
| 86 | + var groupVersionCache = make(map[string]*v1.APIResourceList) |
| 87 | + all := true |
| 88 | + ret := []schema.GroupVersionResource{} |
| 89 | + for i := range filterGVR { |
| 90 | + var serverResources *v1.APIResourceList |
| 91 | + var err error |
| 92 | + |
| 93 | + // Discover the list of resources for this GVR, with a cache of resources per GV to avoid extra round trips |
| 94 | + gv := filterGVR[i].GroupVersion() |
| 95 | + if cachedList, ok := groupVersionCache[gv.String()]; ok { |
| 96 | + serverResources = cachedList |
| 97 | + } else { |
| 98 | + serverResources, err = client.ServerResourcesForGroupVersion(gv.String()) |
| 99 | + if err != nil && errors.IsNotFound(err) { |
| 100 | + // Cache an empty resource list when not found, we don't want another discovery |
| 101 | + groupVersionCache[gv.String()] = &v1.APIResourceList{} |
| 102 | + all = false |
| 103 | + continue |
| 104 | + } |
| 105 | + |
| 106 | + if err != nil { |
| 107 | + return nil, false, err |
| 108 | + } |
| 109 | + |
| 110 | + groupVersionCache[gv.String()] = serverResources |
54 | 111 | }
|
55 |
| - // ignore pre-release version info |
56 |
| - max.Pre = nil |
57 |
| - if semVersion.GTE(max) { |
58 |
| - return fmt.Errorf("This command works only with server versions < %s, found %s", maxServerVersion, ocVersion) |
| 112 | + |
| 113 | + seen := false |
| 114 | + // Add matching resources to the return slice |
| 115 | + for _, resource := range serverResources.APIResources { |
| 116 | + if filterGVR[i].Resource == resource.Name { |
| 117 | + seen = true |
| 118 | + ret = append(ret, filterGVR[i]) |
| 119 | + break |
| 120 | + } |
59 | 121 | }
|
| 122 | + all = all && seen |
60 | 123 | }
|
61 | 124 |
|
62 |
| - // OK this is within min/max all good! |
63 |
| - return nil |
| 125 | + return ret, all, nil |
64 | 126 | }
|
0 commit comments