Merge pull request #863 from micro/certmagice2e
E2E tests for certmagic ACME provider
This commit is contained in:
commit
0da9dff077
@ -3,7 +3,9 @@ package certmagic
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/mholt/certmagic"
|
"github.com/mholt/certmagic"
|
||||||
|
|
||||||
@ -15,6 +17,7 @@ type certmagicProvider struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *certmagicProvider) NewListener(ACMEHosts ...string) (net.Listener, error) {
|
func (c *certmagicProvider) NewListener(ACMEHosts ...string) (net.Listener, error) {
|
||||||
|
certmagic.Default.CA = c.opts.CA
|
||||||
if c.opts.ChallengeProvider != nil {
|
if c.opts.ChallengeProvider != nil {
|
||||||
// Enabling DNS Challenge disables the other challenges
|
// Enabling DNS Challenge disables the other challenges
|
||||||
certmagic.Default.DNSProvider = c.opts.ChallengeProvider
|
certmagic.Default.DNSProvider = c.opts.ChallengeProvider
|
||||||
@ -22,6 +25,16 @@ func (c *certmagicProvider) NewListener(ACMEHosts ...string) (net.Listener, erro
|
|||||||
if c.opts.OnDemand {
|
if c.opts.OnDemand {
|
||||||
certmagic.Default.OnDemand = new(certmagic.OnDemandConfig)
|
certmagic.Default.OnDemand = new(certmagic.OnDemandConfig)
|
||||||
}
|
}
|
||||||
|
if c.opts.Cache != nil {
|
||||||
|
// already validated by new()
|
||||||
|
certmagic.Default.Storage = c.opts.Cache.(certmagic.Storage)
|
||||||
|
}
|
||||||
|
// If multiple instances of the provider are running, inject some
|
||||||
|
// randomness so they don't collide
|
||||||
|
rand.Seed(time.Now().UnixNano())
|
||||||
|
randomDuration := (7 * 24 * time.Hour) + (time.Duration(rand.Intn(504)) * time.Hour)
|
||||||
|
certmagic.Default.RenewDurationBefore = randomDuration
|
||||||
|
|
||||||
return certmagic.Listen(ACMEHosts)
|
return certmagic.Listen(ACMEHosts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package certmagic
|
package certmagic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
"sort"
|
"sort"
|
||||||
@ -185,3 +186,46 @@ func TestStorageImplementation(t *testing.T) {
|
|||||||
// happens
|
// happens
|
||||||
New(acme.Cache(s))
|
New(acme.Cache(s))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Full test with a real zone, with against LE staging
|
||||||
|
func TestE2e(t *testing.T) {
|
||||||
|
apiToken, accountID := os.Getenv("CF_API_TOKEN"), os.Getenv("CF_ACCOUNT_ID")
|
||||||
|
kvID := os.Getenv("KV_NAMESPACE_ID")
|
||||||
|
if len(apiToken) == 0 || len(accountID) == 0 || len(kvID) == 0 {
|
||||||
|
t.Skip("No Cloudflare API keys available, skipping test")
|
||||||
|
}
|
||||||
|
|
||||||
|
testLock := memory.NewLock()
|
||||||
|
testStore, err := cloudflarestorage.New(
|
||||||
|
options.WithValue("CF_API_TOKEN", apiToken),
|
||||||
|
options.WithValue("CF_ACCOUNT_ID", accountID),
|
||||||
|
options.WithValue("KV_NAMESPACE_ID", kvID),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err.Error())
|
||||||
|
}
|
||||||
|
testStorage := NewStorage(testLock, testStore)
|
||||||
|
|
||||||
|
conf := cloudflare.NewDefaultConfig()
|
||||||
|
conf.AuthToken = apiToken
|
||||||
|
conf.ZoneToken = apiToken
|
||||||
|
testChallengeProvider, err := cloudflare.NewDNSProviderConfig(conf)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
testProvider := New(
|
||||||
|
acme.AcceptToS(true),
|
||||||
|
acme.Cache(testStorage),
|
||||||
|
acme.CA(acme.LetsEncryptStagingCA),
|
||||||
|
acme.ChallengeProvider(testChallengeProvider),
|
||||||
|
acme.OnDemand(false),
|
||||||
|
)
|
||||||
|
|
||||||
|
listener, err := testProvider.NewListener("*.micro.mu", "micro.mu")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err.Error())
|
||||||
|
}
|
||||||
|
go http.Serve(listener, http.NotFoundHandler())
|
||||||
|
time.Sleep(10 * time.Minute)
|
||||||
|
}
|
||||||
|
@ -3,6 +3,7 @@ package certmagic
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/gob"
|
"encoding/gob"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"path"
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
@ -55,6 +56,9 @@ func (s *storage) Store(key string, value []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *storage) Load(key string) ([]byte, error) {
|
func (s *storage) Load(key string) ([]byte, error) {
|
||||||
|
if !s.Exists(key) {
|
||||||
|
return nil, certmagic.ErrNotExist(errors.New(key + " doesn't exist"))
|
||||||
|
}
|
||||||
records, err := s.store.Read(key)
|
records, err := s.store.Read(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -77,7 +81,7 @@ func (s *storage) Delete(key string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *storage) Exists(key string) bool {
|
func (s *storage) Exists(key string) bool {
|
||||||
_, err := s.store.Read()
|
_, err := s.store.Read(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -132,3 +136,11 @@ func (s *storage) Stat(key string) (certmagic.KeyInfo, error) {
|
|||||||
IsTerminal: false,
|
IsTerminal: false,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewStorage returns a certmagic.Storage backed by a go-micro/lock and go-micro/store
|
||||||
|
func NewStorage(lock lock.Lock, store store.Store) certmagic.Storage {
|
||||||
|
return &storage{
|
||||||
|
lock: lock,
|
||||||
|
store: store,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user