mirror of
				https://github.com/coredns/coredns.git
				synced 2025-10-31 02:03:20 -04:00 
			
		
		
		
	Traffic is a plugin that communicates via the xDS protocol to an Envoy control plane. Using the data from this control plane it hands out IP addresses. This allows you (via controlling the data in the control plane) to drain or send more traffic to specific endpoints. The plugin itself only acts upon this data; it doesn't do anything fancy by itself. Code used here is copied from grpc-go and other places, this is clearly marked in the source files. Signed-off-by: Miek Gieben <miek@miek.nl>
		
			
				
	
	
		
			123 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			123 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package traffic
 | |
| 
 | |
| import (
 | |
| 	"crypto/tls"
 | |
| 	"fmt"
 | |
| 	"math/rand"
 | |
| 	"strings"
 | |
| 	"time"
 | |
| 
 | |
| 	"github.com/coredns/coredns/core/dnsserver"
 | |
| 	"github.com/coredns/coredns/plugin"
 | |
| 	clog "github.com/coredns/coredns/plugin/pkg/log"
 | |
| 	"github.com/coredns/coredns/plugin/pkg/parse"
 | |
| 	pkgtls "github.com/coredns/coredns/plugin/pkg/tls"
 | |
| 	"github.com/coredns/coredns/plugin/pkg/transport"
 | |
| 	"github.com/coredns/coredns/plugin/traffic/xds"
 | |
| 
 | |
| 	"github.com/caddyserver/caddy"
 | |
| 	"google.golang.org/grpc"
 | |
| 	"google.golang.org/grpc/credentials"
 | |
| )
 | |
| 
 | |
| var log = clog.NewWithPlugin("traffic")
 | |
| 
 | |
| func init() { plugin.Register("traffic", setup) }
 | |
| 
 | |
| func setup(c *caddy.Controller) error {
 | |
| 	rand.Seed(int64(time.Now().Nanosecond()))
 | |
| 	t, err := parseTraffic(c)
 | |
| 	if err != nil {
 | |
| 		return plugin.Error("traffic", err)
 | |
| 	}
 | |
| 
 | |
| 	dnsserver.GetConfig(c).AddPlugin(func(next plugin.Handler) plugin.Handler {
 | |
| 		t.Next = next
 | |
| 		return t
 | |
| 	})
 | |
| 
 | |
| 	c.OnStartup(func() error {
 | |
| 		go t.c.Run()
 | |
| 		return nil
 | |
| 	})
 | |
| 	c.OnShutdown(func() error { return t.c.Stop() })
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func parseTraffic(c *caddy.Controller) (*Traffic, error) {
 | |
| 	node := "coredns"
 | |
| 	toHosts := []string{}
 | |
| 	t := &Traffic{}
 | |
| 	var (
 | |
| 		err           error
 | |
| 		tlsConfig     *tls.Config
 | |
| 		tlsServerName string
 | |
| 	)
 | |
| 
 | |
| 	t.origins = make([]string, len(c.ServerBlockKeys))
 | |
| 	for i := range c.ServerBlockKeys {
 | |
| 		t.origins[i] = plugin.Host(c.ServerBlockKeys[i]).Normalize()
 | |
| 	}
 | |
| 
 | |
| 	for c.Next() {
 | |
| 		args := c.RemainingArgs()
 | |
| 		if len(args) < 1 {
 | |
| 			return nil, c.ArgErr()
 | |
| 		}
 | |
| 		toHosts, err = parse.HostPortOrFile(args...)
 | |
| 		if err != nil {
 | |
| 			return nil, err
 | |
| 		}
 | |
| 		for i := range toHosts {
 | |
| 			if !strings.HasPrefix(toHosts[i], transport.GRPC+"://") {
 | |
| 				return nil, fmt.Errorf("not a %s scheme: %s", transport.GRPC, toHosts[i])
 | |
| 			}
 | |
| 			// now cut the prefix off again, because the dialler needs to see normal address strings. All this
 | |
| 			// grpc:// stuff is to enforce uniform across plugins and future proofing for other protocols.
 | |
| 			toHosts[i] = toHosts[i][len(transport.GRPC+"://"):]
 | |
| 		}
 | |
| 		for c.NextBlock() {
 | |
| 			switch c.Val() {
 | |
| 			case "id":
 | |
| 				args := c.RemainingArgs()
 | |
| 				if len(args) != 1 {
 | |
| 					return nil, c.ArgErr()
 | |
| 				}
 | |
| 				node = args[0]
 | |
| 			case "tls":
 | |
| 				args := c.RemainingArgs()
 | |
| 				if len(args) > 3 {
 | |
| 					return nil, c.ArgErr()
 | |
| 				}
 | |
| 
 | |
| 				tlsConfig, err = pkgtls.NewTLSConfigFromArgs(args...)
 | |
| 				if err != nil {
 | |
| 					return nil, err
 | |
| 				}
 | |
| 			case "tls_servername":
 | |
| 				if !c.NextArg() {
 | |
| 					return nil, c.ArgErr()
 | |
| 				}
 | |
| 				tlsServerName = c.Val()
 | |
| 			default:
 | |
| 				return nil, c.Errf("unknown property '%s'", c.Val())
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	opts := []grpc.DialOption{grpc.WithInsecure()}
 | |
| 	if tlsConfig != nil {
 | |
| 		if tlsServerName != "" {
 | |
| 			tlsConfig.ServerName = tlsServerName
 | |
| 		}
 | |
| 		opts = []grpc.DialOption{grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig))}
 | |
| 	}
 | |
| 
 | |
| 	// TODO: only the first host is used, need to figure out how to reconcile multiple upstream providers.
 | |
| 	if t.c, err = xds.New(toHosts[0], node, opts...); err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	return t, nil
 | |
| }
 |