Add a mutex on local store for HTTPChallenges
This commit is contained in:
parent
bacd58ed7b
commit
f173ff02e3
4 changed files with 66 additions and 53 deletions
|
@ -175,7 +175,7 @@ func runCmd(globalConfiguration *configuration.GlobalConfiguration, configFile s
|
|||
log.Debugf("Global configuration loaded %s", string(jsonConf))
|
||||
if acme.IsEnabled() {
|
||||
store := acme.NewLocalStore(acme.Get().Storage)
|
||||
acme.Get().Store = &store
|
||||
acme.Get().Store = store
|
||||
}
|
||||
svr := server.NewServer(*globalConfiguration, configuration.NewProviderAggregator(globalConfiguration))
|
||||
if acme.IsEnabled() && acme.Get().OnHostRule {
|
||||
|
|
|
@ -34,15 +34,9 @@ func getTokenValue(token, domain string, store Store) []byte {
|
|||
var result []byte
|
||||
|
||||
operation := func() error {
|
||||
var ok bool
|
||||
httpChallenges, err := store.GetHTTPChallenges()
|
||||
if err != nil {
|
||||
return fmt.Errorf("HTTPChallenges not available : %s", err)
|
||||
}
|
||||
if result, ok = httpChallenges[token][domain]; !ok {
|
||||
return fmt.Errorf("cannot find challenge for token %v", token)
|
||||
}
|
||||
return nil
|
||||
var err error
|
||||
result, err = store.GetHTTPChallengeToken(token, domain)
|
||||
return err
|
||||
}
|
||||
|
||||
notify := func(err error, time time.Duration) {
|
||||
|
@ -60,40 +54,9 @@ func getTokenValue(token, domain string, store Store) []byte {
|
|||
}
|
||||
|
||||
func presentHTTPChallenge(domain, token, keyAuth string, store Store) error {
|
||||
httpChallenges, err := store.GetHTTPChallenges()
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to get HTTPChallenges : %s", err)
|
||||
}
|
||||
|
||||
if httpChallenges == nil {
|
||||
httpChallenges = map[string]map[string][]byte{}
|
||||
}
|
||||
|
||||
if _, ok := httpChallenges[token]; !ok {
|
||||
httpChallenges[token] = map[string][]byte{}
|
||||
}
|
||||
|
||||
httpChallenges[token][domain] = []byte(keyAuth)
|
||||
|
||||
return store.SaveHTTPChallenges(httpChallenges)
|
||||
return store.SetHTTPChallengeToken(token, domain, []byte(keyAuth))
|
||||
}
|
||||
|
||||
func cleanUpHTTPChallenge(domain, token string, store Store) error {
|
||||
httpChallenges, err := store.GetHTTPChallenges()
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to get HTTPChallenges : %s", err)
|
||||
}
|
||||
|
||||
log.Debugf("Challenge CleanUp for domain %s", domain)
|
||||
|
||||
if _, ok := httpChallenges[token]; ok {
|
||||
if _, domainOk := httpChallenges[token][domain]; domainOk {
|
||||
delete(httpChallenges[token], domain)
|
||||
}
|
||||
if len(httpChallenges[token]) == 0 {
|
||||
delete(httpChallenges, token)
|
||||
}
|
||||
return store.SaveHTTPChallenges(httpChallenges)
|
||||
}
|
||||
return nil
|
||||
return store.RemoveHTTPChallengeToken(token, domain)
|
||||
}
|
||||
|
|
|
@ -2,9 +2,11 @@ package acme
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"regexp"
|
||||
"sync"
|
||||
|
||||
"github.com/containous/traefik/log"
|
||||
"github.com/containous/traefik/safe"
|
||||
|
@ -17,11 +19,12 @@ type LocalStore struct {
|
|||
filename string
|
||||
storedData *StoredData
|
||||
SaveDataChan chan *StoredData `json:"-"`
|
||||
lock sync.RWMutex
|
||||
}
|
||||
|
||||
// NewLocalStore initializes a new LocalStore with a file name
|
||||
func NewLocalStore(filename string) LocalStore {
|
||||
store := LocalStore{filename: filename, SaveDataChan: make(chan *StoredData)}
|
||||
func NewLocalStore(filename string) *LocalStore {
|
||||
store := &LocalStore{filename: filename, SaveDataChan: make(chan *StoredData)}
|
||||
store.listenSaveAction()
|
||||
return store
|
||||
}
|
||||
|
@ -149,13 +152,59 @@ func (s *LocalStore) SaveCertificates(certificates []*Certificate) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// GetHTTPChallenges returns ACME HTTP Challenges list
|
||||
func (s *LocalStore) GetHTTPChallenges() (map[string]map[string][]byte, error) {
|
||||
return s.storedData.HTTPChallenges, nil
|
||||
// GetHTTPChallengeToken Get the http challenge token from the store
|
||||
func (s *LocalStore) GetHTTPChallengeToken(token, domain string) ([]byte, error) {
|
||||
s.lock.RLock()
|
||||
defer s.lock.RUnlock()
|
||||
|
||||
if s.storedData.HTTPChallenges == nil {
|
||||
s.storedData.HTTPChallenges = map[string]map[string][]byte{}
|
||||
}
|
||||
|
||||
if _, ok := s.storedData.HTTPChallenges[token]; !ok {
|
||||
return nil, fmt.Errorf("cannot find challenge for token %v", token)
|
||||
}
|
||||
|
||||
result, ok := s.storedData.HTTPChallenges[token][domain]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("cannot find challenge for token %v", token)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// SaveHTTPChallenges stores ACME HTTP Challenges list
|
||||
func (s *LocalStore) SaveHTTPChallenges(httpChallenges map[string]map[string][]byte) error {
|
||||
s.storedData.HTTPChallenges = httpChallenges
|
||||
// SetHTTPChallengeToken Set the http challenge token in the store
|
||||
func (s *LocalStore) SetHTTPChallengeToken(token, domain string, keyAuth []byte) error {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
|
||||
if s.storedData.HTTPChallenges == nil {
|
||||
s.storedData.HTTPChallenges = map[string]map[string][]byte{}
|
||||
}
|
||||
|
||||
if _, ok := s.storedData.HTTPChallenges[token]; !ok {
|
||||
s.storedData.HTTPChallenges[token] = map[string][]byte{}
|
||||
}
|
||||
|
||||
s.storedData.HTTPChallenges[token][domain] = []byte(keyAuth)
|
||||
return nil
|
||||
}
|
||||
|
||||
// RemoveHTTPChallengeToken Remove the http challenge token in the store
|
||||
func (s *LocalStore) RemoveHTTPChallengeToken(token, domain string) error {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
|
||||
if s.storedData.HTTPChallenges == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if _, ok := s.storedData.HTTPChallenges[token]; ok {
|
||||
if _, domainOk := s.storedData.HTTPChallenges[token][domain]; domainOk {
|
||||
delete(s.storedData.HTTPChallenges[token], domain)
|
||||
}
|
||||
if len(s.storedData.HTTPChallenges[token]) == 0 {
|
||||
delete(s.storedData.HTTPChallenges, token)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ type Store interface {
|
|||
SaveAccount(*Account) error
|
||||
GetCertificates() ([]*Certificate, error)
|
||||
SaveCertificates([]*Certificate) error
|
||||
GetHTTPChallenges() (map[string]map[string][]byte, error)
|
||||
SaveHTTPChallenges(map[string]map[string][]byte) error
|
||||
GetHTTPChallengeToken(token, domain string) ([]byte, error)
|
||||
SetHTTPChallengeToken(token, domain string, keyAuth []byte) error
|
||||
RemoveHTTPChallengeToken(token, domain string) error
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue