github.com/GoogleContainerTools/skaffold@v1.39.18/pkg/skaffold/kubernetes/context/context_test.go (about) 1 /* 2 Copyright 2019 The Skaffold 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 context 18 19 import ( 20 "io/ioutil" 21 "sync" 22 "testing" 23 24 "github.com/GoogleContainerTools/skaffold/pkg/skaffold/output/log" 25 "github.com/GoogleContainerTools/skaffold/testutil" 26 ) 27 28 const clusterFooContext = "cluster-foo" 29 const clusterBarContext = "cluster-bar" 30 31 const validKubeConfig = ` 32 apiVersion: v1 33 kind: Config 34 clusters: 35 - cluster: 36 server: https://foo.com 37 name: cluster-foo 38 - cluster: 39 server: https://bar.com 40 name: cluster-bar 41 contexts: 42 - context: 43 cluster: cluster-foo 44 user: user1 45 name: cluster-foo 46 - context: 47 cluster: cluster-bar 48 user: user1 49 name: cluster-bar 50 current-context: cluster-foo 51 users: 52 - name: user1 53 user: 54 password: secret 55 username: user 56 ` 57 58 const changedKubeConfig = ` 59 apiVersion: v1 60 kind: Config 61 clusters: 62 - cluster: 63 server: https://changed-url.com 64 name: cluster-bar 65 contexts: 66 - context: 67 cluster: cluster-bar 68 user: user-bar 69 name: context-bar 70 - context: 71 cluster: cluster-bar 72 user: user-baz 73 name: context-baz 74 current-context: context-baz 75 users: 76 - name: user1 77 user: 78 password: secret 79 username: user 80 ` 81 82 func TestCurrentContext(t *testing.T) { 83 testutil.Run(t, "valid context", func(t *testutil.T) { 84 resetKubeConfig(t, validKubeConfig) 85 86 config, err := CurrentConfig() 87 88 t.CheckNoError(err) 89 t.CheckDeepEqual(clusterFooContext, config.CurrentContext) 90 }) 91 92 testutil.Run(t, "valid with override context", func(t *testutil.T) { 93 resetKubeConfig(t, validKubeConfig) 94 95 kubeContext = "cluster-bar" 96 config, err := CurrentConfig() 97 98 t.CheckNoError(err) 99 t.CheckDeepEqual(clusterBarContext, config.CurrentContext) 100 }) 101 102 testutil.Run(t, "kubeconfig CLI flag takes precedence", func(t *testutil.T) { 103 resetKubeConfig(t, validKubeConfig) 104 kubeConfig := t.TempFile("config", []byte(changedKubeConfig)) 105 106 kubeConfigFile = kubeConfig 107 config, err := CurrentConfig() 108 109 t.CheckNoError(err) 110 t.CheckDeepEqual("context-baz", config.CurrentContext) 111 }) 112 113 testutil.Run(t, "invalid context", func(t *testutil.T) { 114 resetKubeConfig(t, "invalid") 115 116 _, err := CurrentConfig() 117 118 t.CheckError(true, err) 119 }) 120 } 121 122 func TestGetRestClientConfig(t *testing.T) { 123 testutil.Run(t, "valid context", func(t *testutil.T) { 124 resetKubeConfig(t, validKubeConfig) 125 126 cfg, err := GetRestClientConfig("") 127 128 t.CheckNoError(err) 129 t.CheckDeepEqual("https://foo.com", cfg.Host) 130 }) 131 132 testutil.Run(t, "valid context with override", func(t *testutil.T) { 133 resetKubeConfig(t, validKubeConfig) 134 135 kubeContext = clusterBarContext 136 cfg, err := GetRestClientConfig("") 137 138 t.CheckNoError(err) 139 t.CheckDeepEqual("https://bar.com", cfg.Host) 140 }) 141 142 testutil.Run(t, "invalid context", func(t *testutil.T) { 143 resetKubeConfig(t, "invalid") 144 145 _, err := GetRestClientConfig("") 146 147 t.CheckError(true, err) 148 }) 149 150 testutil.Run(t, "kube-config immutability", func(t *testutil.T) { 151 log.SetLevel(log.InfoLevel) 152 kubeConfig := t.TempFile("config", []byte(validKubeConfig)) 153 kubeContext = clusterBarContext 154 t.SetEnvs(map[string]string{"KUBECONFIG": kubeConfig}) 155 resetConfig() 156 157 cfg, err := GetRestClientConfig("") 158 159 t.CheckNoError(err) 160 t.CheckDeepEqual("https://bar.com", cfg.Host) 161 162 if err = ioutil.WriteFile(kubeConfig, []byte(changedKubeConfig), 0644); err != nil { 163 t.Error(err) 164 } 165 166 cfg, err = GetRestClientConfig("") 167 168 t.CheckNoError(err) 169 t.CheckDeepEqual("https://bar.com", cfg.Host) 170 }) 171 172 testutil.Run(t, "change context after first execution", func(t *testutil.T) { 173 resetKubeConfig(t, validKubeConfig) 174 175 _, err := GetRestClientConfig("") 176 t.CheckNoError(err) 177 kubeContext = clusterBarContext 178 cfg, err := GetRestClientConfig("") 179 180 t.CheckNoError(err) 181 t.CheckDeepEqual("https://bar.com", cfg.Host) 182 }) 183 184 testutil.Run(t, "REST client in-cluster", func(t *testutil.T) { 185 t.SetEnvs(map[string]string{"KUBECONFIG": "non-valid"}) 186 resetConfig() 187 188 _, err := getRestClientConfig("", "") 189 190 if err == nil { 191 t.Errorf("expected error outside the cluster") 192 } 193 }) 194 } 195 196 func TestUseKubeContext(t *testing.T) { 197 type invocation struct { 198 cliValue string 199 } 200 tests := []struct { 201 name string 202 invocations []invocation 203 expected string 204 }{ 205 { 206 name: "when not called at all", 207 invocations: nil, 208 expected: "", 209 }, 210 { 211 name: "first CLI value takes precedence", 212 invocations: []invocation{ 213 {cliValue: "context-first"}, 214 {cliValue: "context-second"}, 215 }, 216 expected: "context-first", 217 }, 218 } 219 220 for _, test := range tests { 221 testutil.Run(t, test.name, func(t *testutil.T) { 222 kubeContext = "" 223 for _, inv := range test.invocations { 224 ConfigureKubeConfig("", inv.cliValue) 225 } 226 227 t.CheckDeepEqual(test.expected, kubeContext) 228 resetConfig() 229 }) 230 } 231 } 232 233 // resetConfig is used by tests 234 func resetConfig() { 235 kubeConfigOnce = sync.Once{} 236 configureOnce = sync.Once{} 237 } 238 239 func resetKubeConfig(t *testutil.T, content string) { 240 kubeConfig := t.TempFile("config", []byte(content)) 241 t.SetEnvs(map[string]string{"KUBECONFIG": kubeConfig}) 242 kubeContext = "" 243 kubeConfigFile = "" 244 resetConfig() 245 }