k8s.io/apiserver@v0.31.1/pkg/util/webhook/authentication_test.go (about)

     1  /*
     2  Copyright 2017 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package webhook
    18  
    19  import (
    20  	"testing"
    21  
    22  	"github.com/google/go-cmp/cmp"
    23  	"k8s.io/apimachinery/pkg/api/equality"
    24  	"k8s.io/client-go/rest"
    25  	clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
    26  )
    27  
    28  func TestAuthenticationDetection(t *testing.T) {
    29  	tests := []struct {
    30  		name       string
    31  		kubeconfig clientcmdapi.Config
    32  		serverName string
    33  		expected   rest.Config
    34  	}{
    35  		{
    36  			name:       "empty",
    37  			serverName: "foo.com",
    38  		},
    39  		{
    40  			name:       "fallback to current context",
    41  			serverName: "foo.com",
    42  			kubeconfig: clientcmdapi.Config{
    43  				AuthInfos: map[string]*clientcmdapi.AuthInfo{
    44  					"bar.com": {Token: "bar"},
    45  				},
    46  				Contexts: map[string]*clientcmdapi.Context{
    47  					"ctx": {
    48  						AuthInfo: "bar.com",
    49  					},
    50  				},
    51  				CurrentContext: "ctx",
    52  			},
    53  			expected: rest.Config{BearerToken: "bar"},
    54  		},
    55  		{
    56  			name:       "exact match",
    57  			serverName: "foo.com",
    58  			kubeconfig: clientcmdapi.Config{
    59  				AuthInfos: map[string]*clientcmdapi.AuthInfo{
    60  					"foo.com": {Token: "foo"},
    61  					"*.com":   {Token: "foo-star"},
    62  					"bar.com": {Token: "bar"},
    63  				},
    64  			},
    65  			expected: rest.Config{BearerToken: "foo"},
    66  		},
    67  		{
    68  			name:       "match with impersonation",
    69  			serverName: "foo.com",
    70  			kubeconfig: clientcmdapi.Config{
    71  				AuthInfos: map[string]*clientcmdapi.AuthInfo{
    72  					"foo.com": {
    73  						Token:                "foo",
    74  						Impersonate:          "user-a",
    75  						ImpersonateUID:       "user-a-uid-1111",
    76  						ImpersonateGroups:    []string{"user-a-group1", "user-a-group2"},
    77  						ImpersonateUserExtra: map[string][]string{"foo": {"bar", "baz", "etc"}},
    78  					},
    79  				},
    80  			},
    81  			expected: rest.Config{
    82  				BearerToken: "foo",
    83  				Impersonate: rest.ImpersonationConfig{
    84  					UserName: "user-a",
    85  					UID:      "user-a-uid-1111",
    86  					Groups:   []string{"user-a-group1", "user-a-group2"},
    87  					Extra:    map[string][]string{"foo": {"bar", "baz", "etc"}},
    88  				},
    89  			},
    90  		},
    91  		{
    92  			name:       "partial star match",
    93  			serverName: "foo.com",
    94  			kubeconfig: clientcmdapi.Config{
    95  				AuthInfos: map[string]*clientcmdapi.AuthInfo{
    96  					"*.com":   {Token: "foo-star"},
    97  					"bar.com": {Token: "bar"},
    98  				},
    99  			},
   100  			expected: rest.Config{BearerToken: "foo-star"},
   101  		},
   102  		{
   103  			name:       "full star match",
   104  			serverName: "foo.com",
   105  			kubeconfig: clientcmdapi.Config{
   106  				AuthInfos: map[string]*clientcmdapi.AuthInfo{
   107  					"*":       {Token: "star"},
   108  					"bar.com": {Token: "bar"},
   109  				},
   110  			},
   111  			expected: rest.Config{BearerToken: "star"},
   112  		},
   113  		{
   114  			name:       "skip bad in cluster config",
   115  			serverName: "kubernetes.default.svc",
   116  			kubeconfig: clientcmdapi.Config{
   117  				AuthInfos: map[string]*clientcmdapi.AuthInfo{
   118  					"*":       {Token: "star"},
   119  					"bar.com": {Token: "bar"},
   120  				},
   121  			},
   122  			expected: rest.Config{BearerToken: "star"},
   123  		},
   124  		{
   125  			name:       "most selective",
   126  			serverName: "one.two.three.com",
   127  			kubeconfig: clientcmdapi.Config{
   128  				AuthInfos: map[string]*clientcmdapi.AuthInfo{
   129  					"*.two.three.com": {Token: "first"},
   130  					"*.three.com":     {Token: "second"},
   131  					"*.com":           {Token: "third"},
   132  				},
   133  			},
   134  			expected: rest.Config{BearerToken: "first"},
   135  		},
   136  		{
   137  			name:       "exact match with default https port",
   138  			serverName: "one.two.three.com:443",
   139  			kubeconfig: clientcmdapi.Config{
   140  				AuthInfos: map[string]*clientcmdapi.AuthInfo{
   141  					"one.two.three.com:443": {Token: "exact"},
   142  					"*.two.three.com":       {Token: "first"},
   143  					"*.three.com":           {Token: "second"},
   144  					"*.com":                 {Token: "third"},
   145  					"*":                     {Token: "fallback"},
   146  				},
   147  			},
   148  			expected: rest.Config{BearerToken: "exact"},
   149  		},
   150  		{
   151  			name:       "wildcard match with default https port",
   152  			serverName: "one.two.three.com:443",
   153  			kubeconfig: clientcmdapi.Config{
   154  				AuthInfos: map[string]*clientcmdapi.AuthInfo{
   155  					"*.two.three.com:443": {Token: "first-with-port"},
   156  					"*.two.three.com":     {Token: "first"},
   157  					"*.three.com":         {Token: "second"},
   158  					"*.com":               {Token: "third"},
   159  					"*":                   {Token: "fallback"},
   160  				},
   161  			},
   162  			expected: rest.Config{BearerToken: "first-with-port"},
   163  		},
   164  		{
   165  			name:       "wildcard match without default https port",
   166  			serverName: "one.two.three.com:443",
   167  			kubeconfig: clientcmdapi.Config{
   168  				AuthInfos: map[string]*clientcmdapi.AuthInfo{
   169  					"*.two.three.com": {Token: "first"},
   170  					"*.three.com":     {Token: "second"},
   171  					"*.com":           {Token: "third"},
   172  					"*":               {Token: "fallback"},
   173  				},
   174  			},
   175  			expected: rest.Config{BearerToken: "first"},
   176  		},
   177  		{
   178  			name:       "exact match with non-default https port",
   179  			serverName: "one.two.three.com:8443",
   180  			kubeconfig: clientcmdapi.Config{
   181  				AuthInfos: map[string]*clientcmdapi.AuthInfo{
   182  					"one.two.three.com:8443": {Token: "exact"},
   183  					"*.two.three.com":        {Token: "first"},
   184  					"*.three.com":            {Token: "second"},
   185  					"*.com":                  {Token: "third"},
   186  					"*":                      {Token: "fallback"},
   187  				},
   188  			},
   189  			expected: rest.Config{BearerToken: "exact"},
   190  		},
   191  		{
   192  			name:       "wildcard match with non-default https port",
   193  			serverName: "one.two.three.com:8443",
   194  			kubeconfig: clientcmdapi.Config{
   195  				AuthInfos: map[string]*clientcmdapi.AuthInfo{
   196  					"*.two.three.com:8443": {Token: "first-with-port"},
   197  					"one.two.three.com":    {Token: "first-without-port"},
   198  					"*.two.three.com":      {Token: "first"},
   199  					"*.three.com":          {Token: "second"},
   200  					"*.com":                {Token: "third"},
   201  					"*":                    {Token: "fallback"},
   202  				},
   203  			},
   204  			expected: rest.Config{BearerToken: "first-with-port"},
   205  		},
   206  		{
   207  			name:       "wildcard match without non-default https port",
   208  			serverName: "one.two.three.com:8443",
   209  			kubeconfig: clientcmdapi.Config{
   210  				AuthInfos: map[string]*clientcmdapi.AuthInfo{
   211  					"one.two.three.com": {Token: "first-without-port"},
   212  					"*.two.three.com":   {Token: "first"},
   213  					"*.three.com":       {Token: "second"},
   214  					"*.com":             {Token: "third"},
   215  					"*":                 {Token: "fallback"},
   216  				},
   217  			},
   218  			expected: rest.Config{BearerToken: "fallback"},
   219  		},
   220  	}
   221  
   222  	for _, tc := range tests {
   223  		t.Run(tc.name, func(t *testing.T) {
   224  			resolver := defaultAuthenticationInfoResolver{kubeconfig: tc.kubeconfig}
   225  			actual, err := resolver.ClientConfigFor(tc.serverName)
   226  			if err != nil {
   227  				t.Fatal(err)
   228  			}
   229  			actual.UserAgent = ""
   230  			actual.Timeout = 0
   231  
   232  			if !equality.Semantic.DeepEqual(*actual, tc.expected) {
   233  				t.Errorf("%v", cmp.Diff(tc.expected, *actual))
   234  			}
   235  		})
   236  	}
   237  
   238  }