Add duration into ACME

Signed-off-by: Maartje Eyskens <maartje@eyskens.me>
This commit is contained in:
Maartje Eyskens 2020-10-06 17:22:32 +02:00
parent 811b67bb8c
commit 7b6573aa35
30 changed files with 348 additions and 9 deletions

View File

@ -75,6 +75,9 @@ spec:
email:
description: Email is the email address to be associated with the ACME account. This field is optional, but it is strongly recommended to be set. It will be used to contact you in case of issues with your account or certificates, including expiry notification emails. This field may be updated after the account is initially registered.
type: string
enableNotAfterDate:
description: Enables requesting a Not After date on certificates that matches the duration of the certificate. This is not supported by all ACME servers like Let's Encrypt. If set to true when the ACME server does not support it it will create an error on the Order. Defaults to false.
type: boolean
externalAccountBinding:
description: ExternalAccountBinding is a reference to a CA external account of the ACME server. If set, upon registration cert-manager will attempt to associate the given external account credentials with the registered ACME account.
type: object
@ -1087,6 +1090,9 @@ spec:
email:
description: Email is the email address to be associated with the ACME account. This field is optional, but it is strongly recommended to be set. It will be used to contact you in case of issues with your account or certificates, including expiry notification emails. This field may be updated after the account is initially registered.
type: string
enableNotAfterDate:
description: Enables requesting a Not After date on certificates that matches the duration of the certificate. This is not supported by all ACME servers like Let's Encrypt. If set to true when the ACME server does not support it it will create an error on the Order. Defaults to false.
type: boolean
externalAccountBinding:
description: ExternalAccountBinding is a reference to a CA external account of the ACME server. If set, upon registration cert-manager will attempt to associate the given external account credentials with the registered ACME account.
type: object
@ -2101,6 +2107,9 @@ spec:
email:
description: Email is the email address to be associated with the ACME account. This field is optional, but it is strongly recommended to be set. It will be used to contact you in case of issues with your account or certificates, including expiry notification emails. This field may be updated after the account is initially registered.
type: string
enableNotAfterDate:
description: Enables requesting a Not After date on certificates that matches the duration of the certificate. This is not supported by all ACME servers like Let's Encrypt. If set to true when the ACME server does not support it it will create an error on the Order. Defaults to false.
type: boolean
externalAccountBinding:
description: ExternalAccountBinding is a reference to a CA external account of the ACME server. If set, upon registration cert-manager will attempt to associate the given external account credentials with the registered ACME account.
type: object
@ -3115,6 +3124,9 @@ spec:
email:
description: Email is the email address to be associated with the ACME account. This field is optional, but it is strongly recommended to be set. It will be used to contact you in case of issues with your account or certificates, including expiry notification emails. This field may be updated after the account is initially registered.
type: string
enableNotAfterDate:
description: Enables requesting a Not After date on certificates that matches the duration of the certificate. This is not supported by all ACME servers like Let's Encrypt. If set to true when the ACME server does not support it it will create an error on the Order. Defaults to false.
type: boolean
externalAccountBinding:
description: ExternalAccountBinding is a reference to a CA external account of the ACME server. If set, upon registration cert-manager will attempt to associate the given external account credentials with the registered ACME account.
type: object

View File

@ -75,6 +75,9 @@ spec:
email:
description: Email is the email address to be associated with the ACME account. This field is optional, but it is strongly recommended to be set. It will be used to contact you in case of issues with your account or certificates, including expiry notification emails. This field may be updated after the account is initially registered.
type: string
enableNotAfterDate:
description: Enables requesting a Not After date on certificates that matches the duration of the certificate. This is not supported by all ACME servers like Let's Encrypt. If set to true when the ACME server does not support it it will create an error on the Order. Defaults to false.
type: boolean
externalAccountBinding:
description: ExternalAccountBinding is a reference to a CA external account of the ACME server. If set, upon registration cert-manager will attempt to associate the given external account credentials with the registered ACME account.
type: object
@ -1101,6 +1104,9 @@ spec:
email:
description: Email is the email address to be associated with the ACME account. This field is optional, but it is strongly recommended to be set. It will be used to contact you in case of issues with your account or certificates, including expiry notification emails. This field may be updated after the account is initially registered.
type: string
enableNotAfterDate:
description: Enables requesting a Not After date on certificates that matches the duration of the certificate. This is not supported by all ACME servers like Let's Encrypt. If set to true when the ACME server does not support it it will create an error on the Order. Defaults to false.
type: boolean
externalAccountBinding:
description: ExternalAccountBinding is a reference to a CA external account of the ACME server. If set, upon registration cert-manager will attempt to associate the given external account credentials with the registered ACME account.
type: object
@ -2129,6 +2135,9 @@ spec:
email:
description: Email is the email address to be associated with the ACME account. This field is optional, but it is strongly recommended to be set. It will be used to contact you in case of issues with your account or certificates, including expiry notification emails. This field may be updated after the account is initially registered.
type: string
enableNotAfterDate:
description: Enables requesting a Not After date on certificates that matches the duration of the certificate. This is not supported by all ACME servers like Let's Encrypt. If set to true when the ACME server does not support it it will create an error on the Order. Defaults to false.
type: boolean
externalAccountBinding:
description: ExternalAccountBinding is a reference to a CA external account of the ACME server. If set, upon registration cert-manager will attempt to associate the given external account credentials with the registered ACME account.
type: object
@ -3157,6 +3166,9 @@ spec:
email:
description: Email is the email address to be associated with the ACME account. This field is optional, but it is strongly recommended to be set. It will be used to contact you in case of issues with your account or certificates, including expiry notification emails. This field may be updated after the account is initially registered.
type: string
enableNotAfterDate:
description: Enables requesting a Not After date on certificates that matches the duration of the certificate. This is not supported by all ACME servers like Let's Encrypt. If set to true when the ACME server does not support it it will create an error on the Order. Defaults to false.
type: boolean
externalAccountBinding:
description: ExternalAccountBinding is a reference to a CA external account of the ACME server. If set, upon registration cert-manager will attempt to associate the given external account credentials with the registered ACME account.
type: object

