@@ -19,7 +19,9 @@ package webhook
19
19
import (
20
20
"fmt"
21
21
"io/ioutil"
22
+ "net"
22
23
"net/http"
24
+ "strconv"
23
25
"strings"
24
26
"time"
25
27
@@ -40,17 +42,17 @@ func NewDefaultAuthenticationInfoResolverWrapper(
40
42
41
43
webhookAuthResolverWrapper := func (delegate AuthenticationInfoResolver ) AuthenticationInfoResolver {
42
44
return & AuthenticationInfoResolverDelegator {
43
- ClientConfigForFunc : func (server string ) (* rest.Config , error ) {
44
- if server == "kubernetes.default.svc" {
45
+ ClientConfigForFunc : func (hostPort string ) (* rest.Config , error ) {
46
+ if hostPort == "kubernetes.default.svc:443 " {
45
47
return kubeapiserverClientConfig , nil
46
48
}
47
- return delegate .ClientConfigFor (server )
49
+ return delegate .ClientConfigFor (hostPort )
48
50
},
49
- ClientConfigForServiceFunc : func (serviceName , serviceNamespace string ) (* rest.Config , error ) {
50
- if serviceName == "kubernetes" && serviceNamespace == corev1 .NamespaceDefault {
51
+ ClientConfigForServiceFunc : func (serviceName , serviceNamespace string , servicePort int ) (* rest.Config , error ) {
52
+ if serviceName == "kubernetes" && serviceNamespace == corev1 .NamespaceDefault && servicePort == 443 {
51
53
return kubeapiserverClientConfig , nil
52
54
}
53
- ret , err := delegate .ClientConfigForService (serviceName , serviceNamespace )
55
+ ret , err := delegate .ClientConfigForService (serviceName , serviceNamespace , servicePort )
54
56
if err != nil {
55
57
return nil , err
56
58
}
@@ -67,27 +69,27 @@ func NewDefaultAuthenticationInfoResolverWrapper(
67
69
// AuthenticationInfoResolver builds rest.Config base on the server or service
68
70
// name and service namespace.
69
71
type AuthenticationInfoResolver interface {
70
- // ClientConfigFor builds rest.Config based on the server .
71
- ClientConfigFor (server string ) (* rest.Config , error )
72
+ // ClientConfigFor builds rest.Config based on the hostPort .
73
+ ClientConfigFor (hostPort string ) (* rest.Config , error )
72
74
// ClientConfigForService builds rest.Config based on the serviceName and
73
75
// serviceNamespace.
74
- ClientConfigForService (serviceName , serviceNamespace string ) (* rest.Config , error )
76
+ ClientConfigForService (serviceName , serviceNamespace string , servicePort int ) (* rest.Config , error )
75
77
}
76
78
77
79
// AuthenticationInfoResolverDelegator implements AuthenticationInfoResolver.
78
80
type AuthenticationInfoResolverDelegator struct {
79
- ClientConfigForFunc func (server string ) (* rest.Config , error )
80
- ClientConfigForServiceFunc func (serviceName , serviceNamespace string ) (* rest.Config , error )
81
+ ClientConfigForFunc func (hostPort string ) (* rest.Config , error )
82
+ ClientConfigForServiceFunc func (serviceName , serviceNamespace string , servicePort int ) (* rest.Config , error )
81
83
}
82
84
83
- // ClientConfigFor returns client config for given server .
84
- func (a * AuthenticationInfoResolverDelegator ) ClientConfigFor (server string ) (* rest.Config , error ) {
85
- return a .ClientConfigForFunc (server )
85
+ // ClientConfigFor returns client config for given hostPort .
86
+ func (a * AuthenticationInfoResolverDelegator ) ClientConfigFor (hostPort string ) (* rest.Config , error ) {
87
+ return a .ClientConfigForFunc (hostPort )
86
88
}
87
89
88
90
// ClientConfigForService returns client config for given service.
89
- func (a * AuthenticationInfoResolverDelegator ) ClientConfigForService (serviceName , serviceNamespace string ) (* rest.Config , error ) {
90
- return a .ClientConfigForServiceFunc (serviceName , serviceNamespace )
91
+ func (a * AuthenticationInfoResolverDelegator ) ClientConfigForService (serviceName , serviceNamespace string , servicePort int ) (* rest.Config , error ) {
92
+ return a .ClientConfigForServiceFunc (serviceName , serviceNamespace , servicePort )
91
93
}
92
94
93
95
type defaultAuthenticationInfoResolver struct {
@@ -113,12 +115,12 @@ func NewDefaultAuthenticationInfoResolver(kubeconfigFile string) (Authentication
113
115
return & defaultAuthenticationInfoResolver {kubeconfig : clientConfig }, nil
114
116
}
115
117
116
- func (c * defaultAuthenticationInfoResolver ) ClientConfigFor (server string ) (* rest.Config , error ) {
117
- return c .clientConfig (server )
118
+ func (c * defaultAuthenticationInfoResolver ) ClientConfigFor (hostPort string ) (* rest.Config , error ) {
119
+ return c .clientConfig (hostPort )
118
120
}
119
121
120
- func (c * defaultAuthenticationInfoResolver ) ClientConfigForService (serviceName , serviceNamespace string ) (* rest.Config , error ) {
121
- return c .clientConfig (serviceName + "." + serviceNamespace + ".svc" )
122
+ func (c * defaultAuthenticationInfoResolver ) ClientConfigForService (serviceName , serviceNamespace string , servicePort int ) (* rest.Config , error ) {
123
+ return c .clientConfig (net . JoinHostPort ( serviceName + "." + serviceNamespace + ".svc" , strconv . Itoa ( servicePort )) )
122
124
}
123
125
124
126
func (c * defaultAuthenticationInfoResolver ) clientConfig (target string ) (* rest.Config , error ) {
@@ -136,8 +138,25 @@ func (c *defaultAuthenticationInfoResolver) clientConfig(target string) (*rest.C
136
138
}
137
139
}
138
140
141
+ // If target included the default https port (443), search again without the port
142
+ if target , port , err := net .SplitHostPort (target ); err == nil && port == "443" {
143
+ // exact match without port
144
+ if authConfig , ok := c .kubeconfig .AuthInfos [target ]; ok {
145
+ return restConfigFromKubeconfig (authConfig )
146
+ }
147
+
148
+ // star prefixed match without port
149
+ serverSteps := strings .Split (target , "." )
150
+ for i := 1 ; i < len (serverSteps ); i ++ {
151
+ nickName := "*." + strings .Join (serverSteps [i :], "." )
152
+ if authConfig , ok := c .kubeconfig .AuthInfos [nickName ]; ok {
153
+ return restConfigFromKubeconfig (authConfig )
154
+ }
155
+ }
156
+ }
157
+
139
158
// if we're trying to hit the kube-apiserver and there wasn't an explicit config, use the in-cluster config
140
- if target == "kubernetes.default.svc" {
159
+ if target == "kubernetes.default.svc:443 " {
141
160
// if we can find an in-cluster-config use that. If we can't, fall through.
142
161
inClusterConfig , err := rest .InClusterConfig ()
143
162
if err == nil {
0 commit comments