Top-level domain name registry service on Google Cloud Platform
Find a file
Ben McIlwain 6debcceef4 Don't write TX records for domains deleted in autorenew grace period (#244)
* Don't write TX records for domains deleted in autorenew grace period

When the project was originally being designed, we envisioned have a purely
point-in-time architecture that would allow the system to run indefinitely
without requiring any background batch jobs. That is, you could create a domain,
and 10 years later you could infer every autorenewal billing event that should
have happened during those 10 years, without ever having to run any code that
would go through and retroactively create those events as they happened.

This ended up being very complicated, especially when it came to generating
invoices, so we gave up on it and instead wrote the
ExpandRecurringBillingEventsAction mapreduce, which would run as a cronjob and
periodically expand the recurring billing information into actual one-time
billing events. This made the invoicing scripts MUCH less complicated since they
only had to tabulate one-time billing events that had actually occurred over the
past month, rather than perform complicated logic to infer every one-time event
over an arbitrarily long period.

I bring this up because this architectural legacy explains why billing events
are more complicated than could otherwise be explained from current
requirements. This is why, for instance, when a domain is deleted during the 45
day autorenewal period, the ExpandRecurringBillingEventsAction will still write
out a history entry (and corresponding billing events) on the 45th day, because
it needs to be offset by the cancellation billing event for the autorenew grace
period that was already written out synchronously as part of the delete flow.

This no longer really makes sense, and it would be simpler to just not write out
these phantom history entries and billing events at all, but it would be a
larger modification to fix this, so I'm not touching it here.

Instead, what I have done is to simply not write out the DomainTransactionRecord
in the mapreduce if the recurring billing event has already been canceled
(i.e. because the domain was deleted or transferred). This seems inconsistent
but actually does make sense, because domain transaction records are never
written out speculatively (unlike history entries and billing events); they
correspond only to actions that have actually happen.  This is because they were
architected much more recently than billing events, and don't use the
point-in-time hierarchy.

So, here's a full accounting of how DomainTransactionRecords work as of this commit:
1. When a domain is created, one is written out.
2. When a domain is explicitly renewed, one is written out.
3. When a domain is autorenewed, one is written out at the end of the grace period.
4. When a domain is deleted (in all cases), a record is written out recording the
   deletion.
5. When a domain is deleted in the add grace period, an offsetting record is
   written out with a negative number of years, in addition to the deletion record.
6. When a domain is deleted in the renewal grace period, an offsetting record is
   likely written out in addition.
7. When a domain is deleted in the autorenew grace period, there is no record that
   needs to be offset because no code ran at the exact time of the autorenew, so
   NO additional record should be written out by the expand mapreduce.
   *THIS IS CHANGED AS OF THIS COMMIT*.
8. When a domain is transferred, all existing grace periods are cancelled and
   corresponding cancelling records are written out. Note that transfers include a
   mandatory, irrevocable 1 year renewal.
9. In the rare event that a domain is restored, all recurring events are
   re-created, and there is a 1 year mandatory renewal as part of the restore with
   corresponding record written out.

So, in summary, billing events and history entries are often written out
speculatively, and can subsequently be canceled, but the same is not true of
domain transaction records.  Domain transaction records are only written out as
part of a corresponding action (which for autorenewals is the expand recurring
cronjob).

