Browse code

cleanup bootstrap policy to allow future changes

deads2k authored on 2016/05/28 04:05:05
Showing 7 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,91 @@
0
+package api
1
+
2
+import (
3
+	"k8s.io/kubernetes/pkg/util/sets"
4
+)
5
+
6
+// NEVER TOUCH ANYTHING IN THIS FILE!
7
+
8
+const (
9
+	// ResourceGroupPrefix is the prefix for indicating that a resource entry is actually a group of resources.  The groups are defined in code and indicate resources that are commonly permissioned together
10
+	ResourceGroupPrefix = "resourcegroup:"
11
+	BuildGroupName      = ResourceGroupPrefix + "builds"
12
+	DeploymentGroupName = ResourceGroupPrefix + "deployments"
13
+	ImageGroupName      = ResourceGroupPrefix + "images"
14
+	OAuthGroupName      = ResourceGroupPrefix + "oauth"
15
+	UserGroupName       = ResourceGroupPrefix + "users"
16
+	TemplateGroupName   = ResourceGroupPrefix + "templates"
17
+	SDNGroupName        = ResourceGroupPrefix + "sdn"
18
+	// PolicyOwnerGroupName includes the physical resources behind the PermissionGrantingGroupName.  Unless these physical objects are created first, users with privileges to PermissionGrantingGroupName will
19
+	// only be able to bind to global roles
20
+	PolicyOwnerGroupName = ResourceGroupPrefix + "policy"
21
+	// PermissionGrantingGroupName includes resources that are necessary to maintain authorization roles and bindings.  By itself, this group is insufficient to create anything except for bindings
22
+	// to master roles.  If a local Policy already exists, then privileges to this group will allow for modification of local roles.
23
+	PermissionGrantingGroupName = ResourceGroupPrefix + "granter"
24
+	// OpenshiftExposedGroupName includes resources that are commonly viewed and modified by end users of the system.  It does not include any sensitive resources that control authentication or authorization
25
+	OpenshiftExposedGroupName = ResourceGroupPrefix + "exposedopenshift"
26
+	OpenshiftAllGroupName     = ResourceGroupPrefix + "allopenshift"
27
+	OpenshiftStatusGroupName  = ResourceGroupPrefix + "allopenshift-status"
28
+
29
+	QuotaGroupName = ResourceGroupPrefix + "quota"
30
+	// KubeInternalsGroupName includes those resources that should reasonably be viewable to end users, but that most users should probably not modify.  Kubernetes herself will maintain these resources
31
+	KubeInternalsGroupName = ResourceGroupPrefix + "privatekube"
32
+	// KubeExposedGroupName includes resources that are commonly viewed and modified by end users of the system.
33
+	KubeExposedGroupName = ResourceGroupPrefix + "exposedkube"
34
+	KubeAllGroupName     = ResourceGroupPrefix + "allkube"
35
+	KubeStatusGroupName  = ResourceGroupPrefix + "allkube-status"
36
+
37
+	// NonEscalatingResourcesGroupName contains all resources that can be viewed without exposing the risk of using view rights to locate a secret to escalate privileges.  For example, view
38
+	// rights on secrets could be used locate a secret that happened to be  serviceaccount token that has more privileges
39
+	NonEscalatingResourcesGroupName         = ResourceGroupPrefix + "non-escalating"
40
+	KubeNonEscalatingViewableGroupName      = ResourceGroupPrefix + "kube-non-escalating"
41
+	OpenshiftNonEscalatingViewableGroupName = ResourceGroupPrefix + "openshift-non-escalating"
42
+
43
+	// EscalatingResourcesGroupName contains all resources that can be used to escalate privileges when simply viewed
44
+	EscalatingResourcesGroupName         = ResourceGroupPrefix + "escalating"
45
+	KubeEscalatingViewableGroupName      = ResourceGroupPrefix + "kube-escalating"
46
+	OpenshiftEscalatingViewableGroupName = ResourceGroupPrefix + "openshift-escalating"
47
+)
48
+
49
+var (
50
+	GroupsToResources = map[string][]string{
51
+		BuildGroupName:       {"builds", "buildconfigs", "buildlogs", "buildconfigs/instantiate", "buildconfigs/instantiatebinary", "builds/log", "builds/clone", "buildconfigs/webhooks"},
52
+		ImageGroupName:       {"imagestreams", "imagestreammappings", "imagestreamtags", "imagestreamimages", "imagestreamimports"},
53
+		DeploymentGroupName:  {"deploymentconfigs", "generatedeploymentconfigs", "deploymentconfigrollbacks", "deploymentconfigs/log", "deploymentconfigs/scale"},
54
+		SDNGroupName:         {"clusternetworks", "hostsubnets", "netnamespaces"},
55
+		TemplateGroupName:    {"templates", "templateconfigs", "processedtemplates"},
56
+		UserGroupName:        {"identities", "users", "useridentitymappings", "groups"},
57
+		OAuthGroupName:       {"oauthauthorizetokens", "oauthaccesstokens", "oauthclients", "oauthclientauthorizations"},
58
+		PolicyOwnerGroupName: {"policies", "policybindings"},
59
+
60
+		// RAR and SAR are in this list to support backwards compatibility with clients that expect access to those resource in a namespace scope and a cluster scope.
61
+		// TODO remove once we have eliminated the namespace scoped resource.
62
+		PermissionGrantingGroupName: {"roles", "rolebindings", "resourceaccessreviews" /* cluster scoped*/, "subjectaccessreviews" /* cluster scoped*/, "localresourceaccessreviews", "localsubjectaccessreviews"},
63
+		OpenshiftExposedGroupName:   {BuildGroupName, ImageGroupName, DeploymentGroupName, TemplateGroupName, "routes"},
64
+		OpenshiftAllGroupName: {OpenshiftExposedGroupName, UserGroupName, OAuthGroupName, PolicyOwnerGroupName, SDNGroupName, PermissionGrantingGroupName, OpenshiftStatusGroupName, "projects",
65
+			"clusterroles", "clusterrolebindings", "clusterpolicies", "clusterpolicybindings", "images" /* cluster scoped*/, "projectrequests", "builds/details", "imagestreams/secrets",
66
+			"selfsubjectrulesreviews"},
67
+		OpenshiftStatusGroupName: {"imagestreams/status", "routes/status", "deploymentconfigs/status"},
68
+
69
+		QuotaGroupName:         {"limitranges", "resourcequotas", "resourcequotausages"},
70
+		KubeExposedGroupName:   {"pods", "replicationcontrollers", "serviceaccounts", "services", "endpoints", "persistentvolumeclaims", "pods/log", "configmaps"},
71
+		KubeInternalsGroupName: {"minions", "nodes", "bindings", "events", "namespaces", "persistentvolumes", "securitycontextconstraints"},
72
+		KubeAllGroupName:       {KubeInternalsGroupName, KubeExposedGroupName, QuotaGroupName},
73
+		KubeStatusGroupName:    {"pods/status", "resourcequotas/status", "namespaces/status", "replicationcontrollers/status"},
74
+
75
+		OpenshiftEscalatingViewableGroupName: {"oauthauthorizetokens", "oauthaccesstokens", "imagestreams/secrets"},
76
+		KubeEscalatingViewableGroupName:      {"secrets"},
77
+		EscalatingResourcesGroupName:         {OpenshiftEscalatingViewableGroupName, KubeEscalatingViewableGroupName},
78
+
79
+		NonEscalatingResourcesGroupName: {OpenshiftNonEscalatingViewableGroupName, KubeNonEscalatingViewableGroupName},
80
+	}
81
+)
82
+
83
+func init() {
84
+	// set the non-escalating groups
85
+	GroupsToResources[OpenshiftNonEscalatingViewableGroupName] = NormalizeResources(sets.NewString(GroupsToResources[OpenshiftAllGroupName]...)).
86
+		Difference(NormalizeResources(sets.NewString(GroupsToResources[OpenshiftEscalatingViewableGroupName]...))).List()
87
+
88
+	GroupsToResources[KubeNonEscalatingViewableGroupName] = NormalizeResources(sets.NewString(GroupsToResources[KubeAllGroupName]...)).
89
+		Difference(NormalizeResources(sets.NewString(GroupsToResources[KubeEscalatingViewableGroupName]...))).List()
90
+}
... ...
@@ -38,81 +38,6 @@ const (
38 38
 	SystemGroupResource    = "systemgroups"
39 39
 )
40 40
 
