mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 11:21:47 +00:00
Merge pull request #100907 from SataQiu/kubeadm-20210408
kubeadm: add --validity-period flag for 'kubeadm kubeconfig user' command
This commit is contained in:
commit
61641a0640
@ -18,12 +18,15 @@ package alpha
|
||||
|
||||
import (
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
kubeadmapiv1beta2 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2"
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/options"
|
||||
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
|
||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
kubeconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig"
|
||||
configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config"
|
||||
)
|
||||
@ -64,6 +67,7 @@ func newCmdUserKubeConfig(out io.Writer) *cobra.Command {
|
||||
var (
|
||||
token, clientName, cfgPath string
|
||||
organizations []string
|
||||
validityPeriod time.Duration
|
||||
)
|
||||
|
||||
// Creates the UX Command
|
||||
@ -79,13 +83,20 @@ func newCmdUserKubeConfig(out io.Writer) *cobra.Command {
|
||||
return err
|
||||
}
|
||||
|
||||
if validityPeriod > kubeadmconstants.CertificateValidity {
|
||||
klog.Warningf("WARNING: the specified certificate validity period %v is longer than the default duration %v, this may increase security risks.",
|
||||
validityPeriod, kubeadmconstants.CertificateValidity)
|
||||
}
|
||||
|
||||
notAfter := time.Now().Add(validityPeriod).UTC()
|
||||
|
||||
// if the kubeconfig file for an additional user has to use a token, use it
|
||||
if token != "" {
|
||||
return kubeconfigphase.WriteKubeConfigWithToken(out, internalCfg, clientName, token)
|
||||
return kubeconfigphase.WriteKubeConfigWithToken(out, internalCfg, clientName, token, ¬After)
|
||||
}
|
||||
|
||||
// Otherwise, write a kubeconfig file with a generate client cert
|
||||
return kubeconfigphase.WriteKubeConfigWithClientCert(out, internalCfg, clientName, organizations)
|
||||
return kubeconfigphase.WriteKubeConfigWithClientCert(out, internalCfg, clientName, organizations, ¬After)
|
||||
},
|
||||
Args: cobra.NoArgs,
|
||||
}
|
||||
@ -96,6 +107,7 @@ func newCmdUserKubeConfig(out io.Writer) *cobra.Command {
|
||||
cmd.Flags().StringVar(&token, options.TokenStr, token, "The token that should be used as the authentication mechanism for this kubeconfig, instead of client certificates")
|
||||
cmd.Flags().StringVar(&clientName, "client-name", clientName, "The name of user. It will be used as the CN if client certificates are created")
|
||||
cmd.Flags().StringSliceVar(&organizations, "org", organizations, "The orgnizations of the client certificate. It will be used as the O if client certificates are created")
|
||||
cmd.Flags().DurationVar(&validityPeriod, "validity-period", kubeadmconstants.CertificateValidity, "The validity period of the client certificate. It is an offset from the current time.")
|
||||
|
||||
cmd.MarkFlagRequired(options.CfgPath)
|
||||
cmd.MarkFlagRequired("client-name")
|
||||
|
@ -24,6 +24,7 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
@ -120,7 +121,7 @@ func createKubeConfigFiles(outDir string, cfg *kubeadmapi.InitConfiguration, kub
|
||||
}
|
||||
|
||||
// builds the KubeConfig object
|
||||
config, err := buildKubeConfigFromSpec(spec, cfg.ClusterName)
|
||||
config, err := buildKubeConfigFromSpec(spec, cfg.ClusterName, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -156,7 +157,7 @@ func getKubeConfigSpecs(cfg *kubeadmapi.InitConfiguration) (map[string]*kubeConf
|
||||
}
|
||||
|
||||
// buildKubeConfigFromSpec creates a kubeconfig object for the given kubeConfigSpec
|
||||
func buildKubeConfigFromSpec(spec *kubeConfigSpec, clustername string) (*clientcmdapi.Config, error) {
|
||||
func buildKubeConfigFromSpec(spec *kubeConfigSpec, clustername string, notAfter *time.Time) (*clientcmdapi.Config, error) {
|
||||
|
||||
// If this kubeconfig should use token
|
||||
if spec.TokenAuth != nil {
|
||||
@ -171,7 +172,7 @@ func buildKubeConfigFromSpec(spec *kubeConfigSpec, clustername string) (*clientc
|
||||
}
|
||||
|
||||
// otherwise, create a client certs
|
||||
clientCertConfig := newClientCertConfigFromKubeConfigSpec(spec)
|
||||
clientCertConfig := newClientCertConfigFromKubeConfigSpec(spec, notAfter)
|
||||
|
||||
clientCert, clientKey, err := pkiutil.NewCertAndKey(spec.CACert, spec.ClientCertAuth.CAKey, &clientCertConfig)
|
||||
if err != nil {
|
||||
@ -193,13 +194,14 @@ func buildKubeConfigFromSpec(spec *kubeConfigSpec, clustername string) (*clientc
|
||||
), nil
|
||||
}
|
||||
|
||||
func newClientCertConfigFromKubeConfigSpec(spec *kubeConfigSpec) pkiutil.CertConfig {
|
||||
func newClientCertConfigFromKubeConfigSpec(spec *kubeConfigSpec, notAfter *time.Time) pkiutil.CertConfig {
|
||||
return pkiutil.CertConfig{
|
||||
Config: certutil.Config{
|
||||
CommonName: spec.ClientName,
|
||||
Organization: spec.ClientCertAuth.Organizations,
|
||||
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
||||
},
|
||||
NotAfter: notAfter,
|
||||
}
|
||||
}
|
||||
|
||||
@ -279,7 +281,7 @@ func createKubeConfigFileIfNotExists(outDir, filename string, config *clientcmda
|
||||
}
|
||||
|
||||
// WriteKubeConfigWithClientCert writes a kubeconfig file - with a client certificate as authentication info - to the given writer.
|
||||
func WriteKubeConfigWithClientCert(out io.Writer, cfg *kubeadmapi.InitConfiguration, clientName string, organizations []string) error {
|
||||
func WriteKubeConfigWithClientCert(out io.Writer, cfg *kubeadmapi.InitConfiguration, clientName string, organizations []string, notAfter *time.Time) error {
|
||||
|
||||
// creates the KubeConfigSpecs, actualized for the current InitConfiguration
|
||||
caCert, caKey, err := pkiutil.TryLoadCertAndKeyFromDisk(cfg.CertificatesDir, kubeadmconstants.CACertAndKeyBaseName)
|
||||
@ -304,11 +306,11 @@ func WriteKubeConfigWithClientCert(out io.Writer, cfg *kubeadmapi.InitConfigurat
|
||||
},
|
||||
}
|
||||
|
||||
return writeKubeConfigFromSpec(out, spec, cfg.ClusterName)
|
||||
return writeKubeConfigFromSpec(out, spec, cfg.ClusterName, notAfter)
|
||||
}
|
||||
|
||||
// WriteKubeConfigWithToken writes a kubeconfig file - with a token as client authentication info - to the given writer.
|
||||
func WriteKubeConfigWithToken(out io.Writer, cfg *kubeadmapi.InitConfiguration, clientName, token string) error {
|
||||
func WriteKubeConfigWithToken(out io.Writer, cfg *kubeadmapi.InitConfiguration, clientName, token string, notAfter *time.Time) error {
|
||||
|
||||
// creates the KubeConfigSpecs, actualized for the current InitConfiguration
|
||||
caCert, _, err := pkiutil.TryLoadCertAndKeyFromDisk(cfg.CertificatesDir, kubeadmconstants.CACertAndKeyBaseName)
|
||||
@ -332,14 +334,14 @@ func WriteKubeConfigWithToken(out io.Writer, cfg *kubeadmapi.InitConfiguration,
|
||||
},
|
||||
}
|
||||
|
||||
return writeKubeConfigFromSpec(out, spec, cfg.ClusterName)
|
||||
return writeKubeConfigFromSpec(out, spec, cfg.ClusterName, notAfter)
|
||||
}
|
||||
|
||||
// writeKubeConfigFromSpec creates a kubeconfig object from a kubeConfigSpec and writes it to the given writer.
|
||||
func writeKubeConfigFromSpec(out io.Writer, spec *kubeConfigSpec, clustername string) error {
|
||||
func writeKubeConfigFromSpec(out io.Writer, spec *kubeConfigSpec, clustername string, notAfter *time.Time) error {
|
||||
|
||||
// builds the KubeConfig object
|
||||
config, err := buildKubeConfigFromSpec(spec, clustername)
|
||||
config, err := buildKubeConfigFromSpec(spec, clustername, notAfter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -465,7 +467,7 @@ func createKubeConfigAndCSR(kubeConfigDir string, kubeadmConfig *kubeadmapi.Init
|
||||
return errors.Errorf("%s: csr: %s", errExist, kubeConfigPath)
|
||||
}
|
||||
|
||||
clientCertConfig := newClientCertConfigFromKubeConfigSpec(spec)
|
||||
clientCertConfig := newClientCertConfigFromKubeConfigSpec(spec, nil)
|
||||
|
||||
clientKey, err := pkiutil.NewPrivateKey(clientCertConfig.PublicKeyAlgorithm)
|
||||
if err != nil {
|
||||
|
@ -374,13 +374,13 @@ func TestWriteKubeConfigFailsIfCADoesntExists(t *testing.T) {
|
||||
{
|
||||
name: "WriteKubeConfigWithClientCert",
|
||||
writeKubeConfigFunction: func(out io.Writer) error {
|
||||
return WriteKubeConfigWithClientCert(out, cfg, "myUser", []string{"myOrg"})
|
||||
return WriteKubeConfigWithClientCert(out, cfg, "myUser", []string{"myOrg"}, nil)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "WriteKubeConfigWithToken",
|
||||
writeKubeConfigFunction: func(out io.Writer) error {
|
||||
return WriteKubeConfigWithToken(out, cfg, "myUser", "12345")
|
||||
return WriteKubeConfigWithToken(out, cfg, "myUser", "12345", nil)
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -428,14 +428,14 @@ func TestWriteKubeConfig(t *testing.T) {
|
||||
{
|
||||
name: "WriteKubeConfigWithClientCert",
|
||||
writeKubeConfigFunction: func(out io.Writer) error {
|
||||
return WriteKubeConfigWithClientCert(out, cfg, "myUser", []string{"myOrg"})
|
||||
return WriteKubeConfigWithClientCert(out, cfg, "myUser", []string{"myOrg"}, nil)
|
||||
},
|
||||
withClientCert: true,
|
||||
},
|
||||
{
|
||||
name: "WriteKubeConfigWithToken",
|
||||
writeKubeConfigFunction: func(out io.Writer) error {
|
||||
return WriteKubeConfigWithToken(out, cfg, "myUser", "12345")
|
||||
return WriteKubeConfigWithToken(out, cfg, "myUser", "12345", nil)
|
||||
},
|
||||
withToken: true,
|
||||
},
|
||||
@ -664,7 +664,7 @@ func setupdKubeConfigWithClientAuth(t *testing.T, caCert *x509.Certificate, caKe
|
||||
},
|
||||
}
|
||||
|
||||
config, err := buildKubeConfigFromSpec(spec, clustername)
|
||||
config, err := buildKubeConfigFromSpec(spec, clustername, nil)
|
||||
if err != nil {
|
||||
t.Fatal("buildKubeConfigFromSpec failed!")
|
||||
}
|
||||
@ -683,7 +683,7 @@ func setupdKubeConfigWithTokenAuth(t *testing.T, caCert *x509.Certificate, APISe
|
||||
},
|
||||
}
|
||||
|
||||
config, err := buildKubeConfigFromSpec(spec, clustername)
|
||||
config, err := buildKubeConfigFromSpec(spec, clustername, nil)
|
||||
if err != nil {
|
||||
t.Fatal("buildKubeConfigFromSpec failed!")
|
||||
}
|
||||
|
@ -62,6 +62,7 @@ const (
|
||||
// CertConfig is a wrapper around certutil.Config extending it with PublicKeyAlgorithm.
|
||||
type CertConfig struct {
|
||||
certutil.Config
|
||||
NotAfter *time.Time
|
||||
PublicKeyAlgorithm x509.PublicKeyAlgorithm
|
||||
}
|
||||
|
||||
@ -647,6 +648,11 @@ func NewSignedCert(cfg *CertConfig, key crypto.Signer, caCert *x509.Certificate,
|
||||
|
||||
RemoveDuplicateAltNames(&cfg.AltNames)
|
||||
|
||||
notAfter := time.Now().Add(kubeadmconstants.CertificateValidity).UTC()
|
||||
if cfg.NotAfter != nil {
|
||||
notAfter = *cfg.NotAfter
|
||||
}
|
||||
|
||||
certTmpl := x509.Certificate{
|
||||
Subject: pkix.Name{
|
||||
CommonName: cfg.CommonName,
|
||||
@ -656,7 +662,7 @@ func NewSignedCert(cfg *CertConfig, key crypto.Signer, caCert *x509.Certificate,
|
||||
IPAddresses: cfg.AltNames.IPs,
|
||||
SerialNumber: serial,
|
||||
NotBefore: caCert.NotBefore,
|
||||
NotAfter: time.Now().Add(kubeadmconstants.CertificateValidity).UTC(),
|
||||
NotAfter: notAfter,
|
||||
KeyUsage: keyUsage,
|
||||
ExtKeyUsage: cfg.Usages,
|
||||
BasicConstraintsValid: true,
|
||||
|
Loading…
Reference in New Issue
Block a user