Newer
Older
AnthosCertManager / pkg / controller / certificates / policies / checks.go
package policies

import (
	"fmt"

	acmapi "gitbucket.jerxie.com/yangyangxie/AnthosCertManager/pkg/apis/anthoscertmanager/v1"
	"gitbucket.jerxie.com/yangyangxie/AnthosCertManager/pkg/controller/certificates"

	"gitbucket.jerxie.com/yangyangxie/AnthosCertManager/pkg/util/pki"
	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

	"k8s.io/utils/clock"
)

// SecretOwnerReferenceManagedFieldMismatch validates that the Secret has an
// owner reference to the Certificate if enabled. Returns true (violation) if:
// * the Secret doesn't have an owner reference and is expecting one
// * has an owner reference but is not expecting one
// A violation with the reason `ManagedFieldsParseError` should be considered a
// non re-triable error.
func SecretOwnerReferenceManagedFieldMismatch(ownerRefEnabled bool, fieldManager string) Func {
	return func(input Input) (string, string, bool) {
		return "", "", false
	}

}

func SecretDoesNotExist(input Input) (string, string, bool) {
	if input.Secret == nil {
		return DoesNotExist, "Issuing certificate as Secret does not exist", true
	}
	return "", "", false
}

func SecretIssuerAnnotationsNotUpToDate(input Input) (string, string, bool) {
	name := input.Secret.Annotations[acmapi.IssuerNameAnnotationKey]
	kind := input.Secret.Annotations[acmapi.IssuerKindAnnotationKey]
	group := input.Secret.Annotations[acmapi.IssuerGroupAnnotationKey]

	if name != input.Certificate.Spec.IssuerRef.Name ||
		kind != input.Certificate.Spec.IssuerRef.Kind ||
		group != input.Certificate.Spec.IssuerRef.Group {
		return IncorrectIssuer, fmt.Sprintf("Issuing certificate as Secret was previously issued by %s", formatIssuerRef(name, kind, group)), true
	}
	return "", "", false

}

// CurrentCertificateNearingExpiry returns a policy function that can be used to
// check whether an X.509 cert currently issued for a Certificate should be
// renewed.
func CurrentCertificateNearingExpiry(c clock.Clock) Func {

	return func(input Input) (string, string, bool) {

		// Determine if the certificate is nearing expiry solely by looking at
		// the actual cert, if it exists. We assume that at this point we have
		// called policy functions that check that input.Secret and
		// input.Secret.Data exists (SecretDoesNotExist and SecretIsMissingData).
		x509cert, err := pki.DecodeX509CertificateBytes(input.Secret.Data[corev1.TLSCertKey])
		if err != nil {
			// This case should never happen as it should always be caught by the
			// secretPublicKeysMatch function beforehand, but handle it just in case.
			return InvalidCertificate, fmt.Sprintf("Failed to decode stored certificate: %v", err), true
		}

		notBefore := metav1.NewTime(x509cert.NotBefore)
		notAfter := metav1.NewTime(x509cert.NotAfter)
		crt := input.Certificate
		renewalTime := certificates.RenewalTime(notBefore.Time, notAfter.Time, crt.Spec.RenewBefore)

		renewIn := renewalTime.Time.Sub(c.Now())
		if renewIn > 0 {
			//renewal time is in future, no need to renew
			return "", "", false
		}

		return Renewing, fmt.Sprintf("Renewing certificate as renewal was scheduled at %s", input.Certificate.Status.RenewalTime), true
	}
}

func formatIssuerRef(name, kind, group string) string {
	if group == "" {
		group = "anthos-cert-manager.io"
	}
	if kind == "" {
		kind = "Issuer"
	}
	return fmt.Sprintf("%s.%s/%s", kind, group, name)
}