diff --git a/cmd/kubeadm/app/cmd/phases/init/certs.go b/cmd/kubeadm/app/cmd/phases/init/certs.go index 19f99d69c29..7f2c0951d10 100644 --- a/cmd/kubeadm/app/cmd/phases/init/certs.go +++ b/cmd/kubeadm/app/cmd/phases/init/certs.go @@ -86,17 +86,19 @@ func newCertSubPhases() []workflow.Phase { subPhases = append(subPhases, allPhase) - certTree, _ := certsphase.GetDefaultCertList().AsMap().CertTree() - - for ca, certList := range certTree { - caPhase := newCertSubPhase(ca, runCAPhase(ca)) - subPhases = append(subPhases, caPhase) - - for _, cert := range certList { - certPhase := newCertSubPhase(cert, runCertPhase(cert, ca)) - certPhase.LocalFlags = localFlags() - subPhases = append(subPhases, certPhase) + // This loop assumes that GetDefaultCertList() always returns a list of + // certificate that is preceded by the CAs that sign them. + var lastCACert *certsphase.KubeadmCert + for _, cert := range certsphase.GetDefaultCertList() { + var phase workflow.Phase + if cert.CAName == "" { + phase = newCertSubPhase(cert, runCAPhase(cert)) + lastCACert = cert + } else { + phase = newCertSubPhase(cert, runCertPhase(cert, lastCACert)) + phase.LocalFlags = localFlags() } + subPhases = append(subPhases, phase) } // SA creates the private/public key pair, which doesn't use x509 at all diff --git a/cmd/kubeadm/app/phases/certs/certlist_test.go b/cmd/kubeadm/app/phases/certs/certlist_test.go index 2392dc271b3..345c589cb03 100644 --- a/cmd/kubeadm/app/phases/certs/certlist_test.go +++ b/cmd/kubeadm/app/phases/certs/certlist_test.go @@ -29,6 +29,40 @@ import ( kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" ) +func TestCertListOrder(t *testing.T) { + tests := []struct { + certs Certificates + name string + }{ + { + name: "Default Certificate List", + certs: GetDefaultCertList(), + }, + { + name: "Cert list less etcd", + certs: GetCertsWithoutEtcd(), + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + var lastCA *KubeadmCert + for i, cert := range test.certs { + if i > 0 && lastCA == nil { + t.Fatalf("CA not present in list before certificate %q", cert.Name) + } + if cert.CAName == "" { + lastCA = cert + } else { + if cert.CAName != lastCA.Name { + t.Fatalf("expected CA name %q, got %q, for certificate %q", lastCA.Name, cert.CAName, cert.Name) + } + } + } + }) + } +} + func TestCAPointersValid(t *testing.T) { tests := []struct { certs Certificates