2019-07-12 11:10:03 +02:00
package api
import (
2019-09-02 11:38:04 +02:00
"context"
2019-07-12 11:10:03 +02:00
"encoding/json"
"fmt"
2021-03-04 20:08:03 +01:00
"io"
2019-07-12 11:10:03 +02:00
"net/http"
"net/http/httptest"
2024-01-25 10:56:05 +02:00
"net/url"
2021-03-04 20:08:03 +01:00
"os"
2019-07-12 11:10:03 +02:00
"strconv"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
2020-09-16 15:46:04 +02:00
"github.com/traefik/traefik/v2/pkg/config/dynamic"
"github.com/traefik/traefik/v2/pkg/config/runtime"
"github.com/traefik/traefik/v2/pkg/config/static"
2019-07-12 11:10:03 +02:00
)
2019-09-30 18:12:04 +02:00
func Bool ( v bool ) * bool { return & v }
2019-07-12 11:10:03 +02:00
func TestHandler_HTTP ( t * testing . T ) {
type expected struct {
statusCode int
nextPage string
jsonFile string
}
testCases := [ ] struct {
desc string
path string
2019-07-15 17:04:04 +02:00
conf runtime . Configuration
2019-07-12 11:10:03 +02:00
expected expected
} {
{
desc : "all routers, but no config" ,
path : "/api/http/routers" ,
2019-07-15 17:04:04 +02:00
conf : runtime . Configuration { } ,
2019-07-12 11:10:03 +02:00
expected : expected {
statusCode : http . StatusOK ,
nextPage : "1" ,
jsonFile : "testdata/routers-empty.json" ,
} ,
} ,
{
desc : "all routers" ,
path : "/api/http/routers" ,
2019-07-15 17:04:04 +02:00
conf : runtime . Configuration {
Routers : map [ string ] * runtime . RouterInfo {
2019-07-12 11:10:03 +02:00
"test@myprovider" : {
Router : & dynamic . Router {
EntryPoints : [ ] string { "web" } ,
Service : "foo-service@myprovider" ,
Rule : "Host(`foo.bar.other`)" ,
Middlewares : [ ] string { "addPrefixTest" , "auth" } ,
} ,
} ,
"bar@myprovider" : {
Router : & dynamic . Router {
EntryPoints : [ ] string { "web" } ,
Service : "foo-service@myprovider" ,
Rule : "Host(`foo.bar`)" ,
Middlewares : [ ] string { "auth" , "addPrefixTest@anotherprovider" } ,
} ,
} ,
} ,
} ,
expected : expected {
statusCode : http . StatusOK ,
nextPage : "1" ,
jsonFile : "testdata/routers.json" ,
} ,
} ,
{
desc : "all routers, pagination, 1 res per page, want page 2" ,
path : "/api/http/routers?page=2&per_page=1" ,
2019-07-15 17:04:04 +02:00
conf : runtime . Configuration {
Routers : map [ string ] * runtime . RouterInfo {
2019-07-12 11:10:03 +02:00
"bar@myprovider" : {
Router : & dynamic . Router {
EntryPoints : [ ] string { "web" } ,
Service : "foo-service@myprovider" ,
Rule : "Host(`foo.bar`)" ,
Middlewares : [ ] string { "auth" , "addPrefixTest@anotherprovider" } ,
} ,
} ,
"baz@myprovider" : {
Router : & dynamic . Router {
EntryPoints : [ ] string { "web" } ,
Service : "foo-service@myprovider" ,
Rule : "Host(`toto.bar`)" ,
} ,
} ,
"test@myprovider" : {
Router : & dynamic . Router {
EntryPoints : [ ] string { "web" } ,
Service : "foo-service@myprovider" ,
Rule : "Host(`foo.bar.other`)" ,
Middlewares : [ ] string { "addPrefixTest" , "auth" } ,
} ,
} ,
} ,
} ,
expected : expected {
statusCode : http . StatusOK ,
nextPage : "3" ,
jsonFile : "testdata/routers-page2.json" ,
} ,
} ,
{
desc : "all routers, pagination, 19 results overall, 7 res per page, want page 3" ,
path : "/api/http/routers?page=3&per_page=7" ,
2019-07-15 17:04:04 +02:00
conf : runtime . Configuration {
2019-07-12 11:10:03 +02:00
Routers : generateHTTPRouters ( 19 ) ,
} ,
expected : expected {
statusCode : http . StatusOK ,
nextPage : "1" ,
jsonFile : "testdata/routers-many-lastpage.json" ,
} ,
} ,
{
desc : "all routers, pagination, 5 results overall, 10 res per page, want page 2" ,
path : "/api/http/routers?page=2&per_page=10" ,
2019-07-15 17:04:04 +02:00
conf : runtime . Configuration {
2019-07-12 11:10:03 +02:00
Routers : generateHTTPRouters ( 5 ) ,
} ,
expected : expected {
statusCode : http . StatusBadRequest ,
} ,
} ,
{
desc : "all routers, pagination, 10 results overall, 10 res per page, want page 2" ,
path : "/api/http/routers?page=2&per_page=10" ,
2019-07-15 17:04:04 +02:00
conf : runtime . Configuration {
2019-07-12 11:10:03 +02:00
Routers : generateHTTPRouters ( 10 ) ,
} ,
expected : expected {
statusCode : http . StatusBadRequest ,
} ,
} ,
2019-09-02 11:38:04 +02:00
{
desc : "routers filtered by status" ,
path : "/api/http/routers?status=enabled" ,
conf : runtime . Configuration {
Routers : map [ string ] * runtime . RouterInfo {
"test@myprovider" : {
Router : & dynamic . Router {
EntryPoints : [ ] string { "web" } ,
Service : "foo-service@myprovider" ,
Rule : "Host(`foo.bar.other`)" ,
Middlewares : [ ] string { "addPrefixTest" , "auth" } ,
} ,
Status : runtime . StatusEnabled ,
} ,
"bar@myprovider" : {
Router : & dynamic . Router {
EntryPoints : [ ] string { "web" } ,
Service : "foo-service@myprovider" ,
Rule : "Host(`foo.bar`)" ,
Middlewares : [ ] string { "auth" , "addPrefixTest@anotherprovider" } ,
} ,
Status : runtime . StatusDisabled ,
} ,
} ,
} ,
expected : expected {
statusCode : http . StatusOK ,
nextPage : "1" ,
jsonFile : "testdata/routers-filtered-status.json" ,
} ,
} ,
{
desc : "routers filtered by search" ,
path : "/api/http/routers?search=fii" ,
conf : runtime . Configuration {
Routers : map [ string ] * runtime . RouterInfo {
"test@myprovider" : {
Router : & dynamic . Router {
EntryPoints : [ ] string { "web" } ,
Service : "fii-service@myprovider" ,
Rule : "Host(`fii.bar.other`)" ,
Middlewares : [ ] string { "addPrefixTest" , "auth" } ,
} ,
Status : runtime . StatusEnabled ,
} ,
"bar@myprovider" : {
Router : & dynamic . Router {
EntryPoints : [ ] string { "web" } ,
Service : "foo-service@myprovider" ,
Rule : "Host(`foo.bar`)" ,
Middlewares : [ ] string { "auth" , "addPrefixTest@anotherprovider" } ,
} ,
Status : runtime . StatusDisabled ,
} ,
} ,
} ,
expected : expected {
statusCode : http . StatusOK ,
nextPage : "1" ,
jsonFile : "testdata/routers-filtered-search.json" ,
} ,
} ,
2019-07-12 11:10:03 +02:00
{
desc : "one router by id" ,
path : "/api/http/routers/bar@myprovider" ,
2019-07-15 17:04:04 +02:00
conf : runtime . Configuration {
Routers : map [ string ] * runtime . RouterInfo {
2019-07-12 11:10:03 +02:00
"bar@myprovider" : {
Router : & dynamic . Router {
EntryPoints : [ ] string { "web" } ,
Service : "foo-service@myprovider" ,
Rule : "Host(`foo.bar`)" ,
Middlewares : [ ] string { "auth" , "addPrefixTest@anotherprovider" } ,
} ,
2019-07-15 17:04:04 +02:00
Status : "enabled" ,
2019-07-12 11:10:03 +02:00
} ,
} ,
} ,
expected : expected {
statusCode : http . StatusOK ,
jsonFile : "testdata/router-bar.json" ,
} ,
} ,
2024-01-25 10:56:05 +02:00
{
desc : "one router by id containing slash" ,
path : "/api/http/routers/" + url . PathEscape ( "foo / bar@myprovider" ) ,
conf : runtime . Configuration {
Routers : map [ string ] * runtime . RouterInfo {
"foo / bar@myprovider" : {
Router : & dynamic . Router {
EntryPoints : [ ] string { "web" } ,
Service : "foo-service@myprovider" ,
Rule : "Host(`foo.bar`)" ,
Middlewares : [ ] string { "auth" , "addPrefixTest@anotherprovider" } ,
} ,
Status : "enabled" ,
} ,
} ,
} ,
expected : expected {
statusCode : http . StatusOK ,
jsonFile : "testdata/router-foo-slash-bar.json" ,
} ,
} ,
2022-09-09 12:46:09 +02:00
{
desc : "one router by id, implicitly using default TLS options" ,
path : "/api/http/routers/baz@myprovider" ,
conf : runtime . Configuration {
Routers : map [ string ] * runtime . RouterInfo {
"baz@myprovider" : {
Router : & dynamic . Router {
EntryPoints : [ ] string { "web" } ,
Service : "foo-service@myprovider" ,
Rule : "Host(`foo.baz`)" ,
Middlewares : [ ] string { "auth" , "addPrefixTest@anotherprovider" } ,
TLS : & dynamic . RouterTLSConfig { } ,
} ,
Status : "enabled" ,
} ,
} ,
} ,
expected : expected {
statusCode : http . StatusOK ,
jsonFile : "testdata/router-baz-default-tls-options.json" ,
} ,
} ,
{
desc : "one router by id, using specific TLS options" ,
path : "/api/http/routers/baz@myprovider" ,
conf : runtime . Configuration {
Routers : map [ string ] * runtime . RouterInfo {
"baz@myprovider" : {
Router : & dynamic . Router {
EntryPoints : [ ] string { "web" } ,
Service : "foo-service@myprovider" ,
Rule : "Host(`foo.baz`)" ,
Middlewares : [ ] string { "auth" , "addPrefixTest@anotherprovider" } ,
TLS : & dynamic . RouterTLSConfig {
Options : "myTLS" ,
} ,
} ,
Status : "enabled" ,
} ,
} ,
} ,
expected : expected {
statusCode : http . StatusOK ,
jsonFile : "testdata/router-baz-custom-tls-options.json" ,
} ,
} ,
2019-07-12 11:10:03 +02:00
{
desc : "one router by id, that does not exist" ,
path : "/api/http/routers/foo@myprovider" ,
2019-07-15 17:04:04 +02:00
conf : runtime . Configuration {
Routers : map [ string ] * runtime . RouterInfo {
2019-07-12 11:10:03 +02:00
"bar@myprovider" : {
Router : & dynamic . Router {
EntryPoints : [ ] string { "web" } ,
Service : "foo-service@myprovider" ,
Rule : "Host(`foo.bar`)" ,
Middlewares : [ ] string { "auth" , "addPrefixTest@anotherprovider" } ,
} ,
} ,
} ,
} ,
expected : expected {
statusCode : http . StatusNotFound ,
} ,
} ,
{
desc : "one router by id, but no config" ,
path : "/api/http/routers/foo@myprovider" ,
2019-07-15 17:04:04 +02:00
conf : runtime . Configuration { } ,
2019-07-12 11:10:03 +02:00
expected : expected {
statusCode : http . StatusNotFound ,
} ,
} ,
{
desc : "all services, but no config" ,
path : "/api/http/services" ,
2019-07-15 17:04:04 +02:00
conf : runtime . Configuration { } ,
2019-07-12 11:10:03 +02:00
expected : expected {
statusCode : http . StatusOK ,
nextPage : "1" ,
jsonFile : "testdata/services-empty.json" ,
} ,
} ,
{
desc : "all services" ,
path : "/api/http/services" ,
2019-07-15 17:04:04 +02:00
conf : runtime . Configuration {
Services : map [ string ] * runtime . ServiceInfo {
"bar@myprovider" : func ( ) * runtime . ServiceInfo {
si := & runtime . ServiceInfo {
2019-07-12 11:10:03 +02:00
Service : & dynamic . Service {
2019-08-26 10:30:05 +02:00
LoadBalancer : & dynamic . ServersLoadBalancer {
2019-09-30 18:12:04 +02:00
PassHostHeader : Bool ( true ) ,
2019-07-12 11:10:03 +02:00
Servers : [ ] dynamic . Server {
{
URL : "http://127.0.0.1" ,
} ,
} ,
} ,
} ,
UsedBy : [ ] string { "foo@myprovider" , "test@myprovider" } ,
}
2019-07-15 17:04:04 +02:00
si . UpdateServerStatus ( "http://127.0.0.1" , "UP" )
2019-07-12 11:10:03 +02:00
return si
} ( ) ,
2019-07-15 17:04:04 +02:00
"baz@myprovider" : func ( ) * runtime . ServiceInfo {
si := & runtime . ServiceInfo {
2019-07-12 11:10:03 +02:00
Service : & dynamic . Service {
2019-08-26 10:30:05 +02:00
LoadBalancer : & dynamic . ServersLoadBalancer {
2019-09-30 18:12:04 +02:00
PassHostHeader : Bool ( true ) ,
2019-07-12 11:10:03 +02:00
Servers : [ ] dynamic . Server {
{
URL : "http://127.0.0.2" ,
} ,
} ,
} ,
} ,
UsedBy : [ ] string { "foo@myprovider" } ,
}
2019-07-15 17:04:04 +02:00
si . UpdateServerStatus ( "http://127.0.0.2" , "UP" )
2019-07-12 11:10:03 +02:00
return si
} ( ) ,
2019-09-02 11:38:04 +02:00
"canary@myprovider" : {
Service : & dynamic . Service {
Weighted : & dynamic . WeightedRoundRobin {
Services : nil ,
Sticky : & dynamic . Sticky {
Cookie : & dynamic . Cookie {
Name : "chocolat" ,
Secure : true ,
HTTPOnly : true ,
} ,
} ,
} ,
} ,
Status : runtime . StatusEnabled ,
UsedBy : [ ] string { "foo@myprovider" } ,
} ,
"mirror@myprovider" : {
Service : & dynamic . Service {
Mirroring : & dynamic . Mirroring {
Service : "one@myprovider" ,
Mirrors : [ ] dynamic . MirrorService {
{
Name : "two@myprovider" ,
Percent : 10 ,
} ,
{
Name : "three@myprovider" ,
Percent : 15 ,
} ,
{
Name : "four@myprovider" ,
Percent : 80 ,
} ,
} ,
} ,
} ,
Status : runtime . StatusEnabled ,
UsedBy : [ ] string { "foo@myprovider" } ,
} ,
2019-07-12 11:10:03 +02:00
} ,
} ,
expected : expected {
statusCode : http . StatusOK ,
nextPage : "1" ,
jsonFile : "testdata/services.json" ,
} ,
} ,
{
desc : "all services, 1 res per page, want page 2" ,
path : "/api/http/services?page=2&per_page=1" ,
2019-07-15 17:04:04 +02:00
conf : runtime . Configuration {
Services : map [ string ] * runtime . ServiceInfo {
"bar@myprovider" : func ( ) * runtime . ServiceInfo {
si := & runtime . ServiceInfo {
2019-07-12 11:10:03 +02:00
Service : & dynamic . Service {
2019-08-26 10:30:05 +02:00
LoadBalancer : & dynamic . ServersLoadBalancer {
2019-09-30 18:12:04 +02:00
PassHostHeader : Bool ( true ) ,
2019-07-12 11:10:03 +02:00
Servers : [ ] dynamic . Server {
{
URL : "http://127.0.0.1" ,
} ,
} ,
} ,
} ,
UsedBy : [ ] string { "foo@myprovider" , "test@myprovider" } ,
}
2019-07-15 17:04:04 +02:00
si . UpdateServerStatus ( "http://127.0.0.1" , "UP" )
2019-07-12 11:10:03 +02:00
return si
} ( ) ,
2019-07-15 17:04:04 +02:00
"baz@myprovider" : func ( ) * runtime . ServiceInfo {
si := & runtime . ServiceInfo {
2019-07-12 11:10:03 +02:00
Service : & dynamic . Service {
2019-08-26 10:30:05 +02:00
LoadBalancer : & dynamic . ServersLoadBalancer {
2019-09-30 18:12:04 +02:00
PassHostHeader : Bool ( true ) ,
2019-07-12 11:10:03 +02:00
Servers : [ ] dynamic . Server {
{
URL : "http://127.0.0.2" ,
} ,
} ,
} ,
} ,
UsedBy : [ ] string { "foo@myprovider" } ,
}
2019-07-15 17:04:04 +02:00
si . UpdateServerStatus ( "http://127.0.0.2" , "UP" )
2019-07-12 11:10:03 +02:00
return si
} ( ) ,
2019-07-15 17:04:04 +02:00
"test@myprovider" : func ( ) * runtime . ServiceInfo {
si := & runtime . ServiceInfo {
2019-07-12 11:10:03 +02:00
Service : & dynamic . Service {
2019-08-26 10:30:05 +02:00
LoadBalancer : & dynamic . ServersLoadBalancer {
2019-09-30 18:12:04 +02:00
PassHostHeader : Bool ( true ) ,
2019-07-12 11:10:03 +02:00
Servers : [ ] dynamic . Server {
{
URL : "http://127.0.0.3" ,
} ,
} ,
} ,
} ,
UsedBy : [ ] string { "foo@myprovider" , "test@myprovider" } ,
}
2019-07-15 17:04:04 +02:00
si . UpdateServerStatus ( "http://127.0.0.4" , "UP" )
2019-07-12 11:10:03 +02:00
return si
} ( ) ,
} ,
} ,
expected : expected {
statusCode : http . StatusOK ,
nextPage : "3" ,
jsonFile : "testdata/services-page2.json" ,
} ,
} ,
2019-09-02 11:38:04 +02:00
{
desc : "services filtered by status" ,
path : "/api/http/services?status=enabled" ,
conf : runtime . Configuration {
Services : map [ string ] * runtime . ServiceInfo {
"bar@myprovider" : func ( ) * runtime . ServiceInfo {
si := & runtime . ServiceInfo {
Service : & dynamic . Service {
LoadBalancer : & dynamic . ServersLoadBalancer {
2019-09-30 18:12:04 +02:00
PassHostHeader : Bool ( true ) ,
2019-09-02 11:38:04 +02:00
Servers : [ ] dynamic . Server {
{
URL : "http://127.0.0.1" ,
} ,
} ,
} ,
} ,
UsedBy : [ ] string { "foo@myprovider" , "test@myprovider" } ,
Status : runtime . StatusEnabled ,
}
si . UpdateServerStatus ( "http://127.0.0.1" , "UP" )
return si
} ( ) ,
"baz@myprovider" : func ( ) * runtime . ServiceInfo {
si := & runtime . ServiceInfo {
Service : & dynamic . Service {
LoadBalancer : & dynamic . ServersLoadBalancer {
2019-09-30 18:12:04 +02:00
PassHostHeader : Bool ( true ) ,
2019-09-02 11:38:04 +02:00
Servers : [ ] dynamic . Server {
{
URL : "http://127.0.0.2" ,
} ,
} ,
} ,
} ,
UsedBy : [ ] string { "foo@myprovider" } ,
Status : runtime . StatusDisabled ,
}
si . UpdateServerStatus ( "http://127.0.0.2" , "UP" )
return si
} ( ) ,
} ,
} ,
expected : expected {
statusCode : http . StatusOK ,
nextPage : "1" ,
jsonFile : "testdata/services-filtered-status.json" ,
} ,
} ,
{
desc : "services filtered by search" ,
path : "/api/http/services?search=baz" ,
conf : runtime . Configuration {
Services : map [ string ] * runtime . ServiceInfo {
"bar@myprovider" : func ( ) * runtime . ServiceInfo {
si := & runtime . ServiceInfo {
Service : & dynamic . Service {
LoadBalancer : & dynamic . ServersLoadBalancer {
2019-09-30 18:12:04 +02:00
PassHostHeader : Bool ( true ) ,
2019-09-02 11:38:04 +02:00
Servers : [ ] dynamic . Server {
{
URL : "http://127.0.0.1" ,
} ,
} ,
} ,
} ,
UsedBy : [ ] string { "foo@myprovider" , "test@myprovider" } ,
Status : runtime . StatusEnabled ,
}
si . UpdateServerStatus ( "http://127.0.0.1" , "UP" )
return si
} ( ) ,
"baz@myprovider" : func ( ) * runtime . ServiceInfo {
si := & runtime . ServiceInfo {
Service : & dynamic . Service {
LoadBalancer : & dynamic . ServersLoadBalancer {
2019-09-30 18:12:04 +02:00
PassHostHeader : Bool ( true ) ,
2019-09-02 11:38:04 +02:00
Servers : [ ] dynamic . Server {
{
URL : "http://127.0.0.2" ,
} ,
} ,
} ,
} ,
UsedBy : [ ] string { "foo@myprovider" } ,
Status : runtime . StatusDisabled ,
}
si . UpdateServerStatus ( "http://127.0.0.2" , "UP" )
return si
} ( ) ,
} ,
} ,
expected : expected {
statusCode : http . StatusOK ,
nextPage : "1" ,
jsonFile : "testdata/services-filtered-search.json" ,
} ,
} ,
2019-07-12 11:10:03 +02:00
{
desc : "one service by id" ,
path : "/api/http/services/bar@myprovider" ,
2019-07-15 17:04:04 +02:00
conf : runtime . Configuration {
Services : map [ string ] * runtime . ServiceInfo {
"bar@myprovider" : func ( ) * runtime . ServiceInfo {
si := & runtime . ServiceInfo {
2019-07-12 11:10:03 +02:00
Service : & dynamic . Service {
2019-08-26 10:30:05 +02:00
LoadBalancer : & dynamic . ServersLoadBalancer {
2019-09-30 18:12:04 +02:00
PassHostHeader : Bool ( true ) ,
2019-07-12 11:10:03 +02:00
Servers : [ ] dynamic . Server {
{
URL : "http://127.0.0.1" ,
} ,
} ,
} ,
} ,
UsedBy : [ ] string { "foo@myprovider" , "test@myprovider" } ,
}
2019-07-15 17:04:04 +02:00
si . UpdateServerStatus ( "http://127.0.0.1" , "UP" )
2019-07-12 11:10:03 +02:00
return si
} ( ) ,
} ,
} ,
expected : expected {
statusCode : http . StatusOK ,
jsonFile : "testdata/service-bar.json" ,
} ,
} ,
2024-01-25 10:56:05 +02:00
{
desc : "one service by id containing slash" ,
path : "/api/http/services/" + url . PathEscape ( "foo / bar@myprovider" ) ,
conf : runtime . Configuration {
Services : map [ string ] * runtime . ServiceInfo {
"foo / bar@myprovider" : func ( ) * runtime . ServiceInfo {
si := & runtime . ServiceInfo {
Service : & dynamic . Service {
LoadBalancer : & dynamic . ServersLoadBalancer {
PassHostHeader : Bool ( true ) ,
Servers : [ ] dynamic . Server {
{
URL : "http://127.0.0.1" ,
} ,
} ,
} ,
} ,
UsedBy : [ ] string { "foo@myprovider" , "test@myprovider" } ,
}
si . UpdateServerStatus ( "http://127.0.0.1" , "UP" )
return si
} ( ) ,
} ,
} ,
expected : expected {
statusCode : http . StatusOK ,
jsonFile : "testdata/service-foo-slash-bar.json" ,
} ,
} ,
2019-07-12 11:10:03 +02:00
{
desc : "one service by id, that does not exist" ,
path : "/api/http/services/nono@myprovider" ,
2019-07-15 17:04:04 +02:00
conf : runtime . Configuration {
Services : map [ string ] * runtime . ServiceInfo {
"bar@myprovider" : func ( ) * runtime . ServiceInfo {
si := & runtime . ServiceInfo {
2019-07-12 11:10:03 +02:00
Service : & dynamic . Service {
2019-08-26 10:30:05 +02:00
LoadBalancer : & dynamic . ServersLoadBalancer {
2019-09-30 18:12:04 +02:00
PassHostHeader : Bool ( true ) ,
2019-07-12 11:10:03 +02:00
Servers : [ ] dynamic . Server {
{
URL : "http://127.0.0.1" ,
} ,
} ,
} ,
} ,
UsedBy : [ ] string { "foo@myprovider" , "test@myprovider" } ,
}
2019-07-15 17:04:04 +02:00
si . UpdateServerStatus ( "http://127.0.0.1" , "UP" )
2019-07-12 11:10:03 +02:00
return si
} ( ) ,
} ,
} ,
expected : expected {
statusCode : http . StatusNotFound ,
} ,
} ,
{
desc : "one service by id, but no config" ,
path : "/api/http/services/foo@myprovider" ,
2019-07-15 17:04:04 +02:00
conf : runtime . Configuration { } ,
2019-07-12 11:10:03 +02:00
expected : expected {
statusCode : http . StatusNotFound ,
} ,
} ,
{
desc : "all middlewares, but no config" ,
path : "/api/http/middlewares" ,
2019-07-15 17:04:04 +02:00
conf : runtime . Configuration { } ,
2019-07-12 11:10:03 +02:00
expected : expected {
statusCode : http . StatusOK ,
nextPage : "1" ,
jsonFile : "testdata/middlewares-empty.json" ,
} ,
} ,
{
desc : "all middlewares" ,
path : "/api/http/middlewares" ,
2019-07-15 17:04:04 +02:00
conf : runtime . Configuration {
Middlewares : map [ string ] * runtime . MiddlewareInfo {
2019-07-12 11:10:03 +02:00
"auth@myprovider" : {
Middleware : & dynamic . Middleware {
BasicAuth : & dynamic . BasicAuth {
Users : [ ] string { "admin:admin" } ,
} ,
} ,
UsedBy : [ ] string { "bar@myprovider" , "test@myprovider" } ,
} ,
"addPrefixTest@myprovider" : {
Middleware : & dynamic . Middleware {
AddPrefix : & dynamic . AddPrefix {
Prefix : "/titi" ,
} ,
} ,
UsedBy : [ ] string { "test@myprovider" } ,
} ,
"addPrefixTest@anotherprovider" : {
Middleware : & dynamic . Middleware {
AddPrefix : & dynamic . AddPrefix {
Prefix : "/toto" ,
} ,
} ,
UsedBy : [ ] string { "bar@myprovider" } ,
} ,
} ,
} ,
expected : expected {
statusCode : http . StatusOK ,
nextPage : "1" ,
jsonFile : "testdata/middlewares.json" ,
} ,
} ,
2019-09-02 11:38:04 +02:00
{
desc : "middlewares filtered by status" ,
path : "/api/http/middlewares?status=enabled" ,
conf : runtime . Configuration {
Middlewares : map [ string ] * runtime . MiddlewareInfo {
"auth@myprovider" : {
Middleware : & dynamic . Middleware {
BasicAuth : & dynamic . BasicAuth {
Users : [ ] string { "admin:admin" } ,
} ,
} ,
UsedBy : [ ] string { "bar@myprovider" , "test@myprovider" } ,
Status : runtime . StatusEnabled ,
} ,
"addPrefixTest@myprovider" : {
Middleware : & dynamic . Middleware {
AddPrefix : & dynamic . AddPrefix {
Prefix : "/titi" ,
} ,
} ,
UsedBy : [ ] string { "test@myprovider" } ,
Status : runtime . StatusDisabled ,
} ,
"addPrefixTest@anotherprovider" : {
Middleware : & dynamic . Middleware {
AddPrefix : & dynamic . AddPrefix {
Prefix : "/toto" ,
} ,
} ,
UsedBy : [ ] string { "bar@myprovider" } ,
Status : runtime . StatusEnabled ,
} ,
} ,
} ,
expected : expected {
statusCode : http . StatusOK ,
nextPage : "1" ,
jsonFile : "testdata/middlewares-filtered-status.json" ,
} ,
} ,
{
desc : "middlewares filtered by search" ,
path : "/api/http/middlewares?search=addprefixtest" ,
conf : runtime . Configuration {
Middlewares : map [ string ] * runtime . MiddlewareInfo {
"auth@myprovider" : {
Middleware : & dynamic . Middleware {
BasicAuth : & dynamic . BasicAuth {
Users : [ ] string { "admin:admin" } ,
} ,
} ,
UsedBy : [ ] string { "bar@myprovider" , "test@myprovider" } ,
Status : runtime . StatusEnabled ,
} ,
"addPrefixTest@myprovider" : {
Middleware : & dynamic . Middleware {
AddPrefix : & dynamic . AddPrefix {
Prefix : "/titi" ,
} ,
} ,
UsedBy : [ ] string { "test@myprovider" } ,
Status : runtime . StatusDisabled ,
} ,
"addPrefixTest@anotherprovider" : {
Middleware : & dynamic . Middleware {
AddPrefix : & dynamic . AddPrefix {
Prefix : "/toto" ,
} ,
} ,
UsedBy : [ ] string { "bar@myprovider" } ,
Status : runtime . StatusEnabled ,
} ,
} ,
} ,
expected : expected {
statusCode : http . StatusOK ,
nextPage : "1" ,
jsonFile : "testdata/middlewares-filtered-search.json" ,
} ,
} ,
2019-07-12 11:10:03 +02:00
{
desc : "all middlewares, 1 res per page, want page 2" ,
path : "/api/http/middlewares?page=2&per_page=1" ,
2019-07-15 17:04:04 +02:00
conf : runtime . Configuration {
Middlewares : map [ string ] * runtime . MiddlewareInfo {
2019-07-12 11:10:03 +02:00
"auth@myprovider" : {
Middleware : & dynamic . Middleware {
BasicAuth : & dynamic . BasicAuth {
Users : [ ] string { "admin:admin" } ,
} ,
} ,
UsedBy : [ ] string { "bar@myprovider" , "test@myprovider" } ,
} ,
"addPrefixTest@myprovider" : {
Middleware : & dynamic . Middleware {
AddPrefix : & dynamic . AddPrefix {
Prefix : "/titi" ,
} ,
} ,
UsedBy : [ ] string { "test@myprovider" } ,
} ,
"addPrefixTest@anotherprovider" : {
Middleware : & dynamic . Middleware {
AddPrefix : & dynamic . AddPrefix {
Prefix : "/toto" ,
} ,
} ,
UsedBy : [ ] string { "bar@myprovider" } ,
} ,
} ,
} ,
expected : expected {
statusCode : http . StatusOK ,
nextPage : "3" ,
jsonFile : "testdata/middlewares-page2.json" ,
} ,
} ,
{
desc : "one middleware by id" ,
path : "/api/http/middlewares/auth@myprovider" ,
2019-07-15 17:04:04 +02:00
conf : runtime . Configuration {
Middlewares : map [ string ] * runtime . MiddlewareInfo {
2019-07-12 11:10:03 +02:00
"auth@myprovider" : {
Middleware : & dynamic . Middleware {
BasicAuth : & dynamic . BasicAuth {
Users : [ ] string { "admin:admin" } ,
} ,
} ,
UsedBy : [ ] string { "bar@myprovider" , "test@myprovider" } ,
} ,
"addPrefixTest@myprovider" : {
Middleware : & dynamic . Middleware {
AddPrefix : & dynamic . AddPrefix {
Prefix : "/titi" ,
} ,
} ,
UsedBy : [ ] string { "test@myprovider" } ,
} ,
"addPrefixTest@anotherprovider" : {
Middleware : & dynamic . Middleware {
AddPrefix : & dynamic . AddPrefix {
Prefix : "/toto" ,
} ,
} ,
UsedBy : [ ] string { "bar@myprovider" } ,
} ,
} ,
} ,
expected : expected {
statusCode : http . StatusOK ,
jsonFile : "testdata/middleware-auth.json" ,
} ,
} ,
2024-01-25 10:56:05 +02:00
{
desc : "one middleware by id containing slash" ,
path : "/api/http/middlewares/" + url . PathEscape ( "foo / bar@myprovider" ) ,
conf : runtime . Configuration {
Middlewares : map [ string ] * runtime . MiddlewareInfo {
"foo / bar@myprovider" : {
Middleware : & dynamic . Middleware {
AddPrefix : & dynamic . AddPrefix {
Prefix : "/titi" ,
} ,
} ,
UsedBy : [ ] string { "test@myprovider" } ,
} ,
} ,
} ,
expected : expected {
statusCode : http . StatusOK ,
jsonFile : "testdata/middleware-foo-slash-bar.json" ,
} ,
} ,
2019-07-12 11:10:03 +02:00
{
desc : "one middleware by id, that does not exist" ,
path : "/api/http/middlewares/foo@myprovider" ,
2019-07-15 17:04:04 +02:00
conf : runtime . Configuration {
Middlewares : map [ string ] * runtime . MiddlewareInfo {
2019-07-12 11:10:03 +02:00
"auth@myprovider" : {
Middleware : & dynamic . Middleware {
BasicAuth : & dynamic . BasicAuth {
Users : [ ] string { "admin:admin" } ,
} ,
} ,
UsedBy : [ ] string { "bar@myprovider" , "test@myprovider" } ,
} ,
} ,
} ,
expected : expected {
statusCode : http . StatusNotFound ,
} ,
} ,
{
desc : "one middleware by id, but no config" ,
path : "/api/http/middlewares/foo@myprovider" ,
2019-07-15 17:04:04 +02:00
conf : runtime . Configuration { } ,
2019-07-12 11:10:03 +02:00
expected : expected {
statusCode : http . StatusNotFound ,
} ,
} ,
}
for _ , test := range testCases {
t . Run ( test . desc , func ( t * testing . T ) {
t . Parallel ( )
rtConf := & test . conf
2019-07-15 17:04:04 +02:00
// To lazily initialize the Statuses.
rtConf . PopulateUsedBy ( )
2019-09-02 11:38:04 +02:00
rtConf . GetRoutersByEntryPoints ( context . Background ( ) , [ ] string { "web" } , false )
2022-09-09 12:46:09 +02:00
rtConf . GetRoutersByEntryPoints ( context . Background ( ) , [ ] string { "web" } , true )
2019-09-02 11:38:04 +02:00
2019-07-12 11:10:03 +02:00
handler := New ( static . Configuration { API : & static . API { } , Global : & static . Global { } } , rtConf )
2019-11-14 16:40:05 +01:00
server := httptest . NewServer ( handler . createRouter ( ) )
2019-07-12 11:10:03 +02:00
resp , err := http . DefaultClient . Get ( server . URL + test . path )
require . NoError ( t , err )
require . Equal ( t , test . expected . statusCode , resp . StatusCode )
assert . Equal ( t , test . expected . nextPage , resp . Header . Get ( nextPageHeader ) )
if test . expected . jsonFile == "" {
return
}
2023-11-17 01:50:06 +01:00
assert . Equal ( t , "application/json" , resp . Header . Get ( "Content-Type" ) )
2021-03-04 20:08:03 +01:00
contents , err := io . ReadAll ( resp . Body )
2019-07-12 11:10:03 +02:00
require . NoError ( t , err )
err = resp . Body . Close ( )
require . NoError ( t , err )
if * updateExpected {
var results interface { }
err := json . Unmarshal ( contents , & results )
require . NoError ( t , err )
newJSON , err := json . MarshalIndent ( results , "" , "\t" )
require . NoError ( t , err )
2021-03-04 20:08:03 +01:00
err = os . WriteFile ( test . expected . jsonFile , newJSON , 0 o644 )
2019-07-12 11:10:03 +02:00
require . NoError ( t , err )
}
2021-03-04 20:08:03 +01:00
data , err := os . ReadFile ( test . expected . jsonFile )
2019-07-12 11:10:03 +02:00
require . NoError ( t , err )
assert . JSONEq ( t , string ( data ) , string ( contents ) )
} )
}
}
2019-07-15 17:04:04 +02:00
func generateHTTPRouters ( nbRouters int ) map [ string ] * runtime . RouterInfo {
routers := make ( map [ string ] * runtime . RouterInfo , nbRouters )
2024-02-19 15:44:03 +01:00
for i := range nbRouters {
2019-07-15 17:04:04 +02:00
routers [ fmt . Sprintf ( "bar%2d@myprovider" , i ) ] = & runtime . RouterInfo {
2019-07-12 11:10:03 +02:00
Router : & dynamic . Router {
EntryPoints : [ ] string { "web" } ,
Service : "foo-service@myprovider" ,
Rule : "Host(`foo.bar" + strconv . Itoa ( i ) + "`)" ,
} ,
}
}
return routers
}