View File

@ -75,6 +75,9 @@ spec:
email:
description: Email is the email address to be associated with the ACME account. This field is optional, but it is strongly recommended to be set. It will be used to contact you in case of issues with your account or certificates, including expiry notification emails. This field may be updated after the account is initially registered.
type: string
enableNotAfterDate:
description: Enables requesting a Not After date on certificates that matches the duration of the certificate. This is not supported by all ACME servers like Let's Encrypt. If set to true when the ACME server does not support it it will create an error on the Order. Defaults to false.
type: boolean
externalAccountBinding:
description: ExternalAccountBinding is a reference to a CA external account of the ACME server. If set, upon registration cert-manager will attempt to associate the given external account credentials with the registered ACME account.
type: object
@ -1087,6 +1090,9 @@ spec:
email:
description: Email is the email address to be associated with the ACME account. This field is optional, but it is strongly recommended to be set. It will be used to contact you in case of issues with your account or certificates, including expiry notification emails. This field may be updated after the account is initially registered.
type: string
enableNotAfterDate:
description: Enables requesting a Not After date on certificates that matches the duration of the certificate. This is not supported by all ACME servers like Let's Encrypt. If set to true when the ACME server does not support it it will create an error on the Order. Defaults to false.
type: boolean
externalAccountBinding:
description: ExternalAccountBinding is a reference to a CA external account of the ACME server. If set, upon registration cert-manager will attempt to associate the given external account credentials with the registered ACME account.
type: object
@ -2101,6 +2107,9 @@ spec:
email:
description: Email is the email address to be associated with the ACME account. This field is optional, but it is strongly recommended to be set. It will be used to contact you in case of issues with your account or certificates, including expiry notification emails. This field may be updated after the account is initially registered.
type: string
enableNotAfterDate:
description: Enables requesting a Not After date on certificates that matches the duration of the certificate. This is not supported by all ACME servers like Let's Encrypt. If set to true when the ACME server does not support it it will create an error on the Order. Defaults to false.
type: boolean
externalAccountBinding:
description: ExternalAccountBinding is a reference to a CA external account of the ACME server. If set, upon registration cert-manager will attempt to associate the given external account credentials with the registered ACME account.
type: object
@ -3115,6 +3124,9 @@ spec:
email:
description: Email is the email address to be associated with the ACME account. This field is optional, but it is strongly recommended to be set. It will be used to contact you in case of issues with your account or certificates, including expiry notification emails. This field may be updated after the account is initially registered.
type: string
enableNotAfterDate:
description: Enables requesting a Not After date on certificates that matches the duration of the certificate. This is not supported by all ACME servers like Let's Encrypt. If set to true when the ACME server does not support it it will create an error on the Order. Defaults to false.
type: boolean
externalAccountBinding:
description: ExternalAccountBinding is a reference to a CA external account of the ACME server. If set, upon registration cert-manager will attempt to associate the given external account credentials with the registered ACME account.
type: object

View File

