@@ -134,99 +134,54 @@ func (p RESTStorageProvider) storage(version schema.GroupVersion, apiResourceCon
134
134
}
135
135
136
136
func (p RESTStorageProvider ) PostStartHook () (string , genericapiserver.PostStartHookFunc , error ) {
137
- return PostStartHookName , PostStartHook , nil
137
+ policy := & PolicyData {
138
+ ClusterRoles : append (bootstrappolicy .ClusterRoles (), bootstrappolicy .ControllerRoles ()... ),
139
+ ClusterRoleBindings : append (bootstrappolicy .ClusterRoleBindings (), bootstrappolicy .ControllerRoleBindings ()... ),
140
+ Roles : bootstrappolicy .NamespaceRoles (),
141
+ RoleBindings : bootstrappolicy .NamespaceRoleBindings (),
142
+ }
143
+ return PostStartHookName , policy .EnsureRBACPolicy (), nil
138
144
}
139
145
140
- func PostStartHook (hookContext genericapiserver.PostStartHookContext ) error {
141
- // intializing roles is really important. On some e2e runs, we've seen cases where etcd is down when the server
142
- // starts, the roles don't initialize, and nothing works.
143
- err := wait .Poll (1 * time .Second , 30 * time .Second , func () (done bool , err error ) {
144
-
145
- coreclientset , err := coreclient .NewForConfig (hookContext .LoopbackClientConfig )
146
- if err != nil {
147
- utilruntime .HandleError (fmt .Errorf ("unable to initialize client: %v" , err ))
148
- return false , nil
149
- }
146
+ type PolicyData struct {
147
+ ClusterRoles []rbac.ClusterRole
148
+ ClusterRoleBindings []rbac.ClusterRoleBinding
149
+ Roles map [string ][]rbac.Role
150
+ RoleBindings map [string ][]rbac.RoleBinding
151
+ }
150
152
151
- clientset , err := rbacclient .NewForConfig (hookContext .LoopbackClientConfig )
152
- if err != nil {
153
- utilruntime .HandleError (fmt .Errorf ("unable to initialize client: %v" , err ))
154
- return false , nil
155
- }
156
- // Make sure etcd is responding before we start reconciling
157
- if _ , err := clientset .ClusterRoles ().List (metav1.ListOptions {}); err != nil {
158
- utilruntime .HandleError (fmt .Errorf ("unable to initialize clusterroles: %v" , err ))
159
- return false , nil
160
- }
161
- if _ , err := clientset .ClusterRoleBindings ().List (metav1.ListOptions {}); err != nil {
162
- utilruntime .HandleError (fmt .Errorf ("unable to initialize clusterrolebindings: %v" , err ))
163
- return false , nil
164
- }
153
+ func (p * PolicyData ) EnsureRBACPolicy () genericapiserver.PostStartHookFunc {
154
+ return func (hookContext genericapiserver.PostStartHookContext ) error {
155
+ // intializing roles is really important. On some e2e runs, we've seen cases where etcd is down when the server
156
+ // starts, the roles don't initialize, and nothing works.
157
+ err := wait .Poll (1 * time .Second , 30 * time .Second , func () (done bool , err error ) {
165
158
166
- // ensure bootstrap roles are created or reconciled
167
- for _ , clusterRole := range append (bootstrappolicy .ClusterRoles (), bootstrappolicy .ControllerRoles ()... ) {
168
- opts := reconciliation.ReconcileRoleOptions {
169
- Role : reconciliation.ClusterRoleRuleOwner {ClusterRole : & clusterRole },
170
- Client : reconciliation.ClusterRoleModifier {Client : clientset .ClusterRoles ()},
171
- Confirm : true ,
172
- }
173
- err := retry .RetryOnConflict (retry .DefaultBackoff , func () error {
174
- result , err := opts .Run ()
175
- if err != nil {
176
- return err
177
- }
178
- switch {
179
- case result .Protected && result .Operation != reconciliation .ReconcileNone :
180
- glog .Warningf ("skipped reconcile-protected clusterrole.%s/%s with missing permissions: %v" , rbac .GroupName , clusterRole .Name , result .MissingRules )
181
- case result .Operation == reconciliation .ReconcileUpdate :
182
- glog .Infof ("updated clusterrole.%s/%s with additional permissions: %v" , rbac .GroupName , clusterRole .Name , result .MissingRules )
183
- case result .Operation == reconciliation .ReconcileCreate :
184
- glog .Infof ("created clusterrole.%s/%s" , rbac .GroupName , clusterRole .Name )
185
- }
186
- return nil
187
- })
159
+ coreclientset , err := coreclient .NewForConfig (hookContext .LoopbackClientConfig )
188
160
if err != nil {
189
- // don't fail on failures, try to create as many as you can
190
- utilruntime . HandleError ( fmt . Errorf ( "unable to reconcile clusterrole.%s/%s: %v" , rbac . GroupName , clusterRole . Name , err ))
161
+ utilruntime . HandleError ( fmt . Errorf ( "unable to initialize client: %v" , err ))
162
+ return false , nil
191
163
}
192
- }
193
164
194
- // ensure bootstrap rolebindings are created or reconciled
195
- for _ , clusterRoleBinding := range append (bootstrappolicy .ClusterRoleBindings (), bootstrappolicy .ControllerRoleBindings ()... ) {
196
- opts := reconciliation.ReconcileRoleBindingOptions {
197
- RoleBinding : reconciliation.ClusterRoleBindingAdapter {ClusterRoleBinding : & clusterRoleBinding },
198
- Client : reconciliation.ClusterRoleBindingClientAdapter {Client : clientset .ClusterRoleBindings ()},
199
- Confirm : true ,
200
- }
201
- err := retry .RetryOnConflict (retry .DefaultBackoff , func () error {
202
- result , err := opts .Run ()
203
- if err != nil {
204
- return err
205
- }
206
- switch {
207
- case result .Protected && result .Operation != reconciliation .ReconcileNone :
208
- glog .Warningf ("skipped reconcile-protected clusterrolebinding.%s/%s with missing subjects: %v" , rbac .GroupName , clusterRoleBinding .Name , result .MissingSubjects )
209
- case result .Operation == reconciliation .ReconcileUpdate :
210
- glog .Infof ("updated clusterrolebinding.%s/%s with additional subjects: %v" , rbac .GroupName , clusterRoleBinding .Name , result .MissingSubjects )
211
- case result .Operation == reconciliation .ReconcileCreate :
212
- glog .Infof ("created clusterrolebinding.%s/%s" , rbac .GroupName , clusterRoleBinding .Name )
213
- case result .Operation == reconciliation .ReconcileRecreate :
214
- glog .Infof ("recreated clusterrolebinding.%s/%s" , rbac .GroupName , clusterRoleBinding .Name )
215
- }
216
- return nil
217
- })
165
+ clientset , err := rbacclient .NewForConfig (hookContext .LoopbackClientConfig )
218
166
if err != nil {
219
- // don't fail on failures, try to create as many as you can
220
- utilruntime .HandleError (fmt .Errorf ("unable to reconcile clusterrolebinding.%s/%s: %v" , rbac .GroupName , clusterRoleBinding .Name , err ))
167
+ utilruntime .HandleError (fmt .Errorf ("unable to initialize client: %v" , err ))
168
+ return false , nil
169
+ }
170
+ // Make sure etcd is responding before we start reconciling
171
+ if _ , err := clientset .ClusterRoles ().List (metav1.ListOptions {}); err != nil {
172
+ utilruntime .HandleError (fmt .Errorf ("unable to initialize clusterroles: %v" , err ))
173
+ return false , nil
174
+ }
175
+ if _ , err := clientset .ClusterRoleBindings ().List (metav1.ListOptions {}); err != nil {
176
+ utilruntime .HandleError (fmt .Errorf ("unable to initialize clusterrolebindings: %v" , err ))
177
+ return false , nil
221
178
}
222
- }
223
179
224
- // ensure bootstrap namespaced roles are created or reconciled
225
- for namespace , roles := range bootstrappolicy .NamespaceRoles () {
226
- for _ , role := range roles {
180
+ // ensure bootstrap roles are created or reconciled
181
+ for _ , clusterRole := range p .ClusterRoles {
227
182
opts := reconciliation.ReconcileRoleOptions {
228
- Role : reconciliation.RoleRuleOwner { Role : & role },
229
- Client : reconciliation.RoleModifier {Client : clientset , NamespaceClient : coreclientset . Namespaces ()},
183
+ Role : reconciliation.ClusterRoleRuleOwner { ClusterRole : & clusterRole },
184
+ Client : reconciliation.ClusterRoleModifier {Client : clientset . ClusterRoles ()},
230
185
Confirm : true ,
231
186
}
232
187
err := retry .RetryOnConflict (retry .DefaultBackoff , func () error {
@@ -236,27 +191,25 @@ func PostStartHook(hookContext genericapiserver.PostStartHookContext) error {
236
191
}
237
192
switch {
238
193
case result .Protected && result .Operation != reconciliation .ReconcileNone :
239
- glog .Warningf ("skipped reconcile-protected role .%s/%s in %v with missing permissions: %v" , rbac .GroupName , role .Name , namespace , result .MissingRules )
194
+ glog .Warningf ("skipped reconcile-protected clusterrole .%s/%s with missing permissions: %v" , rbac .GroupName , clusterRole .Name , result .MissingRules )
240
195
case result .Operation == reconciliation .ReconcileUpdate :
241
- glog .Infof ("updated role .%s/%s in %v with additional permissions: %v" , rbac .GroupName , role .Name , namespace , result .MissingRules )
196
+ glog .Infof ("updated clusterrole .%s/%s with additional permissions: %v" , rbac .GroupName , clusterRole .Name , result .MissingRules )
242
197
case result .Operation == reconciliation .ReconcileCreate :
243
- glog .Infof ("created role .%s/%s in %v " , rbac .GroupName , role .Name , namespace )
198
+ glog .Infof ("created clusterrole .%s/%s" , rbac .GroupName , clusterRole .Name )
244
199
}
245
200
return nil
246
201
})
247
202
if err != nil {
248
203
// don't fail on failures, try to create as many as you can
249
- utilruntime .HandleError (fmt .Errorf ("unable to reconcile role .%s/%s in %v : %v" , rbac .GroupName , role .Name , namespace , err ))
204
+ utilruntime .HandleError (fmt .Errorf ("unable to reconcile clusterrole .%s/%s: %v" , rbac .GroupName , clusterRole .Name , err ))
250
205
}
251
206
}
252
- }
253
207
254
- // ensure bootstrap namespaced rolebindings are created or reconciled
255
- for namespace , roleBindings := range bootstrappolicy .NamespaceRoleBindings () {
256
- for _ , roleBinding := range roleBindings {
208
+ // ensure bootstrap rolebindings are created or reconciled
209
+ for _ , clusterRoleBinding := range p .ClusterRoleBindings {
257
210
opts := reconciliation.ReconcileRoleBindingOptions {
258
- RoleBinding : reconciliation.RoleBindingAdapter { RoleBinding : & roleBinding },
259
- Client : reconciliation.RoleBindingClientAdapter {Client : clientset , NamespaceClient : coreclientset . Namespaces ()},
211
+ RoleBinding : reconciliation.ClusterRoleBindingAdapter { ClusterRoleBinding : & clusterRoleBinding },
212
+ Client : reconciliation.ClusterRoleBindingClientAdapter {Client : clientset . ClusterRoleBindings ()},
260
213
Confirm : true ,
261
214
}
262
215
err := retry .RetryOnConflict (retry .DefaultBackoff , func () error {
@@ -266,31 +219,93 @@ func PostStartHook(hookContext genericapiserver.PostStartHookContext) error {
266
219
}
267
220
switch {
268
221
case result .Protected && result .Operation != reconciliation .ReconcileNone :
269
- glog .Warningf ("skipped reconcile-protected rolebinding .%s/%s in %v with missing subjects: %v" , rbac .GroupName , roleBinding .Name , namespace , result .MissingSubjects )
222
+ glog .Warningf ("skipped reconcile-protected clusterrolebinding .%s/%s with missing subjects: %v" , rbac .GroupName , clusterRoleBinding .Name , result .MissingSubjects )
270
223
case result .Operation == reconciliation .ReconcileUpdate :
271
- glog .Infof ("updated rolebinding .%s/%s in %v with additional subjects: %v" , rbac .GroupName , roleBinding .Name , namespace , result .MissingSubjects )
224
+ glog .Infof ("updated clusterrolebinding .%s/%s with additional subjects: %v" , rbac .GroupName , clusterRoleBinding .Name , result .MissingSubjects )
272
225
case result .Operation == reconciliation .ReconcileCreate :
273
- glog .Infof ("created rolebinding .%s/%s in %v " , rbac .GroupName , roleBinding .Name , namespace )
226
+ glog .Infof ("created clusterrolebinding .%s/%s" , rbac .GroupName , clusterRoleBinding .Name )
274
227
case result .Operation == reconciliation .ReconcileRecreate :
275
- glog .Infof ("recreated rolebinding .%s/%s in %v " , rbac .GroupName , roleBinding .Name , namespace )
228
+ glog .Infof ("recreated clusterrolebinding .%s/%s" , rbac .GroupName , clusterRoleBinding .Name )
276
229
}
277
230
return nil
278
231
})
279
232
if err != nil {
280
233
// don't fail on failures, try to create as many as you can
281
- utilruntime .HandleError (fmt .Errorf ("unable to reconcile rolebinding.%s/%s in %v: %v" , rbac .GroupName , roleBinding .Name , namespace , err ))
234
+ utilruntime .HandleError (fmt .Errorf ("unable to reconcile clusterrolebinding.%s/%s: %v" , rbac .GroupName , clusterRoleBinding .Name , err ))
235
+ }
236
+ }
237
+
238
+ // ensure bootstrap namespaced roles are created or reconciled
239
+ for namespace , roles := range p .Roles {
240
+ for _ , role := range roles {
241
+ opts := reconciliation.ReconcileRoleOptions {
242
+ Role : reconciliation.RoleRuleOwner {Role : & role },
243
+ Client : reconciliation.RoleModifier {Client : clientset , NamespaceClient : coreclientset .Namespaces ()},
244
+ Confirm : true ,
245
+ }
246
+ err := retry .RetryOnConflict (retry .DefaultBackoff , func () error {
247
+ result , err := opts .Run ()
248
+ if err != nil {
249
+ return err
250
+ }
251
+ switch {
252
+ case result .Protected && result .Operation != reconciliation .ReconcileNone :
253
+ glog .Warningf ("skipped reconcile-protected role.%s/%s in %v with missing permissions: %v" , rbac .GroupName , role .Name , namespace , result .MissingRules )
254
+ case result .Operation == reconciliation .ReconcileUpdate :
255
+ glog .Infof ("updated role.%s/%s in %v with additional permissions: %v" , rbac .GroupName , role .Name , namespace , result .MissingRules )
256
+ case result .Operation == reconciliation .ReconcileCreate :
257
+ glog .Infof ("created role.%s/%s in %v " , rbac .GroupName , role .Name , namespace )
258
+ }
259
+ return nil
260
+ })
261
+ if err != nil {
262
+ // don't fail on failures, try to create as many as you can
263
+ utilruntime .HandleError (fmt .Errorf ("unable to reconcile role.%s/%s in %v: %v" , rbac .GroupName , role .Name , namespace , err ))
264
+ }
282
265
}
283
266
}
267
+
268
+ // ensure bootstrap namespaced rolebindings are created or reconciled
269
+ for namespace , roleBindings := range p .RoleBindings {
270
+ for _ , roleBinding := range roleBindings {
271
+ opts := reconciliation.ReconcileRoleBindingOptions {
272
+ RoleBinding : reconciliation.RoleBindingAdapter {RoleBinding : & roleBinding },
273
+ Client : reconciliation.RoleBindingClientAdapter {Client : clientset , NamespaceClient : coreclientset .Namespaces ()},
274
+ Confirm : true ,
275
+ }
276
+ err := retry .RetryOnConflict (retry .DefaultBackoff , func () error {
277
+ result , err := opts .Run ()
278
+ if err != nil {
279
+ return err
280
+ }
281
+ switch {
282
+ case result .Protected && result .Operation != reconciliation .ReconcileNone :
283
+ glog .Warningf ("skipped reconcile-protected rolebinding.%s/%s in %v with missing subjects: %v" , rbac .GroupName , roleBinding .Name , namespace , result .MissingSubjects )
284
+ case result .Operation == reconciliation .ReconcileUpdate :
285
+ glog .Infof ("updated rolebinding.%s/%s in %v with additional subjects: %v" , rbac .GroupName , roleBinding .Name , namespace , result .MissingSubjects )
286
+ case result .Operation == reconciliation .ReconcileCreate :
287
+ glog .Infof ("created rolebinding.%s/%s in %v" , rbac .GroupName , roleBinding .Name , namespace )
288
+ case result .Operation == reconciliation .ReconcileRecreate :
289
+ glog .Infof ("recreated rolebinding.%s/%s in %v" , rbac .GroupName , roleBinding .Name , namespace )
290
+ }
291
+ return nil
292
+ })
293
+ if err != nil {
294
+ // don't fail on failures, try to create as many as you can
295
+ utilruntime .HandleError (fmt .Errorf ("unable to reconcile rolebinding.%s/%s in %v: %v" , rbac .GroupName , roleBinding .Name , namespace , err ))
296
+ }
297
+ }
298
+ }
299
+
300
+ return true , nil
301
+ })
302
+ // if we're never able to make it through intialization, kill the API server
303
+ if err != nil {
304
+ return fmt .Errorf ("unable to initialize roles: %v" , err )
284
305
}
285
306
286
- return true , nil
287
- })
288
- // if we're never able to make it through intialization, kill the API server
289
- if err != nil {
290
- return fmt .Errorf ("unable to initialize roles: %v" , err )
307
+ return nil
291
308
}
292
-
293
- return nil
294
309
}
295
310
296
311
func (p RESTStorageProvider ) GroupName () string {
0 commit comments