Newer
Older
AnthosCertManager / pkg / controller / certificates / issuing / secret_manager.go
package issuing

import (
	"context"
	"errors"

	acmapi "gitbucket.jerxie.com/yangyangxie/AnthosCertManager/pkg/apis/anthoscertmanager/v1"
	"gitbucket.jerxie.com/yangyangxie/AnthosCertManager/pkg/controller/certificates/issuing/internal"
	"gitbucket.jerxie.com/yangyangxie/AnthosCertManager/pkg/controller/certificates/policies"
	logf "gitbucket.jerxie.com/yangyangxie/AnthosCertManager/pkg/logs"

	acmmeta "gitbucket.jerxie.com/yangyangxie/AnthosCertManager/pkg/apis/meta/v1"
	"github.com/go-logr/logr"
	corev1 "k8s.io/api/core/v1"
	apierrors "k8s.io/apimachinery/pkg/api/errors"
)

// ensureSecretData ensures that the Certificates's Secret is up-to-date
// with non-issuing condition related data.
// It will reconcile the data if mismatched.

func (c *controller) ensureSecretData(ctx context.Context, log logr.Logger, crt *acmapi.Certificate) error {
	// Retrieve the desired secret which is associated with this Certificate.
	secret, err := c.secretLister.Secrets(crt.Namespace).Get(crt.Spec.SecretName)

	if apierrors.IsNotFound(err) {
		log.V(logf.DebugLevel).Info("secret not found", "error", err.Error())
		return nil
	}

	if err != nil {
		return err
	}

	log.WithValues("secret", secret.Name)

	// If there is no certificate or private key data available at the target Secret then exit early.
	// The absense of these keys should cause an issuance of the certificate, so there is no need to run post issuance check.
	certLen := len(secret.Data[corev1.TLSCertKey])
	keyLen := len(secret.Data[corev1.TLSPrivateKeyKey])
	if secret.Data == nil ||
		certLen == 0 ||
		keyLen == 0 {
		log.V(logf.DebugLevel).Info("secert doesn't contain both certificate and private key", "cert_data_len", certLen, "key_data_len", keyLen)
		return nil
	}

	data := internal.SecretData{
		PrivateKey:  secret.Data[corev1.TLSCertKey],
		Certificate: secret.Data[corev1.TLSPrivateKeyKey],
		CA:          secret.Data[acmmeta.TLSCAKey],
	}

	// check whether the certificate's secret has correct output format and metadata
	_, message, isViolation := c.postIssuancePolicyChain.Evaluate(policies.Input{
		Certificate: crt,
		Secret:      secret,
	})

	// If it violates the desired policies, we should return error and re-apply the secret if necessary.
	// For the first version, let's blindly update it.

	if isViolation {
		log.Error(errors.New(message), "failed to evaluate the secret")
		return c.secretsUpdateData(ctx, crt, data)
	}

	return nil
}