mirror of
				https://github.com/traefik/traefik.git
				synced 2025-10-31 08:21:27 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			288 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			288 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package api
 | |
| 
 | |
| import (
 | |
| 	"encoding/json"
 | |
| 	"net/http"
 | |
| 	"reflect"
 | |
| 
 | |
| 	"github.com/rs/zerolog/log"
 | |
| 	"github.com/traefik/traefik/v3/pkg/config/runtime"
 | |
| 	"github.com/traefik/traefik/v3/pkg/config/static"
 | |
| )
 | |
| 
 | |
| type schemeOverview struct {
 | |
| 	Routers     *section `json:"routers,omitempty"`
 | |
| 	Services    *section `json:"services,omitempty"`
 | |
| 	Middlewares *section `json:"middlewares,omitempty"`
 | |
| }
 | |
| 
 | |
| type section struct {
 | |
| 	Total    int `json:"total"`
 | |
| 	Warnings int `json:"warnings"`
 | |
| 	Errors   int `json:"errors"`
 | |
| }
 | |
| 
 | |
| type features struct {
 | |
| 	Tracing   string `json:"tracing"`
 | |
| 	Metrics   string `json:"metrics"`
 | |
| 	AccessLog bool   `json:"accessLog"`
 | |
| 	// TODO add certificates resolvers
 | |
| }
 | |
| 
 | |
| type overview struct {
 | |
| 	HTTP      schemeOverview `json:"http"`
 | |
| 	TCP       schemeOverview `json:"tcp"`
 | |
| 	UDP       schemeOverview `json:"udp"`
 | |
| 	Features  features       `json:"features,omitempty"`
 | |
| 	Providers []string       `json:"providers,omitempty"`
 | |
| }
 | |
| 
 | |
