updated route loading logic

This commit is contained in:
yusing 2025-02-06 16:47:02 +08:00
parent d8cac223ed
commit f5fb4d2a38
3 changed files with 57 additions and 44 deletions

View file

@ -65,7 +65,7 @@ func (p *FileProvider) loadRoutesImpl() (route.Routes, E.Error) {
return nil, E.Wrap(err) return nil, E.Wrap(err)
} }
routes, err := validate(data) routes, err := validate(data)
if err != nil { if err != nil && len(routes) == 0 {
return nil, E.Wrap(err) return nil, E.Wrap(err)
} }
return routes, nil return routes, nil

View file

@ -145,7 +145,6 @@ func (p *Provider) loadRoutes() (routes route.Routes, err E.Error) {
for alias, r := range routes { for alias, r := range routes {
r.Alias = alias r.Alias = alias
r.Provider = p.ShortName() r.Provider = p.ShortName()
r.Finalize()
if err := r.Validate(); err != nil { if err := r.Validate(); err != nil {
errs.Add(err.Subject(alias)) errs.Add(err.Subject(alias))
delete(routes, alias) delete(routes, alias)

View file

@ -8,6 +8,7 @@ import (
"github.com/yusing/go-proxy/internal/docker" "github.com/yusing/go-proxy/internal/docker"
idlewatcher "github.com/yusing/go-proxy/internal/docker/idlewatcher/types" idlewatcher "github.com/yusing/go-proxy/internal/docker/idlewatcher/types"
"github.com/yusing/go-proxy/internal/homepage" "github.com/yusing/go-proxy/internal/homepage"
"github.com/yusing/go-proxy/internal/logging"
net "github.com/yusing/go-proxy/internal/net/types" net "github.com/yusing/go-proxy/internal/net/types"
"github.com/yusing/go-proxy/internal/task" "github.com/yusing/go-proxy/internal/task"
"github.com/yusing/go-proxy/internal/watcher/health" "github.com/yusing/go-proxy/internal/watcher/health"
@ -60,17 +61,18 @@ func (r Routes) Contains(alias string) bool {
return ok return ok
} }
func (r *Route) Validate() E.Error { func (r *Route) Validate() (err E.Error) {
if r.isValidated { if r.isValidated {
return nil return nil
} }
r.isValidated = true r.isValidated = true
r.Finalize()
errs := E.NewBuilder("entry validation failed") errs := E.NewBuilder("entry validation failed")
switch r.Scheme { switch r.Scheme {
case types.SchemeFileServer: case types.SchemeFileServer:
return nil r.impl, err = NewFileServer(r)
case types.SchemeHTTP, types.SchemeHTTPS: case types.SchemeHTTP, types.SchemeHTTPS:
if r.Port.Listening != 0 { if r.Port.Listening != 0 {
errs.Addf("unexpected listening port for %s scheme", r.Scheme) errs.Addf("unexpected listening port for %s scheme", r.Scheme)
@ -94,10 +96,10 @@ func (r *Route) Validate() E.Error {
errs.Adds("healthCheck.disable cannot be true when loadbalancer or idlewatcher is enabled") errs.Adds("healthCheck.disable cannot be true when loadbalancer or idlewatcher is enabled")
} }
return errs.Error() if errs.HasError() {
} return errs.Error()
}
func (r *Route) Start(parent task.Parent) (err E.Error) {
switch r.Scheme { switch r.Scheme {
case types.SchemeFileServer: case types.SchemeFileServer:
r.impl, err = NewFileServer(r) r.impl, err = NewFileServer(r)
@ -108,8 +110,13 @@ func (r *Route) Start(parent task.Parent) (err E.Error) {
default: default:
panic(fmt.Errorf("unexpected scheme %s for alias %s", r.Scheme, r.Alias)) panic(fmt.Errorf("unexpected scheme %s for alias %s", r.Scheme, r.Alias))
} }
if err != nil {
return err return err
}
func (r *Route) Start(parent task.Parent) (err E.Error) {
if r.impl == nil {
return E.New("route not initialized")
} }
return r.impl.Start(parent) return r.impl.Start(parent)
} }
@ -187,19 +194,25 @@ func (r *Route) ShouldExclude() bool {
if r.Container != nil { if r.Container != nil {
switch { switch {
case r.Container.IsExcluded: case r.Container.IsExcluded:
logging.Debug().Str("container", r.Container.ContainerName).Msg("container excluded: explicitly excluded")
return true return true
case r.IsZeroPort() && !r.UseIdleWatcher(): case r.IsZeroPort() && !r.UseIdleWatcher():
logging.Debug().Str("container", r.Container.ContainerName).Msg("container excluded: zero port and no idle watcher")
return true return true
case r.Container.IsDatabase && !r.Container.IsExplicit: case r.Container.IsDatabase && !r.Container.IsExplicit:
logging.Debug().Str("container", r.Container.ContainerName).Msg("container excluded: database")
return true return true
case strings.HasPrefix(r.Container.ContainerName, "buildx_"): case strings.HasPrefix(r.Container.ContainerName, "buildx_"):
logging.Debug().Str("container", r.Container.ContainerName).Msg("container excluded: buildx prefix")
return true return true
} }
} else if r.IsZeroPort() { } else if r.IsZeroPort() {
logging.Debug().Str("container", r.Container.ContainerName).Msg("container excluded: zero port")
return true return true
} }
if strings.HasPrefix(r.Alias, "x-") || if strings.HasPrefix(r.Alias, "x-") ||
strings.HasSuffix(r.Alias, "-old") { strings.HasSuffix(r.Alias, "-old") {
logging.Debug().Str("container", r.Container.ContainerName).Msg("container excluded: alias")
return true return true
} }
return false return false
@ -224,36 +237,35 @@ func (r *Route) UseAccessLog() bool {
func (r *Route) Finalize() { func (r *Route) Finalize() {
isDocker := r.Container != nil isDocker := r.Container != nil
cont := r.Container cont := r.Container
if !isDocker {
cont = docker.DummyContainer
}
if r.Host == "" { if r.Host == "" {
switch { switch {
case !isDocker:
r.Host = "localhost"
case cont.PrivateIP != "": case cont.PrivateIP != "":
r.Host = cont.PrivateIP r.Host = cont.PrivateIP
case cont.PublicIP != "": case cont.PublicIP != "":
r.Host = cont.PublicIP r.Host = cont.PublicIP
case !isDocker:
r.Host = "localhost"
} }
} }
lp, pp := r.Port.Listening, r.Port.Proxy lp, pp := r.Port.Listening, r.Port.Proxy
if port, ok := common.ServiceNamePortMapTCP[cont.ImageName]; ok { if isDocker {
if pp == 0 { if port, ok := common.ServiceNamePortMapTCP[cont.ImageName]; ok {
pp = port if pp == 0 {
} pp = port
if r.Scheme == "" { }
r.Scheme = "tcp" if r.Scheme == "" {
} r.Scheme = "tcp"
} else if port, ok := common.ImageNamePortMap[cont.ImageName]; ok { }
if pp == 0 { } else if port, ok := common.ImageNamePortMap[cont.ImageName]; ok {
pp = port if pp == 0 {
} pp = port
if r.Scheme == "" { }
r.Scheme = "http" if r.Scheme == "" {
r.Scheme = "http"
}
} }
} }
@ -271,25 +283,27 @@ func (r *Route) Finalize() {
} }
} }
// replace private port with public port if using public IP. if isDocker {
if r.Host == cont.PublicIP { // replace private port with public port if using public IP.
if p, ok := cont.PrivatePortMapping[pp]; ok { if r.Host == cont.PublicIP {
pp = int(p.PublicPort) if p, ok := cont.PrivatePortMapping[pp]; ok {
pp = int(p.PublicPort)
}
} }
} // replace public port with private port if using private IP.
// replace public port with private port if using private IP. if r.Host == cont.PrivateIP {
if r.Host == cont.PrivateIP { if p, ok := cont.PublicPortMapping[pp]; ok {
if p, ok := cont.PublicPortMapping[pp]; ok { pp = int(p.PrivatePort)
pp = int(p.PrivatePort) }
} }
}
if r.Scheme == "" && isDocker { if r.Scheme == "" {
switch { switch {
case r.Host == cont.PublicIP && cont.PublicPortMapping[pp].Type == "udp": case r.Host == cont.PublicIP && cont.PublicPortMapping[pp].Type == "udp":
r.Scheme = "udp" r.Scheme = "udp"
case r.Host == cont.PrivateIP && cont.PrivatePortMapping[pp].Type == "udp": case r.Host == cont.PrivateIP && cont.PrivatePortMapping[pp].Type == "udp":
r.Scheme = "udp" r.Scheme = "udp"
}
} }
} }
@ -319,7 +333,7 @@ func (r *Route) Finalize() {
} }
} }
if cont.IdleTimeout != "" { if isDocker && cont.IdleTimeout != "" {
if cont.WakeTimeout == "" { if cont.WakeTimeout == "" {
cont.WakeTimeout = common.WakeTimeoutDefault cont.WakeTimeout = common.WakeTimeoutDefault
} }