From 7d986a982ceb0f0b4e160a9a672ad77dd15ad9fa Mon Sep 17 00:00:00 2001 From: fabriziopandini Date: Mon, 11 Nov 2019 15:48:49 +0100 Subject: [PATCH] alpha certs skip missing files --- cmd/kubeadm/app/cmd/alpha/certs.go | 61 +++++++++++++------ .../app/phases/certs/renewal/manager.go | 20 ++++++ .../app/phases/certs/renewal/readwriter.go | 23 +++++++ 3 files changed, 85 insertions(+), 19 deletions(-) diff --git a/cmd/kubeadm/app/cmd/alpha/certs.go b/cmd/kubeadm/app/cmd/alpha/certs.go index c2981f906c2..ffd70e43490 100644 --- a/cmd/kubeadm/app/cmd/alpha/certs.go +++ b/cmd/kubeadm/app/cmd/alpha/certs.go @@ -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 @@ -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() diff --git a/cmd/kubeadm/app/phases/certs/renewal/manager.go b/cmd/kubeadm/app/phases/certs/renewal/manager.go index d675d10c402..87406360eb9 100644 --- a/cmd/kubeadm/app/phases/certs/renewal/manager.go +++ b/cmd/kubeadm/app/phases/certs/renewal/manager.go @@ -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. @@ -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] diff --git a/cmd/kubeadm/app/phases/certs/renewal/readwriter.go b/cmd/kubeadm/app/phases/certs/renewal/readwriter.go index c6040793d71..cc9b7402776 100644 --- a/cmd/kubeadm/app/phases/certs/renewal/readwriter.go +++ b/cmd/kubeadm/app/phases/certs/renewal/readwriter.go @@ -19,6 +19,7 @@ package renewal import ( "crypto" "crypto/x509" + "os" "path/filepath" "github.com/pkg/errors" @@ -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) @@ -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) @@ -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.)