mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 19:56:01 +00:00
Merge pull request #67605 from liztio/cert-list-2
Automatic merge from submit-queue (batch tested with PRs 67596, 67520, 67605). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. Cert list 2 **What this PR does / why we need it**: Continuation of #67208. Uses the newly created declarative list of certificates kubeadm requires for the certs phase and upgrade steps. **Special notes for your reviewer**: **Release note**: ```release-note ```
This commit is contained in:
commit
6d76e35b39
@ -18,13 +18,13 @@ package phases
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"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"
|
||||||
kubeadmapiv1alpha3 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha3"
|
kubeadmapiv1alpha3 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha3"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation"
|
|
||||||
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"
|
||||||
@ -38,12 +38,12 @@ var (
|
|||||||
Generates a self-signed CA to provision identities for each component in the cluster (including nodes)
|
Generates a self-signed CA to provision identities for each component in the cluster (including nodes)
|
||||||
and client certificates to be used by various components.
|
and client certificates to be used by various components.
|
||||||
|
|
||||||
If a given certificate and private key pair both exist, kubeadm skips the generation step and
|
If a given certificate and private key pair both exist, kubeadm skips the generation step and
|
||||||
existing files will be used.
|
existing files will be used.
|
||||||
` + cmdutil.AlphaDisclaimer)
|
` + cmdutil.AlphaDisclaimer)
|
||||||
|
|
||||||
allCertsExample = normalizer.Examples(`
|
allCertsExample = normalizer.Examples(`
|
||||||
# Creates all PKI assets necessary to establish the control plane,
|
# Creates all PKI assets necessary to establish the control plane,
|
||||||
# functionally equivalent to what generated by kubeadm init.
|
# functionally equivalent to what generated by kubeadm init.
|
||||||
kubeadm alpha phase certs all
|
kubeadm alpha phase certs all
|
||||||
|
|
||||||
@ -51,85 +51,17 @@ var (
|
|||||||
kubeadm alpha phase certs all --config masterconfiguration.yaml
|
kubeadm alpha phase certs all --config masterconfiguration.yaml
|
||||||
`)
|
`)
|
||||||
|
|
||||||
caCertLongDesc = fmt.Sprintf(normalizer.LongDesc(`
|
|
||||||
Generates the self-signed kubernetes certificate authority and related key, and saves them into %s and %s files.
|
|
||||||
|
|
||||||
If both files already exist, kubeadm skips the generation step and existing files will be used.
|
|
||||||
`+cmdutil.AlphaDisclaimer), kubeadmconstants.CACertName, kubeadmconstants.CAKeyName)
|
|
||||||
|
|
||||||
apiServerCertLongDesc = fmt.Sprintf(normalizer.LongDesc(`
|
|
||||||
Generates the API server serving certificate and key and saves them into %s and %s files.
|
|
||||||
|
|
||||||
The certificate includes default subject alternative names and additional SANs provided by the user;
|
|
||||||
default SANs are: <node-name>, <apiserver-advertise-address>, kubernetes, kubernetes.default, kubernetes.default.svc,
|
|
||||||
kubernetes.default.svc.<service-dns-domain>, <internalAPIServerVirtualIP> (that is the .10 address in <service-cidr> address space).
|
|
||||||
|
|
||||||
If both files already exist, kubeadm skips the generation step and existing files will be used.
|
|
||||||
`+cmdutil.AlphaDisclaimer), kubeadmconstants.APIServerCertName, kubeadmconstants.APIServerKeyName)
|
|
||||||
|
|
||||||
apiServerKubeletCertLongDesc = fmt.Sprintf(normalizer.LongDesc(`
|
|
||||||
Generates the client certificate for the API server to connect to the kubelet securely and the respective key,
|
|
||||||
and saves them into %s and %s files.
|
|
||||||
|
|
||||||
If both files already exist, kubeadm skips the generation step and existing files will be used.
|
|
||||||
`+cmdutil.AlphaDisclaimer), kubeadmconstants.APIServerKubeletClientCertName, kubeadmconstants.APIServerKubeletClientKeyName)
|
|
||||||
|
|
||||||
etcdCaCertLongDesc = fmt.Sprintf(normalizer.LongDesc(`
|
|
||||||
Generates the self-signed etcd certificate authority and related key and saves them into %s and %s files.
|
|
||||||
|
|
||||||
If both files already exist, kubeadm skips the generation step and existing files will be used.
|
|
||||||
`+cmdutil.AlphaDisclaimer), kubeadmconstants.EtcdCACertName, kubeadmconstants.EtcdCAKeyName)
|
|
||||||
|
|
||||||
etcdServerCertLongDesc = fmt.Sprintf(normalizer.LongDesc(`
|
|
||||||
Generates the etcd serving certificate and key and saves them into %s and %s files.
|
|
||||||
|
|
||||||
The certificate includes default subject alternative names and additional SANs provided by the user;
|
|
||||||
default SANs are: localhost, 127.0.0.1.
|
|
||||||
|
|
||||||
If both files already exist, kubeadm skips the generation step and existing files will be used.
|
|
||||||
`+cmdutil.AlphaDisclaimer), kubeadmconstants.EtcdServerCertName, kubeadmconstants.EtcdServerKeyName)
|
|
||||||
|
|
||||||
etcdPeerCertLongDesc = fmt.Sprintf(normalizer.LongDesc(`
|
|
||||||
Generates the etcd peer certificate and key and saves them into %s and %s files.
|
|
||||||
|
|
||||||
The certificate includes default subject alternative names and additional SANs provided by the user;
|
|
||||||
default SANs are: <node-name>, <apiserver-advertise-address>.
|
|
||||||
|
|
||||||
If both files already exist, kubeadm skips the generation step and existing files will be used.
|
|
||||||
`+cmdutil.AlphaDisclaimer), kubeadmconstants.EtcdPeerCertName, kubeadmconstants.EtcdPeerKeyName)
|
|
||||||
|
|
||||||
etcdHealthcheckClientCertLongDesc = fmt.Sprintf(normalizer.LongDesc(`
|
|
||||||
Generates the client certificate for liveness probes to healthcheck etcd and the respective key,
|
|
||||||
and saves them into %s and %s files.
|
|
||||||
|
|
||||||
If both files already exist, kubeadm skips the generation step and existing files will be used.
|
|
||||||
`+cmdutil.AlphaDisclaimer), kubeadmconstants.EtcdHealthcheckClientCertName, kubeadmconstants.EtcdHealthcheckClientKeyName)
|
|
||||||
|
|
||||||
apiServerEtcdServerCertLongDesc = fmt.Sprintf(normalizer.LongDesc(`
|
|
||||||
Generates the client certificate for the API server to connect to etcd securely and the respective key,
|
|
||||||
and saves them into %s and %s files.
|
|
||||||
|
|
||||||
If both files already exist, kubeadm skips the generation step and existing files will be used.
|
|
||||||
`+cmdutil.AlphaDisclaimer), kubeadmconstants.APIServerEtcdClientCertName, kubeadmconstants.APIServerEtcdClientKeyName)
|
|
||||||
|
|
||||||
saKeyLongDesc = fmt.Sprintf(normalizer.LongDesc(`
|
saKeyLongDesc = fmt.Sprintf(normalizer.LongDesc(`
|
||||||
Generates the private key for signing service account tokens along with its public key, and saves them into
|
Generates the private key for signing service account tokens along with its public key, and saves them into
|
||||||
%s and %s files.
|
%s and %s files.
|
||||||
|
|
||||||
If both files already exist, kubeadm skips the generation step and existing files will be used.
|
If both files already exist, kubeadm skips the generation step and existing files will be used.
|
||||||
`+cmdutil.AlphaDisclaimer), kubeadmconstants.ServiceAccountPrivateKeyName, kubeadmconstants.ServiceAccountPublicKeyName)
|
`+cmdutil.AlphaDisclaimer), kubeadmconstants.ServiceAccountPrivateKeyName, kubeadmconstants.ServiceAccountPublicKeyName)
|
||||||
|
|
||||||
frontProxyCaCertLongDesc = fmt.Sprintf(normalizer.LongDesc(`
|
genericLongDesc = normalizer.LongDesc(`
|
||||||
Generates the front proxy CA certificate and key and saves them into %s and %s files.
|
Generates the %[1]s, and saves them into %[2]s.cert and %[2]s.key files.%[3]s
|
||||||
|
|
||||||
If both files already exist, kubeadm skips the generation step and existing files will be used.
|
If both files already exist, kubeadm skips the generation step and existing files will be used.
|
||||||
`+cmdutil.AlphaDisclaimer), kubeadmconstants.FrontProxyCACertName, kubeadmconstants.FrontProxyCAKeyName)
|
` + cmdutil.AlphaDisclaimer)
|
||||||
|
|
||||||
frontProxyClientCertLongDesc = fmt.Sprintf(normalizer.LongDesc(`
|
|
||||||
Generates the front proxy client certificate and key and saves them into %s and %s files.
|
|
||||||
|
|
||||||
If both files already exist, kubeadm skips the generation step and existing files will be used.
|
|
||||||
`+cmdutil.AlphaDisclaimer), kubeadmconstants.FrontProxyClientCertName, kubeadmconstants.FrontProxyClientKeyName)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewCmdCerts returns main command for certs phase
|
// NewCmdCerts returns main command for certs phase
|
||||||
@ -154,147 +86,146 @@ func getCertsSubCommands(defaultKubernetesVersion string) []*cobra.Command {
|
|||||||
kubeadmscheme.Scheme.Default(cfg)
|
kubeadmscheme.Scheme.Default(cfg)
|
||||||
|
|
||||||
var cfgPath string
|
var cfgPath string
|
||||||
var subCmds []*cobra.Command
|
|
||||||
|
|
||||||
subCmdProperties := []struct {
|
// Special case commands
|
||||||
use string
|
// All runs CreatePKIAssets, which isn't a particular certificate
|
||||||
short string
|
allCmd := &cobra.Command{
|
||||||
long string
|
Use: "all",
|
||||||
examples string
|
Short: "Generates all PKI assets necessary to establish the control plane",
|
||||||
cmdFunc func(cfg *kubeadmapi.InitConfiguration) error
|
Long: allCertsLongDesc,
|
||||||
}{
|
Example: allCertsExample,
|
||||||
{
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
use: "all",
|
internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(cfgPath, cfg)
|
||||||
short: "Generates all PKI assets necessary to establish the control plane",
|
kubeadmutil.CheckErr(err)
|
||||||
long: allCertsLongDesc,
|
|
||||||
examples: allCertsExample,
|
err = certsphase.CreatePKIAssets(internalcfg)
|
||||||
cmdFunc: certsphase.CreatePKIAssets,
|
kubeadmutil.CheckErr(err)
|
||||||
},
|
|
||||||
{
|
|
||||||
use: "ca",
|
|
||||||
short: "Generates a self-signed kubernetes CA to provision identities for components of the cluster",
|
|
||||||
long: caCertLongDesc,
|
|
||||||
cmdFunc: certsphase.CreateCACertAndKeyFiles,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
use: "apiserver",
|
|
||||||
short: "Generates an API server serving certificate and key",
|
|
||||||
long: apiServerCertLongDesc,
|
|
||||||
cmdFunc: certsphase.CreateAPIServerCertAndKeyFiles,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
use: "apiserver-kubelet-client",
|
|
||||||
short: "Generates a client certificate for the API server to connect to the kubelets securely",
|
|
||||||
long: apiServerKubeletCertLongDesc,
|
|
||||||
cmdFunc: certsphase.CreateAPIServerKubeletClientCertAndKeyFiles,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
use: "etcd-ca",
|
|
||||||
short: "Generates a self-signed CA to provision identities for etcd",
|
|
||||||
long: etcdCaCertLongDesc,
|
|
||||||
cmdFunc: certsphase.CreateEtcdCACertAndKeyFiles,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
use: "etcd-server",
|
|
||||||
short: "Generates an etcd serving certificate and key",
|
|
||||||
long: etcdServerCertLongDesc,
|
|
||||||
cmdFunc: certsphase.CreateEtcdServerCertAndKeyFiles,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
use: "etcd-peer",
|
|
||||||
short: "Generates an etcd peer certificate and key",
|
|
||||||
long: etcdPeerCertLongDesc,
|
|
||||||
cmdFunc: certsphase.CreateEtcdPeerCertAndKeyFiles,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
use: "etcd-healthcheck-client",
|
|
||||||
short: "Generates a client certificate for liveness probes to healthcheck etcd",
|
|
||||||
long: etcdHealthcheckClientCertLongDesc,
|
|
||||||
cmdFunc: certsphase.CreateEtcdHealthcheckClientCertAndKeyFiles,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
use: "apiserver-etcd-client",
|
|
||||||
short: "Generates a client certificate for the API server to connect to etcd securely",
|
|
||||||
long: apiServerEtcdServerCertLongDesc,
|
|
||||||
cmdFunc: certsphase.CreateAPIServerEtcdClientCertAndKeyFiles,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
use: "sa",
|
|
||||||
short: "Generates a private key for signing service account tokens along with its public key",
|
|
||||||
long: saKeyLongDesc,
|
|
||||||
cmdFunc: certsphase.CreateServiceAccountKeyAndPublicKeyFiles,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
use: "front-proxy-ca",
|
|
||||||
short: "Generates a front proxy CA certificate and key for a Kubernetes cluster",
|
|
||||||
long: frontProxyCaCertLongDesc,
|
|
||||||
cmdFunc: certsphase.CreateFrontProxyCACertAndKeyFiles,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
use: "front-proxy-client",
|
|
||||||
short: "Generates a front proxy CA client certificate and key for a Kubernetes cluster",
|
|
||||||
long: frontProxyClientCertLongDesc,
|
|
||||||
cmdFunc: certsphase.CreateFrontProxyClientCertAndKeyFiles,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
addFlags(allCmd, &cfgPath, cfg, true)
|
||||||
|
|
||||||
for _, properties := range subCmdProperties {
|
// SA creates the private/public key pair, which doesn't use x509 at all
|
||||||
// Creates the UX Command
|
saCmd := &cobra.Command{
|
||||||
cmd := &cobra.Command{
|
Use: "sa",
|
||||||
Use: properties.use,
|
Short: "Generates a private key for signing service account tokens along with its public key",
|
||||||
Short: properties.short,
|
Long: saKeyLongDesc,
|
||||||
Long: properties.long,
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
Example: properties.examples,
|
internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(cfgPath, cfg)
|
||||||
Run: runCmdFunc(properties.cmdFunc, &cfgPath, cfg, defaultKubernetesVersion),
|
kubeadmutil.CheckErr(err)
|
||||||
}
|
|
||||||
|
|
||||||
// Add flags to the command
|
err = certsphase.CreateServiceAccountKeyAndPublicKeyFiles(internalcfg)
|
||||||
cmd.Flags().StringVar(&cfgPath, "config", cfgPath, "Path to kubeadm config file. WARNING: Usage of a configuration file is experimental")
|
kubeadmutil.CheckErr(err)
|
||||||
cmd.Flags().StringVar(&cfg.CertificatesDir, "cert-dir", cfg.CertificatesDir, "The path where to save the certificates")
|
},
|
||||||
if properties.use == "all" || properties.use == "apiserver" {
|
}
|
||||||
cmd.Flags().StringVar(&cfg.Networking.DNSDomain, "service-dns-domain", cfg.Networking.DNSDomain, "Alternative domain for services, to use for the API server serving cert")
|
addFlags(saCmd, &cfgPath, cfg, false)
|
||||||
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.API.AdvertiseAddress, "apiserver-advertise-address", cfg.API.AdvertiseAddress, "The IP address the API server is accessible on, to use for the API server serving cert")
|
|
||||||
}
|
|
||||||
|
|
||||||
subCmds = append(subCmds, cmd)
|
subCmds := []*cobra.Command{allCmd, saCmd}
|
||||||
|
|
||||||
|
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
|
return subCmds
|
||||||
}
|
}
|
||||||
|
|
||||||
// runCmdFunc creates a cobra.Command Run function, by composing the call to the given cmdFunc with necessary additional steps (e.g preparation of input parameters)
|
func makeCmd(certSpec *certsphase.KubeadmCert, cfgPath *string, cfg *kubeadmapiv1alpha3.InitConfiguration) *cobra.Command {
|
||||||
func runCmdFunc(cmdFunc func(cfg *kubeadmapi.InitConfiguration) error, cfgPath *string, cfg *kubeadmapiv1alpha3.InitConfiguration, defaultKubernetesVersion string) func(cmd *cobra.Command, args []string) {
|
cmd := &cobra.Command{
|
||||||
|
Use: certSpec.Name,
|
||||||
|
Short: fmt.Sprintf("Generates the %s", certSpec.LongName),
|
||||||
|
Long: fmt.Sprintf(
|
||||||
|
genericLongDesc,
|
||||||
|
certSpec.LongName,
|
||||||
|
certSpec.BaseName,
|
||||||
|
getSANDescription(certSpec),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
addFlags(cmd, cfgPath, cfg, certSpec.Name == "apiserver")
|
||||||
|
// Add flags to the command
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
// the following statement build a closure that wraps a call to a cmdFunc, binding
|
func getSANDescription(certSpec *certsphase.KubeadmCert) string {
|
||||||
// the function itself with the specific parameters of each sub command.
|
//Defaulted config we will use to get SAN certs
|
||||||
// Please note that specific parameter should be passed as value, while other parameters - passed as reference -
|
defaultConfig := &kubeadmapiv1alpha3.InitConfiguration{
|
||||||
// are shared between sub commands and gets access to current value e.g. flags value.
|
API: kubeadmapiv1alpha3.API{
|
||||||
|
// GetAPIServerAltNames errors without an AdvertiseAddress; this is as good as any.
|
||||||
|
AdvertiseAddress: "127.0.0.1",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
defaultInternalConfig := &kubeadmapi.InitConfiguration{}
|
||||||
|
|
||||||
return func(cmd *cobra.Command, args []string) {
|
kubeadmscheme.Scheme.Default(defaultConfig)
|
||||||
if err := validation.ValidateMixedArguments(cmd.Flags()); err != nil {
|
kubeadmscheme.Scheme.Convert(defaultConfig, defaultInternalConfig, nil)
|
||||||
kubeadmutil.CheckErr(err)
|
|
||||||
|
certConfig, err := certSpec.GetConfig(defaultInternalConfig)
|
||||||
|
kubeadmutil.CheckErr(err)
|
||||||
|
|
||||||
|
if len(certConfig.AltNames.DNSNames) == 0 && len(certConfig.AltNames.IPs) == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
// This mutates the certConfig, but we're throwing it after we construct the command anyway
|
||||||
|
sans := []string{}
|
||||||
|
|
||||||
|
for _, dnsName := range certConfig.AltNames.DNSNames {
|
||||||
|
if dnsName != "" {
|
||||||
|
sans = append(sans, dnsName)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// This is used for unit testing only...
|
for _, ip := range certConfig.AltNames.IPs {
|
||||||
// If we wouldn't set this to something, the code would dynamically look up the version from the internet
|
sans = append(sans, ip.String())
|
||||||
// By setting this explicitly for tests workarounds that
|
}
|
||||||
if defaultKubernetesVersion != "" {
|
return fmt.Sprintf("\n\nDefault SANs are %s", strings.Join(sans, ", "))
|
||||||
cfg.KubernetesVersion = defaultKubernetesVersion
|
}
|
||||||
} else {
|
|
||||||
// KubernetesVersion is not used, but we set it explicitly to avoid the lookup
|
|
||||||
// of the version from the internet when executing ConfigFileAndDefaultsToInternalConfig
|
|
||||||
err := SetKubernetesVersion(nil, cfg)
|
|
||||||
kubeadmutil.CheckErr(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// This call returns the ready-to-use configuration based on the configuration file that might or might not exist and the default cfg populated by flags
|
func addFlags(cmd *cobra.Command, cfgPath *string, cfg *kubeadmapiv1alpha3.InitConfiguration, addAPIFlags bool) {
|
||||||
|
cmd.Flags().StringVar(cfgPath, "config", *cfgPath, "Path to kubeadm config file. WARNING: Usage of a configuration file is experimental")
|
||||||
|
cmd.Flags().StringVar(&cfg.CertificatesDir, "cert-dir", cfg.CertificatesDir, "The path where to save the certificates")
|
||||||
|
if addAPIFlags {
|
||||||
|
cmd.Flags().StringVar(&cfg.Networking.DNSDomain, "service-dns-domain", cfg.Networking.DNSDomain, "Alternative domain for services, to use for the API server serving cert")
|
||||||
|
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.API.AdvertiseAddress, "apiserver-advertise-address", cfg.API.AdvertiseAddress, "The IP address the API server is accessible on, to use for the API server serving cert")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeCommandsForCA(ca *certsphase.KubeadmCert, certList []*certsphase.KubeadmCert, cfgPath *string, cfg *kubeadmapiv1alpha3.InitConfiguration) []*cobra.Command {
|
||||||
|
subCmds := []*cobra.Command{}
|
||||||
|
|
||||||
|
caCmd := makeCmd(ca, cfgPath, cfg)
|
||||||
|
caCmd.Run = func(cmd *cobra.Command, args []string) {
|
||||||
internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(*cfgPath, cfg)
|
internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(*cfgPath, cfg)
|
||||||
kubeadmutil.CheckErr(err)
|
kubeadmutil.CheckErr(err)
|
||||||
|
|
||||||
// Execute the cmdFunc
|
err = certsphase.CreateCACertAndKeyFiles(ca, internalcfg)
|
||||||
err = cmdFunc(internalcfg)
|
|
||||||
kubeadmutil.CheckErr(err)
|
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 *kubeadmapiv1alpha3.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 = certsphase.CreateCertAndKeyFilesWithCA(cert, caCert, internalcfg)
|
||||||
|
kubeadmutil.CheckErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return certCmd
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ package phases
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
@ -146,18 +147,21 @@ func TestSubCmdCertsCreateFilesWithFlags(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
// Create temp folder for the test case
|
t.Run(strings.Join(test.subCmds, ","), func(t *testing.T) {
|
||||||
tmpdir := testutil.SetupTempDir(t)
|
// Create temp folder for the test case
|
||||||
defer os.RemoveAll(tmpdir)
|
tmpdir := testutil.SetupTempDir(t)
|
||||||
|
defer os.RemoveAll(tmpdir)
|
||||||
|
|
||||||
// executes given sub commands
|
// executes given sub commands
|
||||||
for _, subCmdName := range test.subCmds {
|
for _, subCmdName := range test.subCmds {
|
||||||
certDirFlag := fmt.Sprintf("--cert-dir=%s", tmpdir)
|
fmt.Printf("running command %q\n", subCmdName)
|
||||||
cmdtestutil.RunSubCommand(t, subCmds, subCmdName, certDirFlag)
|
certDirFlag := fmt.Sprintf("--cert-dir=%s", tmpdir)
|
||||||
}
|
cmdtestutil.RunSubCommand(t, subCmds, subCmdName, certDirFlag)
|
||||||
|
}
|
||||||
|
|
||||||
// verify expected files are there
|
// verify expected files are there
|
||||||
testutil.AssertFileExists(t, tmpdir, test.expectedFiles...)
|
testutil.AssertFileExists(t, tmpdir, test.expectedFiles...)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,8 +230,12 @@ func TestSubCmdCertsCreateFilesWithConfigFile(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
subCmds: []string{"ca", "apiserver", "apiserver-kubelet-client"},
|
subCmds: []string{"ca", "apiserver", "apiserver-kubelet-client"},
|
||||||
expectedFiles: []string{kubeadmconstants.CACertName, kubeadmconstants.CAKeyName, kubeadmconstants.APIServerCertName, kubeadmconstants.APIServerKeyName, kubeadmconstants.APIServerKubeletClientCertName, kubeadmconstants.APIServerKubeletClientKeyName},
|
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"},
|
subCmds: []string{"etcd-ca", "etcd-server", "etcd-peer", "etcd-healthcheck-client", "apiserver-etcd-client"},
|
||||||
@ -250,26 +258,28 @@ func TestSubCmdCertsCreateFilesWithConfigFile(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
// Create temp folder for the test case
|
t.Run(strings.Join(test.subCmds, ","), func(t *testing.T) {
|
||||||
tmpdir := testutil.SetupTempDir(t)
|
// Create temp folder for the test case
|
||||||
defer os.RemoveAll(tmpdir)
|
|
||||||
|
|
||||||
certdir := tmpdir
|
tmpdir := testutil.SetupTempDir(t)
|
||||||
|
defer os.RemoveAll(tmpdir)
|
||||||
|
|
||||||
cfg := &kubeadmapi.InitConfiguration{
|
cfg := &kubeadmapi.InitConfiguration{
|
||||||
API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", BindPort: 1234},
|
API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4", BindPort: 1234},
|
||||||
CertificatesDir: certdir,
|
CertificatesDir: tmpdir,
|
||||||
NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-node-name"},
|
NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-node-name"},
|
||||||
}
|
}
|
||||||
configPath := testutil.SetupInitConfigurationFile(t, tmpdir, cfg)
|
configPath := testutil.SetupInitConfigurationFile(t, tmpdir, cfg)
|
||||||
|
|
||||||
// executes given sub commands
|
// executes given sub commands
|
||||||
for _, subCmdName := range test.subCmds {
|
for _, subCmdName := range test.subCmds {
|
||||||
configFlag := fmt.Sprintf("--config=%s", configPath)
|
t.Logf("running subcommand %q", subCmdName)
|
||||||
cmdtestutil.RunSubCommand(t, subCmds, subCmdName, configFlag)
|
configFlag := fmt.Sprintf("--config=%s", configPath)
|
||||||
}
|
cmdtestutil.RunSubCommand(t, subCmds, subCmdName, configFlag)
|
||||||
|
}
|
||||||
|
|
||||||
// verify expected files are there
|
// verify expected files are there
|
||||||
testutil.AssertFileExists(t, tmpdir, test.expectedFiles...)
|
testutil.AssertFileExists(t, tmpdir, test.expectedFiles...)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ type configMutatorsFunc func(*kubeadmapi.InitConfiguration, *certutil.Config) er
|
|||||||
// KubeadmCert represents a certificate that Kubeadm will create to function properly.
|
// KubeadmCert represents a certificate that Kubeadm will create to function properly.
|
||||||
type KubeadmCert struct {
|
type KubeadmCert struct {
|
||||||
Name string
|
Name string
|
||||||
|
LongName string
|
||||||
BaseName string
|
BaseName string
|
||||||
CAName string
|
CAName string
|
||||||
// Some attributes will depend on the InitConfiguration, only known at runtime.
|
// Some attributes will depend on the InitConfiguration, only known at runtime.
|
||||||
@ -57,13 +58,14 @@ func (k *KubeadmCert) CreateFromCA(ic *kubeadmapi.InitConfiguration, caCert *x50
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't create %q certificate: %v", k.Name, err)
|
return fmt.Errorf("couldn't create %q certificate: %v", k.Name, err)
|
||||||
}
|
}
|
||||||
cert, key, err := pkiutil.NewCertAndKey(caCert, caKey, *cfg)
|
cert, key, err := pkiutil.NewCertAndKey(caCert, caKey, cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
writeCertificateAuthorithyFilesIfNotExist(
|
writeCertificateFilesIfNotExist(
|
||||||
ic.CertificatesDir,
|
ic.CertificatesDir,
|
||||||
k.BaseName,
|
k.BaseName,
|
||||||
|
caCert,
|
||||||
cert,
|
cert,
|
||||||
key,
|
key,
|
||||||
)
|
)
|
||||||
@ -71,14 +73,42 @@ func (k *KubeadmCert) CreateFromCA(ic *kubeadmapi.InitConfiguration, caCert *x50
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateAsCA creates a certificate authority, writing the files to disk and also returning the created CA so it can be used to sign child certs.
|
||||||
|
func (k *KubeadmCert) CreateAsCA(ic *kubeadmapi.InitConfiguration) (*x509.Certificate, *rsa.PrivateKey, error) {
|
||||||
|
cfg, err := k.GetConfig(ic)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("couldn't get configuration for %q CA certificate: %v", k.Name, err)
|
||||||
|
}
|
||||||
|
caCert, caKey, err := NewCACertAndKey(cfg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("couldn't generate %q CA certificate: %v", k.Name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = writeCertificateAuthorithyFilesIfNotExist(
|
||||||
|
ic.CertificatesDir,
|
||||||
|
k.BaseName,
|
||||||
|
caCert,
|
||||||
|
caKey,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("couldn't write out %q CA certificate: %v", k.Name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return caCert, caKey, nil
|
||||||
|
}
|
||||||
|
|
||||||
// CertificateTree is represents a one-level-deep tree, mapping a CA to the certs that depend on it.
|
// CertificateTree is represents a one-level-deep tree, mapping a CA to the certs that depend on it.
|
||||||
type CertificateTree map[*KubeadmCert]Certificates
|
type CertificateTree map[*KubeadmCert]Certificates
|
||||||
|
|
||||||
// CreateTree creates the CAs, certs signed by the CAs, and writes them all to disk.
|
// CreateTree creates the CAs, certs signed by the CAs, and writes them all to disk.
|
||||||
func (t CertificateTree) CreateTree(ic *kubeadmapi.InitConfiguration) error {
|
func (t CertificateTree) CreateTree(ic *kubeadmapi.InitConfiguration) error {
|
||||||
for ca, leaves := range t {
|
for ca, leaves := range t {
|
||||||
// TODO: NewCACertAndKey should take an ic
|
cfg, err := ca.GetConfig(ic)
|
||||||
caCert, caKey, err := NewCACertAndKey()
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
caCert, caKey, err := NewCACertAndKey(cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -89,12 +119,13 @@ func (t CertificateTree) CreateTree(ic *kubeadmapi.InitConfiguration) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := writeCertificateAuthorithyFilesIfNotExist(
|
err = writeCertificateAuthorithyFilesIfNotExist(
|
||||||
ic.CertificatesDir,
|
ic.CertificatesDir,
|
||||||
ca.BaseName,
|
ca.BaseName,
|
||||||
caCert,
|
caCert,
|
||||||
caKey,
|
caKey,
|
||||||
); err != nil {
|
)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -171,7 +202,8 @@ func GetCertsWithoutEtcd() Certificates {
|
|||||||
var (
|
var (
|
||||||
// KubeadmCertRootCA is the definition of the Kubernetes Root CA for the API Server and kubelet.
|
// KubeadmCertRootCA is the definition of the Kubernetes Root CA for the API Server and kubelet.
|
||||||
KubeadmCertRootCA = KubeadmCert{
|
KubeadmCertRootCA = KubeadmCert{
|
||||||
Name: "root-ca",
|
Name: "ca",
|
||||||
|
LongName: "self-signed kubernetes CA to provision identities for other kuberenets components",
|
||||||
BaseName: kubeadmconstants.CACertAndKeyBaseName,
|
BaseName: kubeadmconstants.CACertAndKeyBaseName,
|
||||||
config: certutil.Config{
|
config: certutil.Config{
|
||||||
CommonName: "kubernetes",
|
CommonName: "kubernetes",
|
||||||
@ -179,9 +211,10 @@ var (
|
|||||||
}
|
}
|
||||||
// KubeadmCertAPIServer is the definition of the cert used to serve the kubernetes API.
|
// KubeadmCertAPIServer is the definition of the cert used to serve the kubernetes API.
|
||||||
KubeadmCertAPIServer = KubeadmCert{
|
KubeadmCertAPIServer = KubeadmCert{
|
||||||
Name: "api-server",
|
Name: "apiserver",
|
||||||
|
LongName: "certificate for serving the kubernetes API",
|
||||||
BaseName: kubeadmconstants.APIServerCertAndKeyBaseName,
|
BaseName: kubeadmconstants.APIServerCertAndKeyBaseName,
|
||||||
CAName: "root-ca",
|
CAName: "ca",
|
||||||
config: certutil.Config{
|
config: certutil.Config{
|
||||||
CommonName: kubeadmconstants.APIServerCertCommonName,
|
CommonName: kubeadmconstants.APIServerCertCommonName,
|
||||||
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
||||||
@ -192,9 +225,10 @@ var (
|
|||||||
}
|
}
|
||||||
// KubeadmCertKubeletClient is the definition of the cert used by the API server to access the kubelet.
|
// KubeadmCertKubeletClient is the definition of the cert used by the API server to access the kubelet.
|
||||||
KubeadmCertKubeletClient = KubeadmCert{
|
KubeadmCertKubeletClient = KubeadmCert{
|
||||||
Name: "api-server-kubelet-client",
|
Name: "apiserver-kubelet-client",
|
||||||
|
LongName: "Client certificate for the API server to connect to kubelet",
|
||||||
BaseName: kubeadmconstants.APIServerKubeletClientCertAndKeyBaseName,
|
BaseName: kubeadmconstants.APIServerKubeletClientCertAndKeyBaseName,
|
||||||
CAName: "root-ca",
|
CAName: "ca",
|
||||||
config: certutil.Config{
|
config: certutil.Config{
|
||||||
CommonName: kubeadmconstants.APIServerKubeletClientCertCommonName,
|
CommonName: kubeadmconstants.APIServerKubeletClientCertCommonName,
|
||||||
Organization: []string{kubeadmconstants.MastersGroup},
|
Organization: []string{kubeadmconstants.MastersGroup},
|
||||||
@ -205,6 +239,7 @@ var (
|
|||||||
// KubeadmCertFrontProxyCA is the definition of the CA used for the front end proxy.
|
// KubeadmCertFrontProxyCA is the definition of the CA used for the front end proxy.
|
||||||
KubeadmCertFrontProxyCA = KubeadmCert{
|
KubeadmCertFrontProxyCA = KubeadmCert{
|
||||||
Name: "front-proxy-ca",
|
Name: "front-proxy-ca",
|
||||||
|
LongName: "self-signed CA to provision identities for front proxy",
|
||||||
BaseName: kubeadmconstants.FrontProxyCACertAndKeyBaseName,
|
BaseName: kubeadmconstants.FrontProxyCACertAndKeyBaseName,
|
||||||
config: certutil.Config{
|
config: certutil.Config{
|
||||||
CommonName: "front-proxy-ca",
|
CommonName: "front-proxy-ca",
|
||||||
@ -215,6 +250,7 @@ var (
|
|||||||
KubeadmCertFrontProxyClient = KubeadmCert{
|
KubeadmCertFrontProxyClient = KubeadmCert{
|
||||||
Name: "front-proxy-client",
|
Name: "front-proxy-client",
|
||||||
BaseName: kubeadmconstants.FrontProxyClientCertAndKeyBaseName,
|
BaseName: kubeadmconstants.FrontProxyClientCertAndKeyBaseName,
|
||||||
|
LongName: "client for the front proxy",
|
||||||
CAName: "front-proxy-ca",
|
CAName: "front-proxy-ca",
|
||||||
config: certutil.Config{
|
config: certutil.Config{
|
||||||
CommonName: kubeadmconstants.FrontProxyClientCertCommonName,
|
CommonName: kubeadmconstants.FrontProxyClientCertCommonName,
|
||||||
@ -225,6 +261,7 @@ var (
|
|||||||
// KubeadmCertEtcdCA is the definition of the root CA used by the hosted etcd server.
|
// KubeadmCertEtcdCA is the definition of the root CA used by the hosted etcd server.
|
||||||
KubeadmCertEtcdCA = KubeadmCert{
|
KubeadmCertEtcdCA = KubeadmCert{
|
||||||
Name: "etcd-ca",
|
Name: "etcd-ca",
|
||||||
|
LongName: "self-signed CA to provision identities for etcd",
|
||||||
BaseName: kubeadmconstants.EtcdCACertAndKeyBaseName,
|
BaseName: kubeadmconstants.EtcdCACertAndKeyBaseName,
|
||||||
config: certutil.Config{
|
config: certutil.Config{
|
||||||
CommonName: "etcd-ca",
|
CommonName: "etcd-ca",
|
||||||
@ -233,6 +270,7 @@ var (
|
|||||||
// KubeadmCertEtcdServer is the definition of the cert used to serve etcd to clients.
|
// KubeadmCertEtcdServer is the definition of the cert used to serve etcd to clients.
|
||||||
KubeadmCertEtcdServer = KubeadmCert{
|
KubeadmCertEtcdServer = KubeadmCert{
|
||||||
Name: "etcd-server",
|
Name: "etcd-server",
|
||||||
|
LongName: "certificate for serving etcd",
|
||||||
BaseName: kubeadmconstants.EtcdServerCertAndKeyBaseName,
|
BaseName: kubeadmconstants.EtcdServerCertAndKeyBaseName,
|
||||||
CAName: "etcd-ca",
|
CAName: "etcd-ca",
|
||||||
config: certutil.Config{
|
config: certutil.Config{
|
||||||
@ -250,6 +288,7 @@ var (
|
|||||||
// KubeadmCertEtcdPeer is the definition of the cert used by etcd peers to access each other.
|
// KubeadmCertEtcdPeer is the definition of the cert used by etcd peers to access each other.
|
||||||
KubeadmCertEtcdPeer = KubeadmCert{
|
KubeadmCertEtcdPeer = KubeadmCert{
|
||||||
Name: "etcd-peer",
|
Name: "etcd-peer",
|
||||||
|
LongName: "credentials for etcd nodes to communicate with each other",
|
||||||
BaseName: kubeadmconstants.EtcdPeerCertAndKeyBaseName,
|
BaseName: kubeadmconstants.EtcdPeerCertAndKeyBaseName,
|
||||||
CAName: "etcd-ca",
|
CAName: "etcd-ca",
|
||||||
config: certutil.Config{
|
config: certutil.Config{
|
||||||
@ -262,7 +301,8 @@ var (
|
|||||||
}
|
}
|
||||||
// KubeadmCertEtcdHealthcheck is the definition of the cert used by Kubernetes to check the health of the etcd server.
|
// KubeadmCertEtcdHealthcheck is the definition of the cert used by Kubernetes to check the health of the etcd server.
|
||||||
KubeadmCertEtcdHealthcheck = KubeadmCert{
|
KubeadmCertEtcdHealthcheck = KubeadmCert{
|
||||||
Name: "etcd-healthcheck",
|
Name: "etcd-healthcheck-client",
|
||||||
|
LongName: "client certificate for liveness probes to healtcheck etcd",
|
||||||
BaseName: kubeadmconstants.EtcdHealthcheckClientCertAndKeyBaseName,
|
BaseName: kubeadmconstants.EtcdHealthcheckClientCertAndKeyBaseName,
|
||||||
CAName: "etcd-ca",
|
CAName: "etcd-ca",
|
||||||
config: certutil.Config{
|
config: certutil.Config{
|
||||||
@ -273,7 +313,8 @@ var (
|
|||||||
}
|
}
|
||||||
// KubeadmCertEtcdAPIClient is the definition of the cert used by the API server to access etcd.
|
// KubeadmCertEtcdAPIClient is the definition of the cert used by the API server to access etcd.
|
||||||
KubeadmCertEtcdAPIClient = KubeadmCert{
|
KubeadmCertEtcdAPIClient = KubeadmCert{
|
||||||
Name: "etcd-api-client",
|
Name: "apiserver-etcd-client",
|
||||||
|
LongName: "client apiserver uses to access etcd",
|
||||||
BaseName: kubeadmconstants.APIServerEtcdClientCertAndKeyBaseName,
|
BaseName: kubeadmconstants.APIServerEtcdClientCertAndKeyBaseName,
|
||||||
CAName: "etcd-ca",
|
CAName: "etcd-ca",
|
||||||
config: certutil.Config{
|
config: certutil.Config{
|
||||||
@ -288,7 +329,7 @@ func makeAltNamesMutator(f func(*kubeadmapi.InitConfiguration) (*certutil.AltNam
|
|||||||
return func(mc *kubeadmapi.InitConfiguration, cc *certutil.Config) error {
|
return func(mc *kubeadmapi.InitConfiguration, cc *certutil.Config) error {
|
||||||
altNames, err := f(mc)
|
altNames, err := f(mc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return err
|
||||||
}
|
}
|
||||||
cc.AltNames = *altNames
|
cc.AltNames = *altNames
|
||||||
return nil
|
return nil
|
||||||
|
@ -66,186 +66,6 @@ func CreatePKIAssets(cfg *kubeadmapi.InitConfiguration) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateCACertAndKeyFiles create a new self signed cluster CA certificate and key files.
|
|
||||||
// If the CA certificate and key files already exists in the target folder, they are used only if evaluated equal; otherwise an error is returned.
|
|
||||||
func CreateCACertAndKeyFiles(cfg *kubeadmapi.InitConfiguration) error {
|
|
||||||
glog.V(1).Infoln("create a new self signed cluster CA certificate and key files")
|
|
||||||
caCert, caKey, err := NewCACertAndKey()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return writeCertificateAuthorithyFilesIfNotExist(
|
|
||||||
cfg.CertificatesDir,
|
|
||||||
kubeadmconstants.CACertAndKeyBaseName,
|
|
||||||
caCert,
|
|
||||||
caKey,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateAPIServerCertAndKeyFiles create a new certificate and key files for the apiserver.
|
|
||||||
// If the apiserver certificate and key files already exists in the target folder, they are used only if evaluated equal; otherwise an error is returned.
|
|
||||||
// It assumes the cluster CA certificate and key files exist in the CertificatesDir.
|
|
||||||
func CreateAPIServerCertAndKeyFiles(cfg *kubeadmapi.InitConfiguration) error {
|
|
||||||
glog.V(1).Infoln("creating a new certificate and key files for the apiserver")
|
|
||||||
caCert, caKey, err := loadCertificateAuthority(cfg.CertificatesDir, kubeadmconstants.CACertAndKeyBaseName)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
apiCert, apiKey, err := NewAPIServerCertAndKey(cfg, caCert, caKey)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return writeCertificateFilesIfNotExist(
|
|
||||||
cfg.CertificatesDir,
|
|
||||||
kubeadmconstants.APIServerCertAndKeyBaseName,
|
|
||||||
caCert,
|
|
||||||
apiCert,
|
|
||||||
apiKey,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateAPIServerKubeletClientCertAndKeyFiles create a new certificate for kubelets calling apiserver.
|
|
||||||
// If the apiserver-kubelet-client certificate and key files already exists in the target folder, they are used only if evaluated equals; otherwise an error is returned.
|
|
||||||
// It assumes the cluster CA certificate and key files exist in the CertificatesDir.
|
|
||||||
func CreateAPIServerKubeletClientCertAndKeyFiles(cfg *kubeadmapi.InitConfiguration) error {
|
|
||||||
glog.V(1).Infoln("creating a new certificate for kubelets calling apiserver")
|
|
||||||
caCert, caKey, err := loadCertificateAuthority(cfg.CertificatesDir, kubeadmconstants.CACertAndKeyBaseName)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
apiKubeletClientCert, apiKubeletClientKey, err := NewAPIServerKubeletClientCertAndKey(cfg, caCert, caKey)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return writeCertificateFilesIfNotExist(
|
|
||||||
cfg.CertificatesDir,
|
|
||||||
kubeadmconstants.APIServerKubeletClientCertAndKeyBaseName,
|
|
||||||
caCert,
|
|
||||||
apiKubeletClientCert,
|
|
||||||
apiKubeletClientKey,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateEtcdCACertAndKeyFiles create a self signed etcd CA certificate and key files.
|
|
||||||
// The etcd CA and client certs are used to secure communication between etcd peers and connections to etcd from the API server.
|
|
||||||
// This is a separate CA, so that kubernetes client identities cannot connect to etcd directly or peer with the etcd cluster.
|
|
||||||
// If the etcd CA certificate and key files already exists in the target folder, they are used only if evaluated equals; otherwise an error is returned.
|
|
||||||
func CreateEtcdCACertAndKeyFiles(cfg *kubeadmapi.InitConfiguration) error {
|
|
||||||
glog.V(1).Infoln("creating a self signed etcd CA certificate and key files")
|
|
||||||
etcdCACert, etcdCAKey, err := NewEtcdCACertAndKey()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return writeCertificateAuthorithyFilesIfNotExist(
|
|
||||||
cfg.CertificatesDir,
|
|
||||||
kubeadmconstants.EtcdCACertAndKeyBaseName,
|
|
||||||
etcdCACert,
|
|
||||||
etcdCAKey,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateEtcdServerCertAndKeyFiles create a new certificate and key file for etcd.
|
|
||||||
// If the etcd serving certificate and key file already exist in the target folder, they are used only if evaluated equal; otherwise an error is returned.
|
|
||||||
// It assumes the etcd CA certificate and key file exist in the CertificatesDir
|
|
||||||
func CreateEtcdServerCertAndKeyFiles(cfg *kubeadmapi.InitConfiguration) error {
|
|
||||||
glog.V(1).Infoln("creating a new server certificate and key files for etcd")
|
|
||||||
etcdCACert, etcdCAKey, err := loadCertificateAuthority(cfg.CertificatesDir, kubeadmconstants.EtcdCACertAndKeyBaseName)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
etcdServerCert, etcdServerKey, err := NewEtcdServerCertAndKey(cfg, etcdCACert, etcdCAKey)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return writeCertificateFilesIfNotExist(
|
|
||||||
cfg.CertificatesDir,
|
|
||||||
kubeadmconstants.EtcdServerCertAndKeyBaseName,
|
|
||||||
etcdCACert,
|
|
||||||
etcdServerCert,
|
|
||||||
etcdServerKey,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateEtcdPeerCertAndKeyFiles create a new certificate and key file for etcd peering.
|
|
||||||
// If the etcd peer certificate and key file already exist in the target folder, they are used only if evaluated equal; otherwise an error is returned.
|
|
||||||
// It assumes the etcd CA certificate and key file exist in the CertificatesDir
|
|
||||||
func CreateEtcdPeerCertAndKeyFiles(cfg *kubeadmapi.InitConfiguration) error {
|
|
||||||
glog.V(1).Infoln("creating a new certificate and key files for etcd peering")
|
|
||||||
etcdCACert, etcdCAKey, err := loadCertificateAuthority(cfg.CertificatesDir, kubeadmconstants.EtcdCACertAndKeyBaseName)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
etcdPeerCert, etcdPeerKey, err := NewEtcdPeerCertAndKey(cfg, etcdCACert, etcdCAKey)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return writeCertificateFilesIfNotExist(
|
|
||||||
cfg.CertificatesDir,
|
|
||||||
kubeadmconstants.EtcdPeerCertAndKeyBaseName,
|
|
||||||
etcdCACert,
|
|
||||||
etcdPeerCert,
|
|
||||||
etcdPeerKey,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateEtcdHealthcheckClientCertAndKeyFiles create a new client certificate for liveness probes to healthcheck etcd
|
|
||||||
// If the etcd-healthcheck-client certificate and key file already exist in the target folder, they are used only if evaluated equal; otherwise an error is returned.
|
|
||||||
// It assumes the etcd CA certificate and key file exist in the CertificatesDir
|
|
||||||
func CreateEtcdHealthcheckClientCertAndKeyFiles(cfg *kubeadmapi.InitConfiguration) error {
|
|
||||||
|
|
||||||
etcdCACert, etcdCAKey, err := loadCertificateAuthority(cfg.CertificatesDir, kubeadmconstants.EtcdCACertAndKeyBaseName)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
etcdHealthcheckClientCert, etcdHealthcheckClientKey, err := NewEtcdHealthcheckClientCertAndKey(cfg, etcdCACert, etcdCAKey)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return writeCertificateFilesIfNotExist(
|
|
||||||
cfg.CertificatesDir,
|
|
||||||
kubeadmconstants.EtcdHealthcheckClientCertAndKeyBaseName,
|
|
||||||
etcdCACert,
|
|
||||||
etcdHealthcheckClientCert,
|
|
||||||
etcdHealthcheckClientKey,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateAPIServerEtcdClientCertAndKeyFiles create a new client certificate for the apiserver calling etcd
|
|
||||||
// If the apiserver-etcd-client certificate and key file already exist in the target folder, they are used only if evaluated equal; otherwise an error is returned.
|
|
||||||
// It assumes the etcd CA certificate and key file exist in the CertificatesDir
|
|
||||||
func CreateAPIServerEtcdClientCertAndKeyFiles(cfg *kubeadmapi.InitConfiguration) error {
|
|
||||||
glog.V(1).Infoln("creating a new client certificate for the apiserver calling etcd")
|
|
||||||
etcdCACert, etcdCAKey, err := loadCertificateAuthority(cfg.CertificatesDir, kubeadmconstants.EtcdCACertAndKeyBaseName)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
apiEtcdClientCert, apiEtcdClientKey, err := NewAPIServerEtcdClientCertAndKey(cfg, etcdCACert, etcdCAKey)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return writeCertificateFilesIfNotExist(
|
|
||||||
cfg.CertificatesDir,
|
|
||||||
kubeadmconstants.APIServerEtcdClientCertAndKeyBaseName,
|
|
||||||
etcdCACert,
|
|
||||||
apiEtcdClientCert,
|
|
||||||
apiEtcdClientKey,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateServiceAccountKeyAndPublicKeyFiles create a new public/private key files for signing service account users.
|
// CreateServiceAccountKeyAndPublicKeyFiles create a new public/private key files for signing service account users.
|
||||||
// If the sa public/private key files already exists in the target folder, they are used only if evaluated equals; otherwise an error is returned.
|
// If the sa public/private key files already exists in the target folder, they are used only if evaluated equals; otherwise an error is returned.
|
||||||
func CreateServiceAccountKeyAndPublicKeyFiles(cfg *kubeadmapi.InitConfiguration) error {
|
func CreateServiceAccountKeyAndPublicKeyFiles(cfg *kubeadmapi.InitConfiguration) error {
|
||||||
@ -262,118 +82,8 @@ func CreateServiceAccountKeyAndPublicKeyFiles(cfg *kubeadmapi.InitConfiguration)
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateFrontProxyCACertAndKeyFiles create a self signed front proxy CA certificate and key files.
|
|
||||||
// Front proxy CA and client certs are used to secure a front proxy authenticator which is used to assert identity
|
|
||||||
// without the client cert; This is a separate CA, so that front proxy identities cannot hit the API and normal client certs cannot be used
|
|
||||||
// as front proxies.
|
|
||||||
// If the front proxy CA certificate and key files already exists in the target folder, they are used only if evaluated equals; otherwise an error is returned.
|
|
||||||
func CreateFrontProxyCACertAndKeyFiles(cfg *kubeadmapi.InitConfiguration) error {
|
|
||||||
glog.V(1).Infoln("creating a self signed front proxy CA certificate and key files")
|
|
||||||
frontProxyCACert, frontProxyCAKey, err := NewFrontProxyCACertAndKey()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return writeCertificateAuthorithyFilesIfNotExist(
|
|
||||||
cfg.CertificatesDir,
|
|
||||||
kubeadmconstants.FrontProxyCACertAndKeyBaseName,
|
|
||||||
frontProxyCACert,
|
|
||||||
frontProxyCAKey,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateFrontProxyClientCertAndKeyFiles create a new certificate for proxy server client.
|
|
||||||
// If the front-proxy-client certificate and key files already exists in the target folder, they are used only if evaluated equals; otherwise an error is returned.
|
|
||||||
// It assumes the front proxy CA certificate and key files exist in the CertificatesDir.
|
|
||||||
func CreateFrontProxyClientCertAndKeyFiles(cfg *kubeadmapi.InitConfiguration) error {
|
|
||||||
glog.V(1).Infoln("creating a new certificate for proxy server client")
|
|
||||||
frontProxyCACert, frontProxyCAKey, err := loadCertificateAuthority(cfg.CertificatesDir, kubeadmconstants.FrontProxyCACertAndKeyBaseName)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
frontProxyClientCert, frontProxyClientKey, err := NewFrontProxyClientCertAndKey(cfg, frontProxyCACert, frontProxyCAKey)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return writeCertificateFilesIfNotExist(
|
|
||||||
cfg.CertificatesDir,
|
|
||||||
kubeadmconstants.FrontProxyClientCertAndKeyBaseName,
|
|
||||||
frontProxyCACert,
|
|
||||||
frontProxyClientCert,
|
|
||||||
frontProxyClientKey,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewCACertAndKey will generate a self signed CA.
|
|
||||||
func NewCACertAndKey() (*x509.Certificate, *rsa.PrivateKey, error) {
|
|
||||||
|
|
||||||
caCert, caKey, err := pkiutil.NewCertificateAuthority()
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, fmt.Errorf("failure while generating CA certificate and key: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return caCert, caKey, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func newCertAndKeyFromSpec(certSpec *KubeadmCert, cfg *kubeadmapi.InitConfiguration, caCert *x509.Certificate, caKey *rsa.PrivateKey) (*x509.Certificate, *rsa.PrivateKey, error) {
|
|
||||||
certConfig, err := certSpec.GetConfig(cfg)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, fmt.Errorf("failure while creating certificate %s: %v", certSpec.Name, err)
|
|
||||||
}
|
|
||||||
cert, key, err := pkiutil.NewCertAndKey(caCert, caKey, *certConfig)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, fmt.Errorf("failure while creating %s key and certificate: %v", certSpec.Name, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return cert, key, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewAPIServerCertAndKey generate certificate for apiserver, signed by the given CA.
|
|
||||||
func NewAPIServerCertAndKey(cfg *kubeadmapi.InitConfiguration, caCert *x509.Certificate, caKey *rsa.PrivateKey) (*x509.Certificate, *rsa.PrivateKey, error) {
|
|
||||||
return newCertAndKeyFromSpec(&KubeadmCertAPIServer, cfg, caCert, caKey)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewAPIServerKubeletClientCertAndKey generate certificate for the apiservers to connect to the kubelets securely, signed by the given CA.
|
|
||||||
func NewAPIServerKubeletClientCertAndKey(cfg *kubeadmapi.InitConfiguration, caCert *x509.Certificate, caKey *rsa.PrivateKey) (*x509.Certificate, *rsa.PrivateKey, error) {
|
|
||||||
return newCertAndKeyFromSpec(&KubeadmCertKubeletClient, cfg, caCert, caKey)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewEtcdCACertAndKey generate a self signed etcd CA.
|
|
||||||
func NewEtcdCACertAndKey() (*x509.Certificate, *rsa.PrivateKey, error) {
|
|
||||||
|
|
||||||
etcdCACert, etcdCAKey, err := pkiutil.NewCertificateAuthority()
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, fmt.Errorf("failure while generating etcd CA certificate and key: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return etcdCACert, etcdCAKey, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewEtcdServerCertAndKey generate certificate for etcd, signed by the given CA.
|
|
||||||
func NewEtcdServerCertAndKey(cfg *kubeadmapi.InitConfiguration, caCert *x509.Certificate, caKey *rsa.PrivateKey) (*x509.Certificate, *rsa.PrivateKey, error) {
|
|
||||||
return newCertAndKeyFromSpec(&KubeadmCertEtcdServer, cfg, caCert, caKey)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewEtcdPeerCertAndKey generate certificate for etcd peering, signed by the given CA.
|
|
||||||
func NewEtcdPeerCertAndKey(cfg *kubeadmapi.InitConfiguration, caCert *x509.Certificate, caKey *rsa.PrivateKey) (*x509.Certificate, *rsa.PrivateKey, error) {
|
|
||||||
return newCertAndKeyFromSpec(&KubeadmCertEtcdPeer, cfg, caCert, caKey)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewEtcdHealthcheckClientCertAndKey generate certificate for liveness probes to healthcheck etcd, signed by the given CA.
|
|
||||||
func NewEtcdHealthcheckClientCertAndKey(cfg *kubeadmapi.InitConfiguration, caCert *x509.Certificate, caKey *rsa.PrivateKey) (*x509.Certificate, *rsa.PrivateKey, error) {
|
|
||||||
return newCertAndKeyFromSpec(&KubeadmCertEtcdHealthcheck, cfg, caCert, caKey)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewAPIServerEtcdClientCertAndKey generate certificate for the apiservers to connect to etcd securely, signed by the given CA.
|
|
||||||
func NewAPIServerEtcdClientCertAndKey(cfg *kubeadmapi.InitConfiguration, caCert *x509.Certificate, caKey *rsa.PrivateKey) (*x509.Certificate, *rsa.PrivateKey, error) {
|
|
||||||
return newCertAndKeyFromSpec(&KubeadmCertEtcdHealthcheck, cfg, caCert, caKey)
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewServiceAccountSigningKey generate public/private key pairs for signing service account tokens.
|
// NewServiceAccountSigningKey generate public/private key pairs for signing service account tokens.
|
||||||
func NewServiceAccountSigningKey() (*rsa.PrivateKey, error) {
|
func NewServiceAccountSigningKey() (*rsa.PrivateKey, error) {
|
||||||
|
|
||||||
// The key does NOT exist, let's generate it now
|
// The key does NOT exist, let's generate it now
|
||||||
saSigningKey, err := certutil.NewPrivateKey()
|
saSigningKey, err := certutil.NewPrivateKey()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -383,23 +93,71 @@ func NewServiceAccountSigningKey() (*rsa.PrivateKey, error) {
|
|||||||
return saSigningKey, nil
|
return saSigningKey, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFrontProxyCACertAndKey generate a self signed front proxy CA.
|
// NewCACertAndKey will generate a self signed CA.
|
||||||
func NewFrontProxyCACertAndKey() (*x509.Certificate, *rsa.PrivateKey, error) {
|
func NewCACertAndKey(certSpec *certutil.Config) (*x509.Certificate, *rsa.PrivateKey, error) {
|
||||||
|
|
||||||
frontProxyCACert, frontProxyCAKey, err := pkiutil.NewCertificateAuthority()
|
caCert, caKey, err := pkiutil.NewCertificateAuthority(certSpec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("failure while generating front-proxy CA certificate and key: %v", err)
|
return nil, nil, fmt.Errorf("failure while generating CA certificate and key: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return frontProxyCACert, frontProxyCAKey, nil
|
return caCert, caKey, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFrontProxyClientCertAndKey generate certificate for proxy server client, signed by the given front proxy CA.
|
// CreateCACertAndKeyFiles generates and writes out a given certificate authority.
|
||||||
func NewFrontProxyClientCertAndKey(cfg *kubeadmapi.InitConfiguration, caCert *x509.Certificate, caKey *rsa.PrivateKey) (*x509.Certificate, *rsa.PrivateKey, error) {
|
// The certSpec should be one of the variables from this package.
|
||||||
return newCertAndKeyFromSpec(&KubeadmCertFrontProxyClient, cfg, caCert, caKey)
|
func CreateCACertAndKeyFiles(certSpec *KubeadmCert, cfg *kubeadmapi.InitConfiguration) error {
|
||||||
|
if certSpec.CAName != "" {
|
||||||
|
return fmt.Errorf("This function should only be used for CAs, but cert %s has CA %s", certSpec.Name, certSpec.CAName)
|
||||||
|
}
|
||||||
|
glog.V(1).Infoln("creating a new certificate authority for %s", certSpec.Name)
|
||||||
|
|
||||||
|
certConfig, err := certSpec.GetConfig(cfg)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
caCert, caKey, err := NewCACertAndKey(certConfig)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return writeCertificateAuthorithyFilesIfNotExist(
|
||||||
|
cfg.CertificatesDir,
|
||||||
|
certSpec.BaseName,
|
||||||
|
caCert,
|
||||||
|
caKey,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateCertAndKeyFilesWithCA loads the given certificate authority from disk, then generates and writes out the given certificate and key.
|
||||||
|
// The certSpec and caCertSpec should both be one of the variables from this package.
|
||||||
|
func CreateCertAndKeyFilesWithCA(certSpec *KubeadmCert, caCertSpec *KubeadmCert, cfg *kubeadmapi.InitConfiguration) error {
|
||||||
|
if certSpec.CAName != caCertSpec.Name {
|
||||||
|
return fmt.Errorf("Expected CAname for %s to be %q, but was %s", certSpec.Name, certSpec.CAName, caCertSpec.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
caCert, caKey, err := loadCertificateAuthority(cfg.CertificatesDir, caCertSpec.BaseName)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Couldn't load CA certificate %s: %v", caCertSpec.Name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return certSpec.CreateFromCA(cfg, caCert, caKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
func newCertAndKeyFromSpec(certSpec *KubeadmCert, cfg *kubeadmapi.InitConfiguration, caCert *x509.Certificate, caKey *rsa.PrivateKey) (*x509.Certificate, *rsa.PrivateKey, error) {
|
||||||
|
certConfig, err := certSpec.GetConfig(cfg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("failure while creating certificate %s: %v", certSpec.Name, err)
|
||||||
|
}
|
||||||
|
cert, key, err := pkiutil.NewCertAndKey(caCert, caKey, certConfig)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, fmt.Errorf("failure while creating %s key and certificate: %v", certSpec.Name, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return cert, key, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// loadCertificateAuthority loads certificate authority
|
|
||||||
func loadCertificateAuthority(pkiDir string, baseName string) (*x509.Certificate, *rsa.PrivateKey, error) {
|
func loadCertificateAuthority(pkiDir string, baseName string) (*x509.Certificate, *rsa.PrivateKey, error) {
|
||||||
// Checks if certificate authority exists in the PKI directory
|
// Checks if certificate authority exists in the PKI directory
|
||||||
if !pkiutil.CertOrKeyExist(pkiDir, baseName) {
|
if !pkiutil.CertOrKeyExist(pkiDir, baseName) {
|
||||||
@ -422,7 +180,7 @@ func loadCertificateAuthority(pkiDir string, baseName string) (*x509.Certificate
|
|||||||
|
|
||||||
// writeCertificateAuthorithyFilesIfNotExist write a new certificate Authority to the given path.
|
// writeCertificateAuthorithyFilesIfNotExist write a new certificate Authority to the given path.
|
||||||
// If there already is a certificate file at the given path; kubeadm tries to load it and check if the values in the
|
// If there already is a certificate file at the given path; kubeadm tries to load it and check if the values in the
|
||||||
// existing and the expected certificate equals. If they do; kubeadm will just skip writing the file as it's up-to-date,
|
// existing and the eexpected certificate equals. If they do; kubeadm will just skip writing the file as it's up-to-date,
|
||||||
// otherwise this function returns an error.
|
// otherwise this function returns an error.
|
||||||
func writeCertificateAuthorithyFilesIfNotExist(pkiDir string, baseName string, caCert *x509.Certificate, caKey *rsa.PrivateKey) error {
|
func writeCertificateAuthorithyFilesIfNotExist(pkiDir string, baseName string, caCert *x509.Certificate, caKey *rsa.PrivateKey) error {
|
||||||
|
|
||||||
|
@ -20,11 +20,12 @@ import (
|
|||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
certutil "k8s.io/client-go/util/cert"
|
||||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/pkiutil"
|
"k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/pkiutil"
|
||||||
@ -32,10 +33,30 @@ import (
|
|||||||
certstestutil "k8s.io/kubernetes/cmd/kubeadm/test/certs"
|
certstestutil "k8s.io/kubernetes/cmd/kubeadm/test/certs"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestWriteCertificateAuthorithyFilesIfNotExist(t *testing.T) {
|
func createCACert(t *testing.T) (*x509.Certificate, *rsa.PrivateKey) {
|
||||||
|
certCfg := &certutil.Config{CommonName: "kubernetes"}
|
||||||
|
cert, key, err := NewCACertAndKey(certCfg)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("couldn't create CA: %v", err)
|
||||||
|
}
|
||||||
|
return cert, key
|
||||||
|
}
|
||||||
|
|
||||||
setupCert, setupKey, _ := NewCACertAndKey()
|
func createTestCert(t *testing.T, caCert *x509.Certificate, caKey *rsa.PrivateKey) (*x509.Certificate, *rsa.PrivateKey) {
|
||||||
caCert, caKey, _ := NewCACertAndKey()
|
cert, key, err := pkiutil.NewCertAndKey(caCert, caKey,
|
||||||
|
&certutil.Config{
|
||||||
|
CommonName: "testCert",
|
||||||
|
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageAny},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("couldn't create test cert: %v", err)
|
||||||
|
}
|
||||||
|
return cert, key
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestWriteCertificateAuthorithyFilesIfNotExist(t *testing.T) {
|
||||||
|
setupCert, setupKey := createCACert(t)
|
||||||
|
caCert, caKey := createCACert(t)
|
||||||
|
|
||||||
var tests = []struct {
|
var tests = []struct {
|
||||||
setupFunc func(pkiDir string) error
|
setupFunc func(pkiDir string) error
|
||||||
@ -60,7 +81,7 @@ func TestWriteCertificateAuthorithyFilesIfNotExist(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{ // cert exists, but it is not a ca > err
|
{ // cert exists, but it is not a ca > err
|
||||||
setupFunc: func(pkiDir string) error {
|
setupFunc: func(pkiDir string) error {
|
||||||
cert, key, _ := NewFrontProxyClientCertAndKey(&kubeadmapi.InitConfiguration{}, setupCert, setupKey)
|
cert, key := createTestCert(t, setupCert, setupKey)
|
||||||
return writeCertificateFilesIfNotExist(pkiDir, "dummy", setupCert, cert, key)
|
return writeCertificateFilesIfNotExist(pkiDir, "dummy", setupCert, cert, key)
|
||||||
},
|
},
|
||||||
expectedError: true,
|
expectedError: true,
|
||||||
@ -110,9 +131,9 @@ func TestWriteCertificateAuthorithyFilesIfNotExist(t *testing.T) {
|
|||||||
|
|
||||||
func TestWriteCertificateFilesIfNotExist(t *testing.T) {
|
func TestWriteCertificateFilesIfNotExist(t *testing.T) {
|
||||||
|
|
||||||
caCert, caKey, _ := NewFrontProxyCACertAndKey()
|
caCert, caKey := createCACert(t)
|
||||||
setupCert, setupKey, _ := NewFrontProxyClientCertAndKey(&kubeadmapi.InitConfiguration{}, caCert, caKey)
|
setupCert, setupKey := createTestCert(t, caCert, caKey)
|
||||||
cert, key, _ := NewFrontProxyClientCertAndKey(&kubeadmapi.InitConfiguration{}, caCert, caKey)
|
cert, key := createTestCert(t, caCert, caKey)
|
||||||
|
|
||||||
var tests = []struct {
|
var tests = []struct {
|
||||||
setupFunc func(pkiDir string) error
|
setupFunc func(pkiDir string) error
|
||||||
@ -137,8 +158,8 @@ func TestWriteCertificateFilesIfNotExist(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{ // cert exists, is signed by another ca > err
|
{ // cert exists, is signed by another ca > err
|
||||||
setupFunc: func(pkiDir string) error {
|
setupFunc: func(pkiDir string) error {
|
||||||
anotherCaCert, anotherCaKey, _ := NewFrontProxyCACertAndKey()
|
anotherCaCert, anotherCaKey := createCACert(t)
|
||||||
anotherCert, anotherKey, _ := NewFrontProxyClientCertAndKey(&kubeadmapi.InitConfiguration{}, anotherCaCert, anotherCaKey)
|
anotherCert, anotherKey := createTestCert(t, anotherCaCert, anotherCaKey)
|
||||||
|
|
||||||
return writeCertificateFilesIfNotExist(pkiDir, "dummy", anotherCaCert, anotherCert, anotherKey)
|
return writeCertificateFilesIfNotExist(pkiDir, "dummy", anotherCaCert, anotherCert, anotherKey)
|
||||||
},
|
},
|
||||||
@ -259,7 +280,8 @@ func TestWriteKeyFilesIfNotExist(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestNewCACertAndKey(t *testing.T) {
|
func TestNewCACertAndKey(t *testing.T) {
|
||||||
caCert, _, err := NewCACertAndKey()
|
certCfg := &certutil.Config{CommonName: "kubernetes"}
|
||||||
|
caCert, _, err := NewCACertAndKey(certCfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed call NewCACertAndKey: %v", err)
|
t.Fatalf("failed call NewCACertAndKey: %v", err)
|
||||||
}
|
}
|
||||||
@ -267,269 +289,90 @@ func TestNewCACertAndKey(t *testing.T) {
|
|||||||
certstestutil.AssertCertificateIsCa(t, caCert)
|
certstestutil.AssertCertificateIsCa(t, caCert)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewAPIServerCertAndKey(t *testing.T) {
|
|
||||||
hostname := "valid-hostname"
|
|
||||||
|
|
||||||
advertiseAddresses := []string{"1.2.3.4", "1:2:3::4"}
|
|
||||||
for _, addr := range advertiseAddresses {
|
|
||||||
cfg := &kubeadmapi.InitConfiguration{
|
|
||||||
API: kubeadmapi.API{AdvertiseAddress: addr},
|
|
||||||
Networking: kubeadmapi.Networking{ServiceSubnet: "10.96.0.0/12", DNSDomain: "cluster.local"},
|
|
||||||
NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: hostname},
|
|
||||||
}
|
|
||||||
caCert, caKey, err := NewCACertAndKey()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed creation of ca cert and key: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
apiServerCert, _, err := NewAPIServerCertAndKey(cfg, caCert, caKey)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed creation of cert and key: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
certstestutil.AssertCertificateIsSignedByCa(t, apiServerCert, caCert)
|
|
||||||
certstestutil.AssertCertificateHasServerAuthUsage(t, apiServerCert)
|
|
||||||
certstestutil.AssertCertificateHasDNSNames(t, apiServerCert, hostname, "kubernetes", "kubernetes.default", "kubernetes.default.svc", "kubernetes.default.svc.cluster.local")
|
|
||||||
certstestutil.AssertCertificateHasIPAddresses(t, apiServerCert, net.ParseIP("10.96.0.1"), net.ParseIP(addr))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNewAPIServerKubeletClientCertAndKey(t *testing.T) {
|
|
||||||
caCert, caKey, err := NewCACertAndKey()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed creation of ca cert and key: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
apiKubeletClientCert, _, err := NewAPIServerKubeletClientCertAndKey(&kubeadmapi.InitConfiguration{}, caCert, caKey)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed creation of cert and key: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
certstestutil.AssertCertificateIsSignedByCa(t, apiKubeletClientCert, caCert)
|
|
||||||
certstestutil.AssertCertificateHasClientAuthUsage(t, apiKubeletClientCert)
|
|
||||||
certstestutil.AssertCertificateHasOrganizations(t, apiKubeletClientCert, kubeadmconstants.MastersGroup)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNewEtcdCACertAndKey(t *testing.T) {
|
|
||||||
etcdCACert, _, err := NewEtcdCACertAndKey()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed creation of cert and key: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
certstestutil.AssertCertificateIsCa(t, etcdCACert)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNewEtcdServerCertAndKey(t *testing.T) {
|
|
||||||
proxy := "user-etcd-proxy"
|
|
||||||
proxyIP := "10.10.10.100"
|
|
||||||
|
|
||||||
cfg := &kubeadmapi.InitConfiguration{
|
|
||||||
NodeRegistration: kubeadmapi.NodeRegistrationOptions{
|
|
||||||
Name: "etcd-server-cert",
|
|
||||||
},
|
|
||||||
Etcd: kubeadmapi.Etcd{
|
|
||||||
Local: &kubeadmapi.LocalEtcd{
|
|
||||||
ServerCertSANs: []string{
|
|
||||||
proxy,
|
|
||||||
proxyIP,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
caCert, caKey, err := NewCACertAndKey()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed creation of ca cert and key: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
etcdServerCert, _, err := NewEtcdServerCertAndKey(cfg, caCert, caKey)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed creation of cert and key: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
certstestutil.AssertCertificateIsSignedByCa(t, etcdServerCert, caCert)
|
|
||||||
certstestutil.AssertCertificateHasServerAuthUsage(t, etcdServerCert)
|
|
||||||
certstestutil.AssertCertificateHasDNSNames(t, etcdServerCert, "localhost", proxy)
|
|
||||||
certstestutil.AssertCertificateHasIPAddresses(t, etcdServerCert, net.ParseIP("127.0.0.1"), net.ParseIP(proxyIP))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNewEtcdPeerCertAndKey(t *testing.T) {
|
|
||||||
hostname := "valid-hostname"
|
|
||||||
proxy := "user-etcd-proxy"
|
|
||||||
proxyIP := "10.10.10.100"
|
|
||||||
|
|
||||||
advertiseAddresses := []string{"1.2.3.4", "1:2:3::4"}
|
|
||||||
for _, addr := range advertiseAddresses {
|
|
||||||
cfg := &kubeadmapi.InitConfiguration{
|
|
||||||
API: kubeadmapi.API{AdvertiseAddress: addr},
|
|
||||||
NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: hostname},
|
|
||||||
Etcd: kubeadmapi.Etcd{
|
|
||||||
Local: &kubeadmapi.LocalEtcd{
|
|
||||||
PeerCertSANs: []string{
|
|
||||||
proxy,
|
|
||||||
proxyIP,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
caCert, caKey, err := NewCACertAndKey()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed creation of ca cert and key: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
etcdPeerCert, _, err := NewEtcdPeerCertAndKey(cfg, caCert, caKey)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed creation of cert and key: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
certstestutil.AssertCertificateIsSignedByCa(t, etcdPeerCert, caCert)
|
|
||||||
certstestutil.AssertCertificateHasServerAuthUsage(t, etcdPeerCert)
|
|
||||||
certstestutil.AssertCertificateHasClientAuthUsage(t, etcdPeerCert)
|
|
||||||
certstestutil.AssertCertificateHasDNSNames(t, etcdPeerCert, hostname, proxy)
|
|
||||||
certstestutil.AssertCertificateHasIPAddresses(t, etcdPeerCert, net.ParseIP(addr), net.ParseIP(proxyIP))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNewEtcdHealthcheckClientCertAndKey(t *testing.T) {
|
|
||||||
caCert, caKey, err := NewCACertAndKey()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed creation of ca cert and key: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
etcdHealthcheckClientCert, _, err := NewEtcdHealthcheckClientCertAndKey(&kubeadmapi.InitConfiguration{}, caCert, caKey)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed creation of cert and key: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
certstestutil.AssertCertificateIsSignedByCa(t, etcdHealthcheckClientCert, caCert)
|
|
||||||
certstestutil.AssertCertificateHasClientAuthUsage(t, etcdHealthcheckClientCert)
|
|
||||||
certstestutil.AssertCertificateHasOrganizations(t, etcdHealthcheckClientCert, kubeadmconstants.MastersGroup)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNewAPIServerEtcdClientCertAndKey(t *testing.T) {
|
|
||||||
caCert, caKey, err := NewCACertAndKey()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed creation of ca cert and key: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
apiEtcdClientCert, _, err := NewAPIServerEtcdClientCertAndKey(&kubeadmapi.InitConfiguration{}, caCert, caKey)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed creation of cert and key: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
certstestutil.AssertCertificateIsSignedByCa(t, apiEtcdClientCert, caCert)
|
|
||||||
certstestutil.AssertCertificateHasClientAuthUsage(t, apiEtcdClientCert)
|
|
||||||
certstestutil.AssertCertificateHasOrganizations(t, apiEtcdClientCert, kubeadmconstants.MastersGroup)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNewNewServiceAccountSigningKey(t *testing.T) {
|
|
||||||
|
|
||||||
key, err := NewServiceAccountSigningKey()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed creation of key: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if key.N.BitLen() < 2048 {
|
|
||||||
t.Error("Service account signing key has less than 2048 bits size")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNewFrontProxyCACertAndKey(t *testing.T) {
|
|
||||||
frontProxyCACert, _, err := NewFrontProxyCACertAndKey()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed creation of cert and key: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
certstestutil.AssertCertificateIsCa(t, frontProxyCACert)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNewFrontProxyClientCertAndKey(t *testing.T) {
|
|
||||||
frontProxyCACert, frontProxyCAKey, err := NewFrontProxyCACertAndKey()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed creation of ca cert and key: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
frontProxyClientCert, _, err := NewFrontProxyClientCertAndKey(&kubeadmapi.InitConfiguration{}, frontProxyCACert, frontProxyCAKey)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed creation of cert and key: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
certstestutil.AssertCertificateIsSignedByCa(t, frontProxyClientCert, frontProxyCACert)
|
|
||||||
certstestutil.AssertCertificateHasClientAuthUsage(t, frontProxyClientCert)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSharedCertificateExists(t *testing.T) {
|
func TestSharedCertificateExists(t *testing.T) {
|
||||||
|
caCert, caKey := createCACert(t)
|
||||||
|
_, key := createTestCert(t, caCert, caKey)
|
||||||
|
publicKey := &key.PublicKey
|
||||||
|
|
||||||
var tests = []struct {
|
var tests = []struct {
|
||||||
setupFunc func(cfg *kubeadmapi.InitConfiguration)
|
name string
|
||||||
|
files pkiFiles
|
||||||
expectedError bool
|
expectedError bool
|
||||||
}{
|
}{
|
||||||
{ // expected certs exist, pass
|
{
|
||||||
setupFunc: func(cfg *kubeadmapi.InitConfiguration) {
|
name: "success",
|
||||||
CreateCACertAndKeyFiles(cfg)
|
files: pkiFiles{
|
||||||
CreateServiceAccountKeyAndPublicKeyFiles(cfg)
|
"ca.crt": caCert,
|
||||||
CreateFrontProxyCACertAndKeyFiles(cfg)
|
"ca.key": caKey,
|
||||||
|
"front-proxy-ca.crt": caCert,
|
||||||
|
"front-proxy-ca.key": caKey,
|
||||||
|
"sa.pub": publicKey,
|
||||||
|
"sa.key": key,
|
||||||
},
|
},
|
||||||
expectedError: false,
|
|
||||||
},
|
},
|
||||||
{ // expected ca.crt missing
|
{
|
||||||
setupFunc: func(cfg *kubeadmapi.InitConfiguration) {
|
name: "missing ca.crt",
|
||||||
// start from the condition created by the previous tests
|
files: pkiFiles{
|
||||||
os.Remove(filepath.Join(cfg.CertificatesDir, kubeadmconstants.CACertName))
|
"ca.key": caKey,
|
||||||
|
"front-proxy-ca.crt": caCert,
|
||||||
|
"front-proxy-ca.key": caKey,
|
||||||
|
"sa.pub": publicKey,
|
||||||
|
"sa.key": key,
|
||||||
},
|
},
|
||||||
expectedError: true,
|
expectedError: true,
|
||||||
},
|
},
|
||||||
{ // expected sa.key missing
|
{
|
||||||
setupFunc: func(cfg *kubeadmapi.InitConfiguration) {
|
name: "missing sa.key",
|
||||||
// start from the condition created by the previous tests
|
files: pkiFiles{
|
||||||
CreateCACertAndKeyFiles(cfg)
|
"ca.crt": caCert,
|
||||||
os.Remove(filepath.Join(cfg.CertificatesDir, kubeadmconstants.ServiceAccountPublicKeyName))
|
"ca.key": caKey,
|
||||||
|
"front-proxy-ca.crt": caCert,
|
||||||
|
"front-proxy-ca.key": caKey,
|
||||||
|
"sa.pub": publicKey,
|
||||||
},
|
},
|
||||||
expectedError: true,
|
expectedError: true,
|
||||||
},
|
},
|
||||||
{ // expected front-proxy.crt missing
|
{
|
||||||
setupFunc: func(cfg *kubeadmapi.InitConfiguration) {
|
name: "expected front-proxy.crt missing",
|
||||||
// start from the condition created by the previous tests
|
files: pkiFiles{
|
||||||
CreateServiceAccountKeyAndPublicKeyFiles(cfg)
|
"ca.crt": caCert,
|
||||||
os.Remove(filepath.Join(cfg.CertificatesDir, kubeadmconstants.FrontProxyCACertName))
|
"ca.key": caKey,
|
||||||
|
"front-proxy-ca.key": caKey,
|
||||||
|
"sa.pub": publicKey,
|
||||||
|
"sa.key": key,
|
||||||
},
|
},
|
||||||
expectedError: true,
|
expectedError: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpdir := testutil.SetupTempDir(t)
|
|
||||||
defer os.RemoveAll(tmpdir)
|
|
||||||
|
|
||||||
cfg := &kubeadmapi.InitConfiguration{
|
|
||||||
CertificatesDir: tmpdir,
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
// executes setup func (if necessary)
|
t.Run("", func(t *testing.T) {
|
||||||
if test.setupFunc != nil {
|
tmpdir := testutil.SetupTempDir(t)
|
||||||
test.setupFunc(cfg)
|
defer os.RemoveAll(tmpdir)
|
||||||
}
|
|
||||||
|
|
||||||
// executes create func
|
cfg := &kubeadmapi.InitConfiguration{
|
||||||
ret, err := SharedCertificateExists(cfg)
|
CertificatesDir: tmpdir,
|
||||||
|
}
|
||||||
|
|
||||||
if !test.expectedError && err != nil {
|
// created expected keys
|
||||||
t.Errorf("error SharedCertificateExists failed when not expected to fail: %v", err)
|
writePKIFiles(t, tmpdir, test.files)
|
||||||
continue
|
|
||||||
} else if test.expectedError && err == nil {
|
|
||||||
t.Error("error SharedCertificateExists didn't failed when expected")
|
|
||||||
continue
|
|
||||||
} else if test.expectedError {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if ret != (err == nil) {
|
// executes create func
|
||||||
t.Errorf("error SharedCertificateExists returned %v when expected to return %v", ret, err == nil)
|
ret, err := SharedCertificateExists(cfg)
|
||||||
}
|
|
||||||
|
switch {
|
||||||
|
case !test.expectedError && err != nil:
|
||||||
|
t.Errorf("error SharedCertificateExists failed when not expected to fail: %v", err)
|
||||||
|
case test.expectedError && err == nil:
|
||||||
|
t.Errorf("error SharedCertificateExists didn't failed when expected")
|
||||||
|
case ret != (err == nil):
|
||||||
|
t.Errorf("error SharedCertificateExists returned %v when expected to return %v", ret, err == nil)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUsingExternalCA(t *testing.T) {
|
func TestUsingExternalCA(t *testing.T) {
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
setupFuncs []func(cfg *kubeadmapi.InitConfiguration) error
|
setupFuncs []func(cfg *kubeadmapi.InitConfiguration) error
|
||||||
expected bool
|
expected bool
|
||||||
@ -575,17 +418,20 @@ func TestUsingExternalCA(t *testing.T) {
|
|||||||
|
|
||||||
func TestValidateMethods(t *testing.T) {
|
func TestValidateMethods(t *testing.T) {
|
||||||
|
|
||||||
|
caCert, caKey := createCACert(t)
|
||||||
|
cert, key := createTestCert(t, caCert, caKey)
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
setupFuncs []func(cfg *kubeadmapi.InitConfiguration) error
|
files pkiFiles
|
||||||
validateFunc func(l certKeyLocation) error
|
validateFunc func(l certKeyLocation) error
|
||||||
loc certKeyLocation
|
loc certKeyLocation
|
||||||
expectedSuccess bool
|
expectedSuccess bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "validateCACert",
|
name: "validateCACert",
|
||||||
setupFuncs: []func(cfg *kubeadmapi.InitConfiguration) error{
|
files: pkiFiles{
|
||||||
CreateCACertAndKeyFiles,
|
"ca.crt": caCert,
|
||||||
},
|
},
|
||||||
validateFunc: validateCACert,
|
validateFunc: validateCACert,
|
||||||
loc: certKeyLocation{caBaseName: "ca", baseName: "", uxName: "CA"},
|
loc: certKeyLocation{caBaseName: "ca", baseName: "", uxName: "CA"},
|
||||||
@ -593,28 +439,30 @@ func TestValidateMethods(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "validateCACertAndKey (files present)",
|
name: "validateCACertAndKey (files present)",
|
||||||
setupFuncs: []func(cfg *kubeadmapi.InitConfiguration) error{
|
files: pkiFiles{
|
||||||
CreateCACertAndKeyFiles,
|
"ca.crt": caCert,
|
||||||
|
"ca.key": caKey,
|
||||||
},
|
},
|
||||||
validateFunc: validateCACertAndKey,
|
validateFunc: validateCACertAndKey,
|
||||||
loc: certKeyLocation{caBaseName: "ca", baseName: "", uxName: "CA"},
|
loc: certKeyLocation{caBaseName: "ca", baseName: "", uxName: "CA"},
|
||||||
expectedSuccess: true,
|
expectedSuccess: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "validateCACertAndKey (key missing)",
|
files: pkiFiles{
|
||||||
setupFuncs: []func(cfg *kubeadmapi.InitConfiguration) error{
|
"ca.crt": caCert,
|
||||||
CreatePKIAssets,
|
|
||||||
deleteCAKey,
|
|
||||||
},
|
},
|
||||||
|
name: "validateCACertAndKey (key missing)",
|
||||||
validateFunc: validateCACertAndKey,
|
validateFunc: validateCACertAndKey,
|
||||||
loc: certKeyLocation{caBaseName: "ca", baseName: "", uxName: "CA"},
|
loc: certKeyLocation{caBaseName: "ca", baseName: "", uxName: "CA"},
|
||||||
expectedSuccess: false,
|
expectedSuccess: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "validateSignedCert",
|
name: "validateSignedCert",
|
||||||
setupFuncs: []func(cfg *kubeadmapi.InitConfiguration) error{
|
files: pkiFiles{
|
||||||
CreateCACertAndKeyFiles,
|
"ca.crt": caCert,
|
||||||
CreateAPIServerCertAndKeyFiles,
|
"ca.key": caKey,
|
||||||
|
"apiserver.crt": cert,
|
||||||
|
"apiserver.key": key,
|
||||||
},
|
},
|
||||||
validateFunc: validateSignedCert,
|
validateFunc: validateSignedCert,
|
||||||
loc: certKeyLocation{caBaseName: "ca", baseName: "apiserver", uxName: "apiserver"},
|
loc: certKeyLocation{caBaseName: "ca", baseName: "apiserver", uxName: "apiserver"},
|
||||||
@ -622,8 +470,9 @@ func TestValidateMethods(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "validatePrivatePublicKey",
|
name: "validatePrivatePublicKey",
|
||||||
setupFuncs: []func(cfg *kubeadmapi.InitConfiguration) error{
|
files: pkiFiles{
|
||||||
CreateServiceAccountKeyAndPublicKeyFiles,
|
"sa.pub": &key.PublicKey,
|
||||||
|
"sa.key": key,
|
||||||
},
|
},
|
||||||
validateFunc: validatePrivatePublicKey,
|
validateFunc: validatePrivatePublicKey,
|
||||||
loc: certKeyLocation{baseName: "sa", uxName: "service account"},
|
loc: certKeyLocation{baseName: "sa", uxName: "service account"},
|
||||||
@ -632,25 +481,11 @@ func TestValidateMethods(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
|
|
||||||
dir := testutil.SetupTempDir(t)
|
dir := testutil.SetupTempDir(t)
|
||||||
defer os.RemoveAll(dir)
|
defer os.RemoveAll(dir)
|
||||||
test.loc.pkiDir = dir
|
test.loc.pkiDir = dir
|
||||||
|
|
||||||
cfg := &kubeadmapi.InitConfiguration{
|
writePKIFiles(t, dir, test.files)
|
||||||
API: kubeadmapi.API{AdvertiseAddress: "1.2.3.4"},
|
|
||||||
Networking: kubeadmapi.Networking{ServiceSubnet: "10.96.0.0/12", DNSDomain: "cluster.local"},
|
|
||||||
NodeRegistration: kubeadmapi.NodeRegistrationOptions{Name: "valid-hostname"},
|
|
||||||
CertificatesDir: dir,
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println("Testing", test.name)
|
|
||||||
|
|
||||||
for _, f := range test.setupFuncs {
|
|
||||||
if err := f(cfg); err != nil {
|
|
||||||
t.Errorf("error executing setup function: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err := test.validateFunc(test.loc)
|
err := test.validateFunc(test.loc)
|
||||||
if test.expectedSuccess && err != nil {
|
if test.expectedSuccess && err != nil {
|
||||||
@ -661,18 +496,29 @@ func TestValidateMethods(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteCAKey(cfg *kubeadmapi.InitConfiguration) error {
|
type pkiFiles map[string]interface{}
|
||||||
if err := os.Remove(filepath.Join(cfg.CertificatesDir, kubeadmconstants.CAKeyName)); err != nil {
|
|
||||||
return fmt.Errorf("failed removing %s: %v", kubeadmconstants.CAKeyName, err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func deleteFrontProxyCAKey(cfg *kubeadmapi.InitConfiguration) error {
|
func writePKIFiles(t *testing.T, dir string, files pkiFiles) {
|
||||||
if err := os.Remove(filepath.Join(cfg.CertificatesDir, kubeadmconstants.FrontProxyCAKeyName)); err != nil {
|
for filename, body := range files {
|
||||||
return fmt.Errorf("failed removing %s: %v", kubeadmconstants.FrontProxyCAKeyName, err)
|
switch body := body.(type) {
|
||||||
|
case *x509.Certificate:
|
||||||
|
if err := certutil.WriteCert(path.Join(dir, filename), certutil.EncodeCertPEM(body)); err != nil {
|
||||||
|
t.Errorf("unable to write certificate to file %q: [%v]", dir, err)
|
||||||
|
}
|
||||||
|
case *rsa.PublicKey:
|
||||||
|
publicKeyBytes, err := certutil.EncodePublicKeyPEM(body)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unable to write public key to file %q: [%v]", filename, err)
|
||||||
|
}
|
||||||
|
if err := certutil.WriteKey(path.Join(dir, filename), publicKeyBytes); err != nil {
|
||||||
|
t.Errorf("unable to write public key to file %q: [%v]", filename, err)
|
||||||
|
}
|
||||||
|
case *rsa.PrivateKey:
|
||||||
|
if err := certutil.WriteKey(path.Join(dir, filename), certutil.EncodePrivateKeyPEM(body)); err != nil {
|
||||||
|
t.Errorf("unable to write private key to file %q: [%v]", filename, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCreateCertificateFilesMethods(t *testing.T) {
|
func TestCreateCertificateFilesMethods(t *testing.T) {
|
||||||
@ -711,57 +557,6 @@ func TestCreateCertificateFilesMethods(t *testing.T) {
|
|||||||
kubeadmconstants.FrontProxyClientCertName, kubeadmconstants.FrontProxyClientKeyName,
|
kubeadmconstants.FrontProxyClientCertName, kubeadmconstants.FrontProxyClientKeyName,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
createFunc: CreateCACertAndKeyFiles,
|
|
||||||
expectedFiles: []string{kubeadmconstants.CACertName, kubeadmconstants.CAKeyName},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
setupFunc: CreateCACertAndKeyFiles,
|
|
||||||
createFunc: CreateAPIServerCertAndKeyFiles,
|
|
||||||
expectedFiles: []string{kubeadmconstants.APIServerCertName, kubeadmconstants.APIServerKeyName},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
setupFunc: CreateCACertAndKeyFiles,
|
|
||||||
createFunc: CreateAPIServerKubeletClientCertAndKeyFiles,
|
|
||||||
expectedFiles: []string{kubeadmconstants.APIServerKubeletClientCertName, kubeadmconstants.APIServerKubeletClientKeyName},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
createFunc: CreateEtcdCACertAndKeyFiles,
|
|
||||||
expectedFiles: []string{kubeadmconstants.EtcdCACertName, kubeadmconstants.EtcdCAKeyName},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
setupFunc: CreateEtcdCACertAndKeyFiles,
|
|
||||||
createFunc: CreateEtcdServerCertAndKeyFiles,
|
|
||||||
expectedFiles: []string{kubeadmconstants.EtcdServerCertName, kubeadmconstants.EtcdServerKeyName},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
setupFunc: CreateEtcdCACertAndKeyFiles,
|
|
||||||
createFunc: CreateEtcdPeerCertAndKeyFiles,
|
|
||||||
expectedFiles: []string{kubeadmconstants.EtcdPeerCertName, kubeadmconstants.EtcdPeerKeyName},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
setupFunc: CreateEtcdCACertAndKeyFiles,
|
|
||||||
createFunc: CreateEtcdHealthcheckClientCertAndKeyFiles,
|
|
||||||
expectedFiles: []string{kubeadmconstants.EtcdHealthcheckClientCertName, kubeadmconstants.EtcdHealthcheckClientKeyName},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
setupFunc: CreateEtcdCACertAndKeyFiles,
|
|
||||||
createFunc: CreateAPIServerEtcdClientCertAndKeyFiles,
|
|
||||||
expectedFiles: []string{kubeadmconstants.APIServerEtcdClientCertName, kubeadmconstants.APIServerEtcdClientKeyName},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
createFunc: CreateServiceAccountKeyAndPublicKeyFiles,
|
|
||||||
expectedFiles: []string{kubeadmconstants.ServiceAccountPrivateKeyName, kubeadmconstants.ServiceAccountPublicKeyName},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
createFunc: CreateFrontProxyCACertAndKeyFiles,
|
|
||||||
expectedFiles: []string{kubeadmconstants.FrontProxyCACertName, kubeadmconstants.FrontProxyCAKeyName},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
setupFunc: CreateFrontProxyCACertAndKeyFiles,
|
|
||||||
createFunc: CreateFrontProxyClientCertAndKeyFiles,
|
|
||||||
expectedFiles: []string{kubeadmconstants.FrontProxyCACertName, kubeadmconstants.FrontProxyCAKeyName},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
@ -785,14 +580,6 @@ func TestCreateCertificateFilesMethods(t *testing.T) {
|
|||||||
cfg.Etcd.External.Endpoints = []string{"192.168.1.1:2379"}
|
cfg.Etcd.External.Endpoints = []string{"192.168.1.1:2379"}
|
||||||
}
|
}
|
||||||
|
|
||||||
// executes setup func (if necessary)
|
|
||||||
if test.setupFunc != nil {
|
|
||||||
if err := test.setupFunc(cfg); err != nil {
|
|
||||||
t.Errorf("error executing setupFunc: %v", err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// executes create func
|
// executes create func
|
||||||
if err := test.createFunc(cfg); err != nil {
|
if err := test.createFunc(cfg); err != nil {
|
||||||
t.Errorf("error executing createFunc: %v", err)
|
t.Errorf("error executing createFunc: %v", err)
|
||||||
@ -803,3 +590,17 @@ func TestCreateCertificateFilesMethods(t *testing.T) {
|
|||||||
testutil.AssertFileExists(t, tmpdir, test.expectedFiles...)
|
testutil.AssertFileExists(t, tmpdir, test.expectedFiles...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func deleteCAKey(cfg *kubeadmapi.InitConfiguration) error {
|
||||||
|
if err := os.Remove(filepath.Join(cfg.CertificatesDir, kubeadmconstants.CAKeyName)); err != nil {
|
||||||
|
return fmt.Errorf("failed removing %s: %v", kubeadmconstants.CAKeyName, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func deleteFrontProxyCAKey(cfg *kubeadmapi.InitConfiguration) error {
|
||||||
|
if err := os.Remove(filepath.Join(cfg.CertificatesDir, kubeadmconstants.FrontProxyCAKeyName)); err != nil {
|
||||||
|
return fmt.Errorf("failed removing %s: %v", kubeadmconstants.FrontProxyCAKeyName, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -34,16 +34,13 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// NewCertificateAuthority creates new certificate and private key for the certificate authority
|
// NewCertificateAuthority creates new certificate and private key for the certificate authority
|
||||||
func NewCertificateAuthority() (*x509.Certificate, *rsa.PrivateKey, error) {
|
func NewCertificateAuthority(config *certutil.Config) (*x509.Certificate, *rsa.PrivateKey, error) {
|
||||||
key, err := certutil.NewPrivateKey()
|
key, err := certutil.NewPrivateKey()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("unable to create private key [%v]", err)
|
return nil, nil, fmt.Errorf("unable to create private key [%v]", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
config := certutil.Config{
|
cert, err := certutil.NewSelfSignedCACert(*config, key)
|
||||||
CommonName: "kubernetes",
|
|
||||||
}
|
|
||||||
cert, err := certutil.NewSelfSignedCACert(config, key)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("unable to create self-signed certificate [%v]", err)
|
return nil, nil, fmt.Errorf("unable to create self-signed certificate [%v]", err)
|
||||||
}
|
}
|
||||||
@ -52,13 +49,13 @@ func NewCertificateAuthority() (*x509.Certificate, *rsa.PrivateKey, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewCertAndKey creates new certificate and key by passing the certificate authority certificate and key
|
// NewCertAndKey creates new certificate and key by passing the certificate authority certificate and key
|
||||||
func NewCertAndKey(caCert *x509.Certificate, caKey *rsa.PrivateKey, config certutil.Config) (*x509.Certificate, *rsa.PrivateKey, error) {
|
func NewCertAndKey(caCert *x509.Certificate, caKey *rsa.PrivateKey, config *certutil.Config) (*x509.Certificate, *rsa.PrivateKey, error) {
|
||||||
key, err := certutil.NewPrivateKey()
|
key, err := certutil.NewPrivateKey()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("unable to create private key [%v]", err)
|
return nil, nil, fmt.Errorf("unable to create private key [%v]", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cert, err := certutil.NewSignedCert(config, key, caCert, caKey)
|
cert, err := certutil.NewSignedCert(*config, key, caCert, caKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, fmt.Errorf("unable to sign certificate [%v]", err)
|
return nil, nil, fmt.Errorf("unable to sign certificate [%v]", err)
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestNewCertificateAuthority(t *testing.T) {
|
func TestNewCertificateAuthority(t *testing.T) {
|
||||||
cert, key, err := NewCertificateAuthority()
|
cert, key, err := NewCertificateAuthority(&certutil.Config{CommonName: "kubernetes"})
|
||||||
|
|
||||||
if cert == nil {
|
if cert == nil {
|
||||||
t.Errorf(
|
t.Errorf(
|
||||||
@ -73,7 +73,7 @@ func TestNewCertAndKey(t *testing.T) {
|
|||||||
t.Fatalf("Couldn't create rsa Private Key")
|
t.Fatalf("Couldn't create rsa Private Key")
|
||||||
}
|
}
|
||||||
caCert := &x509.Certificate{}
|
caCert := &x509.Certificate{}
|
||||||
config := certutil.Config{
|
config := &certutil.Config{
|
||||||
CommonName: "test",
|
CommonName: "test",
|
||||||
Organization: []string{"test"},
|
Organization: []string{"test"},
|
||||||
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
||||||
@ -90,7 +90,7 @@ func TestNewCertAndKey(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestHasServerAuth(t *testing.T) {
|
func TestHasServerAuth(t *testing.T) {
|
||||||
caCert, caKey, _ := NewCertificateAuthority()
|
caCert, caKey, _ := NewCertificateAuthority(&certutil.Config{CommonName: "kubernetes"})
|
||||||
|
|
||||||
var tests = []struct {
|
var tests = []struct {
|
||||||
config certutil.Config
|
config certutil.Config
|
||||||
@ -113,7 +113,7 @@ func TestHasServerAuth(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, rt := range tests {
|
for _, rt := range tests {
|
||||||
cert, _, err := NewCertAndKey(caCert, caKey, rt.config)
|
cert, _, err := NewCertAndKey(caCert, caKey, &rt.config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Couldn't create cert: %v", err)
|
t.Fatalf("Couldn't create cert: %v", err)
|
||||||
}
|
}
|
||||||
@ -261,7 +261,7 @@ func TestTryLoadCertAndKeyFromDisk(t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer os.RemoveAll(tmpdir)
|
defer os.RemoveAll(tmpdir)
|
||||||
|
|
||||||
caCert, caKey, err := NewCertificateAuthority()
|
caCert, caKey, err := NewCertificateAuthority(&certutil.Config{CommonName: "kubernetes"})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf(
|
t.Errorf(
|
||||||
"failed to create cert and key with an error: %v",
|
"failed to create cert and key with an error: %v",
|
||||||
@ -311,7 +311,7 @@ func TestTryLoadCertFromDisk(t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer os.RemoveAll(tmpdir)
|
defer os.RemoveAll(tmpdir)
|
||||||
|
|
||||||
caCert, _, err := NewCertificateAuthority()
|
caCert, _, err := NewCertificateAuthority(&certutil.Config{CommonName: "kubernetes"})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf(
|
t.Errorf(
|
||||||
"failed to create cert and key with an error: %v",
|
"failed to create cert and key with an error: %v",
|
||||||
@ -361,7 +361,7 @@ func TestTryLoadKeyFromDisk(t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer os.RemoveAll(tmpdir)
|
defer os.RemoveAll(tmpdir)
|
||||||
|
|
||||||
_, caKey, err := NewCertificateAuthority()
|
_, caKey, err := NewCertificateAuthority(&certutil.Config{CommonName: "kubernetes"})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf(
|
t.Errorf(
|
||||||
"failed to create cert and key with an error: %v",
|
"failed to create cert and key with an error: %v",
|
||||||
|
@ -222,7 +222,7 @@ func buildKubeConfigFromSpec(spec *kubeConfigSpec, clustername string) (*clientc
|
|||||||
Organization: spec.ClientCertAuth.Organizations,
|
Organization: spec.ClientCertAuth.Organizations,
|
||||||
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
||||||
}
|
}
|
||||||
clientCert, clientKey, err := pkiutil.NewCertAndKey(spec.CACert, spec.ClientCertAuth.CAKey, clientCertConfig)
|
clientCert, clientKey, err := pkiutil.NewCertAndKey(spec.CACert, spec.ClientCertAuth.CAKey, &clientCertConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failure while creating %s client certificate: %v", spec.ClientName, err)
|
return nil, fmt.Errorf("failure while creating %s client certificate: %v", spec.ClientName, err)
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,6 @@ go_test(
|
|||||||
"//cmd/kubeadm/app/apis/kubeadm/v1alpha3:go_default_library",
|
"//cmd/kubeadm/app/apis/kubeadm/v1alpha3:go_default_library",
|
||||||
"//cmd/kubeadm/app/constants:go_default_library",
|
"//cmd/kubeadm/app/constants:go_default_library",
|
||||||
"//cmd/kubeadm/app/phases/certs: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/controlplane:go_default_library",
|
||||||
"//cmd/kubeadm/app/phases/etcd:go_default_library",
|
"//cmd/kubeadm/app/phases/etcd:go_default_library",
|
||||||
"//cmd/kubeadm/app/util/apiclient:go_default_library",
|
"//cmd/kubeadm/app/util/apiclient:go_default_library",
|
||||||
|
@ -195,7 +195,11 @@ func backupAPIServerCertIfNeeded(cfg *kubeadmapi.InitConfiguration, dryRun bool)
|
|||||||
if err := backupAPIServerCertAndKey(certAndKeyDir); err != nil {
|
if err := backupAPIServerCertAndKey(certAndKeyDir); err != nil {
|
||||||
fmt.Printf("[postupgrade] WARNING: failed to backup kube-apiserver cert and key: %v", err)
|
fmt.Printf("[postupgrade] WARNING: failed to backup kube-apiserver cert and key: %v", err)
|
||||||
}
|
}
|
||||||
return certsphase.CreateAPIServerCertAndKeyFiles(cfg)
|
return certsphase.CreateCertAndKeyFilesWithCA(
|
||||||
|
&certsphase.KubeadmCertAPIServer,
|
||||||
|
&certsphase.KubeadmCertRootCA,
|
||||||
|
cfg,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeKubeletConfigFiles(client clientset.Interface, cfg *kubeadmapi.InitConfiguration, newK8sVer *version.Version, dryRun bool) error {
|
func writeKubeletConfigFiles(client clientset.Interface, cfg *kubeadmapi.InitConfiguration, newK8sVer *version.Version, dryRun bool) error {
|
||||||
|
@ -27,7 +27,6 @@ import (
|
|||||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
"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"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/pkiutil"
|
|
||||||
testutil "k8s.io/kubernetes/cmd/kubeadm/test"
|
testutil "k8s.io/kubernetes/cmd/kubeadm/test"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -148,23 +147,21 @@ func TestShouldBackupAPIServerCertAndKey(t *testing.T) {
|
|||||||
expected: true,
|
expected: true,
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
caCert, caKey, err := certsphase.NewCACertAndKey()
|
tmpdir := testutil.SetupTempDir(t)
|
||||||
|
defer os.RemoveAll(tmpdir)
|
||||||
|
cfg.CertificatesDir = tmpdir
|
||||||
|
|
||||||
|
caCert, caKey, err := certsphase.KubeadmCertRootCA.CreateAsCA(cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed creation of ca cert and key: %v", err)
|
t.Fatalf("failed creation of ca cert and key: %v", err)
|
||||||
}
|
}
|
||||||
caCert.NotBefore = caCert.NotBefore.Add(-test.adjustedExpiry).UTC()
|
caCert.NotBefore = caCert.NotBefore.Add(-test.adjustedExpiry).UTC()
|
||||||
apiCert, apiKey, err := certsphase.NewAPIServerCertAndKey(cfg, caCert, caKey)
|
|
||||||
|
err = certsphase.KubeadmCertAPIServer.CreateFromCA(cfg, caCert, caKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Test %s: failed creation of cert and key: %v", desc, err)
|
t.Fatalf("Test %s: failed creation of cert and key: %v", desc, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpdir := testutil.SetupTempDir(t)
|
|
||||||
defer os.RemoveAll(tmpdir)
|
|
||||||
|
|
||||||
if err := pkiutil.WriteCertAndKey(tmpdir, constants.APIServerCertAndKeyBaseName, apiCert, apiKey); err != nil {
|
|
||||||
t.Fatalf("Test %s: failure while saving %s certificate and key: %v", desc, constants.APIServerCertAndKeyBaseName, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
certAndKey := []string{filepath.Join(tmpdir, constants.APIServerCertName), filepath.Join(tmpdir, constants.APIServerKeyName)}
|
certAndKey := []string{filepath.Join(tmpdir, constants.APIServerCertName), filepath.Join(tmpdir, constants.APIServerKeyName)}
|
||||||
for _, path := range certAndKey {
|
for _, path := range certAndKey {
|
||||||
if _, err := os.Stat(path); os.IsNotExist(err) {
|
if _, err := os.Stat(path); os.IsNotExist(err) {
|
||||||
|
@ -187,24 +187,27 @@ func upgradeComponent(component string, waiter apiclient.Waiter, pathMgr StaticP
|
|||||||
|
|
||||||
// ensure etcd certs are generated for etcd and kube-apiserver
|
// ensure etcd certs are generated for etcd and kube-apiserver
|
||||||
if component == constants.Etcd || component == constants.KubeAPIServer {
|
if component == constants.Etcd || component == constants.KubeAPIServer {
|
||||||
if err := certsphase.CreateEtcdCACertAndKeyFiles(cfg); err != nil {
|
|
||||||
|
caCert, caKey, err := certsphase.KubeadmCertEtcdCA.CreateAsCA(cfg)
|
||||||
|
if err != nil {
|
||||||
return fmt.Errorf("failed to upgrade the %s CA certificate and key: %v", constants.Etcd, err)
|
return fmt.Errorf("failed to upgrade the %s CA certificate and key: %v", constants.Etcd, err)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if component == constants.Etcd {
|
if component == constants.Etcd {
|
||||||
if err := certsphase.CreateEtcdServerCertAndKeyFiles(cfg); err != nil {
|
if err := certsphase.KubeadmCertEtcdServer.CreateFromCA(cfg, caCert, caKey); err != nil {
|
||||||
return fmt.Errorf("failed to upgrade the %s certificate and key: %v", constants.Etcd, err)
|
return fmt.Errorf("failed to upgrade the %s certificate and key: %v", constants.Etcd, err)
|
||||||
|
}
|
||||||
|
if err := certsphase.KubeadmCertEtcdPeer.CreateFromCA(cfg, caCert, caKey); err != nil {
|
||||||
|
return fmt.Errorf("failed to upgrade the %s peer certificate and key: %v", constants.Etcd, err)
|
||||||
|
}
|
||||||
|
if err := certsphase.KubeadmCertEtcdHealthcheck.CreateFromCA(cfg, caCert, caKey); err != nil {
|
||||||
|
return fmt.Errorf("failed to upgrade the %s healthcheck certificate and key: %v", constants.Etcd, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if err := certsphase.CreateEtcdPeerCertAndKeyFiles(cfg); err != nil {
|
if component == constants.KubeAPIServer {
|
||||||
return fmt.Errorf("failed to upgrade the %s peer certificate and key: %v", constants.Etcd, err)
|
if err := certsphase.KubeadmCertEtcdAPIClient.CreateFromCA(cfg, caCert, caKey); err != nil {
|
||||||
}
|
return fmt.Errorf("failed to upgrade the %s %s-client certificate and key: %v", constants.KubeAPIServer, constants.Etcd, err)
|
||||||
if err := certsphase.CreateEtcdHealthcheckClientCertAndKeyFiles(cfg); err != nil {
|
}
|
||||||
return fmt.Errorf("failed to upgrade the %s healthcheck certificate and key: %v", constants.Etcd, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if component == constants.KubeAPIServer {
|
|
||||||
if err := certsphase.CreateAPIServerEtcdClientCertAndKeyFiles(cfg); err != nil {
|
|
||||||
return fmt.Errorf("failed to upgrade the %s %s-client certificate and key: %v", constants.KubeAPIServer, constants.Etcd, err)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -420,27 +420,16 @@ func TestStaticPodControlPlane(t *testing.T) {
|
|||||||
t.Fatalf("couldn't create config: %v", err)
|
t.Fatalf("couldn't create config: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize PKI minus any etcd certificates to simulate etcd PKI upgrade
|
tree, err := certsphase.GetCertsWithoutEtcd().AsMap().CertTree()
|
||||||
certActions := []func(cfg *kubeadmapi.InitConfiguration) error{
|
if err != nil {
|
||||||
certsphase.CreateCACertAndKeyFiles,
|
t.Fatalf("couldn't get cert tree: %v", err)
|
||||||
certsphase.CreateAPIServerCertAndKeyFiles,
|
|
||||||
certsphase.CreateAPIServerKubeletClientCertAndKeyFiles,
|
|
||||||
// certsphase.CreateEtcdCACertAndKeyFiles,
|
|
||||||
// certsphase.CreateEtcdServerCertAndKeyFiles,
|
|
||||||
// certsphase.CreateEtcdPeerCertAndKeyFiles,
|
|
||||||
// certsphase.CreateEtcdHealthcheckClientCertAndKeyFiles,
|
|
||||||
// certsphase.CreateAPIServerEtcdClientCertAndKeyFiles,
|
|
||||||
certsphase.CreateServiceAccountKeyAndPublicKeyFiles,
|
|
||||||
certsphase.CreateFrontProxyCACertAndKeyFiles,
|
|
||||||
certsphase.CreateFrontProxyClientCertAndKeyFiles,
|
|
||||||
}
|
}
|
||||||
for _, action := range certActions {
|
|
||||||
err := action(oldcfg)
|
if err := tree.CreateTree(oldcfg); err != nil {
|
||||||
if err != nil {
|
t.Fatalf("couldn't get create cert tree: %v", err)
|
||||||
t.Fatalf("couldn't initialize pre-upgrade certificate: %v", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
fmt.Printf("Wrote certs to %s\n", oldcfg.CertificatesDir)
|
|
||||||
|
t.Logf("Wrote certs to %s\n", oldcfg.CertificatesDir)
|
||||||
|
|
||||||
// Initialize the directory with v1.7 manifests; should then be upgraded to v1.8 using the method
|
// Initialize the directory with v1.7 manifests; should then be upgraded to v1.8 using the method
|
||||||
err = controlplanephase.CreateInitStaticPodManifestFiles(pathMgr.RealManifestDir(), oldcfg)
|
err = controlplanephase.CreateInitStaticPodManifestFiles(pathMgr.RealManifestDir(), oldcfg)
|
||||||
|
@ -9,7 +9,10 @@ go_library(
|
|||||||
name = "go_default_library",
|
name = "go_default_library",
|
||||||
srcs = ["util.go"],
|
srcs = ["util.go"],
|
||||||
importpath = "k8s.io/kubernetes/cmd/kubeadm/test/certs",
|
importpath = "k8s.io/kubernetes/cmd/kubeadm/test/certs",
|
||||||
deps = ["//cmd/kubeadm/app/phases/certs/pkiutil:go_default_library"],
|
deps = [
|
||||||
|
"//cmd/kubeadm/app/phases/certs/pkiutil:go_default_library",
|
||||||
|
"//staging/src/k8s.io/client-go/util/cert:go_default_library",
|
||||||
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
filegroup(
|
filegroup(
|
||||||
|
@ -22,13 +22,14 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
certutil "k8s.io/client-go/util/cert"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/pkiutil"
|
"k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/pkiutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SetupCertificateAuthorithy is a utility function for kubeadm testing that creates a
|
// SetupCertificateAuthorithy is a utility function for kubeadm testing that creates a
|
||||||
// CertificateAuthorithy cert/key pair
|
// CertificateAuthorithy cert/key pair
|
||||||
func SetupCertificateAuthorithy(t *testing.T) (*x509.Certificate, *rsa.PrivateKey) {
|
func SetupCertificateAuthorithy(t *testing.T) (*x509.Certificate, *rsa.PrivateKey) {
|
||||||
caCert, caKey, err := pkiutil.NewCertificateAuthority()
|
caCert, caKey, err := pkiutil.NewCertificateAuthority(&certutil.Config{CommonName: "kubernetes"})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failure while generating CA certificate and key: %v", err)
|
t.Fatalf("failure while generating CA certificate and key: %v", err)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user