func NewClient(kubeClient client.Client) (*ACMEClient, error) {
	accountURL, err := getLetsEncryptAccountURL(kubeClient)
	if err != nil {
		return nil, err
	}
	u, err := url.Parse(accountURL)
	if err != nil {
		return nil, err
	}
	acmeClient := &ACMEClient{}
	directoryURL := ""
	if strings.Contains(acme.LetsEncryptStaging, u.Host) {
		directoryURL = acme.LetsEncryptStaging
	} else if strings.Contains(acme.LetsEncryptProduction, u.Host) {
		directoryURL = acme.LetsEncryptProduction
	} else {
		return nil, errors.New("cannot found let's encrypt directory url")
	}
	acmeClient.Client, err = acme.NewClient(directoryURL)
	if err != nil {
		return nil, err
	}
	privateKey, err := getLetsEncryptAccountPrivateKey(kubeClient)
	if err != nil {
		return nil, err
	}
	if privateKey == nil {
		return nil, errors.New("private key cannot be empty")
	}
	acmeClient.Account = acme.Account{PrivateKey: privateKey, URL: accountURL}
	return acmeClient, nil
}
NewClient accepts a client.Client as kubeClient and calls the acme NewClient func.
An ACMEClient is returned, along with any error that occurs.
package leclient
import (
	"crypto"
	"crypto/x509"
	"encoding/pem"
	"errors"
	"fmt"
	"net/url"
	"strings"
	"github.com/eggsampler/acme"
	v1 "k8s.io/api/core/v1"
	kerr "k8s.io/apimachinery/pkg/api/errors"
	"sigs.k8s.io/controller-runtime/pkg/client"
	"github.com/openshift/certman-operator/config"
)
type Client interface {
	UpdateAccount([]string)
	CreateOrder([]string)
	GetOrderURL()
	OrderAuthorization()
	FetchAuthorization(string)
	GetAuthorizationURL()
	GetAuthorizationIndentifier()
	SetChallengeType()
	GetChallengeURL()
	GetDNS01KeyAuthorization()
	UpdateChallenge()
	FinalizeOrder()
	GetOrderEndpoint()
	FetchCertificates()
	RevokeCertificate()
}
type ACMEClient struct {
	Client        acme.Client
	Account       acme.Account
	Order         acme.Order
	Authorization acme.Authorization
	Challenge     acme.Challenge
}
func (c *ACMEClient) UpdateAccount(email string) (err error) {
	var contacts []string
	if email != "" {
		contacts = []string{fmt.Sprintf("mailto:%s", email)}
	}
	account, err := c.Client.UpdateAccount(c.Account, true, contacts...)
	if err != nil {
		return err
	}
	c.Account = account
	return err
}
func (c *ACMEClient) CreateOrder(domains []string) (err error) {
	var ids []acme.Identifier
	for _, domain := range domains {
		ids = append(ids, acme.Identifier{Type: "dns", Value: domain})
	}
	c.Order, err = c.Client.NewOrder(c.Account, ids)
	if err != nil {
		return err
	}
	return nil
}
func (c *ACMEClient) GetOrderURL() (URL string, err error) {
	URL = c.Order.URL
	return URL, err
}
func (c *ACMEClient) OrderAuthorization() []string {
	return c.Order.Authorizations
}
func (c *ACMEClient) FetchAuthorization(authURL string) (err error) {
	c.Authorization, err = c.Client.FetchAuthorization(c.Account, authURL)
	return err
}
func (c *ACMEClient) GetAuthorizationURL() string {
	return c.Authorization.URL
}
func (c *ACMEClient) GetAuthorizationIndentifier() (AuthID string, err error) {
	AuthID = c.Authorization.Identifier.Value
	if AuthID == "" {
		err = errors.New("Authorization indentifier not currently set")
	}
	return AuthID, err
}
func (c *ACMEClient) SetChallengeType() (err error) {
	c.Challenge = c.Authorization.ChallengeMap["dns-01"]
	return err
}
func (c *ACMEClient) GetDNS01KeyAuthorization() (keyAuth string, err error) {
	keyAuth = acme.EncodeDNS01KeyAuthorization(c.Challenge.KeyAuthorization)
	if keyAuth == "" {
		err = errors.New("Authorization key not currently set")
	}
	return keyAuth, err
}
func (c *ACMEClient) GetChallengeURL() string {
	return c.Challenge.URL
}
func (c *ACMEClient) UpdateChallenge() (err error) {
	c.Challenge, err = c.Client.UpdateChallenge(c.Account, c.Challenge)
	return err
}
func (c *ACMEClient) FinalizeOrder(csr *x509.CertificateRequest) (err error) {
	c.Order, err = c.Client.FinalizeOrder(c.Account, c.Order, csr)
	return err
}
func (c *ACMEClient) GetOrderEndpoint() string {
	return c.Order.Certificate
}
func (c *ACMEClient) FetchCertificates() (certbundle []*x509.Certificate, err error) {
	certbundle, err = c.Client.FetchCertificates(c.Account, c.Order.Certificate)
	return certbundle, err
}
func (c *ACMEClient) RevokeCertificate(certificate *x509.Certificate) (err error) {
	err = c.Client.RevokeCertificate(c.Account, certificate, c.Account.PrivateKey, 0)
	return err
}
func getLetsEncryptAccountPrivateKey(kubeClient client.Client) (privateKey crypto.Signer, err error) {
	secret, err := getLetsEncryptAccountSecret(kubeClient)
	if err != nil {
		return privateKey, err
	}
	if secret.Data[letsEncryptAccountPrivateKey] == nil {
		return nil, fmt.Errorf("lets encrypt private key not found")
	}
	keyBytes := secret.Data[letsEncryptAccountPrivateKey]
	keyBlock, _ := pem.Decode(keyBytes)
	switch keyBlock.Type {
	case "RSA PRIVATE KEY":
		privateKey, err = x509.ParsePKCS1PrivateKey(keyBlock.Bytes)
		return privateKey, err
	case "EC PRIVATE KEY":
		privateKey, err = x509.ParseECPrivateKey(keyBlock.Bytes)
		return privateKey, err
	}
	return privateKey, nil
}
func getLetsEncryptAccountURL(kubeClient client.Client) (url string, err error) {
	secret, err := getLetsEncryptAccountSecret(kubeClient)
	if err != nil {
		return url, err
	}
	urlBytes := secret.Data[letsEncryptAccountUrl]
	url = string(urlBytes)
	url = strings.TrimRight(url, "\n")
	return url, nil
}
func getLetsEncryptAccountSecret(kubeClient client.Client) (secret *v1.Secret, err error) {
	secretName := letsEncryptAccountSecretName
	secret, err = GetSecret(kubeClient, secretName, config.OperatorNamespace)
	if err != nil {
		if kerr.IsNotFound(err) {
			secretName = letsEncryptProductionAccountSecretName
			secret, err = GetSecret(kubeClient, secretName, config.OperatorNamespace)
			if kerr.IsNotFound(err) {
				secretName = letsEncryptStagingAccountSecretName
				secret, err = GetSecret(kubeClient, secretName, config.OperatorNamespace)
			}
		}
	}
	return
}