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
|
||||
continue
|
||||
}
|
||||
if !isFileSupported(entry.Name()) {
|
||||
// ignore unsupported file extension
|
||||
continue
|
||||
}
|
||||
watchItems = append(watchItems, path.Join(p.Directory, entry.Name()))
|
||||
}
|
||||
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)
|
||||
default:
|
||||
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)
|
||||
err = watcher.Add(item)
|
||||
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
|
||||
}
|
||||
|
||||
switch strings.ToLower(filepath.Ext(item.Name())) {
|
||||
case ".toml", ".yaml", ".yml":
|
||||
// noop
|
||||
default:
|
||||
if !isFileSupported(item.Name()) {
|
||||
logger.Debug().Msg("Skipping file, unsupported extension")
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -627,3 +632,12 @@ func readFile(filename string) (string, error) {
|
||||
}
|
||||
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 {
|
||||
return []ProvideTestCase{
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user