2017-11-09 18:12:04 +03:00
package api
import (
2018-11-14 12:18:03 +03:00
"io"
2017-11-09 18:12:04 +03:00
"net/http"
"github.com/containous/mux"
2019-03-15 11:42:03 +03:00
"github.com/containous/traefik/pkg/config"
2019-05-16 11:58:06 +03:00
"github.com/containous/traefik/pkg/config/static"
2019-03-15 11:42:03 +03:00
"github.com/containous/traefik/pkg/log"
"github.com/containous/traefik/pkg/types"
"github.com/containous/traefik/pkg/version"
2019-02-18 09:52:03 +03:00
assetfs "github.com/elazarl/go-bindata-assetfs"
2017-11-09 18:12:04 +03:00
"github.com/unrolled/render"
)
2019-05-16 11:58:06 +03:00
var templateRenderer jsonRenderer = render . New ( render . Options { Directory : "nowhere" } )
2018-11-14 12:18:03 +03:00
2019-05-16 11:58:06 +03:00
type jsonRenderer interface {
JSON ( w io . Writer , status int , v interface { } ) error
2018-11-14 12:18:03 +03:00
}
2019-05-16 11:58:06 +03:00
type serviceInfoRepresentation struct {
* config . ServiceInfo
ServerStatus map [ string ] string ` json:"serverStatus,omitempty" `
2018-11-14 12:18:03 +03:00
}
2019-05-16 11:58:06 +03:00
// RunTimeRepresentation is the configuration information exposed by the API handler.
type RunTimeRepresentation struct {
Routers map [ string ] * config . RouterInfo ` json:"routers,omitempty" `
Middlewares map [ string ] * config . MiddlewareInfo ` json:"middlewares,omitempty" `
Services map [ string ] * serviceInfoRepresentation ` json:"services,omitempty" `
TCPRouters map [ string ] * config . TCPRouterInfo ` json:"tcpRouters,omitempty" `
TCPServices map [ string ] * config . TCPServiceInfo ` json:"tcpServices,omitempty" `
2018-11-14 12:18:03 +03:00
}
2019-05-16 11:58:06 +03:00
// Handler serves the configuration and status of Traefik on API endpoints.
2017-11-09 18:12:04 +03:00
type Handler struct {
2019-05-16 11:58:06 +03:00
dashboard bool
debug bool
// runtimeConfiguration is the data set used to create all the data representations exposed by the API.
runtimeConfiguration * config . RuntimeConfiguration
statistics * types . Statistics
// stats *thoasstats.Stats // FIXME stats
2018-11-14 12:18:03 +03:00
// StatsRecorder *middlewares.StatsRecorder // FIXME stats
2019-05-16 11:58:06 +03:00
dashboardAssets * assetfs . AssetFS
2017-11-09 18:12:04 +03:00
}
2019-05-16 11:58:06 +03:00
// New returns a Handler defined by staticConfig, and if provided, by runtimeConfig.
// It finishes populating the information provided in the runtimeConfig.
func New ( staticConfig static . Configuration , runtimeConfig * config . RuntimeConfiguration ) * Handler {
rConfig := runtimeConfig
if rConfig == nil {
rConfig = & config . RuntimeConfiguration { }
}
2018-11-14 12:18:03 +03:00
2019-05-16 11:58:06 +03:00
return & Handler {
dashboard : staticConfig . API . Dashboard ,
statistics : staticConfig . API . Statistics ,
dashboardAssets : staticConfig . API . DashboardAssets ,
runtimeConfiguration : rConfig ,
debug : staticConfig . Global . Debug ,
}
2018-11-14 12:18:03 +03:00
}
2017-11-09 18:12:04 +03:00
2018-11-14 12:18:03 +03:00
// Append add api routes on a router
2019-03-14 11:30:04 +03:00
func ( h Handler ) Append ( router * mux . Router ) {
2019-05-16 11:58:06 +03:00
if h . debug {
2018-11-14 12:18:03 +03:00
DebugHandler { } . Append ( router )
2017-11-09 18:12:04 +03:00
}
2019-05-16 11:58:06 +03:00
router . Methods ( http . MethodGet ) . Path ( "/api/rawdata" ) . HandlerFunc ( h . getRuntimeConfiguration )
2017-11-09 18:12:04 +03:00
2018-11-14 12:18:03 +03:00
// FIXME stats
2017-11-09 18:12:04 +03:00
// health route
2018-11-14 12:18:03 +03:00
//router.Methods(http.MethodGet).Path("/health").HandlerFunc(p.getHealthHandler)
2017-11-09 18:12:04 +03:00
2018-11-14 12:18:03 +03:00
version . Handler { } . Append ( router )
2017-11-09 18:12:04 +03:00
2019-05-16 11:58:06 +03:00
if h . dashboard {
DashboardHandler { Assets : h . dashboardAssets } . Append ( router )
2017-11-09 18:12:04 +03:00
}
}
2019-05-16 11:58:06 +03:00
func ( h Handler ) getRuntimeConfiguration ( rw http . ResponseWriter , request * http . Request ) {
siRepr := make ( map [ string ] * serviceInfoRepresentation , len ( h . runtimeConfiguration . Services ) )
for k , v := range h . runtimeConfiguration . Services {
siRepr [ k ] = & serviceInfoRepresentation {
ServiceInfo : v ,
ServerStatus : v . GetAllStatus ( ) ,
2019-03-14 11:30:04 +03:00
}
}
2019-05-16 11:58:06 +03:00
rtRepr := RunTimeRepresentation {
Routers : h . runtimeConfiguration . Routers ,
Middlewares : h . runtimeConfiguration . Middlewares ,
Services : siRepr ,
TCPRouters : h . runtimeConfiguration . TCPRouters ,
TCPServices : h . runtimeConfiguration . TCPServices ,
2017-11-09 18:12:04 +03:00
}
2018-11-14 12:18:03 +03:00
2019-05-16 11:58:06 +03:00
err := templateRenderer . JSON ( rw , http . StatusOK , rtRepr )
2017-11-09 18:12:04 +03:00
if err != nil {
2018-11-14 12:18:03 +03:00
log . FromContext ( request . Context ( ) ) . Error ( err )
http . Error ( rw , err . Error ( ) , http . StatusInternalServerError )
2017-11-09 18:12:04 +03:00
}
}