Skip to content

Commit

Permalink
Fix import of routed ALIAS records. Fixes #170
Browse files Browse the repository at this point in the history
  • Loading branch information
barnybug committed Apr 17, 2016
1 parent 327a615 commit 510ca4d
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 62 deletions.
20 changes: 10 additions & 10 deletions awsrr.go
Expand Up @@ -10,27 +10,27 @@ import (
const ClassAWS = 253
const TypeALIAS = 0x0F99

type ALIAS struct {
type ALIASRdata struct {
Type string
Target string
ZoneId string
EvaluateTargetHealth bool
}

func (rd *ALIAS) Copy(dest dns.PrivateRdata) error {
d := dest.(*ALIAS)
func (rd *ALIASRdata) Copy(dest dns.PrivateRdata) error {
d := dest.(*ALIASRdata)
d.Type = rd.Type
d.Target = rd.Target
d.ZoneId = rd.ZoneId
d.EvaluateTargetHealth = rd.EvaluateTargetHealth
return nil
}

func (rd *ALIAS) Len() int {
func (rd *ALIASRdata) Len() int {
return 0
}

func (rd *ALIAS) Parse(txt []string) error {
func (rd *ALIASRdata) Parse(txt []string) error {
if len(txt) != 4 {
return errors.New("4 parts required for ALIAS: type target zoneid evaluateTargetHealth")
}
Expand All @@ -41,15 +41,15 @@ func (rd *ALIAS) Parse(txt []string) error {
return nil
}

func (rd *ALIAS) Pack(buf []byte) (int, error) {
func (rd *ALIASRdata) Pack(buf []byte) (int, error) {
return 0, nil
}

func (rd *ALIAS) Unpack(buf []byte) (int, error) {
func (rd *ALIASRdata) Unpack(buf []byte) (int, error) {
return 0, nil
}

func (rr *ALIAS) String() string {
func (rr *ALIASRdata) String() string {
return fmt.Sprintf("%s %s %s %v",
rr.Type,
rr.Target,
Expand All @@ -58,12 +58,12 @@ func (rr *ALIAS) String() string {
)
}

func NewALIAS() dns.PrivateRdata { return new(ALIAS) }
func NewALIASRdata() dns.PrivateRdata { return new(ALIASRdata) }

func init() {
dns.StringToClass["AWS"] = ClassAWS
dns.ClassToString[ClassAWS] = "AWS"
dns.PrivateHandle("ALIAS", TypeALIAS, NewALIAS)
dns.PrivateHandle("ALIAS", TypeALIAS, NewALIASRdata)
}

type AWSRoute interface {
Expand Down
88 changes: 43 additions & 45 deletions bind.go
Expand Up @@ -29,7 +29,7 @@ func parseComment(rr dns.RR, comment string) dns.RR {
fmt.Printf("Warning: parse AWS extension - routing=\"%s\" not understood\n", routing)
}
} else {
fmt.Println("Warning: parse AWS extension: %s", err)
fmt.Printf("Warning: parse AWS extension: %s", err)
}
}
return rr
Expand Down Expand Up @@ -59,73 +59,63 @@ func quoteValues(vals []string) string {
}

// Convert a DNS record into a route53 ResourceRecord.
func ConvertBindToRR(record dns.RR) []*route53.ResourceRecord {
func ConvertBindToRR(record dns.RR) *route53.ResourceRecord {
switch record := record.(type) {
case *dns.A:
rr := &route53.ResourceRecord{
return &route53.ResourceRecord{
Value: aws.String(record.A.String()),
}
return []*route53.ResourceRecord{rr}
case *dns.AAAA:
rr := &route53.ResourceRecord{
return &route53.ResourceRecord{
Value: aws.String(record.AAAA.String()),
}
return []*route53.ResourceRecord{rr}
case *dns.CNAME:
rr := &route53.ResourceRecord{
return &route53.ResourceRecord{
Value: aws.String(record.Target),
}
return []*route53.ResourceRecord{rr}
case *dns.MX:
value := fmt.Sprintf("%d %s", record.Preference, record.Mx)
rr := &route53.ResourceRecord{
return &route53.ResourceRecord{
Value: aws.String(value),
}
return []*route53.ResourceRecord{rr}
case *dns.NS:
rr := &route53.ResourceRecord{
return &route53.ResourceRecord{
Value: aws.String(record.Ns),
}
return []*route53.ResourceRecord{rr}
case *dns.PTR:
rr := &route53.ResourceRecord{
return &route53.ResourceRecord{
Value: aws.String(record.Ptr),
}
return []*route53.ResourceRecord{rr}
case *dns.SOA:
value := fmt.Sprintf("%s %s %d %d %d %d %d", record.Ns, record.Mbox, record.Serial, record.Refresh, record.Retry, record.Expire, record.Minttl)
rr := &route53.ResourceRecord{
return &route53.ResourceRecord{
Value: aws.String(value),
}
return []*route53.ResourceRecord{rr}
case *dns.SPF:
value := quoteValues(record.Txt)
rr := &route53.ResourceRecord{
return &route53.ResourceRecord{
Value: aws.String(value),
}
return []*route53.ResourceRecord{rr}
case *dns.SRV:
value := fmt.Sprintf("%d %d %d %s", record.Priority, record.Weight, record.Port, record.Target)
rr := &route53.ResourceRecord{
return &route53.ResourceRecord{
Value: aws.String(value),
}
return []*route53.ResourceRecord{rr}
case *dns.TXT:
value := quoteValues(record.Txt)
rr := &route53.ResourceRecord{
return &route53.ResourceRecord{
Value: aws.String(value),
}
return []*route53.ResourceRecord{rr}
default:
errorAndExit(fmt.Sprintf("Unsupported resource record: %s", record))
}
return []*route53.ResourceRecord{}
return nil
}

func ConvertAliasToRRSet(alias *dns.PrivateRR) *route53.ResourceRecordSet {
// AWS ALIAS extension record
hdr := alias.Header()
rdata := alias.Data.(*ALIAS)
rdata := alias.Data.(*ALIASRdata)
return &route53.ResourceRecordSet{
Type: aws.String(rdata.Type),
Name: aws.String(hdr.Name),
Expand All @@ -140,26 +130,18 @@ func ConvertAliasToRRSet(alias *dns.PrivateRR) *route53.ResourceRecordSet {
// Convert some DNS records into a route53 ResourceRecordSet. The records should have been
// previously grouped by matching name, type and (if applicable) identifier.
func ConvertBindToRRSet(records []dns.RR) *route53.ResourceRecordSet {
rrs := []*route53.ResourceRecord{}
for _, record := range records {
if rr, ok := record.(*dns.PrivateRR); ok {
return ConvertAliasToRRSet(rr)
} else if rec, ok := record.(*AWSRR); ok {
rrs = append(rrs, ConvertBindToRR(rec.RR)...)
} else {
rrs = append(rrs, ConvertBindToRR(record)...)
}
if len(records) == 0 {
return nil
}
hdr := records[0].Header()
rrset := &route53.ResourceRecordSet{
Type: aws.String(dns.TypeToString[hdr.Rrtype]),
Name: aws.String(hdr.Name),
TTL: aws.Int64(int64(hdr.Ttl)),
}

if len(rrs) > 0 {
hdr := records[0].Header()
rrset := &route53.ResourceRecordSet{
Type: aws.String(dns.Type(hdr.Rrtype).String()),
Name: aws.String(hdr.Name),
ResourceRecords: rrs,
TTL: aws.Int64(int64(hdr.Ttl)),
}
if awsrr, ok := records[0].(*AWSRR); ok {
for _, record := range records {
if awsrr, ok := record.(*AWSRR); ok {
switch route := awsrr.Route.(type) {
case *FailoverRoute:
rrset.Failover = aws.String(route.Failover)
Expand All @@ -178,10 +160,26 @@ func ConvertBindToRRSet(records []dns.RR) *route53.ResourceRecordSet {
rrset.HealthCheckId = awsrr.HealthCheckId
}
rrset.SetIdentifier = aws.String(awsrr.Identifier)
record = awsrr.RR
}

if rr, ok := record.(*dns.PrivateRR); ok {
// 'AWS ALIAS' records do not have ResourceRecords
rdata := rr.Data.(*ALIASRdata)
rrset.Type = aws.String(rdata.Type)
rrset.AliasTarget = &route53.AliasTarget{
DNSName: aws.String(rdata.Target),
HostedZoneId: aws.String(rdata.ZoneId),
EvaluateTargetHealth: aws.Bool(rdata.EvaluateTargetHealth),
}
rrset.TTL = nil
} else {
rr := ConvertBindToRR(record)
rrset.ResourceRecords = append(rrset.ResourceRecords, rr)
}
return rrset
}
return nil

return rrset
}

func ConvertRRSetToBind(rrset *route53.ResourceRecordSet) []dns.RR {
Expand All @@ -206,7 +204,7 @@ func ConvertRRSetToBind(rrset *route53.ResourceRecordSet) []dns.RR {
Class: ClassAWS,
Ttl: 86400,
},
Data: &ALIAS{
Data: &ALIASRdata{
*rrset.Type,
*alias.DNSName,
*alias.HostedZoneId,
Expand Down
2 changes: 1 addition & 1 deletion bind_test.go
Expand Up @@ -284,7 +284,7 @@ var testConvertRRSetToBindTable = []struct {
Class: ClassAWS,
Ttl: uint32(86400),
},
Data: &ALIAS{
Data: &ALIASRdata{
Type: "A",
Target: "target",
ZoneId: "zoneid",
Expand Down
16 changes: 11 additions & 5 deletions commands.go
Expand Up @@ -106,8 +106,11 @@ func expandSelfAliases(records []dns.RR, zone *route53.HostedZone) {
}

func expandSelfAlias(record dns.RR, zone *route53.HostedZone) {
if awsrr, ok := record.(*AWSRR); ok {
record = awsrr.RR
}
if alias, ok := record.(*dns.PrivateRR); ok {
rdata := alias.Data.(*ALIAS)
rdata := alias.Data.(*ALIASRdata)
if rdata.ZoneId == "$self" {
rdata.ZoneId = strings.Replace(*zone.Id, "/hostedzone/", "", 1)
rdata.Target = qualifyName(rdata.Target, *zone.Name)
Expand Down Expand Up @@ -242,8 +245,11 @@ func batchChanges(additions, deletions []*route53.Change, zone *route53.HostedZo
func UnexpandSelfAliases(records []dns.RR, zone *route53.HostedZone, full bool) {
id := strings.Replace(*zone.Id, "/hostedzone/", "", 1)
for _, rr := range records {
if awsrr, ok := rr.(*AWSRR); ok {
rr = awsrr.RR
}
if alias, ok := rr.(*dns.PrivateRR); ok {
rdata := alias.Data.(*ALIAS)
rdata := alias.Data.(*ALIASRdata)
if rdata.ZoneId == id {
rdata.ZoneId = "$self"
if !full {
Expand All @@ -255,7 +261,7 @@ func UnexpandSelfAliases(records []dns.RR, zone *route53.HostedZone, full bool)
}

func exportBind(name string, full bool) {
zone := lookupZone(name)
zone := lookupZone(name)
ExportBindToWriter(r53, zone, full, os.Stdout)
}

Expand Down Expand Up @@ -396,7 +402,7 @@ func (args createArgs) applyRRSetParams(rrset *route53.ResourceRecordSet) {
}
if args.countryCode != "" && args.subdivisionCode != "" {
rrset.GeoLocation = &route53.GeoLocation{
CountryCode: aws.String(args.countryCode),
CountryCode: aws.String(args.countryCode),
SubdivisionCode: aws.String(args.subdivisionCode),
}
}
Expand All @@ -416,7 +422,7 @@ func equalCaseInsensitiveStringPtrs(a, b *string) bool {
if a == nil && b == nil {
return true
} else if a != nil && b != nil {
return strings.EqualFold(*a, *b)
return strings.EqualFold(*a, *b)
} else {
return false
}
Expand Down
5 changes: 5 additions & 0 deletions internal/features/bind.feature
Expand Up @@ -35,6 +35,11 @@ Feature: bind files
When I run "cli53 import --file tests/geo.txt $domain"
Then the domain "$domain" export matches file "tests/geo.txt"

Scenario: I can import a zone with geo ALIAS records
Given I have a domain "$domain"
When I run "cli53 import --file tests/geo_alias.txt $domain"
Then the domain "$domain" export matches file "tests/geo_alias.txt"

Scenario: I can import a zone with latency extensions
Given I have a domain "$domain"
When I run "cli53 import --file tests/latency.txt $domain"
Expand Down
3 changes: 3 additions & 0 deletions tests/geo_alias.txt
@@ -0,0 +1,3 @@
a 300 IN A 127.0.0.1
geo 300 IN A 127.0.0.2 ; AWS routing="GEOLOCATION" continentCode="AF" identifier="Africa"
geo 86400 AWS ALIAS A a $self false ; AWS routing="GEOLOCATION" countryCode="GB" identifier="UK"
2 changes: 1 addition & 1 deletion vendor/github.com/miekg/dns/privaterr.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 510ca4d

Please sign in to comment.