| func (h Handler) getOverview(rw http.ResponseWriter, request *http.Request) {
 | |
| 	result := overview{
 | |
| 		HTTP: schemeOverview{
 | |
| 			Routers:     getHTTPRouterSection(h.runtimeConfiguration.Routers),
 | |
| 			Services:    getHTTPServiceSection(h.runtimeConfiguration.Services),
 | |
| 			Middlewares: getHTTPMiddlewareSection(h.runtimeConfiguration.Middlewares),
 | |
| 		},
 | |
| 		TCP: schemeOverview{
 | |
| 			Routers:     getTCPRouterSection(h.runtimeConfiguration.TCPRouters),
 | |
| 			Services:    getTCPServiceSection(h.runtimeConfiguration.TCPServices),
 | |
| 			Middlewares: getTCPMiddlewareSection(h.runtimeConfiguration.TCPMiddlewares),
 | |
| 		},
 | |
| 		UDP: schemeOverview{
 | |
| 			Routers:  getUDPRouterSection(h.runtimeConfiguration.UDPRouters),
 | |
| 			Services: getUDPServiceSection(h.runtimeConfiguration.UDPServices),
 | |
| 		},
 | |
| 		Features:  getFeatures(h.staticConfig),
 | |
| 		Providers: getProviders(h.staticConfig),
 | |
| 	}
 | |
| 
 | |
| 	rw.Header().Set("Content-Type", "application/json")
 | |
| 
 | |
| 	err := json.NewEncoder(rw).Encode(result)
 | |
| 	if err != nil {
 | |
| 		log.Ctx(request.Context()).Error().Err(err).Send()
 | |
| 		writeError(rw, err.Error(), http.StatusInternalServerError)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func getHTTPRouterSection(routers map[string]*runtime.RouterInfo) *section {
 | |
| 	var countErrors int
 | |
| 	var countWarnings int
 | |
| 	for _, rt := range routers {
 | |
| 		switch rt.Status {
 | |
| 		case runtime.StatusDisabled:
 | |
| 			countErrors++
 | |
| 		case runtime.StatusWarning:
 | |
| 			countWarnings++
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return §ion{
 | |
| 		Total:    len(routers),
 | |
| 		Warnings: countWarnings,
 | |
| 		Errors:   countErrors,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func getHTTPServiceSection(services map[string]*runtime.ServiceInfo) *section {
 | |
| 	var countErrors int
 | |
| 	var countWarnings int
 | |
| 	for _, svc := range services {
 | |
| 		switch svc.Status {
 | |
| 		case runtime.StatusDisabled:
 | |
| 			countErrors++
 | |
| 		case runtime.StatusWarning:
 | |
| 			countWarnings++
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return §ion{
 | |
| 		Total:    len(services),
 | |
| 		Warnings: countWarnings,
 | |
| 		Errors:   countErrors,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func getHTTPMiddlewareSection(middlewares map[string]*runtime.MiddlewareInfo) *section {
 | |
| 	var countErrors int
 | |
| 	var countWarnings int
 | |
| 	for _, mid := range middlewares {
 | |
| 		switch mid.Status {
 | |
| 		case runtime.StatusDisabled:
 | |
| 			countErrors++
 | |
| 		case runtime.StatusWarning:
 | |
| 			countWarnings++
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return §ion{
 | |
| 		Total:    len(middlewares),
 | |
| 		Warnings: countWarnings,
 | |
| 		Errors:   countErrors,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func getTCPRouterSection(routers map[string]*runtime.TCPRouterInfo) *section {
 | |
| 	var countErrors int
 | |
| 	var countWarnings int
 | |
| 	for _, rt := range routers {
 | |
| 		switch rt.Status {
 | |
| 		case runtime.StatusDisabled:
 | |
| 			countErrors++
 | |
| 		case runtime.StatusWarning:
 | |
| 			countWarnings++
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return §ion{
 | |
| 		Total:    len(routers),
 | |
| 		Warnings: countWarnings,
 | |
| 		Errors:   countErrors,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func getTCPServiceSection(services map[string]*runtime.TCPServiceInfo) *section {
 | |
| 	var countErrors int
 | |
| 	var countWarnings int
 | |
| 	for _, svc := range services {
 | |
| 		switch svc.Status {
 | |
| 		case runtime.StatusDisabled:
 | |
| 			countErrors++
 | |
| 		case runtime.StatusWarning:
 | |
| 			countWarnings++
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return §ion{
 | |
| 		Total:    len(services),
 | |
| 		Warnings: countWarnings,
 | |
| 		Errors:   countErrors,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func getTCPMiddlewareSection(middlewares map[string]*runtime.TCPMiddlewareInfo) *section {
 | |
| 	var countErrors int
 | |
| 	var countWarnings int
 | |
| 	for _, mid := range middlewares {
 | |
| 		switch mid.Status {
 | |
| 		case runtime.StatusDisabled:
 | |
| 			countErrors++
 | |
| 		case runtime.StatusWarning:
 | |
| 			countWarnings++
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return §ion{
 | |
| 		Total:    len(middlewares),
 | |
| 		Warnings: countWarnings,
 | |
| 		Errors:   countErrors,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func getUDPRouterSection(routers map[string]*runtime.UDPRouterInfo) *section {
 | |
| 	var countErrors int
 | |
| 	var countWarnings int
 | |
| 	for _, rt := range routers {
 | |
| 		switch rt.Status {
 | |
| 		case runtime.StatusDisabled:
 | |
| 			countErrors++
 | |
| 		case runtime.StatusWarning:
 | |
| 			countWarnings++
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return §ion{
 | |
| 		Total:    len(routers),
 | |
| 		Warnings: countWarnings,
 | |
| 		Errors:   countErrors,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func getUDPServiceSection(services map[string]*runtime.UDPServiceInfo) *section {
 | |
| 	var countErrors int
 | |
| 	var countWarnings int
 | |
| 	for _, svc := range services {
 | |
| 		switch svc.Status {
 | |
| 		case runtime.StatusDisabled:
 | |
| 			countErrors++
 | |
| 		case runtime.StatusWarning:
 | |
| 			countWarnings++
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return §ion{
 | |
| 		Total:    len(services),
 | |
| 		Warnings: countWarnings,
 | |
| 		Errors:   countErrors,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func getProviders(conf static.Configuration) []string {
 | |
| 	if conf.Providers == nil {
 | |
| 		return nil
 | |
| 	}
 | |
| 
 | |
| 	var providers []string
 | |
| 
 | |
| 	v := reflect.ValueOf(conf.Providers).Elem()
 | |
| 	for i := range v.NumField() {
 | |
| 		field := v.Field(i)
 | |
| 		if field.Kind() == reflect.Ptr && field.Elem().Kind() == reflect.Struct {
 | |
| 			if !field.IsNil() {
 | |
| 				providers = append(providers, v.Type().Field(i).Name)
 | |
| 			}
 | |
| 		} else if field.Kind() == reflect.Map && field.Type().Elem() == reflect.TypeOf(static.PluginConf{}) {
 | |
| 			for _, value := range field.MapKeys() {
 | |
| 				providers = append(providers, "plugin-"+value.String())
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return providers
 | |
| }
 | |
| 
 | |
| func getFeatures(conf static.Configuration) features {
 | |
| 	return features{
 | |
| 		Tracing:   getTracing(conf),
 | |
| 		Metrics:   getMetrics(conf),
 | |
| 		AccessLog: conf.AccessLog != nil,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func getMetrics(conf static.Configuration) string {
 | |
| 	if conf.Metrics == nil {
 | |
| 		return ""
 | |
| 	}
 | |
| 
 | |
| 	v := reflect.ValueOf(conf.Metrics).Elem()
 | |
| 	for i := range v.NumField() {
 | |
| 		field := v.Field(i)
 | |
| 		if field.Kind() == reflect.Ptr && field.Elem().Kind() == reflect.Struct {
 | |
| 			if !field.IsNil() {
 | |
| 				return v.Type().Field(i).Name
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return ""
 | |
| }
 | |
| 
 | |
| func getTracing(conf static.Configuration) string {
 | |
| 	if conf.Tracing == nil {
 | |
| 		return ""
 | |
| 	}
 | |
| 
 | |
| 	v := reflect.ValueOf(conf.Tracing).Elem()
 | |
| 	for i := range v.NumField() {
 | |
| 		field := v.Field(i)
 | |
| 		if field.Kind() == reflect.Ptr && field.Elem().Kind() == reflect.Struct {
 | |
| 			if !field.IsNil() {
 | |
| 				return v.Type().Field(i).Name
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return ""
 | |
| }
 |