...

Source file src/k8s.io/client-go/tools/clientcmd/merged_client_builder_test.go

Documentation: k8s.io/client-go/tools/clientcmd

     1  /*
     2  Copyright 2014 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 clientcmd
    18  
    19  import (
    20  	"fmt"
    21  	"testing"
    22  
    23  	restclient "k8s.io/client-go/rest"
    24  	clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
    25  )
    26  
    27  type testClientConfig struct {
    28  	rawconfig          *clientcmdapi.Config
    29  	config             *restclient.Config
    30  	namespace          string
    31  	namespaceSpecified bool
    32  	err                error
    33  }
    34  
    35  func (c *testClientConfig) RawConfig() (clientcmdapi.Config, error) {
    36  	if c.rawconfig == nil {
    37  		return clientcmdapi.Config{}, fmt.Errorf("unexpected call")
    38  	}
    39  	return *c.rawconfig, nil
    40  }
    41  func (c *testClientConfig) ClientConfig() (*restclient.Config, error) {
    42  	return c.config, c.err
    43  }
    44  func (c *testClientConfig) Namespace() (string, bool, error) {
    45  	return c.namespace, c.namespaceSpecified, c.err
    46  }
    47  func (c *testClientConfig) ConfigAccess() ConfigAccess {
    48  	return nil
    49  }
    50  
    51  type testICC struct {
    52  	testClientConfig
    53  
    54  	possible bool
    55  	called   bool
    56  }
    57  
    58  func (icc *testICC) Possible() bool {
    59  	icc.called = true
    60  	return icc.possible
    61  }
    62  
    63  func TestInClusterConfig(t *testing.T) {
    64  	default1 := &DirectClientConfig{
    65  		config:      *createValidTestConfig(),
    66  		contextName: "clean",
    67  		overrides:   &ConfigOverrides{},
    68  	}
    69  	invalidDefaultConfig := clientcmdapi.NewConfig()
    70  	invalidDefaultConfig.Clusters["clean"] = &clientcmdapi.Cluster{
    71  		Server: "http://localhost:8080",
    72  	}
    73  	invalidDefaultConfig.Contexts["other"] = &clientcmdapi.Context{
    74  		Cluster: "clean",
    75  	}
    76  	invalidDefaultConfig.CurrentContext = "clean"
    77  
    78  	defaultInvalid := &DirectClientConfig{
    79  		config:    *invalidDefaultConfig,
    80  		overrides: &ConfigOverrides{},
    81  	}
    82  	if _, err := defaultInvalid.ClientConfig(); err == nil || !IsConfigurationInvalid(err) {
    83  		t.Fatal(err)
    84  	}
    85  	config1, err := default1.ClientConfig()
    86  	if err != nil {
    87  		t.Fatal(err)
    88  	}
    89  	config2 := &restclient.Config{Host: "config2"}
    90  	err1 := fmt.Errorf("unique error")
    91  
    92  	testCases := map[string]struct {
    93  		clientConfig  *testClientConfig
    94  		icc           *testICC
    95  		defaultConfig *DirectClientConfig
    96  
    97  		checkedICC bool
    98  		result     *restclient.Config
    99  		err        error
   100  	}{
   101  		"in-cluster checked on other error": {
   102  			clientConfig: &testClientConfig{err: ErrEmptyConfig},
   103  			icc:          &testICC{},
   104  
   105  			checkedICC: true,
   106  			result:     nil,
   107  			err:        ErrEmptyConfig,
   108  		},
   109  
   110  		"in-cluster not checked on non-empty error": {
   111  			clientConfig: &testClientConfig{err: ErrEmptyCluster},
   112  			icc:          &testICC{},
   113  
   114  			checkedICC: false,
   115  			result:     nil,
   116  			err:        ErrEmptyCluster,
   117  		},
   118  
   119  		"in-cluster checked when config is default": {
   120  			defaultConfig: default1,
   121  			clientConfig:  &testClientConfig{config: config1},
   122  			icc:           &testICC{},
   123  
   124  			checkedICC: true,
   125  			result:     config1,
   126  			err:        nil,
   127  		},
   128  
   129  		"in-cluster not checked when default config is invalid": {
   130  			defaultConfig: defaultInvalid,
   131  			clientConfig:  &testClientConfig{config: config1},
   132  			icc:           &testICC{},
   133  
   134  			checkedICC: false,
   135  			result:     config1,
   136  			err:        nil,
   137  		},
   138  
   139  		"in-cluster not checked when config is not equal to default": {
   140  			defaultConfig: default1,
   141  			clientConfig:  &testClientConfig{config: config2},
   142  			icc:           &testICC{},
   143  
   144  			checkedICC: false,
   145  			result:     config2,
   146  			err:        nil,
   147  		},
   148  
   149  		"in-cluster checked when config is not equal to default and error is empty": {
   150  			clientConfig: &testClientConfig{config: config2, err: ErrEmptyConfig},
   151  			icc:          &testICC{},
   152  
   153  			checkedICC: true,
   154  			result:     config2,
   155  			err:        ErrEmptyConfig,
   156  		},
   157  
   158  		"in-cluster error returned when config is empty": {
   159  			clientConfig: &testClientConfig{err: ErrEmptyConfig},
   160  			icc: &testICC{
   161  				possible: true,
   162  				testClientConfig: testClientConfig{
   163  					err: err1,
   164  				},
   165  			},
   166  
   167  			checkedICC: true,
   168  			result:     nil,
   169  			err:        err1,
   170  		},
   171  
   172  		"in-cluster config returned when config is empty": {
   173  			clientConfig: &testClientConfig{err: ErrEmptyConfig},
   174  			icc: &testICC{
   175  				possible: true,
   176  				testClientConfig: testClientConfig{
   177  					config: config2,
   178  				},
   179  			},
   180  
   181  			checkedICC: true,
   182  			result:     config2,
   183  			err:        nil,
   184  		},
   185  
   186  		"in-cluster not checked when standard default is invalid": {
   187  			defaultConfig: &DefaultClientConfig,
   188  			clientConfig:  &testClientConfig{config: config2},
   189  			icc:           &testICC{},
   190  
   191  			checkedICC: false,
   192  			result:     config2,
   193  			err:        nil,
   194  		},
   195  	}
   196  
   197  	for name, test := range testCases {
   198  		c := &DeferredLoadingClientConfig{icc: test.icc}
   199  		c.loader = &ClientConfigLoadingRules{DefaultClientConfig: test.defaultConfig}
   200  		c.clientConfig = test.clientConfig
   201  
   202  		cfg, err := c.ClientConfig()
   203  		if test.icc.called != test.checkedICC {
   204  			t.Errorf("%s: unexpected in-cluster-config call %t", name, test.icc.called)
   205  		}
   206  		if err != test.err || cfg != test.result {
   207  			t.Errorf("%s: unexpected result: %v %#v", name, err, cfg)
   208  		}
   209  	}
   210  }
   211  
   212  func TestInClusterConfigNamespace(t *testing.T) {
   213  	err1 := fmt.Errorf("unique error")
   214  
   215  	testCases := map[string]struct {
   216  		clientConfig *testClientConfig
   217  		icc          *testICC
   218  		overrides    *ConfigOverrides
   219  
   220  		checkedICC bool
   221  		result     string
   222  		overridden bool
   223  		err        error
   224  	}{
   225  		"in-cluster checked on empty error": {
   226  			clientConfig: &testClientConfig{err: ErrEmptyConfig},
   227  			icc:          &testICC{},
   228  
   229  			checkedICC: true,
   230  			err:        ErrEmptyConfig,
   231  		},
   232  
   233  		"in-cluster not checked on non-empty error": {
   234  			clientConfig: &testClientConfig{err: ErrEmptyCluster},
   235  			icc:          &testICC{},
   236  
   237  			err: ErrEmptyCluster,
   238  		},
   239  
   240  		"in-cluster checked when config is default": {
   241  			clientConfig: &testClientConfig{},
   242  			icc:          &testICC{},
   243  
   244  			checkedICC: true,
   245  		},
   246  
   247  		"in-cluster not checked when config is not equal to default": {
   248  			clientConfig: &testClientConfig{namespace: "test", namespaceSpecified: true},
   249  			icc:          &testICC{},
   250  
   251  			result:     "test",
   252  			overridden: true,
   253  		},
   254  
   255  		"in-cluster checked when namespace is not specified, but is defaulted": {
   256  			clientConfig: &testClientConfig{namespace: "test", namespaceSpecified: false},
   257  			icc:          &testICC{},
   258  
   259  			checkedICC: true,
   260  			result:     "test",
   261  			overridden: false,
   262  		},
   263  
   264  		"in-cluster error returned when config is empty": {
   265  			clientConfig: &testClientConfig{err: ErrEmptyConfig},
   266  			icc: &testICC{
   267  				possible: true,
   268  				testClientConfig: testClientConfig{
   269  					err: err1,
   270  				},
   271  			},
   272  
   273  			checkedICC: true,
   274  			err:        err1,
   275  		},
   276  
   277  		"in-cluster config returned when config is empty": {
   278  			clientConfig: &testClientConfig{err: ErrEmptyConfig},
   279  			icc: &testICC{
   280  				possible: true,
   281  				testClientConfig: testClientConfig{
   282  					namespace:          "test",
   283  					namespaceSpecified: true,
   284  				},
   285  			},
   286  
   287  			checkedICC: true,
   288  			result:     "test",
   289  			overridden: true,
   290  		},
   291  
   292  		"in-cluster config returned when config is empty and namespace is defaulted but not explicitly set": {
   293  			clientConfig: &testClientConfig{err: ErrEmptyConfig},
   294  			icc: &testICC{
   295  				possible: true,
   296  				testClientConfig: testClientConfig{
   297  					namespace:          "test",
   298  					namespaceSpecified: false,
   299  				},
   300  			},
   301  
   302  			checkedICC: true,
   303  			result:     "test",
   304  			overridden: false,
   305  		},
   306  
   307  		"overridden context used to verify explicit namespace in config": {
   308  			clientConfig: &testClientConfig{
   309  				namespace:          "default",
   310  				namespaceSpecified: false, // a namespace that comes from a context is not considered overridden
   311  				rawconfig:          &clientcmdapi.Config{Contexts: map[string]*clientcmdapi.Context{"overridden-context": {Namespace: "default"}}},
   312  			},
   313  			overrides: &ConfigOverrides{CurrentContext: "overridden-context"},
   314  			icc: &testICC{
   315  				possible: true,
   316  				testClientConfig: testClientConfig{
   317  					namespace:          "icc",
   318  					namespaceSpecified: false, // a namespace that comes from icc is not considered overridden
   319  				},
   320  			},
   321  			checkedICC: true,
   322  			result:     "default",
   323  			overridden: false, // a namespace that comes from a context is not considered overridden
   324  		},
   325  	}
   326  
   327  	for name, test := range testCases {
   328  		t.Run(name, func(t *testing.T) {
   329  			c := &DeferredLoadingClientConfig{icc: test.icc, overrides: test.overrides}
   330  			c.clientConfig = test.clientConfig
   331  
   332  			ns, overridden, err := c.Namespace()
   333  			if test.icc.called != test.checkedICC {
   334  				t.Errorf("%s: unexpected in-cluster-config call %t", name, test.icc.called)
   335  			}
   336  			if err != test.err || ns != test.result || overridden != test.overridden {
   337  				t.Errorf("%s: unexpected result: %v %s %t", name, err, ns, overridden)
   338  			}
   339  		})
   340  	}
   341  }
   342  

View as plain text