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)
}