Skip to content

Commit

Permalink
separate record type for alias targets to simplify implementation and to
Browse files Browse the repository at this point in the history
pay attention to owners

```improvement operator
aws-route53: improved handling of alias targets (pay attention to owners)
```

Co-authored-by: Uwe Krueger <[email protected]>
  • Loading branch information
MartinWeindel and mandelsoft committed Jun 12, 2019
1 parent cd289ed commit 8c439b6
Show file tree
Hide file tree
Showing 12 changed files with 84 additions and 100 deletions.
8 changes: 3 additions & 5 deletions pkg/controller/provider/alicloud/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
)

type Handler struct {
provider.DefaultDNSHandler
config provider.DNSHandlerConfig
access Access
}
Expand All @@ -36,7 +37,8 @@ func NewHandler(logger logger.LogContext, config *provider.DNSHandlerConfig, met
var err error

this := &Handler{
config: *config,
DefaultDNSHandler: provider.NewDefaultDNSHandler(TYPE_CODE),
config: *config,
}

accessKeyID := this.config.Properties["ACCESS_KEY_ID"]
Expand All @@ -63,10 +65,6 @@ func NewHandler(logger logger.LogContext, config *provider.DNSHandlerConfig, met
return this, nil
}

func (h *Handler) ProviderType() string {
return TYPE_CODE
}

func (this *Handler) GetZones() (provider.DNSHostedZones, error) {
raw := []alidns.Domain{}
{
Expand Down
41 changes: 14 additions & 27 deletions pkg/controller/provider/aws/aliastarget.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,43 +75,30 @@ func isAliasTarget(r *route53.ResourceRecordSet) bool {
return aws.StringValue(r.Type) == route53.RRTypeA && r.AliasTarget != nil
}

// buildRecordSetForAliasTarget transforms an A alias target to a CNAME dns.RecordSet
func buildRecordSetForAliasTarget(r *route53.ResourceRecordSet) *dns.RecordSet {
rs := dns.NewRecordSet(dns.RS_CNAME, 0, nil)
// buildRecordSetFromAliasTarget transforms an A alias target to a CNAME dns.RecordSet
func buildRecordSetFromAliasTarget(r *route53.ResourceRecordSet) *dns.RecordSet {
rs := dns.NewRecordSet(dns.RS_ALIAS, 0, nil)
rs.IgnoreTTL = true // alias target has no settable TTL
rs.Add(&dns.Record{Value: dns.NormalizeHostname(aws.StringValue(r.AliasTarget.DNSName))})
return rs
}

// canConvertToAliasTarget determines if a given hostname belongs to an AWS load balancer.
// Returns nil otherwise.
func canConvertToAliasTarget(rset *dns.RecordSet) bool {
return getAliasTargetForAWSLoadBalancer(rset) != nil
}

// getAliasTargetForAWSLoadBalancer determines if a given hostname belongs to an AWS load balancer
// and creates an AliasTarget. Returns nil otherwise.
func getAliasTargetForAWSLoadBalancer(rset *dns.RecordSet) *route53.AliasTarget {
if rset.Type == dns.RS_CNAME && len(rset.Records) == 1 {
target := dns.NormalizeHostname(rset.Records[0].Value)
hostedZone := canonicalHostedZone(target)
if hostedZone != "" {
return &route53.AliasTarget{
DNSName: aws.String(target),
HostedZoneId: aws.String(hostedZone),
EvaluateTargetHealth: aws.Bool(true),
}
}
func buildResourceRecordSetForAliasTarget(name string, rset *dns.RecordSet) *route53.ResourceRecordSet {
target := dns.NormalizeHostname(rset.Records[0].Value)
hostedZone := canonicalHostedZone(target)
if hostedZone == "" {
return nil
}
aliasTarget := &route53.AliasTarget{
DNSName: aws.String(target),
HostedZoneId: aws.String(hostedZone),
EvaluateTargetHealth: aws.Bool(true),
}

return nil
}

func buildResourceRecordSetForAliasTarget(name string, rset *dns.RecordSet) *route53.ResourceRecordSet {
return &route53.ResourceRecordSet{
Name: aws.String(name),
Type: aws.String(route53.RRTypeA),
AliasTarget: getAliasTargetForAWSLoadBalancer(rset),
AliasTarget: aliasTarget,
}
}

Expand Down
6 changes: 5 additions & 1 deletion pkg/controller/provider/aws/execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,12 @@ func (this *Execution) addChange(action string, req *provider.ChangeRequest, dns
this.Infof("%s %s record set %s[%s]: %s(%d)", action, rset.Type, name, this.zone.Id(), rset.RecordString(), rset.TTL)

var rrs *route53.ResourceRecordSet
if canConvertToAliasTarget(rset) {
if rset.Type == dns.RS_ALIAS {
rrs = buildResourceRecordSetForAliasTarget(name, rset)
if rrs == nil {
this.Errorf("Corrupted alias record set %s[%s]", name, this.zone.Id())
return
}
} else {
rrs = buildResourceRecordSet(name, rset)
}
Expand Down
47 changes: 11 additions & 36 deletions pkg/controller/provider/aws/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
)

type Handler struct {
provider.DefaultDNSHandler
config provider.DNSHandlerConfig
awsConfig AWSConfig
metrics provider.Metrics
Expand All @@ -54,6 +55,8 @@ func NewHandler(logger logger.LogContext, config *provider.DNSHandlerConfig, met
}

this := &Handler{
DefaultDNSHandler: provider.NewDefaultDNSHandler(TYPE_CODE),

config: *config,
awsConfig: awsConfig,
metrics: metrics,
Expand Down Expand Up @@ -89,10 +92,6 @@ func NewHandler(logger logger.LogContext, config *provider.DNSHandlerConfig, met
return this, nil
}

func (h *Handler) ProviderType() string {
return TYPE_CODE
}

func (this *Handler) GetZones() (provider.DNSHostedZones, error) {
rt := provider.M_LISTZONES
raw := []*route53.HostedZone{}
Expand Down Expand Up @@ -144,18 +143,13 @@ func buildRecordSet(r *route53.ResourceRecordSet) *dns.RecordSet {
func (this *Handler) GetZoneState(zone provider.DNSHostedZone) (provider.DNSZoneState, error) {
dnssets := dns.DNSSets{}

migrations := []*route53.ResourceRecordSet{}

aggr := func(r *route53.ResourceRecordSet) {
if dns.SupportedRecordType(aws.StringValue(r.Type)) {
var rs *dns.RecordSet
if isAliasTarget(r) {
rs = buildRecordSetForAliasTarget(r)
rs = buildRecordSetFromAliasTarget(r)
} else {
rs = buildRecordSet(r)
if canConvertToAliasTarget(rs) {
migrations = append(migrations, r)
}
}
dnssets.AddRecordSetFromProvider(aws.StringValue(r.Name), rs)
}
Expand All @@ -164,10 +158,6 @@ func (this *Handler) GetZoneState(zone provider.DNSHostedZone) (provider.DNSZone
return nil, err
}

if len(migrations) > 0 {
this.migrateRecordsToAliasTargets(zone, migrations)
}

return provider.NewDNSZoneState(dnssets), nil
}

Expand Down Expand Up @@ -206,27 +196,12 @@ func (this *Handler) ExecuteRequests(logger logger.LogContext, zone provider.DNS
return exec.submitChanges(this.metrics)
}

func (this *Handler) migrateRecordsToAliasTargets(zone provider.DNSHostedZone, migrations []*route53.ResourceRecordSet) {
logContext := logger.NewContext("provider", "aws-route53").NewContext("zone", zone.Id())
logContext.Infof("migrating %d records to alias targets", len(migrations))
exec := NewExecution(logContext, this, zone)

for _, r := range migrations {
rs := buildRecordSet(r)
name := aws.StringValue(r.Name)
dnsset := dns.NewDNSSet(dns.NormalizeHostname(name))
dnsset.Sets[rs.Type] = rs

// delete old CNAME DNS record
change := &route53.Change{Action: aws.String(route53.ChangeActionDelete), ResourceRecordSet: r}
exec.addRawChange(name, change, nil)
// add A alias target record (implicitly converted dns.RecordSet)
r := &provider.ChangeRequest{Action: provider.R_CREATE, Type: aws.StringValue(r.Type), Addition: dnsset}
exec.addChange(route53.ChangeActionCreate, r, r.Addition)
}

err := exec.submitChanges(this.metrics)
if err != nil {
logContext.Warnf("Migrating to alias targets failed with %s", err)
func (this *Handler) MapTarget(t provider.Target) provider.Target {
if t.GetRecordType() == dns.RS_CNAME {
hostedZone := canonicalHostedZone(t.GetHostName())
if hostedZone != "" {
return provider.NewTarget(dns.RS_ALIAS, t.GetHostName(), t.GetEntry())
}
}
return t
}
10 changes: 4 additions & 6 deletions pkg/controller/provider/azure/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
)

type Handler struct {
provider.DefaultDNSHandler
config provider.DNSHandlerConfig
ctx context.Context
metrics provider.Metrics
Expand All @@ -45,8 +46,9 @@ var _ provider.DNSHandler = &Handler{}
func NewHandler(logger logger.LogContext, config *provider.DNSHandlerConfig, metrics provider.Metrics) (provider.DNSHandler, error) {

h := &Handler{
config: *config,
metrics: metrics,
DefaultDNSHandler: provider.NewDefaultDNSHandler(TYPE_CODE),
config: *config,
metrics: metrics,
}

h.ctx = config.Context
Expand Down Expand Up @@ -105,10 +107,6 @@ func NewHandler(logger logger.LogContext, config *provider.DNSHandlerConfig, met

var re = regexp.MustCompile("/resourceGroups/([^/]+)/")

func (h *Handler) ProviderType() string {
return TYPE_CODE
}

func (h *Handler) GetZones() (provider.DNSHostedZones, error) {
zones := provider.DNSHostedZones{}

Expand Down
10 changes: 4 additions & 6 deletions pkg/controller/provider/google/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
)

type Handler struct {
provider.DefaultDNSHandler
config provider.DNSHandlerConfig
credentials *google.Credentials
client *http.Client
Expand All @@ -46,8 +47,9 @@ func NewHandler(logger logger.LogContext, config *provider.DNSHandlerConfig, met
var err error

this := &Handler{
config: *config,
metrics: metrics,
DefaultDNSHandler: provider.NewDefaultDNSHandler(TYPE_CODE),
config: *config,
metrics: metrics,
}
scopes := []string{
// "https://www.googleapis.com/auth/compute",
Expand Down Expand Up @@ -81,10 +83,6 @@ func NewHandler(logger logger.LogContext, config *provider.DNSHandlerConfig, met
return this, nil
}

func (h *Handler) ProviderType() string {
return TYPE_CODE
}

func (this *Handler) GetZones() (provider.DNSHostedZones, error) {
rt := provider.M_LISTZONES
raw := []*googledns.ManagedZone{}
Expand Down
12 changes: 5 additions & 7 deletions pkg/controller/provider/mock/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
)

type Handler struct {
provider.DefaultDNSHandler
config provider.DNSHandlerConfig
ctx context.Context
metrics provider.Metrics
Expand All @@ -45,9 +46,10 @@ func NewHandler(logger logger.LogContext, config *provider.DNSHandlerConfig, met
mock := NewInMemory()

h := &Handler{
config: *config,
metrics: metrics,
mock: mock,
DefaultDNSHandler: provider.NewDefaultDNSHandler(TYPE_CODE),
config: *config,
metrics: metrics,
mock: mock,
}

mockConfig := MockConfig{}
Expand Down Expand Up @@ -78,10 +80,6 @@ func NewHandler(logger logger.LogContext, config *provider.DNSHandlerConfig, met
return h, nil
}

func (h *Handler) ProviderType() string {
return TYPE_CODE
}

func (h *Handler) GetZones() (provider.DNSHostedZones, error) {
zones := h.mock.GetZones()

Expand Down
12 changes: 5 additions & 7 deletions pkg/controller/provider/openstack/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
)

type Handler struct {
provider.DefaultDNSHandler
config provider.DNSHandlerConfig
ctx context.Context

Expand Down Expand Up @@ -55,9 +56,10 @@ func NewHandler(logger logger.LogContext, config *provider.DNSHandlerConfig, met
}

h := Handler{
config: *config,
ctx: config.Context,
client: designateClient{serviceClient: serviceClient, metrics: metrics},
DefaultDNSHandler: provider.NewDefaultDNSHandler(TYPE_CODE),
config: *config,
ctx: config.Context,
client: designateClient{serviceClient: serviceClient, metrics: metrics},
}
return &h, nil
}
Expand Down Expand Up @@ -107,10 +109,6 @@ func readAuthConfig(config *provider.DNSHandlerConfig) (*authConfig, error) {
return &authConfig, nil
}

func (h *Handler) ProviderType() string {
return TYPE_CODE
}

func (h *Handler) GetZones() (provider.DNSHostedZones, error) {
hostedZones := provider.DNSHostedZones{}

Expand Down
10 changes: 5 additions & 5 deletions pkg/dns/provider/changemodel.go
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ func (this *ChangeModel) Exec(apply bool, delete bool, name string, done DoneHan
oldset := view.dnssets[name]
newset := dns.NewDNSSet(name)
if !delete {
this.AddTargets(newset, oldset, targets...)
this.AddTargets(newset, oldset, p, targets...)
}
mod := false
if oldset != nil {
Expand Down Expand Up @@ -383,7 +383,7 @@ func (this *ChangeModel) setOwner(set *dns.DNSSet, targets []Target) bool {
return false
}

func (this *ChangeModel) AddTargets(set *dns.DNSSet, base *dns.DNSSet, targets ...Target) *dns.DNSSet {
func (this *ChangeModel) AddTargets(set *dns.DNSSet, base *dns.DNSSet, provider DNSProvider, targets ...Target) *dns.DNSSet {
//if base != nil {
// meta := base.Sets[RS_META]
// if meta != nil {
Expand All @@ -400,10 +400,9 @@ func (this *ChangeModel) AddTargets(set *dns.DNSSet, base *dns.DNSSet, targets .
targetsets := set.Sets
cnames := []string{}
for _, t := range targets {
ty := t.GetRecordType()
// use status calculated in entry
ttl := t.GetEntry().TTL()
if ty == dns.RS_CNAME && len(targets) > 1 {
if t.GetRecordType() == dns.RS_CNAME && len(targets) > 1 {
cnames = append(cnames, t.GetHostName())
addrs, err := net.LookupHost(t.GetHostName())
if err == nil {
Expand All @@ -415,7 +414,8 @@ func (this *ChangeModel) AddTargets(set *dns.DNSSet, base *dns.DNSSet, targets .
}
this.Debugf("mapping target '%s' to A records: %s", t.GetHostName(), strings.Join(addrs, ","))
} else {
AddRecord(targetsets, ty, t.GetHostName(), ttl)
t = provider.MapTarget(t)
AddRecord(targetsets, t.GetRecordType(), t.GetHostName(), ttl)
}
}
set.Sets = targetsets
Expand Down
18 changes: 18 additions & 0 deletions pkg/dns/provider/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,23 @@ type DNSHandler interface {
GetZones() (DNSHostedZones, error)
GetZoneState(DNSHostedZone) (DNSZoneState, error)
ExecuteRequests(logger logger.LogContext, zone DNSHostedZone, state DNSZoneState, reqs []*ChangeRequest) error
MapTarget(t Target) Target
}

type DefaultDNSHandler struct {
providerType string
}

func NewDefaultDNSHandler(providerType string) DefaultDNSHandler {
return DefaultDNSHandler{providerType}
}

func (this *DefaultDNSHandler) ProviderType() string {
return this.providerType
}

func (this *DefaultDNSHandler) MapTarget(t Target) Target {
return t
}

////////////////////////////////////////////////////////////////////////////////
Expand All @@ -179,6 +196,7 @@ type DNSProvider interface {
Match(dns string) int

AccountHash() string
MapTarget(t Target) Target
}

type DoneHandler interface {
Expand Down
Loading

0 comments on commit 8c439b6

Please sign in to comment.