2016-10-17 18:37:56 +01:00
package auto
import (
"os"
"path/filepath"
"regexp"
2017-09-14 09:36:06 +01:00
"github.com/coredns/coredns/plugin/file"
2016-10-17 18:37:56 +01:00
"github.com/miekg/dns"
)
// Walk will recursively walk of the file under l.directory and adds the one that match l.re.
2016-10-26 10:01:52 +01:00
func ( a Auto ) Walk ( ) error {
2016-10-17 18:37:56 +01:00
// TODO(miek): should add something so that we don't stomp on each other.
toDelete := make ( map [ string ] bool )
2025-04-04 20:27:39 +02:00
for _ , n := range a . Names ( ) {
2016-10-17 18:37:56 +01:00
toDelete [ n ] = true
}
2025-04-04 20:27:39 +02:00
filepath . Walk ( a . directory , func ( path string , info os . FileInfo , e error ) error {
2023-12-04 12:51:50 -05:00
if e != nil {
log . Warningf ( "error reading %v: %v" , path , e )
}
2016-11-06 19:37:43 +00:00
if info == nil || info . IsDir ( ) {
2016-10-17 18:37:56 +01:00
return nil
}
2025-04-04 20:27:39 +02:00
match , origin := matches ( a . re , info . Name ( ) , a . template )
2016-10-17 18:37:56 +01:00
if ! match {
return nil
}
2025-04-04 20:27:39 +02:00
if z , ok := a . Z [ origin ] ; ok {
2016-10-17 18:37:56 +01:00
// we already have this zone
toDelete [ origin ] = false
2018-07-03 06:20:39 -04:00
z . SetFile ( path )
2016-10-17 18:37:56 +01:00
return nil
}
2026-03-06 21:50:24 +02:00
reader , err := os . Open ( filepath . Clean ( path ) ) //nolint:gosec // G122: path is from filepath.Walk rooted in a.directory; symlinks must be followed for configmap-style mounts
2016-10-17 18:37:56 +01:00
if err != nil {
2018-04-19 07:41:56 +01:00
log . Warningf ( "Opening %s failed: %s" , path , err )
2016-10-17 18:37:56 +01:00
return nil
}
2016-11-16 10:16:56 +00:00
defer reader . Close ( )
2016-10-17 18:37:56 +01:00
2017-06-08 18:43:11 +01:00
// Serial for loading a zone is 0, because it is a new zone.
zo , err := file . Parse ( reader , origin , path , 0 )
2016-10-17 18:37:56 +01:00
if err != nil {
2018-04-19 07:41:56 +01:00
log . Warningf ( "Parse zone `%s': %v" , origin , err )
2016-10-17 18:37:56 +01:00
return nil
}
2025-04-04 20:27:39 +02:00
zo . ReloadInterval = a . ReloadInterval
zo . Upstream = a . upstream
2016-10-17 18:37:56 +01:00
2025-04-04 20:27:39 +02:00
a . Add ( zo , origin , a . transfer )
2016-10-26 10:01:52 +01:00
if a . metrics != nil {
a . metrics . AddZone ( origin )
}
2016-10-17 18:37:56 +01:00
2018-04-19 07:41:56 +01:00
log . Infof ( "Inserting zone `%s' from: %s" , origin , path )
2016-10-17 18:37:56 +01:00
toDelete [ origin ] = false
return nil
} )
for origin , ok := range toDelete {
if ! ok {
continue
}
2016-10-26 10:01:52 +01:00
if a . metrics != nil {
a . metrics . RemoveZone ( origin )
}
2025-04-04 20:27:39 +02:00
a . Remove ( origin )
2016-10-26 10:01:52 +01:00
2018-04-19 07:41:56 +01:00
log . Infof ( "Deleting zone `%s'" , origin )
2016-10-17 18:37:56 +01:00
}
return nil
}
2019-02-20 19:12:21 +07:00
// matches re to filename, if it is a match, the subexpression will be used to expand
2016-10-17 18:37:56 +01:00
// template to an origin. When match is true that origin is returned. Origin is fully qualified.
func matches ( re * regexp . Regexp , filename , template string ) ( match bool , origin string ) {
2018-10-21 15:59:37 +02:00
base := filepath . Base ( filename )
2016-10-17 18:37:56 +01:00
matches := re . FindStringSubmatchIndex ( base )
if matches == nil {
return false , ""
}
by := re . ExpandString ( nil , template , base , matches )
if by == nil {
return false , ""
}
origin = dns . Fqdn ( string ( by ) )
return true , origin
}