1
0
Fork 0

Add TCP Healthcheck

This commit is contained in:
Douglas De Toni Machado 2025-10-22 06:42:05 -03:00 committed by GitHub
parent d1ab6ed489
commit 8392503df7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
37 changed files with 2416 additions and 307 deletions

View file

@ -33,16 +33,21 @@ type serviceInfoRepresentation struct {
ServerStatus map[string]string `json:"serverStatus,omitempty"`
}
type tcpServiceInfoRepresentation struct {
*runtime.TCPServiceInfo
ServerStatus map[string]string `json:"serverStatus,omitempty"`
}
// RunTimeRepresentation is the configuration information exposed by the API handler.
type RunTimeRepresentation struct {
Routers map[string]*runtime.RouterInfo `json:"routers,omitempty"`
Middlewares map[string]*runtime.MiddlewareInfo `json:"middlewares,omitempty"`
Services map[string]*serviceInfoRepresentation `json:"services,omitempty"`
TCPRouters map[string]*runtime.TCPRouterInfo `json:"tcpRouters,omitempty"`
TCPMiddlewares map[string]*runtime.TCPMiddlewareInfo `json:"tcpMiddlewares,omitempty"`
TCPServices map[string]*runtime.TCPServiceInfo `json:"tcpServices,omitempty"`
UDPRouters map[string]*runtime.UDPRouterInfo `json:"udpRouters,omitempty"`
UDPServices map[string]*runtime.UDPServiceInfo `json:"udpServices,omitempty"`
Routers map[string]*runtime.RouterInfo `json:"routers,omitempty"`
Middlewares map[string]*runtime.MiddlewareInfo `json:"middlewares,omitempty"`
Services map[string]*serviceInfoRepresentation `json:"services,omitempty"`
TCPRouters map[string]*runtime.TCPRouterInfo `json:"tcpRouters,omitempty"`
TCPMiddlewares map[string]*runtime.TCPMiddlewareInfo `json:"tcpMiddlewares,omitempty"`
TCPServices map[string]*tcpServiceInfoRepresentation `json:"tcpServices,omitempty"`
UDPRouters map[string]*runtime.UDPRouterInfo `json:"udpRouters,omitempty"`
UDPServices map[string]*runtime.UDPServiceInfo `json:"udpServices,omitempty"`
}
// Handler serves the configuration and status of Traefik on API endpoints.
@ -127,13 +132,21 @@ func (h Handler) getRuntimeConfiguration(rw http.ResponseWriter, request *http.R
}
}
tcpSIRepr := make(map[string]*tcpServiceInfoRepresentation, len(h.runtimeConfiguration.Services))
for k, v := range h.runtimeConfiguration.TCPServices {
tcpSIRepr[k] = &tcpServiceInfoRepresentation{
TCPServiceInfo: v,
ServerStatus: v.GetAllStatus(),
}
}
result := RunTimeRepresentation{
Routers: h.runtimeConfiguration.Routers,
Middlewares: h.runtimeConfiguration.Middlewares,
Services: siRepr,
TCPRouters: h.runtimeConfiguration.TCPRouters,
TCPMiddlewares: h.runtimeConfiguration.TCPMiddlewares,
TCPServices: h.runtimeConfiguration.TCPServices,
TCPServices: tcpSIRepr,
UDPRouters: h.runtimeConfiguration.UDPRouters,
UDPServices: h.runtimeConfiguration.UDPServices,
}

View file

@ -34,10 +34,10 @@ func newRouterRepresentation(name string, rt *runtime.RouterInfo) routerRepresen
type serviceRepresentation struct {
*runtime.ServiceInfo
ServerStatus map[string]string `json:"serverStatus,omitempty"`
Name string `json:"name,omitempty"`
Provider string `json:"provider,omitempty"`
Type string `json:"type,omitempty"`
ServerStatus map[string]string `json:"serverStatus,omitempty"`
}
func newServiceRepresentation(name string, si *runtime.ServiceInfo) serviceRepresentation {
@ -45,8 +45,8 @@ func newServiceRepresentation(name string, si *runtime.ServiceInfo) serviceRepre
ServiceInfo: si,
Name: name,
Provider: getProviderName(name),
ServerStatus: si.GetAllStatus(),
Type: strings.ToLower(extractType(si.Service)),
ServerStatus: si.GetAllStatus(),
}
}

View file

