diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/GlobalVlanAsyncClient.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/GlobalVlanAsyncClient.java index 7d07d1ff64..878199378a 100644 --- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/GlobalVlanAsyncClient.java +++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/GlobalVlanAsyncClient.java @@ -21,6 +21,7 @@ package org.jclouds.cloudstack.features; import com.google.common.util.concurrent.ListenableFuture; import org.jclouds.cloudstack.domain.VlanIPRange; import org.jclouds.cloudstack.filters.QuerySigner; +import org.jclouds.cloudstack.options.CreateVlanIPRangeOptions; import org.jclouds.cloudstack.options.ListVlanIPRangesOptions; import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.OnlyElement; @@ -29,6 +30,7 @@ import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.SelectJson; import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404; import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404; +import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404; import javax.ws.rs.Consumes; import javax.ws.rs.GET; @@ -74,4 +76,29 @@ public interface GlobalVlanAsyncClient { @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) ListenableFuture> listVlanIPRanges(ListVlanIPRangesOptions... options); + /** + * Creates a VLAN IP range. + * + * @param startIP the beginning IP address in the VLAN IP range + * @param endIP the ending IP address in the VLAN IP range + * @param options optional arguments + * @return the newly-create IP range. + */ + @GET + @QueryParams(keys = "command", values = "createVlanIpRange") + @SelectJson("vlaniprange") + @Consumes(MediaType.APPLICATION_JSON) + @ExceptionParser(ReturnNullOnNotFoundOr404.class) + ListenableFuture createVlanIPRange(@QueryParam("startip") String startIP, @QueryParam("endip") String endIP, CreateVlanIPRangeOptions... options); + + /** + * Deletes a VLAN IP range. + * @param rangeId the id of the VLAN IP range + * @return void + */ + @GET + @QueryParams(keys = "command", values = "deleteVlanIpRange") + @Consumes(MediaType.APPLICATION_JSON) + @ExceptionParser(ReturnVoidOnNotFoundOr404.class) + ListenableFuture deleteVlanIPRange(@QueryParam("id") long rangeId); } diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/GlobalVlanClient.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/GlobalVlanClient.java index 2050336b6a..3ac3f51820 100644 --- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/GlobalVlanClient.java +++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/GlobalVlanClient.java @@ -19,6 +19,7 @@ package org.jclouds.cloudstack.features; import org.jclouds.cloudstack.domain.VlanIPRange; +import org.jclouds.cloudstack.options.CreateVlanIPRangeOptions; import org.jclouds.cloudstack.options.ListVlanIPRangesOptions; import org.jclouds.concurrent.Timeout; @@ -51,4 +52,19 @@ public interface GlobalVlanClient { */ Set listVlanIPRanges(ListVlanIPRangesOptions... options); + /** + * Creates a VLAN IP range. + * + * @param startIP the beginning IP address in the VLAN IP range + * @param endIP the ending IP address in the VLAN IP range + * @param options optional arguments + * @return the newly-create IP range. + */ + VlanIPRange createVlanIPRange(String startIP, String endIP, CreateVlanIPRangeOptions... options); + + /** + * Deletes a VLAN IP range. + * @param rangeId the id of the VLAN IP range + */ + void deleteVlanIPRange(long rangeId); } diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/CreateVlanIPRangeOptions.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/CreateVlanIPRangeOptions.java new file mode 100644 index 0000000000..f977854643 --- /dev/null +++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/CreateVlanIPRangeOptions.java @@ -0,0 +1,123 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds licenses this file + * to you 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 org.jclouds.cloudstack.options; + +import com.google.common.collect.ImmutableSet; + +/** + * Options to the createVlanIPRange API call. + * + * @author Richard Downer + */ +public class CreateVlanIPRangeOptions extends AccountInDomainOptions { + + public static class Builder { + + public static CreateVlanIPRangeOptions accountInDomain(String account, long domain) { + return new CreateVlanIPRangeOptions().accountInDomain(account, domain); + } + + public static CreateVlanIPRangeOptions domainId(long domainId) { + return new CreateVlanIPRangeOptions().domainId(domainId); + } + + public static CreateVlanIPRangeOptions forVirtualNetwork(boolean forVirtualNetwork) { + return new CreateVlanIPRangeOptions().forVirtualNetwork(forVirtualNetwork); + } + + public static CreateVlanIPRangeOptions zoneId(long zoneId) { + return new CreateVlanIPRangeOptions().zoneId(zoneId); + } + + public static CreateVlanIPRangeOptions vlan(long vlan) { + return new CreateVlanIPRangeOptions().vlan(vlan); + } + + public static CreateVlanIPRangeOptions vlan(String vlan) { + return new CreateVlanIPRangeOptions().vlan(vlan); + } + + public static CreateVlanIPRangeOptions podId(long podId) { + return new CreateVlanIPRangeOptions().podId(podId); + } + + public static CreateVlanIPRangeOptions gateway(String gateway) { + return new CreateVlanIPRangeOptions().gateway(gateway); + } + + public static CreateVlanIPRangeOptions netmask(String netmask) { + return new CreateVlanIPRangeOptions().netmask(netmask); + } + + public static CreateVlanIPRangeOptions networkId(long networkId) { + return new CreateVlanIPRangeOptions().networkId(networkId); + } + + } + + @Override + public CreateVlanIPRangeOptions accountInDomain(String account, long domain) { + return (CreateVlanIPRangeOptions) super.accountInDomain(account, domain); + } + + @Override + public CreateVlanIPRangeOptions domainId(long domainId) { + return (CreateVlanIPRangeOptions) super.domainId(domainId); + } + + public CreateVlanIPRangeOptions forVirtualNetwork(boolean forVirtualNetwork) { + this.queryParameters.replaceValues("forvirtualnetwork", ImmutableSet.of(forVirtualNetwork+"")); + return this; + } + + public CreateVlanIPRangeOptions zoneId(long zoneId) { + this.queryParameters.replaceValues("zoneid", ImmutableSet.of(zoneId+"")); + return this; + } + + public CreateVlanIPRangeOptions vlan(long vlan) { + this.queryParameters.replaceValues("vlan", ImmutableSet.of(vlan+"")); + return this; + } + + public CreateVlanIPRangeOptions vlan(String vlan) { + this.queryParameters.replaceValues("vlan", ImmutableSet.of(vlan)); + return this; + } + + public CreateVlanIPRangeOptions podId(long podId) { + this.queryParameters.replaceValues("podid", ImmutableSet.of(podId+"")); + return this; + } + + public CreateVlanIPRangeOptions gateway(String gateway) { + this.queryParameters.replaceValues("gateway", ImmutableSet.of(gateway)); + return this; + } + + public CreateVlanIPRangeOptions netmask(String netmask) { + this.queryParameters.replaceValues("netmask", ImmutableSet.of(netmask)); + return this; + } + + public CreateVlanIPRangeOptions networkId(long networkId) { + this.queryParameters.replaceValues("networkid", ImmutableSet.of(networkId+"")); + return this; + } +} diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/GlobalVlanClientExpectTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/GlobalVlanClientExpectTest.java index 242d3d9265..80cad2a989 100644 --- a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/GlobalVlanClientExpectTest.java +++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/GlobalVlanClientExpectTest.java @@ -22,6 +22,7 @@ import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.ImmutableSet; import org.jclouds.cloudstack.CloudStackContext; import org.jclouds.cloudstack.domain.VlanIPRange; +import org.jclouds.cloudstack.options.CreateVlanIPRangeOptions; import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpResponse; import org.testng.annotations.Test; @@ -109,6 +110,73 @@ public class GlobalVlanClientExpectTest extends BaseCloudStackRestClientExpectTe assertEquals(client.listVlanIPRanges(), ImmutableSet.of()); } + public void testCreateVlanIpRangeWhenResponseIs2xx() { + GlobalVlanClient client = requestSendsResponse( + HttpRequest.builder() + .method("GET") + .endpoint( + URI.create("http://localhost:8080/client/api?response=json&" + + "command=createVlanIpRange&startip=10.22.22.51&endip=10.22.22.100&forvirtualnetwork=false&zoneid=2&vlan=untagged&account=system&domainid=1&podid=2&gateway=10.22.22.254&netmask=255.255.255.0&networkid=209&apiKey=identity&signature=XgDjPYAQNLMVCuSMGRA6QjV8mOY%3D")) + .headers( + ImmutableMultimap.builder() + .put("Accept", "application/json") + .build()) + .build(), + HttpResponse.builder() + .statusCode(200) + .payload(payloadFromResource("/createvlaniprangeresponse.json")) + .build()); + + VlanIPRange actual = client.createVlanIPRange("10.22.22.51", "10.22.22.100", new CreateVlanIPRangeOptions() + .forVirtualNetwork(false) + .zoneId(2) + .vlan("untagged") + .accountInDomain("system", 1) + .podId(2) + .gateway("10.22.22.254") + .netmask("255.255.255.0") + .networkId(209)); + + VlanIPRange expected = VlanIPRange.builder() + .id(2) + .forVirtualNetwork(false) + .zoneId(2) + .vlan("untagged") + .account("system") + .domainId(1) + .domain("ROOT") + .podId(2) + .podName("Dev Pod 2") + .gateway("10.22.22.254") + .netmask("255.255.255.0") + .startIP("10.22.22.51") + .endIP("10.22.22.100") + .networkId(209) + .build(); + + assertEquals(actual, expected); + } + + public void testDeleteVlanIpRangeWhenResponseIs2xx() { + GlobalVlanClient client = requestSendsResponse( + HttpRequest.builder() + .method("GET") + .endpoint( + URI.create("http://localhost:8080/client/api?response=json&" + + "command=deleteVlanIpRange&id=1&apiKey=identity&signature=tTBbpdCndgHXdR397fbbJaN1RZU%3D")) + .headers( + ImmutableMultimap.builder() + .put("Accept", "application/json") + .build()) + .build(), + HttpResponse.builder() + .statusCode(200) + .payload(payloadFromResource("/createvlaniprangeresponse.json")) + .build()); + + client.deleteVlanIPRange(1); + } + @Override protected GlobalVlanClient clientFrom(CloudStackContext context) { return context.getGlobalContext().getApi().getVlanClient(); diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/GlobalVlanClientLiveTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/GlobalVlanClientLiveTest.java index a86ceab556..af3e539ba9 100644 --- a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/GlobalVlanClientLiveTest.java +++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/GlobalVlanClientLiveTest.java @@ -20,16 +20,21 @@ package org.jclouds.cloudstack.features; import com.google.common.base.Strings; import com.google.common.collect.Iterables; +import org.jclouds.cloudstack.domain.Network; +import org.jclouds.cloudstack.domain.NetworkOffering; import org.jclouds.cloudstack.domain.VlanIPRange; +import org.jclouds.cloudstack.domain.Zone; +import org.jclouds.cloudstack.options.CreateVlanIPRangeOptions; import org.jclouds.cloudstack.options.ListVlanIPRangesOptions; +import org.jclouds.cloudstack.predicates.NetworkOfferingPredicates; +import org.jclouds.cloudstack.predicates.ZonePredicates; import org.testng.annotations.AfterClass; import org.testng.annotations.Test; import java.util.Set; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertFalse; -import static org.testng.Assert.assertTrue; +import static com.google.common.collect.Iterables.find; +import static org.testng.Assert.*; /** * Tests behavior of {@code GlobalVlanClient} @@ -39,6 +44,9 @@ import static org.testng.Assert.assertTrue; @Test(groups = "live", singleThreaded = true, testName = "GlobalVlanClientLiveTest") public class GlobalVlanClientLiveTest extends BaseCloudStackClientLiveTest { + private Network network; + private VlanIPRange range; + public void testListVlanIPRanges() throws Exception { Set response = globalAdminClient.getVlanClient().listVlanIPRanges(); assert null != response; @@ -63,8 +71,30 @@ public class GlobalVlanClientLiveTest extends BaseCloudStackClientLiveTest { } } + public void testCreateVlanIPRange() { + Zone zone = Iterables.find(client.getZoneClient().listZones(), ZonePredicates.supportsAdvancedNetworks()); + NetworkOffering offering = find(client.getOfferingClient().listNetworkOfferings(), NetworkOfferingPredicates.supportsGuestVirtualNetworks()); + + network = client.getNetworkClient().createNetworkInZone(zone.getId(), offering.getId(), "net-"+prefix, "jclouds test "+prefix); + + range = globalAdminClient.getVlanClient().createVlanIPRange("172.19.1.1", "172.19.1.199", CreateVlanIPRangeOptions.Builder + .accountInDomain(user.getAccount(), user.getDomainId()) + .forVirtualNetwork(true) + .vlan(1001) + .networkId(network.getId()) + ); + } + @AfterClass public void testFixtureTearDown() { + if (range != null) { + globalAdminClient.getVlanClient().deleteVlanIPRange(range.getId()); + range = null; + } + if (network != null) { + client.getNetworkClient().deleteNetwork(network.getId()); + network = null; + } } } diff --git a/apis/cloudstack/src/test/java/org/jclouds/cloudstack/options/CreateVlanIPRangeOptionsTest.java b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/options/CreateVlanIPRangeOptionsTest.java new file mode 100644 index 0000000000..4a072a4999 --- /dev/null +++ b/apis/cloudstack/src/test/java/org/jclouds/cloudstack/options/CreateVlanIPRangeOptionsTest.java @@ -0,0 +1,127 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds licenses this file + * to you 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 org.jclouds.cloudstack.options; + +import com.google.common.collect.ImmutableSet; +import org.testng.annotations.Test; + +import static org.jclouds.cloudstack.options.CreateVlanIPRangeOptions.Builder.*; +import static org.testng.Assert.assertEquals; + +/** + * Tests behavior of {@code CreateVlanIPRangeOptions} + * + * @author Richard Downer + */ +@Test(groups = "unit") +public class CreateVlanIPRangeOptionsTest { + + public void testAccountInDomain() { + CreateVlanIPRangeOptions options = new CreateVlanIPRangeOptions().accountInDomain("fred", 6); + assertEquals(ImmutableSet.of("fred"), options.buildQueryParameters().get("account")); + assertEquals(ImmutableSet.of("6"), options.buildQueryParameters().get("domainid")); + } + + public void testAccountInDomainStatic() { + CreateVlanIPRangeOptions options = accountInDomain("fred", 6); + assertEquals(ImmutableSet.of("fred"), options.buildQueryParameters().get("account")); + assertEquals(ImmutableSet.of("6"), options.buildQueryParameters().get("domainid")); + } + + public void testDomainId() { + CreateVlanIPRangeOptions options = new CreateVlanIPRangeOptions().domainId(6); + assertEquals(ImmutableSet.of("6"), options.buildQueryParameters().get("domainid")); + } + + public void testDomainIdStatic() { + CreateVlanIPRangeOptions options = domainId(6); + assertEquals(ImmutableSet.of("6"), options.buildQueryParameters().get("domainid")); + } + + public void testForVirtualNetwork() { + CreateVlanIPRangeOptions options = new CreateVlanIPRangeOptions().forVirtualNetwork(true); + assertEquals(ImmutableSet.of("true"), options.buildQueryParameters().get("forvirtualnetwork")); + } + + public void testForVirtualNetworkStatic() { + CreateVlanIPRangeOptions options = forVirtualNetwork(true); + assertEquals(ImmutableSet.of("true"), options.buildQueryParameters().get("forvirtualnetwork")); + } + + public void testGateway() { + CreateVlanIPRangeOptions options = new CreateVlanIPRangeOptions().gateway("192.168.42.24"); + assertEquals(ImmutableSet.of("192.168.42.24"), options.buildQueryParameters().get("gateway")); + } + + public void testGatewayStatic() { + CreateVlanIPRangeOptions options = gateway("192.168.42.24"); + assertEquals(ImmutableSet.of("192.168.42.24"), options.buildQueryParameters().get("gateway")); + } + + public void testNetmask() { + CreateVlanIPRangeOptions options = new CreateVlanIPRangeOptions().netmask("255.255.255.240"); + assertEquals(ImmutableSet.of("255.255.255.240"), options.buildQueryParameters().get("netmask")); + } + + public void testNetmaskStatic() { + CreateVlanIPRangeOptions options = netmask("255.255.255.240"); + assertEquals(ImmutableSet.of("255.255.255.240"), options.buildQueryParameters().get("netmask")); + } + + public void testNetworkId() { + CreateVlanIPRangeOptions options = new CreateVlanIPRangeOptions().networkId(9); + assertEquals(ImmutableSet.of("9"), options.buildQueryParameters().get("networkid")); + } + + public void testNetworkIdStatic() { + CreateVlanIPRangeOptions options = networkId(9); + assertEquals(ImmutableSet.of("9"), options.buildQueryParameters().get("networkid")); + } + + public void testPodId() { + CreateVlanIPRangeOptions options = new CreateVlanIPRangeOptions().podId(8); + assertEquals(ImmutableSet.of("8"), options.buildQueryParameters().get("podid")); + } + + public void testPodIdStatic() { + CreateVlanIPRangeOptions options = podId(8); + assertEquals(ImmutableSet.of("8"), options.buildQueryParameters().get("podid")); + } + + public void testVlan() { + CreateVlanIPRangeOptions options = new CreateVlanIPRangeOptions().vlan(1001); + assertEquals(ImmutableSet.of("1001"), options.buildQueryParameters().get("vlan")); + } + + public void testVlanStatic() { + CreateVlanIPRangeOptions options = vlan(1001); + assertEquals(ImmutableSet.of("1001"), options.buildQueryParameters().get("vlan")); + } + + public void testZoneId() { + CreateVlanIPRangeOptions options = new CreateVlanIPRangeOptions().zoneId(7); + assertEquals(ImmutableSet.of("7"), options.buildQueryParameters().get("zoneid")); + } + + public void testZoneIdStatic() { + CreateVlanIPRangeOptions options = zoneId(7); + assertEquals(ImmutableSet.of("7"), options.buildQueryParameters().get("zoneid")); + } + +} diff --git a/apis/cloudstack/src/test/resources/createvlaniprangeresponse.json b/apis/cloudstack/src/test/resources/createvlaniprangeresponse.json new file mode 100644 index 0000000000..b463074874 --- /dev/null +++ b/apis/cloudstack/src/test/resources/createvlaniprangeresponse.json @@ -0,0 +1 @@ +{ "createvlaniprangeresponse" : { "vlaniprange" : {"id":2,"forvirtualnetwork":false,"zoneid":2,"vlan":"untagged","account":"system","domainid":1,"domain":"ROOT","podid":2,"podname":"Dev Pod 2","gateway":"10.22.22.254","netmask":"255.255.255.0","startip":"10.22.22.51","endip":"10.22.22.100","networkid":209} } } \ No newline at end of file