mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-27 21:47:07 +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 (
|
import (
|
||||||
"io"
|
"io"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"k8s.io/klog/v2"
|
||||||
|
|
||||||
kubeadmapiv1beta2 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2"
|
kubeadmapiv1beta2 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/options"
|
"k8s.io/kubernetes/cmd/kubeadm/app/cmd/options"
|
||||||
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"
|
||||||
kubeconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig"
|
kubeconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig"
|
||||||
configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config"
|
configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config"
|
||||||
)
|
)
|
||||||
@ -64,6 +67,7 @@ func newCmdUserKubeConfig(out io.Writer) *cobra.Command {
|
|||||||
var (
|
var (
|
||||||
token, clientName, cfgPath string
|
token, clientName, cfgPath string
|
||||||
organizations []string
|
organizations []string
|
||||||
|
validityPeriod time.Duration
|
||||||
)
|
)
|
||||||
|
|
||||||
// Creates the UX Command
|
// Creates the UX Command
|
||||||
@ -79,13 +83,20 @@ func newCmdUserKubeConfig(out io.Writer) *cobra.Command {
|
|||||||
return err
|
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 the kubeconfig file for an additional user has to use a token, use it
|
||||||
if token != "" {
|
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
|
// 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,
|
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(&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().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().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(options.CfgPath)
|
||||||
cmd.MarkFlagRequired("client-name")
|
cmd.MarkFlagRequired("client-name")
|
||||||
|
@ -24,6 +24,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
@ -120,7 +121,7 @@ func createKubeConfigFiles(outDir string, cfg *kubeadmapi.InitConfiguration, kub
|
|||||||
}
|
}
|
||||||
|
|
||||||
// builds the KubeConfig object
|
// builds the KubeConfig object
|
||||||
config, err := buildKubeConfigFromSpec(spec, cfg.ClusterName)
|
config, err := buildKubeConfigFromSpec(spec, cfg.ClusterName, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -156,7 +157,7 @@ func getKubeConfigSpecs(cfg *kubeadmapi.InitConfiguration) (map[string]*kubeConf
|
|||||||
}
|
}
|
||||||
|
|
||||||
// buildKubeConfigFromSpec creates a kubeconfig object for the given kubeConfigSpec
|
// 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 this kubeconfig should use token
|
||||||
if spec.TokenAuth != nil {
|
if spec.TokenAuth != nil {
|
||||||
@ -171,7 +172,7 @@ func buildKubeConfigFromSpec(spec *kubeConfigSpec, clustername string) (*clientc
|
|||||||
}
|
}
|
||||||
|
|
||||||
// otherwise, create a client certs
|
// otherwise, create a client certs
|
||||||
clientCertConfig := newClientCertConfigFromKubeConfigSpec(spec)
|
clientCertConfig := newClientCertConfigFromKubeConfigSpec(spec, notAfter)
|
||||||
|
|
||||||
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 {
|
||||||
@ -193,13 +194,14 @@ func buildKubeConfigFromSpec(spec *kubeConfigSpec, clustername string) (*clientc
|
|||||||
), nil
|
), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func newClientCertConfigFromKubeConfigSpec(spec *kubeConfigSpec) pkiutil.CertConfig {
|
func newClientCertConfigFromKubeConfigSpec(spec *kubeConfigSpec, notAfter *time.Time) pkiutil.CertConfig {
|
||||||
return pkiutil.CertConfig{
|
return pkiutil.CertConfig{
|
||||||
Config: certutil.Config{
|
Config: certutil.Config{
|
||||||
CommonName: spec.ClientName,
|
CommonName: spec.ClientName,
|
||||||
Organization: spec.ClientCertAuth.Organizations,
|
Organization: spec.ClientCertAuth.Organizations,
|
||||||
Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
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.
|
// 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
|
// creates the KubeConfigSpecs, actualized for the current InitConfiguration
|
||||||
caCert, caKey, err := pkiutil.TryLoadCertAndKeyFromDisk(cfg.CertificatesDir, kubeadmconstants.CACertAndKeyBaseName)
|
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.
|
// 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
|
// creates the KubeConfigSpecs, actualized for the current InitConfiguration
|
||||||
caCert, _, err := pkiutil.TryLoadCertAndKeyFromDisk(cfg.CertificatesDir, kubeadmconstants.CACertAndKeyBaseName)
|
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.
|
// 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
|
// builds the KubeConfig object
|
||||||
config, err := buildKubeConfigFromSpec(spec, clustername)
|
config, err := buildKubeConfigFromSpec(spec, clustername, notAfter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -465,7 +467,7 @@ func createKubeConfigAndCSR(kubeConfigDir string, kubeadmConfig *kubeadmapi.Init
|
|||||||
return errors.Errorf("%s: csr: %s", errExist, kubeConfigPath)
|
return errors.Errorf("%s: csr: %s", errExist, kubeConfigPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
clientCertConfig := newClientCertConfigFromKubeConfigSpec(spec)
|
clientCertConfig := newClientCertConfigFromKubeConfigSpec(spec, nil)
|
||||||
|
|
||||||
clientKey, err := pkiutil.NewPrivateKey(clientCertConfig.PublicKeyAlgorithm)
|
clientKey, err := pkiutil.NewPrivateKey(clientCertConfig.PublicKeyAlgorithm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -374,13 +374,13 @@ func TestWriteKubeConfigFailsIfCADoesntExists(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "WriteKubeConfigWithClientCert",
|
name: "WriteKubeConfigWithClientCert",
|
||||||
writeKubeConfigFunction: func(out io.Writer) error {
|
writeKubeConfigFunction: func(out io.Writer) error {
|
||||||
return WriteKubeConfigWithClientCert(out, cfg, "myUser", []string{"myOrg"})
|
return WriteKubeConfigWithClientCert(out, cfg, "myUser", []string{"myOrg"}, nil)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "WriteKubeConfigWithToken",
|
name: "WriteKubeConfigWithToken",
|
||||||
writeKubeConfigFunction: func(out io.Writer) error {
|
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",
|
name: "WriteKubeConfigWithClientCert",
|
||||||
writeKubeConfigFunction: func(out io.Writer) error {
|
writeKubeConfigFunction: func(out io.Writer) error {
|
||||||
return WriteKubeConfigWithClientCert(out, cfg, "myUser", []string{"myOrg"})
|
return WriteKubeConfigWithClientCert(out, cfg, "myUser", []string{"myOrg"}, nil)
|
||||||
},
|
},
|
||||||
withClientCert: true,
|
withClientCert: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "WriteKubeConfigWithToken",
|
name: "WriteKubeConfigWithToken",
|
||||||
writeKubeConfigFunction: func(out io.Writer) error {
|
writeKubeConfigFunction: func(out io.Writer) error {
|
||||||
return WriteKubeConfigWithToken(out, cfg, "myUser", "12345")
|
return WriteKubeConfigWithToken(out, cfg, "myUser", "12345", nil)
|
||||||
},
|
},
|
||||||
withToken: true,
|
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 {
|
if err != nil {
|
||||||
t.Fatal("buildKubeConfigFromSpec failed!")
|
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 {
|
if err != nil {
|
||||||
t.Fatal("buildKubeConfigFromSpec failed!")
|
t.Fatal("buildKubeConfigFromSpec failed!")
|
||||||
}
|
}
|
||||||
|
@ -62,6 +62,7 @@ const (
|
|||||||
// CertConfig is a wrapper around certutil.Config extending it with PublicKeyAlgorithm.
|
// CertConfig is a wrapper around certutil.Config extending it with PublicKeyAlgorithm.
|
||||||
type CertConfig struct {
|
type CertConfig struct {
|
||||||
certutil.Config
|
certutil.Config
|
||||||
|
NotAfter *time.Time
|
||||||
PublicKeyAlgorithm x509.PublicKeyAlgorithm
|
PublicKeyAlgorithm x509.PublicKeyAlgorithm
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -647,6 +648,11 @@ func NewSignedCert(cfg *CertConfig, key crypto.Signer, caCert *x509.Certificate,
|
|||||||
|
|
||||||
RemoveDuplicateAltNames(&cfg.AltNames)
|
RemoveDuplicateAltNames(&cfg.AltNames)
|
||||||
|
|
||||||
|
notAfter := time.Now().Add(kubeadmconstants.CertificateValidity).UTC()
|
||||||
|
if cfg.NotAfter != nil {
|
||||||
|
notAfter = *cfg.NotAfter
|
||||||
|
}
|
||||||
|
|
||||||
certTmpl := x509.Certificate{
|
certTmpl := x509.Certificate{
|
||||||
Subject: pkix.Name{
|
Subject: pkix.Name{
|
||||||
CommonName: cfg.CommonName,
|
CommonName: cfg.CommonName,
|
||||||
@ -656,7 +662,7 @@ func NewSignedCert(cfg *CertConfig, key crypto.Signer, caCert *x509.Certificate,
|
|||||||
IPAddresses: cfg.AltNames.IPs,
|
IPAddresses: cfg.AltNames.IPs,
|
||||||
SerialNumber: serial,
|
SerialNumber: serial,
|
||||||
NotBefore: caCert.NotBefore,
|
NotBefore: caCert.NotBefore,
|
||||||
NotAfter: time.Now().Add(kubeadmconstants.CertificateValidity).UTC(),
|
NotAfter: notAfter,
|
||||||
KeyUsage: keyUsage,
|
KeyUsage: keyUsage,
|
||||||
ExtKeyUsage: cfg.Usages,
|
ExtKeyUsage: cfg.Usages,
|
||||||
BasicConstraintsValid: true,
|
BasicConstraintsValid: true,
|
||||||
|
Loading…
Reference in New Issue
Block a user