| 
									
										
										
										
											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)
 | 
					
						
							| 
									
										
										
										
											2016-10-26 10:01:52 +01:00
										 |  |  | 	for _, n := range a.Zones.Names() {
 | 
					
						
							| 
									
										
										
										
											2016-10-17 18:37:56 +01:00
										 |  |  | 		toDelete[n] = true
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-26 10:01:52 +01:00
										 |  |  | 	filepath.Walk(a.loader.directory, func(path string, info os.FileInfo, err error) error {
 | 
					
						
							| 
									
										
										
										
											2016-11-06 19:37:43 +00:00
										 |  |  | 		if info == nil || info.IsDir() {
 | 
					
						
							| 
									
										
										
										
											2016-10-17 18:37:56 +01:00
										 |  |  | 			return nil
 | 
					
						
							|  |  |  | 		}
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-26 10:01:52 +01:00
										 |  |  | 		match, origin := matches(a.loader.re, info.Name(), a.loader.template)
 | 
					
						
							| 
									
										
										
										
											2016-10-17 18:37:56 +01:00
										 |  |  | 		if !match {
 | 
					
						
							|  |  |  | 			return nil
 | 
					
						
							|  |  |  | 		}
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-03 06:20:39 -04:00
										 |  |  | 		if z, ok := a.Zones.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
 | 
					
						
							|  |  |  | 		}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		reader, err := os.Open(path)
 | 
					
						
							|  |  |  | 		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
 | 
					
						
							|  |  |  | 		}
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-29 17:50:49 +02:00
										 |  |  | 		zo.ReloadInterval = a.loader.ReloadInterval
 | 
					
						
							| 
									
										
										
										
											2018-02-16 03:44:50 -05:00
										 |  |  | 		zo.Upstream = a.loader.upstream
 | 
					
						
							| 
									
										
										
										
											2016-10-26 10:01:52 +01:00
										 |  |  | 		zo.TransferTo = a.loader.transferTo
 | 
					
						
							| 
									
										
										
										
											2016-10-17 18:37:56 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-26 10:01:52 +01:00
										 |  |  | 		a.Zones.Add(zo, origin)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if a.metrics != nil {
 | 
					
						
							|  |  |  | 			a.metrics.AddZone(origin)
 | 
					
						
							|  |  |  | 		}
 | 
					
						
							| 
									
										
										
										
											2016-10-17 18:37:56 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		zo.Notify()
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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)
 | 
					
						
							|  |  |  | 		}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		a.Zones.Remove(origin)
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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
 | 
					
						
							|  |  |  | }
 |