@@ -180,20 +180,24 @@ func (c *MasterConfig) newAssetServerHandler() (http.Handler, error) {
180
180
return assetServer .GenericAPIServer .PrepareRun ().GenericAPIServer .Handler .FullHandlerChain , nil
181
181
}
182
182
183
- func (c * MasterConfig ) newOAuthServerHandler () (http.Handler , error ) {
183
+ func (c * MasterConfig ) newOAuthServerHandler () (http.Handler , map [ string ]apiserver. PostStartHookFunc , error ) {
184
184
if c .Options .OAuthConfig == nil {
185
- return http .NotFoundHandler (), nil
185
+ return http .NotFoundHandler (), nil , nil
186
186
}
187
187
188
188
config , err := NewOAuthServerConfigFromMasterConfig (c )
189
189
if err != nil {
190
- return nil , err
190
+ return nil , nil , err
191
191
}
192
192
oauthServer , err := config .Complete ().New (apiserver .EmptyDelegate )
193
193
if err != nil {
194
- return nil , err
194
+ return nil , nil , err
195
195
}
196
- return oauthServer .GenericAPIServer .PrepareRun ().GenericAPIServer .Handler .FullHandlerChain , nil
196
+ return oauthServer .GenericAPIServer .PrepareRun ().GenericAPIServer .Handler .FullHandlerChain ,
197
+ map [string ]apiserver.PostStartHookFunc {
198
+ "oauth.openshift.io-RegisterTokenRequestEndpoint" : config .EnsureBootstrapOAuthClients ,
199
+ },
200
+ nil
197
201
}
198
202
199
203
func (c * MasterConfig ) withAggregator (delegateAPIServer apiserver.DelegationTarget , kubeAPIServerConfig apiserver.Config , apiExtensionsInformers apiextensionsinformers.SharedInformerFactory ) (* aggregatorapiserver.APIAggregator , error ) {
@@ -216,8 +220,9 @@ func (c *MasterConfig) Run(kubeAPIServerConfig *kubeapiserver.Config, controller
216
220
var err error
217
221
var apiExtensionsInformers apiextensionsinformers.SharedInformerFactory
218
222
var delegateAPIServer apiserver.DelegationTarget
223
+ var extraPostStartHooks map [string ]apiserver.PostStartHookFunc
219
224
220
- kubeAPIServerConfig .GenericConfig .BuildHandlerChainFunc , err = c .buildHandlerChain ()
225
+ kubeAPIServerConfig .GenericConfig .BuildHandlerChainFunc , extraPostStartHooks , err = c .buildHandlerChain ()
221
226
if err != nil {
222
227
return err
223
228
}
@@ -255,79 +260,84 @@ func (c *MasterConfig) Run(kubeAPIServerConfig *kubeapiserver.Config, controller
255
260
// add post-start hooks
256
261
aggregatedAPIServer .GenericAPIServer .AddPostStartHookOrDie ("template.openshift.io-sharednamespace" , c .ensureOpenShiftSharedResourcesNamespace )
257
262
aggregatedAPIServer .GenericAPIServer .AddPostStartHookOrDie ("authorization.openshift.io-bootstrapclusterroles" , bootstrappolicy .Policy ().EnsureRBACPolicy ())
263
+ for name , fn := range extraPostStartHooks {
264
+ aggregatedAPIServer .GenericAPIServer .AddPostStartHookOrDie (name , fn )
265
+ }
258
266
259
267
go aggregatedAPIServer .GenericAPIServer .PrepareRun ().Run (stopCh )
260
268
261
269
// Attempt to verify the server came up for 20 seconds (100 tries * 100ms, 100ms timeout per try)
262
270
return cmdutil .WaitForSuccessfulDial (true , aggregatedAPIServer .GenericAPIServer .SecureServingInfo .BindNetwork , aggregatedAPIServer .GenericAPIServer .SecureServingInfo .BindAddress , 100 * time .Millisecond , 100 * time .Millisecond , 100 )
263
271
}
264
272
265
- func (c * MasterConfig ) buildHandlerChain () (func (apiHandler http.Handler , kc * apiserver.Config ) http.Handler , error ) {
273
+ func (c * MasterConfig ) buildHandlerChain () (func (apiHandler http.Handler , kc * apiserver.Config ) http.Handler , map [ string ]apiserver. PostStartHookFunc , error ) {
266
274
assetServerHandler , err := c .newAssetServerHandler ()
267
275
if err != nil {
268
- return nil , err
276
+ return nil , nil , err
269
277
}
270
- oauthServerHandler , err := c .newOAuthServerHandler ()
278
+ oauthServerHandler , extraPostStartHooks , err := c .newOAuthServerHandler ()
271
279
if err != nil {
272
- return nil , err
280
+ return nil , nil , err
273
281
}
274
282
275
283
return func (apiHandler http.Handler , genericConfig * apiserver.Config ) http.Handler {
276
- // these are after the kube handler
277
- handler := c .versionSkewFilter (apiHandler , genericConfig .RequestContextMapper )
278
- handler = namespacingFilter (handler , genericConfig .RequestContextMapper )
279
-
280
- // these are all equivalent to the kube handler chain
281
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
282
- handler = serverhandlers .AuthorizationFilter (handler , c .Authorizer , c .AuthorizationAttributeBuilder , genericConfig .RequestContextMapper )
283
- handler = serverhandlers .ImpersonationFilter (handler , c .Authorizer , cache .NewGroupCache (c .UserInformers .User ().InternalVersion ().Groups ()), genericConfig .RequestContextMapper )
284
- // audit handler must comes before the impersonationFilter to read the original user
285
- if c .Options .AuditConfig .Enabled {
286
- var writer io.Writer
287
- if len (c .Options .AuditConfig .AuditFilePath ) > 0 {
288
- writer = & lumberjack.Logger {
289
- Filename : c .Options .AuditConfig .AuditFilePath ,
290
- MaxAge : c .Options .AuditConfig .MaximumFileRetentionDays ,
291
- MaxBackups : c .Options .AuditConfig .MaximumRetainedFiles ,
292
- MaxSize : c .Options .AuditConfig .MaximumFileSizeMegabytes ,
284
+ // these are after the kube handler
285
+ handler := c .versionSkewFilter (apiHandler , genericConfig .RequestContextMapper )
286
+ handler = namespacingFilter (handler , genericConfig .RequestContextMapper )
287
+
288
+ // these are all equivalent to the kube handler chain
289
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
290
+ handler = serverhandlers .AuthorizationFilter (handler , c .Authorizer , c .AuthorizationAttributeBuilder , genericConfig .RequestContextMapper )
291
+ handler = serverhandlers .ImpersonationFilter (handler , c .Authorizer , cache .NewGroupCache (c .UserInformers .User ().InternalVersion ().Groups ()), genericConfig .RequestContextMapper )
292
+ // audit handler must comes before the impersonationFilter to read the original user
293
+ if c .Options .AuditConfig .Enabled {
294
+ var writer io.Writer
295
+ if len (c .Options .AuditConfig .AuditFilePath ) > 0 {
296
+ writer = & lumberjack.Logger {
297
+ Filename : c .Options .AuditConfig .AuditFilePath ,
298
+ MaxAge : c .Options .AuditConfig .MaximumFileRetentionDays ,
299
+ MaxBackups : c .Options .AuditConfig .MaximumRetainedFiles ,
300
+ MaxSize : c .Options .AuditConfig .MaximumFileSizeMegabytes ,
301
+ }
302
+ } else {
303
+ // backwards compatible writer to regular log
304
+ writer = cmdutil .NewGLogWriterV (0 )
293
305
}
294
- } else {
295
- // backwards compatible writer to regular log
296
- writer = cmdutil .NewGLogWriterV (0 )
306
+ c .AuditBackend = auditlog .NewBackend (writer )
307
+ auditPolicyChecker := auditpolicy .NewChecker (& auditinternal.Policy {
308
+ // This is for backwards compatibility maintaining the old visibility, ie. just
309
+ // raw overview of the requests comming in.
310
+ Rules : []auditinternal.PolicyRule {{Level : auditinternal .LevelMetadata }},
311
+ })
312
+ handler = apifilters .WithAudit (handler , genericConfig .RequestContextMapper , c .AuditBackend , auditPolicyChecker , genericConfig .LongRunningFunc )
297
313
}
298
- c .AuditBackend = auditlog .NewBackend (writer )
299
- auditPolicyChecker := auditpolicy .NewChecker (& auditinternal.Policy {
300
- // This is for backwards compatibility maintaining the old visibility, ie. just
301
- // raw overview of the requests comming in.
302
- Rules : []auditinternal.PolicyRule {{Level : auditinternal .LevelMetadata }},
303
- })
304
- handler = apifilters .WithAudit (handler , genericConfig .RequestContextMapper , c .AuditBackend , auditPolicyChecker , genericConfig .LongRunningFunc )
305
- }
306
- handler = serverhandlers .AuthenticationHandlerFilter (handler , c .Authenticator , genericConfig .RequestContextMapper )
307
- handler = apiserverfilters .WithCORS (handler , c .Options .CORSAllowedOrigins , nil , nil , nil , "true" )
308
- handler = apiserverfilters .WithTimeoutForNonLongRunningRequests (handler , genericConfig .RequestContextMapper , genericConfig .LongRunningFunc )
309
- // TODO: MaxRequestsInFlight should be subdivided by intent, type of behavior, and speed of
310
- // execution - updates vs reads, long reads vs short reads, fat reads vs skinny reads.
311
- // NOTE: read vs. write is implemented in Kube 1.6+
312
- handler = apiserverfilters .WithMaxInFlightLimit (handler , genericConfig .MaxRequestsInFlight , genericConfig .MaxMutatingRequestsInFlight , genericConfig .RequestContextMapper , genericConfig .LongRunningFunc )
313
- handler = apifilters .WithRequestInfo (handler , apiserver .NewRequestInfoResolver (genericConfig ), genericConfig .RequestContextMapper )
314
- handler = apirequest .WithRequestContext (handler , genericConfig .RequestContextMapper )
315
- handler = apiserverfilters .WithPanicRecovery (handler )
316
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
317
-
318
- // these handlers are all before the normal kube chain
319
- handler = cacheControlFilter (handler , "no-store" ) // protected endpoints should not be cached
320
-
321
- if c .WebConsoleEnabled () {
322
- handler = assetapiserver .WithAssetServerRedirect (handler , c .Options .AssetConfig .PublicURL )
323
- }
324
- // these handlers are actually separate API servers which have their own handler chains.
325
- // our server embeds these
326
- handler = c .withConsoleRedirection (handler , assetServerHandler , c .Options .AssetConfig )
327
- handler = c .withOAuthRedirection (handler , oauthServerHandler )
328
-
329
- return handler
330
- }, nil
314
+ handler = serverhandlers .AuthenticationHandlerFilter (handler , c .Authenticator , genericConfig .RequestContextMapper )
315
+ handler = apiserverfilters .WithCORS (handler , c .Options .CORSAllowedOrigins , nil , nil , nil , "true" )
316
+ handler = apiserverfilters .WithTimeoutForNonLongRunningRequests (handler , genericConfig .RequestContextMapper , genericConfig .LongRunningFunc )
317
+ // TODO: MaxRequestsInFlight should be subdivided by intent, type of behavior, and speed of
318
+ // execution - updates vs reads, long reads vs short reads, fat reads vs skinny reads.
319
+ // NOTE: read vs. write is implemented in Kube 1.6+
320
+ handler = apiserverfilters .WithMaxInFlightLimit (handler , genericConfig .MaxRequestsInFlight , genericConfig .MaxMutatingRequestsInFlight , genericConfig .RequestContextMapper , genericConfig .LongRunningFunc )
321
+ handler = apifilters .WithRequestInfo (handler , apiserver .NewRequestInfoResolver (genericConfig ), genericConfig .RequestContextMapper )
322
+ handler = apirequest .WithRequestContext (handler , genericConfig .RequestContextMapper )
323
+ handler = apiserverfilters .WithPanicRecovery (handler )
324
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
325
+
326
+ // these handlers are all before the normal kube chain
327
+ handler = cacheControlFilter (handler , "no-store" ) // protected endpoints should not be cached
328
+
329
+ if c .WebConsoleEnabled () {
330
+ handler = assetapiserver .WithAssetServerRedirect (handler , c .Options .AssetConfig .PublicURL )
331
+ }
332
+ // these handlers are actually separate API servers which have their own handler chains.
333
+ // our server embeds these
334
+ handler = c .withConsoleRedirection (handler , assetServerHandler , c .Options .AssetConfig )
335
+ handler = c .withOAuthRedirection (handler , oauthServerHandler )
336
+
337
+ return handler
338
+ },
339
+ extraPostStartHooks ,
340
+ nil
331
341
}
332
342
333
343
func (c * MasterConfig ) withConsoleRedirection (handler , assetServerHandler http.Handler , assetConfig * configapi.AssetConfig ) http.Handler {
0 commit comments