Traefik_Control/backend/internal/traefik/mock.go

446 lines
No EOL
13 KiB
Go

package traefik
import (
"context"
"time"
"github.com/traefik/traefik-gui/backend/internal/models"
)
type MockClient struct{}
func NewMockClient() *MockClient {
return &MockClient{}
}
func (m *MockClient) GetRouters(ctx context.Context) ([]models.Router, error) {
return []models.Router{
{
Name: "api@internal",
Provider: "internal",
Rule: "PathPrefix(`/api`) || PathPrefix(`/dashboard`)",
EntryPoints: []string{"traefik"},
Service: "api@internal",
Middlewares: []string{},
Priority: 0,
TLS: nil,
Status: "enabled",
Using: []string{},
},
{
Name: "dashboard@internal",
Provider: "internal",
Rule: "PathPrefix(`/dashboard`)",
EntryPoints: []string{"traefik"},
Service: "dashboard@internal",
Middlewares: []string{},
Priority: 0,
TLS: nil,
Status: "enabled",
Using: []string{},
},
{
Name: "web-router@docker",
Provider: "docker",
Rule: "Host(`web.example.com`)",
EntryPoints: []string{"web", "websecure"},
Service: "web-service@docker",
Middlewares: []string{"secure-headers@docker", "redirect-https@docker"},
Priority: 10,
TLS: &models.RouterTLSConfig{
Options: "default@default",
CertResolver: "letsencrypt",
Domains: []models.Domain{
{Main: "web.example.com", SANs: []string{"www.web.example.com"}},
},
},
Status: "enabled",
Using: []string{"secure-headers@docker", "redirect-https@docker"},
},
{
Name: "api-router@file",
Provider: "file",
Rule: "Host(`api.example.com`) && PathPrefix(`/v1`)",
EntryPoints: []string{"websecure"},
Service: "api-service@file",
Middlewares: []string{"rate-limit@file", "cors@file"},
Priority: 20,
TLS: &models.RouterTLSConfig{
Options: "modern@default",
CertResolver: "letsencrypt",
},
Status: "enabled",
Using: []string{"rate-limit@file", "cors@file"},
},
{
Name: "disabled-router@file",
Provider: "file",
Rule: "Host(`old.example.com`)",
EntryPoints: []string{"web"},
Service: "old-service@file",
Middlewares: []string{},
Priority: 5,
TLS: nil,
Status: "disabled",
Using: []string{},
},
}, nil
}
func (m *MockClient) GetServices(ctx context.Context) ([]models.Service, error) {
return []models.Service{
{
Name: "api@internal",
Provider: "internal",
Type: "loadbalancer",
LoadBalancer: &models.LoadBalancer{
Servers: []models.Server{
{URL: "http://127.0.0.1:8080", Weight: ptr(1)},
},
Strategy: "wrr",
},
ServerStatus: map[string]string{"http://127.0.0.1:8080": "UP"},
Status: "enabled",
},
{
Name: "dashboard@internal",
Provider: "internal",
Type: "loadbalancer",
LoadBalancer: &models.LoadBalancer{
Servers: []models.Server{
{URL: "http://127.0.0.1:8080", Weight: ptr(1)},
},
Strategy: "wrr",
},
ServerStatus: map[string]string{"http://127.0.0.1:8080": "UP"},
Status: "enabled",
},
{
Name: "web-service@docker",
Provider: "docker",
Type: "loadbalancer",
LoadBalancer: &models.LoadBalancer{
Servers: []models.Server{
{URL: "http://172.17.0.2:80", Weight: ptr(1)},
{URL: "http://172.17.0.3:80", Weight: ptr(1)},
},
Strategy: "wrr",
PassHostHeader: ptr(true),
HealthCheck: &models.HealthCheck{
Scheme: "http",
Path: "/health",
Method: "GET",
Status: 200,
Interval: "30s",
Timeout: "5s",
},
},
ServerStatus: map[string]string{
"http://172.17.0.2:80": "UP",
"http://172.17.0.3:80": "UP",
},
Status: "enabled",
},
{
Name: "api-service@file",
Provider: "file",
Type: "loadbalancer",
LoadBalancer: &models.LoadBalancer{
Servers: []models.Server{
{URL: "http://10.0.0.10:8080", Weight: ptr(3)},
{URL: "http://10.0.0.11:8080", Weight: ptr(1)},
},
Strategy: "wrr",
PassHostHeader: ptr(true),
HealthCheck: &models.HealthCheck{
Scheme: "http",
Path: "/health",
Method: "GET",
Status: 200,
Interval: "30s",
Timeout: "5s",
},
},
ServerStatus: map[string]string{
"http://10.0.0.10:8080": "UP",
"http://10.0.0.11:8080": "UP",
},
Status: "enabled",
},
{
Name: "old-service@file",
Provider: "file",
Type: "loadbalancer",
LoadBalancer: &models.LoadBalancer{
Servers: []models.Server{
{URL: "http://192.168.1.100:80", Weight: ptr(1)},
},
Strategy: "wrr",
},
ServerStatus: map[string]string{"http://192.168.1.100:80": "DOWN"},
Status: "warning",
},
}, nil
}
func (m *MockClient) GetMiddlewares(ctx context.Context) ([]models.Middleware, error) {
return []models.Middleware{
{
Name: "secure-headers@docker",
Provider: "docker",
Type: "headers",
Spec: map[string]interface{}{
"customResponseHeaders": map[string]string{
"X-Content-Type-Options": "nosniff",
"X-Frame-Options": "DENY",
},
},
Status: "enabled",
},
{
Name: "redirect-https@docker",
Provider: "docker",
Type: "redirectscheme",
Spec: map[string]interface{}{
"scheme": "https",
"permanent": true,
},
Status: "enabled",
},
{
Name: "rate-limit@file",
Provider: "file",
Type: "ratelimit",
Spec: map[string]interface{}{
"average": 100,
"burst": 50,
},
Status: "enabled",
},
{
Name: "cors@file",
Provider: "file",
Type: "headers",
Spec: map[string]interface{}{
"accessControlAllowMethods": []string{"GET", "POST", "PUT", "DELETE"},
"accessControlAllowOriginList": []string{"https://app.example.com"},
"accessControlAllowHeaders": []string{"Authorization", "Content-Type"},
},
Status: "enabled",
},
{
Name: "strip-prefix@file",
Provider: "file",
Type: "stripprefix",
Spec: map[string]interface{}{
"prefixes": []string{"/v1"},
},
Status: "enabled",
},
}, nil
}
func (m *MockClient) GetCertificates(ctx context.Context) ([]models.Certificate, error) {
now := time.Now()
return []models.Certificate{
{
Name: "letsencrypt-web-example-com",
CommonName: "web.example.com",
SANs: []string{"web.example.com", "www.web.example.com"},
IssuerOrg: "Let's Encrypt",
IssuerCN: "R3",
NotBefore: now.AddDate(0, -2, 0),
NotAfter: now.AddDate(0, 1, 0),
Status: "valid",
Provider: "letsencrypt",
},
{
Name: "letsencrypt-api-example-com",
CommonName: "api.example.com",
SANs: []string{"api.example.com"},
IssuerOrg: "Let's Encrypt",
IssuerCN: "R3",
NotBefore: now.AddDate(0, -1, -15),
NotAfter: now.AddDate(0, 2, -15),
Status: "valid",
Provider: "letsencrypt",
},
{
Name: "self-signed-local",
CommonName: "local.example.com",
SANs: []string{"local.example.com", "*.local.example.com"},
IssuerOrg: "Local CA",
IssuerCN: "Local Root CA",
NotBefore: now.AddDate(-1, 0, 0),
NotAfter: now.AddDate(1, 0, 0),
Status: "valid",
Provider: "file",
},
{
Name: "expired-cert",
CommonName: "old.example.com",
SANs: []string{"old.example.com"},
IssuerOrg: "Let's Encrypt",
IssuerCN: "R3",
NotBefore: now.AddDate(0, -4, 0),
NotAfter: now.AddDate(0, -1, 0),
Status: "expired",
Provider: "letsencrypt",
},
}, nil
}
func (m *MockClient) GetEntryPoints(ctx context.Context) ([]models.EntryPoint, error) {
return []models.EntryPoint{
{
Name: "web",
Address: ":80",
HTTP: &models.EntryPointHTTP{
Middlewares: []string{"redirect-https@docker"},
RedirectToHTTPS: true,
},
},
{
Name: "websecure",
Address: ":443",
HTTP: &models.EntryPointHTTP{
TLS: &models.EntryPointTLS{
CertResolver: "letsencrypt",
Options: "default@default",
},
Middlewares: []string{"secure-headers@docker"},
},
},
{
Name: "traefik",
Address: ":8080",
HTTP: &models.EntryPointHTTP{
Middlewares: []string{},
},
},
}, nil
}
func (m *MockClient) GetOverview(ctx context.Context) (*models.Overview, error) {
return &models.Overview{
HTTP: struct {
Routers models.Section `json:"routers"`
Services models.Section `json:"services"`
Middlewares models.Section `json:"middlewares"`
}{
Routers: models.Section{Total: 4, Warnings: 0, Errors: 1},
Services: models.Section{Total: 5, Warnings: 1, Errors: 0},
Middlewares: models.Section{Total: 5, Warnings: 0, Errors: 0},
},
TCP: struct {
Routers models.Section `json:"routers"`
Services models.Section `json:"services"`
Middlewares models.Section `json:"middlewares"`
}{
Routers: models.Section{Total: 0, Warnings: 0, Errors: 0},
Services: models.Section{Total: 0, Warnings: 0, Errors: 0},
Middlewares: models.Section{Total: 0, Warnings: 0, Errors: 0},
},
UDP: struct {
Routers models.Section `json:"routers"`
Services models.Section `json:"services"`
}{
Routers: models.Section{Total: 0, Warnings: 0, Errors: 0},
Services: models.Section{Total: 0, Warnings: 0, Errors: 0},
},
Certificates: &models.Section{Total: 4, Warnings: 1, Errors: 1},
Providers: []string{"docker", "file", "internal"},
}, nil
}
func ptr[T any](v T) *T {
return &v
}
// MockAPIClient implements the new TraefikAPI interface with v3.7 types
type MockAPIClient struct{}
func NewMockAPIClient() *MockAPIClient { return &MockAPIClient{} }
func (m *MockAPIClient) GetHealthz(ctx context.Context) (*HealthResponse, error) {
return &HealthResponse{Status: "OK", Version: "3.7.0"}, nil
}
func (m *MockAPIClient) GetOverview(ctx context.Context) (*Overview, error) {
return &Overview{
HTTP: struct {
Routers Section `json:"routers"`
Services Section `json:"services"`
Middlewares Section `json:"middlewares"`
}{
Routers: Section{Total: 4, Warnings: 0, Errors: 1},
Services: Section{Total: 5, Warnings: 1, Errors: 0},
Middlewares: Section{Total: 5, Warnings: 0, Errors: 0},
},
TCP: struct {
Routers Section `json:"routers"`
Services Section `json:"services"`
Middlewares Section `json:"middlewares"`
}{
Routers: Section{Total: 0, Warnings: 0, Errors: 0},
Services: Section{Total: 0, Warnings: 0, Errors: 0},
Middlewares: Section{Total: 0, Warnings: 0, Errors: 0},
},
UDP: struct {
Routers Section `json:"routers"`
Services Section `json:"services"`
}{
Routers: Section{Total: 0, Warnings: 0, Errors: 0},
Services: Section{Total: 0, Warnings: 0, Errors: 0},
},
Providers: []string{"docker", "file", "internal"},
TotalRouters: 4,
TotalServices: 5,
TotalMiddlewares: 5,
TraefikVersion: "3.7.0",
TraefikCodename: "lascaux",
}, nil
}
func (m *MockAPIClient) GetEntrypoints(ctx context.Context) ([]Entrypoint, error) {
return []Entrypoint{
{Name: "web", Address: ":80"},
{Name: "websecure", Address: ":443"},
{Name: "traefik", Address: ":8080"},
}, nil
}
func (m *MockAPIClient) GetRouters(ctx context.Context) ([]Router, error) {
return []Router{
{Name: "api@internal", Provider: "internal", Rule: "PathPrefix(`/api`)", EntryPoints: []string{"traefik"}, Service: "api@internal", Status: "enabled"},
{Name: "web@docker", Provider: "docker", Rule: "Host(`web.example.com`)", EntryPoints: []string{"web"}, Service: "web@docker", Status: "enabled"},
}, nil
}
func (m *MockAPIClient) GetServices(ctx context.Context) ([]Service, error) {
return []Service{
{Name: "web@docker", Provider: "docker", Type: "loadbalancer", Status: "enabled", Middlewares: []string{"auth@docker"}},
{Name: "api@internal", Provider: "internal", Type: "loadbalancer", Status: "enabled"},
}, nil
}
func (m *MockAPIClient) GetMiddlewares(ctx context.Context) ([]Middleware, error) {
return []Middleware{
{Name: "auth@docker", Provider: "docker", Type: "forwardAuth", Status: "enabled"},
}, nil
}
func (m *MockAPIClient) GetProviders(ctx context.Context) ([]Provider, error) {
return []Provider{{Name: "docker"}, {Name: "file"}, {Name: "internal"}}, nil
}
func (m *MockAPIClient) GetCertificates(ctx context.Context) ([]Certificate, error) {
now := time.Now()
return []Certificate{
{Store: "default", Names: []string{"example.com"}, SANs: []string{"example.com"}, Issuer: "CN=Test CA", NotAfter: now.Add(24 * time.Hour), NotBefore: now.Add(-24 * time.Hour), SerialNumber: "1"},
{Store: "default", Names: []string{"expired.com"}, SANs: []string{"expired.com"}, Issuer: "CN=Test CA", NotAfter: now.Add(-24 * time.Hour), NotBefore: now.Add(-48 * time.Hour), SerialNumber: "2"},
}, nil
}
var _ TraefikAPI = (*MockAPIClient)(nil)
var _ TraefikAPI = (*Client)(nil)