impersonator: wire in genericapiserver.Config

Signed-off-by: Monis Khan <mok@vmware.com>
This commit is contained in:
Monis Khan 2021-03-12 09:56:34 -05:00
parent 5b1dc0abdf
commit 12b13b1ea5
No known key found for this signature in database
GPG Key ID: 52C90ADA01B269B8
2 changed files with 63 additions and 59 deletions

View File

@ -122,7 +122,7 @@ func newInternal( //nolint:funlen // yeah, it's kind of long.
// Assume proto config is safe because transport level configs do not use rest.ContentConfig. // Assume proto config is safe because transport level configs do not use rest.ContentConfig.
// Thus if we are interacting with actual APIs, they should be using pre-built clients. // Thus if we are interacting with actual APIs, they should be using pre-built clients.
impersonationProxy, err := newImpersonationReverseProxy(rest.CopyConfig(kubeClient.ProtoConfig)) impersonationProxyFunc, err := newImpersonationReverseProxyFunc(rest.CopyConfig(kubeClient.ProtoConfig))
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -130,7 +130,8 @@ func newInternal( //nolint:funlen // yeah, it's kind of long.
defaultBuildHandlerChainFunc := serverConfig.BuildHandlerChainFunc defaultBuildHandlerChainFunc := serverConfig.BuildHandlerChainFunc
serverConfig.BuildHandlerChainFunc = func(_ http.Handler, c *genericapiserver.Config) http.Handler { serverConfig.BuildHandlerChainFunc = func(_ http.Handler, c *genericapiserver.Config) http.Handler {
// We ignore the passed in handler because we never have any REST APIs to delegate to. // We ignore the passed in handler because we never have any REST APIs to delegate to.
handler := defaultBuildHandlerChainFunc(impersonationProxy, c) handler := impersonationProxyFunc(c)
handler = defaultBuildHandlerChainFunc(handler, c)
handler = securityheader.Wrap(handler) handler = securityheader.Wrap(handler)
return handler return handler
} }
@ -192,7 +193,7 @@ type comparableAuthorizer struct {
authorizer.AuthorizerFunc authorizer.AuthorizerFunc
} }
func newImpersonationReverseProxy(restConfig *rest.Config) (http.Handler, error) { func newImpersonationReverseProxyFunc(restConfig *rest.Config) (func(*genericapiserver.Config) http.Handler, error) {
serverURL, err := url.Parse(restConfig.Host) serverURL, err := url.Parse(restConfig.Host)
if err != nil { if err != nil {
return nil, fmt.Errorf("could not parse host URL from in-cluster config: %w", err) return nil, fmt.Errorf("could not parse host URL from in-cluster config: %w", err)
@ -209,6 +210,7 @@ func newImpersonationReverseProxy(restConfig *rest.Config) (http.Handler, error)
return nil, fmt.Errorf("could not get in-cluster transport: %w", err) return nil, fmt.Errorf("could not get in-cluster transport: %w", err)
} }
return func(c *genericapiserver.Config) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if len(r.Header.Values("Authorization")) != 0 { if len(r.Header.Values("Authorization")) != 0 {
plog.Warning("aggregated API server logic did not delete authorization header but it is always supposed to do so", plog.Warning("aggregated API server logic did not delete authorization header but it is always supposed to do so",
@ -265,7 +267,8 @@ func newImpersonationReverseProxy(restConfig *rest.Config) (http.Handler, error)
// transport.NewImpersonatingRoundTripper clones the request before setting headers // transport.NewImpersonatingRoundTripper clones the request before setting headers
// so this call will not accidentally mutate the input request (see http.Handler docs) // so this call will not accidentally mutate the input request (see http.Handler docs)
reverseProxy.ServeHTTP(w, r) reverseProxy.ServeHTTP(w, r)
}), nil })
}, nil
} }
func ensureNoImpersonationHeaders(r *http.Request) error { func ensureNoImpersonationHeaders(r *http.Request) error {

View File

@ -450,17 +450,18 @@ func TestImpersonatorHTTPHandler(t *testing.T) {
tt.restConfig = &testKubeAPIServerKubeconfig tt.restConfig = &testKubeAPIServerKubeconfig
} }
impersonatorHTTPHandler, err := newImpersonationReverseProxy(tt.restConfig) impersonatorHTTPHandlerFunc, err := newImpersonationReverseProxyFunc(tt.restConfig)
if tt.wantCreationErr != "" { if tt.wantCreationErr != "" {
require.EqualError(t, err, tt.wantCreationErr) require.EqualError(t, err, tt.wantCreationErr)
require.Nil(t, impersonatorHTTPHandlerFunc)
return return
} }
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, impersonatorHTTPHandler) require.NotNil(t, impersonatorHTTPHandlerFunc)
w := httptest.NewRecorder() w := httptest.NewRecorder()
requestBeforeServe := tt.request.Clone(tt.request.Context()) requestBeforeServe := tt.request.Clone(tt.request.Context())
impersonatorHTTPHandler.ServeHTTP(w, tt.request) impersonatorHTTPHandlerFunc(nil).ServeHTTP(w, tt.request)
require.Equal(t, requestBeforeServe, tt.request, "ServeHTTP() mutated the request, and it should not per http.Handler docs") require.Equal(t, requestBeforeServe, tt.request, "ServeHTTP() mutated the request, and it should not per http.Handler docs")
if tt.wantHTTPStatus != 0 { if tt.wantHTTPStatus != 0 {