diff --git a/core/src/main/java/google/registry/dns/DnsUtils.java b/core/src/main/java/google/registry/dns/DnsUtils.java index eda0ba2a5..bb3b5f62e 100644 --- a/core/src/main/java/google/registry/dns/DnsUtils.java +++ b/core/src/main/java/google/registry/dns/DnsUtils.java @@ -24,7 +24,9 @@ import google.registry.model.common.DatabaseMigrationStateSchedule; import google.registry.model.common.DatabaseMigrationStateSchedule.MigrationState; import google.registry.model.common.DnsRefreshRequest; import google.registry.model.tld.Registries; +import google.registry.model.tld.Tld; import java.util.Collection; +import java.util.Optional; import javax.inject.Inject; import org.joda.time.DateTime; import org.joda.time.Duration; @@ -126,6 +128,18 @@ public class DnsUtils { .collect(toImmutableList()))); } + public static long getDnsAPlusAAAATtlForHost(String host, Duration dnsDefaultATtl) { + Optional 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() { return !DatabaseMigrationStateSchedule.getValueAtTime(dnsQueue.getClock().nowUtc()) .equals(MigrationState.DNS_SQL); diff --git a/core/src/main/java/google/registry/dns/writer/clouddns/CloudDnsWriter.java b/core/src/main/java/google/registry/dns/writer/clouddns/CloudDnsWriter.java index 444c540aa..2f9b58908 100644 --- a/core/src/main/java/google/registry/dns/writer/clouddns/CloudDnsWriter.java +++ b/core/src/main/java/google/registry/dns/writer/clouddns/CloudDnsWriter.java @@ -16,6 +16,7 @@ package google.registry.dns.writer.clouddns; import static com.google.common.base.Preconditions.checkArgument; 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.util.DomainNameUtils.getSecondLevelDomain; @@ -40,6 +41,7 @@ import google.registry.model.domain.Domain; import google.registry.model.domain.secdns.DomainDsData; import google.registry.model.host.Host; import google.registry.model.tld.Registries; +import google.registry.model.tld.Tld; import google.registry.util.Clock; import google.registry.util.Concurrent; import google.registry.util.Retrier; @@ -131,6 +133,7 @@ public class CloudDnsWriter extends BaseDnsWriter { return; } + Tld tld = Tld.get(domain.get().getTld()); ImmutableSet.Builder domainRecords = new ImmutableSet.Builder<>(); // Construct DS records (if any). @@ -145,7 +148,7 @@ public class CloudDnsWriter extends BaseDnsWriter { domainRecords.add( new ResourceRecordSet() .setName(absoluteDomainName) - .setTtl((int) defaultDsTtl.getStandardSeconds()) + .setTtl((int) tld.getDnsDsTtl().orElse(defaultDsTtl).getStandardSeconds()) .setType("DS") .setKind("dns#resourceRecordSet") .setRrdatas(ImmutableList.copyOf(dsRrData))); @@ -170,7 +173,7 @@ public class CloudDnsWriter extends BaseDnsWriter { domainRecords.add( new ResourceRecordSet() .setName(absoluteDomainName) - .setTtl((int) defaultNsTtl.getStandardSeconds()) + .setTtl((int) (tld.getDnsNsTtl().orElse(defaultNsTtl).getStandardSeconds())) .setType("NS") .setKind("dns#resourceRecordSet") .setRrdatas(ImmutableList.copyOf(nsRrData))); @@ -216,7 +219,7 @@ public class CloudDnsWriter extends BaseDnsWriter { domainRecords.add( new ResourceRecordSet() .setName(absoluteHostName) - .setTtl((int) defaultATtl.getStandardSeconds()) + .setTtl((int) getDnsAPlusAAAATtlForHost(hostName, defaultATtl)) .setType("A") .setKind("dns#resourceRecordSet") .setRrdatas(ImmutableList.copyOf(aRrData))); @@ -226,7 +229,7 @@ public class CloudDnsWriter extends BaseDnsWriter { domainRecords.add( new ResourceRecordSet() .setName(absoluteHostName) - .setTtl((int) defaultATtl.getStandardSeconds()) + .setTtl((int) getDnsAPlusAAAATtlForHost(hostName, defaultATtl)) .setType("AAAA") .setKind("dns#resourceRecordSet") .setRrdatas(ImmutableList.copyOf(aaaaRrData))); diff --git a/core/src/main/java/google/registry/dns/writer/dnsupdate/DnsUpdateWriter.java b/core/src/main/java/google/registry/dns/writer/dnsupdate/DnsUpdateWriter.java index f5d9f2910..e02f9142c 100644 --- a/core/src/main/java/google/registry/dns/writer/dnsupdate/DnsUpdateWriter.java +++ b/core/src/main/java/google/registry/dns/writer/dnsupdate/DnsUpdateWriter.java @@ -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.collect.Sets.intersection; import static com.google.common.collect.Sets.union; +import static google.registry.dns.DnsUtils.getDnsAPlusAAAATtlForHost; import static google.registry.model.EppResourceUtils.loadByForeignKey; 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.host.Host; import google.registry.model.tld.Registries; +import google.registry.model.tld.Tld; import google.registry.util.Clock; import java.io.IOException; import java.net.Inet4Address; @@ -185,12 +187,13 @@ public class DnsUpdateWriter extends BaseDnsWriter { private RRset makeDelegationSignerSet(Domain domain) { RRset signerSet = new RRset(); + Tld tld = Tld.get(domain.getTld()); for (DomainDsData signerData : domain.getDsData()) { DSRecord dsRecord = new DSRecord( toAbsoluteName(domain.getDomainName()), DClass.IN, - dnsDefaultDsTtl.getStandardSeconds(), + tld.getDnsDsTtl().orElse(dnsDefaultDsTtl).getStandardSeconds(), signerData.getKeyTag(), signerData.getAlgorithm(), signerData.getDigestType(), @@ -224,12 +227,13 @@ public class DnsUpdateWriter extends BaseDnsWriter { private RRset makeNameServerSet(Domain domain) { RRset nameServerSet = new RRset(); + Tld tld = Tld.get(domain.getTld()); for (String hostName : domain.loadNameserverHostNames()) { NSRecord record = new NSRecord( toAbsoluteName(domain.getDomainName()), DClass.IN, - dnsDefaultNsTtl.getStandardSeconds(), + tld.getDnsNsTtl().orElse(dnsDefaultNsTtl).getStandardSeconds(), toAbsoluteName(hostName)); nameServerSet.addRR(record); } @@ -244,7 +248,7 @@ public class DnsUpdateWriter extends BaseDnsWriter { new ARecord( toAbsoluteName(host.getHostName()), DClass.IN, - dnsDefaultATtl.getStandardSeconds(), + getDnsAPlusAAAATtlForHost(host.getHostName(), dnsDefaultATtl), address); addressSet.addRR(record); } @@ -260,7 +264,7 @@ public class DnsUpdateWriter extends BaseDnsWriter { new AAAARecord( toAbsoluteName(host.getHostName()), DClass.IN, - dnsDefaultATtl.getStandardSeconds(), + getDnsAPlusAAAATtlForHost(host.getHostName(), dnsDefaultATtl), address); addressSet.addRR(record); } diff --git a/core/src/main/java/google/registry/model/tld/Tld.java b/core/src/main/java/google/registry/model/tld/Tld.java index e115658f6..00751e971 100644 --- a/core/src/main/java/google/registry/model/tld/Tld.java +++ b/core/src/main/java/google/registry/model/tld/Tld.java @@ -671,18 +671,18 @@ public class Tld extends ImmutableObject implements Buildable, UnsafeSerializabl } /** Returns the time to live for A and AAAA records. */ - public Duration getDnsAPlusAaaaTtl() { - return dnsAPlusAaaaTtl; + public Optional getDnsAPlusAaaaTtl() { + return Optional.ofNullable(dnsAPlusAaaaTtl); } /** Returns the time to live for NS records. */ - public Duration getDnsNsTtl() { - return dnsNsTtl; + public Optional getDnsNsTtl() { + return Optional.ofNullable(dnsNsTtl); } /** Returns the time to live for DS records. */ - public Duration getDnsDsTtl() { - return dnsDsTtl; + public Optional getDnsDsTtl() { + return Optional.ofNullable(dnsDsTtl); } public ImmutableSet getAllowedRegistrantContactIds() { diff --git a/core/src/main/java/google/registry/tools/server/GenerateZoneFilesAction.java b/core/src/main/java/google/registry/tools/server/GenerateZoneFilesAction.java index 6d9a42aac..d8d5bef48 100644 --- a/core/src/main/java/google/registry/tools/server/GenerateZoneFilesAction.java +++ b/core/src/main/java/google/registry/tools/server/GenerateZoneFilesAction.java @@ -31,6 +31,7 @@ import google.registry.gcs.GcsUtils; import google.registry.model.domain.Domain; import google.registry.model.domain.secdns.DomainDsData; import google.registry.model.host.Host; +import google.registry.model.tld.Tld; import google.registry.request.Action; import google.registry.request.HttpException.BadRequestException; import google.registry.request.JsonActionRunner; @@ -230,12 +231,13 @@ public class GenerateZoneFilesAction implements Runnable, JsonActionRunner.JsonA private String domainStanza(Domain domain, DateTime exportTime) { StringBuilder result = new StringBuilder(); String domainLabel = stripTld(domain.getDomainName(), domain.getTld()); + Tld tld = Tld.get(domain.getTld()); for (Host nameserver : tm().loadByKeys(domain.getNameservers()).values()) { result.append( String.format( NS_FORMAT, domainLabel, - dnsDefaultNsTtl.getStandardSeconds(), + tld.getDnsNsTtl().orElse(dnsDefaultNsTtl).getStandardSeconds(), // Load the nameservers at the export time in case they've been renamed or deleted. loadAtPointInTime(nameserver, exportTime).getHostName())); } @@ -244,7 +246,7 @@ public class GenerateZoneFilesAction implements Runnable, JsonActionRunner.JsonA String.format( DS_FORMAT, domainLabel, - dnsDefaultDsTtl.getStandardSeconds(), + tld.getDnsDsTtl().orElse(dnsDefaultDsTtl).getStandardSeconds(), dsData.getKeyTag(), dsData.getAlgorithm(), dsData.getDigestType(), @@ -265,16 +267,17 @@ public class GenerateZoneFilesAction implements Runnable, JsonActionRunner.JsonA * } * */ - private String hostStanza(Host host, String tld) { + private String hostStanza(Host host, String tldStr) { StringBuilder result = new StringBuilder(); + Tld tld = Tld.get(tldStr); for (InetAddress addr : host.getInetAddresses()) { // must be either IPv4 or IPv6 String rrSetClass = (addr instanceof Inet4Address) ? "A" : "AAAA"; result.append( String.format( A_FORMAT, - stripTld(host.getHostName(), tld), - dnsDefaultATtl.getStandardSeconds(), + stripTld(host.getHostName(), tldStr), + tld.getDnsAPlusAaaaTtl().orElse(dnsDefaultATtl).getStandardSeconds(), rrSetClass, addr.getHostAddress())); } diff --git a/core/src/test/java/google/registry/dns/writer/clouddns/CloudDnsWriterTest.java b/core/src/test/java/google/registry/dns/writer/clouddns/CloudDnsWriterTest.java index c582b8e81..dbcf4b59a 100644 --- a/core/src/test/java/google/registry/dns/writer/clouddns/CloudDnsWriterTest.java +++ b/core/src/test/java/google/registry/dns/writer/clouddns/CloudDnsWriterTest.java @@ -42,6 +42,7 @@ import google.registry.model.domain.Domain; import google.registry.model.domain.secdns.DomainDsData; import google.registry.model.eppcommon.StatusValue; import google.registry.model.host.Host; +import google.registry.model.tld.Tld; import google.registry.persistence.VKey; import google.registry.persistence.transaction.JpaTestExtensions; 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 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.ResourceRecordSets resourceRecordSets; @@ -119,14 +117,21 @@ public class CloudDnsWriterTest { @BeforeEach void beforeEach() throws Exception { createTld("tld"); + persistResource( + Tld.get("tld") + .asBuilder() + .setDnsAPlusAaaaTtl(Duration.standardSeconds(11)) + .setDnsNsTtl(Duration.standardSeconds(222)) + .setDnsDsTtl(Duration.standardSeconds(3333)) + .build()); writer = new CloudDnsWriter( dnsConnection, "projectId", "triple.secret.tld", // used by testInvalidZoneNames() - DEFAULT_A_TTL, - DEFAULT_NS_TTL, - DEFAULT_DS_TTL, + Duration.ZERO, + Duration.ZERO, + Duration.ZERO, RateLimiter.create(20), 10, // max num threads new SystemClock(), @@ -383,6 +388,40 @@ public class CloudDnsWriterTest { 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 void testLoadDomain_withNameserveThatEndsWithDomainName() { persistResource( diff --git a/core/src/test/java/google/registry/dns/writer/dnsupdate/DnsUpdateWriterTest.java b/core/src/test/java/google/registry/dns/writer/dnsupdate/DnsUpdateWriterTest.java index c763ec68a..cdc0f16bb 100644 --- a/core/src/test/java/google/registry/dns/writer/dnsupdate/DnsUpdateWriterTest.java +++ b/core/src/test/java/google/registry/dns/writer/dnsupdate/DnsUpdateWriterTest.java @@ -39,6 +39,7 @@ import google.registry.model.domain.Domain; import google.registry.model.domain.secdns.DomainDsData; import google.registry.model.eppcommon.StatusValue; import google.registry.model.host.Host; +import google.registry.model.tld.Tld; import google.registry.persistence.transaction.JpaTestExtensions; import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationTestExtension; import google.registry.testing.DatabaseHelper; @@ -110,7 +111,13 @@ public class DnsUpdateWriterTest { Update update = updateCaptor.getValue(); assertThatUpdatedZoneIs(update, "tld."); 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 } @@ -166,13 +173,15 @@ public class DnsUpdateWriterTest { assertThatUpdatedZoneIs(update, "tld."); assertThatUpdateDeletes(update, "example1.tld.", Type.ANY); assertThatUpdateDeletes(update, "example2.tld.", Type.ANY); - assertThatUpdateAdds(update, "example1.tld.", Type.NS, "ns.example1.tld."); - assertThatUpdateAdds(update, "example2.tld.", Type.NS, "ns.example2.tld."); + assertThatUpdateAdds( + 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 } @Test - void testPublishDomainCreate_publishesDelegationSigner() throws Exception { + void testPublishDomainCreate_publishesDelegationSigner_usesDefaultTtl() throws Exception { Domain domain = persistActiveDomain("example.tld") .asBuilder() @@ -189,8 +198,53 @@ public class DnsUpdateWriterTest { Update update = updateCaptor.getValue(); assertThatUpdatedZoneIs(update, "tld."); assertThatUpdateDeletes(update, "example.tld.", Type.ANY); - assertThatUpdateAdds(update, "example.tld.", Type.NS, "ns1.example.tld."); - assertThatUpdateAdds(update, "example.tld.", Type.DS, "1 3 1 0123456789ABCDEF"); + assertThatUpdateAdds( + 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 } @@ -229,7 +283,7 @@ public class DnsUpdateWriterTest { } @Test - void testPublishHostCreate_publishesAddressRecords() throws Exception { + void testPublishHostCreate_publishesAddressRecords_usesDefaultTtl() throws Exception { Host host = persistResource( newHost("ns1.example.tld") @@ -255,9 +309,76 @@ public class DnsUpdateWriterTest { assertThatUpdatedZoneIs(update, "tld."); assertThatUpdateDeletes(update, "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(update, "ns1.example.tld.", Type.AAAA, "fd0e:a5c8:6dfb:6a5e:0:0:0:1"); - assertThatUpdateAdds(update, "example.tld.", Type.NS, "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"); + 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); } @@ -294,7 +415,8 @@ public class DnsUpdateWriterTest { assertThatUpdatedZoneIs(update, "tld."); assertThatUpdateDeletes(update, "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); } @@ -329,9 +451,26 @@ public class DnsUpdateWriterTest { assertThatUpdatedZoneIs(update, "tld."); assertThatUpdateDeletes(update, "example.tld.", Type.ANY); assertThatUpdateDeletes(update, "ns1.example.tld.", Type.ANY); - assertThatUpdateAdds(update, "example.tld.", Type.NS, "ns1.example.com.", "ns1.example.tld."); - assertThatUpdateAdds(update, "ns1.example.tld.", Type.A, "10.0.0.1", "10.1.0.1"); - assertThatUpdateAdds(update, "ns1.example.tld.", Type.AAAA, "fd0e:a5c8:6dfb:6a5e:0:0:0:1"); + assertThatUpdateAdds( + update, + "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); } @@ -365,9 +504,21 @@ public class DnsUpdateWriterTest { assertThatUpdateDeletes(update, "example.tld.", Type.ANY); assertThatUpdateDeletes(update, "ns1.example.tld.", Type.ANY); assertThatUpdateDeletes(update, "foo.example.tld.", Type.ANY); - assertThatUpdateAdds(update, "example.tld.", Type.NS, "ns1.example.tld."); - assertThatUpdateAdds(update, "ns1.example.tld.", Type.A, "10.0.0.1", "10.1.0.1"); - assertThatUpdateAdds(update, "ns1.example.tld.", Type.AAAA, "fd0e:a5c8:6dfb:6a5e:0:0:0:1"); + assertThatUpdateAdds( + update, "example.tld.", Type.NS, Duration.ZERO.getStandardSeconds(), "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, 6); } @@ -430,13 +581,14 @@ public class DnsUpdateWriterTest { } private static void assertThatUpdateAdds( - Update update, String resourceName, int recordType, String... resourceData) { + Update update, String resourceName, int recordType, Long ttl, String... resourceData) { ArrayList expectedData = new ArrayList<>(); Collections.addAll(expectedData, resourceData); ArrayList actualData = new ArrayList<>(); for (Record record : findUpdateRecords(update, resourceName, recordType)) { actualData.add(record.rdataToString()); + assertThat(record.getTTL()).isEqualTo(ttl); } assertThat(actualData).containsExactlyElementsIn(expectedData); } diff --git a/core/src/test/java/google/registry/tools/CreateTldCommandTest.java b/core/src/test/java/google/registry/tools/CreateTldCommandTest.java index db14314d4..cf6edbb44 100644 --- a/core/src/test/java/google/registry/tools/CreateTldCommandTest.java +++ b/core/src/test/java/google/registry/tools/CreateTldCommandTest.java @@ -87,9 +87,9 @@ class CreateTldCommandTest extends CommandTestCase { "--dns_ns_ttl=PT180S"); Tld registry = Tld.get("xn--q9jyb4c"); assertThat(registry).isNotNull(); - assertThat(registry.getDnsAPlusAaaaTtl()).isEqualTo(standardMinutes(5)); - assertThat(registry.getDnsDsTtl()).isEqualTo(standardMinutes(4)); - assertThat(registry.getDnsNsTtl()).isEqualTo(standardMinutes(3)); + assertThat(registry.getDnsAPlusAaaaTtl().get()).isEqualTo(standardMinutes(5)); + assertThat(registry.getDnsDsTtl().get()).isEqualTo(standardMinutes(4)); + assertThat(registry.getDnsNsTtl().get()).isEqualTo(standardMinutes(3)); } @Test diff --git a/core/src/test/java/google/registry/tools/UpdateTldCommandTest.java b/core/src/test/java/google/registry/tools/UpdateTldCommandTest.java index 411d654a4..873242e3f 100644 --- a/core/src/test/java/google/registry/tools/UpdateTldCommandTest.java +++ b/core/src/test/java/google/registry/tools/UpdateTldCommandTest.java @@ -1111,10 +1111,10 @@ class UpdateTldCommandTest extends CommandTestCase { "--dns_ds_ttl=PT240S", "--dns_ns_ttl=PT180S", "xn--q9jyb4c"); - Tld registry = Tld.get("xn--q9jyb4c"); - assertThat(registry.getDnsAPlusAaaaTtl()).isEqualTo(standardMinutes(5)); - assertThat(registry.getDnsDsTtl()).isEqualTo(standardMinutes(4)); - assertThat(registry.getDnsNsTtl()).isEqualTo(standardMinutes(3)); + Tld tld = Tld.get("xn--q9jyb4c"); + assertThat(tld.getDnsAPlusAaaaTtl().get()).isEqualTo(standardMinutes(5)); + assertThat(tld.getDnsDsTtl().get()).isEqualTo(standardMinutes(4)); + assertThat(tld.getDnsNsTtl().get()).isEqualTo(standardMinutes(3)); } private void runSuccessfulReservedListsTest(String reservedLists) throws Exception { diff --git a/core/src/test/java/google/registry/tools/server/GenerateZoneFilesActionTest.java b/core/src/test/java/google/registry/tools/server/GenerateZoneFilesActionTest.java index d53956953..a17b8f7ea 100644 --- a/core/src/test/java/google/registry/tools/server/GenerateZoneFilesActionTest.java +++ b/core/src/test/java/google/registry/tools/server/GenerateZoneFilesActionTest.java @@ -35,6 +35,7 @@ import google.registry.gcs.GcsUtils; import google.registry.model.domain.secdns.DomainDsData; import google.registry.model.eppcommon.StatusValue; import google.registry.model.host.Host; +import google.registry.model.tld.Tld; import google.registry.persistence.VKey; import google.registry.persistence.transaction.JpaTestExtensions; import google.registry.persistence.transaction.JpaTestExtensions.JpaIntegrationTestExtension; @@ -58,9 +59,26 @@ class GenerateZoneFilesActionTest { private final GcsUtils gcsUtils = new GcsUtils(LocalStorageHelper.getOptions()); @Test - void testGenerate() throws Exception { - DateTime now = DateTime.now(DateTimeZone.UTC).withTimeAtStartOfDay(); + void testGenerate_defaultTtls() throws Exception { 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 ips = 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. Splitter splitter = Splitter.on('\n').omitEmptyStrings(); Iterable generatedFileLines = splitter.split(generatedFile.replaceAll("\t", " ")); - Iterable goldenFileLines = splitter.split(loadFile(getClass(), "tld.zone")); + Iterable goldenFileLines = splitter.split(loadFile(getClass(), goldenFileName)); // The first line needs to be the same as the golden file. assertThat(generatedFileLines.iterator().next()).isEqualTo(goldenFileLines.iterator().next()); // The remaining lines can be in any order. diff --git a/core/src/test/java/google/registry/tools/server/tldCustomTtl.zone b/core/src/test/java/google/registry/tools/server/tldCustomTtl.zone new file mode 100644 index 000000000..d4be3b2fb --- /dev/null +++ b/core/src/test/java/google/registry/tools/server/tldCustomTtl.zone @@ -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