2
0
mirror of https://github.com/VinylDNS/vinyldns synced 2025-08-30 05:47:56 +00:00

max zone size (#584)

* max zone size rule

* refactor IOs
This commit is contained in:
Nima Eskandary 2019-04-26 09:47:29 -04:00 committed by Rebecca Star
parent 32156cb5bb
commit c1d88c5dca
6 changed files with 47 additions and 17 deletions

View File

@ -44,5 +44,13 @@ class ZoneViewLoaderIntegrationSpec extends WordSpec with Matchers {
.load()
.unsafeRunSync())
}
"return a failure if the zone is larger than the max zone size" in {
assertThrows[ZoneTooLargeError](
DnsZoneViewLoader(Zone("vinyldns.", "test@test.com"), DnsZoneViewLoader.dnsZoneTransfer, 1)
.load()
.unsafeRunSync()
)
}
}
}

View File

@ -8,6 +8,8 @@ vinyldns {
# if we should start up polling for change requests, set this to false for the inactive cluster
processing-disabled = false
max-zone-size = 60000 # number of records that can be in a zone
queue {
class-name = "vinyldns.sqs.queue.SqsMessageQueueProvider"

View File

@ -112,4 +112,6 @@ object VinylDNSConfig {
if (vinyldnsConfig.hasPath(key)) {
vinyldnsConfig.getStringList(key).asScala.toList
} else List()
lazy val maxZoneSize: Int = vinyldnsConfig.as[Option[Int]]("max-zone-size").getOrElse(60000)
}

View File

@ -240,3 +240,14 @@ case class ConnectionFailed(zone: Zone, message: String) extends Throwable(messa
case class ZoneValidationFailed(zone: Zone, errors: List[String], message: String)
extends Throwable(message)
case class ZoneTooLargeError(msg: String) extends Throwable(msg)
object ZoneTooLargeError {
def apply(zone: Zone, zoneSize: Int, maxZoneSize: Int): ZoneTooLargeError = new ZoneTooLargeError(
s"""
|ZoneTooLargeError: Zone '${zone.name}' (id: '${zone.id}') contains $zoneSize records
|which exceeds the max of $maxZoneSize
""".stripMargin.replace("\n", " ")
)
}

View File

@ -27,12 +27,14 @@ import vinyldns.core.domain.zone.Zone
import vinyldns.core.route.Monitored
import scala.collection.JavaConverters._
import vinyldns.core.domain.record.{RecordSetRepository, RecordType}
trait ZoneViewLoader {
def load: () => IO[ZoneView]
}
object DnsZoneViewLoader extends DnsConversions {
def dnsZoneTransfer(zone: Zone): ZoneTransferIn = {
val conn =
ZoneConnectionValidator
@ -54,7 +56,10 @@ object DnsZoneViewLoader extends DnsConversions {
DnsZoneViewLoader(zone, dnsZoneTransfer)
}
case class DnsZoneViewLoader(zone: Zone, zoneTransfer: Zone => ZoneTransferIn)
case class DnsZoneViewLoader(
zone: Zone,
zoneTransfer: Zone => ZoneTransferIn,
maxZoneSize: Int = VinylDNSConfig.maxZoneSize)
extends ZoneViewLoader
with DnsConversions
with Monitored {
@ -62,23 +67,20 @@ case class DnsZoneViewLoader(zone: Zone, zoneTransfer: Zone => ZoneTransferIn)
def load: () => IO[ZoneView] =
() =>
monitor("dns.loadZoneView") {
IO {
val xfr = zoneTransfer(zone)
xfr.run()
val rawDnsRecords: List[DNS.Record] =
for {
zoneXfr <- IO {
val xfr = zoneTransfer(zone)
xfr.run()
xfr.getAXFR.asScala.map(_.asInstanceOf[DNS.Record]).toList.distinct
// not accepting unknown record types
val supportedRecords =
rawDnsRecords.filter(record => fromDnsRecordType(record.getType) != RecordType.UNKNOWN)
val dnsZoneName = zoneDnsName(zone.name)
val recordSets = supportedRecords.map(toRecordSet(_, dnsZoneName, zone.id))
ZoneView(zone, recordSets)
}
}
rawDnsRecords = zoneXfr.filter(record =>
fromDnsRecordType(record.getType) != RecordType.UNKNOWN)
_ <- if (rawDnsRecords.length > maxZoneSize)
IO.raiseError(ZoneTooLargeError(zone, rawDnsRecords.length, maxZoneSize))
else IO.pure(Unit)
dnsZoneName <- IO(zoneDnsName(zone.name))
recordSets <- IO(rawDnsRecords.map(toRecordSet(_, dnsZoneName, zone.id)))
} yield ZoneView(zone, recordSets)
}
}

View File

@ -463,6 +463,11 @@ vinyldns {
host = "0.0.0.0"
port = 9000
}
# The maximum number of records VinylDNS will load when syncing a DNS Zone
# this is to prevent possible out of memory errors when loading a Zone
# this does not stop the zone from existing in DNS, but you will not be able to manage it in VinylDNS if the number of records exceeds the max
max-zone-size = 60000
# the delay between zone syncs so we are not syncing too often
sync-delay = 10000