diff --git a/pkg/controller/certificates/sync.go b/pkg/controller/certificates/sync.go index 73fe64f8c..5b132628b 100644 --- a/pkg/controller/certificates/sync.go +++ b/pkg/controller/certificates/sync.go @@ -77,7 +77,7 @@ func (c *Controller) Sync(ctx context.Context, crt *v1alpha1.Certificate) (err e }() // grab existing certificate and validate private key - certs, key, err := kube.SecretTLSKeyPair(c.secretLister, crtCopy.Namespace, crtCopy.Spec.SecretName) + certs, key, err := kube.SecretTLSKeyPair(ctx, c.secretLister, crtCopy.Namespace, crtCopy.Spec.SecretName) // if we don't have a certificate, we need to trigger a re-issue immediately if err != nil && !(k8sErrors.IsNotFound(err) || errors.IsInvalidData(err)) { return err @@ -256,8 +256,7 @@ func (c *Controller) scheduleRenewal(ctx context.Context, crt *v1alpha1.Certific return } - cert, err := kube.SecretTLSCert(c.secretLister, crt.Namespace, crt.Spec.SecretName) - + cert, err := kube.SecretTLSCert(ctx, c.secretLister, crt.Namespace, crt.Spec.SecretName) if err != nil { if !errors.IsInvalidData(err) { log.Error(err, "error getting secret for certificate resource") diff --git a/pkg/issuer/acme/issue.go b/pkg/issuer/acme/issue.go index c4245b447..9e1122ee2 100644 --- a/pkg/issuer/acme/issue.go +++ b/pkg/issuer/acme/issue.go @@ -280,7 +280,7 @@ func (a *Acme) getCertificatePrivateKey(ctx context.Context, crt *v1alpha1.Certi // private key yet, we may in some cases loop and re-generate the private key // over and over. We could attempt to use the live clientset to read the // private key too to avoid this case. - key, err := kube.SecretTLSKey(a.secretsLister, crt.Namespace, crt.Spec.SecretName) + key, err := kube.SecretTLSKey(ctx, a.secretsLister, crt.Namespace, crt.Spec.SecretName) if err == nil { return key, false, nil } diff --git a/pkg/issuer/ca/issue.go b/pkg/issuer/ca/issue.go index 40f88f092..5074bfa62 100644 --- a/pkg/issuer/ca/issue.go +++ b/pkg/issuer/ca/issue.go @@ -48,7 +48,7 @@ func (c *CA) Issue(ctx context.Context, crt *v1alpha1.Certificate) (*issuer.Issu log = logf.WithRelatedResourceName(log, crt.Spec.SecretName, crt.Namespace, "Secret") // get a copy of the existing/currently issued Certificate's private key - signeeKey, err := kube.SecretTLSKey(c.secretsLister, crt.Namespace, crt.Spec.SecretName) + signeeKey, err := kube.SecretTLSKey(ctx, c.secretsLister, crt.Namespace, crt.Spec.SecretName) if k8sErrors.IsNotFound(err) || errors.IsInvalidData(err) { log.Info("generating new private key") // if one does not already exist, generate a new one @@ -75,7 +75,7 @@ func (c *CA) Issue(ctx context.Context, crt *v1alpha1.Certificate) (*issuer.Issu } // get a copy of the CA certificate named on the Issuer - caCerts, caKey, err := kube.SecretTLSKeyPair(c.secretsLister, c.resourceNamespace, c.issuer.GetSpec().CA.SecretName) + caCerts, caKey, err := kube.SecretTLSKeyPair(ctx, c.secretsLister, c.resourceNamespace, c.issuer.GetSpec().CA.SecretName) if err != nil { log := logf.WithRelatedResourceName(log, c.issuer.GetSpec().CA.SecretName, c.resourceNamespace, "Secret") log.Info("error getting signing CA for Issuer") diff --git a/pkg/issuer/ca/setup.go b/pkg/issuer/ca/setup.go index 56ff0ff6c..1122e35e4 100644 --- a/pkg/issuer/ca/setup.go +++ b/pkg/issuer/ca/setup.go @@ -42,7 +42,7 @@ const ( func (c *CA) Setup(ctx context.Context) error { log := logf.FromContext(ctx, "setup") - cert, err := kube.SecretTLSCert(c.secretsLister, c.resourceNamespace, c.issuer.GetSpec().CA.SecretName) + cert, err := kube.SecretTLSCert(ctx, c.secretsLister, c.resourceNamespace, c.issuer.GetSpec().CA.SecretName) if err != nil { log.Error(err, "error getting signing CA TLS certificate") s := messageErrorGetKeyPair + err.Error() @@ -51,7 +51,7 @@ func (c *CA) Setup(ctx context.Context) error { return err } - _, err = kube.SecretTLSKey(c.secretsLister, c.resourceNamespace, c.issuer.GetSpec().CA.SecretName) + _, err = kube.SecretTLSKey(ctx, c.secretsLister, c.resourceNamespace, c.issuer.GetSpec().CA.SecretName) if err != nil { log.Error(err, "error getting signing CA private key") s := messageErrorGetKeyPair + err.Error() diff --git a/pkg/issuer/selfsigned/issue.go b/pkg/issuer/selfsigned/issue.go index 545922620..921013425 100644 --- a/pkg/issuer/selfsigned/issue.go +++ b/pkg/issuer/selfsigned/issue.go @@ -32,7 +32,7 @@ import ( func (c *SelfSigned) Issue(ctx context.Context, crt *v1alpha1.Certificate) (*issuer.IssueResponse, error) { // get a copy of the existing/currently issued Certificate's private key - signeePrivateKey, err := kube.SecretTLSKey(c.secretsLister, crt.Namespace, crt.Spec.SecretName) + signeePrivateKey, err := kube.SecretTLSKey(ctx, c.secretsLister, crt.Namespace, crt.Spec.SecretName) if k8sErrors.IsNotFound(err) || errors.IsInvalidData(err) { // if one does not already exist, generate a new one signeePrivateKey, err = pki.GeneratePrivateKeyForCertificate(crt) diff --git a/pkg/issuer/vault/issue.go b/pkg/issuer/vault/issue.go index 40da71680..b67a95b08 100644 --- a/pkg/issuer/vault/issue.go +++ b/pkg/issuer/vault/issue.go @@ -53,7 +53,7 @@ const ( func (v *Vault) Issue(ctx context.Context, crt *v1alpha1.Certificate) (*issuer.IssueResponse, error) { // get a copy of the existing/currently issued Certificate's private key - signeePrivateKey, err := kube.SecretTLSKey(v.secretsLister, crt.Namespace, crt.Spec.SecretName) + signeePrivateKey, err := kube.SecretTLSKey(ctx, v.secretsLister, crt.Namespace, crt.Spec.SecretName) if k8sErrors.IsNotFound(err) || errors.IsInvalidData(err) { // if one does not already exist, generate a new one signeePrivateKey, err = pki.GeneratePrivateKeyForCertificate(crt) diff --git a/pkg/metrics/metrics.go b/pkg/metrics/metrics.go index a0cbfb2b5..d585efb4c 100644 --- a/pkg/metrics/metrics.go +++ b/pkg/metrics/metrics.go @@ -165,7 +165,7 @@ func (m *Metrics) UpdateCertificateExpiry(crt *v1alpha1.Certificate, secretListe log.V(logf.DebugLevel).Info("attempting to retrieve secret for certificate") // grab existing certificate - cert, err := kube.SecretTLSCert(secretLister, crt.Namespace, crt.Spec.SecretName) + cert, err := kube.SecretTLSCert(m.ctx, secretLister, crt.Namespace, crt.Spec.SecretName) if err != nil { if !apierrors.IsNotFound(err) && !errors.IsInvalidData(err) { log.Error(err, "error reading secret for certificate") diff --git a/pkg/util/kube/BUILD.bazel b/pkg/util/kube/BUILD.bazel index ef8500260..78743be89 100644 --- a/pkg/util/kube/BUILD.bazel +++ b/pkg/util/kube/BUILD.bazel @@ -9,6 +9,7 @@ go_library( importpath = "github.com/jetstack/cert-manager/pkg/util/kube", visibility = ["//visibility:public"], deps = [ + "//pkg/logs:go_default_library", "//pkg/util:go_default_library", "//pkg/util/errors:go_default_library", "//pkg/util/pki:go_default_library", diff --git a/pkg/util/kube/pki.go b/pkg/util/kube/pki.go index 4b64c3fdf..0f60bb721 100644 --- a/pkg/util/kube/pki.go +++ b/pkg/util/kube/pki.go @@ -17,12 +17,14 @@ limitations under the License. package kube import ( + "context" "crypto" "crypto/x509" api "k8s.io/api/core/v1" corelisters "k8s.io/client-go/listers/core/v1" + logf "github.com/jetstack/cert-manager/pkg/logs" "github.com/jetstack/cert-manager/pkg/util/errors" "github.com/jetstack/cert-manager/pkg/util/pki" ) @@ -30,18 +32,27 @@ import ( // SecretTLSKeyRef will decode a PKCS1/SEC1 (in effect, a RSA or ECDSA) private key stored in a // secret with 'name' in 'namespace'. It will read the private key data from the secret // entry with name 'keyName'. -func SecretTLSKeyRef(secretLister corelisters.SecretLister, namespace, name, keyName string) (crypto.Signer, error) { +func SecretTLSKeyRef(ctx context.Context, secretLister corelisters.SecretLister, namespace, name, keyName string) (crypto.Signer, error) { + log := logf.FromContext(ctx) + log = logf.WithRelatedResourceName(log, name, namespace, "Secret") + secret, err := secretLister.Secrets(namespace).Get(name) if err != nil { + log.Error(err, "failed to retrieve secret") return nil, err } + log = logf.WithRelatedResource(log, secret) + log.V(logf.DebugLevel).Info("got secret resource") + log = log.WithValues("secret_key", keyName) keyBytes, ok := secret.Data[keyName] if !ok { + log.Error(nil, "no data for key in secret") return nil, errors.NewInvalidData("no data for %q in secret '%s/%s'", keyName, namespace, name) } key, err := pki.DecodePrivateKeyBytes(keyBytes) if err != nil { + log.Error(err, "error decoding private key") return key, errors.NewInvalidData(err.Error()) } @@ -51,57 +62,78 @@ func SecretTLSKeyRef(secretLister corelisters.SecretLister, namespace, name, key // SecretTLSKey will decode a PKCS1/SEC1 (in effect, a RSA or ECDSA) private key stored in a // secret with 'name' in 'namespace'. It will read the private key data from the secret // entry with name 'keyName'. -func SecretTLSKey(secretLister corelisters.SecretLister, namespace, name string) (crypto.Signer, error) { - return SecretTLSKeyRef(secretLister, namespace, name, api.TLSPrivateKeyKey) +func SecretTLSKey(ctx context.Context, secretLister corelisters.SecretLister, namespace, name string) (crypto.Signer, error) { + return SecretTLSKeyRef(ctx, secretLister, namespace, name, api.TLSPrivateKeyKey) } -func SecretTLSCertChain(secretLister corelisters.SecretLister, namespace, name string) ([]*x509.Certificate, error) { +func SecretTLSCertChain(ctx context.Context, secretLister corelisters.SecretLister, namespace, name string) ([]*x509.Certificate, error) { + log := logf.FromContext(ctx) + log = logf.WithRelatedResourceName(log, name, namespace, "Secret") + secret, err := secretLister.Secrets(namespace).Get(name) if err != nil { + log.Error(err, "failed to retrieve secret") return nil, err } + log = logf.WithRelatedResource(log, secret) + log.V(logf.DebugLevel).Info("got secret resource") + log = log.WithValues("secret_key", api.TLSCertKey) certBytes, ok := secret.Data[api.TLSCertKey] if !ok { + log.Error(nil, "no data for key in secret") return nil, errors.NewInvalidData("no data for %q in secret '%s/%s'", api.TLSCertKey, namespace, name) } + + log.V(logf.DebugLevel).Info("attempting to decode certificate chain") cert, err := pki.DecodeX509CertificateChainBytes(certBytes) if err != nil { + log.Error(err, "error decoding x509 certificate") return cert, errors.NewInvalidData(err.Error()) } return cert, nil } -func SecretTLSKeyPair(secretLister corelisters.SecretLister, namespace, name string) ([]*x509.Certificate, crypto.Signer, error) { +func SecretTLSKeyPair(ctx context.Context, secretLister corelisters.SecretLister, namespace, name string) ([]*x509.Certificate, crypto.Signer, error) { + log := logf.FromContext(ctx) + log = logf.WithRelatedResourceName(log, name, namespace, "Secret") + secret, err := secretLister.Secrets(namespace).Get(name) if err != nil { return nil, nil, err } + log = logf.WithRelatedResource(log, secret) + log = log.WithValues("secret_key", api.TLSPrivateKeyKey) keyBytes, ok := secret.Data[api.TLSPrivateKeyKey] if !ok { - return nil, nil, errors.NewInvalidData("no private key data for %q in secret '%s/%s'", api.TLSCertKey, namespace, name) + log.Error(nil, "no data for key in secret") + return nil, nil, errors.NewInvalidData("no private key data for %q in secret '%s/%s'", api.TLSPrivateKeyKey, namespace, name) } key, err := pki.DecodePrivateKeyBytes(keyBytes) if err != nil { + log.Error(err, "error decoding private key") return nil, nil, errors.NewInvalidData(err.Error()) } + log = log.WithValues("secret_key", api.TLSCertKey) certBytes, ok := secret.Data[api.TLSCertKey] if !ok { + log.Error(nil, "no data for key in secret") return nil, key, errors.NewInvalidData("no certificate data for %q in secret '%s/%s'", api.TLSCertKey, namespace, name) } cert, err := pki.DecodeX509CertificateChainBytes(certBytes) if err != nil { + log.Error(err, "error decoding x509 certificate") return nil, key, errors.NewInvalidData(err.Error()) } return cert, key, nil } -func SecretTLSCert(secretLister corelisters.SecretLister, namespace, name string) (*x509.Certificate, error) { - certs, err := SecretTLSCertChain(secretLister, namespace, name) +func SecretTLSCert(ctx context.Context, secretLister corelisters.SecretLister, namespace, name string) (*x509.Certificate, error) { + certs, err := SecretTLSCertChain(ctx, secretLister, namespace, name) if err != nil { return nil, err }