mirror of https://github.com/k3s-io/k3s
Split ClientConfigFor()
parent
454276c23c
commit
05fbc22064
|
@ -459,29 +459,35 @@ func BuildGenericConfig(s *options.ServerRunOptions, proxyTransport *http.Transp
|
||||||
genericConfig.DisabledPostStartHooks.Insert(rbacrest.PostStartHookName)
|
genericConfig.DisabledPostStartHooks.Insert(rbacrest.PostStartHookName)
|
||||||
}
|
}
|
||||||
|
|
||||||
webhookAuthResolver := func(delegate webhookconfig.AuthenticationInfoResolver) webhookconfig.AuthenticationInfoResolver {
|
webhookAuthResolverWrapper := func(delegate webhookconfig.AuthenticationInfoResolver) webhookconfig.AuthenticationInfoResolver {
|
||||||
return webhookconfig.AuthenticationInfoResolverFunc(func(server string, directRouting bool) (*rest.Config, error) {
|
return &webhookconfig.AuthenticationInfoResolverDelegator{
|
||||||
if server == "kubernetes.default.svc" {
|
ClientConfigForFunc: func(server string) (*rest.Config, error) {
|
||||||
return genericConfig.LoopbackClientConfig, nil
|
if server == "kubernetes.default.svc" {
|
||||||
}
|
return genericConfig.LoopbackClientConfig, nil
|
||||||
ret, err := delegate.ClientConfigFor(server, directRouting)
|
}
|
||||||
if err != nil {
|
return delegate.ClientConfigFor(server)
|
||||||
return nil, err
|
},
|
||||||
}
|
ClientConfigForServiceFunc: func(serviceName, serviceNamespace string) (*rest.Config, error) {
|
||||||
if !directRouting && proxyTransport != nil && proxyTransport.Dial != nil {
|
if serviceName == "kubernetes" && serviceNamespace == "default" {
|
||||||
// Use the SSH tunnels iff the webhook server is not directly
|
return genericConfig.LoopbackClientConfig, nil
|
||||||
// routable from apiserver's network environment.
|
}
|
||||||
ret.Dial = proxyTransport.Dial
|
ret, err := delegate.ClientConfigForService(serviceName, serviceNamespace)
|
||||||
}
|
if err != nil {
|
||||||
return ret, err
|
return nil, err
|
||||||
})
|
}
|
||||||
|
if proxyTransport != nil && proxyTransport.Dial != nil {
|
||||||
|
ret.Dial = proxyTransport.Dial
|
||||||
|
}
|
||||||
|
return ret, err
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pluginInitializers, err := BuildAdmissionPluginInitializers(
|
pluginInitializers, err := BuildAdmissionPluginInitializers(
|
||||||
s,
|
s,
|
||||||
client,
|
client,
|
||||||
sharedInformers,
|
sharedInformers,
|
||||||
serviceResolver,
|
serviceResolver,
|
||||||
webhookAuthResolver,
|
webhookAuthResolverWrapper,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, nil, nil, fmt.Errorf("failed to create admission plugin initializer: %v", err)
|
return nil, nil, nil, nil, nil, fmt.Errorf("failed to create admission plugin initializer: %v", err)
|
||||||
|
|
|
@ -31,22 +31,28 @@ 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 and
|
// AuthenticationInfoResolver builds rest.Config base on the server or service
|
||||||
// the directRouting flag indicating whether the webhook server is routable
|
// name and service namespace.
|
||||||
// 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, directRouting bool) (*rest.Config, error)
|
// ClientConfigFor builds rest.Config based on the server.
|
||||||
|
ClientConfigFor(server string) (*rest.Config, error)
|
||||||
|
// ClientConfigForService builds rest.Config based on the serviceName and
|
||||||
|
// serviceNamespace.
|
||||||
|
ClientConfigForService(serviceName, serviceNamespace string) (*rest.Config, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// AuthenticationInfoResolverFunc implements AuthenticationInfoResolver.
|
// AuthenticationInfoResolverDelegator implements AuthenticationInfoResolver.
|
||||||
type AuthenticationInfoResolverFunc func(server string, directRouting bool) (*rest.Config, error)
|
type AuthenticationInfoResolverDelegator struct {
|
||||||
|
ClientConfigForFunc func(server string) (*rest.Config, error)
|
||||||
|
ClientConfigForServiceFunc func(serviceName, serviceNamespace string) (*rest.Config, error)
|
||||||
|
}
|
||||||
|
|
||||||
//ClientConfigFor implements AuthenticationInfoResolver.
|
func (a *AuthenticationInfoResolverDelegator) ClientConfigFor(server string) (*rest.Config, error) {
|
||||||
func (a AuthenticationInfoResolverFunc) ClientConfigFor(server string, directRouting bool) (*rest.Config, error) {
|
return a.ClientConfigForFunc(server)
|
||||||
return a(server, directRouting)
|
}
|
||||||
|
|
||||||
|
func (a *AuthenticationInfoResolverDelegator) ClientConfigForService(serviceName, serviceNamespace string) (*rest.Config, error) {
|
||||||
|
return a.ClientConfigForServiceFunc(serviceName, serviceNamespace)
|
||||||
}
|
}
|
||||||
|
|
||||||
type defaultAuthenticationInfoResolver struct {
|
type defaultAuthenticationInfoResolver struct {
|
||||||
|
@ -72,14 +78,22 @@ func NewDefaultAuthenticationInfoResolver(kubeconfigFile string) (Authentication
|
||||||
return &defaultAuthenticationInfoResolver{kubeconfig: clientConfig}, nil
|
return &defaultAuthenticationInfoResolver{kubeconfig: clientConfig}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *defaultAuthenticationInfoResolver) ClientConfigFor(server string, directRouting bool) (*rest.Config, error) {
|
func (c *defaultAuthenticationInfoResolver) ClientConfigFor(server string) (*rest.Config, error) {
|
||||||
|
return c.clientConfig(server)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *defaultAuthenticationInfoResolver) ClientConfigForService(serviceName, serviceNamespace string) (*rest.Config, error) {
|
||||||
|
return c.clientConfig(serviceName + "." + serviceNamespace + ".svc")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *defaultAuthenticationInfoResolver) clientConfig(target string) (*rest.Config, error) {
|
||||||
// exact match
|
// exact match
|
||||||
if authConfig, ok := c.kubeconfig.AuthInfos[server]; ok {
|
if authConfig, ok := c.kubeconfig.AuthInfos[target]; ok {
|
||||||
return restConfigFromKubeconfig(authConfig)
|
return restConfigFromKubeconfig(authConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
// star prefixed match
|
// star prefixed match
|
||||||
serverSteps := strings.Split(server, ".")
|
serverSteps := strings.Split(target, ".")
|
||||||
for i := 1; i < len(serverSteps); i++ {
|
for i := 1; i < len(serverSteps); i++ {
|
||||||
nickName := "*." + strings.Join(serverSteps[i:], ".")
|
nickName := "*." + strings.Join(serverSteps[i:], ".")
|
||||||
if authConfig, ok := c.kubeconfig.AuthInfos[nickName]; ok {
|
if authConfig, ok := c.kubeconfig.AuthInfos[nickName]; ok {
|
||||||
|
@ -88,7 +102,7 @@ func (c *defaultAuthenticationInfoResolver) ClientConfigFor(server string, direc
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we're trying to hit the kube-apiserver and there wasn't an explicit config, use the in-cluster config
|
// if we're trying to hit the kube-apiserver and there wasn't an explicit config, use the in-cluster config
|
||||||
if server == "kubernetes.default.svc" {
|
if target == "kubernetes.default.svc" {
|
||||||
// if we can find an in-cluster-config use that. If we can't, fall through.
|
// if we can find an in-cluster-config use that. If we can't, fall through.
|
||||||
inClusterConfig, err := rest.InClusterConfig()
|
inClusterConfig, err := rest.InClusterConfig()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|
|
@ -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, false)
|
actual, err := resolver.ClientConfigFor(tc.serverName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,12 +122,12 @@ 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"
|
restConfig, err := cm.authInfoResolver.ClientConfigForService(svc.Name, svc.Namespace)
|
||||||
restConfig, err := cm.authInfoResolver.ClientConfigFor(serverName, false)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
cfg := rest.CopyConfig(restConfig)
|
cfg := rest.CopyConfig(restConfig)
|
||||||
|
serverName := svc.Name + "." + svc.Namespace + ".svc"
|
||||||
host := serverName + ":443"
|
host := serverName + ":443"
|
||||||
cfg.Host = "https://" + host
|
cfg.Host = "https://" + host
|
||||||
if svc.Path != nil {
|
if svc.Path != nil {
|
||||||
|
@ -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, true)
|
restConfig, err := cm.authInfoResolver.ClientConfigFor(u.Host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -631,7 +631,12 @@ type fakeAuthenticationInfoResolver struct {
|
||||||
cachedCount *int32
|
cachedCount *int32
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *fakeAuthenticationInfoResolver) ClientConfigFor(server string, directRouting bool) (*rest.Config, error) {
|
func (c *fakeAuthenticationInfoResolver) ClientConfigFor(server string) (*rest.Config, error) {
|
||||||
|
atomic.AddInt32(c.cachedCount, 1)
|
||||||
|
return c.restConfig, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *fakeAuthenticationInfoResolver) ClientConfigForService(serviceName, serviceNamespace string) (*rest.Config, error) {
|
||||||
atomic.AddInt32(c.cachedCount, 1)
|
atomic.AddInt32(c.cachedCount, 1)
|
||||||
return c.restConfig, nil
|
return c.restConfig, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -656,7 +656,12 @@ type fakeAuthenticationInfoResolver struct {
|
||||||
cachedCount *int32
|
cachedCount *int32
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *fakeAuthenticationInfoResolver) ClientConfigFor(server string, directRouting bool) (*rest.Config, error) {
|
func (c *fakeAuthenticationInfoResolver) ClientConfigFor(server string) (*rest.Config, error) {
|
||||||
|
atomic.AddInt32(c.cachedCount, 1)
|
||||||
|
return c.restConfig, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *fakeAuthenticationInfoResolver) ClientConfigForService(serviceName, serviceNamespace string) (*rest.Config, error) {
|
||||||
atomic.AddInt32(c.cachedCount, 1)
|
atomic.AddInt32(c.cachedCount, 1)
|
||||||
return c.restConfig, nil
|
return c.restConfig, nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue