mirror of
https://github.com/traefik/traefik.git
synced 2026-06-17 19:09:29 +03:00
Improve file provider behavior regarding dangling symlinks
This commit is contained in:
@@ -71,9 +71,16 @@ func (p *Provider) Provide(configurationChan chan<- dynamic.Message, pool *safe.
|
|||||||
// ignore sub-dir
|
// ignore sub-dir
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if !isFileSupported(entry.Name()) {
|
||||||
|
// ignore unsupported file extension
|
||||||
|
continue
|
||||||
|
}
|
||||||
watchItems = append(watchItems, path.Join(p.Directory, entry.Name()))
|
watchItems = append(watchItems, path.Join(p.Directory, entry.Name()))
|
||||||
}
|
}
|
||||||
case len(p.Filename) > 0:
|
case len(p.Filename) > 0:
|
||||||
|
if !isFileSupported(p.Filename) {
|
||||||
|
return fmt.Errorf("unsupported file extension for file %s", p.Filename)
|
||||||
|
}
|
||||||
watchItems = append(watchItems, filepath.Dir(p.Filename), p.Filename)
|
watchItems = append(watchItems, filepath.Dir(p.Filename), p.Filename)
|
||||||
default:
|
default:
|
||||||
return errors.New("error using file configuration provider, neither filename nor directory is defined")
|
return errors.New("error using file configuration provider, neither filename nor directory is defined")
|
||||||
@@ -168,7 +175,7 @@ func (p *Provider) addWatcher(pool *safe.Pool, items []string, configurationChan
|
|||||||
log.Debug().Msgf("add watcher on: %s", item)
|
log.Debug().Msgf("add watcher on: %s", item)
|
||||||
err = watcher.Add(item)
|
err = watcher.Add(item)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error adding file watcher: %w", err)
|
return fmt.Errorf("error adding file watcher for %s: %w", item, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -420,10 +427,8 @@ func (p *Provider) loadFileConfigFromDirectory(ctx context.Context, directory st
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
switch strings.ToLower(filepath.Ext(item.Name())) {
|
if !isFileSupported(item.Name()) {
|
||||||
case ".toml", ".yaml", ".yml":
|
logger.Debug().Msg("Skipping file, unsupported extension")
|
||||||
// noop
|
|
||||||
default:
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -627,3 +632,12 @@ func readFile(filename string) (string, error) {
|
|||||||
}
|
}
|
||||||
return "", fmt.Errorf("invalid filename: %s", filename)
|
return "", fmt.Errorf("invalid filename: %s", filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isFileSupported(filename string) bool {
|
||||||
|
switch strings.ToLower(filepath.Ext(filename)) {
|
||||||
|
case ".toml", ".yaml", ".yml":
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -197,6 +197,38 @@ func TestProvideWithWatch(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestProvideWatchWithNonConfigDanglingSymlink(t *testing.T) {
|
||||||
|
tempDir := t.TempDir()
|
||||||
|
|
||||||
|
err := copyFile("./fixtures/yaml/simple_file_01.yml", filepath.Join(tempDir, "simple_file_01.yml"))
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
err = os.Symlink(filepath.Join(tempDir, "non_existent_file.txt"), filepath.Join(tempDir, "dangling_symlink.txt"))
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
provider := &Provider{
|
||||||
|
Directory: tempDir,
|
||||||
|
Watch: true,
|
||||||
|
}
|
||||||
|
configChan := make(chan dynamic.Message)
|
||||||
|
go func() {
|
||||||
|
err := provider.Provide(configChan, safe.NewPool(t.Context()))
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}()
|
||||||
|
|
||||||
|
timeout := time.After(time.Second)
|
||||||
|
select {
|
||||||
|
case conf := <-configChan:
|
||||||
|
require.NotNil(t, conf.Configuration.HTTP)
|
||||||
|
numServices := len(conf.Configuration.HTTP.Services) + len(conf.Configuration.TCP.Services) + len(conf.Configuration.UDP.Services)
|
||||||
|
numRouters := len(conf.Configuration.HTTP.Routers) + len(conf.Configuration.TCP.Routers) + len(conf.Configuration.UDP.Routers)
|
||||||
|
assert.Equal(t, 6, numServices)
|
||||||
|
assert.Equal(t, 3, numRouters)
|
||||||
|
case <-timeout:
|
||||||
|
t.Errorf("timeout while waiting for config")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func getTestCases() []ProvideTestCase {
|
func getTestCases() []ProvideTestCase {
|
||||||
return []ProvideTestCase{
|
return []ProvideTestCase{
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user