1
0
Fork 0

Merge branch 'v2.0' into master

This commit is contained in:
Fernandez Ludovic 2019-10-29 09:52:45 +01:00
commit d66dd01438
46 changed files with 911 additions and 484 deletions

View file

@ -973,6 +973,11 @@ func (in *ServersLoadBalancer) DeepCopyInto(out *ServersLoadBalancer) {
*out = new(HealthCheck)
(*in).DeepCopyInto(*out)
}
if in.PassHostHeader != nil {
in, out := &in.PassHostHeader, &out.PassHostHeader
*out = new(bool)
**out = **in
}
if in.ResponseForwarding != nil {
in, out := &in.ResponseForwarding, &out.ResponseForwarding
*out = new(ResponseForwarding)

View file

@ -1,123 +0,0 @@
package hostresolver
import (
"fmt"
"net"
"sort"
"strings"
"time"
"github.com/containous/traefik/v2/pkg/log"
"github.com/miekg/dns"
"github.com/patrickmn/go-cache"
)
type cnameResolv struct {
TTL time.Duration
Record string
}
type byTTL []*cnameResolv
func (a byTTL) Len() int { return len(a) }
func (a byTTL) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a byTTL) Less(i, j int) bool { return a[i].TTL > a[j].TTL }
// Resolver used for host resolver
type Resolver struct {
CnameFlattening bool
ResolvConfig string
ResolvDepth int
cache *cache.Cache
}
// CNAMEFlatten check if CNAME record exists, flatten if possible
func (hr *Resolver) CNAMEFlatten(host string) (string, string) {
if hr.cache == nil {
hr.cache = cache.New(30*time.Minute, 5*time.Minute)
}
result := []string{host}
request := host
value, found := hr.cache.Get(host)
if found {
result = strings.Split(value.(string), ",")
} else {
var cacheDuration = 0 * time.Second
for depth := 0; depth < hr.ResolvDepth; depth++ {
resolv, err := cnameResolve(request, hr.ResolvConfig)
if err != nil {
log.Error(err)
break
}
if resolv == nil {
break
}
result = append(result, resolv.Record)
if depth == 0 {
cacheDuration = resolv.TTL
}
request = resolv.Record
}
if err := hr.cache.Add(host, strings.Join(result, ","), cacheDuration); err != nil {
log.Error(err)
}
}
return result[0], result[len(result)-1]
}
// cnameResolve resolves CNAME if exists, and return with the highest TTL
func cnameResolve(host string, resolvPath string) (*cnameResolv, error) {
config, err := dns.ClientConfigFromFile(resolvPath)
if err != nil {
return nil, fmt.Errorf("invalid resolver configuration file: %s", resolvPath)
}
client := &dns.Client{Timeout: 30 * time.Second}
m := &dns.Msg{}
m.SetQuestion(dns.Fqdn(host), dns.TypeCNAME)
var result []*cnameResolv
for _, server := range config.Servers {
tempRecord, err := getRecord(client, m, server, config.Port)
if err != nil {
log.Errorf("Failed to resolve host %s: %v", host, err)
continue
}
result = append(result, tempRecord)
}
if len(result) == 0 {
return nil, nil
}
sort.Sort(byTTL(result))
return result[0], nil
}
func getRecord(client *dns.Client, msg *dns.Msg, server string, port string) (*cnameResolv, error) {
resp, _, err := client.Exchange(msg, net.JoinHostPort(server, port))
if err != nil {
return nil, fmt.Errorf("exchange error for server %s: %v", server, err)
}
if resp == nil || len(resp.Answer) == 0 {
return nil, fmt.Errorf("empty answer for server %s", server)
}
rr, ok := resp.Answer[0].(*dns.CNAME)
if !ok {
return nil, fmt.Errorf("invalid response type for server %s", server)
}
return &cnameResolv{
TTL: time.Duration(rr.Hdr.Ttl) * time.Second,
Record: strings.TrimSuffix(rr.Target, "."),
}, nil
}

