From 1b38199ea8b220be0b645af8a4cbdef4c87ce7fc Mon Sep 17 00:00:00 2001 From: Jefftree Date: Thu, 5 Dec 2019 17:28:59 -0800 Subject: [PATCH] pass Dialer instead of egressselector to webhooks --- cmd/kube-apiserver/app/server.go | 25 +++++++++++---- pkg/kubeapiserver/authenticator/BUILD | 2 +- pkg/kubeapiserver/authenticator/config.go | 15 +++------ pkg/kubeapiserver/authorizer/BUILD | 1 + pkg/kubeapiserver/authorizer/config.go | 7 ++++- .../k8s.io/apiserver/pkg/util/webhook/BUILD | 1 - .../apiserver/pkg/util/webhook/webhook.go | 18 ++++------- .../pkg/authenticator/token/webhook/BUILD | 2 +- .../authenticator/token/webhook/webhook.go | 12 +++---- .../plugin/pkg/authorizer/webhook/BUILD | 1 + .../plugin/pkg/authorizer/webhook/webhook.go | 11 ++++--- .../pkg/authorizer/webhook/webhook_v1_test.go | 4 +-- .../webhook/webhook_v1beta1_test.go | 4 +-- test/integration/auth/BUILD | 1 + test/integration/auth/auth_test.go | 31 +++++++++++++++++-- 15 files changed, 85 insertions(+), 50 deletions(-) diff --git a/cmd/kube-apiserver/app/server.go b/cmd/kube-apiserver/app/server.go index 3cb01639651..a278e3ad3b4 100644 --- a/cmd/kube-apiserver/app/server.go +++ b/cmd/kube-apiserver/app/server.go @@ -498,13 +498,13 @@ func buildGenericConfig( } versionedInformers = clientgoinformers.NewSharedInformerFactory(clientgoExternalClient, 10*time.Minute) - genericConfig.Authentication.Authenticator, genericConfig.OpenAPIConfig.SecurityDefinitions, err = BuildAuthenticator(s, genericConfig, clientgoExternalClient, versionedInformers) + genericConfig.Authentication.Authenticator, genericConfig.OpenAPIConfig.SecurityDefinitions, err = BuildAuthenticator(s, genericConfig.EgressSelector, clientgoExternalClient, versionedInformers) if err != nil { lastErr = fmt.Errorf("invalid authentication config: %v", err) return } - genericConfig.Authorization.Authorizer, genericConfig.RuleResolver, err = BuildAuthorizer(s, versionedInformers) + genericConfig.Authorization.Authorizer, genericConfig.RuleResolver, err = BuildAuthorizer(s, genericConfig.EgressSelector, versionedInformers) if err != nil { lastErr = fmt.Errorf("invalid authorization config: %v", err) return @@ -560,7 +560,7 @@ func buildGenericConfig( } // BuildAuthenticator constructs the authenticator -func BuildAuthenticator(s *options.ServerRunOptions, c *genericapiserver.Config, extclient clientgoclientset.Interface, versionedInformer clientgoinformers.SharedInformerFactory) (authenticator.Request, *spec.SecurityDefinitions, error) { +func BuildAuthenticator(s *options.ServerRunOptions, EgressSelector *egressselector.EgressSelector, extclient clientgoclientset.Interface, versionedInformer clientgoinformers.SharedInformerFactory) (authenticator.Request, *spec.SecurityDefinitions, error) { authenticatorConfig, err := s.Authentication.ToAuthenticationConfig() if err != nil { return nil, nil, err @@ -577,16 +577,29 @@ func BuildAuthenticator(s *options.ServerRunOptions, c *genericapiserver.Config, versionedInformer.Core().V1().Secrets().Lister().Secrets(v1.NamespaceSystem), ) - if c.EgressSelector != nil { - authenticatorConfig.EgressLookup = c.EgressSelector.Lookup + if EgressSelector != nil { + egressDialer, err := EgressSelector.Lookup(egressselector.Master.AsNetworkContext()) + if err != nil { + return nil, nil, err + } + authenticatorConfig.CustomDial = egressDialer } return authenticatorConfig.New() } // BuildAuthorizer constructs the authorizer -func BuildAuthorizer(s *options.ServerRunOptions, versionedInformers clientgoinformers.SharedInformerFactory) (authorizer.Authorizer, authorizer.RuleResolver, error) { +func BuildAuthorizer(s *options.ServerRunOptions, EgressSelector *egressselector.EgressSelector, versionedInformers clientgoinformers.SharedInformerFactory) (authorizer.Authorizer, authorizer.RuleResolver, error) { authorizationConfig := s.Authorization.ToAuthorizationConfig(versionedInformers) + + if EgressSelector != nil { + egressDialer, err := EgressSelector.Lookup(egressselector.Master.AsNetworkContext()) + if err != nil { + return nil, nil, err + } + authorizationConfig.CustomDial = egressDialer + } + return authorizationConfig.New() } diff --git a/pkg/kubeapiserver/authenticator/BUILD b/pkg/kubeapiserver/authenticator/BUILD index 9f537e18760..ba70ad6e388 100644 --- a/pkg/kubeapiserver/authenticator/BUILD +++ b/pkg/kubeapiserver/authenticator/BUILD @@ -12,6 +12,7 @@ go_library( deps = [ "//pkg/features:go_default_library", "//pkg/serviceaccount:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/util/net:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authentication/authenticator:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authentication/authenticatorfactory:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authentication/group:go_default_library", @@ -25,7 +26,6 @@ go_library( "//staging/src/k8s.io/apiserver/pkg/authentication/token/tokenfile:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authentication/token/union:go_default_library", "//staging/src/k8s.io/apiserver/pkg/server/dynamiccertificates:go_default_library", - "//staging/src/k8s.io/apiserver/pkg/server/egressselector:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library", "//staging/src/k8s.io/apiserver/plugin/pkg/authenticator/password/passwordfile:go_default_library", "//staging/src/k8s.io/apiserver/plugin/pkg/authenticator/request/basicauth:go_default_library", diff --git a/pkg/kubeapiserver/authenticator/config.go b/pkg/kubeapiserver/authenticator/config.go index daf1894ad82..c54c64651cd 100644 --- a/pkg/kubeapiserver/authenticator/config.go +++ b/pkg/kubeapiserver/authenticator/config.go @@ -21,6 +21,7 @@ import ( "github.com/go-openapi/spec" + utilnet "k8s.io/apimachinery/pkg/util/net" "k8s.io/apiserver/pkg/authentication/authenticator" "k8s.io/apiserver/pkg/authentication/authenticatorfactory" "k8s.io/apiserver/pkg/authentication/group" @@ -34,7 +35,6 @@ import ( "k8s.io/apiserver/pkg/authentication/token/tokenfile" tokenunion "k8s.io/apiserver/pkg/authentication/token/union" "k8s.io/apiserver/pkg/server/dynamiccertificates" - "k8s.io/apiserver/pkg/server/egressselector" utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/apiserver/plugin/pkg/authenticator/password/passwordfile" "k8s.io/apiserver/plugin/pkg/authenticator/request/basicauth" @@ -85,8 +85,8 @@ type Config struct { // If this value is nil, then mutual TLS is disabled. ClientCAContentProvider dynamiccertificates.CAContentProvider - // Lookup will give us a dialer if the egress selector is configured for it - EgressLookup egressselector.Lookup + // Optional field, custom dial function used to connect to webhook + CustomDial utilnet.DialFunc } // New returns an authenticator.Request or an error that supports the standard @@ -311,15 +311,10 @@ func newServiceAccountAuthenticator(iss string, keyfiles []string, apiAudiences } func newWebhookTokenAuthenticator(config Config) (authenticator.Token, error) { - webhookConfigFile := config.WebhookTokenAuthnConfigFile - version := config.WebhookTokenAuthnVersion - ttl := config.WebhookTokenAuthnCacheTTL - implicitAuds := config.APIAudiences - - webhookTokenAuthenticator, err := webhook.New(webhookConfigFile, version, implicitAuds, config.EgressLookup) + webhookTokenAuthenticator, err := webhook.New(config.WebhookTokenAuthnConfigFile, config.WebhookTokenAuthnVersion, config.APIAudiences, config.CustomDial) if err != nil { return nil, err } - return tokencache.New(webhookTokenAuthenticator, false, ttl, ttl), nil + return tokencache.New(webhookTokenAuthenticator, false, config.WebhookTokenAuthnCacheTTL, config.WebhookTokenAuthnCacheTTL), nil } diff --git a/pkg/kubeapiserver/authorizer/BUILD b/pkg/kubeapiserver/authorizer/BUILD index 129eacedfca..06e5735e1a1 100644 --- a/pkg/kubeapiserver/authorizer/BUILD +++ b/pkg/kubeapiserver/authorizer/BUILD @@ -16,6 +16,7 @@ go_library( "//plugin/pkg/auth/authorizer/node:go_default_library", "//plugin/pkg/auth/authorizer/rbac:go_default_library", "//plugin/pkg/auth/authorizer/rbac/bootstrappolicy:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/util/net:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authorization/authorizerfactory:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authorization/union:go_default_library", diff --git a/pkg/kubeapiserver/authorizer/config.go b/pkg/kubeapiserver/authorizer/config.go index a6542bfeaa0..cdbc11f48f3 100644 --- a/pkg/kubeapiserver/authorizer/config.go +++ b/pkg/kubeapiserver/authorizer/config.go @@ -20,6 +20,7 @@ import ( "fmt" "time" + utilnet "k8s.io/apimachinery/pkg/util/net" "k8s.io/apiserver/pkg/authorization/authorizer" "k8s.io/apiserver/pkg/authorization/authorizerfactory" "k8s.io/apiserver/pkg/authorization/union" @@ -54,6 +55,9 @@ type Config struct { WebhookCacheUnauthorizedTTL time.Duration VersionedInformerFactory versionedinformers.SharedInformerFactory + + // Optional field, custom dial function used to connect to webhook + CustomDial utilnet.DialFunc } // New returns the right sort of union of multiple authorizer.Authorizer objects @@ -102,7 +106,8 @@ func (config Config) New() (authorizer.Authorizer, authorizer.RuleResolver, erro webhookAuthorizer, err := webhook.New(config.WebhookConfigFile, config.WebhookVersion, config.WebhookCacheAuthorizedTTL, - config.WebhookCacheUnauthorizedTTL) + config.WebhookCacheUnauthorizedTTL, + config.CustomDial) if err != nil { return nil, nil, err } diff --git a/staging/src/k8s.io/apiserver/pkg/util/webhook/BUILD b/staging/src/k8s.io/apiserver/pkg/util/webhook/BUILD index 91717516b83..d8b20370007 100644 --- a/staging/src/k8s.io/apiserver/pkg/util/webhook/BUILD +++ b/staging/src/k8s.io/apiserver/pkg/util/webhook/BUILD @@ -29,7 +29,6 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/util/validation:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library", - "//staging/src/k8s.io/apiserver/pkg/server/egressselector:go_default_library", "//staging/src/k8s.io/client-go/rest:go_default_library", "//staging/src/k8s.io/client-go/tools/clientcmd:go_default_library", "//staging/src/k8s.io/client-go/tools/clientcmd/api:go_default_library", diff --git a/staging/src/k8s.io/apiserver/pkg/util/webhook/webhook.go b/staging/src/k8s.io/apiserver/pkg/util/webhook/webhook.go index 8975129b0b1..1ac14fb00b6 100644 --- a/staging/src/k8s.io/apiserver/pkg/util/webhook/webhook.go +++ b/staging/src/k8s.io/apiserver/pkg/util/webhook/webhook.go @@ -29,7 +29,6 @@ import ( "k8s.io/apimachinery/pkg/util/net" utilnet "k8s.io/apimachinery/pkg/util/net" "k8s.io/apimachinery/pkg/util/wait" - "k8s.io/apiserver/pkg/server/egressselector" "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" ) @@ -63,11 +62,11 @@ func DefaultShouldRetry(err error) bool { } // NewGenericWebhook creates a new GenericWebhook from the provided kubeconfig file. -func NewGenericWebhook(scheme *runtime.Scheme, codecFactory serializer.CodecFactory, kubeConfigFile string, groupVersions []schema.GroupVersion, initialBackoff time.Duration, egressLookup egressselector.Lookup) (*GenericWebhook, error) { - return newGenericWebhook(scheme, codecFactory, kubeConfigFile, groupVersions, initialBackoff, defaultRequestTimeout, egressLookup) +func NewGenericWebhook(scheme *runtime.Scheme, codecFactory serializer.CodecFactory, kubeConfigFile string, groupVersions []schema.GroupVersion, initialBackoff time.Duration, customDial utilnet.DialFunc) (*GenericWebhook, error) { + return newGenericWebhook(scheme, codecFactory, kubeConfigFile, groupVersions, initialBackoff, defaultRequestTimeout, customDial) } -func newGenericWebhook(scheme *runtime.Scheme, codecFactory serializer.CodecFactory, kubeConfigFile string, groupVersions []schema.GroupVersion, initialBackoff, requestTimeout time.Duration, egressLookup egressselector.Lookup) (*GenericWebhook, error) { +func newGenericWebhook(scheme *runtime.Scheme, codecFactory serializer.CodecFactory, kubeConfigFile string, groupVersions []schema.GroupVersion, initialBackoff, requestTimeout time.Duration, customDial utilnet.DialFunc) (*GenericWebhook, error) { for _, groupVersion := range groupVersions { if !scheme.IsVersionRegistered(groupVersion) { return nil, fmt.Errorf("webhook plugin requires enabling extension resource: %s", groupVersion) @@ -96,14 +95,9 @@ func newGenericWebhook(scheme *runtime.Scheme, codecFactory serializer.CodecFact codec := codecFactory.LegacyCodec(groupVersions...) clientConfig.ContentConfig.NegotiatedSerializer = serializer.NegotiatedSerializerWrapper(runtime.SerializerInfo{Serializer: codec}) - if egressLookup != nil { - networkContext := egressselector.Master.AsNetworkContext() - var egressDialer utilnet.DialFunc - egressDialer, err = egressLookup(networkContext) - if err != nil { - return nil, err - } - clientConfig.Dial = egressDialer + + if customDial != nil { + clientConfig.Dial = customDial } restClient, err := rest.UnversionedRESTClientFor(clientConfig) diff --git a/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook/BUILD b/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook/BUILD index 9159bcb5f89..2de5ec78738 100644 --- a/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook/BUILD +++ b/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook/BUILD @@ -39,9 +39,9 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/util/net:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authentication/authenticator:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library", - "//staging/src/k8s.io/apiserver/pkg/server/egressselector:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/webhook:go_default_library", "//staging/src/k8s.io/client-go/kubernetes/scheme:go_default_library", "//staging/src/k8s.io/client-go/kubernetes/typed/authentication/v1:go_default_library", diff --git a/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook/webhook.go b/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook/webhook.go index 1d5a90f6b8e..8307dd6f32d 100644 --- a/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook/webhook.go +++ b/staging/src/k8s.io/apiserver/plugin/pkg/authenticator/token/webhook/webhook.go @@ -28,9 +28,9 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" + utilnet "k8s.io/apimachinery/pkg/util/net" "k8s.io/apiserver/pkg/authentication/authenticator" "k8s.io/apiserver/pkg/authentication/user" - "k8s.io/apiserver/pkg/server/egressselector" "k8s.io/apiserver/pkg/util/webhook" "k8s.io/client-go/kubernetes/scheme" authenticationv1client "k8s.io/client-go/kubernetes/typed/authentication/v1" @@ -64,8 +64,8 @@ func NewFromInterface(tokenReview authenticationv1client.TokenReviewInterface, i // file. It is recommend to wrap this authenticator with the token cache // authenticator implemented in // k8s.io/apiserver/pkg/authentication/token/cache. -func New(kubeConfigFile string, version string, implicitAuds authenticator.Audiences, egressLookup egressselector.Lookup) (*WebhookTokenAuthenticator, error) { - tokenReview, err := tokenReviewInterfaceFromKubeconfig(kubeConfigFile, version, egressLookup) +func New(kubeConfigFile string, version string, implicitAuds authenticator.Audiences, customDial utilnet.DialFunc) (*WebhookTokenAuthenticator, error) { + tokenReview, err := tokenReviewInterfaceFromKubeconfig(kubeConfigFile, version, customDial) if err != nil { return nil, err } @@ -154,7 +154,7 @@ func (w *WebhookTokenAuthenticator) AuthenticateToken(ctx context.Context, token // tokenReviewInterfaceFromKubeconfig builds a client from the specified kubeconfig file, // and returns a TokenReviewInterface that uses that client. Note that the client submits TokenReview // requests to the exact path specified in the kubeconfig file, so arbitrary non-API servers can be targeted. -func tokenReviewInterfaceFromKubeconfig(kubeConfigFile string, version string, egressLookup egressselector.Lookup) (tokenReviewer, error) { +func tokenReviewInterfaceFromKubeconfig(kubeConfigFile string, version string, customDial utilnet.DialFunc) (tokenReviewer, error) { localScheme := runtime.NewScheme() if err := scheme.AddToScheme(localScheme); err != nil { return nil, err @@ -166,7 +166,7 @@ func tokenReviewInterfaceFromKubeconfig(kubeConfigFile string, version string, e if err := localScheme.SetVersionPriority(groupVersions...); err != nil { return nil, err } - gw, err := webhook.NewGenericWebhook(localScheme, scheme.Codecs, kubeConfigFile, groupVersions, 0, egressLookup) + gw, err := webhook.NewGenericWebhook(localScheme, scheme.Codecs, kubeConfigFile, groupVersions, 0, customDial) if err != nil { return nil, err } @@ -177,7 +177,7 @@ func tokenReviewInterfaceFromKubeconfig(kubeConfigFile string, version string, e if err := localScheme.SetVersionPriority(groupVersions...); err != nil { return nil, err } - gw, err := webhook.NewGenericWebhook(localScheme, scheme.Codecs, kubeConfigFile, groupVersions, 0, egressLookup) + gw, err := webhook.NewGenericWebhook(localScheme, scheme.Codecs, kubeConfigFile, groupVersions, 0, customDial) if err != nil { return nil, err } diff --git a/staging/src/k8s.io/apiserver/plugin/pkg/authorizer/webhook/BUILD b/staging/src/k8s.io/apiserver/plugin/pkg/authorizer/webhook/BUILD index b3208931c75..60276052359 100644 --- a/staging/src/k8s.io/apiserver/plugin/pkg/authorizer/webhook/BUILD +++ b/staging/src/k8s.io/apiserver/plugin/pkg/authorizer/webhook/BUILD @@ -39,6 +39,7 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/cache:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/util/net:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/webhook:go_default_library", diff --git a/staging/src/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook.go b/staging/src/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook.go index b496b6c5874..3383700640d 100644 --- a/staging/src/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook.go +++ b/staging/src/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook.go @@ -31,6 +31,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/cache" + utilnet "k8s.io/apimachinery/pkg/util/net" "k8s.io/apiserver/pkg/authentication/user" "k8s.io/apiserver/pkg/authorization/authorizer" "k8s.io/apiserver/pkg/util/webhook" @@ -84,8 +85,8 @@ func NewFromInterface(subjectAccessReview authorizationv1client.SubjectAccessRev // // For additional HTTP configuration, refer to the kubeconfig documentation // https://kubernetes.io/docs/user-guide/kubeconfig-file/. -func New(kubeConfigFile string, version string, authorizedTTL, unauthorizedTTL time.Duration) (*WebhookAuthorizer, error) { - subjectAccessReview, err := subjectAccessReviewInterfaceFromKubeconfig(kubeConfigFile, version) +func New(kubeConfigFile string, version string, authorizedTTL, unauthorizedTTL time.Duration, customDial utilnet.DialFunc) (*WebhookAuthorizer, error) { + subjectAccessReview, err := subjectAccessReviewInterfaceFromKubeconfig(kubeConfigFile, version, customDial) if err != nil { return nil, err } @@ -245,7 +246,7 @@ func convertToSARExtra(extra map[string][]string) map[string]authorizationv1.Ext // subjectAccessReviewInterfaceFromKubeconfig builds a client from the specified kubeconfig file, // and returns a SubjectAccessReviewInterface that uses that client. Note that the client submits SubjectAccessReview // requests to the exact path specified in the kubeconfig file, so arbitrary non-API servers can be targeted. -func subjectAccessReviewInterfaceFromKubeconfig(kubeConfigFile string, version string) (subjectAccessReviewer, error) { +func subjectAccessReviewInterfaceFromKubeconfig(kubeConfigFile string, version string, customDial utilnet.DialFunc) (subjectAccessReviewer, error) { localScheme := runtime.NewScheme() if err := scheme.AddToScheme(localScheme); err != nil { return nil, err @@ -257,7 +258,7 @@ func subjectAccessReviewInterfaceFromKubeconfig(kubeConfigFile string, version s if err := localScheme.SetVersionPriority(groupVersions...); err != nil { return nil, err } - gw, err := webhook.NewGenericWebhook(localScheme, scheme.Codecs, kubeConfigFile, groupVersions, 0, nil) + gw, err := webhook.NewGenericWebhook(localScheme, scheme.Codecs, kubeConfigFile, groupVersions, 0, customDial) if err != nil { return nil, err } @@ -268,7 +269,7 @@ func subjectAccessReviewInterfaceFromKubeconfig(kubeConfigFile string, version s if err := localScheme.SetVersionPriority(groupVersions...); err != nil { return nil, err } - gw, err := webhook.NewGenericWebhook(localScheme, scheme.Codecs, kubeConfigFile, groupVersions, 0, nil) + gw, err := webhook.NewGenericWebhook(localScheme, scheme.Codecs, kubeConfigFile, groupVersions, 0, customDial) if err != nil { return nil, err } diff --git a/staging/src/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook_v1_test.go b/staging/src/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook_v1_test.go index 4fb870d24a6..f1ccc84d7b2 100644 --- a/staging/src/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook_v1_test.go +++ b/staging/src/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook_v1_test.go @@ -186,7 +186,7 @@ current-context: default return fmt.Errorf("failed to execute test template: %v", err) } // Create a new authorizer - sarClient, err := subjectAccessReviewInterfaceFromKubeconfig(p, "v1") + sarClient, err := subjectAccessReviewInterfaceFromKubeconfig(p, "v1", nil) if err != nil { return fmt.Errorf("error building sar client: %v", err) } @@ -325,7 +325,7 @@ func newV1Authorizer(callbackURL string, clientCert, clientKey, ca []byte, cache if err := json.NewEncoder(tempfile).Encode(config); err != nil { return nil, err } - sarClient, err := subjectAccessReviewInterfaceFromKubeconfig(p, "v1") + sarClient, err := subjectAccessReviewInterfaceFromKubeconfig(p, "v1", nil) if err != nil { return nil, fmt.Errorf("error building sar client: %v", err) } diff --git a/staging/src/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook_v1beta1_test.go b/staging/src/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook_v1beta1_test.go index 53841f743a5..7d664883d75 100644 --- a/staging/src/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook_v1beta1_test.go +++ b/staging/src/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook_v1beta1_test.go @@ -186,7 +186,7 @@ current-context: default return fmt.Errorf("failed to execute test template: %v", err) } // Create a new authorizer - sarClient, err := subjectAccessReviewInterfaceFromKubeconfig(p, "v1beta1") + sarClient, err := subjectAccessReviewInterfaceFromKubeconfig(p, "v1beta1", nil) if err != nil { return fmt.Errorf("error building sar client: %v", err) } @@ -325,7 +325,7 @@ func newV1beta1Authorizer(callbackURL string, clientCert, clientKey, ca []byte, if err := json.NewEncoder(tempfile).Encode(config); err != nil { return nil, err } - sarClient, err := subjectAccessReviewInterfaceFromKubeconfig(p, "v1beta1") + sarClient, err := subjectAccessReviewInterfaceFromKubeconfig(p, "v1beta1", nil) if err != nil { return nil, fmt.Errorf("error building sar client: %v", err) } diff --git a/test/integration/auth/BUILD b/test/integration/auth/BUILD index 70a0c7010f3..b741619dcca 100644 --- a/test/integration/auth/BUILD +++ b/test/integration/auth/BUILD @@ -59,6 +59,7 @@ go_test( "//staging/src/k8s.io/apimachinery/pkg/labels:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/util/net:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/wait:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authentication/authenticator:go_default_library", diff --git a/test/integration/auth/auth_test.go b/test/integration/auth/auth_test.go index 49418001e29..421eef801c6 100644 --- a/test/integration/auth/auth_test.go +++ b/test/integration/auth/auth_test.go @@ -37,6 +37,7 @@ import ( authenticationv1beta1 "k8s.io/api/authentication/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + utilnet "k8s.io/apimachinery/pkg/util/net" "k8s.io/apiserver/pkg/authentication/authenticator" "k8s.io/apiserver/pkg/authentication/group" "k8s.io/apiserver/pkg/authentication/request/bearertoken" @@ -69,7 +70,7 @@ func getTestTokenAuth() authenticator.Request { return group.NewGroupAdder(bearertoken.New(tokenAuthenticator), []string{user.AllAuthenticated}) } -func getTestWebhookTokenAuth(serverURL string) (authenticator.Request, error) { +func getTestWebhookTokenAuth(serverURL string, customDial utilnet.DialFunc) (authenticator.Request, error) { kubecfgFile, err := ioutil.TempFile("", "webhook-kubecfg") if err != nil { return nil, err @@ -85,13 +86,19 @@ func getTestWebhookTokenAuth(serverURL string) (authenticator.Request, error) { if err := json.NewEncoder(kubecfgFile).Encode(config); err != nil { return nil, err } - webhookTokenAuth, err := webhook.New(kubecfgFile.Name(), "v1beta1", nil, nil) + webhookTokenAuth, err := webhook.New(kubecfgFile.Name(), "v1beta1", nil, customDial) if err != nil { return nil, err } return bearertoken.New(cache.New(webhookTokenAuth, false, 2*time.Minute, 2*time.Minute)), nil } +func getTestWebhookTokenAuthCustomDialer(serverURL string) (authenticator.Request, error) { + customDial := http.DefaultTransport.(*http.Transport).DialContext + + return getTestWebhookTokenAuth(serverURL, customDial) +} + func path(resource, namespace, name string) string { return pathWithPrefix("", resource, namespace, name) } @@ -1192,9 +1199,27 @@ func TestReadOnlyAuthorization(t *testing.T) { // authenticator to call out to a remote web server for authentication // decisions. func TestWebhookTokenAuthenticator(t *testing.T) { + testWebhookTokenAuthenticator(false, t) +} + +// TestWebhookTokenAuthenticatorCustomDial is the same as TestWebhookTokenAuthenticator, but uses a +// custom dialer +func TestWebhookTokenAuthenticatorCustomDial(t *testing.T) { + testWebhookTokenAuthenticator(true, t) +} + +func testWebhookTokenAuthenticator(customDialer bool, t *testing.T) { authServer := newTestWebhookTokenAuthServer() defer authServer.Close() - authenticator, err := getTestWebhookTokenAuth(authServer.URL) + var authenticator authenticator.Request + var err error + + if customDialer == false { + authenticator, err = getTestWebhookTokenAuth(authServer.URL, nil) + } else { + authenticator, err = getTestWebhookTokenAuthCustomDialer(authServer.URL) + } + if err != nil { t.Fatalf("error starting webhook token authenticator server: %v", err) }