Use a TLD's configured TTLs if they are present (#1992)

* Use tld's configured TTLs if they are present

* Change to optional

* Use optionals better
This commit is contained in:
sarahcaseybot 2023-04-21 13:47:10 -04:00 committed by GitHub
parent a239a66359
commit 2c258cd1bd
11 changed files with 300 additions and 53 deletions

View file

@ -24,7 +24,9 @@ import google.registry.model.common.DatabaseMigrationStateSchedule;
import google.registry.model.common.DatabaseMigrationStateSchedule.MigrationState; import google.registry.model.common.DatabaseMigrationStateSchedule.MigrationState;
import google.registry.model.common.DnsRefreshRequest; import google.registry.model.common.DnsRefreshRequest;
import google.registry.model.tld.Registries; import google.registry.model.tld.Registries;
import google.registry.model.tld.Tld;
import java.util.Collection; import java.util.Collection;
import java.util.Optional;
import javax.inject.Inject; import javax.inject.Inject;
import org.joda.time.DateTime; import org.joda.time.DateTime;
import org.joda.time.Duration; import org.joda.time.Duration;
@ -126,6 +128,18 @@ public class DnsUtils {
.collect(toImmutableList()))); .collect(toImmutableList())));
} }
public static long getDnsAPlusAAAATtlForHost(String host, Duration dnsDefaultATtl) {
Optional<InternetDomainName> tldName = Registries.findTldForName(InternetDomainName.from(host));
Duration dnsAPlusAaaaTtl = dnsDefaultATtl;
if (tldName.isPresent()) {
Tld tld = Tld.get(tldName.get().toString());
if (tld.getDnsAPlusAaaaTtl().isPresent()) {
dnsAPlusAaaaTtl = tld.getDnsAPlusAaaaTtl().get();
}
}
return dnsAPlusAaaaTtl.getStandardSeconds();
}
private boolean usePullQueue() { private boolean usePullQueue() {
return !DatabaseMigrationStateSchedule.getValueAtTime(dnsQueue.getClock().nowUtc()) return !DatabaseMigrationStateSchedule.getValueAtTime(dnsQueue.getClock().nowUtc())
.equals(MigrationState.DNS_SQL); .equals(MigrationState.DNS_SQL);

View file

@ -16,6 +16,7 @@ package google.registry.dns.writer.clouddns;
import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.collect.ImmutableSet.toImmutableSet; import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static google.registry.dns.DnsUtils.getDnsAPlusAAAATtlForHost;
import static google.registry.model.EppResourceUtils.loadByForeignKey; import static google.registry.model.EppResourceUtils.loadByForeignKey;
import static google.registry.util.DomainNameUtils.getSecondLevelDomain; import static google.registry.util.DomainNameUtils.getSecondLevelDomain;
@ -40,6 +41,7 @@ import google.registry.model.domain.Domain;
import google.registry.model.domain.secdns.DomainDsData; import google.registry.model.domain.secdns.DomainDsData;
import google.registry.model.host.Host; import google.registry.model.host.Host;
import google.registry.model.tld.Registries; import google.registry.model.tld.Registries;
import google.registry.model.tld.Tld;
import google.registry.util.Clock; import google.registry.util.Clock;
import google.registry.util.Concurrent; import google.registry.util.Concurrent;
import google.registry.util.Retrier; import google.registry.util.Retrier;
@ -131,6 +133,7 @@ public class CloudDnsWriter extends BaseDnsWriter {
return; return;
} }
Tld tld = Tld.get(domain.get().getTld());
ImmutableSet.Builder<ResourceRecordSet> domainRecords = new ImmutableSet.Builder<>(); ImmutableSet.Builder<ResourceRecordSet> domainRecords = new ImmutableSet.Builder<>();
// Construct DS records (if any). // Construct DS records (if any).
@ -145,7 +148,7 @@ public class CloudDnsWriter extends BaseDnsWriter {
domainRecords.add( domainRecords.add(
new ResourceRecordSet() new ResourceRecordSet()
.setName(absoluteDomainName) .setName(absoluteDomainName)
.setTtl((int) defaultDsTtl.getStandardSeconds()) .setTtl((int) tld.getDnsDsTtl().orElse(defaultDsTtl).getStandardSeconds())
.setType("DS") .setType("DS")
.setKind("dns#resourceRecordSet") .setKind("dns#resourceRecordSet")
.setRrdatas(ImmutableList.copyOf(dsRrData))); .setRrdatas(ImmutableList.copyOf(dsRrData)));
@ -170,7 +173,7 @@ public class CloudDnsWriter extends BaseDnsWriter {
domainRecords.add( domainRecords.add(
new ResourceRecordSet() new ResourceRecordSet()
.setName(absoluteDomainName) .setName(absoluteDomainName)
.setTtl((int) defaultNsTtl.getStandardSeconds()) .setTtl((int) (tld.getDnsNsTtl().orElse(defaultNsTtl).getStandardSeconds()))
.setType("NS") .setType("NS")
.setKind("dns#resourceRecordSet") .setKind("dns#resourceRecordSet")
.setRrdatas(ImmutableList.copyOf(nsRrData))); .setRrdatas(ImmutableList.copyOf(nsRrData)));
@ -216,7 +219,7 @@ public class CloudDnsWriter extends BaseDnsWriter {
domainRecords.add( domainRecords.add(
new ResourceRecordSet() new ResourceRecordSet()
.setName(absoluteHostName) .setName(absoluteHostName)
.setTtl((int) defaultATtl.getStandardSeconds()) .setTtl((int) getDnsAPlusAAAATtlForHost(hostName, defaultATtl))
.setType("A") .setType("A")
.setKind("dns#resourceRecordSet") .setKind("dns#resourceRecordSet")
.setRrdatas(ImmutableList.copyOf(aRrData))); .setRrdatas(ImmutableList.copyOf(aRrData)));
@ -226,7 +229,7 @@ public class CloudDnsWriter extends BaseDnsWriter {
domainRecords.add( domainRecords.add(
new ResourceRecordSet() new ResourceRecordSet()
.setName(absoluteHostName) .setName(absoluteHostName)
.setTtl((int) defaultATtl.getStandardSeconds()) .setTtl((int) getDnsAPlusAAAATtlForHost(hostName, defaultATtl))
.setType("AAAA") .setType("AAAA")
.setKind("dns#resourceRecordSet") .setKind("dns#resourceRecordSet")
.setRrdatas(ImmutableList.copyOf(aaaaRrData))); .setRrdatas(ImmutableList.copyOf(aaaaRrData)));

View file

@ -18,6 +18,7 @@ import static com.google.common.base.Preconditions.checkState;
import static com.google.common.base.Verify.verify; import static com.google.common.base.Verify.verify;
import static com.google.common.collect.Sets.intersection; import static com.google.common.collect.Sets.intersection;
import static com.google.common.collect.Sets.union; import static com.google.common.collect.Sets.union;
import static google.registry.dns.DnsUtils.getDnsAPlusAAAATtlForHost;
import static google.registry.model.EppResourceUtils.loadByForeignKey; import static google.registry.model.EppResourceUtils.loadByForeignKey;
import com.google.common.base.Joiner; import com.google.common.base.Joiner;
@ -31,6 +32,7 @@ import google.registry.model.domain.Domain;
import google.registry.model.domain.secdns.DomainDsData; import google.registry.model.domain.secdns.DomainDsData;
import google.registry.model.host.Host; import google.registry.model.host.Host;
import google.registry.model.tld.Registries; import google.registry.model.tld.Registries;
import google.registry.model.tld.Tld;
import google.registry.util.Clock; import google.registry.util.Clock;
import java.io.IOException; import java.io.IOException;
import java.net.Inet4Address; import java.net.Inet4Address;
@ -185,12 +187,13 @@ public class DnsUpdateWriter extends BaseDnsWriter {
private RRset makeDelegationSignerSet(Domain domain) { private RRset makeDelegationSignerSet(Domain domain) {
RRset signerSet = new RRset(); RRset signerSet = new RRset();
Tld tld = Tld.get(domain.getTld());
for (DomainDsData signerData : domain.getDsData()) { for (DomainDsData signerData : domain.getDsData()) {
DSRecord dsRecord = DSRecord dsRecord =
new DSRecord( new DSRecord(
toAbsoluteName(domain.getDomainName()), toAbsoluteName(domain.getDomainName()),
DClass.IN, DClass.IN,
dnsDefaultDsTtl.getStandardSeconds(), tld.getDnsDsTtl().orElse(dnsDefaultDsTtl).getStandardSeconds(),
signerData.getKeyTag(), signerData.getKeyTag(),
signerData.getAlgorithm(), signerData.getAlgorithm(),
signerData.getDigestType(), signerData.getDigestType(),
@ -224,12 +227,13 @@ public class DnsUpdateWriter extends BaseDnsWriter {
private RRset makeNameServerSet(Domain domain) { private RRset makeNameServerSet(Domain domain) {
RRset nameServerSet = new RRset(); RRset nameServerSet = new RRset();
Tld tld = Tld.get(domain.getTld());
for (String hostName : domain.loadNameserverHostNames()) { for (String hostName : domain.loadNameserverHostNames()) {
NSRecord record = NSRecord record =
new NSRecord( new NSRecord(
toAbsoluteName(domain.getDomainName()), toAbsoluteName(domain.getDomainName()),
DClass.IN, DClass.IN,
dnsDefaultNsTtl.getStandardSeconds(), tld.getDnsNsTtl().orElse(dnsDefaultNsTtl).getStandardSeconds(),
toAbsoluteName(hostName)); toAbsoluteName(hostName));
nameServerSet.addRR(record); nameServerSet.addRR(record);
} }
@ -244,7 +248,7 @@ public class DnsUpdateWriter extends BaseDnsWriter {
new ARecord( new ARecord(
toAbsoluteName(host.getHostName()), toAbsoluteName(host.getHostName()),
DClass.IN, DClass.IN,
dnsDefaultATtl.getStandardSeconds(), getDnsAPlusAAAATtlForHost(host.getHostName(), dnsDefaultATtl),
address); address);
addressSet.addRR(record); addressSet.addRR(record);
} }
@ -260,7 +264,7 @@ public class DnsUpdateWriter extends BaseDnsWriter {
new AAAARecord( new AAAARecord(
toAbsoluteName(host.getHostName()), toAbsoluteName(host.getHostName()),
DClass.IN, DClass.IN,
dnsDefaultATtl.getStandardSeconds(), getDnsAPlusAAAATtlForHost(host.getHostName(), dnsDefaultATtl),
address); address);
addressSet.addRR(record); addressSet.addRR(record);
} }

View file

@ -671,18 +671,18 @@ public class Tld extends ImmutableObject implements Buildable, UnsafeSerializabl
} }
/** Returns the time to live for A and AAAA records. */ /** Returns the time to live for A and AAAA records. */
public Duration getDnsAPlusAaaaTtl() { public Optional<Duration> getDnsAPlusAaaaTtl() {
return dnsAPlusAaaaTtl; return Optional.ofNullable(dnsAPlusAaaaTtl);
} }
/** Returns the time to live for NS records. */ /** Returns the time to live for NS records. */
public Duration getDnsNsTtl() { public Optional<Duration> getDnsNsTtl() {
return dnsNsTtl; return Optional.ofNullable(dnsNsTtl);
} }
/** Returns the time to live for DS records. */ /** Returns the time to live for DS records. */
public Duration getDnsDsTtl() { public Optional<Duration> getDnsDsTtl() {
return dnsDsTtl; return Optional.ofNullable(dnsDsTtl);
} }
public ImmutableSet<String> getAllowedRegistrantContactIds() { public ImmutableSet<String> getAllowedRegistrantContactIds() {

View file

@ -31,6 +31,7 @@ import google.registry.gcs.GcsUtils;
import google.registry.model.domain.Domain; import google.registry.model.domain.Domain;
import google.registry.model.domain.secdns.DomainDsData; import google.registry.model.domain.secdns.DomainDsData;
import google.registry.model.host.Host; import google.registry.model.host.Host;
import google.registry.model.tld.Tld;
import google.registry.request.Action; import google.registry.request.Action;
import google.registry.request.HttpException.BadRequestException; import google.registry.request.HttpException.BadRequestException;
import google.registry.request.JsonActionRunner; import google.registry.request.JsonActionRunner;
@ -230,12 +231,13 @@ public class GenerateZoneFilesAction implements Runnable, JsonActionRunner.JsonA
private String domainStanza(Domain domain, DateTime exportTime) { private String domainStanza(Domain domain, DateTime exportTime) {
StringBuilder result = new StringBuilder(); StringBuilder result = new StringBuilder();
String domainLabel = stripTld(domain.getDomainName(), domain.getTld()); String domainLabel = stripTld(domain.getDomainName(), domain.getTld());
Tld tld = Tld.get(domain.getTld());
for (Host nameserver : tm().loadByKeys(domain.getNameservers()).values()) { for (Host nameserver : tm().loadByKeys(domain.getNameservers()).values()) {
result.append( result.append(
String.format( String.format(
NS_FORMAT, NS_FORMAT,
domainLabel, domainLabel,
dnsDefaultNsTtl.getStandardSeconds(), tld.getDnsNsTtl().orElse(dnsDefaultNsTtl).getStandardSeconds(),
// Load the nameservers at the export time in case they've been renamed or deleted. // Load the nameservers at the export time in case they've been renamed or deleted.
loadAtPointInTime(nameserver, exportTime).getHostName())); loadAtPointInTime(nameserver, exportTime).getHostName()));
} }
@ -244,7 +246,7 @@ public class GenerateZoneFilesAction implements Runnable, JsonActionRunner.JsonA
String.format( String.format(
DS_FORMAT, DS_FORMAT,
domainLabel, domainLabel,
dnsDefaultDsTtl.getStandardSeconds(), tld.getDnsDsTtl().orElse(dnsDefaultDsTtl).getStandardSeconds(),
dsData.getKeyTag(), dsData.getKeyTag(),
dsData.getAlgorithm(), dsData.getAlgorithm(),
dsData.getDigestType(), dsData.getDigestType(),
@ -265,16 +267,17 @@ public class GenerateZoneFilesAction implements Runnable, JsonActionRunner.JsonA
* } * }
* </pre> * </pre>
*/ */
private String hostStanza(Host host, String tld) { private String hostStanza(Host host, String tldStr) {
StringBuilder result = new StringBuilder(); StringBuilder result = new StringBuilder();
Tld tld = Tld.get(tldStr);
for (InetAddress addr : host.getInetAddresses()) { for (InetAddress addr : host.getInetAddresses()) {
// must be either IPv4 or IPv6 // must be either IPv4 or IPv6
String rrSetClass = (addr instanceof Inet4Address) ? "A" : "AAAA"; String rrSetClass = (addr instanceof Inet4Address) ? "A" : "AAAA";
result.append( result.append(
String.format( String.format(
A_FORMAT, A_FORMAT,
stripTld(host.getHostName(), tld), stripTld(host.getHostName(), tldStr),
dnsDefaultATtl.getStandardSeconds(), tld.getDnsAPlusAaaaTtl().orElse(dnsDefaultATtl).getStandardSeconds(),
rrSetClass, rrSetClass,
addr.getHostAddress())); addr.getHostAddress()));
} }

View file

@ -42,6 +42,7 @@ import google.registry.model.domain.Domain;
import google.registry.model.domain.secdns.DomainDsData; import google.registry.model.domain.secdns.DomainDsData;
import google.registry.model.eppcommon.StatusValue; import google.registry.model.eppcommon.StatusValue;
import google.registry.model.host.Host; import google.registry.model.host.Host;
import google.registry.model.tld.Tld;
import google.registry.persistence.VKey; import google.registry.persistence.VKey;
import google.registry.persistence.transaction.JpaTestExtensions; import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationTestExtension; import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationTestExtension;
@ -76,9 +77,6 @@ public class CloudDnsWriterTest {
private static final Inet4Address IPv4 = (Inet4Address) InetAddresses.forString("127.0.0.1"); private static final Inet4Address IPv4 = (Inet4Address) InetAddresses.forString("127.0.0.1");
private static final Inet6Address IPv6 = (Inet6Address) InetAddresses.forString("::1"); private static final Inet6Address IPv6 = (Inet6Address) InetAddresses.forString("::1");
private static final Duration DEFAULT_A_TTL = Duration.standardSeconds(11);
private static final Duration DEFAULT_NS_TTL = Duration.standardSeconds(222);
private static final Duration DEFAULT_DS_TTL = Duration.standardSeconds(3333);
@Mock private Dns dnsConnection; @Mock private Dns dnsConnection;
@Mock private Dns.ResourceRecordSets resourceRecordSets; @Mock private Dns.ResourceRecordSets resourceRecordSets;
@ -119,14 +117,21 @@ public class CloudDnsWriterTest {
@BeforeEach @BeforeEach
void beforeEach() throws Exception { void beforeEach() throws Exception {
createTld("tld"); createTld("tld");
persistResource(
Tld.get("tld")
.asBuilder()
.setDnsAPlusAaaaTtl(Duration.standardSeconds(11))
.setDnsNsTtl(Duration.standardSeconds(222))
.setDnsDsTtl(Duration.standardSeconds(3333))
.build());
writer = writer =
new CloudDnsWriter( new CloudDnsWriter(
dnsConnection, dnsConnection,
"projectId", "projectId",
"triple.secret.tld", // used by testInvalidZoneNames() "triple.secret.tld", // used by testInvalidZoneNames()
DEFAULT_A_TTL, Duration.ZERO,
DEFAULT_NS_TTL, Duration.ZERO,
DEFAULT_DS_TTL, Duration.ZERO,
RateLimiter.create(20), RateLimiter.create(20),
10, // max num threads 10, // max num threads
new SystemClock(), new SystemClock(),
@ -383,6 +388,40 @@ public class CloudDnsWriterTest {
verifyZone(fakeDomainRecords("example.tld", 0, 1, 0, 0)); verifyZone(fakeDomainRecords("example.tld", 0, 1, 0, 0));
} }
@Test
void testLoadDomain_defaultTtls() {
persistResource(
Tld.get("tld")
.asBuilder()
.setDnsAPlusAaaaTtl(null)
.setDnsNsTtl(null)
.setDnsDsTtl(null)
.build());
writer =
new CloudDnsWriter(
dnsConnection,
"projectId",
"triple.secret.tld",
Duration.standardSeconds(11),
Duration.standardSeconds(222),
Duration.standardSeconds(3333),
RateLimiter.create(20),
10,
new SystemClock(),
new Retrier(new SystemSleeper(), 5));
persistResource(
fakeDomain(
"example.tld",
ImmutableSet.of(persistResource(fakeHost("0.ip6.example.tld", IPv6))),
0)
.asBuilder()
.addSubordinateHost("0.ip6.example.tld")
.build());
writer.publishDomain("example.tld");
verifyZone(fakeDomainRecords("example.tld", 0, 1, 0, 0));
}
@Test @Test
void testLoadDomain_withNameserveThatEndsWithDomainName() { void testLoadDomain_withNameserveThatEndsWithDomainName() {
persistResource( persistResource(

View file

@ -39,6 +39,7 @@ import google.registry.model.domain.Domain;
import google.registry.model.domain.secdns.DomainDsData; import google.registry.model.domain.secdns.DomainDsData;
import google.registry.model.eppcommon.StatusValue; import google.registry.model.eppcommon.StatusValue;
import google.registry.model.host.Host; import google.registry.model.host.Host;
import google.registry.model.tld.Tld;
import google.registry.persistence.transaction.JpaTestExtensions; import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationTestExtension; import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationTestExtension;
import google.registry.testing.DatabaseHelper; import google.registry.testing.DatabaseHelper;
@ -110,7 +111,13 @@ public class DnsUpdateWriterTest {
Update update = updateCaptor.getValue(); Update update = updateCaptor.getValue();
assertThatUpdatedZoneIs(update, "tld."); assertThatUpdatedZoneIs(update, "tld.");
assertThatUpdateDeletes(update, "example.tld.", Type.ANY); assertThatUpdateDeletes(update, "example.tld.", Type.ANY);
assertThatUpdateAdds(update, "example.tld.", Type.NS, "ns1.example.tld.", "ns2.example.tld."); assertThatUpdateAdds(
update,
"example.tld.",
Type.NS,
Duration.ZERO.getStandardSeconds(),
"ns1.example.tld.",
"ns2.example.tld.");
assertThatTotalUpdateSetsIs(update, 2); // The delete and NS sets assertThatTotalUpdateSetsIs(update, 2); // The delete and NS sets
} }
@ -166,13 +173,15 @@ public class DnsUpdateWriterTest {
assertThatUpdatedZoneIs(update, "tld."); assertThatUpdatedZoneIs(update, "tld.");
assertThatUpdateDeletes(update, "example1.tld.", Type.ANY); assertThatUpdateDeletes(update, "example1.tld.", Type.ANY);
assertThatUpdateDeletes(update, "example2.tld.", Type.ANY); assertThatUpdateDeletes(update, "example2.tld.", Type.ANY);
assertThatUpdateAdds(update, "example1.tld.", Type.NS, "ns.example1.tld."); assertThatUpdateAdds(
assertThatUpdateAdds(update, "example2.tld.", Type.NS, "ns.example2.tld."); update, "example1.tld.", Type.NS, Duration.ZERO.getStandardSeconds(), "ns.example1.tld.");
assertThatUpdateAdds(
update, "example2.tld.", Type.NS, Duration.ZERO.getStandardSeconds(), "ns.example2.tld.");
assertThatTotalUpdateSetsIs(update, 4); // The delete and NS sets for each TLD assertThatTotalUpdateSetsIs(update, 4); // The delete and NS sets for each TLD
} }
@Test @Test
void testPublishDomainCreate_publishesDelegationSigner() throws Exception { void testPublishDomainCreate_publishesDelegationSigner_usesDefaultTtl() throws Exception {
Domain domain = Domain domain =
persistActiveDomain("example.tld") persistActiveDomain("example.tld")
.asBuilder() .asBuilder()
@ -189,8 +198,53 @@ public class DnsUpdateWriterTest {
Update update = updateCaptor.getValue(); Update update = updateCaptor.getValue();
assertThatUpdatedZoneIs(update, "tld."); assertThatUpdatedZoneIs(update, "tld.");
assertThatUpdateDeletes(update, "example.tld.", Type.ANY); assertThatUpdateDeletes(update, "example.tld.", Type.ANY);
assertThatUpdateAdds(update, "example.tld.", Type.NS, "ns1.example.tld."); assertThatUpdateAdds(
assertThatUpdateAdds(update, "example.tld.", Type.DS, "1 3 1 0123456789ABCDEF"); update, "example.tld.", Type.NS, Duration.ZERO.getStandardSeconds(), "ns1.example.tld.");
assertThatUpdateAdds(
update,
"example.tld.",
Type.DS,
Duration.ZERO.getStandardSeconds(),
"1 3 1 0123456789ABCDEF");
assertThatTotalUpdateSetsIs(update, 3); // The delete, the NS, and DS sets
}
@Test
void testPublishDomainCreate_publishesDelegationSigner_usesTldConfiguredTtl() throws Exception {
persistResource(
Tld.get("tld")
.asBuilder()
.setDnsNsTtl(Duration.millis(500))
.setDnsDsTtl(Duration.millis(400))
.build());
Domain domain =
persistActiveDomain("example.tld")
.asBuilder()
.setNameservers(ImmutableSet.of(persistActiveHost("ns1.example.tld").createVKey()))
.setDsData(
ImmutableSet.of(DomainDsData.create(1, 3, 1, base16().decode("0123456789ABCDEF"))))
.build();
persistResource(domain);
writer.publishDomain("example.tld");
writer.commit();
verify(mockResolver).send(updateCaptor.capture());
Update update = updateCaptor.getValue();
assertThatUpdatedZoneIs(update, "tld.");
assertThatUpdateDeletes(update, "example.tld.", Type.ANY);
assertThatUpdateAdds(
update,
"example.tld.",
Type.NS,
Duration.millis(500).getStandardSeconds(),
"ns1.example.tld.");
assertThatUpdateAdds(
update,
"example.tld.",
Type.DS,
Duration.millis(400).getStandardSeconds(),
"1 3 1 0123456789ABCDEF");
assertThatTotalUpdateSetsIs(update, 3); // The delete, the NS, and DS sets assertThatTotalUpdateSetsIs(update, 3); // The delete, the NS, and DS sets
} }
@ -229,7 +283,7 @@ public class DnsUpdateWriterTest {
} }
@Test @Test
void testPublishHostCreate_publishesAddressRecords() throws Exception { void testPublishHostCreate_publishesAddressRecords_usesDefaultTtl() throws Exception {
Host host = Host host =
persistResource( persistResource(
newHost("ns1.example.tld") newHost("ns1.example.tld")
@ -255,9 +309,76 @@ public class DnsUpdateWriterTest {
assertThatUpdatedZoneIs(update, "tld."); assertThatUpdatedZoneIs(update, "tld.");
assertThatUpdateDeletes(update, "example.tld.", Type.ANY); assertThatUpdateDeletes(update, "example.tld.", Type.ANY);
assertThatUpdateDeletes(update, "ns1.example.tld.", Type.ANY); assertThatUpdateDeletes(update, "ns1.example.tld.", Type.ANY);
assertThatUpdateAdds(update, "ns1.example.tld.", Type.A, "10.0.0.1", "10.1.0.1"); assertThatUpdateAdds(
assertThatUpdateAdds(update, "ns1.example.tld.", Type.AAAA, "fd0e:a5c8:6dfb:6a5e:0:0:0:1"); update,
assertThatUpdateAdds(update, "example.tld.", Type.NS, "ns1.example.tld."); "ns1.example.tld.",
Type.A,
Duration.ZERO.getStandardSeconds(),
"10.0.0.1",
"10.1.0.1");
assertThatUpdateAdds(
update,
"ns1.example.tld.",
Type.AAAA,
Duration.ZERO.getStandardSeconds(),
"fd0e:a5c8:6dfb:6a5e:0:0:0:1");
assertThatUpdateAdds(
update, "example.tld.", Type.NS, Duration.ZERO.getStandardSeconds(), "ns1.example.tld.");
assertThatTotalUpdateSetsIs(update, 5);
}
@Test
void testPublishHostCreate_publishesAddressRecords_usesTldConfiguredTtl() throws Exception {
persistResource(
Tld.get("tld")
.asBuilder()
.setDnsAPlusAaaaTtl(Duration.millis(500))
.setDnsNsTtl(Duration.millis(400))
.build());
Host host =
persistResource(
newHost("ns1.example.tld")
.asBuilder()
.setInetAddresses(
ImmutableSet.of(
InetAddresses.forString("10.0.0.1"),
InetAddresses.forString("10.1.0.1"),
InetAddresses.forString("fd0e:a5c8:6dfb:6a5e:0:0:0:1")))
.build());
persistResource(
DatabaseHelper.newDomain("example.tld")
.asBuilder()
.addSubordinateHost("ns1.example.tld")
.addNameserver(host.createVKey())
.build());
writer.publishHost("ns1.example.tld");
writer.commit();
verify(mockResolver).send(updateCaptor.capture());
Update update = updateCaptor.getValue();
assertThatUpdatedZoneIs(update, "tld.");
assertThatUpdateDeletes(update, "example.tld.", Type.ANY);
assertThatUpdateDeletes(update, "ns1.example.tld.", Type.ANY);
assertThatUpdateAdds(
update,
"ns1.example.tld.",
Type.A,
Duration.millis(500).getStandardSeconds(),
"10.0.0.1",
"10.1.0.1");
assertThatUpdateAdds(
update,
"ns1.example.tld.",
Type.AAAA,
Duration.millis(500).getStandardSeconds(),
"fd0e:a5c8:6dfb:6a5e:0:0:0:1");
assertThatUpdateAdds(
update,
"example.tld.",
Type.NS,
Duration.millis(400).getStandardSeconds(),
"ns1.example.tld.");
assertThatTotalUpdateSetsIs(update, 5); assertThatTotalUpdateSetsIs(update, 5);
} }
@ -294,7 +415,8 @@ public class DnsUpdateWriterTest {
assertThatUpdatedZoneIs(update, "tld."); assertThatUpdatedZoneIs(update, "tld.");
assertThatUpdateDeletes(update, "example.tld.", Type.ANY); assertThatUpdateDeletes(update, "example.tld.", Type.ANY);
assertThatUpdateDeletes(update, "ns1.example.tld.", Type.ANY); assertThatUpdateDeletes(update, "ns1.example.tld.", Type.ANY);
assertThatUpdateAdds(update, "example.tld.", Type.NS, "ns1.example.com."); assertThatUpdateAdds(
update, "example.tld.", Type.NS, Duration.ZERO.getStandardSeconds(), "ns1.example.com.");
assertThatTotalUpdateSetsIs(update, 3); assertThatTotalUpdateSetsIs(update, 3);
} }
@ -329,9 +451,26 @@ public class DnsUpdateWriterTest {
assertThatUpdatedZoneIs(update, "tld."); assertThatUpdatedZoneIs(update, "tld.");
assertThatUpdateDeletes(update, "example.tld.", Type.ANY); assertThatUpdateDeletes(update, "example.tld.", Type.ANY);
assertThatUpdateDeletes(update, "ns1.example.tld.", Type.ANY); assertThatUpdateDeletes(update, "ns1.example.tld.", Type.ANY);
assertThatUpdateAdds(update, "example.tld.", Type.NS, "ns1.example.com.", "ns1.example.tld."); assertThatUpdateAdds(
assertThatUpdateAdds(update, "ns1.example.tld.", Type.A, "10.0.0.1", "10.1.0.1"); update,
assertThatUpdateAdds(update, "ns1.example.tld.", Type.AAAA, "fd0e:a5c8:6dfb:6a5e:0:0:0:1"); "example.tld.",
Type.NS,
Duration.ZERO.getStandardSeconds(),
"ns1.example.com.",
"ns1.example.tld.");
assertThatUpdateAdds(
update,
"ns1.example.tld.",
Type.A,
Duration.ZERO.getStandardSeconds(),
"10.0.0.1",
"10.1.0.1");
assertThatUpdateAdds(
update,
"ns1.example.tld.",
Type.AAAA,
Duration.ZERO.getStandardSeconds(),
"fd0e:a5c8:6dfb:6a5e:0:0:0:1");
assertThatTotalUpdateSetsIs(update, 5); assertThatTotalUpdateSetsIs(update, 5);
} }
@ -365,9 +504,21 @@ public class DnsUpdateWriterTest {
assertThatUpdateDeletes(update, "example.tld.", Type.ANY); assertThatUpdateDeletes(update, "example.tld.", Type.ANY);
assertThatUpdateDeletes(update, "ns1.example.tld.", Type.ANY); assertThatUpdateDeletes(update, "ns1.example.tld.", Type.ANY);
assertThatUpdateDeletes(update, "foo.example.tld.", Type.ANY); assertThatUpdateDeletes(update, "foo.example.tld.", Type.ANY);
assertThatUpdateAdds(update, "example.tld.", Type.NS, "ns1.example.tld."); assertThatUpdateAdds(
assertThatUpdateAdds(update, "ns1.example.tld.", Type.A, "10.0.0.1", "10.1.0.1"); update, "example.tld.", Type.NS, Duration.ZERO.getStandardSeconds(), "ns1.example.tld.");
assertThatUpdateAdds(update, "ns1.example.tld.", Type.AAAA, "fd0e:a5c8:6dfb:6a5e:0:0:0:1"); assertThatUpdateAdds(
update,
"ns1.example.tld.",
Type.A,
Duration.ZERO.getStandardSeconds(),
"10.0.0.1",
"10.1.0.1");
assertThatUpdateAdds(
update,
"ns1.example.tld.",
Type.AAAA,
Duration.ZERO.getStandardSeconds(),
"fd0e:a5c8:6dfb:6a5e:0:0:0:1");
assertThatTotalUpdateSetsIs(update, 6); assertThatTotalUpdateSetsIs(update, 6);
} }
@ -430,13 +581,14 @@ public class DnsUpdateWriterTest {
} }
private static void assertThatUpdateAdds( private static void assertThatUpdateAdds(
Update update, String resourceName, int recordType, String... resourceData) { Update update, String resourceName, int recordType, Long ttl, String... resourceData) {
ArrayList<String> expectedData = new ArrayList<>(); ArrayList<String> expectedData = new ArrayList<>();
Collections.addAll(expectedData, resourceData); Collections.addAll(expectedData, resourceData);
ArrayList<String> actualData = new ArrayList<>(); ArrayList<String> actualData = new ArrayList<>();
for (Record record : findUpdateRecords(update, resourceName, recordType)) { for (Record record : findUpdateRecords(update, resourceName, recordType)) {
actualData.add(record.rdataToString()); actualData.add(record.rdataToString());
assertThat(record.getTTL()).isEqualTo(ttl);
} }
assertThat(actualData).containsExactlyElementsIn(expectedData); assertThat(actualData).containsExactlyElementsIn(expectedData);
} }

View file

@ -87,9 +87,9 @@ class CreateTldCommandTest extends CommandTestCase<CreateTldCommand> {
"--dns_ns_ttl=PT180S"); "--dns_ns_ttl=PT180S");
Tld registry = Tld.get("xn--q9jyb4c"); Tld registry = Tld.get("xn--q9jyb4c");
assertThat(registry).isNotNull(); assertThat(registry).isNotNull();
assertThat(registry.getDnsAPlusAaaaTtl()).isEqualTo(standardMinutes(5)); assertThat(registry.getDnsAPlusAaaaTtl().get()).isEqualTo(standardMinutes(5));
assertThat(registry.getDnsDsTtl()).isEqualTo(standardMinutes(4)); assertThat(registry.getDnsDsTtl().get()).isEqualTo(standardMinutes(4));
assertThat(registry.getDnsNsTtl()).isEqualTo(standardMinutes(3)); assertThat(registry.getDnsNsTtl().get()).isEqualTo(standardMinutes(3));
} }
@Test @Test

View file

@ -1111,10 +1111,10 @@ class UpdateTldCommandTest extends CommandTestCase<UpdateTldCommand> {
"--dns_ds_ttl=PT240S", "--dns_ds_ttl=PT240S",
"--dns_ns_ttl=PT180S", "--dns_ns_ttl=PT180S",
"xn--q9jyb4c"); "xn--q9jyb4c");
Tld registry = Tld.get("xn--q9jyb4c"); Tld tld = Tld.get("xn--q9jyb4c");
assertThat(registry.getDnsAPlusAaaaTtl()).isEqualTo(standardMinutes(5)); assertThat(tld.getDnsAPlusAaaaTtl().get()).isEqualTo(standardMinutes(5));
assertThat(registry.getDnsDsTtl()).isEqualTo(standardMinutes(4)); assertThat(tld.getDnsDsTtl().get()).isEqualTo(standardMinutes(4));
assertThat(registry.getDnsNsTtl()).isEqualTo(standardMinutes(3)); assertThat(tld.getDnsNsTtl().get()).isEqualTo(standardMinutes(3));
} }
private void runSuccessfulReservedListsTest(String reservedLists) throws Exception { private void runSuccessfulReservedListsTest(String reservedLists) throws Exception {

View file

@ -35,6 +35,7 @@ import google.registry.gcs.GcsUtils;
import google.registry.model.domain.secdns.DomainDsData; import google.registry.model.domain.secdns.DomainDsData;
import google.registry.model.eppcommon.StatusValue; import google.registry.model.eppcommon.StatusValue;
import google.registry.model.host.Host; import google.registry.model.host.Host;
import google.registry.model.tld.Tld;
import google.registry.persistence.VKey; import google.registry.persistence.VKey;
import google.registry.persistence.transaction.JpaTestExtensions; import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationTestExtension; import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationTestExtension;
@ -58,9 +59,26 @@ class GenerateZoneFilesActionTest {
private final GcsUtils gcsUtils = new GcsUtils(LocalStorageHelper.getOptions()); private final GcsUtils gcsUtils = new GcsUtils(LocalStorageHelper.getOptions());
@Test @Test
void testGenerate() throws Exception { void testGenerate_defaultTtls() throws Exception {
DateTime now = DateTime.now(DateTimeZone.UTC).withTimeAtStartOfDay();
createTlds("tld", "com"); createTlds("tld", "com");
testGenerate("tld.zone");
}
@Test
void testGenerate_customTldTtls() throws Exception {
createTlds("tld", "com");
persistResource(
Tld.get("tld")
.asBuilder()
.setDnsAPlusAaaaTtl(Duration.standardSeconds(300))
.setDnsNsTtl(Duration.standardSeconds(400))
.setDnsDsTtl(Duration.standardSeconds(500))
.build());
testGenerate("tldCustomTtl.zone");
}
void testGenerate(String goldenFileName) throws Exception {
DateTime now = DateTime.now(DateTimeZone.UTC).withTimeAtStartOfDay();
ImmutableSet<InetAddress> ips = ImmutableSet<InetAddress> ips =
ImmutableSet.of(InetAddress.getByName("127.0.0.1"), InetAddress.getByName("::1")); ImmutableSet.of(InetAddress.getByName("127.0.0.1"), InetAddress.getByName("::1"));
@ -145,7 +163,7 @@ class GenerateZoneFilesActionTest {
// files with literal tabs irritate our build tools. // files with literal tabs irritate our build tools.
Splitter splitter = Splitter.on('\n').omitEmptyStrings(); Splitter splitter = Splitter.on('\n').omitEmptyStrings();
Iterable<String> generatedFileLines = splitter.split(generatedFile.replaceAll("\t", " ")); Iterable<String> generatedFileLines = splitter.split(generatedFile.replaceAll("\t", " "));
Iterable<String> goldenFileLines = splitter.split(loadFile(getClass(), "tld.zone")); Iterable<String> goldenFileLines = splitter.split(loadFile(getClass(), goldenFileName));
// The first line needs to be the same as the golden file. // The first line needs to be the same as the golden file.
assertThat(generatedFileLines.iterator().next()).isEqualTo(goldenFileLines.iterator().next()); assertThat(generatedFileLines.iterator().next()).isEqualTo(goldenFileLines.iterator().next());
// The remaining lines can be in any order. // The remaining lines can be in any order.

View file

@ -0,0 +1,14 @@
$ORIGIN tld.
bar 400 IN NS ns.bar.tld.
bar 400 IN NS ns.foo.tld.
ns.bar 300 IN A 127.0.0.1
ns.bar 300 IN AAAA 0:0:0:0:0:0:0:1
ns-only 400 IN NS ns.foo.tld.
ns-only 400 IN NS ns.bar.tld.
ns-and-ds 400 IN NS ns.foo.tld.
ns-and-ds 400 IN NS ns.bar.tld.
ns-and-ds 500 IN DS 1 2 3 000102