mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2024-05-11 05:55:12 +00:00
Add R53_ZONE as an domain identifier (#1241)
Using R53_ZONE allows you to differentiate between split horizon domains across zones.
This commit is contained in:
@ -4,8 +4,12 @@ parameters:
|
||||
- zone_id
|
||||
---
|
||||
|
||||
R53_ZONE sets the required Route53 hosted zone id in a R53_ALIAS record.
|
||||
R53_ZONE lets you specify the AWS Zone ID for an entire domain (D()) or a specific R53_ALIAS() record.
|
||||
|
||||
When used with D(), it sets the zone id of the domain. This can be used to differentiate between split horizon domains in public and private zones.
|
||||
|
||||
When used with R53_ALIAS() it sets the required Route53 hosted zone id in a R53_ALIAS record. See [https://stackexchange.github.io/dnscontrol/js#R53_ALIAS](R53_ALIAS's documentation) for details.
|
||||
|
||||
|
||||
|
||||
This directive has no impact when used in anything else than a R53_ALIAS.
|
||||
|
||||
Please refer to the R53_ALIAS directive for usage.
|
@ -26,6 +26,10 @@ function initialize() {
|
||||
defaultArgs = [];
|
||||
}
|
||||
|
||||
function _isDomain(d) {
|
||||
return _.isArray(d.nameservers) && _.isArray(d.records) && _.isString(d.name);
|
||||
}
|
||||
|
||||
// Returns an array of domains which were registered so far during runtime
|
||||
// Own function for compatibility reasons or if some day special processing would be required.
|
||||
function getConfiguredDomains() {
|
||||
@ -277,7 +281,9 @@ var R53_ALIAS = recordBuilder('R53_ALIAS', {
|
||||
// R53_ZONE(zone_id)
|
||||
function R53_ZONE(zone_id) {
|
||||
return function (r) {
|
||||
if (_.isObject(r.r53_alias)) {
|
||||
if (_isDomain(r)) {
|
||||
r.meta.zone_id = zone_id;
|
||||
} else if (_.isObject(r.r53_alias)) {
|
||||
r.r53_alias['zone_id'] = zone_id;
|
||||
} else {
|
||||
r.r53_alias = { zone_id: zone_id };
|
||||
|
7
pkg/js/parse_tests/040-r53-zone.js
Normal file
7
pkg/js/parse_tests/040-r53-zone.js
Normal file
@ -0,0 +1,7 @@
|
||||
D('foo.com', 'none', R53_ZONE('Z2FTEDLFRTZ'));
|
||||
D(
|
||||
'foo.com!internal',
|
||||
'none',
|
||||
R53_ZONE('Z2FTEDLFRTF'),
|
||||
R53_ALIAS('atest', 'A', 'foo.com.', R53_ZONE('Z2FTEDLFRTZ'))
|
||||
);
|
34
pkg/js/parse_tests/040-r53-zone.json
Normal file
34
pkg/js/parse_tests/040-r53-zone.json
Normal file
@ -0,0 +1,34 @@
|
||||
{
|
||||
"registrars": [],
|
||||
"dns_providers": [],
|
||||
"domains": [
|
||||
{
|
||||
"name": "foo.com",
|
||||
"registrar": "none",
|
||||
"dnsProviders": {},
|
||||
"records": [],
|
||||
"meta": {
|
||||
"zone_id": "Z2FTEDLFRTZ"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "foo.com!internal",
|
||||
"registrar": "none",
|
||||
"dnsProviders": {},
|
||||
"records": [
|
||||
{
|
||||
"type": "R53_ALIAS",
|
||||
"name": "atest",
|
||||
"r53_alias": {
|
||||
"type": "A",
|
||||
"zone_id": "Z2FTEDLFRTZ"
|
||||
},
|
||||
"target": "foo.com."
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"zone_id": "Z2FTEDLFRTF"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -25,7 +25,8 @@ type route53Provider struct {
|
||||
client *r53.Route53
|
||||
registrar *r53d.Route53Domains
|
||||
delegationSet *string
|
||||
zones map[string]*r53.HostedZone
|
||||
zonesById map[string]*r53.HostedZone
|
||||
zonesByDomain map[string]*r53.HostedZone
|
||||
originalRecords []*r53.ResourceRecordSet
|
||||
}
|
||||
|
||||
@ -119,7 +120,7 @@ func withRetry(f func() error) {
|
||||
func (r *route53Provider) ListZones() ([]string, error) {
|
||||
var zones []string
|
||||
// Assumes r.zones was filled already by newRoute53().
|
||||
for i := range r.zones {
|
||||
for i := range r.zonesByDomain {
|
||||
zones = append(zones, i)
|
||||
}
|
||||
return zones, nil
|
||||
@ -127,7 +128,8 @@ func (r *route53Provider) ListZones() ([]string, error) {
|
||||
|
||||
func (r *route53Provider) getZones() error {
|
||||
var nextMarker *string
|
||||
r.zones = make(map[string]*r53.HostedZone)
|
||||
r.zonesByDomain = make(map[string]*r53.HostedZone)
|
||||
r.zonesById = make(map[string]*r53.HostedZone)
|
||||
for {
|
||||
var out *r53.ListHostedZonesOutput
|
||||
var err error
|
||||
@ -143,7 +145,8 @@ func (r *route53Provider) getZones() error {
|
||||
}
|
||||
for _, z := range out.HostedZones {
|
||||
domain := strings.TrimSuffix(*z.Name, ".")
|
||||
r.zones[domain] = z
|
||||
r.zonesByDomain[domain] = z
|
||||
r.zonesById[parseZoneId(*z.Id)] = z
|
||||
}
|
||||
if out.NextMarker != nil {
|
||||
nextMarker = out.NextMarker
|
||||
@ -154,19 +157,27 @@ func (r *route53Provider) getZones() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type errNoExist struct {
|
||||
type errDomainNoExist struct {
|
||||
domain string
|
||||
}
|
||||
|
||||
func (e errNoExist) Error() string {
|
||||
type errZoneNoExist struct {
|
||||
zoneId string
|
||||
}
|
||||
|
||||
func (e errDomainNoExist) Error() string {
|
||||
return fmt.Sprintf("Domain %s not found in your route 53 account", e.domain)
|
||||
}
|
||||
|
||||
func (e errZoneNoExist) Error() string {
|
||||
return fmt.Sprintf("Zone with id %s not found in your route 53 account", e.zoneId)
|
||||
}
|
||||
|
||||
func (r *route53Provider) GetNameservers(domain string) ([]*models.Nameserver, error) {
|
||||
|
||||
zone, ok := r.zones[domain]
|
||||
zone, ok := r.zonesByDomain[domain]
|
||||
if !ok {
|
||||
return nil, errNoExist{domain}
|
||||
return nil, errDomainNoExist{domain}
|
||||
}
|
||||
var z *r53.GetHostedZoneOutput
|
||||
var err error
|
||||
@ -187,14 +198,31 @@ func (r *route53Provider) GetNameservers(domain string) ([]*models.Nameserver, e
|
||||
return models.ToNameservers(nss)
|
||||
}
|
||||
|
||||
// GetZoneRecords gets the records of a zone and returns them in RecordConfig format.
|
||||
func (r *route53Provider) GetZoneRecords(domain string) (models.Records, error) {
|
||||
|
||||
zone, ok := r.zones[domain]
|
||||
if !ok {
|
||||
return nil, errNoExist{domain}
|
||||
if zone, ok := r.zonesByDomain[domain]; ok {
|
||||
return r.getZoneRecords(zone)
|
||||
}
|
||||
|
||||
return nil, errDomainNoExist{domain}
|
||||
}
|
||||
|
||||
func (r *route53Provider) getZone(dc *models.DomainConfig) (*r53.HostedZone, error) {
|
||||
if zoneId, ok := dc.Metadata["zone_id"]; ok {
|
||||
zone, ok := r.zonesById[zoneId]
|
||||
if !ok {
|
||||
return nil, errZoneNoExist{zoneId}
|
||||
}
|
||||
return zone, nil
|
||||
}
|
||||
|
||||
if zone, ok := r.zonesByDomain[dc.Name]; ok {
|
||||
return zone, nil
|
||||
}
|
||||
|
||||
return nil, errDomainNoExist{dc.Name}
|
||||
}
|
||||
|
||||
func (r *route53Provider) getZoneRecords(zone *r53.HostedZone) (models.Records, error) {
|
||||
records, err := r.fetchRecordSets(zone.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -203,7 +231,7 @@ func (r *route53Provider) GetZoneRecords(domain string) (models.Records, error)
|
||||
|
||||
var existingRecords = []*models.RecordConfig{}
|
||||
for _, set := range records {
|
||||
rts, err := nativeToRecords(set, domain)
|
||||
rts, err := nativeToRecords(set, unescape(zone.Name))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -217,14 +245,14 @@ func (r *route53Provider) GetDomainCorrections(dc *models.DomainConfig) ([]*mode
|
||||
|
||||
var corrections = []*models.Correction{}
|
||||
|
||||
existingRecords, err := r.GetZoneRecords(dc.Name)
|
||||
zone, err := r.getZone(dc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
zone, ok := r.zones[dc.Name]
|
||||
if !ok {
|
||||
return nil, errNoExist{dc.Name}
|
||||
existingRecords, err := r.getZoneRecords(zone)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, want := range dc.Records {
|
||||
@ -492,6 +520,11 @@ func getZoneID(zone *r53.HostedZone, r *models.RecordConfig) string {
|
||||
if zoneID == "" {
|
||||
zoneID = aws.StringValue(zone.Id)
|
||||
}
|
||||
return parseZoneId(zoneID)
|
||||
}
|
||||
|
||||
/** Removes "/hostedzone/"" prefix from AWS ZoneId */
|
||||
func parseZoneId(zoneID string) string {
|
||||
if strings.HasPrefix(zoneID, "/hostedzone/") {
|
||||
zoneID = strings.TrimPrefix(zoneID, "/hostedzone/")
|
||||
}
|
||||
@ -613,7 +646,7 @@ func unescape(s *string) string {
|
||||
}
|
||||
|
||||
func (r *route53Provider) EnsureDomainExists(domain string) error {
|
||||
if _, ok := r.zones[domain]; ok {
|
||||
if _, ok := r.zonesByDomain[domain]; ok {
|
||||
return nil
|
||||
}
|
||||
if r.delegationSet != nil {
|
||||
|
Reference in New Issue
Block a user