2019-07-12 09:10:03 +00:00
|
|
|
package api
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"io/ioutil"
|
|
|
|
"net/http"
|
|
|
|
"net/http/httptest"
|
|
|
|
"testing"
|
|
|
|
|
2019-08-03 01:58:23 +00:00
|
|
|
"github.com/containous/traefik/v2/pkg/config/dynamic"
|
|
|
|
"github.com/containous/traefik/v2/pkg/config/runtime"
|
|
|
|
"github.com/containous/traefik/v2/pkg/config/static"
|
|
|
|
"github.com/containous/traefik/v2/pkg/provider/docker"
|
|
|
|
"github.com/containous/traefik/v2/pkg/provider/file"
|
|
|
|
"github.com/containous/traefik/v2/pkg/provider/kubernetes/crd"
|
|
|
|
"github.com/containous/traefik/v2/pkg/provider/kubernetes/ingress"
|
|
|
|
"github.com/containous/traefik/v2/pkg/provider/marathon"
|
|
|
|
"github.com/containous/traefik/v2/pkg/provider/rancher"
|
|
|
|
"github.com/containous/traefik/v2/pkg/provider/rest"
|
|
|
|
"github.com/containous/traefik/v2/pkg/tracing/jaeger"
|
|
|
|
"github.com/containous/traefik/v2/pkg/types"
|
|
|
|
"github.com/gorilla/mux"
|
2019-07-12 09:10:03 +00:00
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestHandler_Overview(t *testing.T) {
|
|
|
|
type expected struct {
|
|
|
|
statusCode int
|
|
|
|
jsonFile string
|
|
|
|
}
|
|
|
|
|
|
|
|
testCases := []struct {
|
|
|
|
desc string
|
|
|
|
path string
|
|
|
|
confStatic static.Configuration
|
2019-07-15 15:04:04 +00:00
|
|
|
confDyn runtime.Configuration
|
2019-07-12 09:10:03 +00:00
|
|
|
expected expected
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
desc: "without data in the dynamic configuration",
|
|
|
|
path: "/api/overview",
|
|
|
|
confStatic: static.Configuration{API: &static.API{}, Global: &static.Global{}},
|
2019-07-15 15:04:04 +00:00
|
|
|
confDyn: runtime.Configuration{},
|
2019-07-12 09:10:03 +00:00
|
|
|
expected: expected{
|
|
|
|
statusCode: http.StatusOK,
|
|
|
|
jsonFile: "testdata/overview-empty.json",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "with data in the dynamic configuration",
|
|
|
|
path: "/api/overview",
|
|
|
|
confStatic: static.Configuration{API: &static.API{}, Global: &static.Global{}},
|
2019-07-15 15:04:04 +00:00
|
|
|
confDyn: runtime.Configuration{
|
|
|
|
Services: map[string]*runtime.ServiceInfo{
|
2019-07-12 09:10:03 +00:00
|
|
|
"foo-service@myprovider": {
|
|
|
|
Service: &dynamic.Service{
|
2019-08-26 08:30:05 +00:00
|
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
2019-07-15 15:04:04 +00:00
|
|
|
Servers: []dynamic.Server{{URL: "http://127.0.0.1"}},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Status: runtime.StatusEnabled,
|
|
|
|
},
|
|
|
|
"bar-service@myprovider": {
|
|
|
|
Service: &dynamic.Service{
|
2019-08-26 08:30:05 +00:00
|
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
2019-07-15 15:04:04 +00:00
|
|
|
Servers: []dynamic.Server{{URL: "http://127.0.0.1"}},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Status: runtime.StatusWarning,
|
|
|
|
},
|
|
|
|
"fii-service@myprovider": {
|
|
|
|
Service: &dynamic.Service{
|
2019-08-26 08:30:05 +00:00
|
|
|
LoadBalancer: &dynamic.ServersLoadBalancer{
|
2019-07-15 15:04:04 +00:00
|
|
|
Servers: []dynamic.Server{{URL: "http://127.0.0.1"}},
|
2019-07-12 09:10:03 +00:00
|
|
|
},
|
|
|
|
},
|
2019-07-15 15:04:04 +00:00
|
|
|
Status: runtime.StatusDisabled,
|
2019-07-12 09:10:03 +00:00
|
|
|
},
|
|
|
|
},
|
2019-07-15 15:04:04 +00:00
|
|
|
Middlewares: map[string]*runtime.MiddlewareInfo{
|
2019-07-12 09:10:03 +00:00
|
|
|
"auth@myprovider": {
|
|
|
|
Middleware: &dynamic.Middleware{
|
|
|
|
BasicAuth: &dynamic.BasicAuth{
|
|
|
|
Users: []string{"admin:admin"},
|
|
|
|
},
|
|
|
|
},
|
2019-07-19 14:42:04 +00:00
|
|
|
Status: runtime.StatusEnabled,
|
2019-07-12 09:10:03 +00:00
|
|
|
},
|
|
|
|
"addPrefixTest@myprovider": {
|
|
|
|
Middleware: &dynamic.Middleware{
|
|
|
|
AddPrefix: &dynamic.AddPrefix{
|
|
|
|
Prefix: "/titi",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"addPrefixTest@anotherprovider": {
|
|
|
|
Middleware: &dynamic.Middleware{
|
|
|
|
AddPrefix: &dynamic.AddPrefix{
|
|
|
|
Prefix: "/toto",
|
|
|
|
},
|
|
|
|
},
|
2019-07-19 14:42:04 +00:00
|
|
|
Err: []string{"error"},
|
|
|
|
Status: runtime.StatusDisabled,
|
2019-07-12 09:10:03 +00:00
|
|
|
},
|
|
|
|
},
|
2019-07-15 15:04:04 +00:00
|
|
|
Routers: map[string]*runtime.RouterInfo{
|
2019-07-12 09:10:03 +00: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 15:04:04 +00:00
|
|
|
Status: runtime.StatusEnabled,
|
2019-07-12 09:10:03 +00:00
|
|
|
},
|
|
|
|
"test@myprovider": {
|
|
|
|
Router: &dynamic.Router{
|
|
|
|
EntryPoints: []string{"web"},
|
|
|
|
Service: "foo-service@myprovider",
|
|
|
|
Rule: "Host(`foo.bar.other`)",
|
|
|
|
Middlewares: []string{"addPrefixTest", "auth"},
|
|
|
|
},
|
2019-07-15 15:04:04 +00:00
|
|
|
Status: runtime.StatusWarning,
|
|
|
|
},
|
|
|
|
"foo@myprovider": {
|
|
|
|
Router: &dynamic.Router{
|
|
|
|
EntryPoints: []string{"web"},
|
|
|
|
Service: "foo-service@myprovider",
|
|
|
|
Rule: "Host(`foo.bar.other`)",
|
|
|
|
Middlewares: []string{"addPrefixTest", "auth"},
|
|
|
|
},
|
|
|
|
Status: runtime.StatusDisabled,
|
2019-07-12 09:10:03 +00:00
|
|
|
},
|
|
|
|
},
|
2019-07-15 15:04:04 +00:00
|
|
|
TCPServices: map[string]*runtime.TCPServiceInfo{
|
2019-07-12 09:10:03 +00:00
|
|
|
"tcpfoo-service@myprovider": {
|
|
|
|
TCPService: &dynamic.TCPService{
|
2019-09-13 18:00:06 +00:00
|
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
2019-07-12 09:10:03 +00:00
|
|
|
Servers: []dynamic.TCPServer{
|
|
|
|
{
|
|
|
|
Address: "127.0.0.1",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2019-07-18 13:56:04 +00:00
|
|
|
Status: runtime.StatusEnabled,
|
|
|
|
},
|
|
|
|
"tcpbar-service@myprovider": {
|
|
|
|
TCPService: &dynamic.TCPService{
|
2019-09-13 18:00:06 +00:00
|
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
2019-07-18 13:56:04 +00:00
|
|
|
Servers: []dynamic.TCPServer{
|
|
|
|
{
|
|
|
|
Address: "127.0.0.2",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Status: runtime.StatusWarning,
|
|
|
|
},
|
|
|
|
"tcpfii-service@myprovider": {
|
|
|
|
TCPService: &dynamic.TCPService{
|
2019-09-13 18:00:06 +00:00
|
|
|
LoadBalancer: &dynamic.TCPServersLoadBalancer{
|
2019-07-18 13:56:04 +00:00
|
|
|
Servers: []dynamic.TCPServer{
|
|
|
|
{
|
|
|
|
Address: "127.0.0.2",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Status: runtime.StatusDisabled,
|
2019-07-12 09:10:03 +00:00
|
|
|
},
|
|
|
|
},
|
2019-07-15 15:04:04 +00:00
|
|
|
TCPRouters: map[string]*runtime.TCPRouterInfo{
|
2019-07-12 09:10:03 +00:00
|
|
|
"tcpbar@myprovider": {
|
|
|
|
TCPRouter: &dynamic.TCPRouter{
|
|
|
|
EntryPoints: []string{"web"},
|
|
|
|
Service: "tcpfoo-service@myprovider",
|
|
|
|
Rule: "HostSNI(`foo.bar`)",
|
|
|
|
},
|
2019-07-18 13:56:04 +00:00
|
|
|
Status: runtime.StatusEnabled,
|
2019-07-12 09:10:03 +00:00
|
|
|
},
|
|
|
|
"tcptest@myprovider": {
|
|
|
|
TCPRouter: &dynamic.TCPRouter{
|
|
|
|
EntryPoints: []string{"web"},
|
|
|
|
Service: "tcpfoo-service@myprovider",
|
|
|
|
Rule: "HostSNI(`foo.bar.other`)",
|
|
|
|
},
|
2019-07-18 13:56:04 +00:00
|
|
|
Status: runtime.StatusWarning,
|
|
|
|
},
|
|
|
|
"tcpfoo@myprovider": {
|
|
|
|
TCPRouter: &dynamic.TCPRouter{
|
|
|
|
EntryPoints: []string{"web"},
|
|
|
|
Service: "tcpfoo-service@myprovider",
|
|
|
|
Rule: "HostSNI(`foo.bar.other`)",
|
|
|
|
},
|
|
|
|
Status: runtime.StatusDisabled,
|
2019-07-12 09:10:03 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
expected: expected{
|
|
|
|
statusCode: http.StatusOK,
|
|
|
|
jsonFile: "testdata/overview-dynamic.json",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "with providers",
|
|
|
|
path: "/api/overview",
|
|
|
|
confStatic: static.Configuration{
|
|
|
|
Global: &static.Global{},
|
|
|
|
API: &static.API{},
|
|
|
|
Providers: &static.Providers{
|
|
|
|
Docker: &docker.Provider{},
|
|
|
|
File: &file.Provider{},
|
|
|
|
Marathon: &marathon.Provider{},
|
|
|
|
KubernetesIngress: &ingress.Provider{},
|
|
|
|
KubernetesCRD: &crd.Provider{},
|
|
|
|
Rest: &rest.Provider{},
|
|
|
|
Rancher: &rancher.Provider{},
|
|
|
|
},
|
|
|
|
},
|
2019-07-15 15:04:04 +00:00
|
|
|
confDyn: runtime.Configuration{},
|
2019-07-12 09:10:03 +00:00
|
|
|
expected: expected{
|
|
|
|
statusCode: http.StatusOK,
|
|
|
|
jsonFile: "testdata/overview-providers.json",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "with features",
|
|
|
|
path: "/api/overview",
|
|
|
|
confStatic: static.Configuration{
|
|
|
|
Global: &static.Global{},
|
|
|
|
API: &static.API{},
|
|
|
|
Metrics: &types.Metrics{
|
|
|
|
Prometheus: &types.Prometheus{},
|
|
|
|
},
|
|
|
|
Tracing: &static.Tracing{
|
|
|
|
Jaeger: &jaeger.Config{},
|
|
|
|
},
|
|
|
|
},
|
2019-07-15 15:04:04 +00:00
|
|
|
confDyn: runtime.Configuration{},
|
2019-07-12 09:10:03 +00:00
|
|
|
expected: expected{
|
|
|
|
statusCode: http.StatusOK,
|
|
|
|
jsonFile: "testdata/overview-features.json",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, test := range testCases {
|
|
|
|
test := test
|
|
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
handler := New(test.confStatic, &test.confDyn)
|
|
|
|
router := mux.NewRouter()
|
|
|
|
handler.Append(router)
|
|
|
|
|
|
|
|
server := httptest.NewServer(router)
|
|
|
|
|
|
|
|
resp, err := http.DefaultClient.Get(server.URL + test.path)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
require.Equal(t, test.expected.statusCode, resp.StatusCode)
|
|
|
|
|
|
|
|
if test.expected.jsonFile == "" {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
assert.Equal(t, resp.Header.Get("Content-Type"), "application/json")
|
|
|
|
contents, err := ioutil.ReadAll(resp.Body)
|
|
|
|
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)
|
|
|
|
|
|
|
|
err = ioutil.WriteFile(test.expected.jsonFile, newJSON, 0644)
|
|
|
|
require.NoError(t, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
data, err := ioutil.ReadFile(test.expected.jsonFile)
|
|
|
|
require.NoError(t, err)
|
|
|
|
assert.JSONEq(t, string(data), string(contents))
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|