Merge pull request #70331 from ereslibre/graduate-certs

kubeadm: Graduate certs phase
pull/58/head
k8s-ci-robot 2018-10-29 14:38:43 -07:00 committed by GitHub
commit 8c6fbd708c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 121 additions and 425 deletions

View File

@ -166,6 +166,7 @@ func NewCmdInit(out io.Writer) *cobra.Command {
// initialize the workflow runner with the list of phases // initialize the workflow runner with the list of phases
initRunner.AppendPhase(phases.NewPreflightMasterPhase()) initRunner.AppendPhase(phases.NewPreflightMasterPhase())
initRunner.AppendPhase(phases.NewCertsPhase())
initRunner.AppendPhase(phases.NewKubeletStartPhase()) initRunner.AppendPhase(phases.NewKubeletStartPhase())
// TODO: add other phases to the runner. // TODO: add other phases to the runner.
@ -427,12 +428,6 @@ func runInit(i *initData, out io.Writer) error {
if res, _ := certsphase.UsingExternalCA(i.cfg); !res { if res, _ := certsphase.UsingExternalCA(i.cfg); !res {
// PHASE 1: Generate certificates
glog.V(1).Infof("[init] creating PKI Assets")
if err := certsphase.CreatePKIAssets(i.cfg); err != nil {
return err
}
// PHASE 2: Generate kubeconfig files for the admin and the kubelet // PHASE 2: Generate kubeconfig files for the admin and the kubelet
glog.V(2).Infof("[init] generating kubeconfig files") glog.V(2).Infof("[init] generating kubeconfig files")
if err := kubeconfigphase.CreateInitKubeConfigFiles(kubeConfigDir, i.cfg); err != nil { if err := kubeconfigphase.CreateInitKubeConfigFiles(kubeConfigDir, i.cfg); err != nil {

View File

@ -68,7 +68,6 @@ go_test(
name = "go_default_test", name = "go_default_test",
srcs = [ srcs = [
"addons_test.go", "addons_test.go",
"certs_test.go",
"controlplane_test.go", "controlplane_test.go",
"etcd_test.go", "etcd_test.go",
"kubeconfig_test.go", "kubeconfig_test.go",
@ -84,7 +83,6 @@ go_test(
"//cmd/kubeadm/test:go_default_library", "//cmd/kubeadm/test:go_default_library",
"//cmd/kubeadm/test/cmd:go_default_library", "//cmd/kubeadm/test/cmd:go_default_library",
"//cmd/kubeadm/test/kubeconfig:go_default_library", "//cmd/kubeadm/test/kubeconfig:go_default_library",
"//pkg/util/node:go_default_library",
"//pkg/version:go_default_library", "//pkg/version:go_default_library",
"//staging/src/k8s.io/client-go/tools/clientcmd:go_default_library", "//staging/src/k8s.io/client-go/tools/clientcmd:go_default_library",
"//vendor/github.com/spf13/cobra:go_default_library", "//vendor/github.com/spf13/cobra:go_default_library",

View File

@ -20,18 +20,18 @@ import (
"fmt" "fmt"
"strings" "strings"
"github.com/pkg/errors"
"github.com/spf13/cobra" "github.com/spf13/cobra"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm" kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmscheme "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/scheme" kubeadmscheme "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/scheme"
kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1" kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1"
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/options"
certscmdphase "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/certs" certscmdphase "k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/certs"
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/phases/workflow"
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util" cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants" kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
certsphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs" certsphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs"
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config"
"k8s.io/kubernetes/pkg/util/normalizer" "k8s.io/kubernetes/pkg/util/normalizer"
) )
@ -66,6 +66,24 @@ var (
` + cmdutil.AlphaDisclaimer) ` + cmdutil.AlphaDisclaimer)
) )
// certsData defines the behavior that a runtime data struct passed to the certs phase should
// have. Please note that we are using an interface in order to make this phase reusable in different workflows
// (and thus with different runtime data struct, all of them requested to be compliant to this interface)
type certsData interface {
Cfg() *kubeadmapi.InitConfiguration
CertificateDir() string
CertificateWriteDir() string
}
// NewCertsPhase returns the phase for the certs
func NewCertsPhase() workflow.Phase {
return workflow.Phase{
Name: "certs",
Short: "Certificate generation",
Phases: getCertsSubPhases(),
}
}
// NewCmdCerts returns main command for certs phase // NewCmdCerts returns main command for certs phase
func NewCmdCerts() *cobra.Command { func NewCmdCerts() *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
@ -75,72 +93,62 @@ func NewCmdCerts() *cobra.Command {
Long: cmdutil.MacroCommandLongDescription, Long: cmdutil.MacroCommandLongDescription,
} }
cmd.AddCommand(getCertsSubCommands("")...) cmd.AddCommand(getCertsSubCommands()...)
return cmd return cmd
} }
// getCertsSubCommands returns sub commands for certs phase // getCertsSubCommands returns sub commands for certs phase
func getCertsSubCommands(defaultKubernetesVersion string) []*cobra.Command { func getCertsSubCommands() []*cobra.Command {
return []*cobra.Command{certscmdphase.NewCmdCertsRenewal()}
cfg := &kubeadmapiv1beta1.InitConfiguration{}
// Default values for the cobra help text
kubeadmscheme.Scheme.Default(cfg)
var cfgPath string
// Special case commands
// All runs CreatePKIAssets, which isn't a particular certificate
allCmd := &cobra.Command{
Use: "all",
Short: "Generates all PKI assets necessary to establish the control plane",
Long: allCertsLongDesc,
Example: allCertsExample,
Run: func(cmd *cobra.Command, args []string) {
internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(cfgPath, cfg)
kubeadmutil.CheckErr(err)
err = certsphase.CreatePKIAssets(internalcfg)
kubeadmutil.CheckErr(err)
},
}
addFlags(allCmd, &cfgPath, cfg, true)
// SA creates the private/public key pair, which doesn't use x509 at all
saCmd := &cobra.Command{
Use: "sa",
Short: "Generates a private key for signing service account tokens along with its public key",
Long: saKeyLongDesc,
Run: func(cmd *cobra.Command, args []string) {
internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(cfgPath, cfg)
kubeadmutil.CheckErr(err)
err = certsphase.CreateServiceAccountKeyAndPublicKeyFiles(internalcfg)
kubeadmutil.CheckErr(err)
},
}
addFlags(saCmd, &cfgPath, cfg, false)
// "renew" command
renewCmd := certscmdphase.NewCmdCertsRenewal()
subCmds := []*cobra.Command{allCmd, saCmd, renewCmd}
certTree, err := certsphase.GetDefaultCertList().AsMap().CertTree()
kubeadmutil.CheckErr(err)
for ca, certList := range certTree {
// Don't use pointers from for loops, they will be rewrittenb
caCmds := makeCommandsForCA(ca, certList, &cfgPath, cfg)
subCmds = append(subCmds, caCmds...)
}
return subCmds
} }
func makeCmd(certSpec *certsphase.KubeadmCert, cfgPath *string, cfg *kubeadmapiv1beta1.InitConfiguration) *cobra.Command { // getCertsSubPhases returns sub phases for certs phase
cmd := &cobra.Command{ func getCertsSubPhases() []workflow.Phase {
Use: certSpec.Name, subPhases := []workflow.Phase{}
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))
subPhases = append(subPhases, certPhase)
}
subPhases = append(subPhases, caPhase)
}
// SA creates the private/public key pair, which doesn't use x509 at all
saPhase := workflow.Phase{
Name: "sa",
Short: "Generates a private key for signing service account tokens along with its public key",
Long: saKeyLongDesc,
Run: runCertsSa,
}
subPhases = append(subPhases, saPhase)
return subPhases
}
func runCertsSa(c workflow.RunData) error {
data, ok := c.(certsData)
if !ok {
return errors.New("certs phase invoked with an invalid data struct")
}
cfg := data.Cfg()
cfg.CertificatesDir = data.CertificateWriteDir()
defer func() { cfg.CertificatesDir = data.CertificateDir() }()
return certsphase.CreateServiceAccountKeyAndPublicKeyFiles(cfg)
}
func newCertSubPhase(certSpec *certsphase.KubeadmCert, run func(c workflow.RunData) error) workflow.Phase {
phase := workflow.Phase{
Name: certSpec.Name,
Short: fmt.Sprintf("Generates the %s", certSpec.LongName), Short: fmt.Sprintf("Generates the %s", certSpec.LongName),
Long: fmt.Sprintf( Long: fmt.Sprintf(
genericLongDesc, genericLongDesc,
@ -148,10 +156,9 @@ func makeCmd(certSpec *certsphase.KubeadmCert, cfgPath *string, cfg *kubeadmapiv
certSpec.BaseName, certSpec.BaseName,
getSANDescription(certSpec), getSANDescription(certSpec),
), ),
Run: run,
} }
addFlags(cmd, cfgPath, cfg, certSpec.Name == "apiserver") return phase
// Add flags to the command
return cmd
} }
func getSANDescription(certSpec *certsphase.KubeadmCert) string { func getSANDescription(certSpec *certsphase.KubeadmCert) string {
@ -188,51 +195,32 @@ func getSANDescription(certSpec *certsphase.KubeadmCert) string {
return fmt.Sprintf("\n\nDefault SANs are %s", strings.Join(sans, ", ")) return fmt.Sprintf("\n\nDefault SANs are %s", strings.Join(sans, ", "))
} }
func addFlags(cmd *cobra.Command, cfgPath *string, cfg *kubeadmapiv1beta1.InitConfiguration, addAPIFlags bool) { func runCAPhase(ca *certsphase.KubeadmCert) func(c workflow.RunData) error {
options.AddCertificateDirFlag(cmd.Flags(), &cfg.CertificatesDir) return func(c workflow.RunData) error {
options.AddConfigFlag(cmd.Flags(), cfgPath) data, ok := c.(certsData)
if addAPIFlags { if !ok {
cmd.Flags().StringVar(&cfg.Networking.DNSDomain, "service-dns-domain", cfg.Networking.DNSDomain, "Alternative domain for services, to use for the API server serving cert") return errors.New("certs phase invoked with an invalid data struct")
cmd.Flags().StringVar(&cfg.Networking.ServiceSubnet, "service-cidr", cfg.Networking.ServiceSubnet, "Alternative range of IP address for service VIPs, from which derives the internal API server VIP that will be added to the API Server serving cert") }
cmd.Flags().StringSliceVar(&cfg.APIServerCertSANs, "apiserver-cert-extra-sans", []string{}, "Optional extra altnames to use for the API server serving cert. Can be both IP addresses and DNS names")
cmd.Flags().StringVar(&cfg.APIEndpoint.AdvertiseAddress, "apiserver-advertise-address", cfg.APIEndpoint.AdvertiseAddress, "The IP address the API server is accessible on, to use for the API server serving cert") cfg := data.Cfg()
cfg.CertificatesDir = data.CertificateWriteDir()
defer func() { cfg.CertificatesDir = data.CertificateDir() }()
return certsphase.CreateCACertAndKeyFiles(ca, cfg)
} }
} }
func makeCommandsForCA(ca *certsphase.KubeadmCert, certList []*certsphase.KubeadmCert, cfgPath *string, cfg *kubeadmapiv1beta1.InitConfiguration) []*cobra.Command { func runCertPhase(cert *certsphase.KubeadmCert, caCert *certsphase.KubeadmCert) func(c workflow.RunData) error {
subCmds := []*cobra.Command{} return func(c workflow.RunData) error {
data, ok := c.(certsData)
if !ok {
return errors.New("certs phase invoked with an invalid data struct")
}
caCmd := makeCmd(ca, cfgPath, cfg) cfg := data.Cfg()
caCmd.Run = func(cmd *cobra.Command, args []string) { cfg.CertificatesDir = data.CertificateWriteDir()
internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(*cfgPath, cfg) defer func() { cfg.CertificatesDir = data.CertificateDir() }()
kubeadmutil.CheckErr(err)
err = certsphase.CreateCACertAndKeyFiles(ca, internalcfg) return certsphase.CreateCertAndKeyFilesWithCA(cert, caCert, cfg)
kubeadmutil.CheckErr(err)
} }
subCmds = append(subCmds, caCmd)
for _, cert := range certList {
certCmd := makeCommandForCert(cert, ca, cfgPath, cfg)
subCmds = append(subCmds, certCmd)
}
return subCmds
}
func makeCommandForCert(cert *certsphase.KubeadmCert, caCert *certsphase.KubeadmCert, cfgPath *string, cfg *kubeadmapiv1beta1.InitConfiguration) *cobra.Command {
certCmd := makeCmd(cert, cfgPath, cfg)
certCmd.Run = func(cmd *cobra.Command, args []string) {
internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(*cfgPath, cfg)
kubeadmutil.CheckErr(err)
err = configutil.VerifyAPIServerBindAddress(internalcfg.APIEndpoint.AdvertiseAddress)
kubeadmutil.CheckErr(err)
err = certsphase.CreateCertAndKeyFilesWithCA(cert, caCert, internalcfg)
kubeadmutil.CheckErr(err)
}
return certCmd
} }

View File

@ -1,287 +0,0 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package phases
import (
"fmt"
"os"
"strings"
"testing"
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
"k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/pkiutil"
"k8s.io/kubernetes/pkg/util/node"
testutil "k8s.io/kubernetes/cmd/kubeadm/test"
cmdtestutil "k8s.io/kubernetes/cmd/kubeadm/test/cmd"
)
// phaseTestK8sVersion is a fake kubernetes version to use when testing
const phaseTestK8sVersion = "v1.11.0"
func TestCertsSubCommandsHasFlags(t *testing.T) {
subCmds := getCertsSubCommands(phaseTestK8sVersion)
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: "etcd-ca",
},
{
command: "etcd-server",
},
{
command: "etcd-peer",
},
{
command: "etcd-healthcheck-client",
},
{
command: "apiserver-etcd-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(phaseTestK8sVersion)
var tests = []struct {
subCmds []string
expectedFiles []string
}{
{
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{"ca", "apiserver", "apiserver-kubelet-client"},
expectedFiles: []string{kubeadmconstants.CACertName, kubeadmconstants.CAKeyName, kubeadmconstants.APIServerCertName, kubeadmconstants.APIServerKeyName, kubeadmconstants.APIServerKubeletClientCertName, kubeadmconstants.APIServerKubeletClientKeyName},
},
{
subCmds: []string{"etcd-ca", "etcd-server", "etcd-peer", "etcd-healthcheck-client", "apiserver-etcd-client"},
expectedFiles: []string{
kubeadmconstants.EtcdCACertName, kubeadmconstants.EtcdCAKeyName,
kubeadmconstants.EtcdServerCertName, kubeadmconstants.EtcdServerKeyName,
kubeadmconstants.EtcdPeerCertName, kubeadmconstants.EtcdPeerKeyName,
kubeadmconstants.EtcdHealthcheckClientCertName, kubeadmconstants.EtcdHealthcheckClientKeyName,
kubeadmconstants.APIServerEtcdClientCertName, kubeadmconstants.APIServerEtcdClientKeyName,
},
},
{
subCmds: []string{"sa"},
expectedFiles: []string{kubeadmconstants.ServiceAccountPrivateKeyName, kubeadmconstants.ServiceAccountPublicKeyName},
},
{
subCmds: []string{"front-proxy-ca", "front-proxy-client"},
expectedFiles: []string{kubeadmconstants.FrontProxyCACertName, kubeadmconstants.FrontProxyCAKeyName, kubeadmconstants.FrontProxyClientCertName, kubeadmconstants.FrontProxyClientKeyName},
},
}
for _, test := range tests {
t.Run(strings.Join(test.subCmds, ","), func(t *testing.T) {
// Create temp folder for the test case
tmpdir := testutil.SetupTempDir(t)
defer os.RemoveAll(tmpdir)
// executes given sub commands
for _, subCmdName := range test.subCmds {
fmt.Printf("running command %q\n", subCmdName)
certDirFlag := fmt.Sprintf("--cert-dir=%s", tmpdir)
cmdtestutil.RunSubCommand(t, subCmds, subCmdName, certDirFlag)
}
// verify expected files are there
testutil.AssertFileExists(t, tmpdir, test.expectedFiles...)
})
}
}
func TestSubCmdCertsApiServerForwardsFlags(t *testing.T) {
subCmds := getCertsSubCommands(phaseTestK8sVersion)
// Create temp folder for the test case
tmpdir := testutil.SetupTempDir(t)
defer os.RemoveAll(tmpdir)
// creates ca cert
certDirFlag := fmt.Sprintf("--cert-dir=%s", tmpdir)
cmdtestutil.RunSubCommand(t, subCmds, "ca", certDirFlag)
// creates apiserver cert
apiserverFlags := []string{
fmt.Sprintf("--cert-dir=%s", tmpdir),
"--apiserver-cert-extra-sans=foo,boo",
"--service-cidr=10.0.0.0/24",
"--service-dns-domain=mycluster.local",
"--apiserver-advertise-address=1.2.3.4",
}
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)
}
hostname, err := node.GetHostname("")
if err != nil {
t.Fatal(err)
}
for i, name := range []string{hostname, "kubernetes", "kubernetes.default", "kubernetes.default.svc", "kubernetes.default.svc.mycluster.local"} {
if APIserverCert.DNSNames[i] != name {
t.Errorf("APIserverCert.DNSNames[%d] is %s instead of %s", i, APIserverCert.DNSNames[i], name)
}
}
for i, ip := range []string{"10.0.0.1", "1.2.3.4"} {
if APIserverCert.IPAddresses[i].String() != ip {
t.Errorf("APIserverCert.IPAddresses[%d] is %s instead of %s", i, APIserverCert.IPAddresses[i], ip)
}
}
}
func TestSubCmdCertsCreateFilesWithConfigFile(t *testing.T) {
subCmds := getCertsSubCommands(phaseTestK8sVersion)
var tests = []struct {
subCmds []string
expectedFiles []string
}{
{
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{"ca", "apiserver", "apiserver-kubelet-client"},
expectedFiles: []string{
kubeadmconstants.CACertName, kubeadmconstants.CAKeyName,
kubeadmconstants.APIServerCertName, kubeadmconstants.APIServerKeyName,
kubeadmconstants.APIServerKubeletClientCertName, kubeadmconstants.APIServerKubeletClientKeyName,
},
},
{
subCmds: []string{"etcd-ca", "etcd-server", "etcd-peer", "etcd-healthcheck-client", "apiserver-etcd-client"},
expectedFiles: []string{
kubeadmconstants.EtcdCACertName, kubeadmconstants.EtcdCAKeyName,
kubeadmconstants.EtcdServerCertName, kubeadmconstants.EtcdServerKeyName,
kubeadmconstants.EtcdPeerCertName, kubeadmconstants.EtcdPeerKeyName,
kubeadmconstants.EtcdHealthcheckClientCertName, kubeadmconstants.EtcdHealthcheckClientKeyName,
kubeadmconstants.APIServerEtcdClientCertName, kubeadmconstants.APIServerEtcdClientKeyName,
},
},
{
subCmds: []string{"front-proxy-ca", "front-proxy-client"},
expectedFiles: []string{kubeadmconstants.FrontProxyCACertName, kubeadmconstants.FrontProxyCAKeyName, kubeadmconstants.FrontProxyClientCertName, kubeadmconstants.FrontProxyClientKeyName},
},
{
subCmds: []string{"sa"},
expectedFiles: []string{kubeadmconstants.ServiceAccountPrivateKeyName, kubeadmconstants.ServiceAccountPublicKeyName},
},
}
for _, test := range tests {
t.Run(strings.Join(test.subCmds, ","), func(t *testing.T) {
// Create temp folder for the test case
tmpdir := testutil.SetupTempDir(t)
defer os.RemoveAll(tmpdir)
cfg := &kubeadmapi.InitConfiguration{
APIEndpoint: kubeadmapi.APIEndpoint{AdvertiseAddress: "1.2.3.4", BindPort: 1234},
ClusterConfiguration: kubeadmapi.ClusterConfiguration{
CertificatesDir: tmpdir,
},
NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-node-name"},
}
configPath := testutil.SetupInitConfigurationFile(t, tmpdir, cfg)
// executes given sub commands
for _, subCmdName := range test.subCmds {
t.Logf("running subcommand %q", subCmdName)
configFlag := fmt.Sprintf("--config=%s", configPath)
cmdtestutil.RunSubCommand(t, subCmds, subCmdName, configFlag)
}
// verify expected files are there
testutil.AssertFileExists(t, tmpdir, test.expectedFiles...)
})
}
}

View File

@ -25,6 +25,8 @@ import (
cmdtestutil "k8s.io/kubernetes/cmd/kubeadm/test/cmd" cmdtestutil "k8s.io/kubernetes/cmd/kubeadm/test/cmd"
) )
const phaseTestK8sVersion = "v1.11.0"
func TestControlPlaneSubCommandsHasFlags(t *testing.T) { func TestControlPlaneSubCommandsHasFlags(t *testing.T) {
subCmds := getControlPlaneSubCommands("", phaseTestK8sVersion) subCmds := getControlPlaneSubCommands("", phaseTestK8sVersion)

View File

@ -19,17 +19,6 @@ docs/admin/kubeadm_alpha_phase_bootstrap-token_node.md
docs/admin/kubeadm_alpha_phase_bootstrap-token_node_allow-auto-approve.md docs/admin/kubeadm_alpha_phase_bootstrap-token_node_allow-auto-approve.md
docs/admin/kubeadm_alpha_phase_bootstrap-token_node_allow-post-csrs.md docs/admin/kubeadm_alpha_phase_bootstrap-token_node_allow-post-csrs.md
docs/admin/kubeadm_alpha_phase_certs.md docs/admin/kubeadm_alpha_phase_certs.md
docs/admin/kubeadm_alpha_phase_certs_all.md
docs/admin/kubeadm_alpha_phase_certs_apiserver-etcd-client.md
docs/admin/kubeadm_alpha_phase_certs_apiserver-kubelet-client.md
docs/admin/kubeadm_alpha_phase_certs_apiserver.md
docs/admin/kubeadm_alpha_phase_certs_ca.md
docs/admin/kubeadm_alpha_phase_certs_etcd-ca.md
docs/admin/kubeadm_alpha_phase_certs_etcd-healthcheck-client.md
docs/admin/kubeadm_alpha_phase_certs_etcd-peer.md
docs/admin/kubeadm_alpha_phase_certs_etcd-server.md
docs/admin/kubeadm_alpha_phase_certs_front-proxy-ca.md
docs/admin/kubeadm_alpha_phase_certs_front-proxy-client.md
docs/admin/kubeadm_alpha_phase_certs_renew.md docs/admin/kubeadm_alpha_phase_certs_renew.md
docs/admin/kubeadm_alpha_phase_certs_renew_all.md docs/admin/kubeadm_alpha_phase_certs_renew_all.md
docs/admin/kubeadm_alpha_phase_certs_renew_apiserver-etcd-client.md docs/admin/kubeadm_alpha_phase_certs_renew_apiserver-etcd-client.md
@ -39,7 +28,6 @@ docs/admin/kubeadm_alpha_phase_certs_renew_etcd-healthcheck-client.md
docs/admin/kubeadm_alpha_phase_certs_renew_etcd-peer.md docs/admin/kubeadm_alpha_phase_certs_renew_etcd-peer.md
docs/admin/kubeadm_alpha_phase_certs_renew_etcd-server.md docs/admin/kubeadm_alpha_phase_certs_renew_etcd-server.md
docs/admin/kubeadm_alpha_phase_certs_renew_front-proxy-client.md docs/admin/kubeadm_alpha_phase_certs_renew_front-proxy-client.md
docs/admin/kubeadm_alpha_phase_certs_sa.md
docs/admin/kubeadm_alpha_phase_controlplane.md docs/admin/kubeadm_alpha_phase_controlplane.md
docs/admin/kubeadm_alpha_phase_controlplane_all.md docs/admin/kubeadm_alpha_phase_controlplane_all.md
docs/admin/kubeadm_alpha_phase_controlplane_apiserver.md docs/admin/kubeadm_alpha_phase_controlplane_apiserver.md
@ -81,6 +69,18 @@ docs/admin/kubeadm_config_upload_from-flags.md
docs/admin/kubeadm_config_view.md docs/admin/kubeadm_config_view.md
docs/admin/kubeadm_init.md docs/admin/kubeadm_init.md
docs/admin/kubeadm_init_phase.md docs/admin/kubeadm_init_phase.md
docs/admin/kubeadm_init_phase_certs.md
docs/admin/kubeadm_init_phase_certs_apiserver-etcd-client.md
docs/admin/kubeadm_init_phase_certs_apiserver-kubelet-client.md
docs/admin/kubeadm_init_phase_certs_apiserver.md
docs/admin/kubeadm_init_phase_certs_ca.md
docs/admin/kubeadm_init_phase_certs_etcd-ca.md
docs/admin/kubeadm_init_phase_certs_etcd-healthcheck-client.md
docs/admin/kubeadm_init_phase_certs_etcd-peer.md
docs/admin/kubeadm_init_phase_certs_etcd-server.md
docs/admin/kubeadm_init_phase_certs_front-proxy-ca.md
docs/admin/kubeadm_init_phase_certs_front-proxy-client.md
docs/admin/kubeadm_init_phase_certs_sa.md
docs/admin/kubeadm_init_phase_kubelet-start.md docs/admin/kubeadm_init_phase_kubelet-start.md
docs/admin/kubeadm_init_phase_preflight.md docs/admin/kubeadm_init_phase_preflight.md
docs/admin/kubeadm_join.md docs/admin/kubeadm_join.md
@ -115,17 +115,6 @@ docs/man/man1/kubeadm-alpha-phase-bootstrap-token-node-allow-auto-approve.1
docs/man/man1/kubeadm-alpha-phase-bootstrap-token-node-allow-post-csrs.1 docs/man/man1/kubeadm-alpha-phase-bootstrap-token-node-allow-post-csrs.1
docs/man/man1/kubeadm-alpha-phase-bootstrap-token-node.1 docs/man/man1/kubeadm-alpha-phase-bootstrap-token-node.1
docs/man/man1/kubeadm-alpha-phase-bootstrap-token.1 docs/man/man1/kubeadm-alpha-phase-bootstrap-token.1
docs/man/man1/kubeadm-alpha-phase-certs-all.1
docs/man/man1/kubeadm-alpha-phase-certs-apiserver-etcd-client.1
docs/man/man1/kubeadm-alpha-phase-certs-apiserver-kubelet-client.1
docs/man/man1/kubeadm-alpha-phase-certs-apiserver.1
docs/man/man1/kubeadm-alpha-phase-certs-ca.1
docs/man/man1/kubeadm-alpha-phase-certs-etcd-ca.1
docs/man/man1/kubeadm-alpha-phase-certs-etcd-healthcheck-client.1
docs/man/man1/kubeadm-alpha-phase-certs-etcd-peer.1
docs/man/man1/kubeadm-alpha-phase-certs-etcd-server.1
docs/man/man1/kubeadm-alpha-phase-certs-front-proxy-ca.1
docs/man/man1/kubeadm-alpha-phase-certs-front-proxy-client.1
docs/man/man1/kubeadm-alpha-phase-certs-renew-all.1 docs/man/man1/kubeadm-alpha-phase-certs-renew-all.1
docs/man/man1/kubeadm-alpha-phase-certs-renew-apiserver-etcd-client.1 docs/man/man1/kubeadm-alpha-phase-certs-renew-apiserver-etcd-client.1
docs/man/man1/kubeadm-alpha-phase-certs-renew-apiserver-kubelet-client.1 docs/man/man1/kubeadm-alpha-phase-certs-renew-apiserver-kubelet-client.1
@ -135,7 +124,6 @@ docs/man/man1/kubeadm-alpha-phase-certs-renew-etcd-peer.1
docs/man/man1/kubeadm-alpha-phase-certs-renew-etcd-server.1 docs/man/man1/kubeadm-alpha-phase-certs-renew-etcd-server.1
docs/man/man1/kubeadm-alpha-phase-certs-renew-front-proxy-client.1 docs/man/man1/kubeadm-alpha-phase-certs-renew-front-proxy-client.1
docs/man/man1/kubeadm-alpha-phase-certs-renew.1 docs/man/man1/kubeadm-alpha-phase-certs-renew.1
docs/man/man1/kubeadm-alpha-phase-certs-sa.1
docs/man/man1/kubeadm-alpha-phase-certs.1 docs/man/man1/kubeadm-alpha-phase-certs.1
docs/man/man1/kubeadm-alpha-phase-controlplane-all.1 docs/man/man1/kubeadm-alpha-phase-controlplane-all.1
docs/man/man1/kubeadm-alpha-phase-controlplane-apiserver.1 docs/man/man1/kubeadm-alpha-phase-controlplane-apiserver.1
@ -179,6 +167,18 @@ docs/man/man1/kubeadm-config-upload-from-flags.1
docs/man/man1/kubeadm-config-upload.1 docs/man/man1/kubeadm-config-upload.1
docs/man/man1/kubeadm-config-view.1 docs/man/man1/kubeadm-config-view.1
docs/man/man1/kubeadm-config.1 docs/man/man1/kubeadm-config.1
docs/man/man1/kubeadm-init-phase-certs-apiserver-etcd-client.1
docs/man/man1/kubeadm-init-phase-certs-apiserver-kubelet-client.1
docs/man/man1/kubeadm-init-phase-certs-apiserver.1
docs/man/man1/kubeadm-init-phase-certs-ca.1
docs/man/man1/kubeadm-init-phase-certs-etcd-ca.1
docs/man/man1/kubeadm-init-phase-certs-etcd-healthcheck-client.1
docs/man/man1/kubeadm-init-phase-certs-etcd-peer.1
docs/man/man1/kubeadm-init-phase-certs-etcd-server.1
docs/man/man1/kubeadm-init-phase-certs-front-proxy-ca.1
docs/man/man1/kubeadm-init-phase-certs-front-proxy-client.1
docs/man/man1/kubeadm-init-phase-certs-sa.1
docs/man/man1/kubeadm-init-phase-certs.1
docs/man/man1/kubeadm-init-phase-kubelet-start.1 docs/man/man1/kubeadm-init-phase-kubelet-start.1
docs/man/man1/kubeadm-init-phase-preflight.1 docs/man/man1/kubeadm-init-phase-preflight.1
docs/man/man1/kubeadm-init-phase.1 docs/man/man1/kubeadm-init-phase.1