Add internal provider
Co-authored-by: Julien Salleyron <julien.salleyron@gmail.com>
This commit is contained in:
parent
2ee2e29262
commit
424e2a9439
71 changed files with 2523 additions and 1469 deletions
|
@ -16,6 +16,7 @@ import (
|
|||
"github.com/containous/traefik/v2/pkg/middlewares"
|
||||
"github.com/containous/traefik/v2/pkg/middlewares/forwardedheaders"
|
||||
"github.com/containous/traefik/v2/pkg/safe"
|
||||
"github.com/containous/traefik/v2/pkg/server/router"
|
||||
"github.com/containous/traefik/v2/pkg/tcp"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/net/http2"
|
||||
|
@ -50,11 +51,60 @@ func (h *httpForwarder) Accept() (net.Conn, error) {
|
|||
// TCPEntryPoints holds a map of TCPEntryPoint (the entrypoint names being the keys)
|
||||
type TCPEntryPoints map[string]*TCPEntryPoint
|
||||
|
||||
// NewTCPEntryPoints creates a new TCPEntryPoints.
|
||||
func NewTCPEntryPoints(staticConfiguration static.Configuration) (TCPEntryPoints, error) {
|
||||
serverEntryPointsTCP := make(TCPEntryPoints)
|
||||
for entryPointName, config := range staticConfiguration.EntryPoints {
|
||||
ctx := log.With(context.Background(), log.Str(log.EntryPointName, entryPointName))
|
||||
|
||||
var err error
|
||||
serverEntryPointsTCP[entryPointName], err = NewTCPEntryPoint(ctx, config)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error while building entryPoint %s: %v", entryPointName, err)
|
||||
}
|
||||
}
|
||||
return serverEntryPointsTCP, nil
|
||||
}
|
||||
|
||||
// Start the server entry points.
|
||||
func (eps TCPEntryPoints) Start() {
|
||||
for entryPointName, serverEntryPoint := range eps {
|
||||
ctx := log.With(context.Background(), log.Str(log.EntryPointName, entryPointName))
|
||||
go serverEntryPoint.StartTCP(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
// Stop the server entry points.
|
||||
func (eps TCPEntryPoints) Stop() {
|
||||
var wg sync.WaitGroup
|
||||
|
||||
for epn, ep := range eps {
|
||||
wg.Add(1)
|
||||
|
||||
go func(entryPointName string, entryPoint *TCPEntryPoint) {
|
||||
defer wg.Done()
|
||||
|
||||
ctx := log.With(context.Background(), log.Str(log.EntryPointName, entryPointName))
|
||||
entryPoint.Shutdown(ctx)
|
||||
|
||||
log.FromContext(ctx).Debugf("Entry point %s closed", entryPointName)
|
||||
}(epn, ep)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
// Switch the TCP routers.
|
||||
func (eps TCPEntryPoints) Switch(routersTCP map[string]*tcp.Router) {
|
||||
for entryPointName, rt := range routersTCP {
|
||||
eps[entryPointName].SwitchRouter(rt)
|
||||
}
|
||||
}
|
||||
|
||||
// TCPEntryPoint is the TCP server
|
||||
type TCPEntryPoint struct {
|
||||
listener net.Listener
|
||||
switcher *tcp.HandlerSwitcher
|
||||
RouteAppenderFactory RouteAppenderFactory
|
||||
transportConfiguration *static.EntryPointsTransport
|
||||
tracker *connectionTracker
|
||||
httpServer *httpServer
|
||||
|
@ -99,35 +149,8 @@ func NewTCPEntryPoint(ctx context.Context, configuration *static.EntryPoint) (*T
|
|||
}, nil
|
||||
}
|
||||
|
||||
// writeCloserWrapper wraps together a connection, and the concrete underlying
|
||||
// connection type that was found to satisfy WriteCloser.
|
||||
type writeCloserWrapper struct {
|
||||
net.Conn
|
||||
writeCloser tcp.WriteCloser
|
||||
}
|
||||
|
||||
func (c *writeCloserWrapper) CloseWrite() error {
|
||||
return c.writeCloser.CloseWrite()
|
||||
}
|
||||
|
||||
// writeCloser returns the given connection, augmented with the WriteCloser
|
||||
// implementation, if any was found within the underlying conn.
|
||||
func writeCloser(conn net.Conn) (tcp.WriteCloser, error) {
|
||||
switch typedConn := conn.(type) {
|
||||
case *proxyprotocol.Conn:
|
||||
underlying, err := writeCloser(typedConn.Conn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &writeCloserWrapper{writeCloser: underlying, Conn: typedConn}, nil
|
||||
case *net.TCPConn:
|
||||
return typedConn, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown connection type %T", typedConn)
|
||||
}
|
||||
}
|
||||
|
||||
func (e *TCPEntryPoint) startTCP(ctx context.Context) {
|
||||
// StartTCP starts the TCP server.
|
||||
func (e *TCPEntryPoint) StartTCP(ctx context.Context) {
|
||||
logger := log.FromContext(ctx)
|
||||
logger.Debugf("Start TCP Server")
|
||||
|
||||
|
@ -213,22 +236,55 @@ func (e *TCPEntryPoint) Shutdown(ctx context.Context) {
|
|||
cancel()
|
||||
}
|
||||
|
||||
func (e *TCPEntryPoint) switchRouter(router *tcp.Router) {
|
||||
router.HTTPForwarder(e.httpServer.Forwarder)
|
||||
router.HTTPSForwarder(e.httpsServer.Forwarder)
|
||||
// SwitchRouter switches the TCP router handler.
|
||||
func (e *TCPEntryPoint) SwitchRouter(rt *tcp.Router) {
|
||||
rt.HTTPForwarder(e.httpServer.Forwarder)
|
||||
|
||||
httpHandler := router.GetHTTPHandler()
|
||||
httpsHandler := router.GetHTTPSHandler()
|
||||
httpHandler := rt.GetHTTPHandler()
|
||||
if httpHandler == nil {
|
||||
httpHandler = buildDefaultHTTPRouter()
|
||||
}
|
||||
if httpsHandler == nil {
|
||||
httpsHandler = buildDefaultHTTPRouter()
|
||||
httpHandler = router.BuildDefaultHTTPRouter()
|
||||
}
|
||||
|
||||
e.httpServer.Switcher.UpdateHandler(httpHandler)
|
||||
|
||||
rt.HTTPSForwarder(e.httpsServer.Forwarder)
|
||||
|
||||
httpsHandler := rt.GetHTTPSHandler()
|
||||
if httpsHandler == nil {
|
||||
httpsHandler = router.BuildDefaultHTTPRouter()
|
||||
}
|
||||
|
||||
e.httpsServer.Switcher.UpdateHandler(httpsHandler)
|
||||
e.switcher.Switch(router)
|
||||
|
||||
e.switcher.Switch(rt)
|
||||
}
|
||||
|
||||
// writeCloserWrapper wraps together a connection, and the concrete underlying
|
||||
// connection type that was found to satisfy WriteCloser.
|
||||
type writeCloserWrapper struct {
|
||||
net.Conn
|
||||
writeCloser tcp.WriteCloser
|
||||
}
|
||||
|
||||
func (c *writeCloserWrapper) CloseWrite() error {
|
||||
return c.writeCloser.CloseWrite()
|
||||
}
|
||||
|
||||
// writeCloser returns the given connection, augmented with the WriteCloser
|
||||
// implementation, if any was found within the underlying conn.
|
||||
func writeCloser(conn net.Conn) (tcp.WriteCloser, error) {
|
||||
switch typedConn := conn.(type) {
|
||||
case *proxyprotocol.Conn:
|
||||
underlying, err := writeCloser(typedConn.Conn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &writeCloserWrapper{writeCloser: underlying, Conn: typedConn}, nil
|
||||
case *net.TCPConn:
|
||||
return typedConn, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown connection type %T", typedConn)
|
||||
}
|
||||
}
|
||||
|
||||
// tcpKeepAliveListener sets TCP keep-alive timeouts on accepted
|
||||
|
@ -382,7 +438,7 @@ type httpServer struct {
|
|||
}
|
||||
|
||||
func createHTTPServer(ctx context.Context, ln net.Listener, configuration *static.EntryPoint, withH2c bool) (*httpServer, error) {
|
||||
httpSwitcher := middlewares.NewHandlerSwitcher(buildDefaultHTTPRouter())
|
||||
httpSwitcher := middlewares.NewHandlerSwitcher(router.BuildDefaultHTTPRouter())
|
||||
|
||||
var handler http.Handler
|
||||
var err error
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue