feat(agent): allow specifying agent for routes in route files

This commit is contained in:
yusing 2025-06-14 20:05:11 +08:00
parent 7d17a01de1
commit 5ce1c7865e
2 changed files with 66 additions and 10 deletions

View file

@ -50,6 +50,7 @@ type (
Middlewares map[string]docker.LabelMap `json:"middlewares,omitempty"`
Homepage *homepage.ItemConfig `json:"homepage,omitempty"`
AccessLog *accesslog.RequestLoggerConfig `json:"access_log,omitempty"`
Agent string `json:"agent,omitempty"`
Idlewatcher *idlewatcher.Config `json:"idlewatcher,omitempty"`
HealthMon health.HealthMonitor `json:"health,omitempty"`
@ -76,6 +77,8 @@ type (
lastError gperr.Error
provider routes.Provider
agent *agent.AgentConfig
started chan struct{}
once sync.Once
}
@ -94,6 +97,23 @@ func (r *Route) Validate() gperr.Error {
return r.lastError
}
r.isValidated = true
if r.Agent != "" {
if r.Container != nil {
return gperr.Errorf("specifying agent is not allowed for docker container routes")
}
var ok bool
// by agent address
r.agent, ok = agent.GetAgent(r.Agent)
if !ok {
// fallback to get agent by name
r.agent, ok = agent.GetAgentByName(r.Agent)
if !ok {
return gperr.Errorf("agent %s not found", r.Agent)
}
}
}
r.Finalize()
r.started = make(chan struct{})
@ -177,13 +197,15 @@ func (r *Route) Validate() gperr.Error {
r.Idlewatcher = r.Container.IdlewatcherConfig
}
// return error if route is localhost:<godoxy_port>
switch r.Host {
case "localhost", "127.0.0.1":
switch r.Port.Proxy {
case common.ProxyHTTPPort, common.ProxyHTTPSPort, common.APIHTTPPort:
if r.Scheme.IsReverseProxy() || r.Scheme == route.SchemeTCP {
return gperr.Errorf("localhost:%d is reserved for godoxy", r.Port.Proxy)
// return error if route is localhost:<godoxy_port> but route is not agent
if !r.IsAgent() {
switch r.Host {
case "localhost", "127.0.0.1":
switch r.Port.Proxy {
case common.ProxyHTTPPort, common.ProxyHTTPSPort, common.APIHTTPPort:
if r.Scheme.IsReverseProxy() || r.Scheme == route.SchemeTCP {
return gperr.Errorf("localhost:%d is reserved for godoxy", r.Port.Proxy)
}
}
}
}
@ -352,10 +374,10 @@ func (r *Route) Type() route.RouteType {
}
func (r *Route) GetAgent() *agent.AgentConfig {
if r.Container == nil {
return nil
if r.Container != nil && r.Container.Agent != nil {
return r.Container.Agent
}
return r.Container.Agent
return r.agent
}
func (r *Route) IsAgent() bool {

View file

@ -148,3 +148,37 @@ func TestPreferredPort(t *testing.T) {
port := preferredPort(ports)
expect.Equal(t, port, 3000)
}
func TestDockerRouteDisallowAgent(t *testing.T) {
r := &Route{
Alias: "test",
Scheme: route.SchemeHTTP,
Host: "example.com",
Port: route.Port{Proxy: 80},
Agent: "test-agent",
Metadata: Metadata{
Container: &docker.Container{
ContainerID: "test-id",
Image: &docker.ContainerImage{
Name: "test-image",
},
},
},
}
err := r.Validate()
expect.HasError(t, err, "Validate should return error for docker route with agent")
expect.ErrorContains(t, err, "specifying agent is not allowed for docker container routes")
}
func TestRouteAgent(t *testing.T) {
r := &Route{
Alias: "test",
Scheme: route.SchemeHTTP,
Host: "example.com",
Port: route.Port{Proxy: 80},
Agent: "test-agent",
}
err := r.Validate()
expect.NoError(t, err, "Validate should not return error for valid route with agent")
expect.NotNil(t, r.GetAgent(), "GetAgent should return agent")
}