k8s.io/client-go@v0.31.1/tools/clientcmd/api/helpers_test.go (about) 1 /* 2 Copyright 2015 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 api 18 19 import ( 20 "bytes" 21 "fmt" 22 "os" 23 "reflect" 24 "testing" 25 26 utiltesting "k8s.io/client-go/util/testing" 27 28 "sigs.k8s.io/yaml" 29 ) 30 31 func newMergedConfig(certFile, certContent, keyFile, keyContent, caFile, caContent string, t *testing.T) Config { 32 if err := os.WriteFile(certFile, []byte(certContent), 0644); err != nil { 33 t.Errorf("unexpected error: %v", err) 34 } 35 if err := os.WriteFile(keyFile, []byte(keyContent), 0600); err != nil { 36 t.Errorf("unexpected error: %v", err) 37 } 38 if err := os.WriteFile(caFile, []byte(caContent), 0644); err != nil { 39 t.Errorf("unexpected error: %v", err) 40 } 41 42 return Config{ 43 AuthInfos: map[string]*AuthInfo{ 44 "red-user": {Token: "red-token", ClientCertificateData: []byte(certContent), ClientKeyData: []byte(keyContent)}, 45 "blue-user": {Token: "blue-token", ClientCertificate: certFile, ClientKey: keyFile}}, 46 Clusters: map[string]*Cluster{ 47 "cow-cluster": {Server: "http://cow.org:8080", CertificateAuthorityData: []byte(caContent)}, 48 "chicken-cluster": {Server: "http://chicken.org:8080", CertificateAuthority: caFile}}, 49 Contexts: map[string]*Context{ 50 "federal-context": {AuthInfo: "red-user", Cluster: "cow-cluster"}, 51 "shaker-context": {AuthInfo: "blue-user", Cluster: "chicken-cluster"}}, 52 CurrentContext: "federal-context", 53 } 54 } 55 56 func TestMinifySuccess(t *testing.T) { 57 certFile, _ := os.CreateTemp("", "") 58 keyFile, _ := os.CreateTemp("", "") 59 caFile, _ := os.CreateTemp("", "") 60 defer utiltesting.CloseAndRemove(t, certFile, keyFile, caFile) 61 62 mutatingConfig := newMergedConfig(certFile.Name(), "cert", keyFile.Name(), "key", caFile.Name(), "ca", t) 63 64 if err := MinifyConfig(&mutatingConfig); err != nil { 65 t.Errorf("unexpected error: %v", err) 66 } 67 68 if len(mutatingConfig.Contexts) > 1 { 69 t.Errorf("unexpected contexts: %v", mutatingConfig.Contexts) 70 } 71 if _, exists := mutatingConfig.Contexts["federal-context"]; !exists { 72 t.Errorf("missing context") 73 } 74 75 if len(mutatingConfig.Clusters) > 1 { 76 t.Errorf("unexpected clusters: %v", mutatingConfig.Clusters) 77 } 78 if _, exists := mutatingConfig.Clusters["cow-cluster"]; !exists { 79 t.Errorf("missing cluster") 80 } 81 82 if len(mutatingConfig.AuthInfos) > 1 { 83 t.Errorf("unexpected users: %v", mutatingConfig.AuthInfos) 84 } 85 if _, exists := mutatingConfig.AuthInfos["red-user"]; !exists { 86 t.Errorf("missing user") 87 } 88 } 89 90 func TestMinifyMissingContext(t *testing.T) { 91 certFile, _ := os.CreateTemp("", "") 92 keyFile, _ := os.CreateTemp("", "") 93 caFile, _ := os.CreateTemp("", "") 94 defer utiltesting.CloseAndRemove(t, certFile, keyFile, caFile) 95 96 mutatingConfig := newMergedConfig(certFile.Name(), "cert", keyFile.Name(), "key", caFile.Name(), "ca", t) 97 mutatingConfig.CurrentContext = "missing" 98 99 errMsg := "cannot locate context missing" 100 101 if err := MinifyConfig(&mutatingConfig); err == nil || err.Error() != errMsg { 102 t.Errorf("expected %v, got %v", errMsg, err) 103 } 104 } 105 106 func TestMinifyMissingCluster(t *testing.T) { 107 certFile, _ := os.CreateTemp("", "") 108 keyFile, _ := os.CreateTemp("", "") 109 caFile, _ := os.CreateTemp("", "") 110 defer utiltesting.CloseAndRemove(t, certFile, keyFile, caFile) 111 112 mutatingConfig := newMergedConfig(certFile.Name(), "cert", keyFile.Name(), "key", caFile.Name(), "ca", t) 113 delete(mutatingConfig.Clusters, mutatingConfig.Contexts[mutatingConfig.CurrentContext].Cluster) 114 115 errMsg := "cannot locate cluster cow-cluster" 116 117 if err := MinifyConfig(&mutatingConfig); err == nil || err.Error() != errMsg { 118 t.Errorf("expected %v, got %v", errMsg, err) 119 } 120 } 121 122 func TestMinifyMissingAuthInfo(t *testing.T) { 123 certFile, _ := os.CreateTemp("", "") 124 keyFile, _ := os.CreateTemp("", "") 125 caFile, _ := os.CreateTemp("", "") 126 defer utiltesting.CloseAndRemove(t, certFile, keyFile, caFile) 127 128 mutatingConfig := newMergedConfig(certFile.Name(), "cert", keyFile.Name(), "key", caFile.Name(), "ca", t) 129 delete(mutatingConfig.AuthInfos, mutatingConfig.Contexts[mutatingConfig.CurrentContext].AuthInfo) 130 131 errMsg := "cannot locate user red-user" 132 133 if err := MinifyConfig(&mutatingConfig); err == nil || err.Error() != errMsg { 134 t.Errorf("expected %v, got %v", errMsg, err) 135 } 136 } 137 138 func TestFlattenSuccess(t *testing.T) { 139 certFile, _ := os.CreateTemp("", "") 140 keyFile, _ := os.CreateTemp("", "") 141 caFile, _ := os.CreateTemp("", "") 142 defer utiltesting.CloseAndRemove(t, certFile, keyFile, caFile) 143 144 certData := "cert" 145 keyData := "key" 146 caData := "ca" 147 148 unchangingCluster := "cow-cluster" 149 unchangingAuthInfo := "red-user" 150 changingCluster := "chicken-cluster" 151 changingAuthInfo := "blue-user" 152 153 startingConfig := newMergedConfig(certFile.Name(), certData, keyFile.Name(), keyData, caFile.Name(), caData, t) 154 mutatingConfig := startingConfig 155 156 if err := FlattenConfig(&mutatingConfig); err != nil { 157 t.Errorf("unexpected error: %v", err) 158 } 159 160 if len(mutatingConfig.Contexts) != 2 { 161 t.Errorf("unexpected contexts: %v", mutatingConfig.Contexts) 162 } 163 if !reflect.DeepEqual(startingConfig.Contexts, mutatingConfig.Contexts) { 164 t.Errorf("expected %v, got %v", startingConfig.Contexts, mutatingConfig.Contexts) 165 } 166 167 if len(mutatingConfig.Clusters) != 2 { 168 t.Errorf("unexpected clusters: %v", mutatingConfig.Clusters) 169 } 170 if !reflect.DeepEqual(startingConfig.Clusters[unchangingCluster], mutatingConfig.Clusters[unchangingCluster]) { 171 t.Errorf("expected %v, got %v", startingConfig.Clusters[unchangingCluster], mutatingConfig.Clusters[unchangingCluster]) 172 } 173 if len(mutatingConfig.Clusters[changingCluster].CertificateAuthority) != 0 { 174 t.Errorf("unexpected caFile") 175 } 176 if string(mutatingConfig.Clusters[changingCluster].CertificateAuthorityData) != caData { 177 t.Errorf("expected %v, got %v", caData, string(mutatingConfig.Clusters[changingCluster].CertificateAuthorityData)) 178 } 179 180 if len(mutatingConfig.AuthInfos) != 2 { 181 t.Errorf("unexpected users: %v", mutatingConfig.AuthInfos) 182 } 183 if !reflect.DeepEqual(startingConfig.AuthInfos[unchangingAuthInfo], mutatingConfig.AuthInfos[unchangingAuthInfo]) { 184 t.Errorf("expected %v, got %v", startingConfig.AuthInfos[unchangingAuthInfo], mutatingConfig.AuthInfos[unchangingAuthInfo]) 185 } 186 if len(mutatingConfig.AuthInfos[changingAuthInfo].ClientCertificate) != 0 { 187 t.Errorf("unexpected caFile") 188 } 189 if string(mutatingConfig.AuthInfos[changingAuthInfo].ClientCertificateData) != certData { 190 t.Errorf("expected %v, got %v", certData, string(mutatingConfig.AuthInfos[changingAuthInfo].ClientCertificateData)) 191 } 192 if len(mutatingConfig.AuthInfos[changingAuthInfo].ClientKey) != 0 { 193 t.Errorf("unexpected caFile") 194 } 195 if string(mutatingConfig.AuthInfos[changingAuthInfo].ClientKeyData) != keyData { 196 t.Errorf("expected %v, got %v", keyData, string(mutatingConfig.AuthInfos[changingAuthInfo].ClientKeyData)) 197 } 198 199 } 200 201 func Example_minifyAndShorten() { 202 certFile, _ := os.CreateTemp("", "") 203 keyFile, _ := os.CreateTemp("", "") 204 caFile, _ := os.CreateTemp("", "") 205 defer utiltesting.CloseAndRemove(&testing.T{}, certFile, keyFile, caFile) 206 207 certData := "cert" 208 keyData := "key" 209 caData := "ca" 210 211 config := newMergedConfig(certFile.Name(), certData, keyFile.Name(), keyData, caFile.Name(), caData, nil) 212 213 MinifyConfig(&config) 214 ShortenConfig(&config) 215 216 output, _ := yaml.Marshal(config) 217 fmt.Printf("%s", string(output)) 218 // Output: 219 // clusters: 220 // cow-cluster: 221 // certificate-authority-data: DATA+OMITTED 222 // server: http://cow.org:8080 223 // contexts: 224 // federal-context: 225 // cluster: cow-cluster 226 // user: red-user 227 // current-context: federal-context 228 // preferences: {} 229 // users: 230 // red-user: 231 // client-certificate-data: DATA+OMITTED 232 // client-key-data: DATA+OMITTED 233 // token: REDACTED 234 } 235 236 func TestShortenSuccess(t *testing.T) { 237 certFile, _ := os.CreateTemp("", "") 238 keyFile, _ := os.CreateTemp("", "") 239 caFile, _ := os.CreateTemp("", "") 240 defer utiltesting.CloseAndRemove(t, certFile, keyFile, caFile) 241 242 certData := "cert" 243 keyData := "key" 244 caData := "ca" 245 246 unchangingCluster := "chicken-cluster" 247 unchangingAuthInfo := "blue-user" 248 changingCluster := "cow-cluster" 249 changingAuthInfo := "red-user" 250 251 startingConfig := newMergedConfig(certFile.Name(), certData, keyFile.Name(), keyData, caFile.Name(), caData, t) 252 mutatingConfig := startingConfig 253 254 ShortenConfig(&mutatingConfig) 255 256 if len(mutatingConfig.Contexts) != 2 { 257 t.Errorf("unexpected contexts: %v", mutatingConfig.Contexts) 258 } 259 if !reflect.DeepEqual(startingConfig.Contexts, mutatingConfig.Contexts) { 260 t.Errorf("expected %v, got %v", startingConfig.Contexts, mutatingConfig.Contexts) 261 } 262 263 dataOmitted := string(dataOmittedBytes) 264 if len(mutatingConfig.Clusters) != 2 { 265 t.Errorf("unexpected clusters: %v", mutatingConfig.Clusters) 266 } 267 if !reflect.DeepEqual(startingConfig.Clusters[unchangingCluster], mutatingConfig.Clusters[unchangingCluster]) { 268 t.Errorf("expected %v, got %v", startingConfig.Clusters[unchangingCluster], mutatingConfig.Clusters[unchangingCluster]) 269 } 270 if string(mutatingConfig.Clusters[changingCluster].CertificateAuthorityData) != dataOmitted { 271 t.Errorf("expected %v, got %v", dataOmitted, string(mutatingConfig.Clusters[changingCluster].CertificateAuthorityData)) 272 } 273 274 if len(mutatingConfig.AuthInfos) != 2 { 275 t.Errorf("unexpected users: %v", mutatingConfig.AuthInfos) 276 } 277 if !reflect.DeepEqual(startingConfig.AuthInfos[unchangingAuthInfo], mutatingConfig.AuthInfos[unchangingAuthInfo]) { 278 t.Errorf("expected %v, got %v", startingConfig.AuthInfos[unchangingAuthInfo], mutatingConfig.AuthInfos[unchangingAuthInfo]) 279 } 280 if string(mutatingConfig.AuthInfos[changingAuthInfo].ClientCertificateData) != dataOmitted { 281 t.Errorf("expected %v, got %v", dataOmitted, string(mutatingConfig.AuthInfos[changingAuthInfo].ClientCertificateData)) 282 } 283 if string(mutatingConfig.AuthInfos[changingAuthInfo].ClientKeyData) != dataOmitted { 284 t.Errorf("expected %v, got %v", dataOmitted, string(mutatingConfig.AuthInfos[changingAuthInfo].ClientKeyData)) 285 } 286 if mutatingConfig.AuthInfos[changingAuthInfo].Token != "REDACTED" { 287 t.Errorf("expected REDACTED, got %q", mutatingConfig.AuthInfos[changingAuthInfo].Token) 288 } 289 } 290 291 func TestRedactSecrets(t *testing.T) { 292 certFile, _ := os.CreateTemp("", "") 293 defer os.Remove(certFile.Name()) 294 keyFile, _ := os.CreateTemp("", "") 295 defer os.Remove(keyFile.Name()) 296 caFile, _ := os.CreateTemp("", "") 297 defer os.Remove(caFile.Name()) 298 299 certData := "cert" 300 keyData := "key" 301 caData := "ca" 302 303 unchangingCluster := "chicken-cluster" 304 unchangingAuthInfo := "blue-user" 305 changingAuthInfo := "red-user" 306 307 startingConfig := newMergedConfig(certFile.Name(), certData, keyFile.Name(), keyData, caFile.Name(), caData, t) 308 mutatingConfig := startingConfig 309 310 err := RedactSecrets(&mutatingConfig) 311 if err != nil { 312 t.Errorf("unexpected error redacting secrets:\n%v", err) 313 } 314 315 if len(mutatingConfig.Contexts) != 2 { 316 t.Errorf("unexpected contexts: %v", mutatingConfig.Contexts) 317 } 318 if !reflect.DeepEqual(startingConfig.Contexts, mutatingConfig.Contexts) { 319 t.Errorf("expected %v, got %v", startingConfig.Contexts, mutatingConfig.Contexts) 320 } 321 322 if len(mutatingConfig.Clusters) != 2 { 323 t.Errorf("unexpected clusters: %v", mutatingConfig.Clusters) 324 } 325 if !reflect.DeepEqual(startingConfig.Clusters[unchangingCluster], mutatingConfig.Clusters[unchangingCluster]) { 326 t.Errorf("expected %v, got %v", startingConfig.Clusters[unchangingCluster], mutatingConfig.Clusters[unchangingCluster]) 327 } 328 329 if len(mutatingConfig.AuthInfos) != 2 { 330 t.Errorf("unexpected users: %v", mutatingConfig.AuthInfos) 331 } 332 if !reflect.DeepEqual(startingConfig.AuthInfos[unchangingAuthInfo], mutatingConfig.AuthInfos[unchangingAuthInfo]) { 333 t.Errorf("expected %v, got %v", startingConfig.AuthInfos[unchangingAuthInfo], mutatingConfig.AuthInfos[unchangingAuthInfo]) 334 } 335 if mutatingConfig.AuthInfos[changingAuthInfo].Token != "REDACTED" { 336 t.Errorf("expected REDACTED, got %v", mutatingConfig.AuthInfos[changingAuthInfo].Token) 337 } 338 if !bytes.Equal(mutatingConfig.AuthInfos[changingAuthInfo].ClientKeyData, []byte("REDACTED")) { 339 t.Errorf("expected REDACTED, got %s", mutatingConfig.AuthInfos[changingAuthInfo].ClientKeyData) 340 } 341 }