Skip to content

Commit

Permalink
Merge 188f66e into 97421cb
Browse files Browse the repository at this point in the history
  • Loading branch information
rsliotta committed Dec 2, 2019
2 parents 97421cb + 188f66e commit 9e18632
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 3 deletions.
37 changes: 37 additions & 0 deletions docs/tutorials/coredns.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ This tutorial describes how to setup ExternalDNS for usage within a [minikube](h
You need to:
* install CoreDNS with [etcd](https://github.com/etcd-io/etcd) enabled
* install external-dns with coredns as a provider
* New: Enable on-premise ip address support for sites with external Load Balancers and Ingress
* enable ingress controller for the minikube cluster


Expand Down Expand Up @@ -233,3 +234,39 @@ dnstools# dig @10.100.4.143 nginx.example.org +short
10.0.2.15
dnstools#
```



```
## On-Prem Address Support for sites with External Load Balancer and Ingress
```

This new feature extends the CoreDNS provider to allow the internal IP Address that comes from the K8S discovery to be replaced with an IP Address from outside the cluster. This becomes extremely useful when making use of NodePort, and Ingress tied to an EXTERNAL Load Balancer such as F5, and Citrix Netscaler.

It works like this. The developer utilizes the same annotation that external DNS provides but appends a semi-colon [;] after the hostname and an IP address. This will be replaced on the ‘A’ records.

Here is an example:

```
apiVersion: v1
kind: Service
metadata:
labels:
note: External-DNS-only-see-annotation
name: xxx
namespace: default
annotations:
note: "DNS ONLY SERVICE to map a static 'A' record to a hostname in DNS"
external-dns.alpha.kubernetes.io/hostname: "xxx.subdomain.logistics.corp;10.1.43.17"
spec:
ports:
- port: 53
sessionAffinity: None
type: ClusterIP
```



The feature is enabled only when an environment variable is passed to the container so it is safe as well.

The Environment variable is 'COREDNS_ONPREM_ADDRESS_SUPPORT' and must be set to true to enable the feature.
26 changes: 23 additions & 3 deletions provider/coredns.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -27,6 +28,7 @@ import (
"math/rand"
"net"
"os"
"regexp"
"strings"
"time"

Expand Down Expand Up @@ -249,7 +251,6 @@ func NewCoreDNSProvider(domainFilter DomainFilter, prefix string, dryRun bool) (
if err != nil {
return nil, err
}

return coreDNSProvider{
client: client,
dryRun: dryRun,
Expand Down Expand Up @@ -300,6 +301,13 @@ func (p coreDNSProvider) Records() ([]*endpoint.Endpoint, error) {

// ApplyChanges stores changes back to etcd converting them to CoreDNS format and aggregating A/CNAME and TXT records
func (p coreDNSProvider) ApplyChanges(ctx context.Context, changes *plan.Changes) error {

isOnPremAddressSupportAllowedStr := strings.ToLower(os.Getenv("COREDNS_ONPREM_ADDRESS_SUPPORT"))
isOnPremAddressSupportAllowed := isOnPremAddressSupportAllowedStr == "true" || isOnPremAddressSupportAllowedStr == "yes" || isOnPremAddressSupportAllowedStr == "1"
if isOnPremAddressSupportAllowed {
log.Warnf("CoreDNS On-Prem Support Enabled")
}

grouped := map[string][]*endpoint.Endpoint{}
for _, ep := range changes.Create {
grouped[ep.DNSName] = append(grouped[ep.DNSName], ep)
Expand All @@ -318,17 +326,29 @@ func (p coreDNSProvider) ApplyChanges(ctx context.Context, changes *plan.Changes
if ep.RecordType == endpoint.RecordTypeTXT {
continue
}

for _, target := range ep.Targets {
prefix := ep.Labels[randomPrefixLabel]
if prefix == "" {
prefix = fmt.Sprintf("%08x", rand.Int31())
}
setdnsName := dnsName
if ep.RecordType == endpoint.RecordTypeA {
if isOnPremAddressSupportAllowed {
matched, _ := regexp.MatchString(";", setdnsName)
// Test the result.
if matched {
result := strings.Split(setdnsName, ";")
target = result[1]
setdnsName = result[0]
log.Warnf("CoreDNS On-Prem Support 'A' Record - Found IP Address surrogate: %s split: %v", setdnsName, result[1])
}
}
}

service := Service{
Host: target,
Text: ep.Labels["originalText"],
Key: p.etcdKeyFor(prefix + "." + dnsName),
Key: p.etcdKeyFor(prefix + "." + setdnsName),
TargetStrip: strings.Count(prefix, ".") + 1,
TTL: uint32(ep.RecordTTL),
}
Expand Down
24 changes: 24 additions & 0 deletions provider/coredns_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

/*
Copyright 2017 The Kubernetes Authors.
Expand All @@ -18,11 +19,13 @@ package provider

import (
"context"
"os"
"strings"
"testing"

"github.com/kubernetes-sigs/external-dns/endpoint"
"github.com/kubernetes-sigs/external-dns/plan"
log "github.com/sirupsen/logrus"
)

const defaultCoreDNSPrefix = "/skydns/"
Expand Down Expand Up @@ -233,6 +236,10 @@ func TestCNAMEWithTXTServiceTranslation(t *testing.T) {
}

func TestCoreDNSApplyChanges(t *testing.T) {

os.Setenv("COREDNS_ONPREM_ADDRESS_SUPPORT", "true")
log.SetLevel(log.DebugLevel)

client := fakeETCDClient{
map[string]*Service{},
}
Expand Down Expand Up @@ -293,6 +300,23 @@ func TestCoreDNSApplyChanges(t *testing.T) {
"/skydns/local/domain2": {Host: "site.local"},
}
validateServices(client.services, expectedServices3, t, 3)

changes4 := &plan.Changes{
Create: []*endpoint.Endpoint{
endpoint.NewEndpoint("domain1.local;9.9.9.9", endpoint.RecordTypeA, "8.8.8.8"),
endpoint.NewEndpoint("domain1.local;9.9.9.9", endpoint.RecordTypeTXT, "string4"),
endpoint.NewEndpoint("domain3.local", endpoint.RecordTypeCNAME, "site.local"),
},
}
coredns.ApplyChanges(context.Background(), changes4)

expectedServices4 := map[string]*Service{
"/skydns/local/domain1": {Host: "9.9.9.9", Text: "string4"},
"/skydns/local/domain2": {Host: "site.local"},
"/skydns/local/domain3": {Host: "site.local"},
}
validateServices(client.services, expectedServices4, t, 4)

}

func applyServiceChanges(provider coreDNSProvider, changes *plan.Changes) {
Expand Down

0 comments on commit 9e18632

Please sign in to comment.