mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-25 12:43:23 +00:00
Merge pull request #83932 from SataQiu/report-ca-expiration
kubeadm: enhance certs check-expiration to show the expiration info of related CAs
This commit is contained in:
commit
b4d3dc3718
@ -281,9 +281,27 @@ func newCmdCertsExpiration(out io.Writer, kdir string) *cobra.Command {
|
|||||||
return "no"
|
return "no"
|
||||||
}
|
}
|
||||||
w := tabwriter.NewWriter(out, 10, 4, 3, ' ', 0)
|
w := tabwriter.NewWriter(out, 10, 4, 3, ' ', 0)
|
||||||
fmt.Fprintln(w, "CERTIFICATE\tEXPIRES\tRESIDUAL TIME\tEXTERNALLY MANAGED")
|
fmt.Fprintln(w, "CERTIFICATE\tEXPIRES\tRESIDUAL TIME\tCERTIFICATE AUTHORITY\tEXTERNALLY MANAGED")
|
||||||
for _, handler := range rm.Certificates() {
|
for _, handler := range rm.Certificates() {
|
||||||
e, err := rm.GetExpirationInfo(handler.Name)
|
e, err := rm.GetCertificateExpirationInfo(handler.Name)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
s := fmt.Sprintf("%s\t%s\t%s\t%s\t%-8v",
|
||||||
|
e.Name,
|
||||||
|
e.ExpirationDate.Format("Jan 02, 2006 15:04 MST"),
|
||||||
|
duration.ShortHumanDuration(e.ResidualTime()),
|
||||||
|
handler.CAName,
|
||||||
|
yesNo(e.ExternallyManaged),
|
||||||
|
)
|
||||||
|
|
||||||
|
fmt.Fprintln(w, s)
|
||||||
|
}
|
||||||
|
fmt.Fprintln(w)
|
||||||
|
fmt.Fprintln(w, "CERTIFICATE AUTHORITY\tEXPIRES\tRESIDUAL TIME\tEXTERNALLY MANAGED")
|
||||||
|
for _, handler := range rm.CAs() {
|
||||||
|
e, err := rm.GetCAExpirationInfo(handler.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,9 @@ type Manager struct {
|
|||||||
|
|
||||||
// certificates contains the certificateRenewHandler controlled by this manager
|
// certificates contains the certificateRenewHandler controlled by this manager
|
||||||
certificates map[string]*CertificateRenewHandler
|
certificates map[string]*CertificateRenewHandler
|
||||||
|
|
||||||
|
// cas contains the CAExpirationHandler related to the certificates that are controlled by this manager
|
||||||
|
cas map[string]*CAExpirationHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
// CertificateRenewHandler defines required info for renewing a certificate
|
// CertificateRenewHandler defines required info for renewing a certificate
|
||||||
@ -54,10 +57,29 @@ type CertificateRenewHandler struct {
|
|||||||
// FileName defines the name (or the BaseName) of the certificate file
|
// FileName defines the name (or the BaseName) of the certificate file
|
||||||
FileName string
|
FileName string
|
||||||
|
|
||||||
// CABaseName define the base name for the CA that should be used for certificate renewal
|
// CAName defines the name for the CA on which this certificate depends
|
||||||
|
CAName string
|
||||||
|
|
||||||
|
// CABaseName defines the base name for the CA that should be used for certificate renewal
|
||||||
CABaseName string
|
CABaseName string
|
||||||
|
|
||||||
// readwriter define a CertificateReadWriter to be used for certificate renewal
|
// readwriter defines a CertificateReadWriter to be used for certificate renewal
|
||||||
|
readwriter certificateReadWriter
|
||||||
|
}
|
||||||
|
|
||||||
|
// CAExpirationHandler defines required info for CA expiration check
|
||||||
|
type CAExpirationHandler struct {
|
||||||
|
// Name of the CA to be used for UX.
|
||||||
|
// This value can be used to trigger operations on this CA
|
||||||
|
Name string
|
||||||
|
|
||||||
|
// LongName of the CA to be used for UX
|
||||||
|
LongName string
|
||||||
|
|
||||||
|
// FileName defines the name (or the BaseName) of the CA file
|
||||||
|
FileName string
|
||||||
|
|
||||||
|
// readwriter defines a CertificateReadWriter to be used for CA expiration check
|
||||||
readwriter certificateReadWriter
|
readwriter certificateReadWriter
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,6 +89,7 @@ func NewManager(cfg *kubeadmapi.ClusterConfiguration, kubernetesDir string) (*Ma
|
|||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
kubernetesDir: kubernetesDir,
|
kubernetesDir: kubernetesDir,
|
||||||
certificates: map[string]*CertificateRenewHandler{},
|
certificates: map[string]*CertificateRenewHandler{},
|
||||||
|
cas: map[string]*CAExpirationHandler{},
|
||||||
}
|
}
|
||||||
|
|
||||||
// gets the list of certificates that are expected according to the current cluster configuration
|
// gets the list of certificates that are expected according to the current cluster configuration
|
||||||
@ -93,10 +116,19 @@ func NewManager(cfg *kubeadmapi.ClusterConfiguration, kubernetesDir string) (*Ma
|
|||||||
Name: cert.Name,
|
Name: cert.Name,
|
||||||
LongName: cert.LongName,
|
LongName: cert.LongName,
|
||||||
FileName: cert.BaseName,
|
FileName: cert.BaseName,
|
||||||
|
CAName: ca.Name,
|
||||||
CABaseName: ca.BaseName, //Nb. this is a path for etcd certs (they are stored in a subfolder)
|
CABaseName: ca.BaseName, //Nb. this is a path for etcd certs (they are stored in a subfolder)
|
||||||
readwriter: pkiReadWriter,
|
readwriter: pkiReadWriter,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pkiReadWriter := newPKICertificateReadWriter(rm.cfg.CertificatesDir, ca.BaseName)
|
||||||
|
rm.cas[ca.Name] = &CAExpirationHandler{
|
||||||
|
Name: ca.Name,
|
||||||
|
LongName: ca.LongName,
|
||||||
|
FileName: ca.BaseName,
|
||||||
|
readwriter: pkiReadWriter,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// gets the list of certificates that should be considered for renewal
|
// gets the list of certificates that should be considered for renewal
|
||||||
@ -139,7 +171,7 @@ func NewManager(cfg *kubeadmapi.ClusterConfiguration, kubernetesDir string) (*Ma
|
|||||||
return rm, nil
|
return rm, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Certificates return the list of certificates controlled by this Manager
|
// Certificates returns the list of certificates controlled by this Manager
|
||||||
func (rm *Manager) Certificates() []*CertificateRenewHandler {
|
func (rm *Manager) Certificates() []*CertificateRenewHandler {
|
||||||
certificates := []*CertificateRenewHandler{}
|
certificates := []*CertificateRenewHandler{}
|
||||||
for _, h := range rm.certificates {
|
for _, h := range rm.certificates {
|
||||||
@ -151,6 +183,18 @@ func (rm *Manager) Certificates() []*CertificateRenewHandler {
|
|||||||
return certificates
|
return certificates
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CAs returns the list of CAs related to the certificates that are controlled by this manager
|
||||||
|
func (rm *Manager) CAs() []*CAExpirationHandler {
|
||||||
|
cas := []*CAExpirationHandler{}
|
||||||
|
for _, h := range rm.cas {
|
||||||
|
cas = append(cas, h)
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Slice(cas, func(i, j int) bool { return cas[i].Name < cas[j].Name })
|
||||||
|
|
||||||
|
return cas
|
||||||
|
}
|
||||||
|
|
||||||
// RenewUsingLocalCA executes certificate renewal using local certificate authorities for generating new certs.
|
// RenewUsingLocalCA executes certificate renewal using local certificate authorities for generating new certs.
|
||||||
// For PKI certificates, use the name defined in the certsphase package, while for certificates
|
// For PKI certificates, use the name defined in the certsphase package, while for certificates
|
||||||
// embedded in the kubeConfig files, use the kubeConfig file name defined in the kubeadm constants package.
|
// embedded in the kubeConfig files, use the kubeConfig file name defined in the kubeadm constants package.
|
||||||
@ -162,7 +206,7 @@ func (rm *Manager) RenewUsingLocalCA(name string) (bool, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// checks if the certificate is externally managed (CA certificate provided without the certificate key)
|
// checks if the certificate is externally managed (CA certificate provided without the certificate key)
|
||||||
externallyManaged, err := rm.IsExternallyManaged(handler)
|
externallyManaged, err := rm.IsExternallyManaged(handler.CABaseName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
@ -271,18 +315,18 @@ func (rm *Manager) CreateRenewCSR(name, outdir string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetExpirationInfo returns certificate expiration info.
|
// GetCertificateExpirationInfo returns certificate expiration info.
|
||||||
// For PKI certificates, use the name defined in the certsphase package, while for certificates
|
// For PKI certificates, use the name defined in the certsphase package, while for certificates
|
||||||
// embedded in the kubeConfig files, use the kubeConfig file name defined in the kubeadm constants package.
|
// embedded in the kubeConfig files, use the kubeConfig file name defined in the kubeadm constants package.
|
||||||
// If you use the CertificateRenewHandler returned by Certificates func, handler.Name already contains the right value.
|
// If you use the CertificateRenewHandler returned by Certificates func, handler.Name already contains the right value.
|
||||||
func (rm *Manager) GetExpirationInfo(name string) (*ExpirationInfo, error) {
|
func (rm *Manager) GetCertificateExpirationInfo(name string) (*ExpirationInfo, error) {
|
||||||
handler, ok := rm.certificates[name]
|
handler, ok := rm.certificates[name]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.Errorf("%s is not a known certificate", name)
|
return nil, errors.Errorf("%s is not a known certificate", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// checks if the certificate is externally managed (CA certificate provided without the certificate key)
|
// checks if the certificate is externally managed (CA certificate provided without the certificate key)
|
||||||
externallyManaged, err := rm.IsExternallyManaged(handler)
|
externallyManaged, err := rm.IsExternallyManaged(handler.CABaseName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -297,25 +341,48 @@ func (rm *Manager) GetExpirationInfo(name string) (*ExpirationInfo, error) {
|
|||||||
return newExpirationInfo(name, cert, externallyManaged), nil
|
return newExpirationInfo(name, cert, externallyManaged), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetCAExpirationInfo returns CA expiration info.
|
||||||
|
func (rm *Manager) GetCAExpirationInfo(name string) (*ExpirationInfo, error) {
|
||||||
|
handler, ok := rm.cas[name]
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.Errorf("%s is not a known CA", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// checks if the CA is externally managed (CA certificate provided without the certificate key)
|
||||||
|
externallyManaged, err := rm.IsExternallyManaged(handler.FileName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// reads the current CA
|
||||||
|
ca, err := handler.readwriter.Read()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns the CA expiration info
|
||||||
|
return newExpirationInfo(name, ca, externallyManaged), nil
|
||||||
|
}
|
||||||
|
|
||||||
// IsExternallyManaged checks if we are in the external CA case (CA certificate provided without the certificate key)
|
// IsExternallyManaged checks if we are in the external CA case (CA certificate provided without the certificate key)
|
||||||
func (rm *Manager) IsExternallyManaged(h *CertificateRenewHandler) (bool, error) {
|
func (rm *Manager) IsExternallyManaged(caBaseName string) (bool, error) {
|
||||||
switch h.CABaseName {
|
switch caBaseName {
|
||||||
case kubeadmconstants.CACertAndKeyBaseName:
|
case kubeadmconstants.CACertAndKeyBaseName:
|
||||||
externallyManaged, err := certsphase.UsingExternalCA(rm.cfg)
|
externallyManaged, err := certsphase.UsingExternalCA(rm.cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, errors.Wrapf(err, "Error checking external CA condition for %s certificate authority", h.CABaseName)
|
return false, errors.Wrapf(err, "Error checking external CA condition for %s certificate authority", caBaseName)
|
||||||
}
|
}
|
||||||
return externallyManaged, nil
|
return externallyManaged, nil
|
||||||
case kubeadmconstants.FrontProxyCACertAndKeyBaseName:
|
case kubeadmconstants.FrontProxyCACertAndKeyBaseName:
|
||||||
externallyManaged, err := certsphase.UsingExternalFrontProxyCA(rm.cfg)
|
externallyManaged, err := certsphase.UsingExternalFrontProxyCA(rm.cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, errors.Wrapf(err, "Error checking external CA condition for %s certificate authority", h.CABaseName)
|
return false, errors.Wrapf(err, "Error checking external CA condition for %s certificate authority", caBaseName)
|
||||||
}
|
}
|
||||||
return externallyManaged, nil
|
return externallyManaged, nil
|
||||||
case kubeadmconstants.EtcdCACertAndKeyBaseName:
|
case kubeadmconstants.EtcdCACertAndKeyBaseName:
|
||||||
return false, nil
|
return false, nil
|
||||||
default:
|
default:
|
||||||
return false, errors.Errorf("unknown certificate authority %s", h.CABaseName)
|
return false, errors.Errorf("unknown certificate authority %s", caBaseName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user