Skip to content

Commit

Permalink
support cnames and aaaa for default-targets
Browse files Browse the repository at this point in the history
  • Loading branch information
cgroschupp committed Jun 28, 2023
1 parent 440f513 commit 5740d78
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 13 deletions.
2 changes: 1 addition & 1 deletion pkg/apis/externaldns/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ func (cfg *Config) ParseFlags(args []string) error {
app.Flag("crd-source-kind", "Kind of the CRD for the crd source in API group and version specified by crd-source-apiversion").Default(defaultConfig.CRDSourceKind).StringVar(&cfg.CRDSourceKind)
app.Flag("service-type-filter", "The service types to take care about (default: all, expected: ClusterIP, NodePort, LoadBalancer or ExternalName)").StringsVar(&cfg.ServiceTypeFilter)
app.Flag("managed-record-types", "Record types to manage; specify multiple times to include many; (default: A, AAAA, CNAME) (supported records: CNAME, A, AAAA, NS").Default("A", "AAAA", "CNAME").StringsVar(&cfg.ManagedDNSRecordTypes)
app.Flag("default-targets", "Set globally default IP address that will apply as a target instead of source addresses. Specify multiple times for multiple targets (optional)").StringsVar(&cfg.DefaultTargets)
app.Flag("default-targets", "Set globally default host/IP that will apply as a target instead of source addresses. Specify multiple times for multiple targets (optional)").StringsVar(&cfg.DefaultTargets)
app.Flag("target-net-filter", "Limit possible targets by a net filter; specify multiple times for multiple possible nets (optional)").StringsVar(&cfg.TargetNetFilter)
app.Flag("exclude-target-net", "Exclude target nets (optional)").StringsVar(&cfg.ExcludeTargetNets)

Expand Down
6 changes: 4 additions & 2 deletions source/multisource.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,12 @@ func (ms *multiSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, err
}
if len(ms.defaultTargets) > 0 {
for i := range endpoints {
endpoints[i].Targets = ms.defaultTargets
eps := endpointsForHostname(endpoints[i].DNSName, ms.defaultTargets, endpoints[i].RecordTTL, endpoints[i].ProviderSpecific, endpoints[i].SetIdentifier)
result = append(result, eps...)
}
} else {
result = append(result, endpoints...)
}
result = append(result, endpoints...)
}

return result, nil
Expand Down
10 changes: 7 additions & 3 deletions source/multisource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,12 +128,16 @@ func testMultiSourceEndpointsWithError(t *testing.T) {

func testMultiSourceEndpointsDefaultTargets(t *testing.T) {
// Create the expected default targets
defaultTargets := []string{"127.0.0.1", "127.0.0.2"}
defaultTargetsA := []string{"127.0.0.1", "127.0.0.2"}
defaultTargetsCName := []string{"foo.example.org"}
defaultTargets := append(defaultTargetsA, defaultTargetsCName...)

// Create the expected endpoints
expectedEndpoints := []*endpoint.Endpoint{
{DNSName: "foo", Targets: defaultTargets},
{DNSName: "bar", Targets: defaultTargets},
{DNSName: "foo", Targets: defaultTargetsA, RecordType: "A"},
{DNSName: "bar", Targets: defaultTargetsA, RecordType: "A"},
{DNSName: "foo", Targets: defaultTargetsCName, RecordType: "CNAME"},
{DNSName: "bar", Targets: defaultTargetsCName, RecordType: "CNAME"},
}

// Create the source endpoints with different targets
Expand Down
17 changes: 17 additions & 0 deletions source/source.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,23 @@ func suitableType(target string) string {
return endpoint.RecordTypeCNAME
}

// suitableType returns the DNS resource record type suitable for the target.
// In this case type A for IPs and type CNAME for everything else.
func suitableTypes(targets []string) (string, error) {
lastType := ""
for _, target := range targets {
currentType := suitableType(target)
if lastType != "" && currentType != lastType {
return "", fmt.Errorf("wrong type")
}
lastType = currentType
}
if lastType == "" {
return "", fmt.Errorf("empty")
}
return lastType, nil
}

// 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) []*endpoint.Endpoint {
var endpoints []*endpoint.Endpoint
Expand Down
33 changes: 26 additions & 7 deletions source/source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,18 +91,37 @@ func TestGetTTLFromAnnotations(t *testing.T) {

func TestSuitableType(t *testing.T) {
for _, tc := range []struct {
target, recordType, expected string
target, expectedRecordType string
}{
{"8.8.8.8", "", "A"},
{"2001:db8::1", "", "AAAA"},
{"foo.example.org", "", "CNAME"},
{"bar.eu-central-1.elb.amazonaws.com", "", "CNAME"},
{"8.8.8.8", "A"},
{"2001:db8::1", "AAAA"},
{"foo.example.org", "CNAME"},
{"bar.eu-central-1.elb.amazonaws.com", "CNAME"},
} {

recordType := suitableType(tc.target)

if recordType != tc.expected {
t.Errorf("expected %s, got %s", tc.expected, recordType)
if recordType != tc.expectedRecordType {
t.Errorf("expected %s, got %s", tc.expectedRecordType, recordType)
}
}
}

type suitableTypesTestCase struct {
targets []string
expectedRecordType string
expectedErr error
}

func TestSuitableTypes(t *testing.T) {
for _, tc := range []suitableTypesTestCase{
{[]string{"8.8.8.8", "1.1.1.1"}, "A", nil},
{[]string{"foo.example.org", "1.1.1.1"}, "", fmt.Errorf("wrong type")},
{[]string{"foo.example.org", "bar.eu-central-1.elb.amazonaws.com"}, "CNAME", nil},
{[]string{}, "", fmt.Errorf("empty")},
} {
recordType, err := suitableTypes(tc.targets)
assert.Equal(t, tc.expectedErr, err)
assert.Equal(t, tc.expectedRecordType, recordType)
}
}

0 comments on commit 5740d78

Please sign in to comment.