Merge pull request #863 from micro/certmagice2e
E2E tests for certmagic ACME provider
This commit is contained in:
		| @@ -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, | ||||||
|  | 	} | ||||||
|  | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user