traefik/configuration/router/internal_router.go
2018-04-23 15:30:03 +02:00

133 lines
4.7 KiB
Go

package router
import (
"github.com/containous/mux"
"github.com/containous/traefik/configuration"
"github.com/containous/traefik/log"
"github.com/containous/traefik/metrics"
"github.com/containous/traefik/middlewares"
mauth "github.com/containous/traefik/middlewares/auth"
"github.com/containous/traefik/types"
"github.com/urfave/negroni"
)
// NewInternalRouterAggregator Create a new internalRouterAggregator
func NewInternalRouterAggregator(globalConfiguration configuration.GlobalConfiguration, entryPointName string) *InternalRouterAggregator {
var serverMiddlewares []negroni.Handler
if globalConfiguration.EntryPoints[entryPointName].WhiteList != nil {
ipWhitelistMiddleware, err := middlewares.NewIPWhiteLister(
globalConfiguration.EntryPoints[entryPointName].WhiteList.SourceRange,
globalConfiguration.EntryPoints[entryPointName].WhiteList.UseXForwardedFor)
if err != nil {
log.Fatalf("Error creating whitelist middleware: %s", err)
}
if ipWhitelistMiddleware != nil {
serverMiddlewares = append(serverMiddlewares, ipWhitelistMiddleware)
}
}
if globalConfiguration.EntryPoints[entryPointName].Auth != nil {
authMiddleware, err := mauth.NewAuthenticator(globalConfiguration.EntryPoints[entryPointName].Auth, nil)
if err != nil {
log.Fatalf("Error creating authenticator middleware: %s", err)
}
serverMiddlewares = append(serverMiddlewares, authMiddleware)
}
router := InternalRouterAggregator{}
routerWithPrefix := InternalRouterAggregator{}
routerWithPrefixAndMiddleware := InternalRouterAggregator{}
if globalConfiguration.Metrics != nil && globalConfiguration.Metrics.Prometheus != nil && globalConfiguration.Metrics.Prometheus.EntryPoint == entryPointName {
routerWithPrefixAndMiddleware.AddRouter(metrics.PrometheusHandler{})
}
if globalConfiguration.Rest != nil && globalConfiguration.Rest.EntryPoint == entryPointName {
routerWithPrefixAndMiddleware.AddRouter(globalConfiguration.Rest)
}
if globalConfiguration.API != nil && globalConfiguration.API.EntryPoint == entryPointName {
routerWithPrefixAndMiddleware.AddRouter(globalConfiguration.API)
}
if globalConfiguration.Ping != nil && globalConfiguration.Ping.EntryPoint == entryPointName {
routerWithPrefix.AddRouter(globalConfiguration.Ping)
}
if globalConfiguration.ACME != nil && globalConfiguration.ACME.HTTPChallenge != nil && globalConfiguration.ACME.HTTPChallenge.EntryPoint == entryPointName {
router.AddRouter(globalConfiguration.ACME)
}
realRouterWithMiddleware := WithMiddleware{router: &routerWithPrefixAndMiddleware, routerMiddlewares: serverMiddlewares}
if globalConfiguration.Web != nil && globalConfiguration.Web.Path != "" {
router.AddRouter(&WithPrefix{PathPrefix: globalConfiguration.Web.Path, Router: &routerWithPrefix})
router.AddRouter(&WithPrefix{PathPrefix: globalConfiguration.Web.Path, Router: &realRouterWithMiddleware})
} else {
router.AddRouter(&routerWithPrefix)
router.AddRouter(&realRouterWithMiddleware)
}
return &router
}
// WithMiddleware router with internal middleware
type WithMiddleware struct {
router types.InternalRouter
routerMiddlewares []negroni.Handler
}
// AddRoutes Add routes to the router
func (wm *WithMiddleware) AddRoutes(systemRouter *mux.Router) {
realRouter := systemRouter.PathPrefix("/").Subrouter()
wm.router.AddRoutes(realRouter)
if len(wm.routerMiddlewares) > 0 {
realRouter.Walk(wrapRoute(wm.routerMiddlewares))
}
}
// WithPrefix router which add a prefix
type WithPrefix struct {
Router types.InternalRouter
PathPrefix string
}
// AddRoutes Add routes to the router
func (wp *WithPrefix) AddRoutes(systemRouter *mux.Router) {
realRouter := systemRouter.PathPrefix("/").Subrouter()
if wp.PathPrefix != "" {
realRouter = systemRouter.PathPrefix(wp.PathPrefix).Subrouter()
realRouter.StrictSlash(true)
realRouter.SkipClean(true)
}
wp.Router.AddRoutes(realRouter)
}
// InternalRouterAggregator InternalRouter that aggregate other internalRouter
type InternalRouterAggregator struct {
internalRouters []types.InternalRouter
}
// AddRouter add a router in the aggregator
func (r *InternalRouterAggregator) AddRouter(router types.InternalRouter) {
r.internalRouters = append(r.internalRouters, router)
}
// AddRoutes Add routes to the router
func (r *InternalRouterAggregator) AddRoutes(systemRouter *mux.Router) {
for _, router := range r.internalRouters {
router.AddRoutes(systemRouter)
}
}
// wrapRoute with middlewares
func wrapRoute(middlewares []negroni.Handler) func(*mux.Route, *mux.Router, []*mux.Route) error {
return func(route *mux.Route, router *mux.Router, ancestors []*mux.Route) error {
middles := append(middlewares, negroni.Wrap(route.GetHandler()))
route.Handler(negroni.New(middles...))
return nil
}
}