@ -29,9 +29,10 @@ func newTCPRouterRepresentation(name string, rt *runtime.TCPRouterInfo) tcpRoute
type tcpServiceRepresentation struct {
*runtime.TCPServiceInfo
Name string `json:"name,omitempty"`
Provider string `json:"provider,omitempty"`
Type string `json:"type,omitempty"`
Name string `json:"name,omitempty"`
Provider string `json:"provider,omitempty"`
Type string `json:"type,omitempty"`
ServerStatus map[string]string `json:"serverStatus,omitempty"`
}
func newTCPServiceRepresentation(name string, si *runtime.TCPServiceInfo) tcpServiceRepresentation {
@ -40,6 +41,7 @@ func newTCPServiceRepresentation(name string, si *runtime.TCPServiceInfo) tcpSer
Name: name,
Provider: getProviderName(name),
Type: strings.ToLower(extractType(si.TCPService)),
ServerStatus: si.GetAllStatus(),
}
}

View file

@ -355,45 +355,57 @@ func TestHandler_TCP(t *testing.T) {
path: "/api/tcp/services",
conf: runtime.Configuration{
TCPServices: map[string]*runtime.TCPServiceInfo{
"bar@myprovider": {
TCPService: &dynamic.TCPService{
LoadBalancer: &dynamic.TCPServersLoadBalancer{
Servers: []dynamic.TCPServer{
{
Address: "127.0.0.1:2345",
"bar@myprovider": func() *runtime.TCPServiceInfo {
si := &runtime.TCPServiceInfo{
TCPService: &dynamic.TCPService{
LoadBalancer: &dynamic.TCPServersLoadBalancer{
Servers: []dynamic.TCPServer{
{
Address: "127.0.0.1:2345",
},
},
},
},
},
UsedBy: []string{"foo@myprovider", "test@myprovider"},
Status: runtime.StatusEnabled,
},
"baz@myprovider": {
TCPService: &dynamic.TCPService{
LoadBalancer: &dynamic.TCPServersLoadBalancer{
Servers: []dynamic.TCPServer{
{
Address: "127.0.0.2:2345",
UsedBy: []string{"foo@myprovider", "test@myprovider"},
Status: runtime.StatusEnabled,
}
si.UpdateServerStatus("127.0.0.1:2345", "UP")
return si
}(),
"baz@myprovider": func() *runtime.TCPServiceInfo {
si := &runtime.TCPServiceInfo{
TCPService: &dynamic.TCPService{
LoadBalancer: &dynamic.TCPServersLoadBalancer{
Servers: []dynamic.TCPServer{
{
Address: "127.0.0.2:2345",
},
},
},
},
},
UsedBy: []string{"foo@myprovider"},
Status: runtime.StatusWarning,
},
"foz@myprovider": {
TCPService: &dynamic.TCPService{
LoadBalancer: &dynamic.TCPServersLoadBalancer{
Servers: []dynamic.TCPServer{
{
Address: "127.0.0.2:2345",
UsedBy: []string{"foo@myprovider"},
Status: runtime.StatusWarning,
}
si.UpdateServerStatus("127.0.0.2:2345", "UP")
return si
}(),
"foz@myprovider": func() *runtime.TCPServiceInfo {
si := &runtime.TCPServiceInfo{
TCPService: &dynamic.TCPService{
LoadBalancer: &dynamic.TCPServersLoadBalancer{
Servers: []dynamic.TCPServer{
{
Address: "127.0.0.3:2345",
},
},
},
},
},
UsedBy: []string{"foo@myprovider"},
Status: runtime.StatusDisabled,
},
UsedBy: []string{"foo@myprovider"},
Status: runtime.StatusDisabled,
}
si.UpdateServerStatus("127.0.0.3:2345", "UP")
return si
}(),
},
},
expected: expected{
@ -407,45 +419,57 @@ func TestHandler_TCP(t *testing.T) {
path: "/api/tcp/services?status=enabled",
conf: runtime.Configuration{
TCPServices: map[string]*runtime.TCPServiceInfo{
"bar@myprovider": {
TCPService: &dynamic.TCPService{
LoadBalancer: &dynamic.TCPServersLoadBalancer{
Servers: []dynamic.TCPServer{
{
Address: "127.0.0.1:2345",
"bar@myprovider": func() *runtime.TCPServiceInfo {
si := &runtime.TCPServiceInfo{
TCPService: &dynamic.TCPService{
LoadBalancer: &dynamic.TCPServersLoadBalancer{
Servers: []dynamic.TCPServer{
{
Address: "127.0.0.1:2345",
},
},
},
},
},
UsedBy: []string{"foo@myprovider", "test@myprovider"},
Status: runtime.StatusEnabled,
},
"baz@myprovider": {
TCPService: &dynamic.TCPService{
LoadBalancer: &dynamic.TCPServersLoadBalancer{
Servers: []dynamic.TCPServer{
{
Address: "127.0.0.2:2345",
UsedBy: []string{"foo@myprovider", "test@myprovider"},
Status: runtime.StatusEnabled,
}
si.UpdateServerStatus("127.0.0.1:2345", "UP")
return si
}(),
"baz@myprovider": func() *runtime.TCPServiceInfo {
si := &runtime.TCPServiceInfo{
TCPService: &dynamic.TCPService{
LoadBalancer: &dynamic.TCPServersLoadBalancer{
Servers: []dynamic.TCPServer{
{
Address: "127.0.0.2:2345",
},
},
},
},
},
UsedBy: []string{"foo@myprovider"},
Status: runtime.StatusWarning,
},
"foz@myprovider": {
TCPService: &dynamic.TCPService{
LoadBalancer: &dynamic.TCPServersLoadBalancer{
Servers: []dynamic.TCPServer{
{
Address: "127.0.0.2:2345",
UsedBy: []string{"foo@myprovider"},
Status: runtime.StatusWarning,
}
si.UpdateServerStatus("127.0.0.2:2345", "UP")
return si
}(),
"foz@myprovider": func() *runtime.TCPServiceInfo {
si := &runtime.TCPServiceInfo{
TCPService: &dynamic.TCPService{
LoadBalancer: &dynamic.TCPServersLoadBalancer{
Servers: []dynamic.TCPServer{
{
Address: "127.0.0.3:2345",
},
},
},
},
},
UsedBy: []string{"foo@myprovider"},
Status: runtime.StatusDisabled,
},
UsedBy: []string{"foo@myprovider"},
Status: runtime.StatusDisabled,
}
si.UpdateServerStatus("127.0.0.3:2345", "UP")
return si
}(),
},
},
expected: expected{
@ -459,45 +483,57 @@ func TestHandler_TCP(t *testing.T) {
path: "/api/tcp/services?search=baz@my",
conf: runtime.Configuration{
TCPServices: map[string]*runtime.TCPServiceInfo{
"bar@myprovider": {
TCPService: &dynamic.TCPService{
LoadBalancer: &dynamic.TCPServersLoadBalancer{
Servers: []dynamic.TCPServer{
{
Address: "127.0.0.1:2345",
"bar@myprovider": func() *runtime.TCPServiceInfo {
si := &runtime.TCPServiceInfo{
TCPService: &dynamic.TCPService{
LoadBalancer: &dynamic.TCPServersLoadBalancer{
Servers: []dynamic.TCPServer{
{
Address: "127.0.0.1:2345",
},
},
},
},
},
UsedBy: []string{"foo@myprovider", "test@myprovider"},
Status: runtime.StatusEnabled,
},
"baz@myprovider": {
TCPService: &dynamic.TCPService{
LoadBalancer: &dynamic.TCPServersLoadBalancer{
Servers: []dynamic.TCPServer{
{
Address: "127.0.0.2:2345",
UsedBy: []string{"foo@myprovider", "test@myprovider"},
Status: runtime.StatusEnabled,
}
si.UpdateServerStatus("127.0.0.1:2345", "UP")
return si
}(),
"baz@myprovider": func() *runtime.TCPServiceInfo {
si := &runtime.TCPServiceInfo{
TCPService: &dynamic.TCPService{
LoadBalancer: &dynamic.TCPServersLoadBalancer{
Servers: []dynamic.TCPServer{
{
Address: "127.0.0.2:2345",
},
},
},
},
},
UsedBy: []string{"foo@myprovider"},
Status: runtime.StatusWarning,
},
"foz@myprovider": {
TCPService: &dynamic.TCPService{
LoadBalancer: &dynamic.TCPServersLoadBalancer{
Servers: []dynamic.TCPServer{
{
Address: "127.0.0.2:2345",
UsedBy: []string{"foo@myprovider"},
Status: runtime.StatusWarning,
}
si.UpdateServerStatus("127.0.0.2:2345", "UP")
return si
}(),
"foz@myprovider": func() *runtime.TCPServiceInfo {
si := &runtime.TCPServiceInfo{
TCPService: &dynamic.TCPService{
LoadBalancer: &dynamic.TCPServersLoadBalancer{
Servers: []dynamic.TCPServer{
{
Address: "127.0.0.3:2345",
},
},
},
},
},
UsedBy: []string{"foo@myprovider"},
Status: runtime.StatusDisabled,
},
UsedBy: []string{"foo@myprovider"},
Status: runtime.StatusDisabled,
}
si.UpdateServerStatus("127.0.0.3:2345", "UP")
return si
}(),
},
},
expected: expected{
@ -511,41 +547,53 @@ func TestHandler_TCP(t *testing.T) {
path: "/api/tcp/services?page=2&per_page=1",
conf: runtime.Configuration{
TCPServices: map[string]*runtime.TCPServiceInfo{
"bar@myprovider": {
TCPService: &dynamic.TCPService{
LoadBalancer: &dynamic.TCPServersLoadBalancer{
Servers: []dynamic.TCPServer{
{
Address: "127.0.0.1:2345",
"bar@myprovider": func() *runtime.TCPServiceInfo {
si := &runtime.TCPServiceInfo{
TCPService: &dynamic.TCPService{
LoadBalancer: &dynamic.TCPServersLoadBalancer{
Servers: []dynamic.TCPServer{
{
Address: "127.0.0.1:2345",
},
},
},
},
},
UsedBy: []string{"foo@myprovider", "test@myprovider"},
},
"baz@myprovider": {
TCPService: &dynamic.TCPService{
LoadBalancer: &dynamic.TCPServersLoadBalancer{
Servers: []dynamic.TCPServer{
{
Address: "127.0.0.2:2345",
UsedBy: []string{"foo@myprovider", "test@myprovider"},
}
si.UpdateServerStatus("127.0.0.1:2345", "UP")
return si
}(),
"baz@myprovider": func() *runtime.TCPServiceInfo {
si := &runtime.TCPServiceInfo{
TCPService: &dynamic.TCPService{
LoadBalancer: &dynamic.TCPServersLoadBalancer{
Servers: []dynamic.TCPServer{
{
Address: "127.0.0.2:2345",
},
},
},
},
},
UsedBy: []string{"foo@myprovider"},
},
"test@myprovider": {
TCPService: &dynamic.TCPService{
LoadBalancer: &dynamic.TCPServersLoadBalancer{
Servers: []dynamic.TCPServer{
{
Address: "127.0.0.3:2345",
UsedBy: []string{"foo@myprovider"},
}
si.UpdateServerStatus("127.0.0.2:2345", "UP")
return si
}(),
"test@myprovider": func() *runtime.TCPServiceInfo {
si := &runtime.TCPServiceInfo{
TCPService: &dynamic.TCPService{
LoadBalancer: &dynamic.TCPServersLoadBalancer{
Servers: []dynamic.TCPServer{
{
Address: "127.0.0.3:2345",
},
},
},
},
},
},
}
si.UpdateServerStatus("127.0.0.3:2345", "UP")
return si
}(),
},
},
expected: expected{
@ -559,18 +607,22 @@ func TestHandler_TCP(t *testing.T) {
path: "/api/tcp/services/bar@myprovider",
conf: runtime.Configuration{
TCPServices: map[string]*runtime.TCPServiceInfo{
"bar@myprovider": {
TCPService: &dynamic.TCPService{
LoadBalancer: &dynamic.TCPServersLoadBalancer{
Servers: []dynamic.TCPServer{
{
Address: "127.0.0.1:2345",
"bar@myprovider": func() *runtime.TCPServiceInfo {
si := &runtime.TCPServiceInfo{
TCPService: &dynamic.TCPService{
LoadBalancer: &dynamic.TCPServersLoadBalancer{
Servers: []dynamic.TCPServer{
{
Address: "127.0.0.1:2345",
},
},
},
},
},
UsedBy: []string{"foo@myprovider", "test@myprovider"},
},
UsedBy: []string{"foo@myprovider", "test@myprovider"},
}
si.UpdateServerStatus("127.0.0.1:2345", "UP")
return si
}(),
},
},
expected: expected{
@ -583,18 +635,22 @@ func TestHandler_TCP(t *testing.T) {
path: "/api/tcp/services/" + url.PathEscape("foo / bar@myprovider"),
conf: runtime.Configuration{
TCPServices: map[string]*runtime.TCPServiceInfo{
"foo / bar@myprovider": {
TCPService: &dynamic.TCPService{
LoadBalancer: &dynamic.TCPServersLoadBalancer{
Servers: []dynamic.TCPServer{
{
Address: "127.0.0.1:2345",
"foo / bar@myprovider": func() *runtime.TCPServiceInfo {
si := &runtime.TCPServiceInfo{
TCPService: &dynamic.TCPService{
LoadBalancer: &dynamic.TCPServersLoadBalancer{
Servers: []dynamic.TCPServer{
{
Address: "127.0.0.1:2345",
},
},
},
},
},
UsedBy: []string{"foo@myprovider", "test@myprovider"},
},
UsedBy: []string{"foo@myprovider", "test@myprovider"},
}
si.UpdateServerStatus("127.0.0.1:2345", "UP")
return si
}(),
},
},
expected: expected{
@ -607,18 +663,22 @@ func TestHandler_TCP(t *testing.T) {
path: "/api/tcp/services/nono@myprovider",
conf: runtime.Configuration{
TCPServices: map[string]*runtime.TCPServiceInfo{
"bar@myprovider": {
TCPService: &dynamic.TCPService{
LoadBalancer: &dynamic.TCPServersLoadBalancer{
Servers: []dynamic.TCPServer{
{
Address: "127.0.0.1:2345",
"bar@myprovider": func() *runtime.TCPServiceInfo {
si := &runtime.TCPServiceInfo{
TCPService: &dynamic.TCPService{
LoadBalancer: &dynamic.TCPServersLoadBalancer{
Servers: []dynamic.TCPServer{
{
Address: "127.0.0.1:2345",
},
},
},
},
},
UsedBy: []string{"foo@myprovider", "test@myprovider"},
},
UsedBy: []string{"foo@myprovider", "test@myprovider"},
}
si.UpdateServerStatus("127.0.0.1:2345", "UP")
return si
}(),
},
},
expected: expected{

View file

@ -8,6 +8,9 @@
},
"name": "bar@myprovider",
"provider": "myprovider",
"serverStatus": {
"127.0.0.1:2345": "UP"
},
"status": "enabled",
"type": "loadbalancer",
"usedBy": [

View file

@ -8,6 +8,9 @@
},
"name": "foo / bar@myprovider",
"provider": "myprovider",
"serverStatus": {
"127.0.0.1:2345": "UP"
},
"status": "enabled",
"type": "loadbalancer",
"usedBy": [

View file

@ -9,6 +9,9 @@
},
"name": "baz@myprovider",
"provider": "myprovider",
"serverStatus": {
"127.0.0.2:2345": "UP"
},
"status": "warning",
"type": "loadbalancer",
"usedBy": [

View file

@ -9,6 +9,9 @@
},
"name": "bar@myprovider",
"provider": "myprovider",
"serverStatus": {
"127.0.0.1:2345": "UP"
},
"status": "enabled",
"type": "loadbalancer",
"usedBy": [

View file

@ -9,6 +9,9 @@
},
"name": "baz@myprovider",
"provider": "myprovider",
"serverStatus": {
"127.0.0.2:2345": "UP"
},
"status": "enabled",
"type": "loadbalancer",
"usedBy": [

View file

@ -9,6 +9,9 @@
},
"name": "bar@myprovider",
"provider": "myprovider",
"serverStatus": {
"127.0.0.1:2345": "UP"
},
"status": "enabled",
"type": "loadbalancer",
"usedBy": [
@ -26,6 +29,9 @@
},
"name": "baz@myprovider",
"provider": "myprovider",
"serverStatus": {
"127.0.0.2:2345": "UP"
},
"status": "warning",
"type": "loadbalancer",
"usedBy": [
@ -36,12 +42,15 @@
"loadBalancer": {
"servers": [
{
"address": "127.0.0.2:2345"
"address": "127.0.0.3:2345"
}
]
},
"name": "foz@myprovider",
"provider": "myprovider",
"serverStatus": {
"127.0.0.3:2345": "UP"
},
"status": "disabled",
"type": "loadbalancer",
"usedBy": [