Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: additional template functions #3949

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions docs/sources/nodes.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Using nodes (`--source=node`) as source is possible to synchronize a DNS zone wi
The node source adds an `A` record per each node `externalIP` (if not found, any IPv4 `internalIP` is used instead).
It also adds an `AAAA` record per each node IPv6 `internalIP`.
The TTL of the records can be set with the `external-dns.alpha.kubernetes.io/ttl` node annotation.
The FQDN template provides more than 100+ functions, documented [here](https://go-task.github.io/slim-sprig/). For instance, it includes a function to replace all `.` with `-` in the node name, which can be useful with cloud providers that include dots in the node name. There are two additional functions available on top of the standard sprig functions: `isIPv4` and `isIPv6`. The functions can be used to test a string for being an IPv4 or IPv6 address.

Nodes marked as **Unschedulable** as per [core/v1/NodeSpec](https://pkg.go.dev/k8s.io/[email protected]/core/v1#NodeSpec) are excluded.
This avoid exposing Unhealthy, NotReady or SchedulingDisabled (cordon) nodes.
Expand Down Expand Up @@ -40,7 +41,7 @@ spec:
- --domain-filter=external-dns-test.my-org.com
- --aws-zone-type=public
- --registry=txt
- --fqdn-template={{.Name}}.external-dns-test.my-org.com
- --fqdn-template={{.Name | replace "." "-"}}.external-dns-test.my-org.com
- --txt-owner-id=my-identifier
- --policy=sync
- --log-level=debug
Expand Down Expand Up @@ -111,7 +112,7 @@ spec:
- --domain-filter=external-dns-test.my-org.com
- --aws-zone-type=public
- --registry=txt
- --fqdn-template={{.Name}}.external-dns-test.my-org.com
- --fqdn-template={{.Name | replace "." "-"}}.external-dns-test.my-org.com
- --txt-owner-id=my-identifier
- --policy=sync
- --log-level=debug
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ require (
github.com/ffledgling/pdns-go v0.0.0-20180219074714-524e7daccd99
github.com/go-gandi/go-gandi v0.7.0
github.com/go-logr/logr v1.4.2
github.com/go-task/slim-sprig/v3 v3.0.0
github.com/google/go-cmp v0.6.0
github.com/google/uuid v1.6.0
github.com/gophercloud/gophercloud v1.14.1
Expand Down
1 change: 0 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,6 @@ github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
Expand Down
5 changes: 5 additions & 0 deletions source/node_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ func testNodeSourceNewNodeSource(t *testing.T) {
expectError: false,
fqdnTemplate: "{{.Name}}-{{.Namespace}}.ext-dns.test.com",
},
{
title: "complex template",
expectError: false,
fqdnTemplate: "{{range .Status.Addresses}}{{if and (eq .Type \"ExternalIP\") (isIPv4 .Address)}}{{.Address | replace \".\" \"-\"}}{{break}}{{end}}{{end}}.ext-dns.test.com",
},
{
title: "non-empty annotation filter label",
expectError: false,
Expand Down
28 changes: 25 additions & 3 deletions source/source.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"time"
"unicode"

sprig "github.com/go-task/slim-sprig/v3"
log "github.com/sirupsen/logrus"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
Expand Down Expand Up @@ -147,9 +148,11 @@ func parseTemplate(fqdnTemplate string) (tmpl *template.Template, err error) {
if fqdnTemplate == "" {
return nil, nil
}
funcs := template.FuncMap{
"trimPrefix": strings.TrimPrefix,
}

funcs := sprig.HermeticTxtFuncMap()
funcs["isIPv6"] = isIPv6String
funcs["isIPv4"] = isIPv4String

return template.New("endpoint").Funcs(funcs).Parse(fqdnTemplate)
}

Expand Down Expand Up @@ -266,6 +269,25 @@ func suitableType(target string) string {
return endpoint.RecordTypeCNAME
}

// isIPv6String reports whether the target string is an IPv6 address,
// including IPv4-mapped IPv6 addresses.
func isIPv6String(target string) bool {
netIP, err := netip.ParseAddr(target)
if err != nil {
return false
}
return netIP.Is6()
}

// isIPv4String reports whether the target string is an IPv4 address.
func isIPv4String(target string) bool {
netIP, err := netip.ParseAddr(target)
if err != nil {
return false
}
return netIP.Is4()
}

// endpointsForHostname returns the endpoint objects for each host-target combination.
func endpointsForHostname(hostname string, targets endpoint.Targets, ttl endpoint.TTL, providerSpecific endpoint.ProviderSpecific, setIdentifier string, resource string) []*endpoint.Endpoint {
var endpoints []*endpoint.Endpoint
Expand Down
Loading