registrars;
+ private boolean replaceExisting = false;
+
+ private OteAccountBuilder(String baseClientId) {
+ checkState(
+ RegistryEnvironment.get() != RegistryEnvironment.PRODUCTION,
+ "Can't setup OT&E in production");
+ clientIdToTld = createClientIdToTldMap(baseClientId);
+ sunriseTld =
+ createTld(
+ baseClientId + "-sunrise", TldState.START_DATE_SUNRISE, null, null, null, false, 0);
+ landrushTld =
+ createTld(baseClientId + "-landrush", TldState.LANDRUSH, null, null, null, false, 1);
+ gaTld =
+ createTld(
+ baseClientId + "-ga",
+ TldState.GENERAL_AVAILABILITY,
+ SHORT_ADD_GRACE_PERIOD,
+ SHORT_REDEMPTION_GRACE_PERIOD,
+ SHORT_PENDING_DELETE_LENGTH,
+ false,
+ 2);
+ eapTld =
+ createTld(
+ baseClientId + "-eap",
+ TldState.GENERAL_AVAILABILITY,
+ SHORT_ADD_GRACE_PERIOD,
+ SHORT_REDEMPTION_GRACE_PERIOD,
+ SHORT_PENDING_DELETE_LENGTH,
+ true,
+ 3);
+ registrars =
+ clientIdToTld.keySet().stream()
+ .map(OteAccountBuilder::createRegistrar)
+ .collect(toImmutableList());
+ }
+
+ /**
+ * Creates an OteAccountBuilder for the given base client ID.
+ *
+ * @param baseClientId the base clientId which will help name all the entities we create. Normally
+ * is the same as the "prod" clientId designated for this registrar.
+ */
+ public static OteAccountBuilder forClientId(String baseClientId) {
+ return new OteAccountBuilder(baseClientId);
+ }
+
+ /**
+ * Set whether to replace any conflicting existing entities.
+ *
+ * If true, any existing entity that conflicts with the entities we want to create will be
+ * replaced with the newly created data.
+ *
+ *
If false, encountering an existing entity that conflicts with one we want to create will
+ * throw an exception during {@link #buildAndPersist}.
+ *
+ *
NOTE that if we fail, no entities are created (the creation is atomic).
+ *
+ *
Default is false (failing if entities exist)
+ */
+ public OteAccountBuilder setReplaceExisting(boolean replaceExisting) {
+ this.replaceExisting = replaceExisting;
+ return this;
+ }
+
+ /**
+ * Adds a RegistrarContact with Web Console access.
+ *
+ *
NOTE: can be called more than once, adding multiple contacts. Each contact will have access
+ * to all OT&E Registrars.
+ *
+ * @param email the contact email that will have web-console access to all the Registrars. Must be
+ * from "our G Suite domain" (we have to be able to get its GaeUserId)
+ */
+ public OteAccountBuilder addContact(String email) {
+ String gaeUserId =
+ checkNotNull(
+ GaeUserIdConverter.convertEmailAddressToGaeUserId(email),
+ "Email address %s is not associated with any GAE ID",
+ email);
+ registrars.forEach(
+ registrar -> contactsBuilder.add(createRegistrarContact(email, gaeUserId, registrar)));
+ return this;
+ }
+
+ /**
+ * Apply a function on all the OT&E Registrars.
+ *
+ *
Use this to set up registrar fields.
+ *
+ *
NOTE: DO NOT change anything that would affect the {@link Key#create} result on Registrars.
+ * If you want to make this function public, add a check that the Key.create on the registrars
+ * hasn't changed.
+ *
+ * @param func a function setting the requested fields on Registrar Builders. Will be applied to
+ * all the Registrars.
+ */
+ private OteAccountBuilder transformRegistrars(
+ Function func) {
+ registrars =
+ registrars.stream()
+ .map(Registrar::asBuilder)
+ .map(func)
+ .map(Registrar.Builder::build)
+ .collect(toImmutableList());
+ return this;
+ }
+
+ /** Sets the EPP login password for all the OT&E Registrars. */
+ public OteAccountBuilder setPassword(String password) {
+ return transformRegistrars(builder -> builder.setPassword(password));
+ }
+
+ /** Sets the client certificate hash to all the OT&E Registrars. */
+ public OteAccountBuilder setCertificateHash(String certHash) {
+ return transformRegistrars(builder -> builder.setClientCertificateHash(certHash));
+ }
+
+ /** Sets the client certificate to all the OT&E Registrars. */
+ public OteAccountBuilder setCertificate(String asciiCert, DateTime now) {
+ return transformRegistrars(builder -> builder.setClientCertificate(asciiCert, now));
+ }
+
+ /** Sets the IP whitelist to all the OT&E Registrars. */
+ public OteAccountBuilder setIpWhitelist(Collection ipWhitelist) {
+ ImmutableList ipAddressWhitelist =
+ ipWhitelist.stream().map(CidrAddressBlock::create).collect(toImmutableList());
+ return transformRegistrars(builder -> builder.setIpAddressWhitelist(ipAddressWhitelist));
+ }
+
+ /**
+ * Persists all the OT&E entities to datastore.
+ *
+ * @return map from the new clientIds created to the new TLDs they have access to. Can be used to
+ * go over all the newly created Registrars / Registries / RegistrarContacts if any
+ * post-creation work is needed.
+ */
+ public ImmutableMap buildAndPersist() {
+ // save all the entitiesl in a single transaction
+ ofy().transact(this::saveAllEntities);
+ return clientIdToTld;
+ }
+
+ /**
+ * Return map from the OT&E clientIds we will create to the new TLDs they will have access to.
+ */
+ public ImmutableMap getClientIdToTldMap() {
+ return clientIdToTld;
+ }
+
+ /** Saves all the OT&E entities we created. */
+ private void saveAllEntities() {
+ ofy().assertInTransaction();
+
+ ImmutableList registries = ImmutableList.of(sunriseTld, landrushTld, gaTld, eapTld);
+ ImmutableList contacts = contactsBuilder.build();
+
+ if (!replaceExisting) {
+ ImmutableList> keys =
+ Streams.concat(registries.stream(), registrars.stream(), contacts.stream())
+ .map(Key::create)
+ .collect(toImmutableList());
+ Set> existingKeys = ofy().load().keys(keys).keySet();
+ checkState(
+ existingKeys.isEmpty(),
+ "Found existing object(s) conflicting with OT&E objects: %s",
+ existingKeys);
+ }
+ // Save the Registries (TLDs) first
+ ofy().save().entities(registries).now();
+ // Now we can set the allowedTlds for the registrars
+ registrars = registrars.stream().map(this::addAllowedTld).collect(toImmutableList());
+ // and we can save the registrars and contacts!
+ ofy().save().entities(registrars);
+ ofy().save().entities(contacts);
+ }
+
+ private Registrar addAllowedTld(Registrar registrar) {
+ String tld = clientIdToTld.get(registrar.getClientId());
+ if (registrar.getAllowedTlds().contains(tld)) {
+ return registrar;
+ }
+ return registrar
+ .asBuilder()
+ .setAllowedTldsUncached(Sets.union(registrar.getAllowedTlds(), ImmutableSet.of(tld)))
+ .build();
+ }
+
+ private static Registry createTld(
+ String tldName,
+ TldState initialTldState,
+ Duration addGracePeriod,
+ Duration redemptionGracePeriod,
+ Duration pendingDeleteLength,
+ boolean isEarlyAccess,
+ int roidSuffix) {
+ String tldNameAlphaNumerical = tldName.replaceAll("[^a-z0-9]", "");
+ Optional premiumList = PremiumList.getUncached(DEFAULT_PREMIUM_LIST);
+ checkState(premiumList.isPresent(), "Couldn't find premium list %s.", DEFAULT_PREMIUM_LIST);
+ Registry.Builder builder =
+ new Registry.Builder()
+ .setTldStr(tldName)
+ .setPremiumPricingEngine(StaticPremiumListPricingEngine.NAME)
+ .setTldStateTransitions(ImmutableSortedMap.of(START_OF_TIME, initialTldState))
+ .setDnsWriters(ImmutableSet.of("VoidDnsWriter"))
+ .setPremiumList(premiumList.get())
+ .setRoidSuffix(
+ String.format(
+ "%S%X",
+ tldNameAlphaNumerical.substring(0, Math.min(tldNameAlphaNumerical.length(), 7)),
+ roidSuffix));
+ if (addGracePeriod != null) {
+ builder.setAddGracePeriodLength(addGracePeriod);
+ }
+ if (pendingDeleteLength != null) {
+ builder.setPendingDeleteLength(pendingDeleteLength);
+ }
+ if (redemptionGracePeriod != null) {
+ builder.setRedemptionGracePeriodLength(redemptionGracePeriod);
+ }
+ if (isEarlyAccess) {
+ builder.setEapFeeSchedule(EAP_FEE_SCHEDULE);
+ }
+ return builder.build();
+ }
+
+ /**
+ * Creates the Registrar without the allowedTlds set - because we can't set allowedTlds before the
+ * TLD is saved.
+ */
+ private static Registrar createRegistrar(String registrarName) {
+ return new Registrar.Builder()
+ .setClientId(registrarName)
+ .setRegistrarName(registrarName)
+ .setType(Registrar.Type.OTE)
+ .setLocalizedAddress(DEFAULT_ADDRESS)
+ .setEmailAddress("foo@neverland.com")
+ .setFaxNumber("+1.2125550100")
+ .setPhoneNumber("+1.2125550100")
+ .setIcannReferralEmail("nightmare@registrar.test")
+ .setState(Registrar.State.ACTIVE)
+ .build();
+ }
+
+ private static RegistrarContact createRegistrarContact(
+ String email, String gaeUserId, Registrar registrar) {
+ return new RegistrarContact.Builder()
+ .setParent(registrar)
+ .setName(email)
+ .setEmailAddress(email)
+ .setGaeUserId(gaeUserId)
+ .build();
+ }
+
+ /** Returns the ClientIds of the OT&E, with the TLDs each has access to. */
+ private static ImmutableMap createClientIdToTldMap(String baseClientId) {
+ checkArgument(
+ REGISTRAR_PATTERN.matcher(baseClientId).matches(),
+ "Invalid registrar name: %s",
+ baseClientId);
+ return new ImmutableMap.Builder()
+ .put(baseClientId + "-1", baseClientId + "-sunrise")
+ .put(baseClientId + "-2", baseClientId + "-landrush")
+ .put(baseClientId + "-3", baseClientId + "-ga")
+ .put(baseClientId + "-4", baseClientId + "-ga")
+ .put(baseClientId + "-5", baseClientId + "-eap")
+ .build();
+ }
+}
diff --git a/java/google/registry/model/registrar/Registrar.java b/java/google/registry/model/registrar/Registrar.java
index b67910cbe..23f026159 100644
--- a/java/google/registry/model/registrar/Registrar.java
+++ b/java/google/registry/model/registrar/Registrar.java
@@ -19,6 +19,7 @@ import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Strings.emptyToNull;
import static com.google.common.base.Strings.nullToEmpty;
import static com.google.common.collect.ImmutableMap.toImmutableMap;
+import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.common.collect.ImmutableSortedMap.toImmutableSortedMap;
import static com.google.common.collect.ImmutableSortedSet.toImmutableSortedSet;
import static com.google.common.collect.Ordering.natural;
@@ -68,6 +69,7 @@ import google.registry.model.UpdateAutoTimestamp;
import google.registry.model.annotations.ReportedOn;
import google.registry.model.common.EntityGroupRoot;
import google.registry.model.registrar.Registrar.BillingAccountEntry.CurrencyMapper;
+import google.registry.model.registry.Registry;
import google.registry.util.CidrAddressBlock;
import google.registry.util.NonFinalForTesting;
import java.security.MessageDigest;
@@ -704,6 +706,28 @@ public class Registrar extends ImmutableObject implements Buildable, Jsonifiable
return this;
}
+ /**
+ * Same as {@link #setAllowedTlds}, but doesn't use the cache to check if the TLDs exist.
+ *
+ * This should be used if the TLD we want to set is persisted in the same transaction -
+ * meaning its existence can't be cached before we need to save the Registrar.
+ *
+ *
We can still only set the allowedTld AFTER we saved the Registry entity. Make sure to call
+ * {@code .now()} when saving the Registry entity to make sure it's actually saved before trying
+ * to set the allowed TLDs.
+ */
+ public Builder setAllowedTldsUncached(Set allowedTlds) {
+ ImmutableSet> newTldKeys =
+ Sets.difference(allowedTlds, getInstance().getAllowedTlds()).stream()
+ .map(tld -> Key.create(getCrossTldKey(), Registry.class, tld))
+ .collect(toImmutableSet());
+ Set> missingTldKeys =
+ Sets.difference(newTldKeys, ofy().load().keys(newTldKeys).keySet());
+ checkArgument(missingTldKeys.isEmpty(), "Trying to set nonexisting TLDs: %s", missingTldKeys);
+ getInstance().allowedTlds = ImmutableSortedSet.copyOf(allowedTlds);
+ return this;
+ }
+
public Builder setClientCertificate(String clientCertificate, DateTime now) {
clientCertificate = emptyToNull(clientCertificate);
String clientCertificateHash = calculateHash(clientCertificate);
diff --git a/java/google/registry/tools/SetupOteCommand.java b/java/google/registry/tools/SetupOteCommand.java
index 8764103bb..b53bfcc7c 100644
--- a/java/google/registry/tools/SetupOteCommand.java
+++ b/java/google/registry/tools/SetupOteCommand.java
@@ -15,69 +15,30 @@
package google.registry.tools;
import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static google.registry.model.ofy.ObjectifyService.ofy;
-import static google.registry.tools.CommandUtilities.promptForYes;
import static google.registry.util.X509Utils.loadCertificate;
+import static java.nio.charset.StandardCharsets.US_ASCII;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Throwables;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSortedMap;
-import com.google.re2j.Pattern;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.io.MoreFiles;
import google.registry.config.RegistryConfig.Config;
import google.registry.config.RegistryEnvironment;
-import google.registry.model.common.GaeUserIdConverter;
-import google.registry.model.registrar.Registrar;
-import google.registry.model.registry.Registry.TldState;
+import google.registry.model.OteAccountBuilder;
import google.registry.tools.params.PathParameter;
+import google.registry.util.Clock;
import google.registry.util.StringGenerator;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
-import java.util.Optional;
-import java.util.Set;
import javax.inject.Inject;
-import javax.inject.Named;
-import org.joda.money.CurrencyUnit;
-import org.joda.money.Money;
-import org.joda.time.DateTime;
-import org.joda.time.Duration;
/** Composite command to set up OT&E TLDs and accounts. */
@Parameters(separators = " =", commandDescription = "Set up OT&E TLDs and registrars")
final class SetupOteCommand extends ConfirmingCommand implements CommandWithRemoteApi {
- // Regex: 3-14 alphanumeric characters or hyphens, the first of which must be a letter.
- private static final Pattern REGISTRAR_PATTERN = Pattern.compile("^[a-z][-a-z0-9]{2,13}$");
private static final int PASSWORD_LENGTH = 16;
- // Durations are short so that registrars can test with quick transfer (etc.) turnaround.
- private static final Duration SHORT_ADD_GRACE_PERIOD = Duration.standardMinutes(60);
- private static final Duration SHORT_REDEMPTION_GRACE_PERIOD = Duration.standardMinutes(10);
- private static final Duration SHORT_PENDING_DELETE_LENGTH = Duration.standardMinutes(5);
-
- // Whether to prompt the user on command failures. Set to false for testing of these failures.
- @VisibleForTesting
- static boolean interactive = true;
-
- private static final ImmutableSortedMap EAP_FEE_SCHEDULE =
- ImmutableSortedMap.of(
- new DateTime(0),
- Money.of(CurrencyUnit.USD, 0),
- DateTime.parse("2018-03-01T00:00:00Z"),
- Money.of(CurrencyUnit.USD, 100),
- DateTime.parse("2022-03-01T00:00:00Z"),
- Money.of(CurrencyUnit.USD, 0));
-
- private static final String DEFAULT_PREMIUM_LIST = "default_sandbox_list";
-
- @Inject
- @Named("dnsWriterNames")
- Set validDnsWriterNames;
-
@Parameter(
names = {"-r", "--registrar"},
description =
@@ -101,7 +62,7 @@ final class SetupOteCommand extends ConfirmingCommand implements CommandWithRemo
names = {"--email"},
description =
"the registrar's account to use for console access. "
- + "Must be on the registry's G-Suite domain.",
+ + "Must be on the registry's G Suite domain.",
required = true)
private String email;
@@ -121,252 +82,83 @@ final class SetupOteCommand extends ConfirmingCommand implements CommandWithRemo
private String certHash;
@Parameter(
- names = {"--dns_writers"},
- description = "comma separated list of DNS writers to use on all TLDs",
- required = true
+ names = {"--overwrite"},
+ description = "whether to replace existing entities if we encounter any, instead of failing"
)
- private List dnsWriters;
-
- @Parameter(
- names = {"--premium_list"},
- description = "premium list to apply to all TLDs"
- )
- private String premiumList = DEFAULT_PREMIUM_LIST;
-
- // TODO: (b/74079782) remove this flag once OT&E for .app is complete.
- @Parameter(
- names = {"--eap_only"},
- description = "whether to only create EAP TLD and registrar"
- )
- private boolean eapOnly = false;
+ private boolean overwrite = false;
@Inject
@Config("base64StringGenerator")
StringGenerator passwordGenerator;
- /**
- * Long registrar names are truncated and then have an incrementing digit appended at the end so
- * that unique ROID suffixes can be generated for all TLDs for the registrar.
- */
- private int roidSuffixCounter = 0;
+ @Inject Clock clock;
- /** Runs a command, clearing the cache before and prompting the user on failures. */
- private void runCommand(Command command) {
- ofy().clearSessionCache();
- try {
- command.run();
- } catch (Exception e) {
- System.err.format("Command failed with error %s\n", e);
- if (interactive && promptForYes("Continue to next command?")) {
- return;
- }
- Throwables.throwIfUnchecked(e);
- throw new RuntimeException(e);
- }
- }
-
- /** Constructs and runs a CreateTldCommand. */
- private void createTld(
- String tldName,
- TldState initialTldState,
- Duration addGracePeriod,
- Duration redemptionGracePeriod,
- Duration pendingDeleteLength,
- boolean isEarlyAccess) {
- CreateTldCommand command = new CreateTldCommand();
- command.addGracePeriod = addGracePeriod;
- command.dnsWriters = dnsWriters;
- command.validDnsWriterNames = validDnsWriterNames;
- command.force = force;
- command.initialTldState = initialTldState;
- command.mainParameters = ImmutableList.of(tldName);
- command.pendingDeleteLength = pendingDeleteLength;
- command.premiumListName = Optional.of(premiumList);
- String tldNameAlphaNumerical = tldName.replaceAll("[^a-z0-9]", "");
- command.roidSuffix =
- String.format(
- "%S%X",
- tldNameAlphaNumerical.substring(0, Math.min(tldNameAlphaNumerical.length(), 7)),
- roidSuffixCounter++);
- command.redemptionGracePeriod = redemptionGracePeriod;
- if (isEarlyAccess) {
- command.eapFeeSchedule = EAP_FEE_SCHEDULE;
- }
- runCommand(command);
- }
-
- /** Constructs and runs a CreateRegistrarCommand */
- private void createRegistrar(String registrarName, String password, String tld) {
- CreateRegistrarCommand command = new CreateRegistrarCommand();
- command.mainParameters = ImmutableList.of(registrarName);
- command.createGoogleGroups = false; // Don't create Google Groups for OT&E registrars.
- command.allowedTlds = ImmutableList.of(tld);
- command.registrarName = registrarName;
- command.registrarType = Registrar.Type.OTE;
- command.password = password;
- command.clientCertificateFilename = certFile;
- command.clientCertificateHash = certHash;
- command.ipWhitelist = ipWhitelist;
- command.street = ImmutableList.of("e-street");
- command.city = "Neverland";
- command.state = "NY";
- command.countryCode = "US";
- command.zip = "55555";
- command.email = Optional.of("foo@neverland.com");
- command.fax = Optional.of("+1.2125550100");
- command.phone = Optional.of("+1.2125550100");
- command.icannReferralEmail = "nightmare@registrar.test";
- command.force = force;
- runCommand(command);
- }
-
- /** Constructs and runs a RegistrarContactCommand */
- private void createRegistrarContact(String registrarName) {
- RegistrarContactCommand command = new RegistrarContactCommand();
- command.mainParameters = ImmutableList.of(registrarName);
- command.mode = RegistrarContactCommand.Mode.CREATE;
- command.name = email;
- command.email = email;
- command.allowConsoleAccess = true;
- command.force = force;
- runCommand(command);
- }
+ OteAccountBuilder oteAccountBuilder;
+ String password;
/** Run any pre-execute command checks */
@Override
- protected boolean checkExecutionState() throws Exception {
- checkArgument(
- REGISTRAR_PATTERN.matcher(registrar).matches(),
- "Registrar name is invalid (see usage text for requirements).");
-
- // Make sure the email is "correct" - as in it's a valid email we can convert to gaeId
- // There's no need to look at the result - it'll be converted again inside
- // RegistrarContactCommand.
- checkNotNull(
- GaeUserIdConverter.convertEmailAddressToGaeUserId(email),
- "Email address %s is not associated with any GAE ID",
- email);
-
- boolean warned = false;
- if (RegistryEnvironment.get() != RegistryEnvironment.SANDBOX
- && RegistryEnvironment.get() != RegistryEnvironment.UNITTEST) {
- System.err.printf(
- "WARNING: Running against %s environment. Are "
- + "you sure you didn\'t mean to run this against sandbox (e.g. \"-e SANDBOX\")?%n",
- RegistryEnvironment.get());
- warned = true;
- }
-
- if (warned && !promptForYes("Proceed despite warnings?")) {
- System.out.println("Command aborted.");
- return false;
- }
-
+ protected void init() throws Exception {
checkArgument(
certFile == null ^ certHash == null,
"Must specify exactly one of client certificate file or client certificate hash.");
- // Don't wait for create_registrar to fail if it's a bad certificate file.
+ password = passwordGenerator.createString(PASSWORD_LENGTH);
+ oteAccountBuilder =
+ OteAccountBuilder.forClientId(registrar)
+ .addContact(email)
+ .setPassword(password)
+ .setIpWhitelist(ipWhitelist)
+ .setReplaceExisting(overwrite);
+
if (certFile != null) {
- loadCertificate(certFile.toAbsolutePath());
+ String asciiCert = MoreFiles.asCharSource(certFile, US_ASCII).read();
+ // Don't wait for create_registrar to fail if it's a bad certificate file.
+ loadCertificate(asciiCert);
+ oteAccountBuilder.setCertificate(asciiCert, clock.nowUtc());
+ }
+
+ if (certHash != null) {
+ oteAccountBuilder.setCertificateHash(certHash);
}
- return true;
}
@Override
protected String prompt() {
- // Each underlying command will confirm its own operation as well, so just provide
- // a summary of the steps in this command.
- if (eapOnly) {
- return "Creating TLD:\n"
- + " " + registrar + "-eap\n"
- + "Creating registrar:\n"
- + " " + registrar + "-5 (access to TLD " + registrar + "-eap)\n"
- + "Giving contact access to this registrar:\n"
- + " " + email;
- } else {
- return "Creating TLDs:\n"
- + " " + registrar + "-sunrise\n"
- + " " + registrar + "-landrush\n"
- + " " + registrar + "-ga\n"
- + " " + registrar + "-eap\n"
- + "Creating registrars:\n"
- + " " + registrar + "-1 (access to TLD " + registrar + "-sunrise)\n"
- + " " + registrar + "-2 (access to TLD " + registrar + "-landrush)\n"
- + " " + registrar + "-3 (access to TLD " + registrar + "-ga)\n"
- + " " + registrar + "-4 (access to TLD " + registrar + "-ga)\n"
- + " " + registrar + "-5 (access to TLD " + registrar + "-eap)\n"
- + "Giving contact access to these registrars:\n"
- + " " + email;
+ ImmutableMap registrarToTldMap = oteAccountBuilder.getClientIdToTldMap();
+ StringBuilder builder = new StringBuilder();
+ builder.append("Creating TLDs:");
+ registrarToTldMap.values().forEach(tld -> builder.append("\n ").append(tld));
+ builder.append("\nCreating registrars:");
+ registrarToTldMap.forEach(
+ (clientId, tld) ->
+ builder.append(String.format("\n %s (with access to %s)", clientId, tld)));
+ builder.append("\nGiving contact access to these registrars:").append("\n ").append(email);
+
+ if (RegistryEnvironment.get() != RegistryEnvironment.SANDBOX
+ && RegistryEnvironment.get() != RegistryEnvironment.UNITTEST) {
+ builder.append(
+ String.format(
+ "\n\nWARNING: Running against %s environment. Are "
+ + "you sure you didn\'t mean to run this against sandbox (e.g. \"-e SANDBOX\")?",
+ RegistryEnvironment.get()));
}
+
+ return builder.toString();
}
@Override
public String execute() throws Exception {
- if (!eapOnly) {
- createTld(registrar + "-sunrise", TldState.START_DATE_SUNRISE, null, null, null, false);
- createTld(registrar + "-landrush", TldState.LANDRUSH, null, null, null, false);
- createTld(
- registrar + "-ga",
- TldState.GENERAL_AVAILABILITY,
- SHORT_ADD_GRACE_PERIOD,
- SHORT_REDEMPTION_GRACE_PERIOD,
- SHORT_PENDING_DELETE_LENGTH,
- false);
- } else {
- // Increase ROID suffix counter to not collide with existing TLDs.
- roidSuffixCounter = roidSuffixCounter + 3;
- }
- createTld(
- registrar + "-eap",
- TldState.GENERAL_AVAILABILITY,
- SHORT_ADD_GRACE_PERIOD,
- SHORT_REDEMPTION_GRACE_PERIOD,
- SHORT_PENDING_DELETE_LENGTH,
- true);
-
- // Storing names and credentials in a list of tuples for later play-back.
- List> registrars = new ArrayList<>();
- if (!eapOnly) {
- registrars.add(
- ImmutableList.of(
- registrar + "-1",
- passwordGenerator.createString(PASSWORD_LENGTH),
- registrar + "-sunrise"));
- registrars.add(
- ImmutableList.of(
- registrar + "-2",
- passwordGenerator.createString(PASSWORD_LENGTH),
- registrar + "-landrush"));
- registrars.add(
- ImmutableList.of(
- registrar + "-3",
- passwordGenerator.createString(PASSWORD_LENGTH),
- registrar + "-ga"));
- registrars.add(
- ImmutableList.of(
- registrar + "-4",
- passwordGenerator.createString(PASSWORD_LENGTH),
- registrar + "-ga"));
- }
- registrars.add(
- ImmutableList.of(
- registrar + "-5", passwordGenerator.createString(PASSWORD_LENGTH), registrar + "-eap"));
-
- for (List r : registrars) {
- createRegistrar(r.get(0), r.get(1), r.get(2));
- createRegistrarContact(r.get(0));
- }
+ ImmutableMap clientIdToTld = oteAccountBuilder.buildAndPersist();
StringBuilder output = new StringBuilder();
output.append("Copy these usernames/passwords back into the onboarding bug:\n\n");
-
- for (List r : registrars) {
- output.append("Login: " + r.get(0) + "\n");
- output.append("Password: " + r.get(1) + "\n");
- output.append("TLD: " + r.get(2) + "\n\n");
- }
+ clientIdToTld.forEach(
+ (clientId, tld) -> {
+ output.append(
+ String.format("Login: %s\nPassword: %s\nTLD: %s\n\n", clientId, password, tld));
+ });
return output.toString();
}
diff --git a/javatests/google/registry/model/OteAccountBuilderTest.java b/javatests/google/registry/model/OteAccountBuilderTest.java
new file mode 100644
index 000000000..792f8cd84
--- /dev/null
+++ b/javatests/google/registry/model/OteAccountBuilderTest.java
@@ -0,0 +1,302 @@
+// Copyright 2018 The Nomulus Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package google.registry.model;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth8.assertThat;
+import static google.registry.testing.CertificateSamples.SAMPLE_CERT;
+import static google.registry.testing.CertificateSamples.SAMPLE_CERT_HASH;
+import static google.registry.testing.DatastoreHelper.persistPremiumList;
+import static google.registry.testing.JUnitBackports.assertThrows;
+import static google.registry.util.DateTimeUtils.START_OF_TIME;
+import static org.joda.money.CurrencyUnit.USD;
+
+import com.google.common.collect.ImmutableList;
+import google.registry.model.registrar.Registrar;
+import google.registry.model.registrar.RegistrarContact;
+import google.registry.model.registry.Registry;
+import google.registry.model.registry.Registry.TldState;
+import google.registry.testing.AppEngineRule;
+import google.registry.testing.DatastoreHelper;
+import google.registry.util.CidrAddressBlock;
+import google.registry.util.SystemClock;
+import org.joda.money.Money;
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
+import org.joda.time.Duration;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public final class OteAccountBuilderTest {
+
+ @Rule public final AppEngineRule appEngine = AppEngineRule.builder().withDatastore().build();
+
+ @Test
+ public void testGetRegistrarToTldMap() {
+ assertThat(OteAccountBuilder.forClientId("myclientid").getClientIdToTldMap())
+ .containsExactly(
+ "myclientid-1", "myclientid-sunrise",
+ "myclientid-2", "myclientid-landrush",
+ "myclientid-3", "myclientid-ga",
+ "myclientid-4", "myclientid-ga",
+ "myclientid-5", "myclientid-eap");
+ }
+
+ @Before
+ public void setUp() {
+ persistPremiumList("default_sandbox_list", "sandbox,USD 1000");
+ }
+
+ private void assertTldExists(String tld, Registry.TldState tldState) {
+ Registry registry = Registry.get(tld);
+ assertThat(registry).isNotNull();
+ assertThat(registry.getPremiumList().getName()).isEqualTo("default_sandbox_list");
+ assertThat(registry.getTldStateTransitions()).containsExactly(START_OF_TIME, tldState);
+ assertThat(registry.getDnsWriters()).containsExactly("VoidDnsWriter");
+ assertThat(registry.getAddGracePeriodLength()).isEqualTo(Duration.standardDays(5));
+ assertThat(registry.getPendingDeleteLength()).isEqualTo(Duration.standardDays(5));
+ assertThat(registry.getRedemptionGracePeriodLength()).isEqualTo(Duration.standardDays(30));
+ assertThat(registry.getEapFeeScheduleAsMap()).containsExactly(START_OF_TIME, Money.of(USD, 0));
+ }
+
+ private void assertTldExistsGa(String tld, Money eapFee) {
+ Registry registry = Registry.get(tld);
+ assertThat(registry).isNotNull();
+ assertThat(registry.getPremiumList().getName()).isEqualTo("default_sandbox_list");
+ assertThat(registry.getTldStateTransitions())
+ .containsExactly(START_OF_TIME, TldState.GENERAL_AVAILABILITY);
+ assertThat(registry.getDnsWriters()).containsExactly("VoidDnsWriter");
+ assertThat(registry.getAddGracePeriodLength()).isEqualTo(Duration.standardHours(1));
+ assertThat(registry.getPendingDeleteLength()).isEqualTo(Duration.standardMinutes(5));
+ assertThat(registry.getRedemptionGracePeriodLength()).isEqualTo(Duration.standardMinutes(10));
+ assertThat(registry.getCurrency()).isEqualTo(eapFee.getCurrencyUnit());
+ // This uses "now" on purpose - so the test will break at 2022 when the current EapFee in OTE
+ // goes back to 0
+ assertThat(registry.getEapFeeFor(DateTime.now(DateTimeZone.UTC)).getCost())
+ .isEqualTo(eapFee.getAmount());
+ }
+
+ private void assertRegistrarExists(String clientId, String tld) {
+ Registrar registrar = Registrar.loadByClientId(clientId).orElse(null);
+ assertThat(registrar).isNotNull();
+ assertThat(registrar.getType()).isEqualTo(Registrar.Type.OTE);
+ assertThat(registrar.getState()).isEqualTo(Registrar.State.ACTIVE);
+ assertThat(registrar.getAllowedTlds()).containsExactly(tld);
+ }
+
+ private void assertContactExists(String clientId, String email) {
+ Registrar registrar = Registrar.loadByClientId(clientId).get();
+ assertThat(registrar.getContacts().stream().map(RegistrarContact::getEmailAddress))
+ .contains(email);
+ RegistrarContact contact =
+ registrar.getContacts().stream()
+ .filter(c -> email.equals(c.getEmailAddress()))
+ .findAny()
+ .get();
+ assertThat(contact.getEmailAddress()).isEqualTo(email);
+ assertThat(contact.getGaeUserId()).isNotEmpty();
+ }
+
+ @Test
+ public void testCreateOteEntities_success() {
+ OteAccountBuilder.forClientId("myclientid").addContact("email@example.com").buildAndPersist();
+
+ assertTldExists("myclientid-sunrise", TldState.START_DATE_SUNRISE);
+ assertTldExists("myclientid-landrush", TldState.LANDRUSH);
+ assertTldExistsGa("myclientid-ga", Money.of(USD, 0));
+ assertTldExistsGa("myclientid-eap", Money.of(USD, 100));
+ assertRegistrarExists("myclientid-1", "myclientid-sunrise");
+ assertRegistrarExists("myclientid-2", "myclientid-landrush");
+ assertRegistrarExists("myclientid-3", "myclientid-ga");
+ assertRegistrarExists("myclientid-4", "myclientid-ga");
+ assertRegistrarExists("myclientid-5", "myclientid-eap");
+ assertContactExists("myclientid-1", "email@example.com");
+ assertContactExists("myclientid-2", "email@example.com");
+ assertContactExists("myclientid-3", "email@example.com");
+ assertContactExists("myclientid-4", "email@example.com");
+ assertContactExists("myclientid-5", "email@example.com");
+ }
+
+ @Test
+ public void testCreateOteEntities_multipleContacts_success() {
+ OteAccountBuilder.forClientId("myclientid")
+ .addContact("email@example.com")
+ .addContact("other@example.com")
+ .addContact("someone@example.com")
+ .buildAndPersist();
+
+ assertTldExists("myclientid-sunrise", TldState.START_DATE_SUNRISE);
+ assertTldExists("myclientid-landrush", TldState.LANDRUSH);
+ assertTldExistsGa("myclientid-ga", Money.of(USD, 0));
+ assertTldExistsGa("myclientid-eap", Money.of(USD, 100));
+ assertRegistrarExists("myclientid-1", "myclientid-sunrise");
+ assertRegistrarExists("myclientid-2", "myclientid-landrush");
+ assertRegistrarExists("myclientid-3", "myclientid-ga");
+ assertRegistrarExists("myclientid-4", "myclientid-ga");
+ assertRegistrarExists("myclientid-5", "myclientid-eap");
+ assertContactExists("myclientid-1", "email@example.com");
+ assertContactExists("myclientid-2", "email@example.com");
+ assertContactExists("myclientid-3", "email@example.com");
+ assertContactExists("myclientid-4", "email@example.com");
+ assertContactExists("myclientid-5", "email@example.com");
+ assertContactExists("myclientid-1", "other@example.com");
+ assertContactExists("myclientid-2", "other@example.com");
+ assertContactExists("myclientid-3", "other@example.com");
+ assertContactExists("myclientid-4", "other@example.com");
+ assertContactExists("myclientid-5", "other@example.com");
+ assertContactExists("myclientid-1", "someone@example.com");
+ assertContactExists("myclientid-2", "someone@example.com");
+ assertContactExists("myclientid-3", "someone@example.com");
+ assertContactExists("myclientid-4", "someone@example.com");
+ assertContactExists("myclientid-5", "someone@example.com");
+ }
+
+ @Test
+ public void testCreateOteEntities_setPassword() {
+ OteAccountBuilder.forClientId("myclientid").setPassword("myPassword").buildAndPersist();
+
+ assertThat(Registrar.loadByClientId("myclientid-3").get().testPassword("myPassword")).isTrue();
+ }
+
+ @Test
+ public void testCreateOteEntities_setCertificateHash() {
+ OteAccountBuilder.forClientId("myclientid")
+ .setCertificateHash(SAMPLE_CERT_HASH)
+ .buildAndPersist();
+
+ assertThat(Registrar.loadByClientId("myclientid-3").get().getClientCertificateHash())
+ .isEqualTo(SAMPLE_CERT_HASH);
+ }
+
+ @Test
+ public void testCreateOteEntities_setCertificate() {
+ OteAccountBuilder.forClientId("myclientid")
+ .setCertificate(SAMPLE_CERT, new SystemClock().nowUtc())
+ .buildAndPersist();
+
+ assertThat(Registrar.loadByClientId("myclientid-3").get().getClientCertificateHash())
+ .isEqualTo(SAMPLE_CERT_HASH);
+ assertThat(Registrar.loadByClientId("myclientid-3").get().getClientCertificate())
+ .isEqualTo(SAMPLE_CERT);
+ }
+
+ @Test
+ public void testCreateOteEntities_setIpWhitelist() {
+ OteAccountBuilder.forClientId("myclientid")
+ .setIpWhitelist(ImmutableList.of("1.1.1.0/24"))
+ .buildAndPersist();
+
+ assertThat(Registrar.loadByClientId("myclientid-3").get().getIpAddressWhitelist())
+ .containsExactly(CidrAddressBlock.create("1.1.1.0/24"));
+ }
+
+ @Test
+ public void testCreateOteEntities_invalidClientId_fails() {
+ assertThat(
+ assertThrows(
+ IllegalArgumentException.class, () -> OteAccountBuilder.forClientId("3blobio")))
+ .hasMessageThat()
+ .isEqualTo("Invalid registrar name: 3blobio");
+ }
+
+ @Test
+ public void testCreateOteEntities_clientIdTooShort_fails() {
+ assertThat(
+ assertThrows(IllegalArgumentException.class, () -> OteAccountBuilder.forClientId("bl")))
+ .hasMessageThat()
+ .isEqualTo("Invalid registrar name: bl");
+ }
+
+ @Test
+ public void testCreateOteEntities_clientIdTooLong_fails() {
+ assertThat(
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> OteAccountBuilder.forClientId("blobiotoooolong")))
+ .hasMessageThat()
+ .isEqualTo("Invalid registrar name: blobiotoooolong");
+ }
+
+ @Test
+ public void testCreateOteEntities_clientIdBadCharacter_fails() {
+ assertThat(
+ assertThrows(
+ IllegalArgumentException.class, () -> OteAccountBuilder.forClientId("blo#bio")))
+ .hasMessageThat()
+ .isEqualTo("Invalid registrar name: blo#bio");
+ }
+
+ @Test
+ public void testCreateOteEntities_entityExists_failsWhenNotReplaceExisting() {
+ DatastoreHelper.persistSimpleResource(
+ AppEngineRule.makeRegistrar1().asBuilder().setClientId("myclientid-1").build());
+ OteAccountBuilder oteSetupHelper = OteAccountBuilder.forClientId("myclientid");
+
+ assertThat(assertThrows(IllegalStateException.class, () -> oteSetupHelper.buildAndPersist()))
+ .hasMessageThat()
+ .contains("Found existing object(s) conflicting with OT&E objects");
+ }
+
+ @Test
+ public void testCreateOteEntities_entityExists_succeedsWhenReplaceExisting() {
+ DatastoreHelper.persistSimpleResource(
+ AppEngineRule.makeRegistrar1().asBuilder().setClientId("myclientid-1").build());
+ DatastoreHelper.createTld("myclientid-landrush", Registry.TldState.SUNRUSH);
+
+ OteAccountBuilder.forClientId("myclientid").setReplaceExisting(true).buildAndPersist();
+
+ assertTldExists("myclientid-landrush", TldState.LANDRUSH);
+ assertRegistrarExists("myclientid-3", "myclientid-ga");
+ }
+
+ @Test
+ public void testCreateOteEntities_doubleCreation_actuallyReplaces() {
+ OteAccountBuilder.forClientId("myclientid")
+ .setPassword("oldPassword")
+ .addContact("email@example.com")
+ .buildAndPersist();
+
+ assertThat(Registrar.loadByClientId("myclientid-3").get().testPassword("oldPassword")).isTrue();
+
+ OteAccountBuilder.forClientId("myclientid")
+ .setPassword("newPassword")
+ .addContact("email@example.com")
+ .setReplaceExisting(true)
+ .buildAndPersist();
+
+ assertThat(Registrar.loadByClientId("myclientid-3").get().testPassword("oldPassword"))
+ .isFalse();
+ assertThat(Registrar.loadByClientId("myclientid-3").get().testPassword("newPassword")).isTrue();
+ }
+
+ @Test
+ public void testCreateOteEntities_doubleCreation_keepsOldContacts() {
+ OteAccountBuilder.forClientId("myclientid").addContact("email@example.com").buildAndPersist();
+
+ assertContactExists("myclientid-3", "email@example.com");
+
+ OteAccountBuilder.forClientId("myclientid")
+ .addContact("other@example.com")
+ .setReplaceExisting(true)
+ .buildAndPersist();
+
+ assertContactExists("myclientid-3", "other@example.com");
+ assertContactExists("myclientid-3", "email@example.com");
+ }
+}
diff --git a/javatests/google/registry/model/registrar/RegistrarTest.java b/javatests/google/registry/model/registrar/RegistrarTest.java
index 066660683..ed095087f 100644
--- a/javatests/google/registry/model/registrar/RegistrarTest.java
+++ b/javatests/google/registry/model/registrar/RegistrarTest.java
@@ -23,6 +23,7 @@ import static google.registry.testing.CertificateSamples.SAMPLE_CERT2_HASH;
import static google.registry.testing.CertificateSamples.SAMPLE_CERT_HASH;
import static google.registry.testing.DatastoreHelper.cloneAndSetAutoTimestamps;
import static google.registry.testing.DatastoreHelper.createTld;
+import static google.registry.testing.DatastoreHelper.newRegistry;
import static google.registry.testing.DatastoreHelper.persistResource;
import static google.registry.testing.DatastoreHelper.persistSimpleResource;
import static google.registry.testing.DatastoreHelper.persistSimpleResources;
@@ -33,10 +34,12 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.googlecode.objectify.Key;
+import google.registry.config.RegistryConfig;
import google.registry.model.EntityTestCase;
import google.registry.model.common.EntityGroupRoot;
import google.registry.model.registrar.Registrar.State;
import google.registry.model.registrar.Registrar.Type;
+import google.registry.model.registry.Registries;
import google.registry.util.CidrAddressBlock;
import org.joda.money.CurrencyUnit;
import org.junit.Before;
@@ -415,6 +418,77 @@ public class RegistrarTest extends EntityTestCase {
IllegalArgumentException.class, () -> new Registrar.Builder().setPhonePasscode("code1"));
}
+ @Test
+ public void testSuccess_setAllowedTlds() {
+ assertThat(
+ registrar.asBuilder()
+ .setAllowedTlds(ImmutableSet.of("xn--q9jyb4c"))
+ .build()
+ .getAllowedTlds())
+ .containsExactly("xn--q9jyb4c");
+ }
+
+ @Test
+ public void testSuccess_setAllowedTldsUncached() {
+ assertThat(
+ registrar.asBuilder()
+ .setAllowedTldsUncached(ImmutableSet.of("xn--q9jyb4c"))
+ .build()
+ .getAllowedTlds())
+ .containsExactly("xn--q9jyb4c");
+ }
+
+ @Test
+ public void testFailure_setAllowedTlds_nonexistentTld() {
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> registrar.asBuilder().setAllowedTlds(ImmutableSet.of("bad")));
+ }
+
+ @Test
+ public void testFailure_setAllowedTldsUncached_nonexistentTld() {
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> registrar.asBuilder().setAllowedTldsUncached(ImmutableSet.of("bad")));
+ }
+
+ @Test
+ public void testSuccess_setAllowedTldsUncached_newTldNotInCache() {
+ // Cache duration in tests is 0. To make sure the data isn't in the cache we have to set it to a
+ // higher value and reset the cache.
+ RegistryConfig.CONFIG_SETTINGS.get().caching.singletonCacheRefreshSeconds = 600;
+ Registries.resetCache();
+ // Make sure the TLD we want to create doesn't exist yet.
+ // This is also important because getTlds fills out the cache when used.
+ assertThat(Registries.getTlds()).doesNotContain("newtld");
+ // We can't use createTld here because it failes when the cache is used.
+ persistResource(newRegistry("newtld", "NEWTLD"));
+ // Make sure we set up the cache correctly, so the newly created TLD isn't in the cache
+ assertThat(Registries.getTlds()).doesNotContain("newtld");
+
+ // Test that the uncached version works
+ assertThat(
+ registrar.asBuilder()
+ .setAllowedTldsUncached(ImmutableSet.of("newtld"))
+ .build()
+ .getAllowedTlds())
+ .containsExactly("newtld");
+
+ // Test that the "regular" cached version fails. If this doesn't throw - then we changed how the
+ // cached version works:
+ // - either we switched to a different cache type/duration, and we haven't actually set up that
+ // cache in the test
+ // - or we stopped using the cache entirely and we should rethink if the Uncached version is
+ // still needed
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> registrar.asBuilder().setAllowedTlds(ImmutableSet.of("newtld")));
+
+ // Make sure the cache hasn't expired during the test and "newtld" is still not in the cached
+ // TLDs
+ assertThat(Registries.getTlds()).doesNotContain("newtld");
+ }
+
@Test
public void testLoadByClientIdCached_isTransactionless() {
ofy()
diff --git a/javatests/google/registry/tools/SetupOteCommandTest.java b/javatests/google/registry/tools/SetupOteCommandTest.java
index dc403172b..0b6b92bc3 100644
--- a/javatests/google/registry/tools/SetupOteCommandTest.java
+++ b/javatests/google/registry/tools/SetupOteCommandTest.java
@@ -34,6 +34,7 @@ import google.registry.model.registrar.RegistrarContact;
import google.registry.model.registry.Registry;
import google.registry.model.registry.Registry.TldState;
import google.registry.testing.DeterministicStringGenerator;
+import google.registry.testing.FakeClock;
import google.registry.util.CidrAddressBlock;
import java.security.cert.CertificateParsingException;
import org.joda.money.CurrencyUnit;
@@ -46,23 +47,16 @@ import org.junit.Test;
/** Unit tests for {@link SetupOteCommand}. */
public class SetupOteCommandTest extends CommandTestCase {
- ImmutableList passwords =
- ImmutableList.of(
- "abcdefghijklmnop",
- "qrstuvwxyzabcdef",
- "ghijklmnopqrstuv",
- "wxyzabcdefghijkl",
- "mnopqrstuvwxyzab");
+ static final String PASSWORD = "abcdefghijklmnop";
+
DeterministicStringGenerator passwordGenerator =
new DeterministicStringGenerator("abcdefghijklmnopqrstuvwxyz");
@Before
public void init() {
- SetupOteCommand.interactive = false;
- command.validDnsWriterNames = ImmutableSet.of("FooDnsWriter", "BarDnsWriter", "VoidDnsWriter");
command.passwordGenerator = passwordGenerator;
+ command.clock = new FakeClock(DateTime.parse("2018-07-07TZ"));
persistPremiumList("default_sandbox_list", "sandbox,USD 1000");
- persistPremiumList("alternate_list", "rich,USD 3000");
}
/** Verify TLD creation. */
@@ -70,8 +64,6 @@ public class SetupOteCommandTest extends CommandTestCase {
String tldName,
String roidSuffix,
TldState tldState,
- String dnsWriter,
- String premiumList,
Duration addGracePeriodLength,
Duration redemptionGracePeriodLength,
Duration pendingDeleteLength,
@@ -80,9 +72,9 @@ public class SetupOteCommandTest extends CommandTestCase {
assertThat(registry).isNotNull();
assertThat(registry.getRoidSuffix()).isEqualTo(roidSuffix);
assertThat(registry.getTldState(DateTime.now(UTC))).isEqualTo(tldState);
- assertThat(registry.getDnsWriters()).containsExactly(dnsWriter);
+ assertThat(registry.getDnsWriters()).containsExactly("VoidDnsWriter");
assertThat(registry.getPremiumList()).isNotNull();
- assertThat(registry.getPremiumList().getName()).isEqualTo(premiumList);
+ assertThat(registry.getPremiumList().getName()).isEqualTo("default_sandbox_list");
assertThat(registry.getAddGracePeriodLength()).isEqualTo(addGracePeriodLength);
assertThat(registry.getRedemptionGracePeriodLength()).isEqualTo(redemptionGracePeriodLength);
assertThat(registry.getPendingDeleteLength()).isEqualTo(pendingDeleteLength);
@@ -98,20 +90,18 @@ public class SetupOteCommandTest extends CommandTestCase {
Money.of(CurrencyUnit.USD, 0),
DateTime.parse("2018-03-01T00:00:00Z"),
Money.of(CurrencyUnit.USD, 100),
- DateTime.parse("2022-03-01T00:00:00Z"),
+ DateTime.parse("2030-03-01T00:00:00Z"),
Money.of(CurrencyUnit.USD, 0)));
}
}
/** Verify TLD creation with registry default durations. */
private void verifyTldCreation(
- String tldName, String roidSuffix, TldState tldState, String dnsWriter, String premiumList) {
+ String tldName, String roidSuffix, TldState tldState) {
verifyTldCreation(
tldName,
roidSuffix,
tldState,
- dnsWriter,
- premiumList,
Registry.DEFAULT_ADD_GRACE_PERIOD,
Registry.DEFAULT_REDEMPTION_GRACE_PERIOD,
Registry.DEFAULT_PENDING_DELETE_LENGTH,
@@ -162,23 +152,14 @@ public class SetupOteCommandTest extends CommandTestCase {
"--ip_whitelist=1.1.1.1",
"--registrar=blobio",
"--email=contact@email.com",
- "--dns_writers=VoidDnsWriter",
"--certfile=" + getCertFilename());
- verifyTldCreation(
- "blobio-sunrise",
- "BLOBIOS0",
- TldState.START_DATE_SUNRISE,
- "VoidDnsWriter",
- "default_sandbox_list");
- verifyTldCreation(
- "blobio-landrush", "BLOBIOL1", TldState.LANDRUSH, "VoidDnsWriter", "default_sandbox_list");
+ verifyTldCreation("blobio-sunrise", "BLOBIOS0", TldState.START_DATE_SUNRISE);
+ verifyTldCreation("blobio-landrush", "BLOBIOL1", TldState.LANDRUSH);
verifyTldCreation(
"blobio-ga",
"BLOBIOG2",
TldState.GENERAL_AVAILABILITY,
- "VoidDnsWriter",
- "default_sandbox_list",
Duration.standardMinutes(60),
Duration.standardMinutes(10),
Duration.standardMinutes(5),
@@ -187,8 +168,6 @@ public class SetupOteCommandTest extends CommandTestCase {
"blobio-eap",
"BLOBIOE3",
TldState.GENERAL_AVAILABILITY,
- "VoidDnsWriter",
- "default_sandbox_list",
Duration.standardMinutes(60),
Duration.standardMinutes(10),
Duration.standardMinutes(5),
@@ -197,11 +176,11 @@ public class SetupOteCommandTest extends CommandTestCase {
ImmutableList ipAddress = ImmutableList.of(
CidrAddressBlock.create("1.1.1.1"));
- verifyRegistrarCreation("blobio-1", "blobio-sunrise", passwords.get(0), ipAddress);
- verifyRegistrarCreation("blobio-2", "blobio-landrush", passwords.get(1), ipAddress);
- verifyRegistrarCreation("blobio-3", "blobio-ga", passwords.get(2), ipAddress);
- verifyRegistrarCreation("blobio-4", "blobio-ga", passwords.get(3), ipAddress);
- verifyRegistrarCreation("blobio-5", "blobio-eap", passwords.get(4), ipAddress);
+ verifyRegistrarCreation("blobio-1", "blobio-sunrise", PASSWORD, ipAddress);
+ verifyRegistrarCreation("blobio-2", "blobio-landrush", PASSWORD, ipAddress);
+ verifyRegistrarCreation("blobio-3", "blobio-ga", PASSWORD, ipAddress);
+ verifyRegistrarCreation("blobio-4", "blobio-ga", PASSWORD, ipAddress);
+ verifyRegistrarCreation("blobio-5", "blobio-eap", PASSWORD, ipAddress);
verifyRegistrarContactCreation("blobio-1", "contact@email.com");
verifyRegistrarContactCreation("blobio-2", "contact@email.com");
@@ -216,23 +195,14 @@ public class SetupOteCommandTest extends CommandTestCase {
"--ip_whitelist=1.1.1.1",
"--registrar=abc",
"--email=abc@email.com",
- "--dns_writers=VoidDnsWriter",
"--certfile=" + getCertFilename());
- verifyTldCreation(
- "abc-sunrise",
- "ABCSUNR0",
- TldState.START_DATE_SUNRISE,
- "VoidDnsWriter",
- "default_sandbox_list");
- verifyTldCreation(
- "abc-landrush", "ABCLAND1", TldState.LANDRUSH, "VoidDnsWriter", "default_sandbox_list");
+ verifyTldCreation("abc-sunrise", "ABCSUNR0", TldState.START_DATE_SUNRISE);
+ verifyTldCreation("abc-landrush", "ABCLAND1", TldState.LANDRUSH);
verifyTldCreation(
"abc-ga",
"ABCGA2",
TldState.GENERAL_AVAILABILITY,
- "VoidDnsWriter",
- "default_sandbox_list",
Duration.standardMinutes(60),
Duration.standardMinutes(10),
Duration.standardMinutes(5),
@@ -241,8 +211,6 @@ public class SetupOteCommandTest extends CommandTestCase {
"abc-eap",
"ABCEAP3",
TldState.GENERAL_AVAILABILITY,
- "VoidDnsWriter",
- "default_sandbox_list",
Duration.standardMinutes(60),
Duration.standardMinutes(10),
Duration.standardMinutes(5),
@@ -251,11 +219,11 @@ public class SetupOteCommandTest extends CommandTestCase {
ImmutableList ipAddress =
ImmutableList.of(CidrAddressBlock.create("1.1.1.1"));
- verifyRegistrarCreation("abc-1", "abc-sunrise", passwords.get(0), ipAddress);
- verifyRegistrarCreation("abc-2", "abc-landrush", passwords.get(1), ipAddress);
- verifyRegistrarCreation("abc-3", "abc-ga", passwords.get(2), ipAddress);
- verifyRegistrarCreation("abc-4", "abc-ga", passwords.get(3), ipAddress);
- verifyRegistrarCreation("abc-5", "abc-eap", passwords.get(4), ipAddress);
+ verifyRegistrarCreation("abc-1", "abc-sunrise", PASSWORD, ipAddress);
+ verifyRegistrarCreation("abc-2", "abc-landrush", PASSWORD, ipAddress);
+ verifyRegistrarCreation("abc-3", "abc-ga", PASSWORD, ipAddress);
+ verifyRegistrarCreation("abc-4", "abc-ga", PASSWORD, ipAddress);
+ verifyRegistrarCreation("abc-5", "abc-eap", PASSWORD, ipAddress);
verifyRegistrarContactCreation("abc-1", "abc@email.com");
verifyRegistrarContactCreation("abc-2", "abc@email.com");
@@ -267,19 +235,15 @@ public class SetupOteCommandTest extends CommandTestCase {
@Test
public void testSuccess_certificateHash() throws Exception {
runCommandForced(
- "--eap_only",
"--ip_whitelist=1.1.1.1",
"--registrar=blobio",
"--email=contact@email.com",
- "--dns_writers=VoidDnsWriter",
"--certhash=" + SAMPLE_CERT_HASH);
verifyTldCreation(
"blobio-eap",
"BLOBIOE3",
TldState.GENERAL_AVAILABILITY,
- "VoidDnsWriter",
- "default_sandbox_list",
Duration.standardMinutes(60),
Duration.standardMinutes(10),
Duration.standardMinutes(5),
@@ -288,36 +252,7 @@ public class SetupOteCommandTest extends CommandTestCase {
ImmutableList ipAddress =
ImmutableList.of(CidrAddressBlock.create("1.1.1.1"));
- verifyRegistrarCreation("blobio-5", "blobio-eap", passwords.get(0), ipAddress, true);
-
- verifyRegistrarContactCreation("blobio-5", "contact@email.com");
- }
-
- @Test
- public void testSuccess_eapOnly() throws Exception {
- runCommandForced(
- "--eap_only",
- "--ip_whitelist=1.1.1.1",
- "--registrar=blobio",
- "--email=contact@email.com",
- "--dns_writers=VoidDnsWriter",
- "--certfile=" + getCertFilename());
-
- verifyTldCreation(
- "blobio-eap",
- "BLOBIOE3",
- TldState.GENERAL_AVAILABILITY,
- "VoidDnsWriter",
- "default_sandbox_list",
- Duration.standardMinutes(60),
- Duration.standardMinutes(10),
- Duration.standardMinutes(5),
- true);
-
- ImmutableList ipAddress = ImmutableList.of(
- CidrAddressBlock.create("1.1.1.1"));
-
- verifyRegistrarCreation("blobio-5", "blobio-eap", passwords.get(0), ipAddress);
+ verifyRegistrarCreation("blobio-5", "blobio-eap", PASSWORD, ipAddress, true);
verifyRegistrarContactCreation("blobio-5", "contact@email.com");
}
@@ -328,23 +263,14 @@ public class SetupOteCommandTest extends CommandTestCase {
"--ip_whitelist=1.1.1.1,2.2.2.2",
"--registrar=blobio",
"--email=contact@email.com",
- "--dns_writers=FooDnsWriter",
"--certfile=" + getCertFilename());
- verifyTldCreation(
- "blobio-sunrise",
- "BLOBIOS0",
- TldState.START_DATE_SUNRISE,
- "FooDnsWriter",
- "default_sandbox_list");
- verifyTldCreation(
- "blobio-landrush", "BLOBIOL1", TldState.LANDRUSH, "FooDnsWriter", "default_sandbox_list");
+ verifyTldCreation("blobio-sunrise", "BLOBIOS0", TldState.START_DATE_SUNRISE);
+ verifyTldCreation("blobio-landrush", "BLOBIOL1", TldState.LANDRUSH);
verifyTldCreation(
"blobio-ga",
"BLOBIOG2",
TldState.GENERAL_AVAILABILITY,
- "FooDnsWriter",
- "default_sandbox_list",
Duration.standardMinutes(60),
Duration.standardMinutes(10),
Duration.standardMinutes(5),
@@ -353,8 +279,6 @@ public class SetupOteCommandTest extends CommandTestCase {
"blobio-eap",
"BLOBIOE3",
TldState.GENERAL_AVAILABILITY,
- "FooDnsWriter",
- "default_sandbox_list",
Duration.standardMinutes(60),
Duration.standardMinutes(10),
Duration.standardMinutes(5),
@@ -364,66 +288,11 @@ public class SetupOteCommandTest extends CommandTestCase {
CidrAddressBlock.create("1.1.1.1"),
CidrAddressBlock.create("2.2.2.2"));
- verifyRegistrarCreation("blobio-1", "blobio-sunrise", passwords.get(0), ipAddresses);
- verifyRegistrarCreation("blobio-2", "blobio-landrush", passwords.get(1), ipAddresses);
- verifyRegistrarCreation("blobio-3", "blobio-ga", passwords.get(2), ipAddresses);
- verifyRegistrarCreation("blobio-4", "blobio-ga", passwords.get(3), ipAddresses);
- verifyRegistrarCreation("blobio-5", "blobio-eap", passwords.get(4), ipAddresses);
-
- verifyRegistrarContactCreation("blobio-1", "contact@email.com");
- verifyRegistrarContactCreation("blobio-2", "contact@email.com");
- verifyRegistrarContactCreation("blobio-3", "contact@email.com");
- verifyRegistrarContactCreation("blobio-4", "contact@email.com");
- verifyRegistrarContactCreation("blobio-5", "contact@email.com");
- }
-
- @Test
- public void testSuccess_alternatePremiumList() throws Exception {
- runCommandForced(
- "--ip_whitelist=1.1.1.1",
- "--registrar=blobio",
- "--email=contact@email.com",
- "--certfile=" + getCertFilename(),
- "--dns_writers=BarDnsWriter",
- "--premium_list=alternate_list");
-
- verifyTldCreation(
- "blobio-sunrise",
- "BLOBIOS0",
- TldState.START_DATE_SUNRISE,
- "BarDnsWriter",
- "alternate_list");
- verifyTldCreation(
- "blobio-landrush", "BLOBIOL1", TldState.LANDRUSH, "BarDnsWriter", "alternate_list");
- verifyTldCreation(
- "blobio-ga",
- "BLOBIOG2",
- TldState.GENERAL_AVAILABILITY,
- "BarDnsWriter",
- "alternate_list",
- Duration.standardMinutes(60),
- Duration.standardMinutes(10),
- Duration.standardMinutes(5),
- false);
- verifyTldCreation(
- "blobio-eap",
- "BLOBIOE3",
- TldState.GENERAL_AVAILABILITY,
- "BarDnsWriter",
- "alternate_list",
- Duration.standardMinutes(60),
- Duration.standardMinutes(10),
- Duration.standardMinutes(5),
- true);
-
- ImmutableList ipAddress = ImmutableList.of(
- CidrAddressBlock.create("1.1.1.1"));
-
- verifyRegistrarCreation("blobio-1", "blobio-sunrise", passwords.get(0), ipAddress);
- verifyRegistrarCreation("blobio-2", "blobio-landrush", passwords.get(1), ipAddress);
- verifyRegistrarCreation("blobio-3", "blobio-ga", passwords.get(2), ipAddress);
- verifyRegistrarCreation("blobio-4", "blobio-ga", passwords.get(3), ipAddress);
- verifyRegistrarCreation("blobio-5", "blobio-eap", passwords.get(4), ipAddress);
+ verifyRegistrarCreation("blobio-1", "blobio-sunrise", PASSWORD, ipAddresses);
+ verifyRegistrarCreation("blobio-2", "blobio-landrush", PASSWORD, ipAddresses);
+ verifyRegistrarCreation("blobio-3", "blobio-ga", PASSWORD, ipAddresses);
+ verifyRegistrarCreation("blobio-4", "blobio-ga", PASSWORD, ipAddresses);
+ verifyRegistrarCreation("blobio-5", "blobio-eap", PASSWORD, ipAddresses);
verifyRegistrarContactCreation("blobio-1", "contact@email.com");
verifyRegistrarContactCreation("blobio-2", "contact@email.com");
@@ -441,7 +310,6 @@ public class SetupOteCommandTest extends CommandTestCase {
runCommandForced(
"--registrar=blobio",
"--email=contact@email.com",
- "--dns_writers=VoidDnsWriter",
"--certfile=" + getCertFilename()));
assertThat(thrown).hasMessageThat().contains("option is required: -w, --ip_whitelist");
}
@@ -455,7 +323,6 @@ public class SetupOteCommandTest extends CommandTestCase {
runCommandForced(
"--ip_whitelist=1.1.1.1",
"--email=contact@email.com",
- "--dns_writers=VoidDnsWriter",
"--certfile=" + getCertFilename()));
assertThat(thrown).hasMessageThat().contains("option is required: -r, --registrar");
}
@@ -469,7 +336,6 @@ public class SetupOteCommandTest extends CommandTestCase {
runCommandForced(
"--ip_whitelist=1.1.1.1",
"--email=contact@email.com",
- "--dns_writers=VoidDnsWriter",
"--registrar=blobio"));
assertThat(thrown)
.hasMessageThat()
@@ -486,7 +352,6 @@ public class SetupOteCommandTest extends CommandTestCase {
runCommandForced(
"--ip_whitelist=1.1.1.1",
"--email=contact@email.com",
- "--dns_writers=VoidDnsWriter",
"--registrar=blobio",
"--certfile=" + getCertFilename(),
"--certhash=" + SAMPLE_CERT_HASH));
@@ -496,20 +361,6 @@ public class SetupOteCommandTest extends CommandTestCase {
"Must specify exactly one of client certificate file or client certificate hash.");
}
- @Test
- public void testFailure_missingDnsWriter() {
- ParameterException thrown =
- assertThrows(
- ParameterException.class,
- () ->
- runCommandForced(
- "--ip_whitelist=1.1.1.1",
- "--email=contact@email.com",
- "--certfile=" + getCertFilename(),
- "--registrar=blobio"));
- assertThat(thrown).hasMessageThat().contains("option is required: --dns_writers");
- }
-
@Test
public void testFailure_missingEmail() {
ParameterException thrown =
@@ -518,7 +369,6 @@ public class SetupOteCommandTest extends CommandTestCase {
() ->
runCommandForced(
"--ip_whitelist=1.1.1.1",
- "--dns_writers=VoidDnsWriter",
"--certfile=" + getCertFilename(),
"--registrar=blobio"));
assertThat(thrown).hasMessageThat().contains("option is required: --email");
@@ -534,7 +384,6 @@ public class SetupOteCommandTest extends CommandTestCase {
"--ip_whitelist=1.1.1.1",
"--registrar=blobio",
"--email=contact@email.com",
- "--dns_writers=VoidDnsWriter",
"--certfile=/dev/null"));
assertThat(thrown).hasMessageThat().contains("No X509Certificate found");
}
@@ -549,26 +398,8 @@ public class SetupOteCommandTest extends CommandTestCase {
"--ip_whitelist=1.1.1.1",
"--registrar=3blobio",
"--email=contact@email.com",
- "--dns_writers=VoidDnsWriter",
"--certfile=" + getCertFilename()));
- assertThat(thrown).hasMessageThat().contains("Registrar name is invalid");
- }
-
- @Test
- public void testFailure_invalidDnsWriter() {
- IllegalArgumentException thrown =
- assertThrows(
- IllegalArgumentException.class,
- () ->
- runCommandForced(
- "--ip_whitelist=1.1.1.1",
- "--registrar=blobio",
- "--email=contact@email.com",
- "--dns_writers=InvalidDnsWriter",
- "--certfile=" + getCertFilename()));
- assertThat(thrown)
- .hasMessageThat()
- .contains("Invalid DNS writer name(s) specified: [InvalidDnsWriter]");
+ assertThat(thrown).hasMessageThat().contains("Invalid registrar name: 3blobio");
}
@Test
@@ -581,9 +412,8 @@ public class SetupOteCommandTest extends CommandTestCase {
"--ip_whitelist=1.1.1.1",
"--registrar=bl",
"--email=contact@email.com",
- "--dns_writers=VoidDnsWriter",
"--certfile=" + getCertFilename()));
- assertThat(thrown).hasMessageThat().contains("Registrar name is invalid");
+ assertThat(thrown).hasMessageThat().contains("Invalid registrar name: bl");
}
@Test
@@ -596,9 +426,8 @@ public class SetupOteCommandTest extends CommandTestCase {
"--ip_whitelist=1.1.1.1",
"--registrar=blobiotoooolong",
"--email=contact@email.com",
- "--dns_writers=VoidDnsWriter",
"--certfile=" + getCertFilename()));
- assertThat(thrown).hasMessageThat().contains("Registrar name is invalid");
+ assertThat(thrown).hasMessageThat().contains("Invalid registrar name: blobiotoooolong");
}
@Test
@@ -611,25 +440,8 @@ public class SetupOteCommandTest extends CommandTestCase {
"--ip_whitelist=1.1.1.1",
"--registrar=blo#bio",
"--email=contact@email.com",
- "--dns_writers=VoidDnsWriter",
"--certfile=" + getCertFilename()));
- assertThat(thrown).hasMessageThat().contains("Registrar name is invalid");
- }
-
- @Test
- public void testFailure_invalidPremiumList() {
- IllegalArgumentException thrown =
- assertThrows(
- IllegalArgumentException.class,
- () ->
- runCommandForced(
- "--ip_whitelist=1.1.1.1",
- "--registrar=blobio",
- "--email=contact@email.com",
- "--dns_writers=VoidDnsWriter",
- "--certfile=" + getCertFilename(),
- "--premium_list=foo"));
- assertThat(thrown).hasMessageThat().contains("The premium list 'foo' doesn't exist");
+ assertThat(thrown).hasMessageThat().contains("Invalid registrar name: blo#bio");
}
@Test
@@ -643,9 +455,23 @@ public class SetupOteCommandTest extends CommandTestCase {
"--ip_whitelist=1.1.1.1",
"--registrar=blobio",
"--email=contact@email.com",
- "--dns_writers=VoidDnsWriter",
"--certfile=" + getCertFilename()));
- assertThat(thrown).hasMessageThat().contains("TLD 'blobio-sunrise' already exists");
+ assertThat(thrown).hasMessageThat().contains("Registry(\"blobio-sunrise\")");
+ }
+
+ @Test
+ public void testSuccess_tldExists_replaceExisting() throws Exception {
+ createTld("blobio-sunrise");
+
+ runCommandForced(
+ "--overwrite",
+ "--ip_whitelist=1.1.1.1",
+ "--registrar=blobio",
+ "--email=contact@email.com",
+ "--certfile=" + getCertFilename());
+
+ verifyTldCreation("blobio-sunrise", "BLOBIOS0", TldState.START_DATE_SUNRISE);
+ verifyTldCreation("blobio-landrush", "BLOBIOL1", TldState.LANDRUSH);
}
@Test
@@ -663,8 +489,29 @@ public class SetupOteCommandTest extends CommandTestCase {
"--ip_whitelist=1.1.1.1",
"--registrar=blobio",
"--email=contact@email.com",
- "--dns_writers=VoidDnsWriter",
"--certfile=" + getCertFilename()));
- assertThat(thrown).hasMessageThat().contains("Registrar blobio-1 already exists");
+ assertThat(thrown).hasMessageThat().contains("Registrar(\"blobio-1\")");
+ }
+
+ @Test
+ public void testSuccess_registrarExists_replaceExisting() throws Exception {
+ Registrar registrar = loadRegistrar("TheRegistrar").asBuilder()
+ .setClientId("blobio-1")
+ .setRegistrarName("blobio-1")
+ .build();
+ persistResource(registrar);
+
+ runCommandForced(
+ "--overwrite",
+ "--ip_whitelist=1.1.1.1",
+ "--registrar=blobio",
+ "--email=contact@email.com",
+ "--certfile=" + getCertFilename());
+
+ ImmutableList ipAddress = ImmutableList.of(
+ CidrAddressBlock.create("1.1.1.1"));
+
+ verifyRegistrarCreation("blobio-1", "blobio-sunrise", PASSWORD, ipAddress);
+ verifyRegistrarCreation("blobio-2", "blobio-landrush", PASSWORD, ipAddress);
}
}