fixed host set to localhost even on remote docker, fixed one error in provider causing all routes not to load

This commit is contained in:
yusing 2024-09-21 18:23:20 +08:00
parent 26e2154c64
commit 69361aea1b
8 changed files with 92 additions and 40 deletions

View file

@ -238,14 +238,22 @@ func (cfg *Config) loadProviders(providers *M.ProxyProviders) (res E.NestedError
defer b.To(&res) defer b.To(&res)
for _, filename := range providers.Files { for _, filename := range providers.Files {
p := PR.NewFileProvider(filename) p, err := PR.NewFileProvider(filename)
if err != nil {
b.Add(err.Subject(filename))
continue
}
cfg.proxyProviders.Store(p.GetName(), p) cfg.proxyProviders.Store(p.GetName(), p)
b.Add(p.LoadRoutes()) b.Add(p.LoadRoutes().Subject(filename))
} }
for name, dockerHost := range providers.Docker { for name, dockerHost := range providers.Docker {
p := PR.NewDockerProvider(name, dockerHost) p, err := PR.NewDockerProvider(name, dockerHost)
if err != nil {
b.Add(err.Subject(dockerHost))
continue
}
cfg.proxyProviders.Store(p.GetName(), p) cfg.proxyProviders.Store(p.GetName(), p)
b.Add(p.LoadRoutes()) b.Add(p.LoadRoutes().Subject(dockerHost))
} }
return return
} }

View file

