| 
									
										
										
										
											2017-08-09 03:13:38 -07:00
										 |  |  | package autopath | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"fmt" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/coredns/coredns/core/dnsserver" | 
					
						
							| 
									
										
										
										
											2017-09-14 09:36:06 +01:00
										 |  |  | 	"github.com/coredns/coredns/plugin" | 
					
						
							|  |  |  | 	"github.com/coredns/coredns/plugin/erratic" | 
					
						
							|  |  |  | 	"github.com/coredns/coredns/plugin/kubernetes" | 
					
						
							| 
									
										
										
										
											2017-08-09 03:13:38 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/mholt/caddy" | 
					
						
							|  |  |  | 	"github.com/miekg/dns" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func init() { | 
					
						
							|  |  |  | 	caddy.RegisterPlugin("autopath", caddy.Plugin{ | 
					
						
							|  |  |  | 		ServerType: "dns", | 
					
						
							|  |  |  | 		Action:     setup, | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func setup(c *caddy.Controller) error { | 
					
						
							| 
									
										
										
										
											2017-08-10 21:31:36 +01:00
										 |  |  | 	ap, mw, err := autoPathParse(c) | 
					
						
							| 
									
										
										
										
											2017-08-09 03:13:38 -07:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2017-09-14 09:36:06 +01:00
										 |  |  | 		return plugin.Error("autopath", err) | 
					
						
							| 
									
										
										
										
											2017-08-09 03:13:38 -07:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-14 09:36:06 +01:00
										 |  |  | 	// Do this in OnStartup, so all plugin has been initialized. | 
					
						
							| 
									
										
										
										
											2017-08-09 03:13:38 -07:00
										 |  |  | 	c.OnStartup(func() error { | 
					
						
							| 
									
										
										
										
											2017-08-22 14:21:42 +01:00
										 |  |  | 		m := dnsserver.GetConfig(c).Handler(mw) | 
					
						
							| 
									
										
										
										
											2017-08-10 21:31:36 +01:00
										 |  |  | 		if m == nil { | 
					
						
							|  |  |  | 			return nil | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-09-06 23:28:41 +01:00
										 |  |  | 		if x, ok := m.(*kubernetes.Kubernetes); ok { | 
					
						
							| 
									
										
										
										
											2017-08-18 12:57:23 +01:00
										 |  |  | 			ap.searchFunc = x.AutoPath | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if x, ok := m.(*erratic.Erratic); ok { | 
					
						
							|  |  |  | 			ap.searchFunc = x.AutoPath | 
					
						
							| 
									
										
										
										
											2017-08-10 21:31:36 +01:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2017-08-09 03:13:38 -07:00
										 |  |  | 		return nil | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-14 09:36:06 +01:00
										 |  |  | 	dnsserver.GetConfig(c).AddPlugin(func(next plugin.Handler) plugin.Handler { | 
					
						
							| 
									
										
										
										
											2017-08-09 03:13:38 -07:00
										 |  |  | 		ap.Next = next | 
					
						
							|  |  |  | 		return ap | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-16 14:13:28 +01:00
										 |  |  | // allowedPlugins has a list of plugin that can be used by autopath. | 
					
						
							|  |  |  | var allowedPlugins = map[string]bool{ | 
					
						
							| 
									
										
										
										
											2017-08-09 03:13:38 -07:00
										 |  |  | 	"@kubernetes": true, | 
					
						
							| 
									
										
										
										
											2017-08-18 12:57:23 +01:00
										 |  |  | 	"@erratic":    true, | 
					
						
							| 
									
										
										
										
											2017-08-09 03:13:38 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func autoPathParse(c *caddy.Controller) (*AutoPath, string, error) { | 
					
						
							| 
									
										
										
										
											2017-08-10 19:27:54 +01:00
										 |  |  | 	ap := &AutoPath{} | 
					
						
							| 
									
										
										
										
											2017-08-09 03:13:38 -07:00
										 |  |  | 	mw := "" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for c.Next() { | 
					
						
							|  |  |  | 		zoneAndresolv := c.RemainingArgs() | 
					
						
							|  |  |  | 		if len(zoneAndresolv) < 1 { | 
					
						
							| 
									
										
										
										
											2017-08-10 19:27:54 +01:00
										 |  |  | 			return ap, "", fmt.Errorf("no resolv-conf specified") | 
					
						
							| 
									
										
										
										
											2017-08-09 03:13:38 -07:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		resolv := zoneAndresolv[len(zoneAndresolv)-1] | 
					
						
							|  |  |  | 		if resolv[0] == '@' { | 
					
						
							| 
									
										
										
										
											2017-09-16 14:13:28 +01:00
										 |  |  | 			_, ok := allowedPlugins[resolv] | 
					
						
							| 
									
										
										
										
											2017-08-09 03:13:38 -07:00
										 |  |  | 			if ok { | 
					
						
							|  |  |  | 				mw = resolv[1:] | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			// assume file on disk | 
					
						
							|  |  |  | 			rc, err := dns.ClientConfigFromFile(resolv) | 
					
						
							|  |  |  | 			if err != nil { | 
					
						
							| 
									
										
										
										
											2017-08-10 19:27:54 +01:00
										 |  |  | 				return ap, "", fmt.Errorf("failed to parse %q: %v", resolv, err) | 
					
						
							| 
									
										
										
										
											2017-08-09 03:13:38 -07:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			ap.search = rc.Search | 
					
						
							| 
									
										
										
										
											2017-09-14 09:36:06 +01:00
										 |  |  | 			plugin.Zones(ap.search).Normalize() | 
					
						
							| 
									
										
										
										
											2017-08-09 03:13:38 -07:00
										 |  |  | 			ap.search = append(ap.search, "") // sentinal value as demanded. | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		ap.Zones = zoneAndresolv[:len(zoneAndresolv)-1] | 
					
						
							|  |  |  | 		if len(ap.Zones) == 0 { | 
					
						
							|  |  |  | 			ap.Zones = make([]string, len(c.ServerBlockKeys)) | 
					
						
							|  |  |  | 			copy(ap.Zones, c.ServerBlockKeys) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		for i, str := range ap.Zones { | 
					
						
							| 
									
										
										
										
											2017-09-14 09:36:06 +01:00
										 |  |  | 			ap.Zones[i] = plugin.Host(str).Normalize() | 
					
						
							| 
									
										
										
										
											2017-08-09 03:13:38 -07:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return ap, mw, nil | 
					
						
							|  |  |  | } |