Remove acme provider dependency in server
This commit is contained in:
parent
9daae9c705
commit
b4e3bca6fa
7 changed files with 124 additions and 101 deletions
|
@ -24,7 +24,6 @@ import (
|
||||||
"github.com/containous/traefik/configuration/router"
|
"github.com/containous/traefik/configuration/router"
|
||||||
"github.com/containous/traefik/job"
|
"github.com/containous/traefik/job"
|
||||||
"github.com/containous/traefik/log"
|
"github.com/containous/traefik/log"
|
||||||
"github.com/containous/traefik/provider/acme"
|
|
||||||
"github.com/containous/traefik/provider/ecs"
|
"github.com/containous/traefik/provider/ecs"
|
||||||
"github.com/containous/traefik/provider/kubernetes"
|
"github.com/containous/traefik/provider/kubernetes"
|
||||||
"github.com/containous/traefik/safe"
|
"github.com/containous/traefik/safe"
|
||||||
|
@ -174,28 +173,47 @@ func runCmd(globalConfiguration *configuration.GlobalConfiguration, configFile s
|
||||||
stats(globalConfiguration)
|
stats(globalConfiguration)
|
||||||
|
|
||||||
log.Debugf("Global configuration loaded %s", string(jsonConf))
|
log.Debugf("Global configuration loaded %s", string(jsonConf))
|
||||||
if acme.IsEnabled() {
|
|
||||||
store := acme.NewLocalStore(acme.Get().Storage)
|
providerAggregator := configuration.NewProviderAggregator(globalConfiguration)
|
||||||
acme.Get().Store = &store
|
|
||||||
|
acmeprovider := globalConfiguration.InitACMEProvider()
|
||||||
|
if acmeprovider != nil {
|
||||||
|
providerAggregator.AddProvider(acmeprovider)
|
||||||
}
|
}
|
||||||
|
|
||||||
entryPoints := map[string]server.EntryPoint{}
|
entryPoints := map[string]server.EntryPoint{}
|
||||||
for entryPointName, config := range globalConfiguration.EntryPoints {
|
for entryPointName, config := range globalConfiguration.EntryPoints {
|
||||||
internalRouter := router.NewInternalRouterAggregator(*globalConfiguration, entryPointName)
|
|
||||||
if acme.IsEnabled() && acme.Get().HTTPChallenge != nil && acme.Get().HTTPChallenge.EntryPoint == entryPointName {
|
entryPoint := server.EntryPoint{
|
||||||
internalRouter.AddRouter(acme.Get())
|
Configuration: config,
|
||||||
}
|
}
|
||||||
|
|
||||||
entryPoints[entryPointName] = server.EntryPoint{
|
internalRouter := router.NewInternalRouterAggregator(*globalConfiguration, entryPointName)
|
||||||
InternalRouter: internalRouter,
|
if acmeprovider != nil {
|
||||||
Configuration: config,
|
if acmeprovider.HTTPChallenge != nil && acmeprovider.HTTPChallenge.EntryPoint == entryPointName {
|
||||||
|
internalRouter.AddRouter(acmeprovider)
|
||||||
|
}
|
||||||
|
|
||||||
|
if acmeprovider.EntryPoint == entryPointName && acmeprovider.OnDemand {
|
||||||
|
entryPoint.OnDemandListener = acmeprovider.ListenRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
entryPoint.CertificateStore = &traefiktls.CertificateStore{
|
||||||
|
DynamicCerts: &safe.Safe{},
|
||||||
|
StaticCerts: &safe.Safe{},
|
||||||
|
}
|
||||||
|
acmeprovider.SetCertificateStore(*entryPoint.CertificateStore)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
entryPoint.InternalRouter = internalRouter
|
||||||
|
entryPoints[entryPointName] = entryPoint
|
||||||
}
|
}
|
||||||
|
|
||||||
svr := server.NewServer(*globalConfiguration, configuration.NewProviderAggregator(globalConfiguration), entryPoints)
|
svr := server.NewServer(*globalConfiguration, providerAggregator, entryPoints)
|
||||||
if acme.IsEnabled() && acme.Get().OnHostRule {
|
if acmeprovider != nil && acmeprovider.OnHostRule {
|
||||||
acme.Get().SetConfigListenerChan(make(chan types.Configuration))
|
acmeprovider.SetConfigListenerChan(make(chan types.Configuration))
|
||||||
svr.AddListener(acme.Get().ListenConfiguration)
|
svr.AddListener(acmeprovider.ListenConfiguration)
|
||||||
}
|
}
|
||||||
ctx := cmd.ContextWithSignal(context.Background())
|
ctx := cmd.ContextWithSignal(context.Background())
|
||||||
|
|
||||||
|
|
|
@ -370,11 +370,17 @@ func (gc *GlobalConfiguration) initACMEProvider() {
|
||||||
if gc.ACME.OnDemand {
|
if gc.ACME.OnDemand {
|
||||||
log.Warn("ACME.OnDemand is deprecated")
|
log.Warn("ACME.OnDemand is deprecated")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// InitACMEProvider create an acme provider from the ACME part of globalConfiguration
|
||||||
|
func (gc *GlobalConfiguration) InitACMEProvider() *acmeprovider.Provider {
|
||||||
|
if gc.ACME != nil {
|
||||||
// TODO: Remove when Provider ACME will replace totally ACME
|
// TODO: Remove when Provider ACME will replace totally ACME
|
||||||
// If provider file, use Provider ACME instead of ACME
|
// If provider file, use Provider ACME instead of ACME
|
||||||
if gc.Cluster == nil {
|
if gc.Cluster == nil {
|
||||||
acmeprovider.Get().Configuration = &acmeprovider.Configuration{
|
provider := &acmeprovider.Provider{}
|
||||||
|
provider.Configuration = &acmeprovider.Configuration{
|
||||||
OnHostRule: gc.ACME.OnHostRule,
|
OnHostRule: gc.ACME.OnHostRule,
|
||||||
OnDemand: gc.ACME.OnDemand,
|
OnDemand: gc.ACME.OnDemand,
|
||||||
Email: gc.ACME.Email,
|
Email: gc.ACME.Email,
|
||||||
|
@ -386,9 +392,15 @@ func (gc *GlobalConfiguration) initACMEProvider() {
|
||||||
CAServer: gc.ACME.CAServer,
|
CAServer: gc.ACME.CAServer,
|
||||||
EntryPoint: gc.ACME.EntryPoint,
|
EntryPoint: gc.ACME.EntryPoint,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
store := acmeprovider.NewLocalStore(provider.Storage)
|
||||||
|
provider.Store = &store
|
||||||
|
acme.ConvertToNewFormat(provider.Storage)
|
||||||
gc.ACME = nil
|
gc.ACME = nil
|
||||||
|
return provider
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidateConfiguration validate that configuration is coherent
|
// ValidateConfiguration validate that configuration is coherent
|
||||||
|
@ -401,14 +413,6 @@ func (gc *GlobalConfiguration) ValidateConfiguration() {
|
||||||
log.Fatalf("Entrypoint %q has no TLS configuration for ACME configuration", gc.ACME.EntryPoint)
|
log.Fatalf("Entrypoint %q has no TLS configuration for ACME configuration", gc.ACME.EntryPoint)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if acmeprovider.IsEnabled() {
|
|
||||||
if _, ok := gc.EntryPoints[acmeprovider.Get().EntryPoint]; !ok {
|
|
||||||
log.Fatalf("Unknown entrypoint %q for provider ACME configuration", acmeprovider.Get().EntryPoint)
|
|
||||||
} else {
|
|
||||||
if gc.EntryPoints[acmeprovider.Get().EntryPoint].TLS == nil {
|
|
||||||
log.Fatalf("Entrypoint %q has no TLS configuration for provider ACME configuration", acmeprovider.Get().EntryPoint)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,21 +4,20 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
"github.com/containous/traefik/acme"
|
|
||||||
"github.com/containous/traefik/log"
|
"github.com/containous/traefik/log"
|
||||||
"github.com/containous/traefik/provider"
|
"github.com/containous/traefik/provider"
|
||||||
acmeprovider "github.com/containous/traefik/provider/acme"
|
|
||||||
"github.com/containous/traefik/safe"
|
"github.com/containous/traefik/safe"
|
||||||
"github.com/containous/traefik/types"
|
"github.com/containous/traefik/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
type providerAggregator struct {
|
// ProviderAggregator aggregate providers
|
||||||
|
type ProviderAggregator struct {
|
||||||
providers []provider.Provider
|
providers []provider.Provider
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewProviderAggregator return an aggregate of all the providers configured in GlobalConfiguration
|
// NewProviderAggregator return an aggregate of all the providers configured in GlobalConfiguration
|
||||||
func NewProviderAggregator(gc *GlobalConfiguration) provider.Provider {
|
func NewProviderAggregator(gc *GlobalConfiguration) ProviderAggregator {
|
||||||
provider := providerAggregator{}
|
provider := ProviderAggregator{}
|
||||||
if gc.Docker != nil {
|
if gc.Docker != nil {
|
||||||
provider.providers = append(provider.providers, gc.Docker)
|
provider.providers = append(provider.providers, gc.Docker)
|
||||||
}
|
}
|
||||||
|
@ -67,17 +66,16 @@ func NewProviderAggregator(gc *GlobalConfiguration) provider.Provider {
|
||||||
if gc.ServiceFabric != nil {
|
if gc.ServiceFabric != nil {
|
||||||
provider.providers = append(provider.providers, gc.ServiceFabric)
|
provider.providers = append(provider.providers, gc.ServiceFabric)
|
||||||
}
|
}
|
||||||
if acmeprovider.IsEnabled() {
|
|
||||||
provider.providers = append(provider.providers, acmeprovider.Get())
|
|
||||||
acme.ConvertToNewFormat(acmeprovider.Get().Storage)
|
|
||||||
}
|
|
||||||
if len(provider.providers) == 1 {
|
|
||||||
return provider.providers[0]
|
|
||||||
}
|
|
||||||
return provider
|
return provider
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p providerAggregator) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints types.Constraints) error {
|
// AddProvider add a provider in the providers map
|
||||||
|
func (p *ProviderAggregator) AddProvider(provider provider.Provider) {
|
||||||
|
p.providers = append(p.providers, provider)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Provide call the provide method of every providers
|
||||||
|
func (p ProviderAggregator) Provide(configurationChan chan<- types.ConfigMessage, pool *safe.Pool, constraints types.Constraints) error {
|
||||||
for _, p := range p.providers {
|
for _, p := range p.providers {
|
||||||
providerType := reflect.TypeOf(p)
|
providerType := reflect.TypeOf(p)
|
||||||
jsonConf, err := json.Marshal(p)
|
jsonConf, err := json.Marshal(p)
|
||||||
|
|
|
@ -20,7 +20,7 @@ import (
|
||||||
"github.com/containous/traefik/log"
|
"github.com/containous/traefik/log"
|
||||||
"github.com/containous/traefik/rules"
|
"github.com/containous/traefik/rules"
|
||||||
"github.com/containous/traefik/safe"
|
"github.com/containous/traefik/safe"
|
||||||
traefikTLS "github.com/containous/traefik/tls"
|
traefiktls "github.com/containous/traefik/tls"
|
||||||
"github.com/containous/traefik/types"
|
"github.com/containous/traefik/types"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
acme "github.com/xenolf/lego/acmev2"
|
acme "github.com/xenolf/lego/acmev2"
|
||||||
|
@ -30,7 +30,6 @@ import (
|
||||||
var (
|
var (
|
||||||
// OSCPMustStaple enables OSCP stapling as from https://github.com/xenolf/lego/issues/270
|
// OSCPMustStaple enables OSCP stapling as from https://github.com/xenolf/lego/issues/270
|
||||||
OSCPMustStaple = false
|
OSCPMustStaple = false
|
||||||
provider = &Provider{}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Configuration holds ACME configuration provided by users
|
// Configuration holds ACME configuration provided by users
|
||||||
|
@ -56,8 +55,7 @@ type Provider struct {
|
||||||
client *acme.Client
|
client *acme.Client
|
||||||
certsChan chan *Certificate
|
certsChan chan *Certificate
|
||||||
configurationChan chan<- types.ConfigMessage
|
configurationChan chan<- types.ConfigMessage
|
||||||
dynamicCerts *safe.Safe
|
certificateStore traefiktls.CertificateStore
|
||||||
staticCerts map[string]*tls.Certificate
|
|
||||||
clientMutex sync.Mutex
|
clientMutex sync.Mutex
|
||||||
configFromListenerChan chan types.Configuration
|
configFromListenerChan chan types.Configuration
|
||||||
pool *safe.Pool
|
pool *safe.Pool
|
||||||
|
@ -81,16 +79,6 @@ type HTTPChallenge struct {
|
||||||
EntryPoint string `description:"HTTP challenge EntryPoint"`
|
EntryPoint string `description:"HTTP challenge EntryPoint"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get returns the provider instance
|
|
||||||
func Get() *Provider {
|
|
||||||
return provider
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsEnabled returns true if the provider instance and its configuration are not nil, otherwise false
|
|
||||||
func IsEnabled() bool {
|
|
||||||
return provider != nil && provider.Configuration != nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetConfigListenerChan initializes the configFromListenerChan
|
// SetConfigListenerChan initializes the configFromListenerChan
|
||||||
func (p *Provider) SetConfigListenerChan(configFromListenerChan chan types.Configuration) {
|
func (p *Provider) SetConfigListenerChan(configFromListenerChan chan types.Configuration) {
|
||||||
p.configFromListenerChan = configFromListenerChan
|
p.configFromListenerChan = configFromListenerChan
|
||||||
|
@ -196,14 +184,9 @@ func (p *Provider) watchNewDomains() {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetDynamicCertificates allow to initialize dynamicCerts map
|
// SetCertificateStore allow to initialize certificate store
|
||||||
func (p *Provider) SetDynamicCertificates(safe *safe.Safe) {
|
func (p *Provider) SetCertificateStore(certificateStore traefiktls.CertificateStore) {
|
||||||
p.dynamicCerts = safe
|
p.certificateStore = certificateStore
|
||||||
}
|
|
||||||
|
|
||||||
// SetStaticCertificates allow to initialize staticCerts map
|
|
||||||
func (p *Provider) SetStaticCertificates(staticCerts map[string]*tls.Certificate) {
|
|
||||||
p.staticCerts = staticCerts
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Provider) resolveCertificate(domain types.Domain, domainFromConfigurationFile bool) (*acme.CertificateResource, error) {
|
func (p *Provider) resolveCertificate(domain types.Domain, domainFromConfigurationFile bool) (*acme.CertificateResource, error) {
|
||||||
|
@ -424,13 +407,13 @@ func (p *Provider) refreshCertificates() {
|
||||||
Configuration: &types.Configuration{
|
Configuration: &types.Configuration{
|
||||||
Backends: map[string]*types.Backend{},
|
Backends: map[string]*types.Backend{},
|
||||||
Frontends: map[string]*types.Frontend{},
|
Frontends: map[string]*types.Frontend{},
|
||||||
TLS: []*traefikTLS.Configuration{},
|
TLS: []*traefiktls.Configuration{},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, cert := range p.certificates {
|
for _, cert := range p.certificates {
|
||||||
certificate := &traefikTLS.Certificate{CertFile: traefikTLS.FileOrContent(cert.Certificate), KeyFile: traefikTLS.FileOrContent(cert.Key)}
|
certificate := &traefiktls.Certificate{CertFile: traefiktls.FileOrContent(cert.Certificate), KeyFile: traefiktls.FileOrContent(cert.Key)}
|
||||||
config.Configuration.TLS = append(config.Configuration.TLS, &traefikTLS.Configuration{Certificate: certificate, EntryPoints: []string{p.EntryPoint}})
|
config.Configuration.TLS = append(config.Configuration.TLS, &traefiktls.Configuration{Certificate: certificate, EntryPoints: []string{p.EntryPoint}})
|
||||||
}
|
}
|
||||||
p.configurationChan <- config
|
p.configurationChan <- config
|
||||||
}
|
}
|
||||||
|
@ -507,33 +490,23 @@ func (p *Provider) AddRoutes(router *mux.Router) {
|
||||||
// from static and dynamic provided certificates
|
// from static and dynamic provided certificates
|
||||||
func (p *Provider) getUncheckedDomains(domainsToCheck []string, checkConfigurationDomains bool) []string {
|
func (p *Provider) getUncheckedDomains(domainsToCheck []string, checkConfigurationDomains bool) []string {
|
||||||
log.Debugf("Looking for provided certificate(s) to validate %q...", domainsToCheck)
|
log.Debugf("Looking for provided certificate(s) to validate %q...", domainsToCheck)
|
||||||
var allCerts []string
|
var allDomains []string
|
||||||
|
|
||||||
// Get static certificates
|
allDomains = p.certificateStore.GetAllDomains()
|
||||||
for domains := range p.staticCerts {
|
|
||||||
allCerts = append(allCerts, domains)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get dynamic certificates
|
|
||||||
if p.dynamicCerts != nil && p.dynamicCerts.Get() != nil {
|
|
||||||
for domains := range p.dynamicCerts.Get().(map[string]*tls.Certificate) {
|
|
||||||
allCerts = append(allCerts, domains)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get ACME certificates
|
// Get ACME certificates
|
||||||
for _, certificate := range p.certificates {
|
for _, certificate := range p.certificates {
|
||||||
allCerts = append(allCerts, strings.Join(certificate.Domain.ToStrArray(), ","))
|
allDomains = append(allDomains, strings.Join(certificate.Domain.ToStrArray(), ","))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get Configuration Domains
|
// Get Configuration Domains
|
||||||
if checkConfigurationDomains {
|
if checkConfigurationDomains {
|
||||||
for i := 0; i < len(p.Domains); i++ {
|
for i := 0; i < len(p.Domains); i++ {
|
||||||
allCerts = append(allCerts, strings.Join(p.Domains[i].ToStrArray(), ","))
|
allDomains = append(allDomains, strings.Join(p.Domains[i].ToStrArray(), ","))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return searchUncheckedDomains(domainsToCheck, allCerts)
|
return searchUncheckedDomains(domainsToCheck, allDomains)
|
||||||
}
|
}
|
||||||
|
|
||||||
func searchUncheckedDomains(domainsToCheck []string, existentDomains []string) []string {
|
func searchUncheckedDomains(domainsToCheck []string, existentDomains []string) []string {
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/containous/traefik/safe"
|
"github.com/containous/traefik/safe"
|
||||||
|
traefiktls "github.com/containous/traefik/tls"
|
||||||
"github.com/containous/traefik/types"
|
"github.com/containous/traefik/types"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
@ -25,7 +26,7 @@ func TestGetUncheckedCertificates(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
desc string
|
desc string
|
||||||
dynamicCerts *safe.Safe
|
dynamicCerts *safe.Safe
|
||||||
staticCerts map[string]*tls.Certificate
|
staticCerts *safe.Safe
|
||||||
acmeCertificates []*Certificate
|
acmeCertificates []*Certificate
|
||||||
domains []string
|
domains []string
|
||||||
expectedDomains []string
|
expectedDomains []string
|
||||||
|
@ -44,7 +45,7 @@ func TestGetUncheckedCertificates(t *testing.T) {
|
||||||
{
|
{
|
||||||
desc: "wildcard already exists in static certificates",
|
desc: "wildcard already exists in static certificates",
|
||||||
domains: []string{"*.traefik.wtf"},
|
domains: []string{"*.traefik.wtf"},
|
||||||
staticCerts: wildcardMap,
|
staticCerts: wildcardSafe,
|
||||||
expectedDomains: nil,
|
expectedDomains: nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -71,7 +72,7 @@ func TestGetUncheckedCertificates(t *testing.T) {
|
||||||
{
|
{
|
||||||
desc: "domain CN already exists in static certificates and SANs to generate",
|
desc: "domain CN already exists in static certificates and SANs to generate",
|
||||||
domains: []string{"traefik.wtf", "foo.traefik.wtf"},
|
domains: []string{"traefik.wtf", "foo.traefik.wtf"},
|
||||||
staticCerts: domainMap,
|
staticCerts: domainSafe,
|
||||||
expectedDomains: []string{"foo.traefik.wtf"},
|
expectedDomains: []string{"foo.traefik.wtf"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -93,7 +94,7 @@ func TestGetUncheckedCertificates(t *testing.T) {
|
||||||
{
|
{
|
||||||
desc: "domain already exists in static certificates",
|
desc: "domain already exists in static certificates",
|
||||||
domains: []string{"traefik.wtf"},
|
domains: []string{"traefik.wtf"},
|
||||||
staticCerts: domainMap,
|
staticCerts: domainSafe,
|
||||||
expectedDomains: nil,
|
expectedDomains: nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -115,7 +116,7 @@ func TestGetUncheckedCertificates(t *testing.T) {
|
||||||
{
|
{
|
||||||
desc: "domain matched by wildcard in static certificates",
|
desc: "domain matched by wildcard in static certificates",
|
||||||
domains: []string{"who.traefik.wtf", "foo.traefik.wtf"},
|
domains: []string{"who.traefik.wtf", "foo.traefik.wtf"},
|
||||||
staticCerts: wildcardMap,
|
staticCerts: wildcardSafe,
|
||||||
expectedDomains: nil,
|
expectedDomains: nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -146,8 +147,10 @@ func TestGetUncheckedCertificates(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
acmeProvider := Provider{
|
acmeProvider := Provider{
|
||||||
dynamicCerts: test.dynamicCerts,
|
certificateStore: traefiktls.CertificateStore{
|
||||||
staticCerts: test.staticCerts,
|
DynamicCerts: test.dynamicCerts,
|
||||||
|
StaticCerts: test.staticCerts,
|
||||||
|
},
|
||||||
certificates: test.acmeCertificates,
|
certificates: test.acmeCertificates,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,6 @@ import (
|
||||||
"github.com/containous/traefik/middlewares/redirect"
|
"github.com/containous/traefik/middlewares/redirect"
|
||||||
"github.com/containous/traefik/middlewares/tracing"
|
"github.com/containous/traefik/middlewares/tracing"
|
||||||
"github.com/containous/traefik/provider"
|
"github.com/containous/traefik/provider"
|
||||||
"github.com/containous/traefik/provider/acme"
|
|
||||||
"github.com/containous/traefik/rules"
|
"github.com/containous/traefik/rules"
|
||||||
"github.com/containous/traefik/safe"
|
"github.com/containous/traefik/safe"
|
||||||
"github.com/containous/traefik/server/cookie"
|
"github.com/containous/traefik/server/cookie"
|
||||||
|
@ -81,8 +80,10 @@ type Server struct {
|
||||||
|
|
||||||
// EntryPoint entryPoint information (configuration + internalRouter)
|
// EntryPoint entryPoint information (configuration + internalRouter)
|
||||||
type EntryPoint struct {
|
type EntryPoint struct {
|
||||||
InternalRouter types.InternalRouter
|
InternalRouter types.InternalRouter
|
||||||
Configuration *configuration.EntryPoint
|
Configuration *configuration.EntryPoint
|
||||||
|
OnDemandListener func(string) (*tls.Certificate, error)
|
||||||
|
CertificateStore *traefiktls.CertificateStore
|
||||||
}
|
}
|
||||||
|
|
||||||
type serverEntryPoints map[string]*serverEntryPoint
|
type serverEntryPoints map[string]*serverEntryPoint
|
||||||
|
@ -502,11 +503,6 @@ func (s *Server) AddListener(listener func(types.Configuration)) {
|
||||||
s.configurationListeners = append(s.configurationListeners, listener)
|
s.configurationListeners = append(s.configurationListeners, listener)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetOnDemandListener adds a new listener function used when a request is caught
|
|
||||||
func (s *serverEntryPoint) SetOnDemandListener(listener func(string) (*tls.Certificate, error)) {
|
|
||||||
s.onDemandListener = listener
|
|
||||||
}
|
|
||||||
|
|
||||||
// loadHTTPSConfiguration add/delete HTTPS certificate managed dynamically
|
// loadHTTPSConfiguration add/delete HTTPS certificate managed dynamically
|
||||||
func (s *Server) loadHTTPSConfiguration(configurations types.Configurations, defaultEntryPoints configuration.DefaultEntryPoints) (map[string]map[string]*tls.Certificate, error) {
|
func (s *Server) loadHTTPSConfiguration(configurations types.Configurations, defaultEntryPoints configuration.DefaultEntryPoints) (map[string]map[string]*tls.Certificate, error) {
|
||||||
newEPCertificates := make(map[string]map[string]*tls.Certificate)
|
newEPCertificates := make(map[string]map[string]*tls.Certificate)
|
||||||
|
@ -693,14 +689,8 @@ func (s *Server) createTLSConfig(entryPointName string, tlsOption *traefiktls.TL
|
||||||
// in each certificate and populates the config.NameToCertificate map.
|
// in each certificate and populates the config.NameToCertificate map.
|
||||||
config.BuildNameToCertificate()
|
config.BuildNameToCertificate()
|
||||||
|
|
||||||
if acme.IsEnabled() {
|
if s.entryPoints[entryPointName].CertificateStore != nil {
|
||||||
if entryPointName == acme.Get().EntryPoint {
|
s.entryPoints[entryPointName].CertificateStore.StaticCerts.Set(config.NameToCertificate)
|
||||||
acme.Get().SetStaticCertificates(config.NameToCertificate)
|
|
||||||
acme.Get().SetDynamicCertificates(&s.serverEntryPoints[entryPointName].certs)
|
|
||||||
if acme.Get().OnDemand {
|
|
||||||
s.serverEntryPoints[entryPointName].SetOnDemandListener(acme.Get().ListenRequest)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the minimum TLS version if set in the config TOML
|
// Set the minimum TLS version if set in the config TOML
|
||||||
|
@ -839,9 +829,13 @@ func buildServerTimeouts(globalConfig configuration.GlobalConfiguration) (readTi
|
||||||
|
|
||||||
func (s *Server) buildEntryPoints() map[string]*serverEntryPoint {
|
func (s *Server) buildEntryPoints() map[string]*serverEntryPoint {
|
||||||
serverEntryPoints := make(map[string]*serverEntryPoint)
|
serverEntryPoints := make(map[string]*serverEntryPoint)
|
||||||
for entryPointName := range s.entryPoints {
|
for entryPointName, entryPoint := range s.entryPoints {
|
||||||
serverEntryPoints[entryPointName] = &serverEntryPoint{
|
serverEntryPoints[entryPointName] = &serverEntryPoint{
|
||||||
httpRouter: middlewares.NewHandlerSwitcher(s.buildDefaultHTTPRouter()),
|
httpRouter: middlewares.NewHandlerSwitcher(s.buildDefaultHTTPRouter()),
|
||||||
|
onDemandListener: entryPoint.OnDemandListener,
|
||||||
|
}
|
||||||
|
if entryPoint.CertificateStore != nil {
|
||||||
|
serverEntryPoints[entryPointName].certs = *entryPoint.CertificateStore.DynamicCerts
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return serverEntryPoints
|
return serverEntryPoints
|
||||||
|
|
33
tls/certificate_store.go
Normal file
33
tls/certificate_store.go
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
package tls
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/tls"
|
||||||
|
|
||||||
|
"github.com/containous/traefik/safe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CertificateStore store for dynamic and static certificates
|
||||||
|
type CertificateStore struct {
|
||||||
|
DynamicCerts *safe.Safe
|
||||||
|
StaticCerts *safe.Safe
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAllDomains return a slice with all the certificate domain
|
||||||
|
func (c CertificateStore) GetAllDomains() []string {
|
||||||
|
var allCerts []string
|
||||||
|
|
||||||
|
// Get static certificates
|
||||||
|
if c.StaticCerts != nil && c.StaticCerts.Get() != nil {
|
||||||
|
for domains := range c.StaticCerts.Get().(map[string]*tls.Certificate) {
|
||||||
|
allCerts = append(allCerts, domains)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get dynamic certificates
|
||||||
|
if c.DynamicCerts != nil && c.DynamicCerts.Get() != nil {
|
||||||
|
for domains := range c.DynamicCerts.Get().(map[string]*tls.Certificate) {
|
||||||
|
allCerts = append(allCerts, domains)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return allCerts
|
||||||
|
}
|
Loading…
Reference in a new issue