mirror of
https://github.com/prometheus/prometheus.git
synced 2025-01-12 14:27:27 -08:00
Add support for A record based DNS SD
If using A records, the user needs to specify "port" and set "type" to "A".
This commit is contained in:
parent
d437fce299
commit
9ab340e95e
|
@ -80,6 +80,7 @@ var (
|
|||
// The default DNS SD configuration.
|
||||
DefaultDNSSDConfig = DNSSDConfig{
|
||||
RefreshInterval: Duration(30 * time.Second),
|
||||
Type: "SRV",
|
||||
}
|
||||
|
||||
// The default file SD configuration.
|
||||
|
@ -362,7 +363,8 @@ func (tg *TargetGroup) UnmarshalJSON(b []byte) error {
|
|||
type DNSSDConfig struct {
|
||||
Names []string `yaml:"names"`
|
||||
RefreshInterval Duration `yaml:"refresh_interval,omitempty"`
|
||||
|
||||
Type string `yaml:"type"`
|
||||
Port int `yaml:"port"` // Ignored for SRV records
|
||||
// Catches all undefined fields and must be empty after parsing.
|
||||
XXX map[string]interface{} `yaml:",inline"`
|
||||
}
|
||||
|
@ -378,6 +380,15 @@ func (c *DNSSDConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
|||
if len(c.Names) == 0 {
|
||||
return fmt.Errorf("DNS-SD config must contain at least one SRV record name")
|
||||
}
|
||||
switch strings.ToUpper(c.Type) {
|
||||
case "SRV":
|
||||
case "A", "AAAA":
|
||||
if c.Port == 0 {
|
||||
return fmt.Errorf("a port is required in DNS-SD configs for all record types except SRV")
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("invalid DNS-SD records type %s", c.Type)
|
||||
}
|
||||
return checkOverflow(c.XXX, "dns_sd_config")
|
||||
}
|
||||
|
||||
|
|
|
@ -98,12 +98,14 @@ var expectedConf = &Config{
|
|||
"second.dns.address.domain.com",
|
||||
},
|
||||
RefreshInterval: Duration(15 * time.Second),
|
||||
Type: "SRV",
|
||||
},
|
||||
{
|
||||
Names: []string{
|
||||
"first.dns.address.domain.com",
|
||||
},
|
||||
RefreshInterval: Duration(30 * time.Second),
|
||||
Type: "SRV",
|
||||
},
|
||||
},
|
||||
|
||||
|
|
|
@ -68,14 +68,27 @@ type DNSDiscovery struct {
|
|||
done chan struct{}
|
||||
ticker *time.Ticker
|
||||
m sync.RWMutex
|
||||
port int
|
||||
qtype uint16
|
||||
}
|
||||
|
||||
// NewDNSDiscovery returns a new DNSDiscovery which periodically refreshes its targets.
|
||||
func NewDNSDiscovery(conf *config.DNSSDConfig) *DNSDiscovery {
|
||||
qtype := dns.TypeSRV
|
||||
switch strings.ToUpper(conf.Type) {
|
||||
case "A":
|
||||
qtype = dns.TypeA
|
||||
case "AAAA":
|
||||
qtype = dns.TypeAAAA
|
||||
case "SRV":
|
||||
qtype = dns.TypeSRV
|
||||
}
|
||||
return &DNSDiscovery{
|
||||
names: conf.Names,
|
||||
done: make(chan struct{}),
|
||||
ticker: time.NewTicker(time.Duration(conf.RefreshInterval)),
|
||||
qtype: qtype,
|
||||
port: conf.Port,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -130,7 +143,7 @@ func (dd *DNSDiscovery) refreshAll(ch chan<- *config.TargetGroup) {
|
|||
}
|
||||
|
||||
func (dd *DNSDiscovery) refresh(name string, ch chan<- *config.TargetGroup) error {
|
||||
response, err := lookupSRV(name)
|
||||
response, err := lookupAll(name, dd.qtype)
|
||||
dnsSDLookupsCount.Inc()
|
||||
if err != nil {
|
||||
dnsSDLookupFailuresCount.Inc()
|
||||
|
@ -139,15 +152,22 @@ func (dd *DNSDiscovery) refresh(name string, ch chan<- *config.TargetGroup) erro
|
|||
|
||||
tg := &config.TargetGroup{}
|
||||
for _, record := range response.Answer {
|
||||
addr, ok := record.(*dns.SRV)
|
||||
if !ok {
|
||||
target := clientmodel.LabelValue("")
|
||||
switch addr := record.(type) {
|
||||
case *dns.SRV:
|
||||
// Remove the final dot from rooted DNS names to make them look more usual.
|
||||
addr.Target = strings.TrimRight(addr.Target, ".")
|
||||
|
||||
target = clientmodel.LabelValue(fmt.Sprintf("%s:%d", addr.Target, addr.Port))
|
||||
case *dns.A:
|
||||
target = clientmodel.LabelValue(fmt.Sprintf("%s:%d", addr.A, dd.port))
|
||||
case *dns.AAAA:
|
||||
target = clientmodel.LabelValue(fmt.Sprintf("%s:%d", addr.AAAA, dd.port))
|
||||
default:
|
||||
log.Warnf("%q is not a valid SRV record", record)
|
||||
continue
|
||||
}
|
||||
// Remove the final dot from rooted DNS names to make them look more usual.
|
||||
addr.Target = strings.TrimRight(addr.Target, ".")
|
||||
|
||||
target := clientmodel.LabelValue(fmt.Sprintf("%s:%d", addr.Target, addr.Port))
|
||||
}
|
||||
tg.Targets = append(tg.Targets, clientmodel.LabelSet{
|
||||
clientmodel.AddressLabel: target,
|
||||
DNSNameLabel: clientmodel.LabelValue(name),
|
||||
|
@ -160,7 +180,7 @@ func (dd *DNSDiscovery) refresh(name string, ch chan<- *config.TargetGroup) erro
|
|||
return nil
|
||||
}
|
||||
|
||||
func lookupSRV(name string) (*dns.Msg, error) {
|
||||
func lookupAll(name string, qtype uint16) (*dns.Msg, error) {
|
||||
conf, err := dns.ClientConfigFromFile(resolvConf)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not load resolv.conf: %s", err)
|
||||
|
@ -172,7 +192,7 @@ func lookupSRV(name string) (*dns.Msg, error) {
|
|||
for _, server := range conf.Servers {
|
||||
servAddr := net.JoinHostPort(server, conf.Port)
|
||||
for _, suffix := range conf.Search {
|
||||
response, err = lookup(name, dns.TypeSRV, client, servAddr, suffix, false)
|
||||
response, err = lookup(name, qtype, client, servAddr, suffix, false)
|
||||
if err != nil {
|
||||
log.Warnf("resolving %s.%s failed: %s", name, suffix, err)
|
||||
continue
|
||||
|
@ -181,7 +201,7 @@ func lookupSRV(name string) (*dns.Msg, error) {
|
|||
return response, nil
|
||||
}
|
||||
}
|
||||
response, err = lookup(name, dns.TypeSRV, client, servAddr, "", false)
|
||||
response, err = lookup(name, qtype, client, servAddr, "", false)
|
||||
if err == nil {
|
||||
return response, nil
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue