k8s.io/kubernetes@v1.31.0-alpha.0.0.20240520171757-56147500dadc/cmd/kubeadm/app/phases/certs/certs_test.go (about) 1 /* 2 Copyright 2016 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 certs 18 19 import ( 20 "bytes" 21 "crypto/x509" 22 "net" 23 "os" 24 "path/filepath" 25 "testing" 26 27 "github.com/pkg/errors" 28 "github.com/stretchr/testify/assert" 29 30 utilerrors "k8s.io/apimachinery/pkg/util/errors" 31 certutil "k8s.io/client-go/util/cert" 32 "k8s.io/client-go/util/keyutil" 33 34 kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" 35 kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" 36 certstestutil "k8s.io/kubernetes/cmd/kubeadm/app/util/certs" 37 "k8s.io/kubernetes/cmd/kubeadm/app/util/pkiutil" 38 pkiutiltesting "k8s.io/kubernetes/cmd/kubeadm/app/util/pkiutil/testing" 39 testutil "k8s.io/kubernetes/cmd/kubeadm/test" 40 ) 41 42 func TestWriteCertificateAuthorityFilesIfNotExist(t *testing.T) { 43 setupCert, setupKey := certstestutil.CreateCACert(t) 44 caCert, caKey := certstestutil.CreateCACert(t) 45 46 var tests = []struct { 47 setupFunc func(pkiDir string) error 48 expectedError bool 49 expectedCa *x509.Certificate 50 }{ 51 { // ca cert does not exists > ca written 52 expectedCa: caCert, 53 }, 54 { // ca cert exists, is ca > existing ca used 55 setupFunc: func(pkiDir string) error { 56 return writeCertificateAuthorityFilesIfNotExist(pkiDir, "dummy", setupCert, setupKey) 57 }, 58 expectedCa: setupCert, 59 }, 60 { // some file exists, but it is not a valid ca cert > err 61 setupFunc: func(pkiDir string) error { 62 testutil.SetupEmptyFiles(t, pkiDir, "dummy.crt") 63 return nil 64 }, 65 expectedError: true, 66 }, 67 { // cert exists, but it is not a ca > err 68 setupFunc: func(pkiDir string) error { 69 cert, key, config := certstestutil.CreateTestCert(t, setupCert, setupKey, certutil.AltNames{}) 70 return writeCertificateFilesIfNotExist(pkiDir, "dummy", setupCert, cert, key, config) 71 }, 72 expectedError: true, 73 }, 74 } 75 76 for _, test := range tests { 77 // Create temp folder for the test case 78 tmpdir := testutil.SetupTempDir(t) 79 defer os.RemoveAll(tmpdir) 80 81 // executes setup func (if necessary) 82 if test.setupFunc != nil { 83 if err := test.setupFunc(tmpdir); err != nil { 84 t.Errorf("error executing setupFunc: %v", err) 85 continue 86 } 87 } 88 89 // executes create func 90 err := writeCertificateAuthorityFilesIfNotExist(tmpdir, "dummy", caCert, caKey) 91 92 if !test.expectedError && err != nil { 93 t.Errorf("error writeCertificateAuthorityFilesIfNotExist failed when not expected to fail: %v", err) 94 continue 95 } else if test.expectedError && err == nil { 96 t.Error("error writeCertificateAuthorityFilesIfNotExist didn't failed when expected") 97 continue 98 } else if test.expectedError { 99 continue 100 } 101 102 // asserts expected files are there 103 testutil.AssertFileExists(t, tmpdir, "dummy.key", "dummy.crt") 104 105 // check created cert 106 resultingCaCert, _, err := pkiutil.TryLoadCertAndKeyFromDisk(tmpdir, "dummy") 107 if err != nil { 108 t.Errorf("failure reading created cert: %v", err) 109 continue 110 } 111 if !resultingCaCert.Equal(test.expectedCa) { 112 t.Error("created ca cert does not match expected ca cert") 113 } 114 } 115 } 116 117 func TestWriteCertificateFilesIfNotExist(t *testing.T) { 118 altNames := certutil.AltNames{ 119 DNSNames: []string{"example.com"}, 120 IPs: []net.IP{ 121 net.IPv4(0, 0, 0, 0), 122 }, 123 } 124 125 caCert, caKey := certstestutil.CreateCACert(t) 126 setupCert, setupKey, _ := certstestutil.CreateTestCert(t, caCert, caKey, altNames) 127 cert, key, config := certstestutil.CreateTestCert(t, caCert, caKey, altNames) 128 129 var tests = []struct { 130 setupFunc func(pkiDir string) error 131 expectedError bool 132 expectedCert *x509.Certificate 133 }{ 134 { // cert does not exists > cert written 135 expectedCert: cert, 136 }, 137 { // cert exists, is signed by the same ca, missing SANs (dns name) > err 138 setupFunc: func(pkiDir string) error { 139 setupCert, setupKey, setupConfig := certstestutil.CreateTestCert(t, caCert, caKey, certutil.AltNames{ 140 IPs: []net.IP{ 141 net.IPv4(0, 0, 0, 0), 142 }, 143 }) 144 return writeCertificateFilesIfNotExist(pkiDir, "dummy", caCert, setupCert, setupKey, setupConfig) 145 }, 146 expectedError: true, 147 }, 148 { // cert exists, is signed by the same ca, missing SANs (IP address) > err 149 setupFunc: func(pkiDir string) error { 150 setupCert, setupKey, setupConfig := certstestutil.CreateTestCert(t, caCert, caKey, certutil.AltNames{ 151 DNSNames: []string{"example.com"}, 152 }) 153 return writeCertificateFilesIfNotExist(pkiDir, "dummy", caCert, setupCert, setupKey, setupConfig) 154 }, 155 expectedError: true, 156 }, 157 { // cert exists, is signed by the same ca, all SANs present > existing cert used 158 setupFunc: func(pkiDir string) error { 159 return writeCertificateFilesIfNotExist(pkiDir, "dummy", caCert, setupCert, setupKey, config) 160 }, 161 expectedCert: setupCert, 162 }, 163 { // some file exists, but it is not a valid cert > err 164 setupFunc: func(pkiDir string) error { 165 testutil.SetupEmptyFiles(t, pkiDir, "dummy.crt") 166 return nil 167 }, 168 expectedError: true, 169 }, 170 { // cert exists, is signed by another ca > err 171 setupFunc: func(pkiDir string) error { 172 anotherCaCert, anotherCaKey := certstestutil.CreateCACert(t) 173 anotherCert, anotherKey, config := certstestutil.CreateTestCert(t, anotherCaCert, anotherCaKey, certutil.AltNames{}) 174 175 return writeCertificateFilesIfNotExist(pkiDir, "dummy", anotherCaCert, anotherCert, anotherKey, config) 176 }, 177 expectedError: true, 178 }, 179 } 180 181 for _, test := range tests { 182 // Create temp folder for the test case 183 tmpdir := testutil.SetupTempDir(t) 184 defer os.RemoveAll(tmpdir) 185 186 // executes setup func (if necessary) 187 if test.setupFunc != nil { 188 if err := test.setupFunc(tmpdir); err != nil { 189 t.Errorf("error executing setupFunc: %v", err) 190 continue 191 } 192 } 193 194 // executes create func 195 err := writeCertificateFilesIfNotExist(tmpdir, "dummy", caCert, cert, key, config) 196 197 if !test.expectedError && err != nil { 198 t.Errorf("error writeCertificateFilesIfNotExist failed when not expected to fail: %v", err) 199 continue 200 } else if test.expectedError && err == nil { 201 t.Error("error writeCertificateFilesIfNotExist didn't fail when expected") 202 continue 203 } else if test.expectedError { 204 continue 205 } 206 207 // asserts expected files are there 208 testutil.AssertFileExists(t, tmpdir, "dummy.key", "dummy.crt") 209 210 // check created cert 211 resultingCert, _, err := pkiutil.TryLoadCertAndKeyFromDisk(tmpdir, "dummy") 212 if err != nil { 213 t.Errorf("failure reading created cert: %v", err) 214 continue 215 } 216 if !resultingCert.Equal(test.expectedCert) { 217 t.Error("created cert does not match expected cert") 218 } 219 } 220 } 221 222 func TestCreateServiceAccountKeyAndPublicKeyFiles(t *testing.T) { 223 setupKey, err := keyutil.MakeEllipticPrivateKeyPEM() 224 if err != nil { 225 t.Fatalf("Can't setup test: %v", err) 226 } 227 228 tcases := []struct { 229 name string 230 setupFunc func(pkiDir string) error 231 expectedErr bool 232 expectedKey []byte 233 }{ 234 { // key does not exists > key written 235 name: "generate successfully", 236 }, 237 { // key exists > existing key used 238 name: "use existing key", 239 setupFunc: func(pkiDir string) error { 240 err := keyutil.WriteKey(filepath.Join(pkiDir, kubeadmconstants.ServiceAccountPrivateKeyName), setupKey) 241 return err 242 }, 243 expectedKey: setupKey, 244 }, 245 { // some file exists, but it is not a valid key > err 246 name: "empty key", 247 setupFunc: func(pkiDir string) error { 248 testutil.SetupEmptyFiles(t, pkiDir, kubeadmconstants.ServiceAccountPrivateKeyName) 249 return nil 250 }, 251 expectedErr: true, 252 }, 253 } 254 for _, tt := range tcases { 255 t.Run(tt.name, func(t *testing.T) { 256 dir := testutil.SetupTempDir(t) 257 defer os.RemoveAll(dir) 258 259 if tt.setupFunc != nil { 260 if err := tt.setupFunc(dir); err != nil { 261 t.Fatalf("error executing setupFunc: %v", err) 262 } 263 } 264 265 err := CreateServiceAccountKeyAndPublicKeyFiles(dir, kubeadmapi.EncryptionAlgorithmRSA2048) 266 if (err != nil) != tt.expectedErr { 267 t.Fatalf("expected error: %v, got: %v, error: %v", tt.expectedErr, err != nil, err) 268 } else if tt.expectedErr { 269 return 270 } 271 272 resultingKeyPEM, wasGenerated, err := keyutil.LoadOrGenerateKeyFile(filepath.Join(dir, kubeadmconstants.ServiceAccountPrivateKeyName)) 273 if err != nil { 274 t.Errorf("Can't load created key: %v", err) 275 } else if wasGenerated { 276 t.Error("The key was not created") 277 } else if tt.expectedKey != nil && !bytes.Equal(resultingKeyPEM, tt.expectedKey) { 278 t.Error("Non-existing key is used") 279 } 280 }) 281 } 282 } 283 284 func TestSharedCertificateExists(t *testing.T) { 285 caCert, caKey := certstestutil.CreateCACert(t) 286 _, key, _ := certstestutil.CreateTestCert(t, caCert, caKey, certutil.AltNames{}) 287 publicKey := key.Public() 288 289 var tests = []struct { 290 name string 291 files certstestutil.PKIFiles 292 expectedErrors int 293 }{ 294 { 295 name: "success", 296 files: certstestutil.PKIFiles{ 297 "ca.crt": caCert, 298 "ca.key": caKey, 299 "front-proxy-ca.crt": caCert, 300 "front-proxy-ca.key": caKey, 301 "sa.pub": publicKey, 302 "sa.key": key, 303 "etcd/ca.crt": caCert, 304 "etcd/ca.key": caKey, 305 }, 306 }, 307 { 308 name: "missing ca.crt", 309 files: certstestutil.PKIFiles{ 310 "ca.key": caKey, 311 "front-proxy-ca.crt": caCert, 312 "front-proxy-ca.key": caKey, 313 "sa.pub": publicKey, 314 "sa.key": key, 315 "etcd/ca.crt": caCert, 316 "etcd/ca.key": caKey, 317 }, 318 expectedErrors: 1, 319 }, 320 { 321 name: "missing ca.key", 322 files: certstestutil.PKIFiles{ 323 "ca.crt": caCert, 324 "front-proxy-ca.crt": caCert, 325 "front-proxy-ca.key": caKey, 326 "sa.pub": publicKey, 327 "sa.key": key, 328 "etcd/ca.crt": caCert, 329 "etcd/ca.key": caKey, 330 }, 331 }, 332 { 333 name: "missing sa.key", 334 files: certstestutil.PKIFiles{ 335 "ca.crt": caCert, 336 "ca.key": caKey, 337 "front-proxy-ca.crt": caCert, 338 "front-proxy-ca.key": caKey, 339 "sa.pub": publicKey, 340 "etcd/ca.crt": caCert, 341 "etcd/ca.key": caKey, 342 }, 343 expectedErrors: 1, 344 }, 345 { 346 name: "missing front-proxy.crt", 347 files: certstestutil.PKIFiles{ 348 "ca.crt": caCert, 349 "ca.key": caKey, 350 "front-proxy-ca.key": caKey, 351 "sa.pub": publicKey, 352 "sa.key": key, 353 "etcd/ca.crt": caCert, 354 "etcd/ca.key": caKey, 355 }, 356 expectedErrors: 1, 357 }, 358 { 359 name: "missing etcd/ca.crt", 360 files: certstestutil.PKIFiles{ 361 "ca.crt": caCert, 362 "ca.key": caKey, 363 "front-proxy-ca.crt": caCert, 364 "front-proxy-ca.key": caKey, 365 "sa.pub": publicKey, 366 "sa.key": key, 367 "etcd/ca.key": caKey, 368 }, 369 expectedErrors: 1, 370 }, 371 { 372 name: "missing multiple certs (ca.crt and etcd/ca.crt)", 373 files: certstestutil.PKIFiles{ 374 "ca.key": caKey, 375 "front-proxy-ca.crt": caCert, 376 "front-proxy-ca.key": caKey, 377 "sa.pub": publicKey, 378 "sa.key": key, 379 "etcd/ca.key": caKey, 380 }, 381 expectedErrors: 2, 382 }, 383 } 384 385 for _, test := range tests { 386 t.Run("", func(t *testing.T) { 387 tmpdir := testutil.SetupTempDir(t) 388 os.MkdirAll(tmpdir+"/etcd", os.ModePerm) 389 defer os.RemoveAll(tmpdir) 390 391 cfg := &kubeadmapi.ClusterConfiguration{ 392 CertificatesDir: tmpdir, 393 } 394 395 // created expected keys 396 certstestutil.WritePKIFiles(t, tmpdir, test.files) 397 398 // executes create func 399 ret, err := SharedCertificateExists(cfg) 400 switch { 401 case err != nil: 402 if agg, ok := err.(utilerrors.Aggregate); ok && len(agg.Errors()) != test.expectedErrors { 403 t.Errorf("SharedCertificateExists didn't fail with the expected number of errors, expected: %v, got: %v", test.expectedErrors, len(agg.Errors())) 404 } 405 case err == nil && test.expectedErrors != 0: 406 t.Errorf("error SharedCertificateExists didn't fail when expected") 407 case ret != (err == nil): 408 t.Errorf("error SharedCertificateExists returned %v when expected to return %v", ret, err == nil) 409 } 410 }) 411 } 412 } 413 414 func TestCreatePKIAssetsWithSparseCerts(t *testing.T) { 415 for _, test := range certstestutil.GetSparseCertTestCases(t) { 416 t.Run(test.Name, func(t *testing.T) { 417 pkiutiltesting.Reset() 418 419 tmpdir := testutil.SetupTempDir(t) 420 defer os.RemoveAll(tmpdir) 421 422 cfg := testutil.GetDefaultInternalConfig(t) 423 cfg.ClusterConfiguration.CertificatesDir = tmpdir 424 425 certstestutil.WritePKIFiles(t, tmpdir, test.Files) 426 427 err := CreatePKIAssets(cfg) 428 if err != nil { 429 if test.ExpectError { 430 return 431 } 432 t.Fatalf("Unexpected error: %v", err) 433 } 434 if test.ExpectError { 435 t.Fatal("Expected error from CreatePKIAssets, got none") 436 } 437 assertCertsExist(t, tmpdir) 438 }) 439 } 440 441 } 442 443 func TestUsingExternalCA(t *testing.T) { 444 tests := []struct { 445 name string 446 setupFuncs []func(cfg *kubeadmapi.InitConfiguration) error 447 externalCAFunc func(*kubeadmapi.ClusterConfiguration) (bool, error) 448 expected bool 449 expectedErr bool 450 }{ 451 { 452 name: "Test External CA, when complete PKI exists", 453 setupFuncs: []func(cfg *kubeadmapi.InitConfiguration) error{ 454 CreatePKIAssets, 455 }, 456 externalCAFunc: UsingExternalCA, 457 expected: false, 458 }, 459 { 460 name: "Test External CA, when ca.key missing", 461 setupFuncs: []func(cfg *kubeadmapi.InitConfiguration) error{ 462 CreatePKIAssets, 463 deleteCertOrKey(kubeadmconstants.CAKeyName), 464 }, 465 externalCAFunc: UsingExternalCA, 466 expected: true, 467 }, 468 { 469 name: "Test External CA, when ca.key missing and signed certs are missing", 470 setupFuncs: []func(cfg *kubeadmapi.InitConfiguration) error{ 471 CreatePKIAssets, 472 deleteCertOrKey(kubeadmconstants.CAKeyName), 473 deleteCertOrKey(kubeadmconstants.APIServerCertName), 474 }, 475 externalCAFunc: UsingExternalCA, 476 expected: true, 477 expectedErr: true, 478 }, 479 { 480 name: "Test External CA, when ca.key missing", 481 setupFuncs: []func(cfg *kubeadmapi.InitConfiguration) error{ 482 CreatePKIAssets, 483 deleteCertOrKey(kubeadmconstants.CAKeyName), 484 }, 485 externalCAFunc: UsingExternalCA, 486 expected: true, 487 }, 488 { 489 name: "Test External Front Proxy CA, when complete PKI exists", 490 setupFuncs: []func(cfg *kubeadmapi.InitConfiguration) error{ 491 CreatePKIAssets, 492 }, 493 externalCAFunc: UsingExternalFrontProxyCA, 494 expected: false, 495 }, 496 { 497 name: "Test External Front Proxy CA, when front-proxy-ca.key missing", 498 setupFuncs: []func(cfg *kubeadmapi.InitConfiguration) error{ 499 CreatePKIAssets, 500 deleteCertOrKey(kubeadmconstants.FrontProxyCAKeyName), 501 }, 502 externalCAFunc: UsingExternalFrontProxyCA, 503 expected: true, 504 }, 505 { 506 name: "Test External Front Proxy CA, when front-proxy-.key missing and signed certs are missing", 507 setupFuncs: []func(cfg *kubeadmapi.InitConfiguration) error{ 508 CreatePKIAssets, 509 deleteCertOrKey(kubeadmconstants.FrontProxyCAKeyName), 510 deleteCertOrKey(kubeadmconstants.FrontProxyClientCertName), 511 }, 512 externalCAFunc: UsingExternalFrontProxyCA, 513 expected: true, 514 expectedErr: true, 515 }, 516 } 517 518 for _, test := range tests { 519 t.Run(test.name, func(t *testing.T) { 520 pkiutiltesting.Reset() 521 522 dir := testutil.SetupTempDir(t) 523 defer os.RemoveAll(dir) 524 525 cfg := &kubeadmapi.InitConfiguration{ 526 LocalAPIEndpoint: kubeadmapi.APIEndpoint{AdvertiseAddress: "1.2.3.4"}, 527 ClusterConfiguration: kubeadmapi.ClusterConfiguration{ 528 Networking: kubeadmapi.Networking{ServiceSubnet: "10.96.0.0/12", DNSDomain: "cluster.local"}, 529 CertificatesDir: dir, 530 }, 531 NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-hostname"}, 532 } 533 534 for _, f := range test.setupFuncs { 535 if err := f(cfg); err != nil { 536 t.Errorf("error executing setup function: %v", err) 537 } 538 } 539 540 val, err := test.externalCAFunc(&cfg.ClusterConfiguration) 541 if val != test.expected { 542 t.Errorf("UsingExternalCA did not match expected: %v", test.expected) 543 } 544 545 if (err != nil) != test.expectedErr { 546 t.Errorf("UsingExternalCA returned un expected err: %v", err) 547 } 548 }) 549 } 550 } 551 552 func TestValidateMethods(t *testing.T) { 553 554 caCert, caKey := certstestutil.CreateCACert(t) 555 cert, key, _ := certstestutil.CreateTestCert(t, caCert, caKey, certutil.AltNames{}) 556 557 tests := []struct { 558 name string 559 files certstestutil.PKIFiles 560 validateFunc func(l certKeyLocation) error 561 loc certKeyLocation 562 expectedSuccess bool 563 }{ 564 { 565 name: "validateCACert", 566 files: certstestutil.PKIFiles{ 567 "ca.crt": caCert, 568 }, 569 validateFunc: validateCACert, 570 loc: certKeyLocation{caBaseName: "ca", baseName: "", uxName: "CA"}, 571 expectedSuccess: true, 572 }, 573 { 574 name: "validateCACertAndKey (files present)", 575 files: certstestutil.PKIFiles{ 576 "ca.crt": caCert, 577 "ca.key": caKey, 578 }, 579 validateFunc: validateCACertAndKey, 580 loc: certKeyLocation{caBaseName: "ca", baseName: "", uxName: "CA"}, 581 expectedSuccess: true, 582 }, 583 { 584 files: certstestutil.PKIFiles{ 585 "ca.crt": caCert, 586 }, 587 name: "validateCACertAndKey (key missing)", 588 validateFunc: validateCACertAndKey, 589 loc: certKeyLocation{caBaseName: "ca", baseName: "", uxName: "CA"}, 590 expectedSuccess: true, 591 }, 592 { 593 name: "validateSignedCert", 594 files: certstestutil.PKIFiles{ 595 "ca.crt": caCert, 596 "ca.key": caKey, 597 "apiserver.crt": cert, 598 "apiserver.key": key, 599 }, 600 validateFunc: validateSignedCert, 601 loc: certKeyLocation{caBaseName: "ca", baseName: "apiserver", uxName: "apiserver"}, 602 expectedSuccess: true, 603 }, 604 { 605 name: "validatePrivatePublicKey", 606 files: certstestutil.PKIFiles{ 607 "sa.pub": key.Public(), 608 "sa.key": key, 609 }, 610 validateFunc: validatePrivatePublicKey, 611 loc: certKeyLocation{baseName: "sa", uxName: "service account"}, 612 expectedSuccess: true, 613 }, 614 { 615 name: "validatePrivatePublicKey (missing key)", 616 files: certstestutil.PKIFiles{ 617 "sa.pub": key.Public(), 618 }, 619 validateFunc: validatePrivatePublicKey, 620 loc: certKeyLocation{baseName: "sa", uxName: "service account"}, 621 expectedSuccess: false, 622 }, 623 } 624 625 for _, test := range tests { 626 dir := testutil.SetupTempDir(t) 627 defer os.RemoveAll(dir) 628 test.loc.pkiDir = dir 629 630 certstestutil.WritePKIFiles(t, dir, test.files) 631 632 err := test.validateFunc(test.loc) 633 if test.expectedSuccess && err != nil { 634 t.Errorf("expected success, error executing validateFunc: %v, %v", test.name, err) 635 } else if !test.expectedSuccess && err == nil { 636 t.Errorf("expected failure, no error executing validateFunc: %v", test.name) 637 } 638 } 639 } 640 641 func TestNewCSR(t *testing.T) { 642 kubeadmCert := KubeadmCertAPIServer() 643 cfg := testutil.GetDefaultInternalConfig(t) 644 645 certConfig, err := kubeadmCert.GetConfig(cfg) 646 if err != nil { 647 t.Fatalf("couldn't get cert config: %v", err) 648 } 649 650 csr, _, err := NewCSR(kubeadmCert, cfg) 651 652 if err != nil { 653 t.Errorf("invalid signature on CSR: %v", err) 654 } 655 656 assert.ElementsMatch(t, certConfig.Organization, csr.Subject.Organization, "organizations not equal") 657 658 if csr.Subject.CommonName != certConfig.CommonName { 659 t.Errorf("expected common name %q, got %q", certConfig.CommonName, csr.Subject.CommonName) 660 } 661 662 assert.ElementsMatch(t, certConfig.AltNames.DNSNames, csr.DNSNames, "dns names not equal") 663 664 assert.Len(t, csr.IPAddresses, len(certConfig.AltNames.IPs)) 665 666 for i, ip := range csr.IPAddresses { 667 if !ip.Equal(certConfig.AltNames.IPs[i]) { 668 t.Errorf("[%d]: %v != %v", i, ip, certConfig.AltNames.IPs[i]) 669 } 670 } 671 } 672 673 func TestCreateCertificateFilesMethods(t *testing.T) { 674 675 var tests = []struct { 676 createFunc func(cfg *kubeadmapi.InitConfiguration) error 677 expectedFiles []string 678 externalEtcd bool 679 }{ 680 { 681 createFunc: CreatePKIAssets, 682 expectedFiles: []string{ 683 kubeadmconstants.CACertName, kubeadmconstants.CAKeyName, 684 kubeadmconstants.APIServerCertName, kubeadmconstants.APIServerKeyName, 685 kubeadmconstants.APIServerKubeletClientCertName, kubeadmconstants.APIServerKubeletClientKeyName, 686 kubeadmconstants.EtcdCACertName, kubeadmconstants.EtcdCAKeyName, 687 kubeadmconstants.EtcdServerCertName, kubeadmconstants.EtcdServerKeyName, 688 kubeadmconstants.EtcdPeerCertName, kubeadmconstants.EtcdPeerKeyName, 689 kubeadmconstants.EtcdHealthcheckClientCertName, kubeadmconstants.EtcdHealthcheckClientKeyName, 690 kubeadmconstants.APIServerEtcdClientCertName, kubeadmconstants.APIServerEtcdClientKeyName, 691 kubeadmconstants.ServiceAccountPrivateKeyName, kubeadmconstants.ServiceAccountPublicKeyName, 692 kubeadmconstants.FrontProxyCACertName, kubeadmconstants.FrontProxyCAKeyName, 693 kubeadmconstants.FrontProxyClientCertName, kubeadmconstants.FrontProxyClientKeyName, 694 }, 695 }, 696 { 697 createFunc: CreatePKIAssets, 698 externalEtcd: true, 699 expectedFiles: []string{ 700 kubeadmconstants.CACertName, kubeadmconstants.CAKeyName, 701 kubeadmconstants.APIServerCertName, kubeadmconstants.APIServerKeyName, 702 kubeadmconstants.APIServerKubeletClientCertName, kubeadmconstants.APIServerKubeletClientKeyName, 703 kubeadmconstants.ServiceAccountPrivateKeyName, kubeadmconstants.ServiceAccountPublicKeyName, 704 kubeadmconstants.FrontProxyCACertName, kubeadmconstants.FrontProxyCAKeyName, 705 kubeadmconstants.FrontProxyClientCertName, kubeadmconstants.FrontProxyClientKeyName, 706 }, 707 }, 708 } 709 710 for _, test := range tests { 711 pkiutiltesting.Reset() 712 713 // Create temp folder for the test case 714 tmpdir := testutil.SetupTempDir(t) 715 defer os.RemoveAll(tmpdir) 716 717 cfg := &kubeadmapi.InitConfiguration{ 718 LocalAPIEndpoint: kubeadmapi.APIEndpoint{AdvertiseAddress: "1.2.3.4"}, 719 ClusterConfiguration: kubeadmapi.ClusterConfiguration{ 720 Etcd: kubeadmapi.Etcd{Local: &kubeadmapi.LocalEtcd{}}, 721 Networking: kubeadmapi.Networking{ServiceSubnet: "10.96.0.0/12", DNSDomain: "cluster.local"}, 722 CertificatesDir: tmpdir, 723 }, 724 NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-hostname"}, 725 } 726 727 if test.externalEtcd { 728 if cfg.Etcd.External == nil { 729 cfg.Etcd.External = &kubeadmapi.ExternalEtcd{} 730 } 731 cfg.Etcd.Local = nil 732 cfg.Etcd.External.Endpoints = []string{"192.168.1.1:2379"} 733 } 734 735 // executes create func 736 if err := test.createFunc(cfg); err != nil { 737 t.Errorf("error executing createFunc: %v", err) 738 continue 739 } 740 741 // asserts expected files are there 742 testutil.AssertFileExists(t, tmpdir, test.expectedFiles...) 743 } 744 } 745 746 func deleteCertOrKey(name string) func(*kubeadmapi.InitConfiguration) error { 747 return func(cfg *kubeadmapi.InitConfiguration) error { 748 if err := os.Remove(filepath.Join(cfg.CertificatesDir, name)); err != nil { 749 return errors.Wrapf(err, "failed removing %s", name) 750 } 751 return nil 752 } 753 } 754 755 func assertCertsExist(t *testing.T, dir string) { 756 tree, err := GetDefaultCertList().AsMap().CertTree() 757 if err != nil { 758 t.Fatalf("unexpected error getting certificates: %v", err) 759 } 760 761 for caCert, certs := range tree { 762 if err := validateCACert(certKeyLocation{dir, caCert.BaseName, "", caCert.Name}); err != nil { 763 t.Errorf("couldn't validate CA certificate %v: %v", caCert.Name, err) 764 // Don't bother validating child certs, but do try the other CAs 765 continue 766 } 767 768 for _, cert := range certs { 769 if err := validateSignedCert(certKeyLocation{dir, caCert.BaseName, cert.BaseName, cert.Name}); err != nil { 770 t.Errorf("couldn't validate certificate %v: %v", cert.Name, err) 771 } 772 } 773 } 774 }