* rm unused import
2019-08-30 12:04:35 -04:00
buildSrc Rename dependency_license.gradle file (#196) 2019-07-26 14:19:08 -04:00
config Only apply Google Java format to changed lines (#176) 2019-08-29 16:04:34 -04:00
core Don't write TX records for domains deleted in autorenew grace period (#244) 2019-08-30 12:04:35 -04:00
db/src/main/resources/sql/schema Add sql schema and entity class for ClaimsList (#227) 2019-08-26 18:30:51 -04:00
docs Move terraform and kubernetes folder to be under proxy (#127) 2019-06-20 14:28:32 -04:00
gradle Use Gradle from gradle.org in Gradle wrapper (#239) 2019-08-27 11:11:35 -04:00
java-format Only apply Google Java format to changed lines (#176) 2019-08-29 16:04:34 -04:00
node_modules Refactor to be more in line with a standard Gradle project structure 2019-06-13 09:41:11 -04:00
prober Update Gradle wrapper to 5.6 (#232) 2019-08-23 22:10:55 -07:00
proxy Update proxy deployment script description (#245) 2019-08-28 17:35:43 -04:00
python/google/registry/scripts Remove Bazel build (#94) 2019-06-13 18:15:33 -04:00
release Merge beam and GAE configs deployment to one GCB job (#182) 2019-07-19 16:54:56 -04:00
services Upgrade google-auth-library-java to latest version 2019-06-18 17:27:21 -04:00
third_party Require the license in Gradle files (#149) 2019-07-02 11:47:35 -04:00
util Add a registry lock password to contacts (#226) 2019-08-23 22:34:43 -04:00
.gcloudignore Build docker image of nomulus tool (#142) 2019-07-16 20:18:44 -04:00
.gitignore Create a Gradle task to run the test server (#192) 2019-07-29 11:03:29 -04:00
.lgtm.yml Add customized .lgtm.yml (#191) 2019-07-23 17:09:05 -04:00
appengine_war.gradle Add a Gradle task to deploy the proxy (#214) 2019-08-06 11:45:34 -04:00
AUTHORS Change all references to Domain Registry to Nomulus 2016-10-14 16:58:07 -04:00
build.gradle Remove the "showAllOutput" property from the build (#247) 2019-08-30 10:43:07 -04:00
CONTRIBUTING.md Add Google Java Style Guide info and link to CONTRIBUTING.md 2016-11-15 11:01:16 -05:00
CONTRIBUTORS Add shicong@ and gbrodman@ to CONTRIBUTORS 2019-06-13 16:07:31 -04:00
dependencies.gradle Set up database connection pool (#234) 2019-08-29 16:12:28 -04:00
dependency_lic.gradle Rename dependency_license.gradle file (#196) 2019-07-26 14:19:08 -04:00
gradle.properties Update Gradle wrapper to 5.6 (#232) 2019-08-23 22:10:55 -07:00
gradlew Upgrade to Gradle 5.5.1 (#178) 2019-07-17 17:37:44 -04:00
gradlew.bat Upgrade to Gradle 5.5.1 (#178) 2019-07-17 17:37:44 -04:00
java_common.gradle Only apply Google Java format to changed lines (#176) 2019-08-29 16:04:34 -04:00
karma.conf.js Move JS and CSS files to a Javascript source dir (#156) 2019-07-05 12:01:16 -04:00
LICENSE Fix a typo (#174) 2019-07-15 17:49:22 -04:00
nomulus-logo.png Update Nomulus logo 2017-05-23 17:22:49 -04:00
package-lock.json Bump lodash from 4.17.11 to 4.17.14 (#173) 2019-07-15 11:26:12 -04:00
package.json Use strict versions in NPM versioning (#132) 2019-06-25 16:10:04 -04:00
projects.gradle Add a Gradle task to deploy the proxy (#214) 2019-08-06 11:45:34 -04:00
README.md Update build badges to use Kokoro results for both FOSS and internal (#229) 2019-08-16 15:06:02 -04:00
settings.gradle Add sql schema and entity class for ClaimsList (#227) 2019-08-26 18:30:51 -04:00

Nomulus

Internal Build FOSS Build LGTM License Code Search
Build Status for Google Registry internal build Build Status for the open source build Total alerts License for this repo Link to Source Graph

Nomulus logo

Overview

Nomulus is an open source, scalable, cloud-based service for operating top-level domains (TLDs). It is the authoritative source for the TLDs that it runs, meaning that it is responsible for tracking domain name ownership and handling registrations, renewals, availability checks, and WHOIS requests. End-user registrants (i.e. people or companies that want to register a domain name) use an intermediate domain name registrar acting on their behalf to interact with the registry.

Nomulus runs on Google App Engine and is written primarily in Java. It is the software that Google Registry uses to operate TLDs such as .google, .app, .how, .soy, and .みんな. It can run any number of TLDs in a single shared registry system using horizontal scaling. Its source code is publicly available in this repository under the Apache 2.0 free and open source license.

Getting started

The following resources provide information on getting the code and setting up a running system:

If you are thinking about running a production registry service using our platform, please drop by the user group and introduce yourself and your use case. To report issues or make contributions, use GitHub issues and pull requests.

Capabilities

Nomulus has the following capabilities:

  • Extensible Provisioning Protocol (EPP): An XML protocol that is the standard format for communication between registrars and registries. It includes operations for registering, renewing, checking, updating, and transferring domain names.
  • DNS interface: The registry provides a pluggable interface that can be implemented to handle different DNS providers. It includes a sample implementation using Google Cloud DNS as well as an RFC 2136 compliant implementation that works with BIND.
  • WHOIS: A text-based protocol that returns ownership and contact information on registered domain names.
  • Registration Data Access Protocol (RDAP): A JSON API that returns structured, machine-readable information about domain name ownership. It is essentially a newer version of WHOIS.
  • Registry Data Escrow (RDE): A daily export of all ownership information for a TLD to a third party escrow provider to allow take-over by another registry operator in the event of serious failure. This is required by ICANN for all new gTLDs.
  • Premium pricing: Communicates prices for premium domain names (i.e. those that are highly desirable) and supports configurable premium registration and renewal prices. An extensible interface allows fully programmatic pricing.
  • Billing history: A full history of all billable events is recorded, suitable for ingestion into an invoicing system.
  • Registration periods: Qualified Launch Partner, Sunrise, Landrush, Claims, and General Availability periods of the standard gTLD lifecycle are all supported.
  • Brand protection for trademark holders (via TMCH): Allows rights-holders to protect their brands by blocking registration of domains using their trademark. This is required by ICANN for all new gTLDs.
  • Registrar support console: A self-service web console that registrars can use to manage their accounts in the registry system.
  • Reporting: Support for required external reporting (such as ICANN monthly registry reports, CZDS, Billing and Registration Activity) as well as internal reporting using BigQuery.
  • Administrative tool: Performs the full range of administrative tasks needed to manage a running registry system, including creating and configuring new TLDs.
  • DNS interface: An interface for DNS operations is provided so you can write an implementation for your chosen provider, along with a sample implementation that uses Google Cloud DNS. If you are using Google Cloud DNS you may need to understand its capabilities and provide your own multi-AS solution.
  • GAE Proxy: App Engine Standard only serves HTTP/S traffic. A proxy to forward traffic on EPP and WHOIS ports to App Engine via HTTPS is provided. Instructions on setting up the proxy on Google Kubernetes Engine is available. Running the proxy on GKE supports IPv4 and IPv6 access, per ICANN's requirements for gTLDs. The proxy can also run as a single jar file, or on other Kubernetes providers, with modifications.

Additional components

Registry operators interested in deploying Nomulus will likely require some additional components that are need to be configured separately.

  • A way to invoice registrars for domain name registrations and accept payments. Nomulus records the information required to generate invoices in billing events.
  • Fully automated reporting to meet ICANN's requirements for gTLDs. Nomulus includes substantial reporting functionality but some additional work will be required by the operator in this area.
  • A secure method for storing cryptographic keys. A keyring interface is provided for plugging in your own implementation (see configuration doc for details).
  • System status and uptime monitoring.

Outside references

  • Donuts Registry has helped review the code and provided valuable feedback
  • CoCCa and FRED are other open-source registry platforms in use by many TLDs
  • We are not aware of any fully open source domain registrar projects, but open source EPP Toolkits (not yet tested with Nomulus; may require integration work) include:
  • Some Open Source DNS Projects that may be useful, but which we have not tested: