This repository has been archived by the owner on Jan 9, 2023. It is now read-only.
/
route53.go
140 lines (116 loc) · 3.68 KB
/
route53.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// Copyright Jetstack Ltd. See LICENSE for details.
package amazon
import (
"errors"
"fmt"
"net"
"reflect"
"sort"
"strings"
"time"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/route53"
)
func (a *Amazon) PublicZone() string {
return a.conf.Amazon.PublicZone
}
// this removes an ending . in zone and converts it to lowercase
func normalizeZone(in string) string {
return strings.ToLower(strings.TrimRight(in, "."))
}
func (a *Amazon) initPublicZone() (*route53.HostedZone, error) {
publicZone := normalizeZone(a.conf.Amazon.PublicZone)
if publicZone == "" {
return nil, errors.New("no public zone given in provider config")
}
if a.conf.Amazon.PublicHostedZoneID != "" {
return nil, errors.New("can not auto create public zone as there is HostedZoneID given in provider config")
}
svc, err := a.Route53()
if err != nil {
return nil, err
}
result, err := svc.CreateHostedZone(&route53.CreateHostedZoneInput{
CallerReference: aws.String(time.Now().Format(time.RFC3339)),
Name: aws.String(normalizeZone(publicZone)),
HostedZoneConfig: &route53.HostedZoneConfig{
Comment: aws.String("public zone for tarmak"),
},
})
return result.HostedZone, err
}
func (a *Amazon) verifyPublicZone() error {
svc, err := a.Route53()
if err != nil {
return err
}
publicZoneName := normalizeZone(a.conf.Amazon.PublicZone)
input := &route53.ListHostedZonesByNameInput{}
if publicZoneName != "" {
input.DNSName = aws.String(publicZoneName)
}
if hostedZoneID := a.conf.Amazon.PublicHostedZoneID; hostedZoneID != "" {
input.HostedZoneId = aws.String(hostedZoneID)
}
var zone *route53.HostedZone
zonesResponse, err := svc.ListHostedZonesByName(input)
if err != nil {
return err
}
var zones []*route53.HostedZone
for pos, _ := range zonesResponse.HostedZones {
zone := zonesResponse.HostedZones[pos]
if normalizeZone(*zone.Name) == publicZoneName {
zones = append(zones, zone)
}
}
if len(zones) > 1 {
msg := "more than one matching zone found, "
if input.HostedZoneId != nil {
msg = fmt.Sprintf("%shostedZoneID = %s ", msg, *input.HostedZoneId)
}
if input.DNSName != nil {
msg = fmt.Sprintf("%sdnsName = %s ", msg, *input.DNSName)
}
return errors.New(msg)
} else if len(zones) == 0 {
zone, err = a.initPublicZone()
if err != nil {
return err
}
} else {
zone = zones[0]
}
// store hostedzone id
if split := strings.Split(*zone.Id, "/"); len(split) < 2 {
return fmt.Errorf("Unexpected ID %s", *zone.Id)
} else {
a.conf.Amazon.PublicHostedZoneID = split[2]
}
// store zone information
a.conf.Amazon.PublicZone = normalizeZone(*zone.Name)
// validate delegation
zoneResult, err := svc.GetHostedZone(&route53.GetHostedZoneInput{Id: zone.Id})
if err != nil {
return fmt.Errorf("unabled to get zone with ID '%s': %s", *zone.Id, err)
}
zoneNameservers := make([]string, len(zoneResult.DelegationSet.NameServers))
for pos, _ := range zoneResult.DelegationSet.NameServers {
zoneNameservers[pos] = *zoneResult.DelegationSet.NameServers[pos]
}
notice := fmt.Sprintf("make sure the domain is delegated to these nameservers %+v", zoneNameservers)
dnsResult, err := net.LookupNS(a.conf.Amazon.PublicZone)
if err != nil {
return fmt.Errorf("error resolving NS records for %s (%s), %s", a.conf.Amazon.PublicZone, err, notice)
}
dnsNameservers := make([]string, len(dnsResult))
for pos, _ := range dnsResult {
dnsNameservers[pos] = normalizeZone(dnsResult[pos].Host)
}
sort.Strings(dnsNameservers)
sort.Strings(zoneNameservers)
if !reflect.DeepEqual(dnsNameservers, zoneNameservers) {
return fmt.Errorf("public root dns nameservers %v and zone nameservers %v mismatch", dnsNameservers, zoneNameservers)
}
return nil
}