@ -20,9 +20,23 @@ type Client struct {
l logrus.FieldLogger l logrus.FieldLogger
} }
func ParseDockerHostname(host string) (string, E.NestedError) {
if host == common.DockerHostFromEnv {
return host, nil
} else if host == "" {
return "localhost", nil
}
url, err := E.Check(client.ParseHostURL(host))
if err != nil {
return "", E.Invalid("host", host).With(err)
}
return url.Hostname(), nil
}
func (c Client) DaemonHostname() string { func (c Client) DaemonHostname() string {
url, _ := client.ParseHostURL(c.DaemonHost()) // DaemonHost should always return a valid host
return url.Hostname() hostname, _ := ParseDockerHostname(c.DaemonHost())
return hostname
} }
func (c Client) Connected() bool { func (c Client) Connected() bool {

View file

@ -1,6 +1,7 @@
package fields package fields
import ( import (
"fmt"
"strings" "strings"
"github.com/yusing/go-proxy/common" "github.com/yusing/go-proxy/common"
@ -15,7 +16,7 @@ type StreamPort struct {
func ValidateStreamPort(p string) (StreamPort, E.NestedError) { func ValidateStreamPort(p string) (StreamPort, E.NestedError) {
split := strings.Split(p, ":") split := strings.Split(p, ":")
if len(split) != 2 { if len(split) != 2 {
return StreamPort{}, E.Invalid("stream port", p).With("should be in 'x:y' format") return StreamPort{}, E.Invalid("stream port", fmt.Sprintf("%q", p)).With("should be in 'x:y' format")
} }
listeningPort, err := ValidatePort(split[0]) listeningPort, err := ValidatePort(split[0])

View file

@ -18,8 +18,12 @@ type DockerProvider struct {
var AliasRefRegex = regexp.MustCompile(`\$\d+`) var AliasRefRegex = regexp.MustCompile(`\$\d+`)
func DockerProviderImpl(dockerHost string) ProviderImpl { func DockerProviderImpl(dockerHost string) (ProviderImpl, E.NestedError) {
return &DockerProvider{dockerHost: dockerHost} hostname, err := D.ParseDockerHostname(dockerHost)
if err.HasError() {
return nil, err
}
return &DockerProvider{dockerHost: dockerHost, hostname: hostname}, nil
} }
func (p *DockerProvider) NewWatcher() W.Watcher { func (p *DockerProvider) NewWatcher() W.Watcher {
@ -27,6 +31,7 @@ func (p *DockerProvider) NewWatcher() W.Watcher {
} }
func (p *DockerProvider) LoadRoutesImpl() (routes R.Routes, err E.NestedError) { func (p *DockerProvider) LoadRoutesImpl() (routes R.Routes, err E.NestedError) {
routes = R.NewRoutes()
entries := M.NewProxyEntries() entries := M.NewProxyEntries()
info, err := D.GetClientInfo(p.dockerHost, true) info, err := D.GetClientInfo(p.dockerHost, true)

View file

@ -5,6 +5,7 @@ import (
"testing" "testing"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/yusing/go-proxy/common"
D "github.com/yusing/go-proxy/docker" D "github.com/yusing/go-proxy/docker"
E "github.com/yusing/go-proxy/error" E "github.com/yusing/go-proxy/error"
F "github.com/yusing/go-proxy/utils/functional" F "github.com/yusing/go-proxy/utils/functional"
@ -51,6 +52,12 @@ X_Custom_Header2: value3
Names: dummyNames, Names: dummyNames,
Labels: map[string]string{ Labels: map[string]string{
D.LableAliases: "a,b", D.LableAliases: "a,b",
D.LabelIdleTimeout: common.IdleTimeoutDefault,
D.LabelStopMethod: common.StopMethodDefault,
D.LabelStopSignal: "SIGTERM",
D.LabelStopTimeout: common.StopTimeoutDefault,
D.LabelWakeTimeout: common.WakeTimeoutDefault,
"proxy.*.no_tls_verify": "true",
"proxy.*.scheme": "https", "proxy.*.scheme": "https",
"proxy.*.host": "app", "proxy.*.host": "app",
"proxy.*.port": "4567", "proxy.*.port": "4567",
@ -73,8 +80,8 @@ X_Custom_Header2: value3
ExpectEqual(t, a.Port, "4567") ExpectEqual(t, a.Port, "4567")
ExpectEqual(t, b.Port, "4567") ExpectEqual(t, b.Port, "4567")
ExpectEqual(t, a.NoTLSVerify, true) ExpectTrue(t, a.NoTLSVerify)
ExpectEqual(t, b.NoTLSVerify, false) ExpectTrue(t, b.NoTLSVerify)
ExpectDeepEqual(t, a.PathPatterns, pathPatternsExpect) ExpectDeepEqual(t, a.PathPatterns, pathPatternsExpect)
ExpectEqual(t, len(b.PathPatterns), 0) ExpectEqual(t, len(b.PathPatterns), 0)
@ -84,6 +91,21 @@ X_Custom_Header2: value3
ExpectDeepEqual(t, a.HideHeaders, hideHeadersExpect) ExpectDeepEqual(t, a.HideHeaders, hideHeadersExpect)
ExpectEqual(t, len(b.HideHeaders), 0) ExpectEqual(t, len(b.HideHeaders), 0)
ExpectEqual(t, a.IdleTimeout, common.IdleTimeoutDefault)
ExpectEqual(t, b.IdleTimeout, common.IdleTimeoutDefault)
ExpectEqual(t, a.StopTimeout, common.StopTimeoutDefault)
ExpectEqual(t, b.StopTimeout, common.StopTimeoutDefault)
ExpectEqual(t, a.StopMethod, common.StopMethodDefault)
ExpectEqual(t, b.StopMethod, common.StopMethodDefault)
ExpectEqual(t, a.WakeTimeout, common.WakeTimeoutDefault)
ExpectEqual(t, b.WakeTimeout, common.WakeTimeoutDefault)
ExpectEqual(t, a.StopSignal, "SIGTERM")
ExpectEqual(t, b.StopSignal, "SIGTERM")
} }
func TestApplyLabel(t *testing.T) { func TestApplyLabel(t *testing.T) {

View file

@ -1,6 +1,7 @@
package provider package provider
import ( import (
"errors"
"os" "os"
"path" "path"
@ -17,11 +18,20 @@ type FileProvider struct {
path string path string
} }
func FileProviderImpl(filename string) ProviderImpl { func FileProviderImpl(filename string) (ProviderImpl, E.NestedError) {
return &FileProvider{ impl := &FileProvider{
fileName: filename, fileName: filename,
path: path.Join(common.ConfigBasePath, filename), path: path.Join(common.ConfigBasePath, filename),
} }
_, err := os.Stat(impl.path)
switch {
case err == nil:
return impl, nil
case errors.Is(err, os.ErrNotExist):
return nil, E.NotExist("file", impl.path)
default:
return nil, E.UnexpectedError(err)
}
} }
func Validate(data []byte) E.NestedError { func Validate(data []byte) E.NestedError {
@ -52,6 +62,8 @@ func (p FileProvider) OnEvent(event W.Event, routes R.Routes) (res EventResult)
} }
func (p *FileProvider) LoadRoutesImpl() (routes R.Routes, res E.NestedError) { func (p *FileProvider) LoadRoutesImpl() (routes R.Routes, res E.NestedError) {
routes = R.NewRoutes()
b := E.NewBuilder("file %q validation failure", p.fileName) b := E.NewBuilder("file %q validation failure", p.fileName)
defer b.To(&res) defer b.To(&res)

View file

@ -27,6 +27,7 @@ type (
} }
ProviderImpl interface { ProviderImpl interface {
NewWatcher() W.Watcher NewWatcher() W.Watcher
// even returns error, routes must be non-nil
LoadRoutesImpl() (R.Routes, E.NestedError) LoadRoutesImpl() (R.Routes, E.NestedError)
OnEvent(event W.Event, routes R.Routes) EventResult OnEvent(event W.Event, routes R.Routes) EventResult
} }
@ -53,19 +54,25 @@ func newProvider(name string, t ProviderType) *Provider {
return p return p
} }
func NewFileProvider(filename string) *Provider { func NewFileProvider(filename string) (p *Provider, err E.NestedError) {
name := path.Base(filename) name := path.Base(filename)
p := newProvider(name, ProviderTypeFile) p = newProvider(name, ProviderTypeFile)
p.ProviderImpl = FileProviderImpl(filename) p.ProviderImpl, err = FileProviderImpl(filename)
if err != nil {
return nil, err
}
p.watcher = p.NewWatcher() p.watcher = p.NewWatcher()
return p return
} }
func NewDockerProvider(name string, dockerHost string) *Provider { func NewDockerProvider(name string, dockerHost string) (p *Provider, err E.NestedError) {
p := newProvider(name, ProviderTypeDocker) p = newProvider(name, ProviderTypeDocker)
p.ProviderImpl = DockerProviderImpl(dockerHost) p.ProviderImpl, err = DockerProviderImpl(dockerHost)
if err != nil {
return nil, err
}
p.watcher = p.NewWatcher() p.watcher = p.NewWatcher()
return p return
} }
func (p *Provider) GetName() string { func (p *Provider) GetName() string {
@ -137,11 +144,9 @@ func (p *Provider) GetRoute(alias string) (R.Route, bool) {
func (p *Provider) LoadRoutes() E.NestedError { func (p *Provider) LoadRoutes() E.NestedError {
routes, err := p.LoadRoutesImpl() routes, err := p.LoadRoutesImpl()
if err != nil {
return err
}
p.routes = routes p.routes = routes
return nil p.l.Infof("loaded %d routes", routes.Size())
return err
} }
func (p *Provider) watchEvents() { func (p *Provider) watchEvents() {

View file

@ -1,15 +0,0 @@
package utils
import (
"os"
"path"
)
func FileOK(p string) bool {
_, err := os.Stat(p)
return err == nil
}
func FileName(p string) string {
return path.Base(p)
}