@ -75,6 +75,9 @@ spec:
email:
description: Email is the email address to be associated with the ACME account. This field is optional, but it is strongly recommended to be set. It will be used to contact you in case of issues with your account or certificates, including expiry notification emails. This field may be updated after the account is initially registered.
type: string
enableNotAfterDate:
description: Enables requesting a Not After date on certificates that matches the duration of the certificate. This is not supported by all ACME servers like Let's Encrypt. If set to true when the ACME server does not support it it will create an error on the Order. Defaults to false.
type: boolean
externalAccountBinding:
description: ExternalAccountBinding is a reference to a CA external account of the ACME server. If set, upon registration cert-manager will attempt to associate the given external account credentials with the registered ACME account.
type: object
@ -1101,6 +1104,9 @@ spec:
email:
description: Email is the email address to be associated with the ACME account. This field is optional, but it is strongly recommended to be set. It will be used to contact you in case of issues with your account or certificates, including expiry notification emails. This field may be updated after the account is initially registered.
type: string
enableNotAfterDate:
description: Enables requesting a Not After date on certificates that matches the duration of the certificate. This is not supported by all ACME servers like Let's Encrypt. If set to true when the ACME server does not support it it will create an error on the Order. Defaults to false.
type: boolean
externalAccountBinding:
description: ExternalAccountBinding is a reference to a CA external account of the ACME server. If set, upon registration cert-manager will attempt to associate the given external account credentials with the registered ACME account.
type: object
@ -2129,6 +2135,9 @@ spec:
email:
description: Email is the email address to be associated with the ACME account. This field is optional, but it is strongly recommended to be set. It will be used to contact you in case of issues with your account or certificates, including expiry notification emails. This field may be updated after the account is initially registered.
type: string
enableNotAfterDate:
description: Enables requesting a Not After date on certificates that matches the duration of the certificate. This is not supported by all ACME servers like Let's Encrypt. If set to true when the ACME server does not support it it will create an error on the Order. Defaults to false.
type: boolean
externalAccountBinding:
description: ExternalAccountBinding is a reference to a CA external account of the ACME server. If set, upon registration cert-manager will attempt to associate the given external account credentials with the registered ACME account.
type: object
@ -3157,6 +3166,9 @@ spec:
email:
description: Email is the email address to be associated with the ACME account. This field is optional, but it is strongly recommended to be set. It will be used to contact you in case of issues with your account or certificates, including expiry notification emails. This field may be updated after the account is initially registered.
type: string
enableNotAfterDate:
description: Enables requesting a Not After date on certificates that matches the duration of the certificate. This is not supported by all ACME servers like Let's Encrypt. If set to true when the ACME server does not support it it will create an error on the Order. Defaults to false.
type: boolean
externalAccountBinding:
description: ExternalAccountBinding is a reference to a CA external account of the ACME server. If set, upon registration cert-manager will attempt to associate the given external account credentials with the registered ACME account.
type: object

View File

@ -102,6 +102,10 @@ spec:
name:
description: Name of the resource being referred to.
type: string
notAfter:
description: NotAfter is the date for the requested certificate's Not Valid After date
type: string
format: date-time
status:
type: object
properties:
@ -238,6 +242,10 @@ spec:
name:
description: Name of the resource being referred to.
type: string
notAfter:
description: NotAfter is the date for the requested certificate's Not Valid After date
type: string
format: date-time
status:
type: object
properties:
@ -371,6 +379,10 @@ spec:
name:
description: Name of the resource being referred to.
type: string
notAfter:
description: NotAfter is the date for the requested certificate's Not Valid After date
type: string
format: date-time
request:
description: Certificate signing request bytes in DER encoding. This will be used when finalizing the order. This field must be set on the order.
type: string
@ -508,6 +520,10 @@ spec:
name:
description: Name of the resource being referred to.
type: string
notAfter:
description: NotAfter is the date for the requested certificate's Not Valid After date
type: string
format: date-time
request:
description: Certificate signing request bytes in DER encoding. This will be used when finalizing the order. This field must be set on the order.
type: string

View File

@ -102,6 +102,10 @@ spec:
name:
description: Name of the resource being referred to.
type: string
notAfter:
description: NotAfter is the date for the requested certificate's Not Valid After date
type: string
format: date-time
status:
type: object
properties:
@ -256,6 +260,10 @@ spec:
name:
description: Name of the resource being referred to.
type: string
notAfter:
description: NotAfter is the date for the requested certificate's Not Valid After date
type: string
format: date-time
status:
type: object
properties:
@ -407,6 +415,10 @@ spec:
name:
description: Name of the resource being referred to.
type: string
notAfter:
description: NotAfter is the date for the requested certificate's Not Valid After date
type: string
format: date-time
request:
description: Certificate signing request bytes in DER encoding. This will be used when finalizing the order. This field must be set on the order.
type: string
@ -562,6 +574,10 @@ spec:
name:
description: Name of the resource being referred to.
type: string
notAfter:
description: NotAfter is the date for the requested certificate's Not Valid After date
type: string
format: date-time
request:
description: Certificate signing request bytes in DER encoding. This will be used when finalizing the order. This field must be set on the order.
type: string

View File

@ -93,6 +93,14 @@ type ACMEIssuer struct {
// Defaults to false.
// +optional
DisableAccountKeyGeneration bool `json:"disableAccountKeyGeneration,omitempty"`
// Enables requesting a Not After date on certificates that matches the
// duration of the certificate. This is not supported by all ACME servers
// like Let's Encrypt. If set to true when the ACME server does not support
// it it will create an error on the Order.
// Defaults to false.
// +optional
EnableNotAfterDate bool `json:"enableNotAfterDate,omitempty"`
}
// ACMEExternalAccountBinding is a reference to a CA external account of the ACME

View File

