diff --git a/java/google/registry/tools/CreateHostCommand.java b/java/google/registry/tools/CreateHostCommand.java new file mode 100644 index 000000000..fbb377fa5 --- /dev/null +++ b/java/google/registry/tools/CreateHostCommand.java @@ -0,0 +1,76 @@ +// Copyright 2016 The Domain Registry 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 google.registry.util.CollectionUtils.nullToEmpty; + +import com.beust.jcommander.Parameter; +import com.beust.jcommander.Parameters; +import com.google.common.collect.ImmutableList; +import com.google.common.net.InetAddresses; +import com.google.template.soy.data.SoyMapData; +import google.registry.tools.Command.GtechCommand; +import google.registry.tools.soy.HostCreateSoyInfo; +import java.net.Inet4Address; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.util.List; + +/** A command to create a new host via EPP. */ +@Parameters(separators = " =", commandDescription = "Create a new host via EPP.") +final class CreateHostCommand extends MutatingEppToolCommand implements GtechCommand { + + @Parameter( + names = {"-c", "--client"}, + description = "Client identifier of the registrar to execute the command as.", + required = true) + String clientIdentifier; + + @Parameter( + names = "--host", + description = "Host name.", + required = true) + private String hostName; + + @Parameter( + names = {"-a", "--addresses"}, + description = "List of addresses in IPv4 and/or IPv6 format.", + variableArity = true) + private List addresses; + + @Override + protected void initMutatingEppToolCommand() { + setSoyTemplate(HostCreateSoyInfo.getInstance(), HostCreateSoyInfo.HOSTCREATE); + ImmutableList.Builder ipv4Addresses = new ImmutableList.Builder<>(); + ImmutableList.Builder ipv6Addresses = new ImmutableList.Builder<>(); + for (String address : nullToEmpty(addresses)) { + InetAddress inetAddress = InetAddresses.forString(address); + if (inetAddress instanceof Inet4Address) { + ipv4Addresses.add(inetAddress.getHostAddress()); + } else if (inetAddress instanceof Inet6Address) { + ipv6Addresses.add(inetAddress.getHostAddress()); + } else { + throw new IllegalArgumentException( + String.format("IP address in unknown format: %s", address)); + } + } + addSoyRecord( + clientIdentifier, + new SoyMapData( + "hostname", hostName, + "ipv4addresses", ipv4Addresses.build(), + "ipv6addresses", ipv6Addresses.build())); + } +} diff --git a/java/google/registry/tools/GtechTool.java b/java/google/registry/tools/GtechTool.java index 51aec666b..e46095c0d 100644 --- a/java/google/registry/tools/GtechTool.java +++ b/java/google/registry/tools/GtechTool.java @@ -37,6 +37,7 @@ public final class GtechTool { .put("create_credit", CreateCreditCommand.class) .put("create_credit_balance", CreateCreditBalanceCommand.class) .put("create_domain", CreateDomainCommand.class) + .put("create_host", CreateHostCommand.class) .put("create_registrar_groups", CreateRegistrarGroupsCommand.class) .put("create_registrar", CreateRegistrarCommand.class) .put("create_sandbox_tld", CreateSandboxTldCommand.class) diff --git a/java/google/registry/tools/soy/HostCreate.soy b/java/google/registry/tools/soy/HostCreate.soy new file mode 100644 index 000000000..c2220a489 --- /dev/null +++ b/java/google/registry/tools/soy/HostCreate.soy @@ -0,0 +1,45 @@ +// Copyright 2016 The Domain Registry 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. + +{namespace domain.registry.tools autoescape="strict"} +/** + * Create host + */ +{template .hostcreate} + {@param hostname: string} + {@param? ipv4addresses: list} + {@param? ipv6addresses: list} + + + + + + + {$hostname} + {if $ipv4addresses} + {foreach $ipv4 in $ipv4addresses} + {$ipv4} + {/foreach} + {/if} + {if $ipv6addresses} + {foreach $ipv6 in $ipv6addresses} + {$ipv6} + {/foreach} + {/if} + + + GTechTool + + +{/template} diff --git a/javatests/google/registry/tools/CreateHostCommandTest.java b/javatests/google/registry/tools/CreateHostCommandTest.java new file mode 100644 index 000000000..1be0c34a5 --- /dev/null +++ b/javatests/google/registry/tools/CreateHostCommandTest.java @@ -0,0 +1,59 @@ +// Copyright 2016 The Domain Registry 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 google.registry.testing.DatastoreHelper.createTld; + +import com.beust.jcommander.ParameterException; +import org.junit.Test; + +/** Unit tests for {@link CreateHostCommand}. */ +public class CreateHostCommandTest extends EppToolCommandTestCase { + + @Test + public void testSuccess_complete() throws Exception { + createTld("tld"); + runCommandForced( + "--client=NewRegistrar", + "--host=example.tld", + "--addresses=162.100.102.99,2001:0db8:85a3:0000:0000:8a2e:0370:7334,4.5.6.7"); + eppVerifier().verifySent("host_create_complete.xml"); + } + + @Test + public void testSuccess_minimal() throws Exception { + // Test that each optional field can be omitted. + runCommandForced( + "--client=NewRegistrar", + "--host=notours.external"); + eppVerifier().verifySent("host_create_minimal.xml"); + } + + @Test + public void testFailure_missingHost() throws Exception { + thrown.expect(ParameterException.class); + runCommandForced("--client=NewRegistrar"); + } + + @Test + public void testFailure_invalidIpAddress() throws Exception { + createTld("tld"); + thrown.expect(IllegalArgumentException.class, "'a.b.c.d' is not an IP string literal."); + runCommandForced( + "--client=NewRegistrar", + "--host=example.tld", + "--addresses=a.b.c.d"); + } +} diff --git a/javatests/google/registry/tools/testdata/host_create_complete.xml b/javatests/google/registry/tools/testdata/host_create_complete.xml new file mode 100644 index 000000000..dcc596cfe --- /dev/null +++ b/javatests/google/registry/tools/testdata/host_create_complete.xml @@ -0,0 +1,13 @@ + + + + + example.tld + 162.100.102.99 + 4.5.6.7 + 2001:0db8:85a3:0000:0000:8a2e:0370:7334 + + + GTechTool + + diff --git a/javatests/google/registry/tools/testdata/host_create_minimal.xml b/javatests/google/registry/tools/testdata/host_create_minimal.xml new file mode 100644 index 000000000..97133dc88 --- /dev/null +++ b/javatests/google/registry/tools/testdata/host_create_minimal.xml @@ -0,0 +1,10 @@ + + + + + notours.external + + + GTechTool + +