mirror of
https://github.com/kubernetes-sigs/external-dns.git
synced 2025-08-07 01:56:57 +02:00
Allow multiple RFC2136 zones
This commit is contained in:
parent
bc22050579
commit
4794c01c6f
@ -227,6 +227,7 @@ spec:
|
|||||||
- --rfc2136-host=192.168.0.1
|
- --rfc2136-host=192.168.0.1
|
||||||
- --rfc2136-port=53
|
- --rfc2136-port=53
|
||||||
- --rfc2136-zone=k8s.example.org
|
- --rfc2136-zone=k8s.example.org
|
||||||
|
- --rfc2136-zone=k8s.your-zone.org
|
||||||
- --rfc2136-tsig-secret=96Ah/a2g0/nLeFGK+d/0tzQcccf9hCEIy34PoXX2Qg8=
|
- --rfc2136-tsig-secret=96Ah/a2g0/nLeFGK+d/0tzQcccf9hCEIy34PoXX2Qg8=
|
||||||
- --rfc2136-tsig-secret-alg=hmac-sha256
|
- --rfc2136-tsig-secret-alg=hmac-sha256
|
||||||
- --rfc2136-tsig-keyname=externaldns-key
|
- --rfc2136-tsig-keyname=externaldns-key
|
||||||
@ -269,6 +270,7 @@ spec:
|
|||||||
- --rfc2136-host=192.168.0.1
|
- --rfc2136-host=192.168.0.1
|
||||||
- --rfc2136-port=53
|
- --rfc2136-port=53
|
||||||
- --rfc2136-zone=k8s.example.org
|
- --rfc2136-zone=k8s.example.org
|
||||||
|
- --rfc2136-zone=k8s.your-zone.org
|
||||||
- --rfc2136-tsig-secret=96Ah/a2g0/nLeFGK+d/0tzQcccf9hCEIy34PoXX2Qg8=
|
- --rfc2136-tsig-secret=96Ah/a2g0/nLeFGK+d/0tzQcccf9hCEIy34PoXX2Qg8=
|
||||||
- --rfc2136-tsig-secret-alg=hmac-sha256
|
- --rfc2136-tsig-secret-alg=hmac-sha256
|
||||||
- --rfc2136-tsig-keyname=externaldns-key
|
- --rfc2136-tsig-keyname=externaldns-key
|
||||||
@ -299,6 +301,7 @@ You'll want to configure `external-dns` similarly to the following:
|
|||||||
- --rfc2136-host=192.168.0.1
|
- --rfc2136-host=192.168.0.1
|
||||||
- --rfc2136-port=53
|
- --rfc2136-port=53
|
||||||
- --rfc2136-zone=k8s.example.org
|
- --rfc2136-zone=k8s.example.org
|
||||||
|
- --rfc2136-zone=k8s.your-zone.org
|
||||||
- --rfc2136-insecure
|
- --rfc2136-insecure
|
||||||
- --rfc2136-tsig-axfr # needed to enable zone transfers, which is required for deletion of records.
|
- --rfc2136-tsig-axfr # needed to enable zone transfers, which is required for deletion of records.
|
||||||
...
|
...
|
||||||
@ -384,6 +387,7 @@ You'll want to configure `external-dns` similarly to the following:
|
|||||||
- --rfc2136-host=dns-host.yourdomain.com
|
- --rfc2136-host=dns-host.yourdomain.com
|
||||||
- --rfc2136-port=53
|
- --rfc2136-port=53
|
||||||
- --rfc2136-zone=your-zone.com
|
- --rfc2136-zone=your-zone.com
|
||||||
|
- --rfc2136-zone=your-secondary-zone.com
|
||||||
- --rfc2136-kerberos-username=your-domain-account
|
- --rfc2136-kerberos-username=your-domain-account
|
||||||
- --rfc2136-kerberos-password=your-domain-password
|
- --rfc2136-kerberos-password=your-domain-password
|
||||||
- --rfc2136-kerberos-realm=your-domain.com
|
- --rfc2136-kerberos-realm=your-domain.com
|
||||||
|
@ -175,7 +175,7 @@ type Config struct {
|
|||||||
ResolveServiceLoadBalancerHostname bool
|
ResolveServiceLoadBalancerHostname bool
|
||||||
RFC2136Host string
|
RFC2136Host string
|
||||||
RFC2136Port int
|
RFC2136Port int
|
||||||
RFC2136Zone string
|
RFC2136Zone []string
|
||||||
RFC2136Insecure bool
|
RFC2136Insecure bool
|
||||||
RFC2136GSSTSIG bool
|
RFC2136GSSTSIG bool
|
||||||
RFC2136KerberosRealm string
|
RFC2136KerberosRealm string
|
||||||
@ -330,7 +330,7 @@ var defaultConfig = &Config{
|
|||||||
CFPassword: "",
|
CFPassword: "",
|
||||||
RFC2136Host: "",
|
RFC2136Host: "",
|
||||||
RFC2136Port: 0,
|
RFC2136Port: 0,
|
||||||
RFC2136Zone: "",
|
RFC2136Zone: []string{},
|
||||||
RFC2136Insecure: false,
|
RFC2136Insecure: false,
|
||||||
RFC2136GSSTSIG: false,
|
RFC2136GSSTSIG: false,
|
||||||
RFC2136KerberosRealm: "",
|
RFC2136KerberosRealm: "",
|
||||||
@ -558,7 +558,7 @@ func (cfg *Config) ParseFlags(args []string) error {
|
|||||||
// Flags related to RFC2136 provider
|
// Flags related to RFC2136 provider
|
||||||
app.Flag("rfc2136-host", "When using the RFC2136 provider, specify the host of the DNS server").Default(defaultConfig.RFC2136Host).StringVar(&cfg.RFC2136Host)
|
app.Flag("rfc2136-host", "When using the RFC2136 provider, specify the host of the DNS server").Default(defaultConfig.RFC2136Host).StringVar(&cfg.RFC2136Host)
|
||||||
app.Flag("rfc2136-port", "When using the RFC2136 provider, specify the port of the DNS server").Default(strconv.Itoa(defaultConfig.RFC2136Port)).IntVar(&cfg.RFC2136Port)
|
app.Flag("rfc2136-port", "When using the RFC2136 provider, specify the port of the DNS server").Default(strconv.Itoa(defaultConfig.RFC2136Port)).IntVar(&cfg.RFC2136Port)
|
||||||
app.Flag("rfc2136-zone", "When using the RFC2136 provider, specify the zone entry of the DNS server to use").Default(defaultConfig.RFC2136Zone).StringVar(&cfg.RFC2136Zone)
|
app.Flag("rfc2136-zone", "When using the RFC2136 provider, specify zone entries of the DNS server to use").StringsVar(&cfg.RFC2136Zone)
|
||||||
app.Flag("rfc2136-insecure", "When using the RFC2136 provider, specify whether to attach TSIG or not (default: false, requires --rfc2136-tsig-keyname and rfc2136-tsig-secret)").Default(strconv.FormatBool(defaultConfig.RFC2136Insecure)).BoolVar(&cfg.RFC2136Insecure)
|
app.Flag("rfc2136-insecure", "When using the RFC2136 provider, specify whether to attach TSIG or not (default: false, requires --rfc2136-tsig-keyname and rfc2136-tsig-secret)").Default(strconv.FormatBool(defaultConfig.RFC2136Insecure)).BoolVar(&cfg.RFC2136Insecure)
|
||||||
app.Flag("rfc2136-tsig-keyname", "When using the RFC2136 provider, specify the TSIG key to attached to DNS messages (required when --rfc2136-insecure=false)").Default(defaultConfig.RFC2136TSIGKeyName).StringVar(&cfg.RFC2136TSIGKeyName)
|
app.Flag("rfc2136-tsig-keyname", "When using the RFC2136 provider, specify the TSIG key to attached to DNS messages (required when --rfc2136-insecure=false)").Default(defaultConfig.RFC2136TSIGKeyName).StringVar(&cfg.RFC2136TSIGKeyName)
|
||||||
app.Flag("rfc2136-tsig-secret", "When using the RFC2136 provider, specify the TSIG (base64) value to attached to DNS messages (required when --rfc2136-insecure=false)").Default(defaultConfig.RFC2136TSIGSecret).StringVar(&cfg.RFC2136TSIGSecret)
|
app.Flag("rfc2136-tsig-secret", "When using the RFC2136 provider, specify the TSIG (base64) value to attached to DNS messages (required when --rfc2136-insecure=false)").Default(defaultConfig.RFC2136TSIGSecret).StringVar(&cfg.RFC2136TSIGSecret)
|
||||||
|
@ -20,6 +20,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@ -45,7 +46,7 @@ const (
|
|||||||
type rfc2136Provider struct {
|
type rfc2136Provider struct {
|
||||||
provider.BaseProvider
|
provider.BaseProvider
|
||||||
nameserver string
|
nameserver string
|
||||||
zoneName string
|
zoneName []string
|
||||||
tsigKeyName string
|
tsigKeyName string
|
||||||
tsigSecret string
|
tsigSecret string
|
||||||
tsigSecretAlg string
|
tsigSecretAlg string
|
||||||
@ -81,19 +82,15 @@ type rfc2136Actions interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewRfc2136Provider is a factory function for OpenStack rfc2136 providers
|
// NewRfc2136Provider is a factory function for OpenStack rfc2136 providers
|
||||||
func NewRfc2136Provider(host string, port int, zoneName string, insecure bool, keyName string, secret string, secretAlg string, axfr bool, domainFilter endpoint.DomainFilter, dryRun bool, minTTL time.Duration, gssTsig bool, krb5Username string, krb5Password string, krb5Realm string, batchChangeSize int, actions rfc2136Actions) (provider.Provider, error) {
|
func NewRfc2136Provider(host string, port int, zoneName []string, insecure bool, keyName string, secret string, secretAlg string, axfr bool, domainFilter endpoint.DomainFilter, dryRun bool, minTTL time.Duration, gssTsig bool, krb5Username string, krb5Password string, krb5Realm string, batchChangeSize int, actions rfc2136Actions) (provider.Provider, error) {
|
||||||
secretAlgChecked, ok := tsigAlgs[secretAlg]
|
secretAlgChecked, ok := tsigAlgs[secretAlg]
|
||||||
if !ok && !insecure && !gssTsig {
|
if !ok && !insecure && !gssTsig {
|
||||||
return nil, errors.Errorf("%s is not supported TSIG algorithm", secretAlg)
|
return nil, errors.Errorf("%s is not supported TSIG algorithm", secretAlg)
|
||||||
}
|
}
|
||||||
|
|
||||||
if krb5Realm == "" {
|
|
||||||
krb5Realm = strings.ToUpper(zoneName)
|
|
||||||
}
|
|
||||||
|
|
||||||
r := &rfc2136Provider{
|
r := &rfc2136Provider{
|
||||||
nameserver: net.JoinHostPort(host, strconv.Itoa(port)),
|
nameserver: net.JoinHostPort(host, strconv.Itoa(port)),
|
||||||
zoneName: dns.Fqdn(zoneName),
|
zoneName: zoneName,
|
||||||
insecure: insecure,
|
insecure: insecure,
|
||||||
gssTsig: gssTsig,
|
gssTsig: gssTsig,
|
||||||
krb5Username: krb5Username,
|
krb5Username: krb5Username,
|
||||||
@ -209,30 +206,32 @@ func (r rfc2136Provider) List() ([]dns.RR, error) {
|
|||||||
return make([]dns.RR, 0), nil
|
return make([]dns.RR, 0), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("Fetching records for '%s'", r.zoneName)
|
|
||||||
|
|
||||||
m := new(dns.Msg)
|
|
||||||
m.SetAxfr(r.zoneName)
|
|
||||||
if !r.insecure && !r.gssTsig {
|
|
||||||
m.SetTsig(r.tsigKeyName, r.tsigSecretAlg, clockSkew, time.Now().Unix())
|
|
||||||
}
|
|
||||||
|
|
||||||
env, err := r.actions.IncomeTransfer(m, r.nameserver)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to fetch records via AXFR: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
records := make([]dns.RR, 0)
|
records := make([]dns.RR, 0)
|
||||||
for e := range env {
|
for _, zone := range r.zoneName {
|
||||||
if e.Error != nil {
|
log.Debugf("Fetching records for '%s'", zone)
|
||||||
if e.Error == dns.ErrSoa {
|
|
||||||
log.Error("AXFR error: unexpected response received from the server")
|
m := new(dns.Msg)
|
||||||
} else {
|
m.SetAxfr(dns.Fqdn(zone))
|
||||||
log.Errorf("AXFR error: %v", e.Error)
|
if !r.insecure && !r.gssTsig {
|
||||||
}
|
m.SetTsig(r.tsigKeyName, r.tsigSecretAlg, clockSkew, time.Now().Unix())
|
||||||
continue
|
}
|
||||||
|
|
||||||
|
env, err := r.actions.IncomeTransfer(m, r.nameserver)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to fetch records via AXFR: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for e := range env {
|
||||||
|
if e.Error != nil {
|
||||||
|
if e.Error == dns.ErrSoa {
|
||||||
|
log.Error("AXFR error: unexpected response received from the server")
|
||||||
|
} else {
|
||||||
|
log.Errorf("AXFR error: %v", e.Error)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
records = append(records, e.RR...)
|
||||||
}
|
}
|
||||||
records = append(records, e.RR...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return records, nil
|
return records, nil
|
||||||
@ -248,14 +247,14 @@ func (r rfc2136Provider) ApplyChanges(ctx context.Context, changes *plan.Changes
|
|||||||
log.Debugf("Processing batch %d of create changes", c)
|
log.Debugf("Processing batch %d of create changes", c)
|
||||||
|
|
||||||
m := new(dns.Msg)
|
m := new(dns.Msg)
|
||||||
m.SetUpdate(r.zoneName)
|
|
||||||
|
|
||||||
for _, ep := range chunk {
|
for _, ep := range chunk {
|
||||||
if !r.domainFilter.Match(ep.DNSName) {
|
if !r.domainFilter.Match(ep.DNSName) {
|
||||||
log.Debugf("Skipping record %s because it was filtered out by the specified --domain-filter", ep.DNSName)
|
log.Debugf("Skipping record %s because it was filtered out by the specified --domain-filter", ep.DNSName)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
findMsgZone(ep, m, &r)
|
||||||
|
|
||||||
r.AddRecord(m, ep)
|
r.AddRecord(m, ep)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,7 +273,6 @@ func (r rfc2136Provider) ApplyChanges(ctx context.Context, changes *plan.Changes
|
|||||||
log.Debugf("Processing batch %d of update changes", c)
|
log.Debugf("Processing batch %d of update changes", c)
|
||||||
|
|
||||||
m := new(dns.Msg)
|
m := new(dns.Msg)
|
||||||
m.SetUpdate(r.zoneName)
|
|
||||||
|
|
||||||
for i, ep := range chunk {
|
for i, ep := range chunk {
|
||||||
if !r.domainFilter.Match(ep.DNSName) {
|
if !r.domainFilter.Match(ep.DNSName) {
|
||||||
@ -282,6 +280,8 @@ func (r rfc2136Provider) ApplyChanges(ctx context.Context, changes *plan.Changes
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
findMsgZone(ep, m, &r)
|
||||||
|
|
||||||
r.UpdateRecord(m, changes.UpdateOld[i], ep)
|
r.UpdateRecord(m, changes.UpdateOld[i], ep)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,7 +300,6 @@ func (r rfc2136Provider) ApplyChanges(ctx context.Context, changes *plan.Changes
|
|||||||
log.Debugf("Processing batch %d of delete changes", c)
|
log.Debugf("Processing batch %d of delete changes", c)
|
||||||
|
|
||||||
m := new(dns.Msg)
|
m := new(dns.Msg)
|
||||||
m.SetUpdate(r.zoneName)
|
|
||||||
|
|
||||||
for _, ep := range chunk {
|
for _, ep := range chunk {
|
||||||
if !r.domainFilter.Match(ep.DNSName) {
|
if !r.domainFilter.Match(ep.DNSName) {
|
||||||
@ -308,6 +307,8 @@ func (r rfc2136Provider) ApplyChanges(ctx context.Context, changes *plan.Changes
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
findMsgZone(ep, m, &r)
|
||||||
|
|
||||||
r.RemoveRecord(m, ep)
|
r.RemoveRecord(m, ep)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -439,3 +440,22 @@ func chunkBy(slice []*endpoint.Endpoint, chunkSize int) [][]*endpoint.Endpoint {
|
|||||||
|
|
||||||
return chunks
|
return chunks
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func findMsgZone(ep *endpoint.Endpoint, m *dns.Msg, r *rfc2136Provider) {
|
||||||
|
sort.Slice(r.zoneName, func(i, j int) bool {
|
||||||
|
return len(strings.Split(r.zoneName[i], ".")) > len(strings.Split(r.zoneName[j], "."))
|
||||||
|
})
|
||||||
|
|
||||||
|
for _, zone := range r.zoneName {
|
||||||
|
if strings.HasSuffix(ep.DNSName, zone) {
|
||||||
|
r.krb5Realm = strings.ToUpper(dns.Fqdn(zone))
|
||||||
|
m.SetUpdate(dns.Fqdn(zone))
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("No avialable zone found for %s, set it to 'root'", ep.DNSName)
|
||||||
|
r.krb5Realm = dns.Fqdn(".")
|
||||||
|
m.SetUpdate(dns.Fqdn("."))
|
||||||
|
}
|
||||||
|
@ -95,7 +95,7 @@ func (r *rfc2136Stub) IncomeTransfer(m *dns.Msg, a string) (env chan *dns.Envelo
|
|||||||
}
|
}
|
||||||
|
|
||||||
func createRfc2136StubProvider(stub *rfc2136Stub) (provider.Provider, error) {
|
func createRfc2136StubProvider(stub *rfc2136Stub) (provider.Provider, error) {
|
||||||
return NewRfc2136Provider("", 0, "", false, "key", "secret", "hmac-sha512", true, endpoint.DomainFilter{}, false, 300*time.Second, false, "", "", "", 50, stub)
|
return NewRfc2136Provider("", 0, []string{}, false, "key", "secret", "hmac-sha512", true, endpoint.DomainFilter{}, false, 300*time.Second, false, "", "", "", 50, stub)
|
||||||
}
|
}
|
||||||
|
|
||||||
func extractAuthoritySectionFromMessage(msg fmt.Stringer) []string {
|
func extractAuthoritySectionFromMessage(msg fmt.Stringer) []string {
|
||||||
|
Loading…
Reference in New Issue
Block a user