Merge pull request #2461 from johngmyers/quad-a

Add support for AAAA records
This commit is contained in:
Kubernetes Prow Robot 2023-04-13 14:26:42 -07:00 committed by GitHub
commit e48ec6b241
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 1141 additions and 551 deletions

View File

@ -102,6 +102,14 @@ var (
Help: "Number of Registry A records.",
},
)
registryAAAARecords = prometheus.NewGauge(
prometheus.GaugeOpts{
Namespace: "external_dns",
Subsystem: "registry",
Name: "aaaa_records",
Help: "Number of Registry AAAA records.",
},
)
sourceARecords = prometheus.NewGauge(
prometheus.GaugeOpts{
Namespace: "external_dns",
@ -110,6 +118,14 @@ var (
Help: "Number of Source A records.",
},
)
sourceAAAARecords = prometheus.NewGauge(
prometheus.GaugeOpts{
Namespace: "external_dns",
Subsystem: "source",
Name: "aaaa_records",
Help: "Number of Source AAAA records.",
},
)
verifiedARecords = prometheus.NewGauge(
prometheus.GaugeOpts{
Namespace: "external_dns",
@ -118,6 +134,14 @@ var (
Help: "Number of DNS A-records that exists both in source and registry.",
},
)
verifiedAAAARecords = prometheus.NewGauge(
prometheus.GaugeOpts{
Namespace: "external_dns",
Subsystem: "controller",
Name: "verified_aaaa_records",
Help: "Number of DNS AAAA-records that exists both in source and registry.",
},
)
)
func init() {
@ -130,8 +154,11 @@ func init() {
prometheus.MustRegister(deprecatedSourceErrors)
prometheus.MustRegister(controllerNoChangesTotal)
prometheus.MustRegister(registryARecords)
prometheus.MustRegister(registryAAAARecords)
prometheus.MustRegister(sourceARecords)
prometheus.MustRegister(sourceAAAARecords)
prometheus.MustRegister(verifiedARecords)
prometheus.MustRegister(verifiedAAAARecords)
}
// Controller is responsible for orchestrating the different components.
@ -171,8 +198,9 @@ func (c *Controller) RunOnce(ctx context.Context) error {
missingRecords := c.Registry.MissingRecords()
registryEndpointsTotal.Set(float64(len(records)))
regARecords := filterARecords(records)
registryARecords.Set(float64(len(regARecords)))
regARecords, regAAAARecords := countAddressRecords(records)
registryARecords.Set(float64(regARecords))
registryAAAARecords.Set(float64(regAAAARecords))
ctx = context.WithValue(ctx, provider.RecordsContextKey, records)
endpoints, err := c.Source.Endpoints(ctx)
@ -182,10 +210,12 @@ func (c *Controller) RunOnce(ctx context.Context) error {
return err
}
sourceEndpointsTotal.Set(float64(len(endpoints)))
srcARecords := filterARecords(endpoints)
sourceARecords.Set(float64(len(srcARecords)))
vRecords := fetchMatchingARecords(endpoints, records)
verifiedARecords.Set(float64(len(vRecords)))
srcARecords, srcAAAARecords := countAddressRecords(endpoints)
sourceARecords.Set(float64(srcARecords))
sourceAAAARecords.Set(float64(srcAAAARecords))
vARecords, vAAAARecords := countMatchingAddressRecords(endpoints, records)
verifiedARecords.Set(float64(vARecords))
verifiedAAAARecords.Set(float64(vAAAARecords))
endpoints = c.Registry.AdjustEndpoints(endpoints)
if len(missingRecords) > 0 {
@ -238,30 +268,44 @@ func (c *Controller) RunOnce(ctx context.Context) error {
return nil
}
// Checks and returns the intersection of A records in endpoint and registry.
func fetchMatchingARecords(endpoints []*endpoint.Endpoint, registryRecords []*endpoint.Endpoint) []string {
aRecords := filterARecords(endpoints)
recordsMap := make(map[string]struct{})
// Counts the intersections of A and AAAA records in endpoint and registry.
func countMatchingAddressRecords(endpoints []*endpoint.Endpoint, registryRecords []*endpoint.Endpoint) (int, int) {
recordsMap := make(map[string]map[string]struct{})
for _, regRecord := range registryRecords {
recordsMap[regRecord.DNSName] = struct{}{}
if _, found := recordsMap[regRecord.DNSName]; !found {
recordsMap[regRecord.DNSName] = make(map[string]struct{})
}
recordsMap[regRecord.DNSName][regRecord.RecordType] = struct{}{}
}
var cm []string
for _, sourceRecord := range aRecords {
if _, found := recordsMap[sourceRecord]; found {
cm = append(cm, sourceRecord)
aCount := 0
aaaaCount := 0
for _, sourceRecord := range endpoints {
if _, found := recordsMap[sourceRecord.DNSName]; found {
if _, found := recordsMap[sourceRecord.DNSName][sourceRecord.RecordType]; found {
switch sourceRecord.RecordType {
case endpoint.RecordTypeA:
aCount++
case endpoint.RecordTypeAAAA:
aaaaCount++
}
}
}
}
return cm
return aCount, aaaaCount
}
func filterARecords(endpoints []*endpoint.Endpoint) []string {
var aRecords []string
func countAddressRecords(endpoints []*endpoint.Endpoint) (int, int) {
aCount := 0
aaaaCount := 0
for _, endPoint := range endpoints {
if endPoint.RecordType == endpoint.RecordTypeA {
aRecords = append(aRecords, endPoint.DNSName)
switch endPoint.RecordType {
case endpoint.RecordTypeA:
aCount++
case endpoint.RecordTypeAAAA:
aaaaCount++
}
}
return aRecords
return aCount, aaaaCount
}
// ScheduleRunOnce makes sure execution happens at most once per interval.

View File

@ -21,6 +21,7 @@ import (
"errors"
"math"
"reflect"
"sort"
"testing"
"time"
@ -83,32 +84,20 @@ func (p *errorMockProvider) Records(ctx context.Context) ([]*endpoint.Endpoint,
// ApplyChanges validates that the passed in changes satisfy the assumptions.
func (p *mockProvider) ApplyChanges(ctx context.Context, changes *plan.Changes) error {
if len(changes.Create) != len(p.ExpectChanges.Create) {
return errors.New("number of created records is wrong")
if err := verifyEndpoints(changes.Create, p.ExpectChanges.Create); err != nil {
return err
}
for i := range changes.Create {
if changes.Create[i].DNSName != p.ExpectChanges.Create[i].DNSName || !changes.Create[i].Targets.Same(p.ExpectChanges.Create[i].Targets) {
return errors.New("created record is wrong")
}
if err := verifyEndpoints(changes.UpdateNew, p.ExpectChanges.UpdateNew); err != nil {
return err
}
for i := range changes.UpdateNew {
if changes.UpdateNew[i].DNSName != p.ExpectChanges.UpdateNew[i].DNSName || !changes.UpdateNew[i].Targets.Same(p.ExpectChanges.UpdateNew[i].Targets) {
return errors.New("delete record is wrong")
}
if err := verifyEndpoints(changes.UpdateOld, p.ExpectChanges.UpdateOld); err != nil {
return err
}
for i := range changes.UpdateOld {
if changes.UpdateOld[i].DNSName != p.ExpectChanges.UpdateOld[i].DNSName || !changes.UpdateOld[i].Targets.Same(p.ExpectChanges.UpdateOld[i].Targets) {
return errors.New("delete record is wrong")
}
}
for i := range changes.Delete {
if changes.Delete[i].DNSName != p.ExpectChanges.Delete[i].DNSName || !changes.Delete[i].Targets.Same(p.ExpectChanges.Delete[i].Targets) {
return errors.New("delete record is wrong")
}
if err := verifyEndpoints(changes.Delete, p.ExpectChanges.Delete); err != nil {
return err
}
if !reflect.DeepEqual(ctx.Value(provider.RecordsContextKey), p.RecordsStore) {
@ -117,6 +106,21 @@ func (p *mockProvider) ApplyChanges(ctx context.Context, changes *plan.Changes)
return nil
}
func verifyEndpoints(actual, expected []*endpoint.Endpoint) error {
if len(actual) != len(expected) {
return errors.New("number of records is wrong")
}
sort.Slice(actual, func(i, j int) bool {
return actual[i].DNSName < actual[j].DNSName
})
for i := range actual {
if actual[i].DNSName != expected[i].DNSName || !actual[i].Targets.Same(expected[i].Targets) {
return errors.New("record is wrong")
}
}
return nil
}
// newMockProvider creates a new mockProvider returning the given endpoints and validating the desired changes.
func newMockProvider(endpoints []*endpoint.Endpoint, changes *plan.Changes) provider.Provider {
dnsProvider := &mockProvider{
@ -132,7 +136,7 @@ func TestRunOnce(t *testing.T) {
// Fake some desired endpoints coming from our source.
source := new(testutils.MockSource)
cfg := externaldns.NewConfig()
cfg.ManagedDNSRecordTypes = []string{endpoint.RecordTypeA, endpoint.RecordTypeCNAME}
cfg.ManagedDNSRecordTypes = []string{endpoint.RecordTypeA, endpoint.RecordTypeAAAA, endpoint.RecordTypeCNAME}
source.On("Endpoints").Return([]*endpoint.Endpoint{
{
DNSName: "create-record",
@ -144,6 +148,16 @@ func TestRunOnce(t *testing.T) {
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.4.4"},
},
{
DNSName: "create-aaaa-record",
RecordType: endpoint.RecordTypeAAAA,
Targets: endpoint.Targets{"2001:DB8::1"},
},
{
DNSName: "update-aaaa-record",
RecordType: endpoint.RecordTypeAAAA,
Targets: endpoint.Targets{"2001:DB8::2"},
},
}, nil)
// Fake some existing records in our DNS provider and validate some desired changes.
@ -159,18 +173,32 @@ func TestRunOnce(t *testing.T) {
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"4.3.2.1"},
},
{
DNSName: "update-aaaa-record",
RecordType: endpoint.RecordTypeAAAA,
Targets: endpoint.Targets{"2001:DB8::3"},
},
{
DNSName: "delete-aaaa-record",
RecordType: endpoint.RecordTypeAAAA,
Targets: endpoint.Targets{"2001:DB8::4"},
},
},
&plan.Changes{
Create: []*endpoint.Endpoint{
{DNSName: "create-aaaa-record", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:DB8::1"}},
{DNSName: "create-record", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
},
UpdateNew: []*endpoint.Endpoint{
{DNSName: "update-aaaa-record", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:DB8::2"}},
{DNSName: "update-record", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"8.8.4.4"}},
},
UpdateOld: []*endpoint.Endpoint{
{DNSName: "update-aaaa-record", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:DB8::3"}},
{DNSName: "update-record", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"8.8.8.8"}},
},
Delete: []*endpoint.Endpoint{
{DNSName: "delete-aaaa-record", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:DB8::4"}},
{DNSName: "delete-record", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"4.3.2.1"}},
},
},
@ -193,6 +221,7 @@ func TestRunOnce(t *testing.T) {
source.AssertExpectations(t)
// check the verified records
assert.Equal(t, math.Float64bits(1), valueFromMetric(verifiedARecords))
assert.Equal(t, math.Float64bits(1), valueFromMetric(verifiedAAAARecords))
}
func valueFromMetric(metric prometheus.Gauge) uint64 {
@ -253,7 +282,7 @@ func TestShouldRunOnce(t *testing.T) {
func testControllerFiltersDomains(t *testing.T, configuredEndpoints []*endpoint.Endpoint, domainFilter endpoint.DomainFilterInterface, providerEndpoints []*endpoint.Endpoint, expectedChanges []*plan.Changes) {
t.Helper()
cfg := externaldns.NewConfig()
cfg.ManagedDNSRecordTypes = []string{endpoint.RecordTypeA, endpoint.RecordTypeCNAME}
cfg.ManagedDNSRecordTypes = []string{endpoint.RecordTypeA, endpoint.RecordTypeAAAA, endpoint.RecordTypeCNAME}
source := new(testutils.MockSource)
source.On("Endpoints").Return(configuredEndpoints, nil)
@ -526,6 +555,85 @@ func TestVerifyARecords(t *testing.T) {
}},
)
assert.Equal(t, math.Float64bits(2), valueFromMetric(verifiedARecords))
assert.Equal(t, math.Float64bits(0), valueFromMetric(verifiedAAAARecords))
}
func TestVerifyAAAARecords(t *testing.T) {
testControllerFiltersDomains(
t,
[]*endpoint.Endpoint{
{
DNSName: "create-record.used.tld",
RecordType: endpoint.RecordTypeAAAA,
Targets: endpoint.Targets{"2001:DB8::1"},
},
{
DNSName: "some-record.used.tld",
RecordType: endpoint.RecordTypeAAAA,
Targets: endpoint.Targets{"2001:DB8::2"},
},
},
endpoint.NewDomainFilter([]string{"used.tld"}),
[]*endpoint.Endpoint{
{
DNSName: "some-record.used.tld",
RecordType: endpoint.RecordTypeAAAA,
Targets: endpoint.Targets{"2001:DB8::2"},
},
{
DNSName: "create-record.used.tld",
RecordType: endpoint.RecordTypeAAAA,
Targets: endpoint.Targets{"2001:DB8::1"},
},
},
[]*plan.Changes{},
)
assert.Equal(t, math.Float64bits(2), valueFromMetric(verifiedAAAARecords))
testControllerFiltersDomains(
t,
[]*endpoint.Endpoint{
{
DNSName: "some-record.1.used.tld",
RecordType: endpoint.RecordTypeAAAA,
Targets: endpoint.Targets{"2001:DB8::1"},
},
{
DNSName: "some-record.2.used.tld",
RecordType: endpoint.RecordTypeAAAA,
Targets: endpoint.Targets{"2001:DB8::2"},
},
{
DNSName: "some-record.3.used.tld",
RecordType: endpoint.RecordTypeAAAA,
Targets: endpoint.Targets{"2001:DB8::3"},
},
},
endpoint.NewDomainFilter([]string{"used.tld"}),
[]*endpoint.Endpoint{
{
DNSName: "some-record.1.used.tld",
RecordType: endpoint.RecordTypeAAAA,
Targets: endpoint.Targets{"2001:DB8::1"},
},
{
DNSName: "some-record.2.used.tld",
RecordType: endpoint.RecordTypeAAAA,
Targets: endpoint.Targets{"2001:DB8::2"},
},
},
[]*plan.Changes{{
Create: []*endpoint.Endpoint{
{
DNSName: "some-record.3.used.tld",
RecordType: endpoint.RecordTypeAAAA,
Targets: endpoint.Targets{"2001:DB8::3"},
},
},
}},
)
assert.Equal(t, math.Float64bits(0), valueFromMetric(verifiedARecords))
assert.Equal(t, math.Float64bits(2), valueFromMetric(verifiedAAAARecords))
}
func TestARecords(t *testing.T) {
@ -628,3 +736,50 @@ func TestMissingRecordsApply(t *testing.T) {
},
})
}
func TestAAAARecords(t *testing.T) {
testControllerFiltersDomains(
t,
[]*endpoint.Endpoint{
{
DNSName: "record1.used.tld",
RecordType: endpoint.RecordTypeAAAA,
Targets: endpoint.Targets{"2001:DB8::1"},
},
{
DNSName: "record2.used.tld",
RecordType: endpoint.RecordTypeAAAA,
Targets: endpoint.Targets{"2001:DB8::2"},
},
{
DNSName: "_mysql-svc._tcp.mysql.used.tld",
RecordType: endpoint.RecordTypeSRV,
Targets: endpoint.Targets{"0 50 30007 mysql.used.tld"},
},
},
endpoint.NewDomainFilter([]string{"used.tld"}),
[]*endpoint.Endpoint{
{
DNSName: "record1.used.tld",
RecordType: endpoint.RecordTypeAAAA,
Targets: endpoint.Targets{"2001:DB8::1"},
},
{
DNSName: "_mysql-svc._tcp.mysql.used.tld",
RecordType: endpoint.RecordTypeSRV,
Targets: endpoint.Targets{"0 50 30007 mysql.used.tld"},
},
},
[]*plan.Changes{{
Create: []*endpoint.Endpoint{
{
DNSName: "record2.used.tld",
RecordType: endpoint.RecordTypeAAAA,
Targets: endpoint.Targets{"2001:DB8::2"},
},
},
}},
)
assert.Equal(t, math.Float64bits(2), valueFromMetric(sourceAAAARecords))
assert.Equal(t, math.Float64bits(1), valueFromMetric(registryAAAARecords))
}

View File

@ -178,16 +178,18 @@ You can use the host label in the metric to figure out if the request was agains
Here is the full list of available metrics provided by ExternalDNS:
| Name | Description | Type |
| --------------------------------------------------- | ------------------------------------------------------- | ------- |
| external_dns_controller_last_sync_timestamp_seconds | Timestamp of last successful sync with the DNS provider | Gauge |
| external_dns_registry_endpoints_total | Number of Endpoints in all sources | Gauge |
| external_dns_registry_errors_total | Number of Registry errors | Counter |
| external_dns_source_endpoints_total | Number of Endpoints in the registry | Gauge |
| external_dns_source_errors_total | Number of Source errors | Counter |
| external_dns_controller_verified_records | Number of DNS A-records that exists both in | Gauge |
| | source & registry | |
| Name | Description | Type |
| --------------------------------------------------- | ------------------------------------------------------------------ | ------- |
| external_dns_controller_last_sync_timestamp_seconds | Timestamp of last successful sync with the DNS provider | Gauge |
| external_dns_registry_endpoints_total | Number of Endpoints in all sources | Gauge |
| external_dns_registry_errors_total | Number of Registry errors | Counter |
| external_dns_source_endpoints_total | Number of Endpoints in the registry | Gauge |
| external_dns_source_errors_total | Number of Source errors | Counter |
| external_dns_controller_verified_aaaa_records | Number of DNS AAAA-records that exists both in source and registry | Gauge |
| external_dns_controller_verified_a_records | Number of DNS A-records that exists both in source and registry | Gauge |
| external_dns_registry_aaaa_records | Number of AAAA records in registry | Gauge |
| external_dns_registry_a_records | Number of A records in registry | Gauge |
| external_dns_source_aaaa_records | Number of AAAA records in source | Gauge |
| external_dns_source_a_records | Number of A records in source | Gauge |
### How can I run ExternalDNS under a specific GCP Service Account, e.g. to access DNS records in other projects?

View File

@ -30,6 +30,8 @@ import (
const (
// RecordTypeA is a RecordType enum value
RecordTypeA = "A"
// RecordTypeAAAA is a RecordType enum value
RecordTypeAAAA = "AAAA"
// RecordTypeCNAME is a RecordType enum value
RecordTypeCNAME = "CNAME"
// RecordTypeTXT is a RecordType enum value
@ -164,7 +166,7 @@ type Endpoint struct {
DNSName string `json:"dnsName,omitempty"`
// The targets the DNS record points to
Targets Targets `json:"targets,omitempty"`
// RecordType type of record, e.g. CNAME, A, SRV, TXT etc
// RecordType type of record, e.g. CNAME, A, AAAA, SRV, TXT etc
RecordType string `json:"recordType,omitempty"`
// Identifier to distinguish multiple records with the same name and type (e.g. Route53 records with routing policies other than 'simple')
SetIdentifier string `json:"setIdentifier,omitempty"`

View File

@ -329,7 +329,7 @@ var defaultConfig = &Config{
TransIPAccountName: "",
TransIPPrivateKeyFile: "",
DigitalOceanAPIPageSize: 50,
ManagedDNSRecordTypes: []string{endpoint.RecordTypeA, endpoint.RecordTypeCNAME},
ManagedDNSRecordTypes: []string{endpoint.RecordTypeA, endpoint.RecordTypeAAAA, endpoint.RecordTypeCNAME},
GoDaddyAPIKey: "",
GoDaddySecretKey: "",
GoDaddyTTL: 600,
@ -426,7 +426,7 @@ func (cfg *Config) ParseFlags(args []string) error {
app.Flag("crd-source-apiversion", "API version of the CRD for crd source, e.g. `externaldns.k8s.io/v1alpha1`, valid only when using crd source").Default(defaultConfig.CRDSourceAPIVersion).StringVar(&cfg.CRDSourceAPIVersion)
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, CNAME) (supported records: CNAME, A, NS").Default("A", "CNAME").StringsVar(&cfg.ManagedDNSRecordTypes)
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("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)

View File

@ -122,7 +122,7 @@ var (
TransIPAccountName: "",
TransIPPrivateKeyFile: "",
DigitalOceanAPIPageSize: 50,
ManagedDNSRecordTypes: []string{endpoint.RecordTypeA, endpoint.RecordTypeCNAME},
ManagedDNSRecordTypes: []string{endpoint.RecordTypeA, endpoint.RecordTypeAAAA, endpoint.RecordTypeCNAME},
RFC2136BatchChangeSize: 50,
OCPRouterName: "default",
IBMCloudProxied: false,
@ -233,7 +233,7 @@ var (
TransIPAccountName: "transip",
TransIPPrivateKeyFile: "/path/to/transip.key",
DigitalOceanAPIPageSize: 100,
ManagedDNSRecordTypes: []string{endpoint.RecordTypeA, endpoint.RecordTypeCNAME, endpoint.RecordTypeNS},
ManagedDNSRecordTypes: []string{endpoint.RecordTypeA, endpoint.RecordTypeAAAA, endpoint.RecordTypeCNAME, endpoint.RecordTypeNS},
RFC2136BatchChangeSize: 100,
IBMCloudProxied: true,
IBMCloudConfigFile: "ibmcloud.json",
@ -372,6 +372,7 @@ func TestParseFlags(t *testing.T) {
"--transip-keyfile=/path/to/transip.key",
"--digitalocean-api-page-size=100",
"--managed-record-types=A",
"--managed-record-types=AAAA",
"--managed-record-types=CNAME",
"--managed-record-types=NS",
"--rfc2136-batch-change-size=100",
@ -488,7 +489,7 @@ func TestParseFlags(t *testing.T) {
"EXTERNAL_DNS_TRANSIP_ACCOUNT": "transip",
"EXTERNAL_DNS_TRANSIP_KEYFILE": "/path/to/transip.key",
"EXTERNAL_DNS_DIGITALOCEAN_API_PAGE_SIZE": "100",
"EXTERNAL_DNS_MANAGED_RECORD_TYPES": "A\nCNAME\nNS",
"EXTERNAL_DNS_MANAGED_RECORD_TYPES": "A\nAAAA\nCNAME\nNS",
"EXTERNAL_DNS_RFC2136_BATCH_CHANGE_SIZE": "100",
"EXTERNAL_DNS_IBMCLOUD_PROXIED": "1",
"EXTERNAL_DNS_IBMCLOUD_CONFIG_FILE": "ibmcloud.json",

View File

@ -78,12 +78,12 @@ bar.com | | [->191.1.1.1, ->190.1.1.1] | = create (bar.com -> 1
"=", i.e. result of calculation relies on supplied ConflictResolver
*/
type planTable struct {
rows map[string]map[string]*planTableRow
rows map[string]map[string]map[string]*planTableRow
resolver ConflictResolver
}
func newPlanTable() planTable { // TODO: make resolver configurable
return planTable{map[string]map[string]*planTableRow{}, PerResource{}}
return planTable{map[string]map[string]map[string]*planTableRow{}, PerResource{}}
}
// planTableRow
@ -101,23 +101,29 @@ func (t planTableRow) String() string {
func (t planTable) addCurrent(e *endpoint.Endpoint) {
dnsName := normalizeDNSName(e.DNSName)
if _, ok := t.rows[dnsName]; !ok {
t.rows[dnsName] = make(map[string]*planTableRow)
t.rows[dnsName] = make(map[string]map[string]*planTableRow)
}
if _, ok := t.rows[dnsName][e.SetIdentifier]; !ok {
t.rows[dnsName][e.SetIdentifier] = &planTableRow{}
t.rows[dnsName][e.SetIdentifier] = make(map[string]*planTableRow)
}
t.rows[dnsName][e.SetIdentifier].current = e
if _, ok := t.rows[e.SetIdentifier][e.RecordType]; !ok {
t.rows[dnsName][e.SetIdentifier][e.RecordType] = &planTableRow{}
}
t.rows[dnsName][e.SetIdentifier][e.RecordType].current = e
}
func (t planTable) addCandidate(e *endpoint.Endpoint) {
dnsName := normalizeDNSName(e.DNSName)
if _, ok := t.rows[dnsName]; !ok {
t.rows[dnsName] = make(map[string]*planTableRow)
t.rows[dnsName] = make(map[string]map[string]*planTableRow)
}
if _, ok := t.rows[dnsName][e.SetIdentifier]; !ok {
t.rows[dnsName][e.SetIdentifier] = &planTableRow{}
t.rows[dnsName][e.SetIdentifier] = make(map[string]*planTableRow)
}
t.rows[dnsName][e.SetIdentifier].candidates = append(t.rows[dnsName][e.SetIdentifier].candidates, e)
if _, ok := t.rows[dnsName][e.SetIdentifier][e.RecordType]; !ok {
t.rows[dnsName][e.SetIdentifier][e.RecordType] = &planTableRow{}
}
t.rows[dnsName][e.SetIdentifier][e.RecordType].candidates = append(t.rows[dnsName][e.SetIdentifier][e.RecordType].candidates, e)
}
func (c *Changes) HasChanges() bool {
@ -147,24 +153,26 @@ func (p *Plan) Calculate() *Plan {
changes := &Changes{}
for _, topRow := range t.rows {
for _, row := range topRow {
if row.current == nil { // dns name not taken
changes.Create = append(changes.Create, t.resolver.ResolveCreate(row.candidates))
}
if row.current != nil && len(row.candidates) == 0 {
changes.Delete = append(changes.Delete, row.current)
}
// TODO: allows record type change, which might not be supported by all dns providers
if row.current != nil && len(row.candidates) > 0 { // dns name is taken
update := t.resolver.ResolveUpdate(row.current, row.candidates)
// compare "update" to "current" to figure out if actual update is required
if shouldUpdateTTL(update, row.current) || targetChanged(update, row.current) || p.shouldUpdateProviderSpecific(update, row.current) {
inheritOwner(row.current, update)
changes.UpdateNew = append(changes.UpdateNew, update)
changes.UpdateOld = append(changes.UpdateOld, row.current)
for _, midRow := range topRow {
for _, row := range midRow {
if row.current == nil { // dns name not taken
changes.Create = append(changes.Create, t.resolver.ResolveCreate(row.candidates))
}
if row.current != nil && len(row.candidates) == 0 {
changes.Delete = append(changes.Delete, row.current)
}
// TODO: allows record type change, which might not be supported by all dns providers
if row.current != nil && len(row.candidates) > 0 { // dns name is taken
update := t.resolver.ResolveUpdate(row.current, row.candidates)
// compare "update" to "current" to figure out if actual update is required
if shouldUpdateTTL(update, row.current) || targetChanged(update, row.current) || p.shouldUpdateProviderSpecific(update, row.current) {
inheritOwner(row.current, update)
changes.UpdateNew = append(changes.UpdateNew, update)
changes.UpdateOld = append(changes.UpdateOld, row.current)
}
continue
}
continue
}
}
}
@ -181,7 +189,7 @@ func (p *Plan) Calculate() *Plan {
Current: p.Current,
Desired: p.Desired,
Changes: changes,
ManagedRecords: []string{endpoint.RecordTypeA, endpoint.RecordTypeCNAME},
ManagedRecords: []string{endpoint.RecordTypeA, endpoint.RecordTypeAAAA, endpoint.RecordTypeCNAME},
}
return plan

View File

@ -35,6 +35,9 @@ type PlanTestSuite struct {
fooV2CnameNoLabel *endpoint.Endpoint
fooV3CnameSameResource *endpoint.Endpoint
fooA5 *endpoint.Endpoint
fooAAAA *endpoint.Endpoint
dsA *endpoint.Endpoint
dsAAAA *endpoint.Endpoint
bar127A *endpoint.Endpoint
bar127AWithTTL *endpoint.Endpoint
bar127AWithProviderSpecificTrue *endpoint.Endpoint
@ -106,6 +109,30 @@ func (suite *PlanTestSuite) SetupTest() {
endpoint.ResourceLabelKey: "ingress/default/foo-5",
},
}
suite.fooAAAA = &endpoint.Endpoint{
DNSName: "foo",
Targets: endpoint.Targets{"2001:DB8::1"},
RecordType: "AAAA",
Labels: map[string]string{
endpoint.ResourceLabelKey: "ingress/default/foo-AAAA",
},
}
suite.dsA = &endpoint.Endpoint{
DNSName: "ds",
Targets: endpoint.Targets{"1.1.1.1"},
RecordType: "A",
Labels: map[string]string{
endpoint.ResourceLabelKey: "ingress/default/ds",
},
}
suite.dsAAAA = &endpoint.Endpoint{
DNSName: "ds",
Targets: endpoint.Targets{"1.1.1.1"},
RecordType: "AAAA",
Labels: map[string]string{
endpoint.ResourceLabelKey: "ingress/default/ds-AAAAA",
},
}
suite.bar127A = &endpoint.Endpoint{
DNSName: "bar",
Targets: endpoint.Targets{"127.0.0.1"},
@ -438,9 +465,9 @@ func (suite *PlanTestSuite) TestIdempotency() {
func (suite *PlanTestSuite) TestDifferentTypes() {
current := []*endpoint.Endpoint{suite.fooV1Cname}
desired := []*endpoint.Endpoint{suite.fooV2Cname, suite.fooA5}
expectedCreate := []*endpoint.Endpoint{}
expectedCreate := []*endpoint.Endpoint{suite.fooA5}
expectedUpdateOld := []*endpoint.Endpoint{suite.fooV1Cname}
expectedUpdateNew := []*endpoint.Endpoint{suite.fooA5}
expectedUpdateNew := []*endpoint.Endpoint{suite.fooV2Cname}
expectedDelete := []*endpoint.Endpoint{}
p := &Plan{
@ -544,52 +571,6 @@ func (suite *PlanTestSuite) TestRemoveEndpointWithUpsert() {
validateEntries(suite.T(), changes.Delete, expectedDelete)
}
// TODO: remove once multiple-target per endpoint is supported
func (suite *PlanTestSuite) TestDuplicatedEndpointsForSameResourceReplace() {
current := []*endpoint.Endpoint{suite.fooV3CnameSameResource, suite.bar192A}
desired := []*endpoint.Endpoint{suite.fooV1Cname, suite.fooV3CnameSameResource}
expectedCreate := []*endpoint.Endpoint{}
expectedUpdateOld := []*endpoint.Endpoint{suite.fooV3CnameSameResource}
expectedUpdateNew := []*endpoint.Endpoint{suite.fooV1Cname}
expectedDelete := []*endpoint.Endpoint{suite.bar192A}
p := &Plan{
Policies: []Policy{&SyncPolicy{}},
Current: current,
Desired: desired,
ManagedRecords: []string{endpoint.RecordTypeA, endpoint.RecordTypeCNAME},
}
changes := p.Calculate().Changes
validateEntries(suite.T(), changes.Create, expectedCreate)
validateEntries(suite.T(), changes.UpdateNew, expectedUpdateNew)
validateEntries(suite.T(), changes.UpdateOld, expectedUpdateOld)
validateEntries(suite.T(), changes.Delete, expectedDelete)
}
// TODO: remove once multiple-target per endpoint is supported
func (suite *PlanTestSuite) TestDuplicatedEndpointsForSameResourceRetain() {
current := []*endpoint.Endpoint{suite.fooV1Cname, suite.bar192A}
desired := []*endpoint.Endpoint{suite.fooV1Cname, suite.fooV3CnameSameResource}
expectedCreate := []*endpoint.Endpoint{}
expectedUpdateOld := []*endpoint.Endpoint{}
expectedUpdateNew := []*endpoint.Endpoint{}
expectedDelete := []*endpoint.Endpoint{suite.bar192A}
p := &Plan{
Policies: []Policy{&SyncPolicy{}},
Current: current,
Desired: desired,
ManagedRecords: []string{endpoint.RecordTypeA, endpoint.RecordTypeCNAME},
}
changes := p.Calculate().Changes
validateEntries(suite.T(), changes.Create, expectedCreate)
validateEntries(suite.T(), changes.UpdateNew, expectedUpdateNew)
validateEntries(suite.T(), changes.UpdateOld, expectedUpdateOld)
validateEntries(suite.T(), changes.Delete, expectedDelete)
}
func (suite *PlanTestSuite) TestMultipleRecordsSameNameDifferentSetIdentifier() {
current := []*endpoint.Endpoint{suite.multiple1}
desired := []*endpoint.Endpoint{suite.multiple2, suite.multiple3}
@ -695,6 +676,39 @@ func (suite *PlanTestSuite) TestMissing() {
validateEntries(suite.T(), changes.Create, expectedCreate)
}
func (suite *PlanTestSuite) TestAAAARecords() {
current := []*endpoint.Endpoint{}
desired := []*endpoint.Endpoint{suite.fooAAAA}
expectedCreate := []*endpoint.Endpoint{suite.fooAAAA}
p := &Plan{
Policies: []Policy{&SyncPolicy{}},
Current: current,
Desired: desired,
ManagedRecords: []string{endpoint.RecordTypeAAAA, endpoint.RecordTypeCNAME},
}
changes := p.Calculate().Changes
validateEntries(suite.T(), changes.Create, expectedCreate)
}
func (suite *PlanTestSuite) TestDualStackRecords() {
current := []*endpoint.Endpoint{}
desired := []*endpoint.Endpoint{suite.dsA, suite.dsAAAA}
expectedCreate := []*endpoint.Endpoint{suite.dsA, suite.dsAAAA}
p := &Plan{
Policies: []Policy{&SyncPolicy{}},
Current: current,
Desired: desired,
ManagedRecords: []string{endpoint.RecordTypeA, endpoint.RecordTypeAAAA, endpoint.RecordTypeCNAME},
}
changes := p.Calculate().Changes
validateEntries(suite.T(), changes.Create, expectedCreate)
}
func TestPlan(t *testing.T) {
suite.Run(t, new(PlanTestSuite))
}

View File

@ -315,7 +315,6 @@ func (p *PDNSProvider) ConvertEndpointsToZones(eps []*endpoint.Endpoint, changet
if ep.RecordType == "CNAME" {
t = provider.EnsureTrailingDot(t)
}
records = append(records, pgo.Record{Content: t})
}
rrset := pgo.RrSet{

View File

@ -17,10 +17,10 @@ limitations under the License.
package provider
// SupportedRecordType returns true only for supported record types.
// Currently A, CNAME, SRV, TXT and NS record types are supported.
// Currently A, AAAA, CNAME, SRV, TXT and NS record types are supported.
func SupportedRecordType(recordType string) bool {
switch recordType {
case "A", "CNAME", "SRV", "TXT", "NS":
case "A", "AAAA", "CNAME", "SRV", "TXT", "NS":
return true
default:
return false

View File

@ -27,6 +27,10 @@ func TestRecordTypeFilter(t *testing.T) {
"A",
true,
},
{
"AAAA",
true,
},
{
"CNAME",
true,

View File

@ -256,7 +256,7 @@ func TestProviderRecords(t *testing.T) {
endpoints, err := p.Records(context.TODO())
if assert.NoError(t, err) {
if assert.Equal(t, 2, len(endpoints)) {
if assert.Equal(t, 4, len(endpoints)) {
assert.Equal(t, "www.example.org", endpoints[0].DNSName)
assert.EqualValues(t, "@", endpoints[0].Targets[0])
assert.Equal(t, "CNAME", endpoints[0].RecordType)

View File

@ -54,6 +54,8 @@ type TXTRegistry struct {
missingTXTRecords []*endpoint.Endpoint
}
const keySuffixAAAA = ":AAAA"
// NewTXTRegistry returns new TXTRegistry object
func NewTXTRegistry(provider provider.Provider, txtPrefix, txtSuffix, ownerID string, cacheInterval time.Duration, txtWildcardReplacement string, managedRecordTypes []string) (*TXTRegistry, error) {
if ownerID == "" {
@ -77,7 +79,7 @@ func NewTXTRegistry(provider provider.Provider, txtPrefix, txtSuffix, ownerID st
}
func getSupportedTypes() []string {
return []string{endpoint.RecordTypeA, endpoint.RecordTypeCNAME, endpoint.RecordTypeNS}
return []string{endpoint.RecordTypeA, endpoint.RecordTypeAAAA, endpoint.RecordTypeCNAME, endpoint.RecordTypeNS}
}
func (im *TXTRegistry) GetDomainFilter() endpoint.DomainFilterInterface {
@ -123,7 +125,11 @@ func (im *TXTRegistry) Records(ctx context.Context) ([]*endpoint.Endpoint, error
if err != nil {
return nil, err
}
key := fmt.Sprintf("%s::%s", im.mapper.toEndpointName(record.DNSName), record.SetIdentifier)
endpointName, isAAAA := im.mapper.toEndpointName(record.DNSName)
key := fmt.Sprintf("%s::%s", endpointName, record.SetIdentifier)
if isAAAA {
key += keySuffixAAAA
}
labelMap[key] = labels
txtRecordsMap[record.DNSName] = struct{}{}
}
@ -139,6 +145,9 @@ func (im *TXTRegistry) Records(ctx context.Context) ([]*endpoint.Endpoint, error
}
dnsName := strings.Join(dnsNameSplit, ".")
key := fmt.Sprintf("%s::%s", dnsName, ep.SetIdentifier)
if ep.RecordType == endpoint.RecordTypeAAAA {
key += keySuffixAAAA
}
if labels, ok := labelMap[key]; ok {
for k, v := range labels {
ep.Labels[k] = v
@ -194,13 +203,15 @@ func (im *TXTRegistry) generateTXTRecord(r *endpoint.Endpoint) []*endpoint.Endpo
endpoints := make([]*endpoint.Endpoint, 0)
// old TXT record format
txt := endpoint.NewEndpoint(im.mapper.toTXTName(r.DNSName), endpoint.RecordTypeTXT, r.Labels.Serialize(true))
if txt != nil {
txt.WithSetIdentifier(r.SetIdentifier)
txt.Labels[endpoint.OwnedRecordLabelKey] = r.DNSName
txt.ProviderSpecific = r.ProviderSpecific
endpoints = append(endpoints, txt)
if r.RecordType != endpoint.RecordTypeAAAA {
// old TXT record format
txt := endpoint.NewEndpoint(im.mapper.toTXTName(r.DNSName), endpoint.RecordTypeTXT, r.Labels.Serialize(true))
if txt != nil {
txt.WithSetIdentifier(r.SetIdentifier)
txt.Labels[endpoint.OwnedRecordLabelKey] = r.DNSName
txt.ProviderSpecific = r.ProviderSpecific
endpoints = append(endpoints, txt)
}
}
// new TXT record format (containing record type)
@ -290,12 +301,12 @@ func (im *TXTRegistry) AdjustEndpoints(endpoints []*endpoint.Endpoint) []*endpoi
*/
/**
nameMapper defines interface which maps the dns name defined for the source
to the dns name which TXT record will be created with
nameMapper is the interface for mapping between the endpoint for the source
and the endpoint for the TXT record.
*/
type nameMapper interface {
toEndpointName(string) string
toEndpointName(string) (endpointName string, isAAAA bool)
toTXTName(string) string
toNewTXTName(string, string) string
}
@ -312,14 +323,14 @@ func newaffixNameMapper(prefix, suffix, wildcardReplacement string) affixNameMap
return affixNameMapper{prefix: strings.ToLower(prefix), suffix: strings.ToLower(suffix), wildcardReplacement: strings.ToLower(wildcardReplacement)}
}
func dropRecordType(name string) string {
func extractRecordType(name string) (baseName, recordType string) {
nameS := strings.Split(name, "-")
for _, t := range getSupportedTypes() {
if nameS[0] == strings.ToLower(t) {
return strings.TrimPrefix(name, nameS[0]+"-")
return strings.TrimPrefix(name, nameS[0]+"-"), t
}
}
return name
return name, ""
}
// dropAffix strips TXT record to find an endpoint name it manages
@ -362,20 +373,20 @@ func (pr affixNameMapper) isSuffix() bool {
return len(pr.prefix) == 0 && len(pr.suffix) > 0
}
func (pr affixNameMapper) toEndpointName(txtDNSName string) string {
lowerDNSName := dropRecordType(strings.ToLower(txtDNSName))
func (pr affixNameMapper) toEndpointName(txtDNSName string) (endpointName string, isAAAA bool) {
lowerDNSName, recordType := extractRecordType(strings.ToLower(txtDNSName))
// drop prefix
if strings.HasPrefix(lowerDNSName, pr.prefix) && pr.isPrefix() {
return pr.dropAffix(lowerDNSName)
return pr.dropAffix(lowerDNSName), recordType == endpoint.RecordTypeAAAA
}
// drop suffix
if pr.isSuffix() {
DNSName := strings.SplitN(lowerDNSName, ".", 2)
return pr.dropAffix(DNSName[0]) + "." + DNSName[1]
return pr.dropAffix(DNSName[0]) + "." + DNSName[1], recordType == endpoint.RecordTypeAAAA
}
return ""
return "", false
}
func (pr affixNameMapper) toTXTName(endpointDNSName string) string {

View File

@ -101,6 +101,10 @@ func testTXTRegistryRecordsPrefixed(t *testing.T) {
newEndpointWithOwner("multiple.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner\"", endpoint.RecordTypeTXT, "").WithSetIdentifier("test-set-2"),
newEndpointWithOwner("*.wildcard.test-zone.example.org", "foo.loadbalancer.com", endpoint.RecordTypeCNAME, ""),
newEndpointWithOwner("txt.wc.wildcard.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner\"", endpoint.RecordTypeTXT, ""),
newEndpointWithOwner("dualstack.test-zone.example.org", "1.1.1.1", endpoint.RecordTypeA, ""),
newEndpointWithOwner("txt.dualstack.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner\"", endpoint.RecordTypeTXT, ""),
newEndpointWithOwner("dualstack.test-zone.example.org", "2001:DB8::1", endpoint.RecordTypeAAAA, ""),
newEndpointWithOwner("aaaa-txt.dualstack.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner-2\"", endpoint.RecordTypeTXT, ""),
},
})
expectedRecords := []*endpoint.Endpoint{
@ -181,6 +185,22 @@ func testTXTRegistryRecordsPrefixed(t *testing.T) {
endpoint.OwnerLabelKey: "owner",
},
},
{
DNSName: "dualstack.test-zone.example.org",
Targets: endpoint.Targets{"1.1.1.1"},
RecordType: endpoint.RecordTypeA,
Labels: map[string]string{
endpoint.OwnerLabelKey: "owner",
},
},
{
DNSName: "dualstack.test-zone.example.org",
Targets: endpoint.Targets{"2001:DB8::1"},
RecordType: endpoint.RecordTypeAAAA,
Labels: map[string]string{
endpoint.OwnerLabelKey: "owner-2",
},
},
}
r, _ := NewTXTRegistry(p, "txt.", "", "owner", time.Hour, "wc", []string{})
@ -214,6 +234,10 @@ func testTXTRegistryRecordsSuffixed(t *testing.T) {
newEndpointWithOwner("multiple.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner\"", endpoint.RecordTypeTXT, "").WithSetIdentifier("test-set-1"),
newEndpointWithOwner("multiple.test-zone.example.org", "lb2.loadbalancer.com", endpoint.RecordTypeCNAME, "").WithSetIdentifier("test-set-2"),
newEndpointWithOwner("multiple.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner\"", endpoint.RecordTypeTXT, "").WithSetIdentifier("test-set-2"),
newEndpointWithOwner("dualstack.test-zone.example.org", "1.1.1.1", endpoint.RecordTypeA, ""),
newEndpointWithOwner("dualstack-txt.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner\"", endpoint.RecordTypeTXT, ""),
newEndpointWithOwner("dualstack.test-zone.example.org", "2001:DB8::1", endpoint.RecordTypeAAAA, ""),
newEndpointWithOwner("aaaa-dualstack-txt.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner-2\"", endpoint.RecordTypeTXT, ""),
},
})
expectedRecords := []*endpoint.Endpoint{
@ -286,6 +310,22 @@ func testTXTRegistryRecordsSuffixed(t *testing.T) {
endpoint.OwnerLabelKey: "",
},
},
{
DNSName: "dualstack.test-zone.example.org",
Targets: endpoint.Targets{"1.1.1.1"},
RecordType: endpoint.RecordTypeA,
Labels: map[string]string{
endpoint.OwnerLabelKey: "owner",
},
},
{
DNSName: "dualstack.test-zone.example.org",
Targets: endpoint.Targets{"2001:DB8::1"},
RecordType: endpoint.RecordTypeAAAA,
Labels: map[string]string{
endpoint.OwnerLabelKey: "owner-2",
},
},
}
r, _ := NewTXTRegistry(p, "", "-txt", "owner", time.Hour, "", []string{})
@ -315,6 +355,10 @@ func testTXTRegistryRecordsNoPrefix(t *testing.T) {
newEndpointWithOwner("txt.tar.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner-2\"", endpoint.RecordTypeTXT, ""),
newEndpointWithOwner("foobar.test-zone.example.org", "foobar.loadbalancer.com", endpoint.RecordTypeCNAME, ""),
newEndpointWithOwner("foobar.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner\"", endpoint.RecordTypeTXT, ""),
newEndpointWithOwner("dualstack.test-zone.example.org", "1.1.1.1", endpoint.RecordTypeA, ""),
newEndpointWithOwner("dualstack.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner\"", endpoint.RecordTypeTXT, ""),
newEndpointWithOwner("dualstack.test-zone.example.org", "2001:DB8::1", endpoint.RecordTypeAAAA, ""),
newEndpointWithOwner("aaaa-dualstack.test-zone.example.org", "\"heritage=external-dns,external-dns/owner=owner-2\"", endpoint.RecordTypeTXT, ""),
},
})
expectedRecords := []*endpoint.Endpoint{
@ -367,6 +411,22 @@ func testTXTRegistryRecordsNoPrefix(t *testing.T) {
endpoint.OwnerLabelKey: "owner",
},
},
{
DNSName: "dualstack.test-zone.example.org",
Targets: endpoint.Targets{"1.1.1.1"},
RecordType: endpoint.RecordTypeA,
Labels: map[string]string{
endpoint.OwnerLabelKey: "owner",
},
},
{
DNSName: "dualstack.test-zone.example.org",
Targets: endpoint.Targets{"2001:DB8::1"},
RecordType: endpoint.RecordTypeAAAA,
Labels: map[string]string{
endpoint.OwnerLabelKey: "owner-2",
},
},
}
r, _ := NewTXTRegistry(p, "", "", "owner", time.Hour, "", []string{})
@ -1012,6 +1072,7 @@ func TestCacheMethods(t *testing.T) {
newEndpointWithOwner("thing2.com", "1.2.3.4", "CNAME", "owner"),
newEndpointWithOwner("thing3.com", "1.2.3.4", "A", "owner"),
newEndpointWithOwner("thing4.com", "1.2.3.4", "A", "owner"),
newEndpointWithOwner("thing4.com", "2001:DB8::1", "AAAA", "owner"),
newEndpointWithOwner("thing5.com", "1.2.3.5", "A", "owner"),
}
@ -1022,6 +1083,7 @@ func TestCacheMethods(t *testing.T) {
newEndpointWithOwner("thing4.com", "1.2.3.4", "A", "owner"),
newEndpointWithOwner("thing5.com", "1.2.3.5", "A", "owner"),
newEndpointWithOwner("thing.com", "1.2.3.6", "A", "owner2"),
newEndpointWithOwner("thing4.com", "2001:DB8::2", "AAAA", "owner"),
}
expectedCacheAfterDelete := []*endpoint.Endpoint{
@ -1032,6 +1094,7 @@ func TestCacheMethods(t *testing.T) {
newEndpointWithOwner("thing5.com", "1.2.3.5", "A", "owner"),
}
// test add cache
registry.addToCache(newEndpointWithOwner("thing4.com", "2001:DB8::1", "AAAA", "owner"))
registry.addToCache(newEndpointWithOwner("thing5.com", "1.2.3.5", "A", "owner"))
if !reflect.DeepEqual(expectedCacheAfterAdd, registry.recordsCache) {
@ -1041,6 +1104,8 @@ func TestCacheMethods(t *testing.T) {
// test update cache
registry.removeFromCache(newEndpointWithOwner("thing.com", "1.2.3.4", "A", "owner"))
registry.addToCache(newEndpointWithOwner("thing.com", "1.2.3.6", "A", "owner2"))
registry.removeFromCache(newEndpointWithOwner("thing4.com", "2001:DB8::1", "AAAA", "owner"))
registry.addToCache(newEndpointWithOwner("thing4.com", "2001:DB8::2", "AAAA", "owner"))
// ensure it was updated
if !reflect.DeepEqual(expectedCacheAfterUpdate, registry.recordsCache) {
t.Fatalf("expected endpoints should match endpoints from cache: expected %v, but got %v", expectedCacheAfterUpdate, registry.recordsCache)
@ -1048,6 +1113,7 @@ func TestCacheMethods(t *testing.T) {
// test deleting a record
registry.removeFromCache(newEndpointWithOwner("thing.com", "1.2.3.6", "A", "owner2"))
registry.removeFromCache(newEndpointWithOwner("thing4.com", "2001:DB8::2", "AAAA", "owner"))
// ensure it was deleted
if !reflect.DeepEqual(expectedCacheAfterDelete, registry.recordsCache) {
t.Fatalf("expected endpoints should match endpoints from cache: expected %v, but got %v", expectedCacheAfterDelete, registry.recordsCache)
@ -1075,11 +1141,40 @@ func TestDropSuffix(t *testing.T) {
assert.Equal(t, expectedARecord, actualARecord)
}
func TestDropRecordType(t *testing.T) {
r := "ns-zone.example.com"
expectedRecord := "zone.example.com"
actualRecord := dropRecordType(r)
assert.Equal(t, expectedRecord, actualRecord)
func TestExtractRecordType(t *testing.T) {
tests := []struct {
input string
expectedName string
expectedType string
}{
{
input: "ns-zone.example.com",
expectedName: "zone.example.com",
expectedType: "NS",
},
{
input: "aaaa-zone.example.com",
expectedName: "zone.example.com",
expectedType: "AAAA",
},
{
input: "ptr-zone.example.com",
expectedName: "ptr-zone.example.com",
expectedType: "",
},
{
input: "zone.example.com",
expectedName: "zone.example.com",
expectedType: "",
},
}
for _, tc := range tests {
t.Run(tc.input, func(t *testing.T) {
actualName, actualType := extractRecordType(tc.input)
assert.Equal(t, tc.expectedName, actualName)
assert.Equal(t, tc.expectedType, actualType)
})
}
}
func TestNewTXTScheme(t *testing.T) {
@ -1185,6 +1280,25 @@ func TestGenerateTXT(t *testing.T) {
assert.Equal(t, expectedTXT, gotTXT)
}
func TestGenerateTXTForAAAA(t *testing.T) {
record := newEndpointWithOwner("foo.test-zone.example.org", "2001:DB8::1", endpoint.RecordTypeAAAA, "owner")
expectedTXT := []*endpoint.Endpoint{
{
DNSName: "aaaa-foo.test-zone.example.org",
Targets: endpoint.Targets{"\"heritage=external-dns,external-dns/owner=owner\""},
RecordType: endpoint.RecordTypeTXT,
Labels: map[string]string{
endpoint.OwnedRecordLabelKey: "foo.test-zone.example.org",
},
},
}
p := inmemory.NewInMemoryProvider()
p.CreateZone(testZone)
r, _ := NewTXTRegistry(p, "", "", "owner", time.Hour, "", []string{})
gotTXT := r.generateTXTRecord(record)
assert.Equal(t, expectedTXT, gotTXT)
}
func TestFailGenerateTXT(t *testing.T) {
cnameRecord := &endpoint.Endpoint{

View File

@ -220,8 +220,9 @@ func testEndpointsFromHTTPProxy(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "foo.bar",
Targets: endpoint.Targets{"lb.com"},
DNSName: "foo.bar",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"lb.com"},
},
},
},
@ -235,8 +236,9 @@ func testEndpointsFromHTTPProxy(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "foo.bar",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "foo.bar",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
},
},
@ -251,12 +253,14 @@ func testEndpointsFromHTTPProxy(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "foo.bar",
Targets: endpoint.Targets{"8.8.8.8", "127.0.0.1"},
DNSName: "foo.bar",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8", "127.0.0.1"},
},
{
DNSName: "foo.bar",
Targets: endpoint.Targets{"elb.com", "alb.com"},
DNSName: "foo.bar",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"elb.com", "alb.com"},
},
},
},
@ -342,20 +346,24 @@ func testHTTPProxyEndpoints(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "example.org",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "example.org",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
{
DNSName: "example.org",
Targets: endpoint.Targets{"lb.com"},
DNSName: "example.org",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"lb.com"},
},
{
DNSName: "new.org",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "new.org",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
{
DNSName: "new.org",
Targets: endpoint.Targets{"lb.com"},
DNSName: "new.org",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"lb.com"},
},
},
},
@ -380,20 +388,24 @@ func testHTTPProxyEndpoints(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "example.org",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "example.org",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
{
DNSName: "example.org",
Targets: endpoint.Targets{"lb.com"},
DNSName: "example.org",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"lb.com"},
},
{
DNSName: "new.org",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "new.org",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
{
DNSName: "new.org",
Targets: endpoint.Targets{"lb.com"},
DNSName: "new.org",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"lb.com"},
},
},
},
@ -418,12 +430,14 @@ func testHTTPProxyEndpoints(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "example.org",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "example.org",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
{
DNSName: "example.org",
Targets: endpoint.Targets{"lb.com"},
DNSName: "example.org",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"lb.com"},
},
},
},
@ -446,8 +460,9 @@ func testHTTPProxyEndpoints(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "example.org",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "example.org",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
},
},
@ -509,8 +524,9 @@ func testHTTPProxyEndpoints(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "example.org",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "example.org",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
},
},
@ -551,8 +567,9 @@ func testHTTPProxyEndpoints(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "example.org",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "example.org",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
},
},
@ -593,12 +610,14 @@ func testHTTPProxyEndpoints(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "fake1.ext-dns.test.com",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "fake1.ext-dns.test.com",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
{
DNSName: "fake1.ext-dns.test.com",
Targets: endpoint.Targets{"elb.com"},
DNSName: "fake1.ext-dns.test.com",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"elb.com"},
},
},
fqdnTemplate: "{{.Name}}.ext-dns.test.com",
@ -882,19 +901,22 @@ func testHTTPProxyEndpoints(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "example.org",
Targets: endpoint.Targets{"httpproxy-target.com"},
RecordTTL: endpoint.TTL(6),
DNSName: "example.org",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"httpproxy-target.com"},
RecordTTL: endpoint.TTL(6),
},
{
DNSName: "example2.org",
Targets: endpoint.Targets{"httpproxy-target.com"},
RecordTTL: endpoint.TTL(1),
DNSName: "example2.org",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"httpproxy-target.com"},
RecordTTL: endpoint.TTL(1),
},
{
DNSName: "example3.org",
Targets: endpoint.Targets{"httpproxy-target.com"},
RecordTTL: endpoint.TTL(10),
DNSName: "example3.org",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"httpproxy-target.com"},
RecordTTL: endpoint.TTL(10),
},
},
},
@ -997,20 +1019,24 @@ func testHTTPProxyEndpoints(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "example.org",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "example.org",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
{
DNSName: "example.org",
Targets: endpoint.Targets{"lb.com"},
DNSName: "example.org",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"lb.com"},
},
{
DNSName: "new.org",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "new.org",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
{
DNSName: "new.org",
Targets: endpoint.Targets{"lb.com"},
DNSName: "new.org",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"lb.com"},
},
},
ignoreHostnameAnnotation: true,

View File

@ -177,8 +177,9 @@ func testEndpointsFromIngress(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "foo.bar",
Targets: endpoint.Targets{"lb.com"},
DNSName: "foo.bar",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"lb.com"},
},
},
},
@ -190,8 +191,9 @@ func testEndpointsFromIngress(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "foo.bar",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "foo.bar",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
},
},
@ -204,12 +206,14 @@ func testEndpointsFromIngress(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "foo.bar",
Targets: endpoint.Targets{"8.8.8.8", "127.0.0.1"},
DNSName: "foo.bar",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8", "127.0.0.1"},
},
{
DNSName: "foo.bar",
Targets: endpoint.Targets{"elb.com", "alb.com"},
DNSName: "foo.bar",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"elb.com", "alb.com"},
},
},
},
@ -270,12 +274,14 @@ func testEndpointsFromIngressHostnameSourceAnnotation(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "foo.bar",
Targets: endpoint.Targets{"lb.com"},
DNSName: "foo.bar",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"lb.com"},
},
{
DNSName: "foo.baz",
Targets: endpoint.Targets{"lb.com"},
DNSName: "foo.baz",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"lb.com"},
},
},
},
@ -287,8 +293,9 @@ func testEndpointsFromIngressHostnameSourceAnnotation(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "foo.bar",
Targets: endpoint.Targets{"lb.com"},
DNSName: "foo.bar",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"lb.com"},
},
},
},
@ -301,12 +308,14 @@ func testEndpointsFromIngressHostnameSourceAnnotation(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "foo.bar",
Targets: endpoint.Targets{"lb.com"},
DNSName: "foo.bar",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"lb.com"},
},
{
DNSName: "foo.baz",
Targets: endpoint.Targets{"lb.com"},
DNSName: "foo.baz",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"lb.com"},
},
},
},
@ -319,8 +328,9 @@ func testEndpointsFromIngressHostnameSourceAnnotation(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "foo.bar",
Targets: endpoint.Targets{"lb.com"},
DNSName: "foo.bar",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"lb.com"},
},
},
},
@ -333,8 +343,9 @@ func testEndpointsFromIngressHostnameSourceAnnotation(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "foo.baz",
Targets: endpoint.Targets{"lb.com"},
DNSName: "foo.baz",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"lb.com"},
},
},
},
@ -387,12 +398,33 @@ func testIngressEndpoints(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "example.org",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "example.org",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
{
DNSName: "new.org",
Targets: endpoint.Targets{"lb.com"},
DNSName: "new.org",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"lb.com"},
},
},
},
{
title: "ipv6 ingress",
targetNamespace: "",
ingressItems: []fakeIngress{
{
name: "fake1",
namespace: namespace,
dnsnames: []string{"example.org"},
ips: []string{"2001:DB8::1"},
},
},
expected: []*endpoint.Endpoint{
{
DNSName: "example.org",
RecordType: endpoint.RecordTypeAAAA,
Targets: endpoint.Targets{"2001:DB8::1"},
},
},
},
@ -435,12 +467,14 @@ func testIngressEndpoints(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "example.org",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "example.org",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
{
DNSName: "new.org",
Targets: endpoint.Targets{"lb.com"},
DNSName: "new.org",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"lb.com"},
},
},
},
@ -463,8 +497,9 @@ func testIngressEndpoints(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "example.org",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "example.org",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
},
},
@ -485,8 +520,9 @@ func testIngressEndpoints(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "example.org",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "example.org",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
},
},
@ -542,8 +578,9 @@ func testIngressEndpoints(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "example.org",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "example.org",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
},
},
@ -580,8 +617,9 @@ func testIngressEndpoints(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "example.org",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "example.org",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
},
},
@ -618,12 +656,14 @@ func testIngressEndpoints(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "fake1.ext-dns.test.com",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "fake1.ext-dns.test.com",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
{
DNSName: "fake1.ext-dns.test.com",
Targets: endpoint.Targets{"elb.com"},
DNSName: "fake1.ext-dns.test.com",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"elb.com"},
},
},
fqdnTemplate: "{{.Name}}.ext-dns.test.com",
@ -973,19 +1013,22 @@ func testIngressEndpoints(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "example.org",
Targets: endpoint.Targets{"ingress-target.com"},
RecordTTL: endpoint.TTL(6),
DNSName: "example.org",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"ingress-target.com"},
RecordTTL: endpoint.TTL(6),
},
{
DNSName: "example2.org",
Targets: endpoint.Targets{"ingress-target.com"},
RecordTTL: endpoint.TTL(1),
DNSName: "example2.org",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"ingress-target.com"},
RecordTTL: endpoint.TTL(1),
},
{
DNSName: "example3.org",
Targets: endpoint.Targets{"ingress-target.com"},
RecordTTL: endpoint.TTL(10),
DNSName: "example3.org",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"ingress-target.com"},
RecordTTL: endpoint.TTL(10),
},
},
},
@ -1132,12 +1175,14 @@ func testIngressEndpoints(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "example.org",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "example.org",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
{
DNSName: "new.org",
Targets: endpoint.Targets{"lb.com"},
DNSName: "new.org",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"lb.com"},
},
},
},
@ -1169,8 +1214,9 @@ func testIngressEndpoints(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "example.org",
Targets: endpoint.Targets{"1.2.3.4"},
DNSName: "example.org",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"1.2.3.4"},
},
},
},
@ -1189,8 +1235,9 @@ func testIngressEndpoints(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "example.org",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "example.org",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
},
},

View File

@ -184,8 +184,9 @@ func testEndpointsFromGatewayConfig(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "foo.bar",
Targets: endpoint.Targets{"lb.com"},
DNSName: "foo.bar",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"lb.com"},
},
},
},
@ -203,8 +204,9 @@ func testEndpointsFromGatewayConfig(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "foo.bar",
Targets: endpoint.Targets{"lb.com"},
DNSName: "foo.bar",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"lb.com"},
},
},
},
@ -222,8 +224,9 @@ func testEndpointsFromGatewayConfig(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "foo.bar",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "foo.bar",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
},
},
@ -242,12 +245,14 @@ func testEndpointsFromGatewayConfig(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "foo.bar",
Targets: endpoint.Targets{"8.8.8.8", "127.0.0.1"},
DNSName: "foo.bar",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8", "127.0.0.1"},
},
{
DNSName: "foo.bar",
Targets: endpoint.Targets{"elb.com", "alb.com"},
DNSName: "foo.bar",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"elb.com", "alb.com"},
},
},
},
@ -310,8 +315,9 @@ func testEndpointsFromGatewayConfig(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "foo.bar",
Targets: endpoint.Targets{"lb.com", "lb2.com"},
DNSName: "foo.bar",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"lb.com", "lb2.com"},
},
},
},
@ -376,20 +382,24 @@ func testGatewayEndpoints(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "example.org",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "example.org",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
{
DNSName: "example.org",
Targets: endpoint.Targets{"lb.com"},
DNSName: "example.org",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"lb.com"},
},
{
DNSName: "new.org",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "new.org",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
{
DNSName: "new.org",
Targets: endpoint.Targets{"lb.com"},
DNSName: "new.org",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"lb.com"},
},
},
},
@ -416,20 +426,24 @@ func testGatewayEndpoints(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "example.org",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "example.org",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
{
DNSName: "example.org",
Targets: endpoint.Targets{"lb.com"},
DNSName: "example.org",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"lb.com"},
},
{
DNSName: "new.org",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "new.org",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
{
DNSName: "new.org",
Targets: endpoint.Targets{"lb.com"},
DNSName: "new.org",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"lb.com"},
},
},
},
@ -452,12 +466,14 @@ func testGatewayEndpoints(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "example.org",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "example.org",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
{
DNSName: "example.org",
Targets: endpoint.Targets{"lb.com"},
DNSName: "example.org",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"lb.com"},
},
},
},
@ -482,8 +498,9 @@ func testGatewayEndpoints(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "example.org",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "example.org",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
},
},
@ -551,8 +568,9 @@ func testGatewayEndpoints(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "example.org",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "example.org",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
},
},
@ -597,8 +615,9 @@ func testGatewayEndpoints(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "example.org",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "example.org",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
},
},
@ -643,12 +662,14 @@ func testGatewayEndpoints(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "fake1.ext-dns.test.com",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "fake1.ext-dns.test.com",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
{
DNSName: "fake1.ext-dns.test.com",
Targets: endpoint.Targets{"elb.com"},
DNSName: "fake1.ext-dns.test.com",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"elb.com"},
},
},
fqdnTemplate: "{{.Name}}.ext-dns.test.com",
@ -948,19 +969,22 @@ func testGatewayEndpoints(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "example.org",
Targets: endpoint.Targets{"gateway-target.com"},
RecordTTL: endpoint.TTL(6),
DNSName: "example.org",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"gateway-target.com"},
RecordTTL: endpoint.TTL(6),
},
{
DNSName: "example2.org",
Targets: endpoint.Targets{"gateway-target.com"},
RecordTTL: endpoint.TTL(1),
DNSName: "example2.org",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"gateway-target.com"},
RecordTTL: endpoint.TTL(1),
},
{
DNSName: "example3.org",
Targets: endpoint.Targets{"gateway-target.com"},
RecordTTL: endpoint.TTL(10),
DNSName: "example3.org",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"gateway-target.com"},
RecordTTL: endpoint.TTL(10),
},
},
},
@ -1069,20 +1093,24 @@ func testGatewayEndpoints(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "example.org",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "example.org",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
{
DNSName: "example.org",
Targets: endpoint.Targets{"lb.com"},
DNSName: "example.org",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"lb.com"},
},
{
DNSName: "new.org",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "new.org",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
{
DNSName: "new.org",
Targets: endpoint.Targets{"lb.com"},
DNSName: "new.org",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"lb.com"},
},
},
ignoreHostnameAnnotation: true,
@ -1137,12 +1165,14 @@ func testGatewayEndpoints(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "fake1.dns-through-hostname.com",
Targets: endpoint.Targets{"1.2.3.4"},
DNSName: "fake1.dns-through-hostname.com",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"1.2.3.4"},
},
{
DNSName: "fake2.dns-through-hostname.com",
Targets: endpoint.Targets{"1.2.3.4"},
DNSName: "fake2.dns-through-hostname.com",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"1.2.3.4"},
},
},
},

View File

@ -394,8 +394,9 @@ func testEndpointsFromVirtualServiceConfig(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "foo.bar",
Targets: endpoint.Targets{"lb.com"},
DNSName: "foo.bar",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"lb.com"},
},
},
},
@ -416,8 +417,9 @@ func testEndpointsFromVirtualServiceConfig(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "foo.bar",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "foo.bar",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
},
},
@ -439,12 +441,14 @@ func testEndpointsFromVirtualServiceConfig(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "foo.bar",
Targets: endpoint.Targets{"8.8.8.8", "127.0.0.1"},
DNSName: "foo.bar",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8", "127.0.0.1"},
},
{
DNSName: "foo.bar",
Targets: endpoint.Targets{"elb.com", "alb.com"},
DNSName: "foo.bar",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"elb.com", "alb.com"},
},
},
},
@ -543,8 +547,9 @@ func testEndpointsFromVirtualServiceConfig(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "foo.bar",
Targets: endpoint.Targets{"elb.com", "alb.com"},
DNSName: "foo.bar",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"elb.com", "alb.com"},
},
},
},
@ -618,20 +623,24 @@ func testVirtualServiceEndpoints(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "example.org",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "example.org",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
{
DNSName: "example.org",
Targets: endpoint.Targets{"lb.com"},
DNSName: "example.org",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"lb.com"},
},
{
DNSName: "new.org",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "new.org",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
{
DNSName: "new.org",
Targets: endpoint.Targets{"lb.com"},
DNSName: "new.org",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"lb.com"},
},
},
},
@ -665,8 +674,9 @@ func testVirtualServiceEndpoints(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "example.org",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "example.org",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
},
},
@ -702,20 +712,24 @@ func testVirtualServiceEndpoints(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "example.org",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "example.org",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
{
DNSName: "example.org",
Targets: endpoint.Targets{"lb.com"},
DNSName: "example.org",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"lb.com"},
},
{
DNSName: "new.org",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "new.org",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
{
DNSName: "new.org",
Targets: endpoint.Targets{"lb.com"},
DNSName: "new.org",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"lb.com"},
},
},
},
@ -752,12 +766,14 @@ func testVirtualServiceEndpoints(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "example.org",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "example.org",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
{
DNSName: "example.org",
Targets: endpoint.Targets{"lb.com"},
DNSName: "example.org",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"lb.com"},
},
},
},
@ -790,8 +806,9 @@ func testVirtualServiceEndpoints(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "example.org",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "example.org",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
},
},
@ -858,8 +875,9 @@ func testVirtualServiceEndpoints(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "example.org",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "example.org",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
},
},
@ -917,12 +935,14 @@ func testVirtualServiceEndpoints(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "vs1.ext-dns.test.com",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "vs1.ext-dns.test.com",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
{
DNSName: "vs1.ext-dns.test.com",
Targets: endpoint.Targets{"elb.com"},
DNSName: "vs1.ext-dns.test.com",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"elb.com"},
},
},
fqdnTemplate: "{{.Name}}.ext-dns.test.com",
@ -1206,14 +1226,16 @@ func testVirtualServiceEndpoints(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "example.org",
Targets: endpoint.Targets{"8.8.8.8"},
RecordTTL: endpoint.TTL(6),
DNSName: "example.org",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
RecordTTL: endpoint.TTL(6),
},
{
DNSName: "example2.org",
Targets: endpoint.Targets{"8.8.8.8"},
RecordTTL: endpoint.TTL(1),
DNSName: "example2.org",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
RecordTTL: endpoint.TTL(1),
},
},
},
@ -1322,20 +1344,24 @@ func testVirtualServiceEndpoints(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "example.org",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "example.org",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
{
DNSName: "example.org",
Targets: endpoint.Targets{"lb.com"},
DNSName: "example.org",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"lb.com"},
},
{
DNSName: "new.org",
Targets: endpoint.Targets{"8.8.8.8"},
DNSName: "new.org",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets{"8.8.8.8"},
},
{
DNSName: "new.org",
Targets: endpoint.Targets{"lb.com"},
DNSName: "new.org",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets{"lb.com"},
},
},
ignoreHostnameAnnotation: true,

View File

@ -197,7 +197,8 @@ func testOcpRouteSourceEndpoints(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "my-domain.com",
DNSName: "my-domain.com",
RecordType: endpoint.RecordTypeCNAME,
Targets: []string{
"apps.my-domain.com",
},
@ -230,7 +231,8 @@ func testOcpRouteSourceEndpoints(t *testing.T) {
ocpRouterName: "default",
expected: []*endpoint.Endpoint{
{
DNSName: "my-domain.com",
DNSName: "my-domain.com",
RecordType: endpoint.RecordTypeCNAME,
Targets: []string{
"router-default.my-domain.com",
},
@ -274,7 +276,8 @@ func testOcpRouteSourceEndpoints(t *testing.T) {
ocpRouterName: "default",
expected: []*endpoint.Endpoint{
{
DNSName: "my-domain.com",
DNSName: "my-domain.com",
RecordType: endpoint.RecordTypeCNAME,
Targets: []string{
"router-default.my-domain.com",
},
@ -393,8 +396,11 @@ func testOcpRouteSourceEndpoints(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "my-domain.com",
Targets: []string{"router-test.my-domain.com"},
DNSName: "my-domain.com",
RecordType: endpoint.RecordTypeCNAME,
Targets: []string{
"router-test.my-domain.com",
},
},
},
},
@ -439,7 +445,8 @@ func testOcpRouteSourceEndpoints(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "my-annotation-domain.com",
DNSName: "my-annotation-domain.com",
RecordType: endpoint.RecordTypeCNAME,
Targets: []string{
"my.site.foo.com",
},
@ -479,7 +486,8 @@ func testOcpRouteSourceEndpoints(t *testing.T) {
},
expected: []*endpoint.Endpoint{
{
DNSName: "my-annotation-domain.com",
DNSName: "my-annotation-domain.com",
RecordType: endpoint.RecordTypeCNAME,
Targets: []string{
"my.site.foo.com",
},

View File

@ -456,6 +456,14 @@ func (sc *serviceSource) generateEndpoints(svc *v1.Service, hostname string, pro
DNSName: hostname,
}
epAAAA := &endpoint.Endpoint{
RecordTTL: ttl,
RecordType: endpoint.RecordTypeAAAA,
Labels: endpoint.NewLabels(),
Targets: make(endpoint.Targets, 0, defaultTargetsCapacity),
DNSName: hostname,
}
epCNAME := &endpoint.Endpoint{
RecordTTL: ttl,
RecordType: endpoint.RecordTypeCNAME,
@ -494,10 +502,12 @@ func (sc *serviceSource) generateEndpoints(svc *v1.Service, hostname string, pro
}
for _, t := range targets {
if suitableType(t) == endpoint.RecordTypeA {
switch suitableType(t) {
case endpoint.RecordTypeA:
epA.Targets = append(epA.Targets, t)
}
if suitableType(t) == endpoint.RecordTypeCNAME {
case endpoint.RecordTypeAAAA:
epAAAA.Targets = append(epAAAA.Targets, t)
case endpoint.RecordTypeCNAME:
epCNAME.Targets = append(epCNAME.Targets, t)
}
}
@ -505,6 +515,9 @@ func (sc *serviceSource) generateEndpoints(svc *v1.Service, hostname string, pro
if len(epA.Targets) > 0 {
endpoints = append(endpoints, epA)
}
if len(epAAAA.Targets) > 0 {
endpoints = append(endpoints, epAAAA)
}
if len(epCNAME.Targets) > 0 {
endpoints = append(endpoints, epCNAME)
}

View File

@ -232,7 +232,7 @@ func testServiceSourceEndpoints(t *testing.T) {
lbs: []string{"1.2.3.4"},
serviceTypesFilter: []string{},
expected: []*endpoint.Endpoint{
{DNSName: "foo.example.org", Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "foo.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
},
},
{
@ -277,8 +277,8 @@ func testServiceSourceEndpoints(t *testing.T) {
lbs: []string{"1.2.3.4"},
serviceTypesFilter: []string{},
expected: []*endpoint.Endpoint{
{DNSName: "foo.fqdn.org", Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "foo.fqdn.com", Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "foo.fqdn.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "foo.fqdn.com", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
},
},
{
@ -294,8 +294,8 @@ func testServiceSourceEndpoints(t *testing.T) {
lbs: []string{"1.2.3.4"},
serviceTypesFilter: []string{},
expected: []*endpoint.Endpoint{
{DNSName: "foo.fqdn.org", Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "foo.fqdn.com", Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "foo.fqdn.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "foo.fqdn.com", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
},
},
{
@ -313,10 +313,10 @@ func testServiceSourceEndpoints(t *testing.T) {
lbs: []string{"1.2.3.4"},
serviceTypesFilter: []string{},
expected: []*endpoint.Endpoint{
{DNSName: "foo.example.org", Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "bar.example.org", Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "foo.fqdn.org", Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "foo.fqdn.com", Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "foo.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "bar.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "foo.fqdn.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "foo.fqdn.com", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
},
},
{
@ -335,8 +335,8 @@ func testServiceSourceEndpoints(t *testing.T) {
lbs: []string{"1.2.3.4"},
serviceTypesFilter: []string{},
expected: []*endpoint.Endpoint{
{DNSName: "foo.fqdn.org", Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "foo.fqdn.com", Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "foo.fqdn.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "foo.fqdn.com", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
},
},
{
@ -352,8 +352,8 @@ func testServiceSourceEndpoints(t *testing.T) {
lbs: []string{"1.2.3.4"},
serviceTypesFilter: []string{},
expected: []*endpoint.Endpoint{
{DNSName: "foo.example.org", Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "bar.example.org", Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "foo.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "bar.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
},
},
{
@ -369,8 +369,8 @@ func testServiceSourceEndpoints(t *testing.T) {
lbs: []string{"1.2.3.4"},
serviceTypesFilter: []string{},
expected: []*endpoint.Endpoint{
{DNSName: "foo.example.org", Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "bar.example.org", Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "foo.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "bar.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
},
},
{
@ -386,7 +386,7 @@ func testServiceSourceEndpoints(t *testing.T) {
lbs: []string{"lb.example.com"}, // Kubernetes omits the trailing dot
serviceTypesFilter: []string{},
expected: []*endpoint.Endpoint{
{DNSName: "foo.example.org", Targets: endpoint.Targets{"lb.example.com"}},
{DNSName: "foo.example.org", RecordType: endpoint.RecordTypeCNAME, Targets: endpoint.Targets{"lb.example.com"}},
},
},
{
@ -402,8 +402,8 @@ func testServiceSourceEndpoints(t *testing.T) {
lbs: []string{"1.2.3.4", "lb.example.com"}, // Kubernetes omits the trailing dot
serviceTypesFilter: []string{},
expected: []*endpoint.Endpoint{
{DNSName: "foo.example.org", Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "foo.example.org", Targets: endpoint.Targets{"lb.example.com"}},
{DNSName: "foo.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "foo.example.org", RecordType: endpoint.RecordTypeCNAME, Targets: endpoint.Targets{"lb.example.com"}},
},
},
{
@ -420,7 +420,7 @@ func testServiceSourceEndpoints(t *testing.T) {
lbs: []string{"1.2.3.4"},
serviceTypesFilter: []string{},
expected: []*endpoint.Endpoint{
{DNSName: "foo.example.org", Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "foo.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
},
},
{
@ -453,7 +453,7 @@ func testServiceSourceEndpoints(t *testing.T) {
lbs: []string{"1.2.3.4"},
serviceTypesFilter: []string{},
expected: []*endpoint.Endpoint{
{DNSName: "foo.example.org", Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "foo.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
},
},
{
@ -484,7 +484,7 @@ func testServiceSourceEndpoints(t *testing.T) {
lbs: []string{"1.2.3.4"},
serviceTypesFilter: []string{},
expected: []*endpoint.Endpoint{
{DNSName: "foo.example.org", Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "foo.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
},
},
{
@ -502,7 +502,7 @@ func testServiceSourceEndpoints(t *testing.T) {
lbs: []string{"1.2.3.4"},
serviceTypesFilter: []string{},
expected: []*endpoint.Endpoint{
{DNSName: "foo.example.org", Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "foo.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
},
},
{
@ -553,7 +553,7 @@ func testServiceSourceEndpoints(t *testing.T) {
lbs: []string{"1.2.3.4"},
serviceTypesFilter: []string{},
expected: []*endpoint.Endpoint{
{DNSName: "foo.example.org", Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "foo.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
},
},
{
@ -599,7 +599,7 @@ func testServiceSourceEndpoints(t *testing.T) {
lbs: []string{"1.2.3.4"},
serviceTypesFilter: []string{},
expected: []*endpoint.Endpoint{
{DNSName: "foo.example.org", Targets: endpoint.Targets{"10.2.3.4", "11.2.3.4"}},
{DNSName: "foo.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"10.2.3.4", "11.2.3.4"}},
},
},
{
@ -615,7 +615,7 @@ func testServiceSourceEndpoints(t *testing.T) {
lbs: []string{"1.2.3.4", "8.8.8.8"},
serviceTypesFilter: []string{},
expected: []*endpoint.Endpoint{
{DNSName: "foo.example.org", Targets: endpoint.Targets{"1.2.3.4", "8.8.8.8"}},
{DNSName: "foo.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4", "8.8.8.8"}},
},
},
{
@ -646,7 +646,7 @@ func testServiceSourceEndpoints(t *testing.T) {
lbs: []string{"1.2.3.4"},
serviceTypesFilter: []string{},
expected: []*endpoint.Endpoint{
{DNSName: "foo.example.org", Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "foo.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
},
},
{
@ -665,8 +665,8 @@ func testServiceSourceEndpoints(t *testing.T) {
lbs: []string{"1.2.3.4"},
serviceTypesFilter: []string{},
expected: []*endpoint.Endpoint{
{DNSName: "foo.example.org", Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "bar.example.org", Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "foo.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "bar.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
},
},
{
@ -683,8 +683,8 @@ func testServiceSourceEndpoints(t *testing.T) {
lbs: []string{"1.2.3.4", "lb.example.com"},
serviceTypesFilter: []string{},
expected: []*endpoint.Endpoint{
{DNSName: "internal.foo.example.org", Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "internal.foo.example.org", Targets: endpoint.Targets{"lb.example.com"}},
{DNSName: "internal.foo.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "internal.foo.example.org", RecordType: endpoint.RecordTypeCNAME, Targets: endpoint.Targets{"lb.example.com"}},
},
},
{
@ -702,10 +702,10 @@ func testServiceSourceEndpoints(t *testing.T) {
lbs: []string{"1.2.3.4"},
serviceTypesFilter: []string{},
expected: []*endpoint.Endpoint{
{DNSName: "foo.example.org", Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "bar.example.org", Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "internal.foo.example.org", Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "internal.bar.example.org", Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "foo.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "bar.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "internal.foo.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "internal.bar.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
},
},
{
@ -720,8 +720,8 @@ func testServiceSourceEndpoints(t *testing.T) {
lbs: []string{"1.2.3.4", "elb.com"},
serviceTypesFilter: []string{},
expected: []*endpoint.Endpoint{
{DNSName: "foo.bar.example.com", Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "foo.bar.example.com", Targets: endpoint.Targets{"elb.com"}},
{DNSName: "foo.bar.example.com", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "foo.bar.example.com", RecordType: endpoint.RecordTypeCNAME, Targets: endpoint.Targets{"elb.com"}},
},
},
{
@ -738,8 +738,8 @@ func testServiceSourceEndpoints(t *testing.T) {
lbs: []string{"1.2.3.4", "elb.com"},
serviceTypesFilter: []string{},
expected: []*endpoint.Endpoint{
{DNSName: "foo.example.org", Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "foo.example.org", Targets: endpoint.Targets{"elb.com"}},
{DNSName: "foo.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "foo.example.org", RecordType: endpoint.RecordTypeCNAME, Targets: endpoint.Targets{"elb.com"}},
},
},
{
@ -757,7 +757,7 @@ func testServiceSourceEndpoints(t *testing.T) {
lbs: []string{"1.2.3.4"},
serviceTypesFilter: []string{},
expected: []*endpoint.Endpoint{
{DNSName: "mate.example.org", Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "mate.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
},
},
{
@ -787,7 +787,7 @@ func testServiceSourceEndpoints(t *testing.T) {
lbs: []string{"1.2.3.4"},
serviceTypesFilter: []string{},
expected: []*endpoint.Endpoint{
{DNSName: "foo.example.org", Targets: endpoint.Targets{"1.2.3.4"}, RecordTTL: endpoint.TTL(0)},
{DNSName: "foo.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}, RecordTTL: endpoint.TTL(0)},
},
},
{
@ -804,7 +804,7 @@ func testServiceSourceEndpoints(t *testing.T) {
lbs: []string{"1.2.3.4"},
serviceTypesFilter: []string{},
expected: []*endpoint.Endpoint{
{DNSName: "foo.example.org", Targets: endpoint.Targets{"1.2.3.4"}, RecordTTL: endpoint.TTL(0)},
{DNSName: "foo.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}, RecordTTL: endpoint.TTL(0)},
},
},
{
@ -821,7 +821,7 @@ func testServiceSourceEndpoints(t *testing.T) {
lbs: []string{"1.2.3.4"},
serviceTypesFilter: []string{},
expected: []*endpoint.Endpoint{
{DNSName: "foo.example.org", Targets: endpoint.Targets{"1.2.3.4"}, RecordTTL: endpoint.TTL(10)},
{DNSName: "foo.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}, RecordTTL: endpoint.TTL(10)},
},
},
{
@ -838,7 +838,7 @@ func testServiceSourceEndpoints(t *testing.T) {
lbs: []string{"1.2.3.4"},
serviceTypesFilter: []string{},
expected: []*endpoint.Endpoint{
{DNSName: "foo.example.org", Targets: endpoint.Targets{"1.2.3.4"}, RecordTTL: endpoint.TTL(60)},
{DNSName: "foo.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}, RecordTTL: endpoint.TTL(60)},
},
},
{
@ -855,7 +855,7 @@ func testServiceSourceEndpoints(t *testing.T) {
lbs: []string{"1.2.3.4"},
serviceTypesFilter: []string{},
expected: []*endpoint.Endpoint{
{DNSName: "foo.example.org", Targets: endpoint.Targets{"1.2.3.4"}, RecordTTL: endpoint.TTL(0)},
{DNSName: "foo.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}, RecordTTL: endpoint.TTL(0)},
},
},
{
@ -871,7 +871,7 @@ func testServiceSourceEndpoints(t *testing.T) {
lbs: []string{"1.2.3.4"},
serviceTypesFilter: []string{string(v1.ServiceTypeLoadBalancer)},
expected: []*endpoint.Endpoint{
{DNSName: "foo.example.org", Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "foo.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
},
},
{
@ -902,7 +902,7 @@ func testServiceSourceEndpoints(t *testing.T) {
lbs: []string{"1.2.3.4"},
serviceTypesFilter: []string{},
expected: []*endpoint.Endpoint{
{DNSName: "foo.internal.example.org", Targets: endpoint.Targets{"1.1.1.1"}},
{DNSName: "foo.internal.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.1.1.1"}},
},
},
{
@ -920,8 +920,8 @@ func testServiceSourceEndpoints(t *testing.T) {
lbs: []string{"1.2.3.4"},
serviceTypesFilter: []string{},
expected: []*endpoint.Endpoint{
{DNSName: "foo.internal.example.org", Targets: endpoint.Targets{"1.1.1.1"}},
{DNSName: "foo.example.org", Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "foo.internal.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.1.1.1"}},
{DNSName: "foo.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
},
},
{
@ -939,7 +939,7 @@ func testServiceSourceEndpoints(t *testing.T) {
serviceLabelSelector: "app=web-external",
fqdnTemplate: "{{.Name}}.bar.example.com",
expected: []*endpoint.Endpoint{
{DNSName: "fqdn.bar.example.com", Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "fqdn.bar.example.com", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
},
},
{
@ -957,7 +957,7 @@ func testServiceSourceEndpoints(t *testing.T) {
serviceLabelSelector: "app=web-external",
annotations: map[string]string{hostnameAnnotationKey: "annotation.bar.example.com"},
expected: []*endpoint.Endpoint{
{DNSName: "annotation.bar.example.com", Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "annotation.bar.example.com", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
},
},
{
@ -992,6 +992,37 @@ func testServiceSourceEndpoints(t *testing.T) {
annotations: map[string]string{hostnameAnnotationKey: "annotation.bar.example.com"},
expected: []*endpoint.Endpoint{},
},
{
title: "dual-stack load-balancer service gets both addresses",
svcNamespace: "testing",
svcName: "foobar",
svcType: v1.ServiceTypeLoadBalancer,
labels: map[string]string{},
clusterIP: "1.1.1.2,2001:db8::2",
externalIPs: []string{},
lbs: []string{"1.1.1.1", "2001:db8::1"},
serviceTypesFilter: []string{},
annotations: map[string]string{hostnameAnnotationKey: "foobar.example.org"},
expected: []*endpoint.Endpoint{
{DNSName: "foobar.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.1.1.1"}},
{DNSName: "foobar.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:db8::1"}},
},
},
{
title: "IPv6-only load-balancer service gets IPv6 endpoint",
svcNamespace: "testing",
svcName: "foobar-v6",
svcType: v1.ServiceTypeLoadBalancer,
labels: map[string]string{},
clusterIP: "2001:db8::1",
externalIPs: []string{},
lbs: []string{"2001:db8::2"},
serviceTypesFilter: []string{},
annotations: map[string]string{hostnameAnnotationKey: "foobar-v6.example.org"},
expected: []*endpoint.Endpoint{
{DNSName: "foobar-v6.example.org", RecordType: endpoint.RecordTypeAAAA, Targets: endpoint.Targets{"2001:db8::2"}},
},
},
} {
tc := tc
t.Run(tc.title, func(t *testing.T) {
@ -1112,7 +1143,7 @@ func testMultipleServicesEndpoints(t *testing.T) {
},
[]string{},
[]*endpoint.Endpoint{
{DNSName: "foo.example.org", Targets: endpoint.Targets{"1.2.3.4"}, Labels: map[string]string{endpoint.ResourceLabelKey: "service/testing/foo1.2.3.4"}},
{DNSName: "foo.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}, Labels: map[string]string{endpoint.ResourceLabelKey: "service/testing/foo1.2.3.4"}},
},
false,
},
@ -1136,7 +1167,7 @@ func testMultipleServicesEndpoints(t *testing.T) {
},
[]string{},
[]*endpoint.Endpoint{
{DNSName: "foo.example.org", Targets: endpoint.Targets{"1.2.3.4", "1.2.3.5", "1.2.3.6"}, Labels: map[string]string{endpoint.ResourceLabelKey: "service/testing/foo1.2.3.4"}},
{DNSName: "foo.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4", "1.2.3.5", "1.2.3.6"}, Labels: map[string]string{endpoint.ResourceLabelKey: "service/testing/foo1.2.3.4"}},
},
false,
},
@ -1164,9 +1195,9 @@ func testMultipleServicesEndpoints(t *testing.T) {
},
[]string{},
[]*endpoint.Endpoint{
{DNSName: "foo.example.org", Targets: endpoint.Targets{"1.2.3.4", "1.2.3.5", "1.2.3.6"}, Labels: map[string]string{endpoint.ResourceLabelKey: "service/testing/foo1.2.3.4"}},
{DNSName: "bar.example.org", Targets: endpoint.Targets{"10.1.1.1", "10.1.1.2", "10.1.1.3"}, Labels: map[string]string{endpoint.ResourceLabelKey: "service/testing/foo10.1.1.1"}},
{DNSName: "foobar.example.org", Targets: endpoint.Targets{"20.1.1.1"}, Labels: map[string]string{endpoint.ResourceLabelKey: "service/testing/foo20.1.1.1"}},
{DNSName: "foo.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4", "1.2.3.5", "1.2.3.6"}, Labels: map[string]string{endpoint.ResourceLabelKey: "service/testing/foo1.2.3.4"}},
{DNSName: "bar.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"10.1.1.1", "10.1.1.2", "10.1.1.3"}, Labels: map[string]string{endpoint.ResourceLabelKey: "service/testing/foo10.1.1.1"}},
{DNSName: "foobar.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"20.1.1.1"}, Labels: map[string]string{endpoint.ResourceLabelKey: "service/testing/foo20.1.1.1"}},
},
false,
},
@ -1189,8 +1220,8 @@ func testMultipleServicesEndpoints(t *testing.T) {
},
[]string{},
[]*endpoint.Endpoint{
{DNSName: "foo.example.org", Targets: endpoint.Targets{"a.elb.com"}, Labels: map[string]string{endpoint.ResourceLabelKey: "service/testing/fooa.elb.com"}, SetIdentifier: "a"},
{DNSName: "foo.example.org", Targets: endpoint.Targets{"b.elb.com"}, Labels: map[string]string{endpoint.ResourceLabelKey: "service/testing/foob.elb.com"}, SetIdentifier: "b"},
{DNSName: "foo.example.org", RecordType: endpoint.RecordTypeCNAME, Targets: endpoint.Targets{"a.elb.com"}, Labels: map[string]string{endpoint.ResourceLabelKey: "service/testing/fooa.elb.com"}, SetIdentifier: "a"},
{DNSName: "foo.example.org", RecordType: endpoint.RecordTypeCNAME, Targets: endpoint.Targets{"b.elb.com"}, Labels: map[string]string{endpoint.ResourceLabelKey: "service/testing/foob.elb.com"}, SetIdentifier: "b"},
},
false,
},
@ -1304,7 +1335,7 @@ func TestClusterIpServices(t *testing.T) {
},
clusterIP: "1.2.3.4",
expected: []*endpoint.Endpoint{
{DNSName: "foo.example.org", Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "foo.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
},
},
{
@ -1327,7 +1358,7 @@ func TestClusterIpServices(t *testing.T) {
fqdnTemplate: "{{.Name}}.bar.example.com",
clusterIP: "4.5.6.7",
expected: []*endpoint.Endpoint{
{DNSName: "foo.bar.example.com", Targets: endpoint.Targets{"4.5.6.7"}},
{DNSName: "foo.bar.example.com", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"4.5.6.7"}},
},
},
{
@ -1347,7 +1378,7 @@ func TestClusterIpServices(t *testing.T) {
labels: map[string]string{"app": "web-internal"},
clusterIP: "4.5.6.7",
expected: []*endpoint.Endpoint{
{DNSName: "foo.bar.example.com", Targets: endpoint.Targets{"4.5.6.7"}},
{DNSName: "foo.bar.example.com", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"4.5.6.7"}},
},
labelSelector: "app=web-internal",
},
@ -1748,8 +1779,8 @@ func TestServiceSourceNodePortServices(t *testing.T) {
kopsDNSControllerInternalHostnameAnnotationKey: "internal.foo.example.org., internal.bar.example.org",
},
expected: []*endpoint.Endpoint{
{DNSName: "internal.foo.example.org", Targets: endpoint.Targets{"10.0.1.1"}},
{DNSName: "internal.bar.example.org", Targets: endpoint.Targets{"10.0.1.1"}},
{DNSName: "internal.foo.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"10.0.1.1"}},
{DNSName: "internal.bar.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"10.0.1.1"}},
},
nodes: []*v1.Node{{
ObjectMeta: metav1.ObjectMeta{
@ -1790,8 +1821,8 @@ func TestServiceSourceNodePortServices(t *testing.T) {
kopsDNSControllerInternalHostnameAnnotationKey: "internal.foo.example.org., internal.bar.example.org",
},
expected: []*endpoint.Endpoint{
{DNSName: "internal.foo.example.org", Targets: endpoint.Targets{"10.0.1.1", "10.0.1.2"}},
{DNSName: "internal.bar.example.org", Targets: endpoint.Targets{"10.0.1.1", "10.0.1.2"}},
{DNSName: "internal.foo.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"10.0.1.1", "10.0.1.2"}},
{DNSName: "internal.bar.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"10.0.1.1", "10.0.1.2"}},
},
nodes: []*v1.Node{{
ObjectMeta: metav1.ObjectMeta{
@ -1832,8 +1863,8 @@ func TestServiceSourceNodePortServices(t *testing.T) {
kopsDNSControllerHostnameAnnotationKey: "foo.example.org., bar.example.org",
},
expected: []*endpoint.Endpoint{
{DNSName: "foo.example.org", Targets: endpoint.Targets{"54.10.11.1", "54.10.11.2"}},
{DNSName: "bar.example.org", Targets: endpoint.Targets{"54.10.11.1", "54.10.11.2"}},
{DNSName: "foo.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"54.10.11.1", "54.10.11.2"}},
{DNSName: "bar.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"54.10.11.1", "54.10.11.2"}},
},
nodes: []*v1.Node{{
ObjectMeta: metav1.ObjectMeta{
@ -2051,9 +2082,9 @@ func TestHeadlessServices(t *testing.T) {
false,
[]v1.Node{},
[]*endpoint.Endpoint{
{DNSName: "foo-0.service.example.org", Targets: endpoint.Targets{"1.1.1.1"}},
{DNSName: "foo-1.service.example.org", Targets: endpoint.Targets{"1.1.1.2"}},
{DNSName: "service.example.org", Targets: endpoint.Targets{"1.1.1.1", "1.1.1.2"}},
{DNSName: "foo-0.service.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.1.1.1"}},
{DNSName: "foo-1.service.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.1.1.2"}},
{DNSName: "service.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.1.1.1", "1.1.1.2"}},
},
false,
},
@ -2114,9 +2145,9 @@ func TestHeadlessServices(t *testing.T) {
false,
[]v1.Node{},
[]*endpoint.Endpoint{
{DNSName: "foo-0.service.example.org", Targets: endpoint.Targets{"1.1.1.1"}, RecordTTL: endpoint.TTL(1)},
{DNSName: "foo-1.service.example.org", Targets: endpoint.Targets{"1.1.1.2"}, RecordTTL: endpoint.TTL(1)},
{DNSName: "service.example.org", Targets: endpoint.Targets{"1.1.1.1", "1.1.1.2"}, RecordTTL: endpoint.TTL(1)},
{DNSName: "foo-0.service.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.1.1.1"}, RecordTTL: endpoint.TTL(1)},
{DNSName: "foo-1.service.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.1.1.2"}, RecordTTL: endpoint.TTL(1)},
{DNSName: "service.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.1.1.1", "1.1.1.2"}, RecordTTL: endpoint.TTL(1)},
},
false,
},
@ -2147,8 +2178,8 @@ func TestHeadlessServices(t *testing.T) {
false,
[]v1.Node{},
[]*endpoint.Endpoint{
{DNSName: "foo-0.service.example.org", Targets: endpoint.Targets{"1.1.1.1"}},
{DNSName: "service.example.org", Targets: endpoint.Targets{"1.1.1.1"}},
{DNSName: "foo-0.service.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.1.1.1"}},
{DNSName: "service.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.1.1.1"}},
},
false,
},
@ -2179,9 +2210,9 @@ func TestHeadlessServices(t *testing.T) {
true,
[]v1.Node{},
[]*endpoint.Endpoint{
{DNSName: "foo-0.service.example.org", Targets: endpoint.Targets{"1.1.1.1"}},
{DNSName: "foo-1.service.example.org", Targets: endpoint.Targets{"1.1.1.2"}},
{DNSName: "service.example.org", Targets: endpoint.Targets{"1.1.1.1", "1.1.1.2"}},
{DNSName: "foo-0.service.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.1.1.1"}},
{DNSName: "foo-1.service.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.1.1.2"}},
{DNSName: "service.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.1.1.1", "1.1.1.2"}},
},
false,
},
@ -2212,7 +2243,7 @@ func TestHeadlessServices(t *testing.T) {
false,
[]v1.Node{},
[]*endpoint.Endpoint{
{DNSName: "service.example.org", Targets: endpoint.Targets{"1.1.1.1", "1.1.1.2"}},
{DNSName: "service.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.1.1.1", "1.1.1.2"}},
},
false,
},
@ -2243,7 +2274,7 @@ func TestHeadlessServices(t *testing.T) {
false,
[]v1.Node{},
[]*endpoint.Endpoint{
{DNSName: "service.example.org", Targets: endpoint.Targets{"1.1.1.1", "1.1.1.2"}},
{DNSName: "service.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.1.1.1", "1.1.1.2"}},
},
false,
},
@ -2276,7 +2307,7 @@ func TestHeadlessServices(t *testing.T) {
false,
[]v1.Node{},
[]*endpoint.Endpoint{
{DNSName: "service.example.org", Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "service.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
},
false,
},
@ -2319,7 +2350,7 @@ func TestHeadlessServices(t *testing.T) {
},
},
[]*endpoint.Endpoint{
{DNSName: "service.example.org", Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "service.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
},
false,
},
@ -2351,7 +2382,7 @@ func TestHeadlessServices(t *testing.T) {
false,
[]v1.Node{},
[]*endpoint.Endpoint{
{DNSName: "service.example.org", Targets: endpoint.Targets{"1.2.3.4"}},
{DNSName: "service.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.2.3.4"}},
},
false,
},
@ -2523,9 +2554,9 @@ func TestHeadlessServicesHostIP(t *testing.T) {
},
false,
[]*endpoint.Endpoint{
{DNSName: "foo-0.service.example.org", Targets: endpoint.Targets{"1.1.1.1"}},
{DNSName: "foo-1.service.example.org", Targets: endpoint.Targets{"1.1.1.2"}},
{DNSName: "service.example.org", Targets: endpoint.Targets{"1.1.1.1", "1.1.1.2"}},
{DNSName: "foo-0.service.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.1.1.1"}},
{DNSName: "foo-1.service.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.1.1.2"}},
{DNSName: "service.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.1.1.1", "1.1.1.2"}},
},
false,
},
@ -2588,9 +2619,9 @@ func TestHeadlessServicesHostIP(t *testing.T) {
},
false,
[]*endpoint.Endpoint{
{DNSName: "foo-0.service.example.org", Targets: endpoint.Targets{"1.1.1.1"}, RecordTTL: endpoint.TTL(1)},
{DNSName: "foo-1.service.example.org", Targets: endpoint.Targets{"1.1.1.2"}, RecordTTL: endpoint.TTL(1)},
{DNSName: "service.example.org", Targets: endpoint.Targets{"1.1.1.1", "1.1.1.2"}, RecordTTL: endpoint.TTL(1)},
{DNSName: "foo-0.service.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.1.1.1"}, RecordTTL: endpoint.TTL(1)},
{DNSName: "foo-1.service.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.1.1.2"}, RecordTTL: endpoint.TTL(1)},
{DNSName: "service.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.1.1.1", "1.1.1.2"}, RecordTTL: endpoint.TTL(1)},
},
false,
},
@ -2622,8 +2653,8 @@ func TestHeadlessServicesHostIP(t *testing.T) {
},
false,
[]*endpoint.Endpoint{
{DNSName: "foo-0.service.example.org", Targets: endpoint.Targets{"1.1.1.1"}},
{DNSName: "service.example.org", Targets: endpoint.Targets{"1.1.1.1"}},
{DNSName: "foo-0.service.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.1.1.1"}},
{DNSName: "service.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.1.1.1"}},
},
false,
},
@ -2655,9 +2686,9 @@ func TestHeadlessServicesHostIP(t *testing.T) {
},
true,
[]*endpoint.Endpoint{
{DNSName: "foo-0.service.example.org", Targets: endpoint.Targets{"1.1.1.1"}},
{DNSName: "foo-1.service.example.org", Targets: endpoint.Targets{"1.1.1.2"}},
{DNSName: "service.example.org", Targets: endpoint.Targets{"1.1.1.1", "1.1.1.2"}},
{DNSName: "foo-0.service.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.1.1.1"}},
{DNSName: "foo-1.service.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.1.1.2"}},
{DNSName: "service.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.1.1.1", "1.1.1.2"}},
},
false,
},
@ -2689,7 +2720,7 @@ func TestHeadlessServicesHostIP(t *testing.T) {
},
false,
[]*endpoint.Endpoint{
{DNSName: "service.example.org", Targets: endpoint.Targets{"1.1.1.1", "1.1.1.2"}},
{DNSName: "service.example.org", RecordType: endpoint.RecordTypeA, Targets: endpoint.Targets{"1.1.1.1", "1.1.1.2"}},
},
false,
},

View File

@ -79,7 +79,7 @@ func validateEndpoint(t *testing.T, endpoint, expected *endpoint.Endpoint) {
}
// if non-empty record type is expected, check that it matches.
if expected.RecordType != "" && endpoint.RecordType != expected.RecordType {
if endpoint.RecordType != expected.RecordType {
t.Errorf("RecordType expected %q, got %q", expected.RecordType, endpoint.RecordType)
}

View File

@ -90,8 +90,9 @@ func TestEndpointsFromRouteGroups(t *testing.T) {
}),
want: []*endpoint.Endpoint{
{
DNSName: "rg1.k8s.example",
Targets: endpoint.Targets([]string{"lb.example.org"}),
DNSName: "rg1.k8s.example",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets([]string{"lb.example.org"}),
},
},
},
@ -113,12 +114,14 @@ func TestEndpointsFromRouteGroups(t *testing.T) {
),
want: []*endpoint.Endpoint{
{
DNSName: "rg1.k8s.example",
Targets: endpoint.Targets([]string{"lb.example.org"}),
DNSName: "rg1.k8s.example",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets([]string{"lb.example.org"}),
},
{
DNSName: "my.example",
Targets: endpoint.Targets([]string{"lb.example.org"}),
DNSName: "my.example",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets([]string{"lb.example.org"}),
},
},
},
@ -140,8 +143,9 @@ func TestEndpointsFromRouteGroups(t *testing.T) {
),
want: []*endpoint.Endpoint{
{
DNSName: "rg1.k8s.example",
Targets: endpoint.Targets([]string{"lb.example.org"}),
DNSName: "rg1.k8s.example",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets([]string{"lb.example.org"}),
},
},
},
@ -163,9 +167,10 @@ func TestEndpointsFromRouteGroups(t *testing.T) {
),
want: []*endpoint.Endpoint{
{
DNSName: "rg1.k8s.example",
Targets: endpoint.Targets([]string{"lb.example.org"}),
RecordTTL: endpoint.TTL(2189),
DNSName: "rg1.k8s.example",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets([]string{"lb.example.org"}),
RecordTTL: endpoint.TTL(2189),
},
},
},
@ -185,8 +190,9 @@ func TestEndpointsFromRouteGroups(t *testing.T) {
),
want: []*endpoint.Endpoint{
{
DNSName: "rg1.k8s.example",
Targets: endpoint.Targets([]string{"1.5.1.4"}),
DNSName: "rg1.k8s.example",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets([]string{"1.5.1.4"}),
},
},
},
@ -207,12 +213,14 @@ func TestEndpointsFromRouteGroups(t *testing.T) {
),
want: []*endpoint.Endpoint{
{
DNSName: "rg1.k8s.example",
Targets: endpoint.Targets([]string{"1.5.1.4"}),
DNSName: "rg1.k8s.example",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets([]string{"1.5.1.4"}),
},
{
DNSName: "rg1.k8s.example",
Targets: endpoint.Targets([]string{"lb.example.org"}),
DNSName: "rg1.k8s.example",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets([]string{"lb.example.org"}),
},
},
},
@ -278,8 +286,9 @@ func TestRouteGroupsEndpoints(t *testing.T) {
},
want: []*endpoint.Endpoint{
{
DNSName: "rg1.k8s.example",
Targets: endpoint.Targets([]string{"lb.example.org"}),
DNSName: "rg1.k8s.example",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets([]string{"lb.example.org"}),
},
},
},
@ -308,12 +317,14 @@ func TestRouteGroupsEndpoints(t *testing.T) {
},
want: []*endpoint.Endpoint{
{
DNSName: "rg1.k8s.example",
Targets: endpoint.Targets([]string{"lb.example.org"}),
DNSName: "rg1.k8s.example",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets([]string{"lb.example.org"}),
},
{
DNSName: "rg1.namespace1.example",
Targets: endpoint.Targets([]string{"lb.example.org"}),
DNSName: "rg1.namespace1.example",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets([]string{"lb.example.org"}),
},
},
},
@ -341,8 +352,9 @@ func TestRouteGroupsEndpoints(t *testing.T) {
},
want: []*endpoint.Endpoint{
{
DNSName: "rg1.namespace1.example",
Targets: endpoint.Targets([]string{"lb.example.org"}),
DNSName: "rg1.namespace1.example",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets([]string{"lb.example.org"}),
},
},
},
@ -370,8 +382,9 @@ func TestRouteGroupsEndpoints(t *testing.T) {
},
want: []*endpoint.Endpoint{
{
DNSName: "rg1.k8s.example",
Targets: endpoint.Targets([]string{"lb.example.org"}),
DNSName: "rg1.k8s.example",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets([]string{"lb.example.org"}),
},
},
},
@ -400,9 +413,10 @@ func TestRouteGroupsEndpoints(t *testing.T) {
},
want: []*endpoint.Endpoint{
{
DNSName: "rg1.k8s.example",
Targets: endpoint.Targets([]string{"lb.example.org"}),
RecordTTL: endpoint.TTL(2189),
DNSName: "rg1.k8s.example",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets([]string{"lb.example.org"}),
RecordTTL: endpoint.TTL(2189),
},
},
},
@ -430,12 +444,14 @@ func TestRouteGroupsEndpoints(t *testing.T) {
},
want: []*endpoint.Endpoint{
{
DNSName: "rg1.k8s.example",
Targets: endpoint.Targets([]string{"1.5.1.4"}),
DNSName: "rg1.k8s.example",
RecordType: endpoint.RecordTypeA,
Targets: endpoint.Targets([]string{"1.5.1.4"}),
},
{
DNSName: "rg1.k8s.example",
Targets: endpoint.Targets([]string{"lb.example.org"}),
DNSName: "rg1.k8s.example",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets([]string{"lb.example.org"}),
},
},
},
@ -495,20 +511,24 @@ func TestRouteGroupsEndpoints(t *testing.T) {
},
want: []*endpoint.Endpoint{
{
DNSName: "rg1.k8s.example",
Targets: endpoint.Targets([]string{"lb.example.org"}),
DNSName: "rg1.k8s.example",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets([]string{"lb.example.org"}),
},
{
DNSName: "rg2.k8s.example",
Targets: endpoint.Targets([]string{"lb.example.org"}),
DNSName: "rg2.k8s.example",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets([]string{"lb.example.org"}),
},
{
DNSName: "rg3.k8s.example",
Targets: endpoint.Targets([]string{"lb.example.org"}),
DNSName: "rg3.k8s.example",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets([]string{"lb.example.org"}),
},
{
DNSName: "rg.k8s.example",
Targets: endpoint.Targets([]string{"lb2.example.org"}),
DNSName: "rg.k8s.example",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets([]string{"lb2.example.org"}),
},
},
},
@ -575,8 +595,9 @@ func TestRouteGroupsEndpoints(t *testing.T) {
},
want: []*endpoint.Endpoint{
{
DNSName: "rg1.k8s.example",
Targets: endpoint.Targets([]string{"lb.example.org"}),
DNSName: "rg1.k8s.example",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets([]string{"lb.example.org"}),
},
},
},
@ -643,12 +664,14 @@ func TestRouteGroupsEndpoints(t *testing.T) {
},
want: []*endpoint.Endpoint{
{
DNSName: "rg1.k8s.example",
Targets: endpoint.Targets([]string{"lb.example.org"}),
DNSName: "rg1.k8s.example",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets([]string{"lb.example.org"}),
},
{
DNSName: "rg2.k8s.example",
Targets: endpoint.Targets([]string{"lb.example.org"}),
DNSName: "rg2.k8s.example",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets([]string{"lb.example.org"}),
},
},
},
@ -701,12 +724,14 @@ func TestRouteGroupsEndpoints(t *testing.T) {
},
want: []*endpoint.Endpoint{
{
DNSName: "rg1.k8s.example",
Targets: endpoint.Targets([]string{"lb.example.org"}),
DNSName: "rg1.k8s.example",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets([]string{"lb.example.org"}),
},
{
DNSName: "rg3.k8s.example",
Targets: endpoint.Targets([]string{"lb.example.org"}),
DNSName: "rg3.k8s.example",
RecordType: endpoint.RecordTypeCNAME,
Targets: endpoint.Targets([]string{"lb.example.org"}),
},
},
},

View File

@ -239,8 +239,10 @@ func getTargetsFromTargetAnnotation(annotations map[string]string) endpoint.Targ
// 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 suitableType(target string) string {
if net.ParseIP(target) != nil {
if net.ParseIP(target) != nil && net.ParseIP(target).To4() != nil {
return endpoint.RecordTypeA
} else if net.ParseIP(target) != nil && net.ParseIP(target).To16() != nil {
return endpoint.RecordTypeAAAA
}
return endpoint.RecordTypeCNAME
}
@ -250,12 +252,21 @@ func endpointsForHostname(hostname string, targets endpoint.Targets, ttl endpoin
var endpoints []*endpoint.Endpoint
var aTargets endpoint.Targets
var aaaaTargets endpoint.Targets
var cnameTargets endpoint.Targets
for _, t := range targets {
switch suitableType(t) {
case endpoint.RecordTypeA:
if isIPv6String(t) {
continue
}
aTargets = append(aTargets, t)
case endpoint.RecordTypeAAAA:
if !isIPv6String(t) {
continue
}
aaaaTargets = append(aaaaTargets, t)
default:
cnameTargets = append(cnameTargets, t)
}
@ -274,6 +285,19 @@ func endpointsForHostname(hostname string, targets endpoint.Targets, ttl endpoin
endpoints = append(endpoints, epA)
}
if len(aaaaTargets) > 0 {
epAAAA := &endpoint.Endpoint{
DNSName: strings.TrimSuffix(hostname, "."),
Targets: aaaaTargets,
RecordTTL: ttl,
RecordType: endpoint.RecordTypeAAAA,
Labels: endpoint.NewLabels(),
ProviderSpecific: providerSpecific,
SetIdentifier: setIdentifier,
}
endpoints = append(endpoints, epAAAA)
}
if len(cnameTargets) > 0 {
epCNAME := &endpoint.Endpoint{
DNSName: strings.TrimSuffix(hostname, "."),
@ -286,7 +310,6 @@ func endpointsForHostname(hostname string, targets endpoint.Targets, ttl endpoin
}
endpoints = append(endpoints, epCNAME)
}
return endpoints
}
@ -348,3 +371,9 @@ func waitForDynamicCacheSync(ctx context.Context, factory dynamicInformerFactory
}
return nil
}
// isIPv6String returns if ip is IPv6.
func isIPv6String(ip string) bool {
netIP := net.ParseIP(ip)
return netIP != nil && netIP.To4() == nil
}

View File

@ -94,6 +94,7 @@ func TestSuitableType(t *testing.T) {
target, recordType, expected string
}{
{"8.8.8.8", "", "A"},
{"2001:db8::1", "", "AAAA"},
{"foo.example.org", "", "CNAME"},
{"bar.eu-central-1.elb.amazonaws.com", "", "CNAME"},
} {