Use SSH tunnel for webhook communication iff the webhook is deployed as a service
This commit is contained in:
		@@ -460,15 +460,17 @@ func BuildGenericConfig(s *options.ServerRunOptions, proxyTransport *http.Transp
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	webhookAuthResolver := func(delegate webhookconfig.AuthenticationInfoResolver) webhookconfig.AuthenticationInfoResolver {
 | 
						webhookAuthResolver := func(delegate webhookconfig.AuthenticationInfoResolver) webhookconfig.AuthenticationInfoResolver {
 | 
				
			||||||
		return webhookconfig.AuthenticationInfoResolverFunc(func(server string) (*rest.Config, error) {
 | 
							return webhookconfig.AuthenticationInfoResolverFunc(func(server string, directRouting bool) (*rest.Config, error) {
 | 
				
			||||||
			if server == "kubernetes.default.svc" {
 | 
								if server == "kubernetes.default.svc" {
 | 
				
			||||||
				return genericConfig.LoopbackClientConfig, nil
 | 
									return genericConfig.LoopbackClientConfig, nil
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			ret, err := delegate.ClientConfigFor(server)
 | 
								ret, err := delegate.ClientConfigFor(server, directRouting)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				return nil, err
 | 
									return nil, err
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if proxyTransport != nil && proxyTransport.Dial != nil {
 | 
								if !directRouting && proxyTransport != nil && proxyTransport.Dial != nil {
 | 
				
			||||||
 | 
									// Use the SSH tunnels iff the webhook server is not directly
 | 
				
			||||||
 | 
									// routable from apiserver's network environment.
 | 
				
			||||||
				ret.Dial = proxyTransport.Dial
 | 
									ret.Dial = proxyTransport.Dial
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			return ret, err
 | 
								return ret, err
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,17 +31,22 @@ import (
 | 
				
			|||||||
// rest.Config generated by the resolver.
 | 
					// rest.Config generated by the resolver.
 | 
				
			||||||
type AuthenticationInfoResolverWrapper func(AuthenticationInfoResolver) AuthenticationInfoResolver
 | 
					type AuthenticationInfoResolverWrapper func(AuthenticationInfoResolver) AuthenticationInfoResolver
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// AuthenticationInfoResolver builds rest.Config base on the server name.
 | 
					// AuthenticationInfoResolver builds rest.Config base on the server name and
 | 
				
			||||||
 | 
					// the directRouting flag indicating whether the webhook server is routable
 | 
				
			||||||
 | 
					// directly from apiserver's network environment.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// TODO(yguo0905): Remove the directRouting flag once the SSH tunnels that is
 | 
				
			||||||
 | 
					// used for the communication from master to nodes get removed.
 | 
				
			||||||
type AuthenticationInfoResolver interface {
 | 
					type AuthenticationInfoResolver interface {
 | 
				
			||||||
	ClientConfigFor(server string) (*rest.Config, error)
 | 
						ClientConfigFor(server string, directRouting bool) (*rest.Config, error)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// AuthenticationInfoResolverFunc implements AuthenticationInfoResolver.
 | 
					// AuthenticationInfoResolverFunc implements AuthenticationInfoResolver.
 | 
				
			||||||
type AuthenticationInfoResolverFunc func(server string) (*rest.Config, error)
 | 
					type AuthenticationInfoResolverFunc func(server string, directRouting bool) (*rest.Config, error)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//ClientConfigFor implements AuthenticationInfoResolver.
 | 
					//ClientConfigFor implements AuthenticationInfoResolver.
 | 
				
			||||||
func (a AuthenticationInfoResolverFunc) ClientConfigFor(server string) (*rest.Config, error) {
 | 
					func (a AuthenticationInfoResolverFunc) ClientConfigFor(server string, directRouting bool) (*rest.Config, error) {
 | 
				
			||||||
	return a(server)
 | 
						return a(server, directRouting)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type defaultAuthenticationInfoResolver struct {
 | 
					type defaultAuthenticationInfoResolver struct {
 | 
				
			||||||
@@ -67,7 +72,7 @@ func NewDefaultAuthenticationInfoResolver(kubeconfigFile string) (Authentication
 | 
				
			|||||||
	return &defaultAuthenticationInfoResolver{kubeconfig: clientConfig}, nil
 | 
						return &defaultAuthenticationInfoResolver{kubeconfig: clientConfig}, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (c *defaultAuthenticationInfoResolver) ClientConfigFor(server string) (*rest.Config, error) {
 | 
					func (c *defaultAuthenticationInfoResolver) ClientConfigFor(server string, directRouting bool) (*rest.Config, error) {
 | 
				
			||||||
	// exact match
 | 
						// exact match
 | 
				
			||||||
	if authConfig, ok := c.kubeconfig.AuthInfos[server]; ok {
 | 
						if authConfig, ok := c.kubeconfig.AuthInfos[server]; ok {
 | 
				
			||||||
		return restConfigFromKubeconfig(authConfig)
 | 
							return restConfigFromKubeconfig(authConfig)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -114,7 +114,7 @@ func TestAuthenticationDetection(t *testing.T) {
 | 
				
			|||||||
	for _, tc := range tests {
 | 
						for _, tc := range tests {
 | 
				
			||||||
		t.Run(tc.name, func(t *testing.T) {
 | 
							t.Run(tc.name, func(t *testing.T) {
 | 
				
			||||||
			resolver := defaultAuthenticationInfoResolver{kubeconfig: tc.kubeconfig}
 | 
								resolver := defaultAuthenticationInfoResolver{kubeconfig: tc.kubeconfig}
 | 
				
			||||||
			actual, err := resolver.ClientConfigFor(tc.serverName)
 | 
								actual, err := resolver.ClientConfigFor(tc.serverName, false)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				t.Fatal(err)
 | 
									t.Fatal(err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -123,7 +123,7 @@ func (cm *ClientManager) HookClient(h *v1beta1.Webhook) (*rest.RESTClient, error
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	if svc := h.ClientConfig.Service; svc != nil {
 | 
						if svc := h.ClientConfig.Service; svc != nil {
 | 
				
			||||||
		serverName := svc.Name + "." + svc.Namespace + ".svc"
 | 
							serverName := svc.Name + "." + svc.Namespace + ".svc"
 | 
				
			||||||
		restConfig, err := cm.authInfoResolver.ClientConfigFor(serverName)
 | 
							restConfig, err := cm.authInfoResolver.ClientConfigFor(serverName, false)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return nil, err
 | 
								return nil, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -162,7 +162,7 @@ func (cm *ClientManager) HookClient(h *v1beta1.Webhook) (*rest.RESTClient, error
 | 
				
			|||||||
		return nil, &webhookerrors.ErrCallingWebhook{WebhookName: h.Name, Reason: fmt.Errorf("Unparsable URL: %v", err)}
 | 
							return nil, &webhookerrors.ErrCallingWebhook{WebhookName: h.Name, Reason: fmt.Errorf("Unparsable URL: %v", err)}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	restConfig, err := cm.authInfoResolver.ClientConfigFor(u.Host)
 | 
						restConfig, err := cm.authInfoResolver.ClientConfigFor(u.Host, true)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -631,7 +631,7 @@ type fakeAuthenticationInfoResolver struct {
 | 
				
			|||||||
	cachedCount *int32
 | 
						cachedCount *int32
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (c *fakeAuthenticationInfoResolver) ClientConfigFor(server string) (*rest.Config, error) {
 | 
					func (c *fakeAuthenticationInfoResolver) ClientConfigFor(server string, directRouting bool) (*rest.Config, error) {
 | 
				
			||||||
	atomic.AddInt32(c.cachedCount, 1)
 | 
						atomic.AddInt32(c.cachedCount, 1)
 | 
				
			||||||
	return c.restConfig, nil
 | 
						return c.restConfig, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -656,7 +656,7 @@ type fakeAuthenticationInfoResolver struct {
 | 
				
			|||||||
	cachedCount *int32
 | 
						cachedCount *int32
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (c *fakeAuthenticationInfoResolver) ClientConfigFor(server string) (*rest.Config, error) {
 | 
					func (c *fakeAuthenticationInfoResolver) ClientConfigFor(server string, directRouting bool) (*rest.Config, error) {
 | 
				
			||||||
	atomic.AddInt32(c.cachedCount, 1)
 | 
						atomic.AddInt32(c.cachedCount, 1)
 | 
				
			||||||
	return c.restConfig, nil
 | 
						return c.restConfig, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user