diff --git a/java/google/registry/tools/BUILD b/java/google/registry/tools/BUILD index 469713d49..203e48532 100644 --- a/java/google/registry/tools/BUILD +++ b/java/google/registry/tools/BUILD @@ -69,6 +69,7 @@ java_library( "@com_beust_jcommander", "@com_google_api_client", "@com_google_apis_google_api_services_bigquery", + "@com_google_apis_google_api_services_dns", "@com_google_appengine_api_1_0_sdk", "@com_google_appengine_remote_api", "@com_google_appengine_remote_api//:link", diff --git a/java/google/registry/tools/CreateCdnsTld.java b/java/google/registry/tools/CreateCdnsTld.java new file mode 100644 index 000000000..c495ab67a --- /dev/null +++ b/java/google/registry/tools/CreateCdnsTld.java @@ -0,0 +1,104 @@ +// Copyright 2017 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.tools; + +import com.beust.jcommander.Parameter; +import com.beust.jcommander.Parameters; +import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; +import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport; +import com.google.api.client.http.HttpTransport; +import com.google.api.client.json.JsonFactory; +import com.google.api.client.json.jackson2.JacksonFactory; +import com.google.api.services.dns.Dns; +import com.google.api.services.dns.model.ManagedZone; +import com.google.common.annotations.VisibleForTesting; +import google.registry.config.RegistryConfig.Config; +import java.io.IOException; +import java.security.GeneralSecurityException; +import java.util.Arrays; +import javax.annotation.Nullable; +import javax.inject.Inject; + +@Parameters(separators = " =", commandDescription = "Create a Managed Zone for a TLD in Cloud DNS.") +class CreateCdnsTld implements Command { + + @Parameter(names = "--description", description = "Description of the new TLD.") + String description; + + @Parameter( + names = "--dns_name", + description = "DNS name of the new tld, including trailing period, e.g.: search.", + required = true + ) + String dnsName; + + @Nullable + @Parameter( + names = "--name", + description = "Managed zone name. If not specified, dns_name is used." + ) + String name; + + @Inject + @Config("projectId") + String projectId; + + @Override + public void run() throws IOException, GeneralSecurityException { + ManagedZone requestBody = new ManagedZone(); + requestBody.setDescription(description); + // TODO(b/67413698): allow parameterizing the nameserver set once it's safe to do so. + requestBody.setNameServerSet("cloud-dns-registry-test"); + requestBody.setDnsName(dnsName); + requestBody.setName((name != null) ? name : dnsName); + + Dns dnsService = createDnsService(); + Dns.ManagedZones.Create request = dnsService.managedZones().create(projectId, requestBody); + + ManagedZone response = request.execute(); + + System.err.println("Created managed zone: " + response); + } + + @VisibleForTesting + Dns createDnsService() throws IOException, GeneralSecurityException { + // TODO(b/67367533): We should be obtaining the Dns instance from CloudDnsWriter module. But + // to do this cleanly we need to refactor everything down to the credential object. Having + // done that, this method will go away and this class will become final. + HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport(); + JsonFactory jsonFactory = JacksonFactory.getDefaultInstance(); + + GoogleCredential credential = GoogleCredential.getApplicationDefault(); + if (credential.createScopedRequired()) { + credential = + credential.createScoped( + Arrays.asList( + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + "https://www.googleapis.com/auth/ndev.clouddns.readonly", + "https://www.googleapis.com/auth/ndev.clouddns.readwrite")); + } + + Dns.Builder builder = + new Dns.Builder(httpTransport, jsonFactory, credential).setApplicationName(projectId); + if (RegistryToolEnvironment.get() != RegistryToolEnvironment.PRODUCTION) { + builder + .setRootUrl("https://staging-www.sandbox.googleapis.com") + .setServicePath("dns/v2beta1_staging/projects/"); + } + + return builder.build(); + } +} diff --git a/java/google/registry/tools/RegistryTool.java b/java/google/registry/tools/RegistryTool.java index 58fd44c7b..4682a5f3c 100644 --- a/java/google/registry/tools/RegistryTool.java +++ b/java/google/registry/tools/RegistryTool.java @@ -36,6 +36,7 @@ public final class RegistryTool { .put("convert_idn", ConvertIdnCommand.class) .put("create_anchor_tenant", CreateAnchorTenantCommand.class) .put("create_auction_credits", CreateAuctionCreditsCommand.class) + .put("create_cdns_tld", CreateCdnsTld.class) .put("create_contact", CreateContactCommand.class) .put("create_credit", CreateCreditCommand.class) .put("create_credit_balance", CreateCreditBalanceCommand.class) diff --git a/java/google/registry/tools/RegistryToolComponent.java b/java/google/registry/tools/RegistryToolComponent.java index 204729bdf..bc4a54e0b 100644 --- a/java/google/registry/tools/RegistryToolComponent.java +++ b/java/google/registry/tools/RegistryToolComponent.java @@ -77,6 +77,7 @@ import javax.inject.Singleton; ) interface RegistryToolComponent { void inject(CreateAnchorTenantCommand command); + void inject(CreateCdnsTld command); void inject(CreateContactCommand command); void inject(CreateDomainCommand command); void inject(CreateLrpTokensCommand command); diff --git a/javatests/google/registry/tools/BUILD b/javatests/google/registry/tools/BUILD index 3dd21ff69..fd850228b 100644 --- a/javatests/google/registry/tools/BUILD +++ b/javatests/google/registry/tools/BUILD @@ -39,6 +39,7 @@ java_library( "//third_party/java/objectify:objectify-v4_1", "@com_beust_jcommander", "@com_google_api_client", + "@com_google_apis_google_api_services_dns", "@com_google_appengine_api_1_0_sdk//:testonly", "@com_google_appengine_remote_api//:link", "@com_google_auto_value", diff --git a/javatests/google/registry/tools/CreateCdnsTldTest.java b/javatests/google/registry/tools/CreateCdnsTldTest.java new file mode 100644 index 000000000..2c3ecab62 --- /dev/null +++ b/javatests/google/registry/tools/CreateCdnsTldTest.java @@ -0,0 +1,77 @@ +// Copyright 2017 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.tools; + +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.google.api.services.dns.Dns; +import com.google.api.services.dns.model.ManagedZone; +import java.io.IOException; +import java.security.GeneralSecurityException; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class CreateCdnsTldTest extends CommandTestCase { + + @Mock Dns dnsService; + @Mock Dns.ManagedZones managedZones; + @Mock Dns.ManagedZones.Create request; + @Captor ArgumentCaptor projectId; + @Captor ArgumentCaptor requestBody; + + @Before + public void setUp() throws Exception { + when(dnsService.managedZones()).thenReturn(managedZones); + when(managedZones.create(projectId.capture(), requestBody.capture())).thenReturn(request); + command = new CreateCdnsTldForTest(); + command.projectId = "test-project"; + } + + /** Fake the command class so we can override createDnsService() */ + class CreateCdnsTldForTest extends CreateCdnsTld { + @Override + Dns createDnsService() throws IOException, GeneralSecurityException { + return dnsService; + } + } + + @Test + public void testBasicFunctionality() throws Exception { + runCommand("--dns_name=tld.", "--name=tld", "--description=test run"); + verify(request).execute(); + assertThat(projectId.getValue()).isEqualTo("test-project"); + ManagedZone zone = requestBody.getValue(); + assertThat(zone.getNameServerSet()).isEqualTo("cloud-dns-registry-test"); + assertThat(zone.getDnsName()).isEqualTo("tld."); + assertThat(zone.getName()).isEqualTo("tld"); + } + + @Test + public void testNameDefault() throws Exception { + runCommand("--dns_name=tld.", "--description=test run"); + ManagedZone zone = requestBody.getValue(); + assertThat(zone.getNameServerSet()).isEqualTo("cloud-dns-registry-test"); + assertThat(zone.getDnsName()).isEqualTo("tld."); + assertThat(zone.getName()).isEqualTo("tld."); + } +}