Commit cc90d34f authored by Kubernetes Submit Queue's avatar Kubernetes Submit Queue Committed by GitHub

Merge pull request #50691 from fabriziopandini/kubeadm-phases-certs3

Automatic merge from submit-queue (batch tested with PRs 50904, 50691) Make Kubeadm phase certs codebase consistent with other phases **What this PR does / why we need it:** This PR is a refactoring of [#48196](https://github.com/kubernetes/kubernetes/pull/48196), that makes this part of kubeadm more consistent with other parts of kubeadm recently changed, e.g. [controlplane & etcd phase #50302](https://github.com/kubernetes/kubernetes/pull/50302) and [kubeconfig phase #49419](https://github.com/kubernetes/kubernetes/pull/49419) **Which issue this PR fixes:** none **Special notes for your reviewer:** cc @luxas
parents 26eb7c94 c6bb8fbb
......@@ -30,6 +30,7 @@ go_library(
"//cmd/kubeadm/app/phases/apiconfig:go_default_library",
"//cmd/kubeadm/app/phases/bootstraptoken/clusterinfo:go_default_library",
"//cmd/kubeadm/app/phases/bootstraptoken/node:go_default_library",
"//cmd/kubeadm/app/phases/certs:go_default_library",
"//cmd/kubeadm/app/phases/certs/pkiutil:go_default_library",
"//cmd/kubeadm/app/phases/controlplane:go_default_library",
"//cmd/kubeadm/app/phases/etcd:go_default_library",
......
......@@ -31,13 +31,13 @@ import (
kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1"
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation"
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/features"
cmdphases "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases"
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
dnsaddonphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/dns"
proxyaddonphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/addons/proxy"
apiconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/apiconfig"
clusterinfophase "k8s.io/kubernetes/cmd/kubeadm/app/phases/bootstraptoken/clusterinfo"
nodebootstraptokenphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/bootstraptoken/node"
certsphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs"
"k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/pkiutil"
controlplanephase "k8s.io/kubernetes/cmd/kubeadm/app/phases/controlplane"
etcdphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/etcd"
......@@ -234,7 +234,7 @@ func (i *Init) Run(out io.Writer) error {
}
// PHASE 1: Generate certificates
if err := cmdphases.CreatePKIAssets(i.cfg); err != nil {
if err := certsphase.CreatePKIAssets(i.cfg); err != nil {
return err
}
......
......@@ -29,7 +29,6 @@ go_library(
"//cmd/kubeadm/app/phases/bootstraptoken/clusterinfo:go_default_library",
"//cmd/kubeadm/app/phases/bootstraptoken/node:go_default_library",
"//cmd/kubeadm/app/phases/certs:go_default_library",
"//cmd/kubeadm/app/phases/certs/pkiutil:go_default_library",
"//cmd/kubeadm/app/phases/controlplane:go_default_library",
"//cmd/kubeadm/app/phases/etcd:go_default_library",
"//cmd/kubeadm/app/phases/kubeconfig:go_default_library",
......
......@@ -33,7 +33,61 @@ import (
cmdtestutil "k8s.io/kubernetes/cmd/kubeadm/test/cmd"
)
func TestSubCmdCertsCreateFiles(t *testing.T) {
func TestCertsSubCommandsHasFlags(t *testing.T) {
subCmds := getCertsSubCommands()
commonFlags := []string{
"cert-dir",
"config",
}
var tests = []struct {
command string
additionalFlags []string
}{
{
command: "all",
additionalFlags: []string{
"apiserver-advertise-address",
"apiserver-cert-extra-sans",
"service-cidr",
"service-dns-domain",
},
},
{
command: "ca",
},
{
command: "apiserver",
additionalFlags: []string{
"apiserver-advertise-address",
"apiserver-cert-extra-sans",
"service-cidr",
"service-dns-domain",
},
},
{
command: "apiserver-kubelet-client",
},
{
command: "sa",
},
{
command: "front-proxy-ca",
},
{
command: "front-proxy-client",
},
}
for _, test := range tests {
expectedFlags := append(commonFlags, test.additionalFlags...)
cmdtestutil.AssertSubCommandHasFlags(t, subCmds, test.command, expectedFlags...)
}
}
func TestSubCmdCertsCreateFilesWithFlags(t *testing.T) {
subCmds := getCertsSubCommands()
......@@ -53,26 +107,14 @@ func TestSubCmdCertsCreateFiles(t *testing.T) {
},
},
{
subCmds: []string{"ca"},
expectedFiles: []string{kubeadmconstants.CACertName, kubeadmconstants.CAKeyName},
},
{
subCmds: []string{"ca", "apiserver"},
expectedFiles: []string{kubeadmconstants.CACertName, kubeadmconstants.CAKeyName, kubeadmconstants.APIServerCertName, kubeadmconstants.APIServerKeyName},
},
{
subCmds: []string{"ca", "apiserver-kubelet-client"},
expectedFiles: []string{kubeadmconstants.CACertName, kubeadmconstants.CAKeyName, kubeadmconstants.APIServerKubeletClientCertName, kubeadmconstants.APIServerKubeletClientKeyName},
subCmds: []string{"ca", "apiserver", "apiserver-kubelet-client"},
expectedFiles: []string{kubeadmconstants.CACertName, kubeadmconstants.CAKeyName, kubeadmconstants.APIServerCertName, kubeadmconstants.APIServerKeyName, kubeadmconstants.APIServerKubeletClientCertName, kubeadmconstants.APIServerKubeletClientKeyName},
},
{
subCmds: []string{"sa"},
expectedFiles: []string{kubeadmconstants.ServiceAccountPrivateKeyName, kubeadmconstants.ServiceAccountPublicKeyName},
},
{
subCmds: []string{"front-proxy-ca"},
expectedFiles: []string{kubeadmconstants.FrontProxyCACertName, kubeadmconstants.FrontProxyCAKeyName},
},
{
subCmds: []string{"front-proxy-ca", "front-proxy-client"},
expectedFiles: []string{kubeadmconstants.FrontProxyCACertName, kubeadmconstants.FrontProxyCAKeyName, kubeadmconstants.FrontProxyClientCertName, kubeadmconstants.FrontProxyClientKeyName},
},
......@@ -94,7 +136,7 @@ func TestSubCmdCertsCreateFiles(t *testing.T) {
}
}
func TestSubCmdApiServerFlags(t *testing.T) {
func TestSubCmdCertsApiServerForwardsFlags(t *testing.T) {
subCmds := getCertsSubCommands()
......@@ -116,6 +158,7 @@ func TestSubCmdApiServerFlags(t *testing.T) {
}
cmdtestutil.RunSubCommand(t, subCmds, "apiserver", apiserverFlags...)
// asserts created cert has values from CLI flags
APIserverCert, err := pkiutil.TryLoadCertFromDisk(tmpdir, kubeadmconstants.APIServerCertAndKeyBaseName)
if err != nil {
t.Fatalf("Error loading API server certificate: %v", err)
......@@ -135,29 +178,36 @@ func TestSubCmdApiServerFlags(t *testing.T) {
}
}
func TestSubCmdCertsReadsConfig(t *testing.T) {
func TestSubCmdCertsCreateFilesWithConfigFile(t *testing.T) {
subCmds := getCertsSubCommands()
var tests = []struct {
subCmds []string
expectedFileCount int
subCmds []string
expectedFiles []string
}{
{
subCmds: []string{"sa"},
expectedFileCount: 2,
subCmds: []string{"all"},
expectedFiles: []string{
kubeadmconstants.CACertName, kubeadmconstants.CAKeyName,
kubeadmconstants.APIServerCertName, kubeadmconstants.APIServerKeyName,
kubeadmconstants.APIServerKubeletClientCertName, kubeadmconstants.APIServerKubeletClientKeyName,
kubeadmconstants.ServiceAccountPrivateKeyName, kubeadmconstants.ServiceAccountPublicKeyName,
kubeadmconstants.FrontProxyCACertName, kubeadmconstants.FrontProxyCAKeyName,
kubeadmconstants.FrontProxyClientCertName, kubeadmconstants.FrontProxyClientKeyName,
},
},
{
subCmds: []string{"front-proxy-ca", "front-proxy-client"},
expectedFileCount: 4,
subCmds: []string{"ca", "apiserver", "apiserver-kubelet-client"},
expectedFiles: []string{kubeadmconstants.CACertName, kubeadmconstants.CAKeyName, kubeadmconstants.APIServerCertName, kubeadmconstants.APIServerKeyName, kubeadmconstants.APIServerKubeletClientCertName, kubeadmconstants.APIServerKubeletClientKeyName},
},
{
subCmds: []string{"ca", "apiserver", "apiserver-kubelet-client"},
expectedFileCount: 6,
subCmds: []string{"front-proxy-ca", "front-proxy-client"},
expectedFiles: []string{kubeadmconstants.FrontProxyCACertName, kubeadmconstants.FrontProxyCAKeyName, kubeadmconstants.FrontProxyClientCertName, kubeadmconstants.FrontProxyClientKeyName},
},
{
subCmds: []string{"all"},
expectedFileCount: 12,
subCmds: []string{"sa"},
expectedFiles: []string{kubeadmconstants.ServiceAccountPrivateKeyName, kubeadmconstants.ServiceAccountPublicKeyName},
},
}
......@@ -182,6 +232,6 @@ func TestSubCmdCertsReadsConfig(t *testing.T) {
}
// verify expected files are there
testutil.AssertFilesCount(t, tmpdir, test.expectedFileCount)
testutil.AssertFileExists(t, tmpdir, test.expectedFiles...)
}
}
......@@ -13,6 +13,9 @@ go_test(
deps = [
"//cmd/kubeadm/app/apis/kubeadm:go_default_library",
"//cmd/kubeadm/app/constants:go_default_library",
"//cmd/kubeadm/app/phases/certs/pkiutil:go_default_library",
"//cmd/kubeadm/test:go_default_library",
"//cmd/kubeadm/test/certs:go_default_library",
],
)
......@@ -27,7 +30,7 @@ go_library(
"//cmd/kubeadm/app/constants:go_default_library",
"//cmd/kubeadm/app/phases/certs/pkiutil:go_default_library",
"//pkg/registry/core/service/ipallocator:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/validation:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/validation:go_default_library",
"//vendor/k8s.io/client-go/util/cert:go_default_library",
],
)
......
......@@ -19,6 +19,7 @@ package certs
import (
"crypto/rsa"
"crypto/x509"
"net"
"testing"
"k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/pkiutil"
......@@ -35,6 +36,13 @@ func SetupCertificateAuthorithy(t *testing.T) (*x509.Certificate, *rsa.PrivateKe
return caCert, caKey
}
// AssertCertificateIsCa is a utility function for kubeadm testing that asserts if a given certificate is a CA
func AssertCertificateIsCa(t *testing.T, cert *x509.Certificate) {
if !cert.IsCA {
t.Error("cert is not a valida CA")
}
}
// AssertCertificateIsSignedByCa is a utility function for kubeadm testing that asserts if a given certificate is signed
// by the expected CA
func AssertCertificateIsSignedByCa(t *testing.T, cert *x509.Certificate, signingCa *x509.Certificate) {
......@@ -77,3 +85,50 @@ func AssertCertificateHasClientAuthUsage(t *testing.T, cert *x509.Certificate) {
}
t.Error("cert has not ClientAuth usage as expected")
}
// AssertCertificateHasServerAuthUsage is a utility function for kubeadm testing that asserts if a given certificate has
// the expected ExtKeyUsageServerAuth
func AssertCertificateHasServerAuthUsage(t *testing.T, cert *x509.Certificate) {
for i := range cert.ExtKeyUsage {
if cert.ExtKeyUsage[i] == x509.ExtKeyUsageServerAuth {
return
}
}
t.Error("cert is not a ServerAuth")
}
// AssertCertificateHasDNSNames is a utility function for kubeadm testing that asserts if a given certificate has
// the expected DNSNames
func AssertCertificateHasDNSNames(t *testing.T, cert *x509.Certificate, DNSNames ...string) {
for _, DNSName := range DNSNames {
found := false
for _, val := range cert.DNSNames {
if val == DNSName {
found = true
break
}
}
if !found {
t.Errorf("cert does not contain DNSName %s", DNSName)
}
}
}
// AssertCertificateHasIPAddresses is a utility function for kubeadm testing that asserts if a given certificate has
// the expected IPAddresses
func AssertCertificateHasIPAddresses(t *testing.T, cert *x509.Certificate, IPAddresses ...net.IP) {
for _, IPAddress := range IPAddresses {
found := false
for _, val := range cert.IPAddresses {
if val.Equal(IPAddress) {
found = true
break
}
}
if !found {
t.Errorf("cert does not contain IPAddress %s", IPAddress)
}
}
}
......@@ -76,6 +76,17 @@ func SetupMasterConfigurationFile(t *testing.T, tmpdir string, cfg *kubeadmapi.M
return cfgPath
}
// SetupEmptyFiles is a utility function for kubeadm testing that creates one or more empty files (touch)
func SetupEmptyFiles(t *testing.T, tmpdir string, fileNames ...string) {
for _, fileName := range fileNames {
newFile, err := os.Create(filepath.Join(tmpdir, fileName))
if err != nil {
t.Fatalf("Error creating file %s in %s: %v", fileName, tmpdir, err)
}
newFile.Close()
}
}
// SetupPkiDirWithCertificateAuthorithy is a utility function for kubeadm testing that creates a
// CertificateAuthorithy cert/key pair into /pki subfolder of a given temporary directory.
// The funtion returns the path of the created pki.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment