Skip to content

Commit

Permalink
Merge 14d64e0 into 5fc6adf
Browse files Browse the repository at this point in the history
  • Loading branch information
bl1nk committed Feb 24, 2020
2 parents 5fc6adf + 14d64e0 commit d4bbd59
Show file tree
Hide file tree
Showing 51 changed files with 286 additions and 200 deletions.
10 changes: 7 additions & 3 deletions controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/prometheus/client_golang/prometheus"
log "github.com/sirupsen/logrus"

"sigs.k8s.io/external-dns/endpoint"
"sigs.k8s.io/external-dns/plan"
"sigs.k8s.io/external-dns/provider"
"sigs.k8s.io/external-dns/registry"
Expand Down Expand Up @@ -100,6 +101,8 @@ type Controller struct {
Policy plan.Policy
// The interval between individual synchronizations
Interval time.Duration
// The DomainFilter defines which DNS records to keep or exclude
DomainFilter endpoint.DomainFilter
}

// RunOnce runs a single iteration of a reconciliation loop.
Expand All @@ -123,9 +126,10 @@ func (c *Controller) RunOnce(ctx context.Context) error {
sourceEndpointsTotal.Set(float64(len(endpoints)))

plan := &plan.Plan{
Policies: []plan.Policy{c.Policy},
Current: records,
Desired: endpoints,
Policies: []plan.Policy{c.Policy},
Current: records,
Desired: endpoints,
DomainFilter: c.DomainFilter,
}

plan = plan.Calculate()
Expand Down
14 changes: 8 additions & 6 deletions provider/domain_filter.go → endpoint/domain_filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,17 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

package provider
package endpoint

import (
"strings"
)

// DomainFilter holds a lists of valid domain names
type DomainFilter struct {
filters []string
// Filters define what domains to match
Filters []string
// exclude define what domains not to match
exclude []string
}

Expand All @@ -47,7 +49,7 @@ func NewDomainFilter(domainFilters []string) DomainFilter {

// Match checks whether a domain can be found in the DomainFilter.
func (df DomainFilter) Match(domain string) bool {
return matchFilter(df.filters, domain, true) && !matchFilter(df.exclude, domain, false)
return matchFilter(df.Filters, domain, true) && !matchFilter(df.exclude, domain, false)
}

// matchFilter determines if any `filters` match `domain`.
Expand Down Expand Up @@ -78,8 +80,8 @@ func matchFilter(filters []string, domain string, emptyval bool) bool {

// IsConfigured returns true if DomainFilter is configured, false otherwise
func (df DomainFilter) IsConfigured() bool {
if len(df.filters) == 1 {
return df.filters[0] != ""
if len(df.Filters) == 1 {
return df.Filters[0] != ""
}
return len(df.filters) > 0
return len(df.Filters) > 0
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

package provider
package endpoint

import (
"testing"
Expand Down
12 changes: 7 additions & 5 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
_ "k8s.io/client-go/plugin/pkg/client/auth"

"sigs.k8s.io/external-dns/controller"
"sigs.k8s.io/external-dns/endpoint"
"sigs.k8s.io/external-dns/pkg/apis/externaldns"
"sigs.k8s.io/external-dns/pkg/apis/externaldns/validation"
"sigs.k8s.io/external-dns/plan"
Expand Down Expand Up @@ -111,7 +112,7 @@ func main() {
// Combine multiple sources into a single, deduplicated source.
endpointsSource := source.NewDedupSource(source.NewMultiSource(sources))

domainFilter := provider.NewDomainFilterWithExclusions(cfg.DomainFilter, cfg.ExcludeDomains)
domainFilter := endpoint.NewDomainFilterWithExclusions(cfg.DomainFilter, cfg.ExcludeDomains)
zoneIDFilter := provider.NewZoneIDFilter(cfg.ZoneIDFilter)
zoneTypeFilter := provider.NewZoneTypeFilter(cfg.AWSZoneType)
zoneTagFilter := provider.NewZoneTagFilter(cfg.AWSZoneTagFilter)
Expand Down Expand Up @@ -282,10 +283,11 @@ func main() {
}

ctrl := controller.Controller{
Source: endpointsSource,
Registry: r,
Policy: policy,
Interval: cfg.Interval,
Source: endpointsSource,
Registry: r,
Policy: policy,
Interval: cfg.Interval,
DomainFilter: domainFilter,
}

if cfg.UpdateEvents {
Expand Down
13 changes: 10 additions & 3 deletions plan/plan.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ type Plan struct {
// List of changes necessary to move towards desired state
// Populated after calling Calculate()
Changes *Changes
// DomainFilter matches DNS names
DomainFilter endpoint.DomainFilter
}

// Changes holds lists of actions to be executed by dns providers
Expand Down Expand Up @@ -111,10 +113,10 @@ func (t planTable) addCandidate(e *endpoint.Endpoint) {
func (p *Plan) Calculate() *Plan {
t := newPlanTable()

for _, current := range filterRecordsForPlan(p.Current) {
for _, current := range filterRecordsForPlan(p.Current, p.DomainFilter) {
t.addCurrent(current)
}
for _, desired := range filterRecordsForPlan(p.Desired) {
for _, desired := range filterRecordsForPlan(p.Desired, p.DomainFilter) {
t.addCandidate(desired)
}

Expand Down Expand Up @@ -227,10 +229,15 @@ func shouldUpdateProviderSpecific(desired, current *endpoint.Endpoint) bool {
// Per RFC 1034, CNAME records conflict with all other records - it is the
// only record with this property. The behavior of the planner may need to be
// made more sophisticated to codify this.
func filterRecordsForPlan(records []*endpoint.Endpoint) []*endpoint.Endpoint {
func filterRecordsForPlan(records []*endpoint.Endpoint, domainFilter endpoint.DomainFilter) []*endpoint.Endpoint {
filtered := []*endpoint.Endpoint{}

for _, record := range records {
// Ignore records that do not match the domain filter provided
if !domainFilter.Match(record.DNSName) {
continue
}

// Explicitly specify which records we want to use for planning.
// TODO: Add AAAA records as well when they are supported.
switch record.RecordType {
Expand Down
70 changes: 70 additions & 0 deletions plan/plan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ type PlanTestSuite struct {
multiple1 *endpoint.Endpoint
multiple2 *endpoint.Endpoint
multiple3 *endpoint.Endpoint
domainFilterFiltered1 *endpoint.Endpoint
domainFilterFiltered2 *endpoint.Endpoint
domainFilterFiltered3 *endpoint.Endpoint
domainFilterExcluded *endpoint.Endpoint
}

func (suite *PlanTestSuite) SetupTest() {
Expand Down Expand Up @@ -160,6 +164,26 @@ func (suite *PlanTestSuite) SetupTest() {
RecordType: "A",
SetIdentifier: "test-set-2",
}
suite.domainFilterFiltered1 = &endpoint.Endpoint{
DNSName: "foo.domain.tld",
Targets: endpoint.Targets{"1.2.3.4"},
RecordType: "A",
}
suite.domainFilterFiltered2 = &endpoint.Endpoint{
DNSName: "bar.domain.tld",
Targets: endpoint.Targets{"1.2.3.5"},
RecordType: "A",
}
suite.domainFilterFiltered3 = &endpoint.Endpoint{
DNSName: "baz.domain.tld",
Targets: endpoint.Targets{"1.2.3.6"},
RecordType: "A",
}
suite.domainFilterExcluded = &endpoint.Endpoint{
DNSName: "foo.ex.domain.tld",
Targets: endpoint.Targets{"1.1.1.1"},
RecordType: "A",
}
}

func (suite *PlanTestSuite) TestSyncFirstRound() {
Expand Down Expand Up @@ -492,6 +516,52 @@ func (suite *PlanTestSuite) TestSetIdentifierUpdateCreatesAndDeletes() {
validateEntries(suite.T(), changes.Delete, expectedDelete)
}

func (suite *PlanTestSuite) TestDomainFiltersInitial() {

current := []*endpoint.Endpoint{suite.domainFilterExcluded}
desired := []*endpoint.Endpoint{suite.domainFilterExcluded, suite.domainFilterFiltered1, suite.domainFilterFiltered2, suite.domainFilterFiltered3}
expectedCreate := []*endpoint.Endpoint{suite.domainFilterFiltered1, suite.domainFilterFiltered2, suite.domainFilterFiltered3}
expectedUpdateOld := []*endpoint.Endpoint{}
expectedUpdateNew := []*endpoint.Endpoint{}
expectedDelete := []*endpoint.Endpoint{}

p := &Plan{
Policies: []Policy{&SyncPolicy{}},
Current: current,
Desired: desired,
DomainFilter: endpoint.NewDomainFilterWithExclusions([]string{"domain.tld"}, []string{"ex.domain.tld"}),
}

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) TestDomainFiltersUpdate() {

current := []*endpoint.Endpoint{suite.domainFilterExcluded, suite.domainFilterFiltered1, suite.domainFilterFiltered2}
desired := []*endpoint.Endpoint{suite.domainFilterExcluded, suite.domainFilterFiltered1, suite.domainFilterFiltered2, suite.domainFilterFiltered3}
expectedCreate := []*endpoint.Endpoint{suite.domainFilterFiltered3}
expectedUpdateOld := []*endpoint.Endpoint{}
expectedUpdateNew := []*endpoint.Endpoint{}
expectedDelete := []*endpoint.Endpoint{}

p := &Plan{
Policies: []Policy{&SyncPolicy{}},
Current: current,
Desired: desired,
DomainFilter: endpoint.NewDomainFilterWithExclusions([]string{"domain.tld"}, []string{"ex.domain.tld"}),
}

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 TestPlan(t *testing.T) {
suite.Run(t, new(PlanTestSuite))
}
Expand Down
4 changes: 2 additions & 2 deletions provider/akamai.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func (*akamaiOpenClient) Do(config edgegrid.Config, req *http.Request) (*http.Re

// AkamaiConfig clarifies the method signature
type AkamaiConfig struct {
DomainFilter DomainFilter
DomainFilter endpoint.DomainFilter
ZoneIDFilter ZoneIDFilter
ServiceConsumerDomain string
ClientToken string
Expand All @@ -60,7 +60,7 @@ type AkamaiConfig struct {

// AkamaiProvider implements the DNS provider for Akamai.
type AkamaiProvider struct {
domainFilter DomainFilter
domainFilter endpoint.DomainFilter
zoneIDFilter ZoneIDFilter
config edgegrid.Config
dryRun bool
Expand Down
10 changes: 5 additions & 5 deletions provider/akamai_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ func TestFetchZonesZoneIDFilter(t *testing.T) {

func TestFetchZonesEmpty(t *testing.T) {
config := AkamaiConfig{
DomainFilter: NewDomainFilter([]string{"Nonexistent"}),
DomainFilter: endpoint.NewDomainFilter([]string{"Nonexistent"}),
ZoneIDFilter: NewZoneIDFilter([]string{"Nonexistent"}),
}

Expand Down Expand Up @@ -184,7 +184,7 @@ func TestAkamaiRecordsEmpty(t *testing.T) {

func TestAkamaiRecordsFilters(t *testing.T) {
config := AkamaiConfig{
DomainFilter: NewDomainFilter([]string{"www.exclude.me"}),
DomainFilter: endpoint.NewDomainFilter([]string{"www.exclude.me"}),
ZoneIDFilter: NewZoneIDFilter([]string{"Exclude-Me"}),
}

Expand Down Expand Up @@ -221,7 +221,7 @@ func TestCreateRecords(t *testing.T) {

func TestCreateRecordsDomainFilter(t *testing.T) {
config := AkamaiConfig{
DomainFilter: NewDomainFilter([]string{"example.com"}),
DomainFilter: endpoint.NewDomainFilter([]string{"example.com"}),
}

client := &mockAkamaiClient{}
Expand Down Expand Up @@ -260,7 +260,7 @@ func TestDeleteRecords(t *testing.T) {

func TestDeleteRecordsDomainFilter(t *testing.T) {
config := AkamaiConfig{
DomainFilter: NewDomainFilter([]string{"example.com"}),
DomainFilter: endpoint.NewDomainFilter([]string{"example.com"}),
}

client := &mockAkamaiClient{}
Expand Down Expand Up @@ -299,7 +299,7 @@ func TestUpdateRecords(t *testing.T) {

func TestUpdateRecordsDomainFilter(t *testing.T) {
config := AkamaiConfig{
DomainFilter: NewDomainFilter([]string{"example.com"}),
DomainFilter: endpoint.NewDomainFilter([]string{"example.com"}),
}

client := &mockAkamaiClient{}
Expand Down
10 changes: 5 additions & 5 deletions provider/alibaba_cloud.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ type AlibabaCloudPrivateZoneAPI interface {

// AlibabaCloudProvider implements the DNS provider for Alibaba Cloud.
type AlibabaCloudProvider struct {
domainFilter DomainFilter
domainFilter endpoint.DomainFilter
zoneIDFilter ZoneIDFilter // Private Zone only
MaxChangeCount int
EvaluateTargetHealth bool
Expand All @@ -93,7 +93,7 @@ type alibabaCloudConfig struct {
// NewAlibabaCloudProvider creates a new Alibaba Cloud provider.
//
// Returns the provider or an error if a provider could not be created.
func NewAlibabaCloudProvider(configFile string, domainFilter DomainFilter, zoneIDFileter ZoneIDFilter, zoneType string, dryRun bool) (*AlibabaCloudProvider, error) {
func NewAlibabaCloudProvider(configFile string, domainFilter endpoint.DomainFilter, zoneIDFileter ZoneIDFilter, zoneType string, dryRun bool) (*AlibabaCloudProvider, error) {
cfg := alibabaCloudConfig{}
if configFile != "" {
contents, err := ioutil.ReadFile(configFile)
Expand Down Expand Up @@ -382,7 +382,7 @@ func (p *AlibabaCloudProvider) records() ([]alidns.Record, error) {
log.Infof("Retrieving Alibaba Cloud DNS Domain Records")
var results []alidns.Record

if len(p.domainFilter.filters) == 1 && p.domainFilter.filters[0] == "" {
if len(p.domainFilter.Filters) == 1 && p.domainFilter.Filters[0] == "" {
domainNames, tmpErr := p.getDomainList()
if tmpErr != nil {
log.Errorf("AlibabaCloudProvider getDomainList error %v", tmpErr)
Expand All @@ -397,7 +397,7 @@ func (p *AlibabaCloudProvider) records() ([]alidns.Record, error) {
results = append(results, tmpResults...)
}
} else {
for _, domainName := range p.domainFilter.filters {
for _, domainName := range p.domainFilter.Filters {
tmpResults, err := p.getDomainRecords(domainName)
if err != nil {
log.Errorf("getDomainRecords %s error %v", domainName, err)
Expand Down Expand Up @@ -672,7 +672,7 @@ func (p *AlibabaCloudProvider) splitDNSName(endpoint *endpoint.Endpoint) (rr str

found := false

for _, filter := range p.domainFilter.filters {
for _, filter := range p.domainFilter.Filters {
if strings.HasSuffix(name, "."+filter) {
rr = name[0 : len(name)-len(filter)-1]
domain = filter
Expand Down
3 changes: 2 additions & 1 deletion provider/alibaba_cloud_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (

"github.com/aliyun/alibaba-cloud-sdk-go/services/alidns"
"github.com/aliyun/alibaba-cloud-sdk-go/services/pvtz"

"sigs.k8s.io/external-dns/endpoint"

"sigs.k8s.io/external-dns/plan"
Expand Down Expand Up @@ -232,7 +233,7 @@ func newTestAlibabaCloudProvider(private bool) *AlibabaCloudProvider {
// cfg.AccessKeyID,
// cfg.AccessKeySecret,
//)
domainFilterTest := NewDomainFilter([]string{"container-service.top.", "example.org"})
domainFilterTest := endpoint.NewDomainFilter([]string{"container-service.top.", "example.org"})

return &AlibabaCloudProvider{
domainFilter: domainFilterTest,
Expand Down
4 changes: 2 additions & 2 deletions provider/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ type AWSProvider struct {
batchChangeInterval time.Duration
evaluateTargetHealth bool
// only consider hosted zones managing domains ending in this suffix
domainFilter DomainFilter
domainFilter endpoint.DomainFilter
// filter hosted zones by id
zoneIDFilter ZoneIDFilter
// filter hosted zones by type (e.g. private or public)
Expand All @@ -129,7 +129,7 @@ type AWSProvider struct {

// AWSConfig contains configuration to create a new AWS provider.
type AWSConfig struct {
DomainFilter DomainFilter
DomainFilter endpoint.DomainFilter
ZoneIDFilter ZoneIDFilter
ZoneTypeFilter ZoneTypeFilter
ZoneTagFilter ZoneTagFilter
Expand Down
Loading

0 comments on commit d4bbd59

Please sign in to comment.