41
-const (
42
-	// ResourceGroupPrefix is the prefix for indicating that a resource entry is actually a group of resources.  The groups are defined in code and indicate resources that are commonly permissioned together
43
-	ResourceGroupPrefix = "resourcegroup:"
44
-	BuildGroupName      = ResourceGroupPrefix + "builds"
45
-	DeploymentGroupName = ResourceGroupPrefix + "deployments"
46
-	ImageGroupName      = ResourceGroupPrefix + "images"
47
-	OAuthGroupName      = ResourceGroupPrefix + "oauth"
48
-	UserGroupName       = ResourceGroupPrefix + "users"
49
-	TemplateGroupName   = ResourceGroupPrefix + "templates"
50
-	SDNGroupName        = ResourceGroupPrefix + "sdn"
51
-	// PolicyOwnerGroupName includes the physical resources behind the PermissionGrantingGroupName.  Unless these physical objects are created first, users with privileges to PermissionGrantingGroupName will
52
-	// only be able to bind to global roles
53
-	PolicyOwnerGroupName = ResourceGroupPrefix + "policy"
54
-	// PermissionGrantingGroupName includes resources that are necessary to maintain authorization roles and bindings.  By itself, this group is insufficient to create anything except for bindings
55
-	// to master roles.  If a local Policy already exists, then privileges to this group will allow for modification of local roles.
56
-	PermissionGrantingGroupName = ResourceGroupPrefix + "granter"
57
-	// OpenshiftExposedGroupName includes resources that are commonly viewed and modified by end users of the system.  It does not include any sensitive resources that control authentication or authorization
58
-	OpenshiftExposedGroupName = ResourceGroupPrefix + "exposedopenshift"
59
-	OpenshiftAllGroupName     = ResourceGroupPrefix + "allopenshift"
60
-	OpenshiftStatusGroupName  = ResourceGroupPrefix + "allopenshift-status"
61
-
62
-	QuotaGroupName = ResourceGroupPrefix + "quota"
63
-	// KubeInternalsGroupName includes those resources that should reasonably be viewable to end users, but that most users should probably not modify.  Kubernetes herself will maintain these resources
64
-	KubeInternalsGroupName = ResourceGroupPrefix + "privatekube"
65
-	// KubeExposedGroupName includes resources that are commonly viewed and modified by end users of the system.
66
-	KubeExposedGroupName = ResourceGroupPrefix + "exposedkube"
67
-	KubeAllGroupName     = ResourceGroupPrefix + "allkube"
68
-	KubeStatusGroupName  = ResourceGroupPrefix + "allkube-status"
69
-
70
-	// NonEscalatingResourcesGroupName contains all resources that can be viewed without exposing the risk of using view rights to locate a secret to escalate privileges.  For example, view
71
-	// rights on secrets could be used locate a secret that happened to be  serviceaccount token that has more privileges
72
-	NonEscalatingResourcesGroupName         = ResourceGroupPrefix + "non-escalating"
73
-	KubeNonEscalatingViewableGroupName      = ResourceGroupPrefix + "kube-non-escalating"
74
-	OpenshiftNonEscalatingViewableGroupName = ResourceGroupPrefix + "openshift-non-escalating"
75
-
76
-	// EscalatingResourcesGroupName contains all resources that can be used to escalate privileges when simply viewed
77
-	EscalatingResourcesGroupName         = ResourceGroupPrefix + "escalating"
78
-	KubeEscalatingViewableGroupName      = ResourceGroupPrefix + "kube-escalating"
79
-	OpenshiftEscalatingViewableGroupName = ResourceGroupPrefix + "openshift-escalating"
80
-)
81
-
82
-var (
83
-	GroupsToResources = map[string][]string{
84
-		BuildGroupName:       {"builds", "buildconfigs", "buildlogs", "buildconfigs/instantiate", "buildconfigs/instantiatebinary", "builds/log", "builds/clone", "buildconfigs/webhooks"},
85
-		ImageGroupName:       {"imagestreams", "imagestreammappings", "imagestreamtags", "imagestreamimages", "imagestreamimports"},
86
-		DeploymentGroupName:  {"deploymentconfigs", "generatedeploymentconfigs", "deploymentconfigrollbacks", "deploymentconfigs/log", "deploymentconfigs/scale"},
87
-		SDNGroupName:         {"clusternetworks", "hostsubnets", "netnamespaces"},
88
-		TemplateGroupName:    {"templates", "templateconfigs", "processedtemplates"},
89
-		UserGroupName:        {"identities", "users", "useridentitymappings", "groups"},
90
-		OAuthGroupName:       {"oauthauthorizetokens", "oauthaccesstokens", "oauthclients", "oauthclientauthorizations"},
91
-		PolicyOwnerGroupName: {"policies", "policybindings"},
92
-
93
-		// RAR and SAR are in this list to support backwards compatibility with clients that expect access to those resource in a namespace scope and a cluster scope.
94
-		// TODO remove once we have eliminated the namespace scoped resource.
95
-		PermissionGrantingGroupName: {"roles", "rolebindings", "resourceaccessreviews" /* cluster scoped*/, "subjectaccessreviews" /* cluster scoped*/, "localresourceaccessreviews", "localsubjectaccessreviews"},
96
-		OpenshiftExposedGroupName:   {BuildGroupName, ImageGroupName, DeploymentGroupName, TemplateGroupName, "routes"},
97
-		OpenshiftAllGroupName: {OpenshiftExposedGroupName, UserGroupName, OAuthGroupName, PolicyOwnerGroupName, SDNGroupName, PermissionGrantingGroupName, OpenshiftStatusGroupName, "projects",
98
-			"clusterroles", "clusterrolebindings", "clusterpolicies", "clusterpolicybindings", "images" /* cluster scoped*/, "projectrequests", "builds/details", "imagestreams/secrets",
99
-			"selfsubjectrulesreviews"},
100
-		OpenshiftStatusGroupName: {"imagestreams/status", "routes/status", "deploymentconfigs/status"},
101
-
102
-		QuotaGroupName:         {"limitranges", "resourcequotas", "resourcequotausages"},
103
-		KubeExposedGroupName:   {"pods", "replicationcontrollers", "serviceaccounts", "services", "endpoints", "persistentvolumeclaims", "pods/log", "configmaps"},
104
-		KubeInternalsGroupName: {"minions", "nodes", "bindings", "events", "namespaces", "persistentvolumes", "securitycontextconstraints"},
105
-		KubeAllGroupName:       {KubeInternalsGroupName, KubeExposedGroupName, QuotaGroupName},
106
-		KubeStatusGroupName:    {"pods/status", "resourcequotas/status", "namespaces/status", "replicationcontrollers/status"},
107
-
108
-		OpenshiftEscalatingViewableGroupName: {"oauthauthorizetokens", "oauthaccesstokens", "imagestreams/secrets"},
109
-		KubeEscalatingViewableGroupName:      {"secrets"},
110
-		EscalatingResourcesGroupName:         {OpenshiftEscalatingViewableGroupName, KubeEscalatingViewableGroupName},
111
-
112
-		NonEscalatingResourcesGroupName: {OpenshiftNonEscalatingViewableGroupName, KubeNonEscalatingViewableGroupName},
113
-	}
114
-)
115
-
116 41
 // DiscoveryRule is a rule that allows a client to discover the API resources available on this server
117 42
 var DiscoveryRule = PolicyRule{
118 43
 	Verbs: sets.NewString("get"),
... ...
@@ -128,15 +53,6 @@ var DiscoveryRule = PolicyRule{
128 128
 	),
129 129
 }
130 130
 
131
-func init() {
132
-	// set the non-escalating groups
133
-	GroupsToResources[OpenshiftNonEscalatingViewableGroupName] = NormalizeResources(sets.NewString(GroupsToResources[OpenshiftAllGroupName]...)).
134
-		Difference(NormalizeResources(sets.NewString(GroupsToResources[OpenshiftEscalatingViewableGroupName]...))).List()
135
-
136
-	GroupsToResources[KubeNonEscalatingViewableGroupName] = NormalizeResources(sets.NewString(GroupsToResources[KubeAllGroupName]...)).
137
-		Difference(NormalizeResources(sets.NewString(GroupsToResources[KubeEscalatingViewableGroupName]...))).List()
138
-}
139
-
140 131
 // PolicyRule holds information that describes a policy rule, but does not contain information
141 132
 // about who the rule applies to or which namespace the rule applies to.
