mirror of
https://github.com/coredns/coredns.git
synced 2026-08-20 23:08:28 -04:00
Use net.JoinHostPort rather than string concatenation to support both ipv4, ipv6, and hostname service endpoints for the trace plugin. Previously, ipv6 bind addresses in the coredns configuration would fail to be parsed, as the ipv6 address was not surrounded in brackets. Signed-off-by: Michael Wolf <mwolf@cloudflare.com> Closes #8409 Co-authored-by: Michael Wolf <mwolf@cloudflare.com>
168 lines
3.7 KiB
Go
168 lines
3.7 KiB
Go
package trace
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/coredns/caddy"
|
|
"github.com/coredns/coredns/core/dnsserver"
|
|
"github.com/coredns/coredns/plugin"
|
|
)
|
|
|
|
func init() { plugin.Register("trace", setup) }
|
|
|
|
func setup(c *caddy.Controller) error {
|
|
t, err := traceParse(c)
|
|
if err != nil {
|
|
return plugin.Error("trace", err)
|
|
}
|
|
|
|
dnsserver.GetConfig(c).AddPlugin(func(next plugin.Handler) plugin.Handler {
|
|
t.Next = next
|
|
return t
|
|
})
|
|
|
|
c.OnStartup(t.OnStartup)
|
|
c.OnShutdown(t.OnShutdown)
|
|
|
|
return nil
|
|
}
|
|
|
|
func traceParse(c *caddy.Controller) (*trace, error) {
|
|
var (
|
|
tr = &trace{every: 1, serviceName: defServiceName}
|
|
err error
|
|
)
|
|
|
|
cfg := dnsserver.GetConfig(c)
|
|
if len(cfg.ListenHosts) > 0 && cfg.ListenHosts[0] != "" {
|
|
tr.serviceEndpoint = net.JoinHostPort(cfg.ListenHosts[0], cfg.Port)
|
|
}
|
|
|
|
for c.Next() { // trace
|
|
var err error
|
|
args := c.RemainingArgs()
|
|
switch len(args) {
|
|
case 0:
|
|
tr.EndpointType, tr.Endpoint, err = normalizeEndpoint(defEpType, "")
|
|
case 1:
|
|
tr.EndpointType, tr.Endpoint, err = normalizeEndpoint(defEpType, args[0])
|
|
case 2:
|
|
epType := strings.ToLower(args[0])
|
|
tr.EndpointType, tr.Endpoint, err = normalizeEndpoint(epType, args[1])
|
|
default:
|
|
err = c.ArgErr()
|
|
}
|
|
if err != nil {
|
|
return tr, err
|
|
}
|
|
for c.NextBlock() {
|
|
switch c.Val() {
|
|
case "every":
|
|
args := c.RemainingArgs()
|
|
if len(args) != 1 {
|
|
return nil, c.ArgErr()
|
|
}
|
|
tr.every, err = strconv.ParseUint(args[0], 10, 64)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
case "service":
|
|
args := c.RemainingArgs()
|
|
if len(args) != 1 {
|
|
return nil, c.ArgErr()
|
|
}
|
|
tr.serviceName = args[0]
|
|
case "client_server":
|
|
args := c.RemainingArgs()
|
|
if len(args) > 1 {
|
|
return nil, c.ArgErr()
|
|
}
|
|
tr.clientServer = true
|
|
if len(args) == 1 {
|
|
tr.clientServer, err = strconv.ParseBool(args[0])
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
case "datadog_analytics_rate":
|
|
args := c.RemainingArgs()
|
|
if len(args) > 1 {
|
|
return nil, c.ArgErr()
|
|
}
|
|
tr.datadogAnalyticsRate = 0
|
|
if len(args) == 1 {
|
|
tr.datadogAnalyticsRate, err = strconv.ParseFloat(args[0], 64)
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if tr.datadogAnalyticsRate > 1 || tr.datadogAnalyticsRate < 0 {
|
|
return nil, fmt.Errorf("datadog analytics rate must be between 0 and 1, '%f' is not supported", tr.datadogAnalyticsRate)
|
|
}
|
|
case "zipkin_max_backlog_size":
|
|
args := c.RemainingArgs()
|
|
if len(args) != 1 {
|
|
return nil, c.ArgErr()
|
|
}
|
|
tr.zipkinMaxBacklogSize, err = strconv.Atoi(args[0])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
case "zipkin_max_batch_size":
|
|
args := c.RemainingArgs()
|
|
if len(args) != 1 {
|
|
return nil, c.ArgErr()
|
|
}
|
|
tr.zipkinMaxBatchSize, err = strconv.Atoi(args[0])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
case "zipkin_max_batch_interval":
|
|
args := c.RemainingArgs()
|
|
if len(args) != 1 {
|
|
return nil, c.ArgErr()
|
|
}
|
|
tr.zipkinMaxBatchInterval, err = time.ParseDuration(args[0])
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
default:
|
|
return nil, c.Errf("unknown property '%s'", c.Val())
|
|
}
|
|
}
|
|
}
|
|
return tr, err
|
|
}
|
|
|
|
func normalizeEndpoint(epType, ep string) (string, string, error) {
|
|
if _, ok := supportedProviders[epType]; !ok {
|
|
return "", "", fmt.Errorf("tracing endpoint type '%s' is not supported", epType)
|
|
}
|
|
|
|
if ep == "" {
|
|
ep = supportedProviders[epType]
|
|
}
|
|
|
|
if epType == "zipkin" {
|
|
if !strings.Contains(ep, "http") {
|
|
ep = "http://" + ep + "/api/v2/spans"
|
|
}
|
|
}
|
|
|
|
return epType, ep, nil
|
|
}
|
|
|
|
var supportedProviders = map[string]string{
|
|
"zipkin": "localhost:9411",
|
|
"datadog": "localhost:8126",
|
|
}
|
|
|
|
const (
|
|
defEpType = "zipkin"
|
|
defServiceName = "coredns"
|
|
)
|