mirror of
https://github.com/github/octodns.git
synced 2024-05-11 05:55:00 +00:00
deal with duplicates and duplicate auto-creates cleanly
This commit is contained in:
@@ -13,6 +13,17 @@ from ..record import Record
|
||||
from .base import BaseSource
|
||||
|
||||
|
||||
def _unique(values):
|
||||
try:
|
||||
# this will work if they're simple strings
|
||||
return list(set(values))
|
||||
except TypeError:
|
||||
pass
|
||||
# if they're dictionaries it's a bit more involved since dict's aren't
|
||||
# hashable, based on https://stackoverflow.com/a/38521207
|
||||
return [dict(s) for s in set(frozenset(v.items()) for v in values)]
|
||||
|
||||
|
||||
class TinyDnsBaseSource(BaseSource):
|
||||
SUPPORTS_GEO = False
|
||||
SUPPORTS_DYNAMIC = False
|
||||
@@ -387,7 +398,7 @@ class TinyDnsBaseSource(BaseSource):
|
||||
|
||||
def _process_symbols(self, zone, symbols, arpa):
|
||||
types = defaultdict(lambda: defaultdict(list))
|
||||
ttls = defaultdict(lambda: defaultdict(lambda: self.default_ttl))
|
||||
ttls = defaultdict(dict)
|
||||
for symbol, names in symbols.items():
|
||||
records_for = self.SYMBOL_MAP.get(symbol, None)
|
||||
if not records_for:
|
||||
@@ -404,8 +415,10 @@ class TinyDnsBaseSource(BaseSource):
|
||||
# remove the zone name
|
||||
name = zone.hostname_from_fqdn(name)
|
||||
types[_type][name].extend(values)
|
||||
# last one wins
|
||||
ttls[_type][name] = ttl
|
||||
# first non-default wins, if we never see anything we'll
|
||||
# just use the default below
|
||||
if ttl != self.default_ttl:
|
||||
ttls[_type][name] = ttl
|
||||
|
||||
return types, ttls
|
||||
|
||||
@@ -440,9 +453,12 @@ class TinyDnsBaseSource(BaseSource):
|
||||
# it to the zone
|
||||
for _type, names in types.items():
|
||||
for name, values in names.items():
|
||||
data = {'ttl': ttls[_type][name], 'type': _type}
|
||||
data = {
|
||||
'ttl': ttls[_type].get(name, self.default_ttl),
|
||||
'type': _type,
|
||||
}
|
||||
if len(values) > 1:
|
||||
data['values'] = values
|
||||
data['values'] = _unique(values)
|
||||
else:
|
||||
data['value'] = values[0]
|
||||
record = Record.new(zone, name, data, lenient=lenient)
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
# Multi-value A
|
||||
+example.com:10.2.3.4:30
|
||||
+example.com.:10.2.3.5:30
|
||||
# duplicate value should be ignored
|
||||
+example.com:10.2.3.4
|
||||
|
||||
Ccname.other.foo:www.other.foo
|
||||
|
||||
@@ -65,5 +67,8 @@ Ccname.other.foo:www.other.foo
|
||||
# SRV
|
||||
S_a._tcp.example.com:56.57.58.59:target:8888
|
||||
S_a._tcp.example.com::target.somewhere.else:8080:10:50:43
|
||||
# TODO: add an IP so it tries to create a record that already exists
|
||||
S_b._tcp.example.com::target.srv.example.com.:9999
|
||||
# will try and re-create an already existing A with the same IP, should be a
|
||||
# noop
|
||||
S_b._tcp.example.com:56.57.58.59:target.srv.example.com.:9999
|
||||
# complete duplicate should be ignored
|
||||
S_b._tcp.example.com:56.57.58.59:target.srv.example.com.:9999
|
||||
|
||||
Reference in New Issue
Block a user