142 133
 type PolicyRule struct {
... ...
@@ -3,23 +3,13 @@ package bootstrappolicy_test
3 3
 import (
4 4
 	"testing"
5 5
 
6
-	kapi "k8s.io/kubernetes/pkg/api"
7
-	"k8s.io/kubernetes/pkg/apis/autoscaling"
8
-	"k8s.io/kubernetes/pkg/apis/batch"
9
-	"k8s.io/kubernetes/pkg/apis/extensions"
10
-	"k8s.io/kubernetes/pkg/util/sets"
11
-
12
-	"github.com/openshift/origin/pkg/api"
13 6
 	authorizationapi "github.com/openshift/origin/pkg/authorization/api"
14
-	authorizationapiv1 "github.com/openshift/origin/pkg/authorization/api/v1"
15 7
 	"github.com/openshift/origin/pkg/authorization/rulevalidation"
16 8
 	"github.com/openshift/origin/pkg/cmd/server/bootstrappolicy"
17
-	imageapi "github.com/openshift/origin/pkg/image/api"
18
-	projectapi "github.com/openshift/origin/pkg/project/api"
19
-	routeapi "github.com/openshift/origin/pkg/route/api"
20 9
 )
21 10
 
22
-func TestClusterRoles(t *testing.T) {
11
+// leave this in place so I can use when converting the SAs
12
+func DisableTestClusterRoles(t *testing.T) {
23 13
 	currentRoles := bootstrappolicy.GetBootstrapClusterRoles()
24 14
 	oldRoles := oldGetBootstrapClusterRoles()
25 15
 
... ...
@@ -42,860 +32,6 @@ func TestClusterRoles(t *testing.T) {
42 42
 	}
43 43
 }
44 44
 
45
-func oldGetBootstrapOpenshiftRoles(openshiftNamespace string) []authorizationapi.Role {
46
-	roles := []authorizationapi.Role{
47
-		{
48
-			ObjectMeta: kapi.ObjectMeta{
49
-				Name:      bootstrappolicy.OpenshiftSharedResourceViewRoleName,
50
-				Namespace: openshiftNamespace,
51
-			},
52
-			Rules: []authorizationapi.PolicyRule{
53
-				{
54
-					Verbs:     sets.NewString("get", "list"),
55
-					Resources: sets.NewString("templates", authorizationapi.ImageGroupName),
56
-				},
57
-				{
58
-					// so anyone can pull from openshift/* image streams
59
-					Verbs:     sets.NewString("get"),
60
-					Resources: sets.NewString("imagestreams/layers"),
61
-				},
62
-			},
63
-		},
64
-	}
65
-
66
-	// we don't want to expose the resourcegroups externally because it makes it very difficult for customers to learn from
67
-	// our default roles and hard for them to reason about what power they are granting their users
68
-	for i := range roles {
69
-		for j := range roles[i].Rules {
70
-			roles[i].Rules[j].Resources = authorizationapi.NormalizeResources(roles[i].Rules[j].Resources)
71
-		}
72
-	}
73
-
74
-	return roles
75
-
76
-}
77
-
78 45
 func oldGetBootstrapClusterRoles() []authorizationapi.ClusterRole {
79
-	roles := []authorizationapi.ClusterRole{
80
-		{
81
-			ObjectMeta: kapi.ObjectMeta{
82
-				Name: bootstrappolicy.ClusterAdminRoleName,
83
-			},
84
-			Rules: []authorizationapi.PolicyRule{
85
-				{
86
-					APIGroups: []string{authorizationapi.APIGroupAll},
87
-					Verbs:     sets.NewString(authorizationapi.VerbAll),
88
-					Resources: sets.NewString(authorizationapi.ResourceAll),
89
-				},
90
-				{
91
-					Verbs:           sets.NewString(authorizationapi.VerbAll),
92
-					NonResourceURLs: sets.NewString(authorizationapi.NonResourceAll),
93
-				},
94
-			},
95
-		},
96
-		{
97
-			ObjectMeta: kapi.ObjectMeta{
98
-				Name: bootstrappolicy.SudoerRoleName,
99
-			},
100
-			Rules: []authorizationapi.PolicyRule{
101
-				{
102
-					APIGroups:     []string{kapi.GroupName},
103
-					Verbs:         sets.NewString("impersonate"),
104
-					Resources:     sets.NewString(authorizationapi.SystemUserResource),
105
-					ResourceNames: sets.NewString(bootstrappolicy.SystemAdminUsername),
106
-				},
107
-			},
108
-		},
109
-		{
110
-			ObjectMeta: kapi.ObjectMeta{
111
-				Name: bootstrappolicy.ClusterReaderRoleName,
112
-			},
113
-			Rules: []authorizationapi.PolicyRule{
114
-				{
115
-					Verbs:     sets.NewString("get", "list", "watch"),
116
-					Resources: sets.NewString(authorizationapi.NonEscalatingResourcesGroupName),
117
-				},
118
-				{
119
-					APIGroups: []string{autoscaling.GroupName},
120
-					Verbs:     sets.NewString("get", "list", "watch"),
121
-					Resources: sets.NewString("horizontalpodautoscalers"),
122
-				},
123
-				{
124
-					APIGroups: []string{batch.GroupName},
125
-					Verbs:     sets.NewString("get", "list", "watch"),
126
-					Resources: sets.NewString("jobs"),
127
-				},
128
-				{
129
-					APIGroups: []string{extensions.GroupName},
130
-					Verbs:     sets.NewString("get", "list", "watch"),
131
-					Resources: sets.NewString("daemonsets", "jobs", "horizontalpodautoscalers", "replicationcontrollers/scale"),
132
-				},
133
-				{ // permissions to check access.  These creates are non-mutating
134
-					Verbs:     sets.NewString("create"),
135
-					Resources: sets.NewString("resourceaccessreviews", "subjectaccessreviews"),
136
-				},
137
-				// Allow read access to node metrics
138
-				{
139
-					Verbs:     sets.NewString("get"),
140
-					Resources: sets.NewString(authorizationapi.NodeMetricsResource),
141
-				},
142
-				// Allow read access to stats
143
-				// Node stats requests are submitted as POSTs.  These creates are non-mutating
144
-				{
145
-					Verbs:     sets.NewString("get", "create"),
146
-					Resources: sets.NewString(authorizationapi.NodeStatsResource),
147
-				},
148
-				{
149
-					Verbs:           sets.NewString("get"),
150
-					NonResourceURLs: sets.NewString(authorizationapi.NonResourceAll),
151
-				},
152
-			},
153
-		},
154
-		{
155
-			ObjectMeta: kapi.ObjectMeta{
156
-				Name: bootstrappolicy.BuildStrategyDockerRoleName,
157
-			},
158
-			Rules: []authorizationapi.PolicyRule{
159
-				{
160
-					APIGroups: []string{api.GroupName},
161
-					Verbs:     sets.NewString("create"),
162
-					Resources: sets.NewString(authorizationapi.DockerBuildResource),
163
-				},
164
-			},
165
-		},
166
-		{
167
-			ObjectMeta: kapi.ObjectMeta{
168
-				Name: bootstrappolicy.BuildStrategyCustomRoleName,
169
-			},
170
-			Rules: []authorizationapi.PolicyRule{
171
-				{
172
-					APIGroups: []string{api.GroupName},
173
-					Verbs:     sets.NewString("create"),
174
-					Resources: sets.NewString(authorizationapi.CustomBuildResource),
175
-				},
176
-			},
177
-		},
178
-		{
179
-			ObjectMeta: kapi.ObjectMeta{
180
-				Name: bootstrappolicy.BuildStrategySourceRoleName,
181
-			},
182
-			Rules: []authorizationapi.PolicyRule{
183
-				{
184
-					APIGroups: []string{api.GroupName},
185
-					Verbs:     sets.NewString("create"),
186
-					Resources: sets.NewString(authorizationapi.SourceBuildResource),
187
-				},
188
-			},
189
-		},
190
-		{
191
-			ObjectMeta: kapi.ObjectMeta{
192
-				Name: bootstrappolicy.BuildStrategyJenkinsPipelineRoleName,
193
-			},
194
-			Rules: []authorizationapi.PolicyRule{
195
-				{
196
-					APIGroups: []string{api.GroupName},
197
-					Verbs:     sets.NewString("create"),
198
-					Resources: sets.NewString(authorizationapi.JenkinsPipelineBuildResource),
199
-				},
200
-			},
201
-		},
202
-
203
-		{
204
-			ObjectMeta: kapi.ObjectMeta{
205
-				Name: bootstrappolicy.AdminRoleName,
206
-			},
207
-			Rules: []authorizationapi.PolicyRule{
208
-				{
209
-					APIGroups: []string{kapi.GroupName},
210
-					Verbs:     sets.NewString("get", "list", "watch", "create", "update", "patch", "delete", "deletecollection"),
211
-					Resources: sets.NewString(
212
-						authorizationapi.KubeExposedGroupName,
213
-						"secrets",
214
-						"pods/attach", "pods/proxy", "pods/exec", "pods/portforward",
215
-						"services/proxy",
216
-						"replicationcontrollers/scale",
217
-					),
218
-				},
219
-				{
220
-					APIGroups: []string{kapi.GroupName},
221
-					Verbs:     sets.NewString("impersonate"),
222
-					Resources: sets.NewString("serviceaccounts"),
223
-				},
224
-				{
225
-					APIGroups: []string{api.GroupName},
226
-					Verbs:     sets.NewString("get", "list", "watch", "create", "update", "patch", "delete", "deletecollection"),
227
-					Resources: sets.NewString(
228
-						authorizationapi.OpenshiftExposedGroupName,
229
-						authorizationapi.PermissionGrantingGroupName,
230
-						"projects",
231
-						"deploymentconfigs/scale",
232
-						"imagestreams/secrets",
233
-					),
234
-				},
235
-				{
236
-					APIGroups: []string{autoscaling.GroupName},
237
-					Verbs:     sets.NewString("get", "list", "watch", "create", "update", "patch", "delete", "deletecollection"),
238
-					Resources: sets.NewString("horizontalpodautoscalers"),
239
-				},
240
-				{
241
-					APIGroups: []string{batch.GroupName},
242
-					Verbs:     sets.NewString("get", "list", "watch", "create", "update", "patch", "delete", "deletecollection"),
243
-					Resources: sets.NewString("jobs"),
244
-				},
245
-				{
246
-					APIGroups: []string{extensions.GroupName},
247
-					Verbs:     sets.NewString("get", "list", "watch", "create", "update", "patch", "delete", "deletecollection"),
248
-					Resources: sets.NewString("jobs", "horizontalpodautoscalers", "replicationcontrollers/scale"),
249
-				},
250
-				{
251
-					APIGroups: []string{extensions.GroupName},
252
-					Verbs:     sets.NewString("get", "list", "watch"),
253
-					Resources: sets.NewString("daemonsets"),
254
-				},
255
-				{
256
-					APIGroups: []string{api.GroupName},
257
-					Verbs:     sets.NewString("get", "list", "watch"),
258
-					Resources: sets.NewString(authorizationapi.PolicyOwnerGroupName, authorizationapi.KubeAllGroupName, authorizationapi.OpenshiftStatusGroupName, authorizationapi.KubeStatusGroupName),
259
-				},
260
-				{
261
-					APIGroups: []string{imageapi.GroupName},
262
-					Verbs:     sets.NewString("get", "update"),
263
-					// this is used by verifyImageStreamAccess in pkg/dockerregistry/server/auth.go
264
-					Resources: sets.NewString("imagestreams/layers"),
265
-				},
266
-				// an admin can run routers that write back conditions to the route
267
-				{
268
-					APIGroups: []string{routeapi.GroupName},
269
-					Verbs:     sets.NewString("update"),
270
-					Resources: sets.NewString("routes/status"),
271
-				},
272
-			},
273
-		},
274
-		{
275
-			ObjectMeta: kapi.ObjectMeta{
276
-				Name: bootstrappolicy.EditRoleName,
277
-			},
278
-			Rules: []authorizationapi.PolicyRule{
279
-				{
280
-					APIGroups: []string{kapi.GroupName},
281
-					Verbs:     sets.NewString("get", "list", "watch", "create", "update", "patch", "delete", "deletecollection"),
282
-					Resources: sets.NewString(
283
-						authorizationapi.KubeExposedGroupName,
284
-						"secrets",
285
-						"pods/attach", "pods/proxy", "pods/exec", "pods/portforward",
286
-						"services/proxy",
287
-						"replicationcontrollers/scale",
288
-					),
289
-				},
290
-				{
291
-					APIGroups: []string{kapi.GroupName},
292
-					Verbs:     sets.NewString("impersonate"),
293
-					Resources: sets.NewString("serviceaccounts"),
294
-				},
295
-				{
296
-					APIGroups: []string{api.GroupName},
297
-					Verbs:     sets.NewString("get", "list", "watch", "create", "update", "patch", "delete", "deletecollection"),
298
-					Resources: sets.NewString(
299
-						authorizationapi.OpenshiftExposedGroupName,
300
-						"deploymentconfigs/scale",
301
-						"imagestreams/secrets",
302
-					),
303
-				},
304
-				{
305
-					APIGroups: []string{autoscaling.GroupName},
306
-					Verbs:     sets.NewString("get", "list", "watch", "create", "update", "patch", "delete", "deletecollection"),
307
-					Resources: sets.NewString("horizontalpodautoscalers"),
308
-				},
309
-				{
310
-					APIGroups: []string{batch.GroupName},
311
-					Verbs:     sets.NewString("get", "list", "watch", "create", "update", "patch", "delete", "deletecollection"),
312
-					Resources: sets.NewString("jobs"),
313
-				},
314
-				{
315
-					APIGroups: []string{extensions.GroupName},
316
-					Verbs:     sets.NewString("get", "list", "watch", "create", "update", "patch", "delete", "deletecollection"),
317
-					Resources: sets.NewString("jobs", "horizontalpodautoscalers", "replicationcontrollers/scale"),
318
-				},
319
-				{
320
-					APIGroups: []string{extensions.GroupName},
321
-					Verbs:     sets.NewString("get", "list", "watch"),
322
-					Resources: sets.NewString("daemonsets"),
323
-				},
324
-				{
325
-					APIGroups: []string{api.GroupName},
326
-					Verbs:     sets.NewString("get", "list", "watch"),
327
-					Resources: sets.NewString(authorizationapi.KubeAllGroupName, authorizationapi.OpenshiftStatusGroupName, authorizationapi.KubeStatusGroupName, "projects"),
328
-				},
329
-				{
330
-					APIGroups: []string{imageapi.GroupName},
331
-					Verbs:     sets.NewString("get", "update"),
332
-					// this is used by verifyImageStreamAccess in pkg/dockerregistry/server/auth.go
333
-					Resources: sets.NewString("imagestreams/layers"),
334
-				},
335
-			},
336
-		},
337
-		{
338
-			ObjectMeta: kapi.ObjectMeta{
339
-				Name: bootstrappolicy.ViewRoleName,
340
-			},
341
-			Rules: []authorizationapi.PolicyRule{
342
-				{
343
-					APIGroups: []string{api.GroupName},
344
-					Verbs:     sets.NewString("get", "list", "watch"),
345
-					Resources: sets.NewString(authorizationapi.OpenshiftExposedGroupName, authorizationapi.KubeAllGroupName, authorizationapi.OpenshiftStatusGroupName, authorizationapi.KubeStatusGroupName, "projects"),
346
-				},
347
-				{
348
-					APIGroups: []string{autoscaling.GroupName},
349
-					Verbs:     sets.NewString("get", "list", "watch"),
350
-					Resources: sets.NewString("horizontalpodautoscalers"),
351
-				},
352
-				{
353
-					APIGroups: []string{batch.GroupName},
354
-					Verbs:     sets.NewString("get", "list", "watch"),
355
-					Resources: sets.NewString("jobs"),
356
-				},
357
-				{
358
-					APIGroups: []string{extensions.GroupName},
359
-					Verbs:     sets.NewString("get", "list", "watch"),
360
-					Resources: sets.NewString("daemonsets", "jobs", "horizontalpodautoscalers"),
361
-				},
362
-			},
363
-		},
364
-		{
365
-			ObjectMeta: kapi.ObjectMeta{
366
-				Name: bootstrappolicy.BasicUserRoleName,
367
-			},
368
-			Rules: []authorizationapi.PolicyRule{
369
-				{Verbs: sets.NewString("get"), Resources: sets.NewString("users"), ResourceNames: sets.NewString("~")},
370
-				{Verbs: sets.NewString("list"), Resources: sets.NewString("projectrequests")},
371
-				{Verbs: sets.NewString("list", "get"), Resources: sets.NewString("clusterroles")},
372
-				{Verbs: sets.NewString("list", "watch"), Resources: sets.NewString("projects")},
373
-				{Verbs: sets.NewString("create"), Resources: sets.NewString("subjectaccessreviews", "localsubjectaccessreviews"), AttributeRestrictions: &authorizationapi.IsPersonalSubjectAccessReview{}},
374
-				{Verbs: sets.NewString("create"), Resources: sets.NewString("selfsubjectrulesreviews")},
375
-			},
376
-		},
377
-		{
378
-			ObjectMeta: kapi.ObjectMeta{
379
-				Name: bootstrappolicy.SelfProvisionerRoleName,
380
-			},
381
-			Rules: []authorizationapi.PolicyRule{
382
-				{Verbs: sets.NewString("create"), Resources: sets.NewString("projectrequests")},
383
-			},
384
-		},
385
-		{
386
-			ObjectMeta: kapi.ObjectMeta{
387
-				Name: bootstrappolicy.StatusCheckerRoleName,
388
-			},
389
-			Rules: []authorizationapi.PolicyRule{
390
-				{
391
-					Verbs: sets.NewString("get"),
392
-					NonResourceURLs: sets.NewString(
393
-						// Health
394
-						"/healthz", "/healthz/*",
395
-					),
396
-				},
397
-				authorizationapi.DiscoveryRule,
398
-			},
399
-		},
400
-		{
401
-			ObjectMeta: kapi.ObjectMeta{
402
-				Name: bootstrappolicy.ImageAuditorRoleName,
403
-			},
404
-			Rules: []authorizationapi.PolicyRule{
405
-				{
406
-					APIGroups: []string{imageapi.GroupName},
407
-					Verbs:     sets.NewString("get", "list", "watch", "patch", "update"),
408
-					Resources: sets.NewString("images"),
409
-				},
410
-			},
411
-		},
412
-		{
413
-			ObjectMeta: kapi.ObjectMeta{
414
-				Name: bootstrappolicy.ImagePullerRoleName,
415
-			},
416
-			Rules: []authorizationapi.PolicyRule{
417
-				{
418
-					Verbs: sets.NewString("get"),
419
-					// this is used by verifyImageStreamAccess in pkg/dockerregistry/server/auth.go
420
-					Resources: sets.NewString("imagestreams/layers"),
421
-				},
422
-			},
423
-		},
424
-		{
425
-			// This role looks like a duplicate of ImageBuilderRole, but the ImageBuilder role is specifically for our builder service accounts
426
-			// if we found another permission needed by them, we'd add it there so the intent is different if you used the ImageBuilderRole
427
-			// you could end up accidentally granting more permissions than you intended.  This is intended to only grant enough powers to
428
-			// push an image to our registry
429
-			ObjectMeta: kapi.ObjectMeta{
430
-				Name: bootstrappolicy.ImagePusherRoleName,
431
-			},
432
-			Rules: []authorizationapi.PolicyRule{
433
-				{
434
-					Verbs: sets.NewString("get", "update"),
435
-					// this is used by verifyImageStreamAccess in pkg/dockerregistry/server/auth.go
436
-					Resources: sets.NewString("imagestreams/layers"),
437
-				},
438
-			},
439
-		},
440
-		{
441
-			ObjectMeta: kapi.ObjectMeta{
442
-				Name: bootstrappolicy.ImageBuilderRoleName,
443
-			},
444
-			Rules: []authorizationapi.PolicyRule{
445
-				{
446
-					Verbs: sets.NewString("get", "update"),
447
-					// this is used by verifyImageStreamAccess in pkg/dockerregistry/server/auth.go
448
-					Resources: sets.NewString("imagestreams/layers"),
449
-				},
450
-				{
451
-					Verbs:     sets.NewString("update"),
452
-					Resources: sets.NewString("builds/details"),
453
-				},
454
-			},
455
-		},
456
-		{
457
-			ObjectMeta: kapi.ObjectMeta{
458
-				Name: bootstrappolicy.ImagePrunerRoleName,
459
-			},
460
-			Rules: []authorizationapi.PolicyRule{
461
-				{
462
-					Verbs:     sets.NewString("delete"),
463
-					Resources: sets.NewString("images"),
464
-				},
465
-				{
466
-					Verbs:     sets.NewString("get", "list"),
467
-					Resources: sets.NewString("images", "imagestreams", "pods", "replicationcontrollers", "buildconfigs", "builds", "deploymentconfigs"),
468
-				},
469
-				{
470
-					Verbs:     sets.NewString("update"),
471
-					Resources: sets.NewString("imagestreams/status"),
472
-				},
473
-			},
474
-		},
475
-		{
476
-			ObjectMeta: kapi.ObjectMeta{
477
-				Name: bootstrappolicy.DeployerRoleName,
478
-			},
479
-			Rules: []authorizationapi.PolicyRule{
480
-				{
481
-					// replicationControllerGetter
482
-					Verbs:     sets.NewString("get", "list"),
483
-					Resources: sets.NewString("replicationcontrollers"),
484
-				},
485
-				{
486
-					// RecreateDeploymentStrategy.replicationControllerClient
487
-					// RollingDeploymentStrategy.updaterClient
488
-					Verbs:     sets.NewString("get", "update"),
489
-					Resources: sets.NewString("replicationcontrollers"),
490
-				},
491
-				{
492
-					// RecreateDeploymentStrategy.hookExecutor
493
-					// RollingDeploymentStrategy.hookExecutor
494
-					Verbs:     sets.NewString("get", "list", "watch", "create"),
495
-					Resources: sets.NewString("pods"),
496
-				},
497
-				{
498
-					// RecreateDeploymentStrategy.hookExecutor
499
-					// RollingDeploymentStrategy.hookExecutor
500
-					Verbs:     sets.NewString("get"),
501
-					Resources: sets.NewString("pods/log"),
502
-				},
503
-				{
504
-					// Deployer.After.TagImages
505
-					Verbs:     sets.NewString("update"),
506
-					Resources: sets.NewString("imagestreamtags"),
507
-				},
508
-			},
509
-		},
510
-		{
511
-			ObjectMeta: kapi.ObjectMeta{
512
-				Name: bootstrappolicy.MasterRoleName,
513
-			},
514
-			Rules: []authorizationapi.PolicyRule{
515
-				{
516
-					APIGroups: []string{authorizationapi.APIGroupAll},
517
-					Verbs:     sets.NewString(authorizationapi.VerbAll),
518
-					Resources: sets.NewString(authorizationapi.ResourceAll),
519
-				},
520
-			},
521
-		},
522
-		{
523
-			ObjectMeta: kapi.ObjectMeta{
524
-				Name: bootstrappolicy.OAuthTokenDeleterRoleName,
525
-			},
526
-			Rules: []authorizationapi.PolicyRule{
527
-				{
528
-					Verbs:     sets.NewString("delete"),
529
-					Resources: sets.NewString("oauthaccesstokens", "oauthauthorizetokens"),
530
-				},
531
-			},
532
-		},
533
-		{
534
-			ObjectMeta: kapi.ObjectMeta{
535
-				Name: bootstrappolicy.RouterRoleName,
536
-			},
537
-			Rules: []authorizationapi.PolicyRule{
538
-				{
539
-					Verbs:     sets.NewString("list", "watch"),
540
-					Resources: sets.NewString("routes", "endpoints"),
541
-				},
542
-				// routers write back conditions to the route
543
-				{
544
-					Verbs:     sets.NewString("update"),
545
-					Resources: sets.NewString("routes/status"),
546
-				},
547
-			},
548
-		},
549
-		{
550
-			ObjectMeta: kapi.ObjectMeta{
551
-				Name: bootstrappolicy.RegistryRoleName,
552
-			},
553
-			Rules: []authorizationapi.PolicyRule{
554
-				{
555
-					Verbs:     sets.NewString("get", "delete"),
556
-					Resources: sets.NewString("images"),
557
-				},
558
-				{
559
-					Verbs:     sets.NewString("get"),
560
-					Resources: sets.NewString("imagestreamimages", "imagestreamtags", "imagestreams", "imagestreams/secrets"),
561
-				},
562
-				{
563
-					Verbs:     sets.NewString("update"),
564
-					Resources: sets.NewString("imagestreams"),
565
-				},
566
-				{
567
-					Verbs:     sets.NewString("create"),
568
-					Resources: sets.NewString("imagestreammappings"),
569
-				},
570
-				{
571
-					Verbs:     sets.NewString("list"),
572
-					Resources: sets.NewString("resourcequotas"),
573
-				},
574
-			},
575
-		},
576
-		{
577
-			ObjectMeta: kapi.ObjectMeta{
578
-				Name: bootstrappolicy.NodeProxierRoleName,
579
-			},
580
-			Rules: []authorizationapi.PolicyRule{
581
-				{
582
-					// Used to build serviceLister
583
-					Verbs:     sets.NewString("list", "watch"),
584
-					Resources: sets.NewString("services", "endpoints"),
585
-				},
586
-			},
587
-		},
588
-		{
589
-			ObjectMeta: kapi.ObjectMeta{
590
-				Name: bootstrappolicy.NodeAdminRoleName,
591
-			},
592
-			Rules: []authorizationapi.PolicyRule{
593
-				// Allow read-only access to the API objects
594
-				{
595
-					Verbs:     sets.NewString("get", "list", "watch"),
596
-					Resources: sets.NewString("nodes"),
597
-				},
598
-				// Allow all API calls to the nodes
599
-				{
600
-					Verbs:     sets.NewString("proxy"),
601
-					Resources: sets.NewString("nodes"),
602
-				},
603
-				{
604
-					Verbs:     sets.NewString(authorizationapi.VerbAll),
605
-					Resources: sets.NewString("nodes/proxy", authorizationapi.NodeMetricsResource, authorizationapi.NodeStatsResource, authorizationapi.NodeLogResource),
606
-				},
607
-			},
608
-		},
609
-		{
610
-			ObjectMeta: kapi.ObjectMeta{
611
-				Name: bootstrappolicy.NodeReaderRoleName,
612
-			},
613
-			Rules: []authorizationapi.PolicyRule{
614
-				// Allow read-only access to the API objects
615
-				{
616
-					Verbs:     sets.NewString("get", "list", "watch"),
617
-					Resources: sets.NewString("nodes"),
618
-				},
619
-				// Allow read access to node metrics
620
-				{
621
-					Verbs:     sets.NewString("get"),
622
-					Resources: sets.NewString(authorizationapi.NodeMetricsResource),
623
-				},
624
-				// Allow read access to stats
625
-				// Node stats requests are submitted as POSTs.  These creates are non-mutating
626
-				{
627
-					Verbs:     sets.NewString("get", "create"),
628
-					Resources: sets.NewString(authorizationapi.NodeStatsResource),
629
-				},
630
-				// TODO: expose other things like /healthz on the node once we figure out non-resource URL policy across systems
631
-			},
632
-		},
633
-		{
634
-			ObjectMeta: kapi.ObjectMeta{
635
-				Name: bootstrappolicy.NodeRoleName,
636
-			},
637
-			Rules: []authorizationapi.PolicyRule{
638
-				{
639
-					// Needed to check API access.  These creates are non-mutating
640
-					Verbs:     sets.NewString("create"),
641
-					Resources: sets.NewString("subjectaccessreviews", "localsubjectaccessreviews"),
642
-				},
643
-				{
644
-					// Needed to build serviceLister, to populate env vars for services
645
-					Verbs:     sets.NewString("get", "list", "watch"),
646
-					Resources: sets.NewString("services"),
647
-				},
648
-				{
649
-					// Nodes can register themselves
650
-					// TODO: restrict to creating a node with the same name they announce
651
-					Verbs:     sets.NewString("create", "get", "list", "watch"),
652
-					Resources: sets.NewString("nodes"),
653
-				},
654
-				{
655
-					// TODO: restrict to the bound node once supported
656
-					Verbs:     sets.NewString("update"),
657
-					Resources: sets.NewString("nodes/status"),
658
-				},
659
-
660
-				{
661
-					// TODO: restrict to the bound node as creator once supported
662
-					Verbs:     sets.NewString("create", "update", "patch"),
663
-					Resources: sets.NewString("events"),
664
-				},
665
-
666
-				{
667
-					// TODO: restrict to pods scheduled on the bound node once supported
668
-					Verbs:     sets.NewString("get", "list", "watch"),
669
-					Resources: sets.NewString("pods"),
670
-				},
671
-				{
672
-					// TODO: remove once mirror pods are removed
673
-					// TODO: restrict deletion to mirror pods created by the bound node once supported
674
-					// Needed for the node to create/delete mirror pods
675
-					Verbs:     sets.NewString("get", "create", "delete"),
676
-					Resources: sets.NewString("pods"),
677
-				},
678
-				{
679
-					// TODO: restrict to pods scheduled on the bound node once supported
680
-					Verbs:     sets.NewString("update"),
681
-					Resources: sets.NewString("pods/status"),
682
-				},
683
-
684
-				{
685
-					// TODO: restrict to secrets and configmaps used by pods scheduled on bound node once supported
686
-					// Needed for imagepullsecrets, rbd/ceph and secret volumes, and secrets in envs
687
-					// Needed for configmap volume and envs
688
-					Verbs:     sets.NewString("get"),
689
-					Resources: sets.NewString("secrets", "configmaps"),
690
-				},
691
-				{
692
-					// TODO: restrict to claims/volumes used by pods scheduled on bound node once supported
693
-					// Needed for persistent volumes
694
-					Verbs:     sets.NewString("get"),
695
-					Resources: sets.NewString("persistentvolumeclaims", "persistentvolumes"),
696
-				},
697
-				{
698
-					// TODO: restrict to namespaces of pods scheduled on bound node once supported
699
-					// TODO: change glusterfs to use DNS lookup so this isn't needed?
700
-					// Needed for glusterfs volumes
701
-					Verbs:     sets.NewString("get"),
702
-					Resources: sets.NewString("endpoints"),
703
-				},
704
-			},
705
-		},
706
-
707
-		{
708
-			ObjectMeta: kapi.ObjectMeta{
709
-				Name: bootstrappolicy.SDNReaderRoleName,
710
-			},
711
-			Rules: []authorizationapi.PolicyRule{
712
-				{
713
-					Verbs:     sets.NewString("get", "list", "watch"),
714
-					Resources: sets.NewString("hostsubnets"),
715
-				},
716
-				{
717
-					Verbs:     sets.NewString("get", "list", "watch"),
718
-					Resources: sets.NewString("netnamespaces"),
719
-				},
720
-				{
721
-					Verbs:     sets.NewString("get", "list", "watch"),
722
-					Resources: sets.NewString("nodes"),
723
-				},
724
-				{
725
-					Verbs:     sets.NewString("get"),
726
-					Resources: sets.NewString("clusternetworks"),
727
-				},
728
-				{
729
-					Verbs:     sets.NewString("get", "list", "watch"),
730
-					Resources: sets.NewString("namespaces"),
731
-				},
732
-			},
733
-		},
734
-
735
-		{
736
-			ObjectMeta: kapi.ObjectMeta{
737
-				Name: bootstrappolicy.SDNManagerRoleName,
738
-			},
739
-			Rules: []authorizationapi.PolicyRule{
740
-				{
741
-					Verbs:     sets.NewString("get", "list", "watch", "create", "delete"),
742
-					Resources: sets.NewString("hostsubnets"),
743
-				},
744
-				{
745
-					Verbs:     sets.NewString("get", "list", "watch", "create", "delete"),
746
-					Resources: sets.NewString("netnamespaces"),
747
-				},
748
-				{
749
-					Verbs:     sets.NewString("get", "list", "watch"),
750
-					Resources: sets.NewString("nodes"),
751
-				},
752
-				{
753
-					Verbs:     sets.NewString("get", "create"),
754
-					Resources: sets.NewString("clusternetworks"),
755
-				},
756
-			},
757
-		},
758
-
759
-		{
760
-			ObjectMeta: kapi.ObjectMeta{
761
-				Name: bootstrappolicy.WebHooksRoleName,
762
-			},
763
-			Rules: []authorizationapi.PolicyRule{
764
-				{
765
-					Verbs:     sets.NewString("get", "create"),
766
-					Resources: sets.NewString("buildconfigs/webhooks"),
767
-				},
768
-			},
769
-		},
770
-
771
-		{
772
-			ObjectMeta: kapi.ObjectMeta{
773
-				Name: bootstrappolicy.DiscoveryRoleName,
774
-			},
775
-			Rules: []authorizationapi.PolicyRule{
776
-				authorizationapi.DiscoveryRule,
777
-			},
778
-		},
779
-
780
-		{
781
-			ObjectMeta: kapi.ObjectMeta{
782
-				Name: bootstrappolicy.RegistryAdminRoleName,
783
-			},
784
-			Rules: []authorizationapi.PolicyRule{
785
-				{
786
-					Verbs:     sets.NewString("create", "delete", "deletecollection", "get", "list", "patch", "update", "watch"),
787
-					APIGroups: []string{imageapi.GroupName},
788
-					Resources: sets.NewString("imagestreamimages", "imagestreamimports", "imagestreammappings", "imagestreams", "imagestreams/secrets", "imagestreamtags"),
789
-				},
790
-				{
791
-					Verbs:     sets.NewString("get", "update"),
792
-					APIGroups: []string{imageapi.GroupName},
793
-					Resources: sets.NewString("imagestreams/layers"),
794
-				},
795
-				{
796
-					Verbs:     sets.NewString("create"),
797
-					APIGroups: []string{authorizationapi.GroupName},
798
-					Resources: sets.NewString("localresourceaccessreviews", "localsubjectaccessreviews", "resourceaccessreviews", "subjectaccessreviews"),
799
-				},
800
-				{
801
-					Verbs:     sets.NewString("create", "delete", "deletecollection", "get", "list", "patch", "update", "watch"),
802
-					APIGroups: []string{authorizationapi.GroupName},
803
-					Resources: sets.NewString("rolebindings", "roles"),
804
-				},
805
-				{
806
-					Verbs:     sets.NewString("get", "list", "watch"),
807
-					APIGroups: []string{authorizationapi.GroupName},
808
-					Resources: sets.NewString("policies", "policybindings"),
809
-				},
810
-				{
811
-					Verbs:     sets.NewString("get"),
812
-					APIGroups: []string{kapi.GroupName},
813
-					Resources: sets.NewString("namespaces"),
814
-				},
815
-				{
816
-					Verbs:     sets.NewString("get", "delete"),
817
-					APIGroups: []string{projectapi.GroupName},
818
-					Resources: sets.NewString("projects"),
819
-				},
820
-			},
821
-		},
822
-		{
823
-			ObjectMeta: kapi.ObjectMeta{
824
-				Name: bootstrappolicy.RegistryEditorRoleName,
825
-			},
826
-			Rules: []authorizationapi.PolicyRule{
827
-				{
828
-					Verbs:     sets.NewString("create", "delete", "deletecollection", "get", "list", "patch", "update", "watch"),
829
-					APIGroups: []string{imageapi.GroupName},
830
-					Resources: sets.NewString("imagestreamimages", "imagestreamimports", "imagestreammappings", "imagestreams", "imagestreams/secrets", "imagestreamtags"),
831
-				},
832
-				{
833
-					Verbs:     sets.NewString("get", "update"),
834
-					APIGroups: []string{imageapi.GroupName},
835
-					Resources: sets.NewString("imagestreams/layers"),
836
-				},
837
-				{
838
-					Verbs:     sets.NewString("get"),
839
-					APIGroups: []string{kapi.GroupName},
840
-					Resources: sets.NewString("namespaces"),
841
-				},
842
-				{
843
-					Verbs:     sets.NewString("get"),
844
-					APIGroups: []string{projectapi.GroupName},
845
-					Resources: sets.NewString("projects"),
846
-				},
847
-			},
848
-		},
849
-		{
850
-			ObjectMeta: kapi.ObjectMeta{
851
-				Name: bootstrappolicy.RegistryViewerRoleName,
852
-			},
853
-			Rules: []authorizationapi.PolicyRule{
854
-				{
855
-					Verbs:     sets.NewString("get", "list", "watch"),
856
-					APIGroups: []string{imageapi.GroupName},
857
-					Resources: sets.NewString("imagestreamimages", "imagestreamimports", "imagestreammappings", "imagestreams", "imagestreamtags"),
858
-				},
859
-				{
860
-					Verbs:     sets.NewString("get"),
861
-					APIGroups: []string{imageapi.GroupName},
862
-					Resources: sets.NewString("imagestreams/layers"),
863
-				},
864
-				{
865
-					Verbs:     sets.NewString("get"),
866
-					APIGroups: []string{kapi.GroupName},
867
-					Resources: sets.NewString("namespaces"),
868
-				},
869
-				{
870
-					Verbs:     sets.NewString("get"),
871
-					APIGroups: []string{projectapi.GroupName},
872
-					Resources: sets.NewString("projects"),
873
-				},
874
-			},
875
-		},
876
-	}
877
-
878
-	// we don't want to expose the resourcegroups externally because it makes it very difficult for customers to learn from
879
-	// our default roles and hard for them to reason about what power they are granting their users
880
-	for i := range roles {
881
-		for j := range roles[i].Rules {
882
-			roles[i].Rules[j].Resources = authorizationapi.NormalizeResources(roles[i].Rules[j].Resources)
883
-		}
884
-	}
885
-
886
-	versionedRoles := []authorizationapiv1.ClusterRole{}
887
-	for i := range roles {
888
-		newRole := &authorizationapiv1.ClusterRole{}
889
-		kapi.Scheme.Convert(&roles[i], newRole)
890
-		versionedRoles = append(versionedRoles, *newRole)
891
-	}
892
-
893
-	roundtrippedRoles := []authorizationapi.ClusterRole{}
894
-	for i := range versionedRoles {
895
-		newRole := &authorizationapi.ClusterRole{}
896
-		kapi.Scheme.Convert(&versionedRoles[i], newRole)
897
-		roundtrippedRoles = append(roundtrippedRoles, *newRole)
898
-	}
899
-
900
-	return roundtrippedRoles
46
+	return nil
901 47
 }
... ...
@@ -211,16 +211,6 @@ func GetBootstrapClusterRoles() []authorizationapi.ClusterRole {
211 211
 				authorizationapi.NewRule(readWrite...).Groups(buildGroup).Resources("buildlogs").RuleOrDie(),
212 212
 				authorizationapi.NewRule(read...).Groups(kapiGroup).Resources("resourcequotausages").RuleOrDie(),
213 213
 				authorizationapi.NewRule("create").Groups(authzGroup).Resources("resourceaccessreviews", "subjectaccessreviews").RuleOrDie(),
214
-
215
-				// rules that shouldn't exist, but are here for the covers check until we're convinced of consistency
216
-				authorizationapi.NewRule("create", "delete", "deletecollection", "patch", "update").Groups(kapiGroup).Resources("pods/log").RuleOrDie(),
217
-				authorizationapi.NewRule("create", "delete", "deletecollection", "patch", "update").Groups(deployGroup).Resources("deploymentconfigs/log").RuleOrDie(),
218
-				authorizationapi.NewRule("get", "list", "watch", "delete", "deletecollection", "patch", "update").Groups(authzGroup).Resources("localresourceaccessreviews", "localsubjectaccessreviews", "resourceaccessreviews", "subjectaccessreviews").RuleOrDie(),
219
-				authorizationapi.NewRule("create", "delete", "deletecollection", "patch", "update").Groups(buildGroup).Resources("builds/log").RuleOrDie(),
220
-				authorizationapi.NewRule("get", "list", "watch", "delete", "deletecollection", "patch", "update").Groups(buildGroup).Resources("buildconfigs/instantiate", "buildconfigs/instantiateBinary", "builds/clone").RuleOrDie(),
221
-				authorizationapi.NewRule("get", "list", "watch", "delete", "deletecollection", "patch", "update").Groups(imageGroup).Resources("imagestreamimports").RuleOrDie(),
222
-				authorizationapi.NewRule("get", "list", "watch").Groups(kapiGroup).Resources("nodes", "persistentvolumes", "minions", "securitycontextconstraints").RuleOrDie(),
223
-				authorizationapi.NewRule("list", "watch", "create", "deletecollection").Groups(projectGroup).Resources("projects").RuleOrDie(),
224 214
 			},
225 215
 		},
226 216
 		{
... ...
@@ -265,15 +255,6 @@ func GetBootstrapClusterRoles() []authorizationapi.ClusterRole {
265 265
 				// backwards compatibility
266 266
 				authorizationapi.NewRule(readWrite...).Groups(buildGroup).Resources("buildlogs").RuleOrDie(),
267 267
 				authorizationapi.NewRule(read...).Groups(kapiGroup).Resources("resourcequotausages").RuleOrDie(),
268
-
269
-				// rules that shouldn't exist, but are here for the covers check until we're convinced of consistency
270
-				authorizationapi.NewRule("create", "delete", "deletecollection", "patch", "update").Groups(kapiGroup).Resources("pods/log").RuleOrDie(),
271
-				authorizationapi.NewRule("create", "delete", "deletecollection", "patch", "update").Groups(deployGroup).Resources("deploymentconfigs/log").RuleOrDie(),
272
-				authorizationapi.NewRule("create", "delete", "deletecollection", "patch", "update").Groups(buildGroup).Resources("builds/log").RuleOrDie(),
273
-				authorizationapi.NewRule("get", "list", "watch", "delete", "deletecollection", "patch", "update").Groups(buildGroup).Resources("buildconfigs/instantiate", "buildconfigs/instantiateBinary", "builds/clone").RuleOrDie(),
274
-				authorizationapi.NewRule("get", "list", "watch", "delete", "deletecollection", "patch", "update").Groups(imageGroup).Resources("imagestreamimports").RuleOrDie(),
275
-				authorizationapi.NewRule("get", "list", "watch").Groups(kapiGroup).Resources("nodes", "persistentvolumes", "minions", "securitycontextconstraints").RuleOrDie(),
276
-				authorizationapi.NewRule("list", "watch").Groups(projectGroup).Resources("projects").RuleOrDie(),
277 268
 			},
278 269
 		},
279 270
 		{
... ...
@@ -306,7 +287,7 @@ func GetBootstrapClusterRoles() []authorizationapi.ClusterRole {
306 306
 				// pull images
307 307
 				// authorizationapi.NewRule("get").Groups(imageGroup).Resources("imagestreams/layers").RuleOrDie(),
308 308
 
309
-				authorizationapi.NewRule(read...).Groups(projectGroup).Resources("projects").RuleOrDie(),
309
+				authorizationapi.NewRule("get").Groups(projectGroup).Resources("projects").RuleOrDie(),
310 310
 
311 311
 				authorizationapi.NewRule(read...).Groups(routeGroup).Resources("routes").RuleOrDie(),
312 312
 				authorizationapi.NewRule(read...).Groups(routeGroup).Resources("routes/status").RuleOrDie(),
... ...
@@ -316,12 +297,6 @@ func GetBootstrapClusterRoles() []authorizationapi.ClusterRole {
316 316
 				// backwards compatibility
317 317
 				authorizationapi.NewRule(read...).Groups(buildGroup).Resources("buildlogs").RuleOrDie(),
318 318
 				authorizationapi.NewRule(read...).Groups(kapiGroup).Resources("resourcequotausages").RuleOrDie(),
319
-
320
-				// rules that shouldn't exist, but are here for the covers check until we're convinced of consistency
321
-				authorizationapi.NewRule("get", "list", "watch").Groups(buildGroup).Resources("buildconfigs/instantiate", "buildconfigs/instantiateBinary", "builds/clone").RuleOrDie(),
322
-				authorizationapi.NewRule("get", "list", "watch").Groups(imageGroup).Resources("imagestreamimports").RuleOrDie(),
323
-				authorizationapi.NewRule("get", "list", "watch").Groups(kapiGroup).Resources("nodes", "persistentvolumes", "minions", "securitycontextconstraints").RuleOrDie(),
324
-				authorizationapi.NewRule("list", "watch").Groups(projectGroup).Resources("projects").RuleOrDie(),
325 319
 			},
326 320
 		},
327 321
 		{
... ...
@@ -590,7 +565,8 @@ func GetBootstrapClusterRoles() []authorizationapi.ClusterRole {
590 590
 				Name: RegistryAdminRoleName,
591 591
 			},
592 592
 			Rules: []authorizationapi.PolicyRule{
593
-				authorizationapi.NewRule(readWrite...).Groups(imageGroup).Resources("imagestreamimages", "imagestreamimports", "imagestreammappings", "imagestreams", "imagestreams/secrets", "imagestreamtags").RuleOrDie(),
593
+				authorizationapi.NewRule(readWrite...).Groups(imageGroup).Resources("imagestreamimages", "imagestreammappings", "imagestreams", "imagestreams/secrets", "imagestreamtags").RuleOrDie(),
594
+				authorizationapi.NewRule("create").Groups(imageGroup).Resources("imagestreamimports").RuleOrDie(),
594 595
 				authorizationapi.NewRule("get", "update").Groups(imageGroup).Resources("imagestreams/layers").RuleOrDie(),
595 596
 
596 597
 				authorizationapi.NewRule(readWrite...).Groups(authzGroup).Resources("rolebindings", "roles").RuleOrDie(),
... ...
@@ -609,7 +585,8 @@ func GetBootstrapClusterRoles() []authorizationapi.ClusterRole {
609 609
 				Name: RegistryEditorRoleName,
610 610
 			},
611 611
 			Rules: []authorizationapi.PolicyRule{
612
-				authorizationapi.NewRule(readWrite...).Groups(imageGroup).Resources("imagestreamimages", "imagestreamimports", "imagestreammappings", "imagestreams", "imagestreams/secrets", "imagestreamtags").RuleOrDie(),
612
+				authorizationapi.NewRule(readWrite...).Groups(imageGroup).Resources("imagestreamimages", "imagestreammappings", "imagestreams", "imagestreams/secrets", "imagestreamtags").RuleOrDie(),
613
+				authorizationapi.NewRule("create").Groups(imageGroup).Resources("imagestreamimports").RuleOrDie(),
613 614
 				authorizationapi.NewRule("get", "update").Groups(imageGroup).Resources("imagestreams/layers").RuleOrDie(),
614 615
 
615 616
 				authorizationapi.NewRule("get").Groups(kapiGroup).Resources("namespaces").RuleOrDie(),
... ...
@@ -621,7 +598,7 @@ func GetBootstrapClusterRoles() []authorizationapi.ClusterRole {
621 621
 				Name: RegistryViewerRoleName,
622 622
 			},
623 623
 			Rules: []authorizationapi.PolicyRule{
624
-				authorizationapi.NewRule(read...).Groups(imageGroup).Resources("imagestreamimages", "imagestreamimports", "imagestreammappings", "imagestreams", "imagestreamtags").RuleOrDie(),
624
+				authorizationapi.NewRule(read...).Groups(imageGroup).Resources("imagestreamimages", "imagestreammappings", "imagestreams", "imagestreamtags").RuleOrDie(),
625 625
 				authorizationapi.NewRule("get").Groups(imageGroup).Resources("imagestreams/layers").RuleOrDie(),
626 626
 
627 627
 				authorizationapi.NewRule("get").Groups(kapiGroup).Resources("namespaces").RuleOrDie(),
... ...
@@ -122,22 +122,22 @@ func TestCovers(t *testing.T) {
122 122
 		}
123 123
 	}
124 124
 
125
-	if covers, _ := rulevalidation.Covers(admin.Rules, editor.Rules); !covers {
126
-		t.Errorf("failed to cover")
125
+	if covers, miss := rulevalidation.Covers(admin.Rules, editor.Rules); !covers {
126
+		t.Errorf("failed to cover: %#v", miss)
127 127
 	}
128
-	if covers, _ := rulevalidation.Covers(admin.Rules, editor.Rules); !covers {
129
-		t.Errorf("failed to cover")
128
+	if covers, miss := rulevalidation.Covers(admin.Rules, editor.Rules); !covers {
129
+		t.Errorf("failed to cover: %#v", miss)
130 130
 	}
131
-	if covers, _ := rulevalidation.Covers(admin.Rules, viewer.Rules); !covers {
132
-		t.Errorf("failed to cover")
131
+	if covers, miss := rulevalidation.Covers(admin.Rules, viewer.Rules); !covers {
132
+		t.Errorf("failed to cover: %#v", miss)
133 133
 	}
134
-	if covers, _ := rulevalidation.Covers(admin.Rules, registryAdmin.Rules); !covers {
135
-		t.Errorf("failed to cover")
134
+	if covers, miss := rulevalidation.Covers(admin.Rules, registryAdmin.Rules); !covers {
135
+		t.Errorf("failed to cover: %#v", miss)
136 136
 	}
137
-	if covers, _ := rulevalidation.Covers(registryAdmin.Rules, registryEditor.Rules); !covers {
138
-		t.Errorf("failed to cover")
137
+	if covers, miss := rulevalidation.Covers(registryAdmin.Rules, registryEditor.Rules); !covers {
138
+		t.Errorf("failed to cover: %#v", miss)
139 139
 	}
140
-	if covers, _ := rulevalidation.Covers(registryAdmin.Rules, registryViewer.Rules); !covers {
141
-		t.Errorf("failed to cover")
140
+	if covers, miss := rulevalidation.Covers(registryAdmin.Rules, registryViewer.Rules); !covers {
141
+		t.Errorf("failed to cover: %#v", miss)
142 142
 	}
143 143
 }
... ...
@@ -34,7 +34,7 @@ os::cmd::expect_failure_and_text 'oc get pods --token="${listprojecttoken}" -n c
34 34
 adminnonescalatingpowerstoken=$(oc process -f ${OS_ROOT}/test/fixtures/authentication/scoped-token-template.yaml TOKEN_PREFIX=admin SCOPE=role:admin:* USER_NAME="${username}" USER_UID="${useruid}" | oc create -f - -o name | awk -F/ '{print $2}')
35 35
 os::cmd::expect_failure_and_text 'oc get user/~ --token="${adminnonescalatingpowerstoken}"' 'prevent this action; User "scoped-user" cannot get users at the cluster scope'
36 36
 os::cmd::expect_failure_and_text 'oc get secrets --token="${adminnonescalatingpowerstoken}" -n cmd-authentication' 'prevent this action; User "scoped-user" cannot list secrets in project "cmd-authentication"'
37
-os::cmd::expect_success_and_text 'oc get projects --token="${adminnonescalatingpowerstoken}" -n cmd-authentication' 'cmd-authentication'
37
+os::cmd::expect_success_and_text 'oc get projects/cmd-authentication --token="${adminnonescalatingpowerstoken}" -n cmd-authentication' 'cmd-authentication'
38 38
 
39 39
 allescalatingpowerstoken=$(oc process -f ${OS_ROOT}/test/fixtures/authentication/scoped-token-template.yaml TOKEN_PREFIX=clusteradmin SCOPE='role:cluster-admin:*:!' USER_NAME="${username}" USER_UID="${useruid}" | oc create -f - -o name | awk -F/ '{print $2}')
40 40
 os::cmd::expect_success_and_text 'oc get user/~ --token="${allescalatingpowerstoken}"' "${username}"
... ...
@@ -577,105 +577,6 @@ items:
577 577
     - subjectaccessreviews
578 578
     verbs:
579 579
     - create
580
-  - apiGroups:
581
-    - ""
582
-    attributeRestrictions: null
583
-    resources:
584
-    - pods/log
585
-    verbs:
586
-    - create
587
-    - delete
588
-    - deletecollection
589
-    - patch
590
-    - update
591
-  - apiGroups:
592
-    - ""
593
-    attributeRestrictions: null
594
-    resources:
595
-    - deploymentconfigs/log
596
-    verbs:
597
-    - create
598
-    - delete
599
-    - deletecollection
600
-    - patch
601
-    - update
602
-  - apiGroups:
603
-    - ""
604
-    attributeRestrictions: null
605
-    resources:
606
-    - localresourceaccessreviews
607
-    - localsubjectaccessreviews
608
-    - resourceaccessreviews
609
-    - subjectaccessreviews
610
-    verbs:
611
-    - delete
612
-    - deletecollection
613
-    - get
614
-    - list
615
-    - patch
616
-    - update
617
-    - watch
618
-  - apiGroups:
619
-    - ""
620
-    attributeRestrictions: null
621
-    resources:
622
-    - builds/log
623
-    verbs:
624
-    - create
625
-    - delete
626
-    - deletecollection
627
-    - patch
628
-    - update
629
-  - apiGroups:
630
-    - ""
631
-    attributeRestrictions: null
632
-    resources:
633
-    - buildconfigs/instantiate
634
-    - buildconfigs/instantiatebinary
635
-    - builds/clone
636
-    verbs:
637
-    - delete
638
-    - deletecollection
639
-    - get
640
-    - list
641
-    - patch
642
-    - update
643
-    - watch
644
-  - apiGroups:
645
-    - ""
646
-    attributeRestrictions: null
647
-    resources:
648
-    - imagestreamimports
649
-    verbs:
650
-    - delete
651
-    - deletecollection
652
-    - get
653
-    - list
654
-    - patch
655
-    - update
656
-    - watch
657
-  - apiGroups:
658
-    - ""
659
-    attributeRestrictions: null
660
-    resources:
661
-    - minions
662
-    - nodes
663
-    - persistentvolumes
664
-    - securitycontextconstraints
665
-    verbs:
666
-    - get
667
-    - list
668
-    - watch
669
-  - apiGroups:
670
-    - ""
671
-    attributeRestrictions: null
672
-    resources:
673
-    - projects
674
-    verbs:
675
-    - create
676
-    - deletecollection
677
-    - list
678
-    - watch
679 580
 - apiVersion: v1
680 581
   kind: ClusterRole
681 582
   metadata:
... ...
@@ -972,87 +873,6 @@ items:
972 972
     - get
973 973
     - list
974 974
     - watch
975
-  - apiGroups:
976
-    - ""
977
-    attributeRestrictions: null
978
-    resources:
979
-    - pods/log
980
-    verbs:
981
-    - create
982
-    - delete
983
-    - deletecollection
984
-    - patch
985
-    - update
986
-  - apiGroups:
987
-    - ""
988
-    attributeRestrictions: null
989
-    resources:
990
-    - deploymentconfigs/log
991
-    verbs:
992
-    - create
993
-    - delete
994
-    - deletecollection
995
-    - patch
996
-    - update
997
-  - apiGroups:
998
-    - ""
999
-    attributeRestrictions: null
1000
-    resources:
1001
-    - builds/log
1002
-    verbs:
1003
-    - create
1004
-    - delete
1005
-    - deletecollection
1006
-    - patch
1007
-    - update
1008
-  - apiGroups:
1009
-    - ""
1010
-    attributeRestrictions: null
1011
-    resources:
1012
-    - buildconfigs/instantiate
1013
-    - buildconfigs/instantiatebinary
1014
-    - builds/clone
1015
-    verbs:
1016
-    - delete
1017
-    - deletecollection
1018
-    - get
1019
-    - list
1020
-    - patch
1021
-    - update
1022
-    - watch
1023
-  - apiGroups:
1024
-    - ""
1025
-    attributeRestrictions: null
1026
-    resources:
1027
-    - imagestreamimports
1028
-    verbs:
1029
-    - delete
1030
-    - deletecollection
1031
-    - get
1032
-    - list
1033
-    - patch
1034
-    - update
1035
-    - watch
1036
-  - apiGroups:
1037
-    - ""
1038
-    attributeRestrictions: null
1039
-    resources:
1040
-    - minions
1041
-    - nodes
1042
-    - persistentvolumes
1043
-    - securitycontextconstraints
1044
-    verbs:
1045
-    - get
1046
-    - list
1047
-    - watch
1048
-  - apiGroups:
1049
-    - ""
1050
-    attributeRestrictions: null
1051
-    resources:
1052
-    - projects
1053
-    verbs:
1054
-    - list
1055
-    - watch
1056 975
 - apiVersion: v1
1057 976
   kind: ClusterRole
1058 977
   metadata:
... ...
@@ -1199,8 +1019,6 @@ items:
1199 1199
     - projects
1200 1200
     verbs:
1201 1201
     - get
1202
-    - list
1203
-    - watch
1204 1202
   - apiGroups:
1205 1203
     - ""
1206 1204
     attributeRestrictions: null
... ...
@@ -1248,46 +1066,6 @@ items:
1248 1248
     - get
1249 1249
     - list
1250 1250
     - watch
1251
-  - apiGroups:
1252
-    - ""
1253
-    attributeRestrictions: null
1254
-    resources:
1255
-    - buildconfigs/instantiate
1256
-    - buildconfigs/instantiatebinary
1257
-    - builds/clone
1258
-    verbs:
1259
-    - get
1260
-    - list
1261
-    - watch
1262
-  - apiGroups:
1263
-    - ""
1264
-    attributeRestrictions: null
1265
-    resources:
1266
-    - imagestreamimports
1267
-    verbs:
1268
-    - get
1269
-    - list
1270
-    - watch
1271
-  - apiGroups:
1272
-    - ""
1273
-    attributeRestrictions: null
1274
-    resources:
1275
-    - minions
1276
-    - nodes
1277
-    - persistentvolumes
1278
-    - securitycontextconstraints
1279
-    verbs:
1280
-    - get
1281
-    - list
1282
-    - watch
1283
-  - apiGroups:
1284
-    - ""
1285
-    attributeRestrictions: null
1286
-    resources:
1287
-    - projects
1288
-    verbs:
1289
-    - list
1290
-    - watch
1291 1251
 - apiVersion: v1
1292 1252
   kind: ClusterRole
1293 1253
   metadata:
... ...
@@ -1933,7 +1711,6 @@ items:
1933 1933
     attributeRestrictions: null
1934 1934
     resources:
1935 1935
     - imagestreamimages
1936
-    - imagestreamimports
1937 1936
     - imagestreammappings
1938 1937
     - imagestreams
1939 1938
     - imagestreams/secrets
... ...
@@ -1951,6 +1728,13 @@ items:
1951 1951
     - ""
1952 1952
     attributeRestrictions: null
1953 1953
     resources:
1954
+    - imagestreamimports
1955
+    verbs:
1956
+    - create
1957
+  - apiGroups:
1958
+    - ""
1959
+    attributeRestrictions: null
1960
+    resources:
1954 1961
     - imagestreams/layers
1955 1962
     verbs:
1956 1963
     - get
... ...
@@ -2022,7 +1806,6 @@ items:
2022 2022
     attributeRestrictions: null
2023 2023
     resources:
2024 2024
     - imagestreamimages
2025
-    - imagestreamimports
2026 2025
     - imagestreammappings
2027 2026
     - imagestreams
2028 2027
     - imagestreams/secrets
... ...
@@ -2040,6 +1823,13 @@ items:
2040 2040
     - ""
2041 2041
     attributeRestrictions: null
2042 2042
     resources:
2043
+    - imagestreamimports
2044
+    verbs:
2045
+    - create
2046
+  - apiGroups:
2047
+    - ""
2048
+    attributeRestrictions: null
2049
+    resources:
2043 2050
     - imagestreams/layers
2044 2051
     verbs:
2045 2052
     - get
... ...
@@ -2069,7 +1859,6 @@ items:
2069 2069
     attributeRestrictions: null
2070 2070
     resources:
2071 2071
     - imagestreamimages
2072
-    - imagestreamimports
2073 2072
     - imagestreammappings
2074 2073
     - imagestreams
2075 2074
     - imagestreamtags