2019-07-12 12:10:03 +03:00
package api
import (
"encoding/json"
2019-09-02 12:38:04 +03:00
"fmt"
2019-07-12 12:10:03 +03:00
"net/http"
2024-01-25 11:56:05 +03:00
"net/url"
2019-07-12 12:10:03 +03:00
"sort"
"strconv"
2019-09-02 12:38:04 +03:00
"strings"
2019-07-12 12:10:03 +03:00
2019-08-03 04:58:23 +03:00
"github.com/gorilla/mux"
2020-09-16 16:46:04 +03:00
"github.com/traefik/traefik/v2/pkg/config/runtime"
"github.com/traefik/traefik/v2/pkg/log"
2019-07-12 12:10:03 +03:00
)
type tcpRouterRepresentation struct {
2019-07-15 18:04:04 +03:00
* runtime . TCPRouterInfo
2019-07-12 12:10:03 +03:00
Name string ` json:"name,omitempty" `
Provider string ` json:"provider,omitempty" `
}
2019-09-02 12:38:04 +03:00
func newTCPRouterRepresentation ( name string , rt * runtime . TCPRouterInfo ) tcpRouterRepresentation {
return tcpRouterRepresentation {
TCPRouterInfo : rt ,
Name : name ,
Provider : getProviderName ( name ) ,
}
}
2019-07-12 12:10:03 +03:00
type tcpServiceRepresentation struct {
2019-07-15 18:04:04 +03:00
* runtime . TCPServiceInfo
2019-07-12 12:10:03 +03:00
Name string ` json:"name,omitempty" `
Provider string ` json:"provider,omitempty" `
2019-09-02 12:38:04 +03:00
Type string ` json:"type,omitempty" `
}
func newTCPServiceRepresentation ( name string , si * runtime . TCPServiceInfo ) tcpServiceRepresentation {
return tcpServiceRepresentation {
TCPServiceInfo : si ,
Name : name ,
Provider : getProviderName ( name ) ,
Type : strings . ToLower ( extractType ( si . TCPService ) ) ,
}
2019-07-12 12:10:03 +03:00
}
2021-06-11 16:30:05 +03:00
type tcpMiddlewareRepresentation struct {
* runtime . TCPMiddlewareInfo
Name string ` json:"name,omitempty" `
Provider string ` json:"provider,omitempty" `
Type string ` json:"type,omitempty" `
}
func newTCPMiddlewareRepresentation ( name string , mi * runtime . TCPMiddlewareInfo ) tcpMiddlewareRepresentation {
return tcpMiddlewareRepresentation {
TCPMiddlewareInfo : mi ,
Name : name ,
Provider : getProviderName ( name ) ,
Type : strings . ToLower ( extractType ( mi . TCPMiddleware ) ) ,
}
}
2019-07-12 12:10:03 +03:00
func ( h Handler ) getTCPRouters ( rw http . ResponseWriter , request * http . Request ) {
results := make ( [ ] tcpRouterRepresentation , 0 , len ( h . runtimeConfiguration . TCPRouters ) )
2019-09-02 12:38:04 +03:00
criterion := newSearchCriterion ( request . URL . Query ( ) )
2019-07-12 12:10:03 +03:00
for name , rt := range h . runtimeConfiguration . TCPRouters {
2019-09-02 12:38:04 +03:00
if keepTCPRouter ( name , rt , criterion ) {
results = append ( results , newTCPRouterRepresentation ( name , rt ) )
}
2019-07-12 12:10:03 +03:00
}
sort . Slice ( results , func ( i , j int ) bool {
return results [ i ] . Name < results [ j ] . Name
} )
2019-09-02 12:38:04 +03:00
rw . Header ( ) . Set ( "Content-Type" , "application/json" )
2019-07-12 12:10:03 +03:00
pageInfo , err := pagination ( request , len ( results ) )
if err != nil {
2019-09-02 12:38:04 +03:00
writeError ( rw , err . Error ( ) , http . StatusBadRequest )
2019-07-12 12:10:03 +03:00
return
}
rw . Header ( ) . Set ( nextPageHeader , strconv . Itoa ( pageInfo . nextPage ) )
err = json . NewEncoder ( rw ) . Encode ( results [ pageInfo . startIndex : pageInfo . endIndex ] )
if err != nil {
log . FromContext ( request . Context ( ) ) . Error ( err )
2019-09-02 12:38:04 +03:00
writeError ( rw , err . Error ( ) , http . StatusInternalServerError )
2019-07-12 12:10:03 +03:00
}
}
func ( h Handler ) getTCPRouter ( rw http . ResponseWriter , request * http . Request ) {
2024-01-25 11:56:05 +03:00
scapedRouterID := mux . Vars ( request ) [ "routerID" ]
routerID , err := url . PathUnescape ( scapedRouterID )
if err != nil {
writeError ( rw , fmt . Sprintf ( "unable to decode routerID %q: %s" , scapedRouterID , err ) , http . StatusBadRequest )
return
}
2019-07-12 12:10:03 +03:00
2019-09-02 12:38:04 +03:00
rw . Header ( ) . Set ( "Content-Type" , "application/json" )
2019-07-12 12:10:03 +03:00
router , ok := h . runtimeConfiguration . TCPRouters [ routerID ]
if ! ok {
2019-09-02 12:38:04 +03:00
writeError ( rw , fmt . Sprintf ( "router not found: %s" , routerID ) , http . StatusNotFound )
2019-07-12 12:10:03 +03:00
return
}
2019-09-02 12:38:04 +03:00
result := newTCPRouterRepresentation ( routerID , router )
2019-07-12 12:10:03 +03:00
2024-01-25 11:56:05 +03:00
err = json . NewEncoder ( rw ) . Encode ( result )
2019-07-12 12:10:03 +03:00
if err != nil {
log . FromContext ( request . Context ( ) ) . Error ( err )
2019-09-02 12:38:04 +03:00
writeError ( rw , err . Error ( ) , http . StatusInternalServerError )
2019-07-12 12:10:03 +03:00
}
}
func ( h Handler ) getTCPServices ( rw http . ResponseWriter , request * http . Request ) {
results := make ( [ ] tcpServiceRepresentation , 0 , len ( h . runtimeConfiguration . TCPServices ) )
2019-09-02 12:38:04 +03:00
criterion := newSearchCriterion ( request . URL . Query ( ) )
2019-07-12 12:10:03 +03:00
for name , si := range h . runtimeConfiguration . TCPServices {
2019-09-02 12:38:04 +03:00
if keepTCPService ( name , si , criterion ) {
results = append ( results , newTCPServiceRepresentation ( name , si ) )
}
2019-07-12 12:10:03 +03:00
}
sort . Slice ( results , func ( i , j int ) bool {
return results [ i ] . Name < results [ j ] . Name
} )
2019-09-02 12:38:04 +03:00
rw . Header ( ) . Set ( "Content-Type" , "application/json" )
2019-07-12 12:10:03 +03:00
pageInfo , err := pagination ( request , len ( results ) )
if err != nil {
2019-09-02 12:38:04 +03:00
writeError ( rw , err . Error ( ) , http . StatusBadRequest )
2019-07-12 12:10:03 +03:00
return
}
rw . Header ( ) . Set ( nextPageHeader , strconv . Itoa ( pageInfo . nextPage ) )
err = json . NewEncoder ( rw ) . Encode ( results [ pageInfo . startIndex : pageInfo . endIndex ] )
if err != nil {
log . FromContext ( request . Context ( ) ) . Error ( err )
2019-09-02 12:38:04 +03:00
writeError ( rw , err . Error ( ) , http . StatusInternalServerError )
2019-07-12 12:10:03 +03:00
}
}
func ( h Handler ) getTCPService ( rw http . ResponseWriter , request * http . Request ) {
2024-01-25 11:56:05 +03:00
scapedServiceID := mux . Vars ( request ) [ "serviceID" ]
serviceID , err := url . PathUnescape ( scapedServiceID )
if err != nil {
writeError ( rw , fmt . Sprintf ( "unable to decode serviceID %q: %s" , scapedServiceID , err ) , http . StatusBadRequest )
return
}
2019-07-12 12:10:03 +03:00
2019-09-02 12:38:04 +03:00
rw . Header ( ) . Set ( "Content-Type" , "application/json" )
2019-07-12 12:10:03 +03:00
service , ok := h . runtimeConfiguration . TCPServices [ serviceID ]
if ! ok {
2019-09-02 12:38:04 +03:00
writeError ( rw , fmt . Sprintf ( "service not found: %s" , serviceID ) , http . StatusNotFound )
2019-07-12 12:10:03 +03:00
return
}
2019-09-02 12:38:04 +03:00
result := newTCPServiceRepresentation ( serviceID , service )
2019-07-12 12:10:03 +03:00
2024-01-25 11:56:05 +03:00
err = json . NewEncoder ( rw ) . Encode ( result )
2019-07-12 12:10:03 +03:00
if err != nil {
log . FromContext ( request . Context ( ) ) . Error ( err )
2019-09-02 12:38:04 +03:00
writeError ( rw , err . Error ( ) , http . StatusInternalServerError )
2019-07-12 12:10:03 +03:00
}
}
2019-09-02 12:38:04 +03:00
2021-06-11 16:30:05 +03:00
func ( h Handler ) getTCPMiddlewares ( rw http . ResponseWriter , request * http . Request ) {
results := make ( [ ] tcpMiddlewareRepresentation , 0 , len ( h . runtimeConfiguration . Middlewares ) )
criterion := newSearchCriterion ( request . URL . Query ( ) )
for name , mi := range h . runtimeConfiguration . TCPMiddlewares {
if keepTCPMiddleware ( name , mi , criterion ) {
results = append ( results , newTCPMiddlewareRepresentation ( name , mi ) )
}
}
sort . Slice ( results , func ( i , j int ) bool {
return results [ i ] . Name < results [ j ] . Name
} )
rw . Header ( ) . Set ( "Content-Type" , "application/json" )
pageInfo , err := pagination ( request , len ( results ) )
if err != nil {
writeError ( rw , err . Error ( ) , http . StatusBadRequest )
return
}
rw . Header ( ) . Set ( nextPageHeader , strconv . Itoa ( pageInfo . nextPage ) )
err = json . NewEncoder ( rw ) . Encode ( results [ pageInfo . startIndex : pageInfo . endIndex ] )
if err != nil {
log . FromContext ( request . Context ( ) ) . Error ( err )
writeError ( rw , err . Error ( ) , http . StatusInternalServerError )
}
}
func ( h Handler ) getTCPMiddleware ( rw http . ResponseWriter , request * http . Request ) {
2024-01-25 11:56:05 +03:00
scapedMiddlewareID := mux . Vars ( request ) [ "middlewareID" ]
middlewareID , err := url . PathUnescape ( scapedMiddlewareID )
if err != nil {
writeError ( rw , fmt . Sprintf ( "unable to decode middlewareID %q: %s" , scapedMiddlewareID , err ) , http . StatusBadRequest )
return
}
2021-06-11 16:30:05 +03:00
rw . Header ( ) . Set ( "Content-Type" , "application/json" )
middleware , ok := h . runtimeConfiguration . TCPMiddlewares [ middlewareID ]
if ! ok {
writeError ( rw , fmt . Sprintf ( "middleware not found: %s" , middlewareID ) , http . StatusNotFound )
return
}
result := newTCPMiddlewareRepresentation ( middlewareID , middleware )
2024-01-25 11:56:05 +03:00
err = json . NewEncoder ( rw ) . Encode ( result )
2021-06-11 16:30:05 +03:00
if err != nil {
log . FromContext ( request . Context ( ) ) . Error ( err )
writeError ( rw , err . Error ( ) , http . StatusInternalServerError )
}
}
2019-09-02 12:38:04 +03:00
func keepTCPRouter ( name string , item * runtime . TCPRouterInfo , criterion * searchCriterion ) bool {
if criterion == nil {
return true
}
return criterion . withStatus ( item . Status ) && criterion . searchIn ( item . Rule , name )
}
func keepTCPService ( name string , item * runtime . TCPServiceInfo , criterion * searchCriterion ) bool {
if criterion == nil {
return true
}
return criterion . withStatus ( item . Status ) && criterion . searchIn ( name )
}
2021-06-11 16:30:05 +03:00
func keepTCPMiddleware ( name string , item * runtime . TCPMiddlewareInfo , criterion * searchCriterion ) bool {
if criterion == nil {
return true
}
return criterion . withStatus ( item . Status ) && criterion . searchIn ( name )
}