Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

kubeadm: alpha certs should skip missing files #85092

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
61 changes: 42 additions & 19 deletions cmd/kubeadm/app/cmd/alpha/certs.go
Expand Up @@ -206,6 +206,11 @@ func renewCert(flags *renewFlags, kdir string, handler *renewal.CertificateRenew
return err
}

if ok, _ := rm.CertificateExists(handler.Name); !ok {
fmt.Printf("MISSING! %s\n", handler.LongName)
return nil
}

// if the renewal operation is set to generate CSR request only
if flags.csrOnly {
// checks a path for storing CSR request is given
Expand Down Expand Up @@ -282,36 +287,54 @@ func newCmdCertsExpiration(out io.Writer, kdir string) *cobra.Command {
w := tabwriter.NewWriter(out, 10, 4, 3, ' ', 0)
fmt.Fprintln(w, "CERTIFICATE\tEXPIRES\tRESIDUAL TIME\tCERTIFICATE AUTHORITY\tEXTERNALLY MANAGED")
for _, handler := range rm.Certificates() {
e, err := rm.GetCertificateExpirationInfo(handler.Name)
if err != nil {
return err
if ok, _ := rm.CertificateExists(handler.Name); ok {
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)
continue
}

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),
// the certificate does not exist (for any reason)
s := fmt.Sprintf("!MISSING! %s\t\t\t\t",
handler.Name,
)

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 {
return err
if ok, _ := rm.CAExists(handler.Name); ok {
e, err := rm.GetCAExpirationInfo(handler.Name)
if err != nil {
return err
}

s := fmt.Sprintf("%s\t%s\t%s\t%-8v",
e.Name,
e.ExpirationDate.Format("Jan 02, 2006 15:04 MST"),
duration.ShortHumanDuration(e.ResidualTime()),
yesNo(e.ExternallyManaged),
)

fmt.Fprintln(w, s)
continue
}

s := fmt.Sprintf("%s\t%s\t%s\t%-8v",
e.Name,
e.ExpirationDate.Format("Jan 02, 2006 15:04 MST"),
duration.ShortHumanDuration(e.ResidualTime()),
yesNo(e.ExternallyManaged),
// the CA does not exist (for any reason)
s := fmt.Sprintf("!MISSING! %s\t\t\t",
handler.Name,
)

fmt.Fprintln(w, s)
}
w.Flush()
Expand Down
20 changes: 20 additions & 0 deletions cmd/kubeadm/app/phases/certs/renewal/manager.go
Expand Up @@ -315,6 +315,16 @@ func (rm *Manager) CreateRenewCSR(name, outdir string) error {
return nil
}

// CertificateExists returns true if a certificate exists.
func (rm *Manager) CertificateExists(name string) (bool, error) {
handler, ok := rm.certificates[name]
if !ok {
return false, errors.Errorf("%s is not a known certificate", name)
}

return handler.readwriter.Exists(), nil
}

// GetCertificateExpirationInfo returns certificate expiration info.
// 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.
Expand All @@ -341,6 +351,16 @@ func (rm *Manager) GetCertificateExpirationInfo(name string) (*ExpirationInfo, e
return newExpirationInfo(name, cert, externallyManaged), nil
}

// CAExists returns true if a certificate authority exists.
func (rm *Manager) CAExists(name string) (bool, error) {
handler, ok := rm.cas[name]
if !ok {
return false, errors.Errorf("%s is not a known certificate", name)
}

return handler.readwriter.Exists(), nil
}

// GetCAExpirationInfo returns CA expiration info.
func (rm *Manager) GetCAExpirationInfo(name string) (*ExpirationInfo, error) {
handler, ok := rm.cas[name]
Expand Down
23 changes: 23 additions & 0 deletions cmd/kubeadm/app/phases/certs/renewal/readwriter.go
Expand Up @@ -19,6 +19,7 @@ package renewal
import (
"crypto"
"crypto/x509"
"os"
"path/filepath"

"github.com/pkg/errors"
Expand All @@ -33,6 +34,9 @@ import (
// certificateReadWriter defines the behavior of a component that
// read or write a certificate stored/embedded in a file
type certificateReadWriter interface {
//Exists return true if the certificate exists
Exists() bool

// Read a certificate stored/embedded in a file
Read() (*x509.Certificate, error)

Expand All @@ -55,6 +59,20 @@ func newPKICertificateReadWriter(certificateDir string, baseName string) *pkiCer
}
}

// Exists checks if a certificate exist
func (rw *pkiCertificateReadWriter) Exists() bool {
certificatePath, _ := pkiutil.PathsForCertAndKey(rw.certificateDir, rw.baseName)
return fileExists(certificatePath)
}

func fileExists(filename string) bool {
info, err := os.Stat(filename)
if os.IsNotExist(err) {
return false
}
return !info.IsDir()
}

// Read a certificate from a file the K8s pki managed by kubeadm
func (rw *pkiCertificateReadWriter) Read() (*x509.Certificate, error) {
certificatePath, _ := pkiutil.PathsForCertAndKey(rw.certificateDir, rw.baseName)
Expand Down Expand Up @@ -97,6 +115,11 @@ func newKubeconfigReadWriter(kubernetesDir string, kubeConfigFileName string) *k
}
}

// Exists checks if a certificate embedded in kubeConfig file exists
func (rw *kubeConfigReadWriter) Exists() bool {
return fileExists(rw.kubeConfigFilePath)
}

// Read a certificate embedded in kubeConfig file managed by kubeadm.
// Please note that the kubeConfig file itself is kept in the ReadWriter state thus allowing
// to preserve the attributes (Context, Servers, AuthInfo etc.)
Expand Down