@ -69,7 +69,7 @@ type OrderSpec struct {
// DNSNames is a list of DNS names that should be included as part of the Order
// validation process.
// This field must match the corresponding field on the DER encoded CSR.
//+optonal
//+optional
DNSNames []string `json:"dnsNames,omitempty"`
// IPAddresses is a list of IP addresses that should be included as part of the Order
@ -77,6 +77,10 @@ type OrderSpec struct {
// This field must match the corresponding field on the DER encoded CSR.
// +optional
IPAddresses []string `json:"ipAddresses,omitempty"`
// NotAfter is the date for the requested certificate's Not Valid After date
// +optional
NotAfter *metav1.Time `json:"notAfter,omitempty"`
}
type OrderStatus struct {

View File

@ -789,6 +789,10 @@ func (in *OrderSpec) DeepCopyInto(out *OrderSpec) {
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.NotAfter != nil {
in, out := &in.NotAfter, &out.NotAfter
*out = (*in).DeepCopy()
}
return
}

View File

@ -93,6 +93,14 @@ type ACMEIssuer struct {
// Defaults to false.
// +optional
DisableAccountKeyGeneration bool `json:"disableAccountKeyGeneration,omitempty"`
// Enables requesting a Not After date on certificates that matches the
// duration of the certificate. This is not supported by all ACME servers
// like Let's Encrypt. If set to true when the ACME server does not support
// it it will create an error on the Order.
// Defaults to false.
// +optional
EnableNotAfterDate bool `json:"enableNotAfterDate,omitempty"`
}
// ACMEExternalAccountBinding is a reference to a CA external account of the ACME

View File

@ -67,7 +67,7 @@ type OrderSpec struct {
// DNSNames is a list of DNS names that should be included as part of the Order
// validation process.
// This field must match the corresponding field on the DER encoded CSR.
//+optonal
//+optional
DNSNames []string `json:"dnsNames,omitempty"`
// IPAddresses is a list of IP addresses that should be included as part of the Order
@ -75,6 +75,10 @@ type OrderSpec struct {
// This field must match the corresponding field on the DER encoded CSR.
// +optional
IPAddresses []string `json:"ipAddresses,omitempty"`
// NotAfter is the date for the requested certificate's Not Valid After date
// +optional
NotAfter *metav1.Time `json:"notAfter,omitempty"`
}
type OrderStatus struct {

View File

@ -789,6 +789,10 @@ func (in *OrderSpec) DeepCopyInto(out *OrderSpec) {
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.NotAfter != nil {
in, out := &in.NotAfter, &out.NotAfter
*out = (*in).DeepCopy()
}
return
}

View File

@ -93,6 +93,14 @@ type ACMEIssuer struct {
// Defaults to false.
// +optional
DisableAccountKeyGeneration bool `json:"disableAccountKeyGeneration,omitempty"`
// Enables requesting a Not After date on certificates that matches the
// duration of the certificate. This is not supported by all ACME servers
// like Let's Encrypt. If set to true when the ACME server does not support
// it it will create an error on the Order.
// Defaults to false.
// +optional
EnableNotAfterDate bool `json:"enableNotAfterDate,omitempty"`
}
// ACMEExternalAccountBinding is a reference to a CA external account of the ACME

View File

@ -67,7 +67,7 @@ type OrderSpec struct {
// DNSNames is a list of DNS names that should be included as part of the Order
// validation process.
// This field must match the corresponding field on the DER encoded CSR.
//+optonal
//+optional
DNSNames []string `json:"dnsNames,omitempty"`
// IPAddresses is a list of IP addresses that should be included as part of the Order
@ -75,6 +75,10 @@ type OrderSpec struct {
// This field must match the corresponding field on the DER encoded CSR.
// +optional
IPAddresses []string `json:"ipAddresses,omitempty"`
// NotAfter is the date for the requested certificate's Not Valid After date
// +optional
NotAfter *metav1.Time `json:"notAfter,omitempty"`
}
type OrderStatus struct {

View File

@ -789,6 +789,10 @@ func (in *OrderSpec) DeepCopyInto(out *OrderSpec) {
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.NotAfter != nil {
in, out := &in.NotAfter, &out.NotAfter
*out = (*in).DeepCopy()
}
return
}

View File

@ -93,6 +93,14 @@ type ACMEIssuer struct {
// Defaults to false.
// +optional
DisableAccountKeyGeneration bool `json:"disableAccountKeyGeneration,omitempty"`
// Enables requesting a Not After date on certificates that matches the
// duration of the certificate. This is not supported by all ACME servers
// like Let's Encrypt. If set to true when the ACME server does not support
// it it will create an error on the Order.
// Defaults to false.
// +optional
EnableNotAfterDate bool `json:"enableNotAfterDate,omitempty"`
}
// ACMEExternalAccountBinding is a reference to a CA external account of the ACME

View File

@ -68,7 +68,7 @@ type OrderSpec struct {
// DNSNames is a list of DNS names that should be included as part of the Order
// validation process.
// This field must match the corresponding field on the DER encoded CSR.
//+optonal
//+optional
DNSNames []string `json:"dnsNames,omitempty"`
// IPAddresses is a list of IP addresses that should be included as part of the Order
@ -76,6 +76,10 @@ type OrderSpec struct {
// This field must match the corresponding field on the DER encoded CSR.
// +optional
IPAddresses []string `json:"ipAddresses,omitempty"`
// NotAfter is the date for the requested certificate's Not Valid After date
// +optional
NotAfter *metav1.Time `json:"notAfter,omitempty"`
}
type OrderStatus struct {

View File

@ -789,6 +789,10 @@ func (in *OrderSpec) DeepCopyInto(out *OrderSpec) {
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.NotAfter != nil {
in, out := &in.NotAfter, &out.NotAfter
*out = (*in).DeepCopy()
}
return
}

View File

@ -200,7 +200,12 @@ func (c *controller) createOrder(ctx context.Context, cl acmecl.Interface, o *cm
authzIDs := acmeapi.DomainIDs(dnsIdentifierSet.List()...)
authzIDs = append(authzIDs, acmeapi.IPIDs(ipIdentifierSet.List()...)...)
// create a new order with the acme server
acmeOrder, err := cl.AuthorizeOrder(ctx, authzIDs)
var options []acmeapi.OrderOption
if o.Spec.NotAfter != nil {
options = append(options, acmeapi.WithOrderNotAfter(o.Spec.NotAfter.Time))
}
acmeOrder, err := cl.AuthorizeOrder(ctx, authzIDs, options...)
if acmeErr, ok := err.(*acmeapi.Error); ok {
if acmeErr.StatusCode >= 400 && acmeErr.StatusCode < 500 {
log.Error(err, "failed to create Order resource due to bad request, marking Order as failed")

View File

@ -20,6 +20,7 @@ import (
"context"
"crypto/x509"
"fmt"
"time"
k8sErrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -105,7 +106,7 @@ func (a *ACME) Sign(ctx context.Context, cr *v1.CertificateRequest, issuer v1.Ge
}
// If we fail to build the order we have to hard fail.
expectedOrder, err := buildOrder(cr, csr)
expectedOrder, err := buildOrder(cr, csr, issuer)
if err != nil {
message := "Failed to build order"
@ -199,7 +200,7 @@ func (a *ACME) Sign(ctx context.Context, cr *v1.CertificateRequest, issuer v1.Ge
}
// Build order. If we error here it is a terminating failure.
func buildOrder(cr *v1.CertificateRequest, csr *x509.CertificateRequest) (*cmacme.Order, error) {
func buildOrder(cr *v1.CertificateRequest, csr *x509.CertificateRequest, issuer v1.GenericIssuer) (*cmacme.Order, error) {
var ipAddresses []string
for _, ip := range csr.IPAddresses {
ipAddresses = append(ipAddresses, ip.String())
@ -218,9 +219,15 @@ func buildOrder(cr *v1.CertificateRequest, csr *x509.CertificateRequest) (*cmacm
IPAddresses: ipAddresses,
}
if issuer.GetSpec().ACME.EnableNotAfterDate {
notAfterTime := metav1.NewTime(time.Now().Add(cr.Spec.Duration.Duration))
spec.NotAfter = &notAfterTime
}
computeNameSpec := spec.DeepCopy()
// create a deep copy of the OrderSpec so we can overwrite the Request field
// create a deep copy of the OrderSpec so we can overwrite the Request and NotAfter field
computeNameSpec.Request = nil
computeNameSpec.NotAfter = nil // NotAfter is time based and will shift, confusing the controller to reconcile
name, err := apiutil.ComputeName(cr.Name, computeNameSpec)
if err != nil {
return nil, err

View File

@ -153,7 +153,7 @@ func TestSign(t *testing.T) {
t.Fatalf("failed to build order during testing: %s", err)
}
baseOrder, err := buildOrder(baseCR, csr)
baseOrder, err := buildOrder(baseCR, csr, baseIssuer)
if err != nil {
t.Fatalf("failed to build order during testing: %s", err)
}

View File

@ -85,6 +85,13 @@ type ACMEIssuer struct {
// Defaults to false.
// +optional
DisableAccountKeyGeneration bool `json:"disableAccountKeyGeneration,omitempty"`
// Enables requesting a Not After date on certificates that matches the
// duration of the certificate. This is not supported by all ACME servers
// like Let's Encrypt. If set to true when the ACME server does not support
// it it will create an error on the Order.
// Defaults to false.
EnableNotAfterDate bool `json:"enableNotAfterDate,omitempty"`
}
// ACMEExternalAccountBinding is a reference to a CA external account of the ACME

View File

@ -70,6 +70,9 @@ type OrderSpec struct {
// validation process.
// This field must match the corresponding field on the DER encoded CSR.
IPAddresses []string
// NotAfter is the date for the requested certificate's Not Valid After date
NotAfter *metav1.Time `json:"notAfter"`
}
type OrderStatus struct {

View File

@ -694,6 +694,7 @@ func autoConvert_v1_ACMEIssuer_To_acme_ACMEIssuer(in *v1.ACMEIssuer, out *acme.A
}
out.Solvers = *(*[]acme.ACMEChallengeSolver)(unsafe.Pointer(&in.Solvers))
out.DisableAccountKeyGeneration = in.DisableAccountKeyGeneration
out.EnableNotAfterDate = in.EnableNotAfterDate
return nil
}
@ -714,6 +715,7 @@ func autoConvert_acme_ACMEIssuer_To_v1_ACMEIssuer(in *acme.ACMEIssuer, out *v1.A
}
out.Solvers = *(*[]v1.ACMEChallengeSolver)(unsafe.Pointer(&in.Solvers))
out.DisableAccountKeyGeneration = in.DisableAccountKeyGeneration
out.EnableNotAfterDate = in.EnableNotAfterDate
return nil
}
@ -1245,6 +1247,7 @@ func autoConvert_v1_OrderSpec_To_acme_OrderSpec(in *v1.OrderSpec, out *acme.Orde
out.CommonName = in.CommonName
out.DNSNames = *(*[]string)(unsafe.Pointer(&in.DNSNames))
out.IPAddresses = *(*[]string)(unsafe.Pointer(&in.IPAddresses))
out.NotAfter = (*apismetav1.Time)(unsafe.Pointer(in.NotAfter))
return nil
}
@ -1262,6 +1265,7 @@ func autoConvert_acme_OrderSpec_To_v1_OrderSpec(in *acme.OrderSpec, out *v1.Orde
out.CommonName = in.CommonName
out.DNSNames = *(*[]string)(unsafe.Pointer(&in.DNSNames))
out.IPAddresses = *(*[]string)(unsafe.Pointer(&in.IPAddresses))
out.NotAfter = (*apismetav1.Time)(unsafe.Pointer(in.NotAfter))
return nil
}

View File

@ -694,6 +694,7 @@ func autoConvert_v1alpha2_ACMEIssuer_To_acme_ACMEIssuer(in *v1alpha2.ACMEIssuer,
}
out.Solvers = *(*[]acme.ACMEChallengeSolver)(unsafe.Pointer(&in.Solvers))
out.DisableAccountKeyGeneration = in.DisableAccountKeyGeneration
out.EnableNotAfterDate = in.EnableNotAfterDate
return nil
}
@ -714,6 +715,7 @@ func autoConvert_acme_ACMEIssuer_To_v1alpha2_ACMEIssuer(in *acme.ACMEIssuer, out
}
out.Solvers = *(*[]v1alpha2.ACMEChallengeSolver)(unsafe.Pointer(&in.Solvers))
out.DisableAccountKeyGeneration = in.DisableAccountKeyGeneration
out.EnableNotAfterDate = in.EnableNotAfterDate
return nil
}
@ -1255,6 +1257,7 @@ func autoConvert_v1alpha2_OrderSpec_To_acme_OrderSpec(in *v1alpha2.OrderSpec, ou
out.CommonName = in.CommonName
out.DNSNames = *(*[]string)(unsafe.Pointer(&in.DNSNames))
out.IPAddresses = *(*[]string)(unsafe.Pointer(&in.IPAddresses))
out.NotAfter = (*apismetav1.Time)(unsafe.Pointer(in.NotAfter))
return nil
}
@ -1267,6 +1270,7 @@ func autoConvert_acme_OrderSpec_To_v1alpha2_OrderSpec(in *acme.OrderSpec, out *v
out.CommonName = in.CommonName
out.DNSNames = *(*[]string)(unsafe.Pointer(&in.DNSNames))
out.IPAddresses = *(*[]string)(unsafe.Pointer(&in.IPAddresses))
out.NotAfter = (*apismetav1.Time)(unsafe.Pointer(in.NotAfter))
return nil
}

View File

@ -694,6 +694,7 @@ func autoConvert_v1alpha3_ACMEIssuer_To_acme_ACMEIssuer(in *v1alpha3.ACMEIssuer,
}
out.Solvers = *(*[]acme.ACMEChallengeSolver)(unsafe.Pointer(&in.Solvers))
out.DisableAccountKeyGeneration = in.DisableAccountKeyGeneration
out.EnableNotAfterDate = in.EnableNotAfterDate
return nil
}
@ -714,6 +715,7 @@ func autoConvert_acme_ACMEIssuer_To_v1alpha3_ACMEIssuer(in *acme.ACMEIssuer, out
}
out.Solvers = *(*[]v1alpha3.ACMEChallengeSolver)(unsafe.Pointer(&in.Solvers))
out.DisableAccountKeyGeneration = in.DisableAccountKeyGeneration
out.EnableNotAfterDate = in.EnableNotAfterDate
return nil
}
@ -1255,6 +1257,7 @@ func autoConvert_v1alpha3_OrderSpec_To_acme_OrderSpec(in *v1alpha3.OrderSpec, ou
out.CommonName = in.CommonName
out.DNSNames = *(*[]string)(unsafe.Pointer(&in.DNSNames))
out.IPAddresses = *(*[]string)(unsafe.Pointer(&in.IPAddresses))
out.NotAfter = (*apismetav1.Time)(unsafe.Pointer(in.NotAfter))
return nil
}
@ -1267,6 +1270,7 @@ func autoConvert_acme_OrderSpec_To_v1alpha3_OrderSpec(in *acme.OrderSpec, out *v
out.CommonName = in.CommonName
out.DNSNames = *(*[]string)(unsafe.Pointer(&in.DNSNames))
out.IPAddresses = *(*[]string)(unsafe.Pointer(&in.IPAddresses))
out.NotAfter = (*apismetav1.Time)(unsafe.Pointer(in.NotAfter))
return nil
}

View File

@ -694,6 +694,7 @@ func autoConvert_v1beta1_ACMEIssuer_To_acme_ACMEIssuer(in *v1beta1.ACMEIssuer, o
}
out.Solvers = *(*[]acme.ACMEChallengeSolver)(unsafe.Pointer(&in.Solvers))
out.DisableAccountKeyGeneration = in.DisableAccountKeyGeneration
out.EnableNotAfterDate = in.EnableNotAfterDate
return nil
}
@ -714,6 +715,7 @@ func autoConvert_acme_ACMEIssuer_To_v1beta1_ACMEIssuer(in *acme.ACMEIssuer, out
}
out.Solvers = *(*[]v1beta1.ACMEChallengeSolver)(unsafe.Pointer(&in.Solvers))
out.DisableAccountKeyGeneration = in.DisableAccountKeyGeneration
out.EnableNotAfterDate = in.EnableNotAfterDate
return nil
}
@ -1245,6 +1247,7 @@ func autoConvert_v1beta1_OrderSpec_To_acme_OrderSpec(in *v1beta1.OrderSpec, out
out.CommonName = in.CommonName
out.DNSNames = *(*[]string)(unsafe.Pointer(&in.DNSNames))
out.IPAddresses = *(*[]string)(unsafe.Pointer(&in.IPAddresses))
out.NotAfter = (*apismetav1.Time)(unsafe.Pointer(in.NotAfter))
return nil
}
@ -1262,6 +1265,7 @@ func autoConvert_acme_OrderSpec_To_v1beta1_OrderSpec(in *acme.OrderSpec, out *v1
out.CommonName = in.CommonName
out.DNSNames = *(*[]string)(unsafe.Pointer(&in.DNSNames))
out.IPAddresses = *(*[]string)(unsafe.Pointer(&in.IPAddresses))
out.NotAfter = (*apismetav1.Time)(unsafe.Pointer(in.NotAfter))
return nil
}

View File

@ -789,6 +789,10 @@ func (in *OrderSpec) DeepCopyInto(out *OrderSpec) {
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.NotAfter != nil {
in, out := &in.NotAfter, &out.NotAfter
*out = (*in).DeepCopy()
}
return
}

View File

@ -5,6 +5,7 @@ go_library(
srcs = [
"dns01.go",
"http01.go",
"notafter.go",
"webhook.go",
],
importpath = "github.com/jetstack/cert-manager/test/e2e/suite/issuers/acme/certificate",
@ -16,6 +17,7 @@ go_library(
"//pkg/apis/meta/v1:go_default_library",
"//pkg/client/clientset/versioned:go_default_library",
"//pkg/util:go_default_library",
"//pkg/util/pki:go_default_library",
"//test/e2e/framework:go_default_library",
"//test/e2e/framework/addon:go_default_library",
"//test/e2e/framework/log:go_default_library",

View File

@ -0,0 +1,151 @@
/*
Copyright 2019 The Jetstack cert-manager contributors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package certificate
import (
"context"
"fmt"
"time"
"github.com/jetstack/cert-manager/pkg/util/pki"
corev1 "k8s.io/api/core/v1"
cmacme "github.com/jetstack/cert-manager/pkg/apis/acme/v1"
v1 "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1"
cmmeta "github.com/jetstack/cert-manager/pkg/apis/meta/v1"
"github.com/jetstack/cert-manager/test/e2e/framework"
frameworkutil "github.com/jetstack/cert-manager/test/e2e/framework/util"
"github.com/jetstack/cert-manager/test/e2e/util"
"github.com/jetstack/cert-manager/test/unit/gen"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
var _ = framework.CertManagerDescribe("ACME Certificate (HTTP01 + Not After)", func() {
f := framework.NewDefaultFramework("create-acme-certificate-duration")
var acmeIngressDomain string
issuerName := "test-acme-issuer"
certificateName := "test-acme-certificate"
certificateSecretName := "test-acme-certificate"
// fixedIngressName is the name of an ingress resource that is configured
// with a challenge solve.
// To utilise this solver, add the 'testing.cert-manager.io/fixed-ingress: "true"' label.
fixedIngressName := "testingress"
BeforeEach(func() {
acmeIssuer := util.NewCertManagerACMEIssuer(issuerName, f.Config.Addons.ACMEServer.URL, testingACMEEmail, testingACMEPrivateKey)
// Enable NotAfter feature
acmeIssuer.Spec.ACME.EnableNotAfterDate = true
acmeIssuer.Spec.ACME.Solvers = []cmacme.ACMEChallengeSolver{
{
HTTP01: &cmacme.ACMEChallengeSolverHTTP01{
Ingress: &cmacme.ACMEChallengeSolverHTTP01Ingress{
Class: &f.Config.Addons.IngressController.IngressClass,
},
},
},
{
Selector: &cmacme.CertificateDNSNameSelector{
MatchLabels: map[string]string{
"testing.cert-manager.io/fixed-ingress": "true",
},
},
HTTP01: &cmacme.ACMEChallengeSolverHTTP01{
Ingress: &cmacme.ACMEChallengeSolverHTTP01Ingress{
Name: fixedIngressName,
},
},
},
}
By("Creating an Issuer")
_, err := f.CertManagerClientSet.CertmanagerV1().Issuers(f.Namespace.Name).Create(context.TODO(), acmeIssuer, metav1.CreateOptions{})
Expect(err).NotTo(HaveOccurred())
By("Waiting for Issuer to become Ready")
err = util.WaitForIssuerCondition(f.CertManagerClientSet.CertmanagerV1().Issuers(f.Namespace.Name),
issuerName,
v1.IssuerCondition{
Type: v1.IssuerConditionReady,
Status: cmmeta.ConditionTrue,
})
Expect(err).NotTo(HaveOccurred())
By("Verifying the ACME account URI is set")
err = util.WaitForIssuerStatusFunc(f.CertManagerClientSet.CertmanagerV1().Issuers(f.Namespace.Name),
issuerName,
func(i *v1.Issuer) (bool, error) {
if i.GetStatus().ACMEStatus().URI == "" {
return false, nil
}
return true, nil
})
Expect(err).NotTo(HaveOccurred())
By("Verifying ACME account private key exists")
secret, err := f.KubeClientSet.CoreV1().Secrets(f.Namespace.Name).Get(context.TODO(), testingACMEPrivateKey, metav1.GetOptions{})
Expect(err).NotTo(HaveOccurred())
if len(secret.Data) != 1 {
Fail("Expected 1 key in ACME account private key secret, but there was %d", len(secret.Data))
}
})
JustBeforeEach(func() {
acmeIngressDomain = frameworkutil.RandomSubdomain(f.Config.Addons.IngressController.Domain)
})
AfterEach(func() {
By("Cleaning up")
f.CertManagerClientSet.CertmanagerV1().Issuers(f.Namespace.Name).Delete(context.TODO(), issuerName, metav1.DeleteOptions{})
f.KubeClientSet.CoreV1().Secrets(f.Namespace.Name).Delete(context.TODO(), testingACMEPrivateKey, metav1.DeleteOptions{})
})
It("should obtain a signed certificate with a single CN from the ACME server with 1 hour validity", func() {
certClient := f.CertManagerClientSet.CertmanagerV1().Certificates(f.Namespace.Name)
By("Creating a Certificate")
cert := gen.Certificate(certificateName,
gen.SetCertificateDuration(time.Hour),
gen.SetCertificateRenewBefore(45*time.Minute),
gen.SetCertificateSecretName(certificateSecretName),
gen.SetCertificateIssuer(cmmeta.ObjectReference{Name: issuerName}),
gen.SetCertificateDNSNames(acmeIngressDomain),
)
cert.Namespace = f.Namespace.Name
_, err := certClient.Create(context.TODO(), cert, metav1.CreateOptions{})
Expect(err).NotTo(HaveOccurred())
By("Waiting for the Certificate to be issued...")
err = f.Helper().WaitCertificateIssued(f.Namespace.Name, certificateName, time.Minute*5)
Expect(err).NotTo(HaveOccurred())
By("Validating the issued Certificate...")
err = f.Helper().ValidateCertificate(f.Namespace.Name, certificateName)
Expect(err).NotTo(HaveOccurred())
sec, err := f.Helper().WaitForSecretCertificateData(f.Namespace.Name, certificateSecretName, time.Minute*5)
Expect(err).NotTo(HaveOccurred(), "failed to wait for secret")
crtPEM := sec.Data[corev1.TLSCertKey]
crt, err := pki.DecodeX509CertificateBytes(crtPEM)
Expect(err).NotTo(HaveOccurred(), "failed to get decode signed certificate data")
// checking losely to tot hit too many timing issues as the date is defined in the controller
if crt.NotAfter.After(time.Now().Add(time.Hour)) {
Fail(fmt.Sprintf("Certificate has a NotAfter time after more than 1 hour (requested duration), got %s, current time %s", crt.NotAfter.String(), time.Now().String()))
}
})
})