sigs.k8s.io/prow@v0.0.0-20240503223140-c5e374dc7eb1/pkg/kube/config_test.go (about)

     1  /*
     2  Copyright 2019 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 kube
    18  
    19  import (
    20  	"path/filepath"
    21  	"testing"
    22  
    23  	"github.com/google/go-cmp/cmp"
    24  	"github.com/google/go-cmp/cmp/cmpopts"
    25  
    26  	"k8s.io/apimachinery/pkg/api/equality"
    27  	"k8s.io/apimachinery/pkg/util/diff"
    28  	"k8s.io/apimachinery/pkg/util/sets"
    29  	"k8s.io/client-go/rest"
    30  )
    31  
    32  func TestMergeConfigs(t *testing.T) {
    33  	fakeConfig := func(u string) *rest.Config { return &rest.Config{Username: u} }
    34  	cases := []struct {
    35  		name     string
    36  		local    *rest.Config
    37  		foreign  map[string]rest.Config
    38  		current  string
    39  		expected map[string]rest.Config
    40  		err      bool
    41  	}{
    42  		{
    43  			name: "require at least one cluster",
    44  			err:  true,
    45  		},
    46  		{
    47  			name:  "only local cluster",
    48  			local: fakeConfig("local"),
    49  			expected: map[string]rest.Config{
    50  				InClusterContext:    *fakeConfig("local"),
    51  				DefaultClusterAlias: *fakeConfig("local"),
    52  			},
    53  		},
    54  		{
    55  			name: "foreign without local uses current as default",
    56  			foreign: map[string]rest.Config{
    57  				"current-context": *fakeConfig("current"),
    58  			},
    59  			current: "current-context",
    60  			expected: map[string]rest.Config{
    61  				InClusterContext:    *fakeConfig("current"),
    62  				DefaultClusterAlias: *fakeConfig("current"),
    63  				"current-context":   *fakeConfig("current"),
    64  			},
    65  		},
    66  		{
    67  			name: "reject only foreign without a current context",
    68  			foreign: map[string]rest.Config{
    69  				DefaultClusterAlias: *fakeConfig("default"),
    70  			},
    71  			err: true,
    72  		},
    73  		{
    74  			name: "accept only foreign with default",
    75  			foreign: map[string]rest.Config{
    76  				DefaultClusterAlias: *fakeConfig("default"),
    77  				"random-context":    *fakeConfig("random"),
    78  			},
    79  			current: "random-context",
    80  			expected: map[string]rest.Config{
    81  				InClusterContext:    *fakeConfig("random"),
    82  				DefaultClusterAlias: *fakeConfig("default"),
    83  				"random-context":    *fakeConfig("random"),
    84  			},
    85  		},
    86  		{
    87  			name:  "accept local and foreign, using local for default",
    88  			local: fakeConfig("local"),
    89  			foreign: map[string]rest.Config{
    90  				"random-context": *fakeConfig("random"),
    91  			},
    92  			current: "random-context",
    93  			expected: map[string]rest.Config{
    94  				InClusterContext:    *fakeConfig("local"),
    95  				DefaultClusterAlias: *fakeConfig("local"),
    96  				"random-context":    *fakeConfig("random"),
    97  			},
    98  		},
    99  	}
   100  
   101  	for _, tc := range cases {
   102  		t.Run(tc.name, func(t *testing.T) {
   103  			actual, err := mergeConfigs(tc.local, tc.foreign, tc.current)
   104  			switch {
   105  			case err != nil:
   106  				if !tc.err {
   107  					t.Errorf("unexpected error: %v", err)
   108  				}
   109  			case tc.err:
   110  				t.Error("failed to receive an error")
   111  			case !equality.Semantic.DeepEqual(actual, tc.expected):
   112  				t.Errorf("configs do not match:\n%s", diff.ObjectReflectDiff(tc.expected, actual))
   113  			}
   114  		})
   115  	}
   116  }
   117  
   118  func TestLoadClusterConfigs(t *testing.T) {
   119  	cases := []struct {
   120  		name               string
   121  		kubeconfig         string
   122  		kubeconfigDir      string
   123  		suffix             string
   124  		projectedTokenFile string
   125  		noInClusterConfig  bool
   126  		expected           map[string]rest.Config
   127  		expectedErr        bool
   128  		disabledClusters   sets.Set[string]
   129  	}{
   130  		{
   131  			name:       "load from kubeconfig",
   132  			kubeconfig: filepath.Join(filepath.Join("testdata", "load_from_kubeconfig"), "kubeconfig"),
   133  			expected: map[string]rest.Config{
   134  				"": {
   135  					Host:        "https://api.ci.l2s4.p1.openshiftapps.com:6443",
   136  					BearerToken: "REDACTED",
   137  				},
   138  				"app.ci": {
   139  					Host:        "https://api.ci.l2s4.p1.openshiftapps.com:6443",
   140  					BearerToken: "REDACTED",
   141  				},
   142  				"build01": {
   143  					Host:        "https://api.build01.ci.devcluster.openshift.com:6443",
   144  					BearerToken: "REDACTED",
   145  				},
   146  				"build02": {
   147  					Host:        "https://api.build02.gcp.ci.openshift.org:6443",
   148  					BearerToken: "REDACTED",
   149  				},
   150  				"default": {
   151  					Host:        "https://api.ci.l2s4.p1.openshiftapps.com:6443",
   152  					BearerToken: "REDACTED",
   153  				},
   154  				"hive": {
   155  					Host:        "https://api.hive.9xw5.p1.openshiftapps.com:6443",
   156  					BearerToken: "REDACTED",
   157  				},
   158  			},
   159  		},
   160  		{
   161  			name:          "load from kubeconfigDir",
   162  			kubeconfigDir: filepath.Join("testdata", "load_from_kubeconfigDir"),
   163  			suffix:        "yaml",
   164  			expected: map[string]rest.Config{
   165  				"": {
   166  					Host:        "https://api.build02.gcp.ci.openshift.org:6443",
   167  					BearerToken: "REDACTED",
   168  				},
   169  				"app.ci": {
   170  					Host:        "https://api.ci.l2s4.p1.openshiftapps.com:6443",
   171  					BearerToken: "REDACTED",
   172  				},
   173  				"build01": {
   174  					Host:        "https://api.build01.ci.devcluster.openshift.com:6443",
   175  					BearerToken: "REDACTED",
   176  				},
   177  				"build02": {
   178  					Host:        "https://api.build02.gcp.ci.openshift.org:6443",
   179  					BearerToken: "REDACTED",
   180  				},
   181  				"default": {
   182  					Host:        "https://api.build02.gcp.ci.openshift.org:6443",
   183  					BearerToken: "REDACTED",
   184  				},
   185  				"hive": {
   186  					Host:        "https://api.hive.9xw5.p1.openshiftapps.com:6443",
   187  					BearerToken: "REDACTED",
   188  				},
   189  			},
   190  		},
   191  		{
   192  			name:             "load from kubeconfigDir with build02 disabled",
   193  			kubeconfigDir:    filepath.Join("testdata", "load_from_kubeconfigDir"),
   194  			suffix:           "yaml",
   195  			disabledClusters: sets.New[string]("build02"),
   196  			expected: map[string]rest.Config{
   197  				"": {
   198  					Host:        "https://api.build01.ci.devcluster.openshift.com:6443",
   199  					BearerToken: "REDACTED",
   200  				},
   201  				"app.ci": {
   202  					Host:        "https://api.ci.l2s4.p1.openshiftapps.com:6443",
   203  					BearerToken: "REDACTED",
   204  				},
   205  				"build01": {
   206  					Host:        "https://api.build01.ci.devcluster.openshift.com:6443",
   207  					BearerToken: "REDACTED",
   208  				},
   209  				"default": {
   210  					Host:        "https://api.build01.ci.devcluster.openshift.com:6443",
   211  					BearerToken: "REDACTED",
   212  				},
   213  				"hive": {
   214  					Host:        "https://api.hive.9xw5.p1.openshiftapps.com:6443",
   215  					BearerToken: "REDACTED",
   216  				},
   217  			},
   218  		},
   219  		{
   220  			name:          "load from kubeconfigDir having contexts with the same name",
   221  			kubeconfigDir: filepath.Join("testdata", "load_from_kubeconfigDir_having_contexts_with_the_same_name"),
   222  			expectedErr:   true,
   223  		},
   224  		{
   225  			name:          "load from kubeconfig and kubeconfigDir",
   226  			kubeconfig:    filepath.Join(filepath.Join("testdata", "load_from_kubeconfig"), "kubeconfig2"),
   227  			kubeconfigDir: filepath.Join("testdata", "load_from_kubeconfig_and_kubeconfigDir"),
   228  			expected: map[string]rest.Config{
   229  				"": {
   230  					Host:        "https://api.build01.ci.devcluster.openshift.com:6443",
   231  					BearerToken: "REDACTED",
   232  				},
   233  				"app.ci": {
   234  					Host:        "https://api.ci.l2s4.p1.openshiftapps.com:6443",
   235  					BearerToken: "REDACTED",
   236  				},
   237  				"build01": {
   238  					Host:        "https://api.build01.ci.devcluster.openshift.com:6443",
   239  					BearerToken: "REDACTED",
   240  				},
   241  				"build02": {
   242  					Host:        "https://api.build02.gcp.ci.openshift.org:6443",
   243  					BearerToken: "REDACTED",
   244  				},
   245  				"default": {
   246  					Host:        "https://api.build01.ci.devcluster.openshift.com:6443",
   247  					BearerToken: "REDACTED",
   248  				},
   249  				"hive": {
   250  					Host:        "https://api.hive.9xw5.p1.openshiftapps.com:6443",
   251  					BearerToken: "REDACTED",
   252  				},
   253  			},
   254  		},
   255  		{
   256  			name:              "no inCluster config",
   257  			kubeconfig:        filepath.Join(filepath.Join("testdata", "load_from_kubeconfig"), "kubeconfig2"),
   258  			kubeconfigDir:     filepath.Join("testdata", "no_inCluster_config"),
   259  			noInClusterConfig: true,
   260  			expected: map[string]rest.Config{
   261  				"app.ci": {
   262  					Host:        "https://api.ci.l2s4.p1.openshiftapps.com:6443",
   263  					BearerToken: "REDACTED",
   264  				},
   265  				"build01": {
   266  					Host:        "https://api.build01.ci.devcluster.openshift.com:6443",
   267  					BearerToken: "REDACTED",
   268  				},
   269  				"build02": {
   270  					Host:        "https://api.build02.gcp.ci.openshift.org:6443",
   271  					BearerToken: "REDACTED",
   272  				},
   273  				"hive": {
   274  					Host:        "https://api.hive.9xw5.p1.openshiftapps.com:6443",
   275  					BearerToken: "REDACTED",
   276  				},
   277  			},
   278  		},
   279  	}
   280  
   281  	for _, tc := range cases {
   282  		t.Run(tc.name, func(t *testing.T) {
   283  			actual, actualErr := LoadClusterConfigs(NewConfig(ConfigFile(tc.kubeconfig),
   284  				ConfigDir(tc.kubeconfigDir), ConfigProjectedTokenFile(tc.projectedTokenFile),
   285  				NoInClusterConfig(tc.noInClusterConfig), ConfigSuffix(tc.suffix),
   286  				DisabledClusters(tc.disabledClusters)))
   287  			if tc.expectedErr != (actualErr != nil) {
   288  				t.Errorf("%s: actualErr %v does not match expectedErr %v", tc.name, actualErr, tc.expectedErr)
   289  				return
   290  			}
   291  			if diff := cmp.Diff(tc.expected, actual, cmpopts.IgnoreFields(rest.Config{}, "UserAgent")); !tc.expectedErr && diff != "" {
   292  				t.Errorf("%s: actual does not match expected, diff: %s", tc.name, diff)
   293  			}
   294  		})
   295  	}
   296  }