View file

@ -1,61 +0,0 @@
package hostresolver
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestCNAMEFlatten(t *testing.T) {
testCase := []struct {
desc string
resolvFile string
domain string
expectedDomain string
isCNAME bool
}{
{
desc: "host request is CNAME record",
resolvFile: "/etc/resolv.conf",
domain: "www.github.com",
expectedDomain: "github.com",
isCNAME: true,
},
{
desc: "resolve file not found",
resolvFile: "/etc/resolv.oops",
domain: "www.github.com",
expectedDomain: "www.github.com",
isCNAME: false,
},
{
desc: "host request is not CNAME record",
resolvFile: "/etc/resolv.conf",
domain: "github.com",
expectedDomain: "github.com",
isCNAME: false,
},
}
for _, test := range testCase {
test := test
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
hostResolver := &Resolver{
ResolvConfig: test.resolvFile,
ResolvDepth: 5,
}
reqH, flatH := hostResolver.CNAMEFlatten(test.domain)
assert.Equal(t, test.domain, reqH)
assert.Equal(t, test.expectedDomain, flatH)
if test.isCNAME {
assert.NotEqual(t, test.expectedDomain, reqH)
} else {
assert.Equal(t, test.expectedDomain, reqH)
}
})
}
}

View file

@ -3,6 +3,7 @@ package accesslog
import (
"context"
"fmt"
"io"
"net"
"net/http"
"net/url"
@ -31,6 +32,19 @@ const (
JSONFormat string = "json"
)
type noopCloser struct {
*os.File
}
func (n noopCloser) Write(p []byte) (int, error) {
return n.File.Write(p)
}
func (n noopCloser) Close() error {
// noop
return nil
}
type handlerParams struct {
logDataTable *LogData
crr *captureRequestReader
@ -41,7 +55,7 @@ type handlerParams struct {
type Handler struct {
config *types.AccessLog
logger *logrus.Logger
file *os.File
file io.WriteCloser
mu sync.Mutex
httpCodeRanges types.HTTPCodeRanges
logHandlerChan chan handlerParams
@ -59,7 +73,7 @@ func WrapHandler(handler *Handler) alice.Constructor {
// NewHandler creates a new Handler.
func NewHandler(config *types.AccessLog) (*Handler, error) {
file := os.Stdout
var file io.WriteCloser = noopCloser{os.Stdout}
if len(config.FilePath) > 0 {
f, err := openAccessLogFile(config.FilePath)
if err != nil {
@ -213,14 +227,15 @@ func (h *Handler) Close() error {
// Rotate closes and reopens the log file to allow for rotation by an external source.
func (h *Handler) Rotate() error {
var err error
if h.file != nil {
defer func(f *os.File) {
f.Close()
}(h.file)
if h.config.FilePath == "" {
return nil
}
if h.file != nil {
defer func(f io.Closer) { _ = f.Close() }(h.file)
}
var err error
h.file, err = os.OpenFile(h.config.FilePath, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0664)
if err != nil {
return err

View file

@ -22,7 +22,10 @@ import (
)
// Compile time validation that the response recorder implements http interfaces correctly.
var _ middlewares.Stateful = &responseRecorderWithCloseNotify{}
var (
_ middlewares.Stateful = &responseRecorderWithCloseNotify{}
_ middlewares.Stateful = &codeCatcherWithCloseNotify{}
)
const (
typeName = "customError"
@ -80,25 +83,29 @@ func (c *customErrors) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
return
}
recorder := newResponseRecorder(ctx, rw)
c.next.ServeHTTP(recorder, req)
catcher := newCodeCatcher(rw, c.httpCodeRanges)
c.next.ServeHTTP(catcher, req)
if !catcher.isFilteredCode() {
return
}
// check the recorder code against the configured http status code ranges
code := catcher.getCode()
for _, block := range c.httpCodeRanges {
if recorder.GetCode() >= block[0] && recorder.GetCode() <= block[1] {
logger.Errorf("Caught HTTP Status Code %d, returning error page", recorder.GetCode())
if code >= block[0] && code <= block[1] {
logger.Errorf("Caught HTTP Status Code %d, returning error page", code)
var query string
if len(c.backendQuery) > 0 {
query = "/" + strings.TrimPrefix(c.backendQuery, "/")
query = strings.Replace(query, "{status}", strconv.Itoa(recorder.GetCode()), -1)
query = strings.Replace(query, "{status}", strconv.Itoa(code), -1)
}
pageReq, err := newRequest(backendURL + query)
if err != nil {
logger.Error(err)
rw.WriteHeader(recorder.GetCode())
_, err = fmt.Fprint(rw, http.StatusText(recorder.GetCode()))
rw.WriteHeader(code)
_, err = fmt.Fprint(rw, http.StatusText(code))
if err != nil {
http.Error(rw, err.Error(), http.StatusInternalServerError)
}
@ -111,7 +118,7 @@ func (c *customErrors) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
c.backendHandler.ServeHTTP(recorderErrorPage, pageReq.WithContext(req.Context()))
utils.CopyHeaders(rw.Header(), recorderErrorPage.Header())
rw.WriteHeader(recorder.GetCode())
rw.WriteHeader(code)
if _, err = rw.Write(recorderErrorPage.GetBody().Bytes()); err != nil {
logger.Error(err)
@ -119,14 +126,6 @@ func (c *customErrors) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
return
}
}
// did not catch a configured status code so proceed with the request
utils.CopyHeaders(rw.Header(), recorder.Header())
rw.WriteHeader(recorder.GetCode())
_, err := rw.Write(recorder.GetBody().Bytes())
if err != nil {
http.Error(rw, err.Error(), http.StatusInternalServerError)
}
}
func newRequest(baseURL string) (*http.Request, error) {
@ -144,6 +143,132 @@ func newRequest(baseURL string) (*http.Request, error) {
return req, nil
}
type responseInterceptor interface {
http.ResponseWriter
http.Flusher
getCode() int
isFilteredCode() bool
}
// codeCatcher is a response writer that detects as soon as possible whether the
// response is a code within the ranges of codes it watches for. If it is, it
// simply drops the data from the response. Otherwise, it forwards it directly to
// the original client (its responseWriter) without any buffering.
type codeCatcher struct {
headerMap http.Header
code int
httpCodeRanges types.HTTPCodeRanges
firstWrite bool
caughtFilteredCode bool
responseWriter http.ResponseWriter
headersSent bool
}
type codeCatcherWithCloseNotify struct {
*codeCatcher
}
// CloseNotify returns a channel that receives at most a
// single value (true) when the client connection has gone away.
func (cc *codeCatcherWithCloseNotify) CloseNotify() <-chan bool {
return cc.responseWriter.(http.CloseNotifier).CloseNotify()
}
func newCodeCatcher(rw http.ResponseWriter, httpCodeRanges types.HTTPCodeRanges) responseInterceptor {
catcher := &codeCatcher{
headerMap: make(http.Header),
code: http.StatusOK, // If backend does not call WriteHeader on us, we consider it's a 200.
responseWriter: rw,
httpCodeRanges: httpCodeRanges,
firstWrite: true,
}
if _, ok := rw.(http.CloseNotifier); ok {
return &codeCatcherWithCloseNotify{catcher}
}
return catcher
}
func (cc *codeCatcher) Header() http.Header {
if cc.headerMap == nil {
cc.headerMap = make(http.Header)
}
return cc.headerMap
}
func (cc *codeCatcher) getCode() int {
return cc.code
}
// isFilteredCode returns whether the codeCatcher received a response code among the ones it is watching,
// and for which the response should be deferred to the error handler.
func (cc *codeCatcher) isFilteredCode() bool {
return cc.caughtFilteredCode
}
func (cc *codeCatcher) Write(buf []byte) (int, error) {
if !cc.firstWrite {
if cc.caughtFilteredCode {
// We don't care about the contents of the response,
// since we want to serve the ones from the error page,
// so we just drop them.
return len(buf), nil
}
return cc.responseWriter.Write(buf)
}
cc.firstWrite = false
// If WriteHeader was already called from the caller, this is a NOOP.
// Otherwise, cc.code is actually a 200 here.
cc.WriteHeader(cc.code)
if cc.caughtFilteredCode {
return len(buf), nil
}
return cc.responseWriter.Write(buf)
}
func (cc *codeCatcher) WriteHeader(code int) {
if cc.headersSent || cc.caughtFilteredCode {
return
}
cc.code = code
for _, block := range cc.httpCodeRanges {
if cc.code >= block[0] && cc.code <= block[1] {
cc.caughtFilteredCode = true
break
}
}
// it will be up to the other response recorder to send the headers,
// so it is out of our hands now.
if cc.caughtFilteredCode {
return
}
utils.CopyHeaders(cc.responseWriter.Header(), cc.Header())
cc.responseWriter.WriteHeader(cc.code)
cc.headersSent = true
}
// Hijack hijacks the connection
func (cc *codeCatcher) Hijack() (net.Conn, *bufio.ReadWriter, error) {
if hj, ok := cc.responseWriter.(http.Hijacker); ok {
return hj.Hijack()
}
return nil, nil, fmt.Errorf("%T is not a http.Hijacker", cc.responseWriter)
}
// Flush sends any buffered data to the client.
func (cc *codeCatcher) Flush() {
// If WriteHeader was already called from the caller, this is a NOOP.
// Otherwise, cc.code is actually a 200 here.
cc.WriteHeader(cc.code)
if flusher, ok := cc.responseWriter.(http.Flusher); ok {
flusher.Flush()
}
}
type responseRecorder interface {
http.ResponseWriter
http.Flusher

View file

@ -33,6 +33,30 @@ func TestHandler(t *testing.T) {
assert.Contains(t, recorder.Body.String(), http.StatusText(http.StatusOK))
},
},
{
desc: "no error, but not a 200",
errorPage: &dynamic.ErrorPage{Service: "error", Query: "/test", Status: []string{"500-501", "503-599"}},
backendCode: http.StatusPartialContent,
backendErrorHandler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "My error page.")
}),
validate: func(t *testing.T, recorder *httptest.ResponseRecorder) {
assert.Equal(t, http.StatusPartialContent, recorder.Code, "HTTP status")
assert.Contains(t, recorder.Body.String(), http.StatusText(http.StatusPartialContent))
},
},
{
desc: "a 304, so no Write called",
errorPage: &dynamic.ErrorPage{Service: "error", Query: "/test", Status: []string{"500-501", "503-599"}},
backendCode: http.StatusNotModified,
backendErrorHandler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "whatever, should not be called")
}),
validate: func(t *testing.T, recorder *httptest.ResponseRecorder) {
assert.Equal(t, http.StatusNotModified, recorder.Code, "HTTP status")
assert.Contains(t, recorder.Body.String(), "")
},
},
{
desc: "in the range",
errorPage: &dynamic.ErrorPage{Service: "error", Query: "/test", Status: []string{"500-501", "503-599"}},
@ -104,6 +128,9 @@ func TestHandler(t *testing.T) {
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(test.backendCode)
if test.backendCode == http.StatusNotModified {
return
}
fmt.Fprintln(w, http.StatusText(test.backendCode))
})
errorPageHandler, err := New(context.Background(), handler, *test.errorPage, serviceBuilderMock, "test")

View file

@ -3,6 +3,7 @@ package recovery
import (
"context"
"net/http"
"runtime"
"github.com/containous/traefik/v2/pkg/log"
"github.com/containous/traefik/v2/pkg/middlewares"
@ -28,13 +29,30 @@ func New(ctx context.Context, next http.Handler, name string) (http.Handler, err
}
func (re *recovery) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
defer recoverFunc(middlewares.GetLoggerCtx(req.Context(), re.name, typeName), rw)
defer recoverFunc(middlewares.GetLoggerCtx(req.Context(), re.name, typeName), rw, req)
re.next.ServeHTTP(rw, req)
}
func recoverFunc(ctx context.Context, rw http.ResponseWriter) {
func recoverFunc(ctx context.Context, rw http.ResponseWriter, r *http.Request) {
if err := recover(); err != nil {
log.FromContext(ctx).Errorf("Recovered from panic in http handler: %+v", err)
if !shouldLogPanic(err) {
log.FromContext(ctx).Debugf("Request has been aborted [%s - %s]: %v", r.RemoteAddr, r.URL, err)
return
}
log.FromContext(ctx).Errorf("Recovered from panic in HTTP handler [%s - %s]: %+v", r.RemoteAddr, r.URL, err)
const size = 64 << 10
buf := make([]byte, size)
buf = buf[:runtime.Stack(buf, false)]
log.FromContext(ctx).Errorf("Stack: %s", buf)
http.Error(rw, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
}
}
// https://github.com/golang/go/blob/a0d6420d8be2ae7164797051ec74fa2a2df466a1/src/net/http/server.go#L1761-L1775
// https://github.com/golang/go/blob/c33153f7b416c03983324b3e8f869ce1116d84bc/src/net/http/httputil/reverseproxy.go#L284
func shouldLogPanic(panicValue interface{}) bool {
return panicValue != nil && panicValue != http.ErrAbortHandler
}

View file

@ -323,7 +323,7 @@ func (p *Provider) resolveDomains(ctx context.Context, domains []string, tlsStor
return
}
log.FromContext(ctx).Debugf("Try to challenge certificate for domain %v founded in HostSNI rule", domains)
log.FromContext(ctx).Debugf("Try to challenge certificate for domain %v found in HostSNI rule", domains)
var domain types.Domain
if len(domains) > 0 {

View file

@ -199,8 +199,6 @@ func flattenCertificates(ctx context.Context, tlsConfig *dynamic.TLSConfiguratio
}
func (p *Provider) loadFileConfigFromDirectory(ctx context.Context, directory string, configuration *dynamic.Configuration) (*dynamic.Configuration, error) {
logger := log.FromContext(ctx)
fileList, err := ioutil.ReadDir(directory)
if err != nil {
return configuration, fmt.Errorf("unable to read directory %s: %v", directory, err)
@ -227,6 +225,8 @@ func (p *Provider) loadFileConfigFromDirectory(ctx context.Context, directory st
configTLSMaps := make(map[*tls.CertAndStores]struct{})
for _, item := range fileList {
logger := log.FromContext(log.With(ctx, log.Str("filename", item.Name())))
if item.IsDir() {
configuration, err = p.loadFileConfigFromDirectory(ctx, filepath.Join(directory, item.Name()), configuration)
if err != nil {
@ -245,7 +245,7 @@ func (p *Provider) loadFileConfigFromDirectory(ctx context.Context, directory st
var c *dynamic.Configuration
c, err = p.loadFileConfig(ctx, filepath.Join(directory, item.Name()), true)
if err != nil {
return configuration, err
return configuration, fmt.Errorf("%s: %v", filepath.Join(directory, item.Name()), err)
}
for name, conf := range c.HTTP.Routers {

View file

@ -7,7 +7,6 @@ import (
"crypto/sha256"
"fmt"
"os"
"reflect"
"sort"
"strconv"
"strings"
@ -21,6 +20,7 @@ import (
"github.com/containous/traefik/v2/pkg/safe"
"github.com/containous/traefik/v2/pkg/tls"
"github.com/containous/traefik/v2/pkg/types"
"github.com/mitchellh/hashstructure"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/labels"
)
@ -127,10 +127,14 @@ func (p *Provider) Provide(configurationChan chan<- dynamic.Message, pool *safe.
// track more information about the dropped events.
conf := p.loadConfigurationFromCRD(ctxLog, k8sClient)
if reflect.DeepEqual(p.lastConfiguration.Get(), conf) {
confHash, err := hashstructure.Hash(conf, nil)
switch {
case err != nil:
logger.Error("Unable to hash the configuration")
case p.lastConfiguration.Get() == confHash:
logger.Debugf("Skipping Kubernetes event kind %T", event)
} else {
p.lastConfiguration.Set(conf)
default:
p.lastConfiguration.Set(confHash)
configurationChan <- dynamic.Message{
ProviderName: "kubernetescrd",
Configuration: conf,

View file

@ -209,8 +209,13 @@ func loadServers(client Client, namespace string, svc v1alpha1.Service) ([]dynam
var servers []dynamic.Server
if service.Spec.Type == corev1.ServiceTypeExternalName {
protocol := "http"
if portSpec.Port == 443 || strings.HasPrefix(portSpec.Name, "https") {
protocol = "https"
}
servers = append(servers, dynamic.Server{
URL: fmt.Sprintf("http://%s:%d", service.Spec.ExternalName, portSpec.Port),
URL: fmt.Sprintf("%s://%s:%d", protocol, service.Spec.ExternalName, portSpec.Port),
})
} else {
endpoints, endpointsExists, endpointsErr := client.GetEndpoints(namespace, svc.Name)

View file

@ -6,7 +6,6 @@ import (
"fmt"
"math"
"os"
"reflect"
"sort"
"strconv"
"strings"
@ -16,9 +15,11 @@ import (
"github.com/containous/traefik/v2/pkg/config/dynamic"
"github.com/containous/traefik/v2/pkg/job"
"github.com/containous/traefik/v2/pkg/log"
"github.com/containous/traefik/v2/pkg/provider"
"github.com/containous/traefik/v2/pkg/safe"
"github.com/containous/traefik/v2/pkg/tls"
"github.com/containous/traefik/v2/pkg/types"
"github.com/mitchellh/hashstructure"
corev1 "k8s.io/api/core/v1"
"k8s.io/api/extensions/v1beta1"
"k8s.io/apimachinery/pkg/labels"
@ -138,10 +139,14 @@ func (p *Provider) Provide(configurationChan chan<- dynamic.Message, pool *safe.
// track more information about the dropped events.
conf := p.loadConfigurationFromIngresses(ctxLog, k8sClient)
if reflect.DeepEqual(p.lastConfiguration.Get(), conf) {
confHash, err := hashstructure.Hash(conf, nil)
switch {
case err != nil:
logger.Error("Unable to hash the configuration")
case p.lastConfiguration.Get() == confHash:
logger.Debugf("Skipping Kubernetes event kind %T", event)
} else {
p.lastConfiguration.Set(conf)
default:
p.lastConfiguration.Set(confHash)
configurationChan <- dynamic.Message{
ProviderName: "kubernetes",
Configuration: conf,
@ -202,8 +207,13 @@ func loadService(client Client, namespace string, backend v1beta1.IngressBackend
}
if service.Spec.Type == corev1.ServiceTypeExternalName {
protocol := "http"
if portSpec.Port == 443 || strings.HasPrefix(portSpec.Name, "https") {
protocol = "https"
}
servers = append(servers, dynamic.Server{
URL: fmt.Sprintf("http://%s:%d", service.Spec.ExternalName, portSpec.Port),
URL: fmt.Sprintf("%s://%s:%d", protocol, service.Spec.ExternalName, portSpec.Port),
})
} else {
endpoints, endpointsExists, endpointsErr := client.GetEndpoints(namespace, backend.ServiceName)
@ -324,8 +334,7 @@ func (p *Provider) loadConfigurationFromIngresses(ctx context.Context, client Cl
continue
}
serviceName := ingress.Namespace + "-" + p.Backend.ServiceName + "-" + p.Backend.ServicePort.String()
serviceName = strings.ReplaceAll(serviceName, ".", "-")
serviceName := provider.Normalize(ingress.Namespace + "-" + p.Backend.ServiceName + "-" + p.Backend.ServicePort.String())
var rules []string
if len(rule.Host) > 0 {
rules = []string{"Host(`" + rule.Host + "`)"}
@ -335,10 +344,7 @@ func (p *Provider) loadConfigurationFromIngresses(ctx context.Context, client Cl
rules = append(rules, "PathPrefix(`"+p.Path+"`)")
}
routerKey := strings.Replace(rule.Host, ".", "-", -1) + strings.Replace(p.Path, "/", "-", 1)
if strings.HasPrefix(routerKey, "-") {
routerKey = strings.Replace(routerKey, "-", "", 1)
}
routerKey := strings.TrimPrefix(provider.Normalize(rule.Host+p.Path), "-")
conf.HTTP.Routers[routerKey] = &dynamic.Router{
Rule: strings.Join(rules, " && "),
Service: serviceName,

View file

@ -94,8 +94,9 @@ func setupTracing(conf *static.Tracing) tracing.Backend {
if backend == nil {
log.WithoutContext().Debug("Could not initialize tracing, use Jaeger by default")
backend := &jaeger.Config{}
backend.SetDefaults()
bcd := &jaeger.Config{}
bcd.SetDefaults()
backend = bcd
}
return backend

View file

@ -254,6 +254,15 @@ func (ln tcpKeepAliveListener) Accept() (net.Conn, error) {
return tc, nil
}
type proxyProtocolLogger struct {
log.Logger
}
// Printf force log level to debug.
func (p proxyProtocolLogger) Printf(format string, v ...interface{}) {
p.Debugf(format, v...)
}
func buildProxyProtocolListener(ctx context.Context, entryPoint *static.EntryPoint, listener net.Listener) (net.Listener, error) {
var sourceCheck func(addr net.Addr) (bool, error)
if entryPoint.ProxyProtocol.Insecure {
@ -280,7 +289,7 @@ func buildProxyProtocolListener(ctx context.Context, entryPoint *static.EntryPoi
return proxyprotocol.NewDefaultListener(listener).
WithSourceChecker(sourceCheck).
WithLogger(log.FromContext(ctx)), nil
WithLogger(proxyProtocolLogger{Logger: log.FromContext(ctx)}), nil
}
func buildListener(ctx context.Context, entryPoint *static.EntryPoint) (net.Listener, error) {

View file

@ -189,7 +189,7 @@ func (c *Certificate) AppendCertificate(certs map[string]map[string]*tls.Certifi
}
}
if certExists {
log.Warnf("Skipping addition of certificate for domain(s) %q, to EntryPoint %s, as it already exists for this Entrypoint.", certKey, ep)
log.Debugf("Skipping addition of certificate for domain(s) %q, to EntryPoint %s, as it already exists for this Entrypoint.", certKey, ep)
} else {
log.Debugf("Adding certificate for domain(s) %s", certKey)
certs[ep][certKey] = &tlsCert

View file

@ -86,6 +86,7 @@ func derCert(privKey *rsa.PrivateKey, expiration time.Time, domain string) ([]by
NotAfter: expiration,
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageKeyAgreement | x509.KeyUsageDataEncipherment,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
BasicConstraintsValid: true,
DNSNames: []string{domain},
}

View file

@ -20,7 +20,6 @@ type Config struct {
// SetDefaults sets the default values.
func (c *Config) SetDefaults() {
c.LocalAgentHost = "localhost"
c.LocalAgentPort = 42699
c.LogLevel = "info"
}