func (spec *Spec) CertExpireTime() time.Time {
	return spec.expiry.Cert
}
CertExpireTime returns the time at which this spec's Certificate is no
longer valid.
package cert
import (
	"context"
	"crypto/ecdsa"
	"crypto/rsa"
	"crypto/tls"
	"crypto/x509"
	"fmt"
	"math/rand"
	"time"
	"github.com/pkg/errors"
	"github.com/cenkalti/backoff"
	"github.com/cloudflare/certmgr/cert/storage"
	"github.com/cloudflare/cfssl/csr"
	"github.com/cloudflare/cfssl/transport"
	log "github.com/sirupsen/logrus"
)
const backoffMaxDelay = time.Minute * 2
const DefaultInterval = time.Hour
const DefaultBefore = time.Hour * 72
type SpecOptions struct {
	Before time.Duration
	Interval time.Duration
	IntervalSplay time.Duration
	InitialSplay time.Duration
	KeyUsages []x509.ExtKeyUsage
}
func NewSpecOptions() *SpecOptions {
	return &SpecOptions{
		Before:   DefaultBefore,
		Interval: DefaultInterval,
	}
}
type Spec struct {
	SpecOptions
	Name string
	Authority *Authority
	Request *csr.CertificateRequest
	Storage storage.PKIStorage
	WakeCallbacks []func()
	tr *transport.Transport
	expiry struct {
		CA   time.Time
		Cert time.Time
	}
}
func NewSpec(name string, options *SpecOptions, authority *Authority, request *csr.CertificateRequest, storage storage.PKIStorage) (*Spec, error) {
	tr, err := authority.CreateTransport(options.Before, request)
	if err != nil {
		return nil, err
	}
	return &Spec{
		Name:        name,
		SpecOptions: *options,
		Authority:   authority,
		Request:     request,
		Storage:     storage,
		tr:          tr,
	}, nil
}
func (spec *Spec) String() string {
	return spec.Name
}
func (spec *Spec) Lifespan() time.Duration {
	t := spec.expiry.CA
	if t.After(spec.expiry.Cert) {
		t = spec.expiry.Cert
	}
	return time.Now().Sub(t)
}