diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/NovaApi.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/NovaApi.java index 78396121ab..cd66f6b401 100644 --- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/NovaApi.java +++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/NovaApi.java @@ -25,6 +25,7 @@ import org.jclouds.openstack.nova.v2_0.extensions.AvailabilityZoneApi; import org.jclouds.openstack.nova.v2_0.extensions.ConsolesApi; import org.jclouds.openstack.nova.v2_0.extensions.FlavorExtraSpecsApi; import org.jclouds.openstack.nova.v2_0.extensions.FloatingIPApi; +import org.jclouds.openstack.nova.v2_0.extensions.FloatingIPPoolApi; import org.jclouds.openstack.nova.v2_0.extensions.HostAdministrationApi; import org.jclouds.openstack.nova.v2_0.extensions.HostAggregateApi; import org.jclouds.openstack.nova.v2_0.extensions.KeyPairApi; @@ -261,6 +262,13 @@ public interface NovaApi extends Closeable { Optional getConsolesApi( @EndpointParam(parser = RegionToEndpoint.class) String region); + /** + * Provides access to Floating IP Pool features. + */ + @Delegate + Optional getFloatingIPPoolApi( + @EndpointParam(parser = RegionToEndpoint.class) String region); + /** * @return the Zone codes configured * @deprecated Please use {@link #getConfiguredRegions()} as this method will be removed in jclouds 3.0. diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/domain/FloatingIPPool.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/domain/FloatingIPPool.java new file mode 100644 index 0000000000..b453750643 --- /dev/null +++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/domain/FloatingIPPool.java @@ -0,0 +1,101 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.openstack.nova.v2_0.domain; + +import com.google.common.base.Objects; + +import java.beans.ConstructorProperties; + +/** + * A pool that holds a collection of floating IP's that can be allocated from it. + */ +public class FloatingIPPool implements Comparable { + + public static Builder builder() { + return new Builder(); + } + + public Builder toBuilder() { + return new Builder().fromFloatingIPPool(this); + } + + public static class Builder { + + protected String name; + + /** + * @see FloatingIPPool#getName() + */ + public Builder name(String name) { + this.name = name; + return this; + } + + public FloatingIPPool build() { + return new FloatingIPPool(name); + } + + public Builder fromFloatingIPPool(FloatingIPPool in) { + return this + .name(in.getName()); + } + } + + + private final String name; + + + @ConstructorProperties({ + "name" + }) + protected FloatingIPPool(String name) { + this.name = name; + } + + public String getName() { + return this.name; + } + + @Override + public int hashCode() { + return Objects.hashCode(name); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null || getClass() != obj.getClass()) return false; + FloatingIPPool that = FloatingIPPool.class.cast(obj); + return Objects.equal(this.name, that.name); + } + + protected Objects.ToStringHelper string() { + return Objects.toStringHelper(this) + .add("name", name); + } + + @Override + public String toString() { + return string().toString(); + } + + @Override + public int compareTo(FloatingIPPool o) { + return this.name.compareTo(o.getName()); + } + +} diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/ExtensionNamespaces.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/ExtensionNamespaces.java index 396c52b6ee..0717452c17 100644 --- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/ExtensionNamespaces.java +++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/ExtensionNamespaces.java @@ -113,6 +113,10 @@ public final class ExtensionNamespaces { */ public static final String BLOCK_DEVICE_MAPPING_V2_BOOT = "http://docs.openstack.org/compute/ext/block_device_mapping_v2_boot/api/v2"; + /** + * Floating IP pools support + */ + public static final String FLOATING_IP_POOLS = "http://docs.openstack.org/ext/floating_ip_pools/api/v1.1"; private ExtensionNamespaces() { throw new AssertionError("intentionally unimplemented"); diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/FloatingIPPoolApi.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/FloatingIPPoolApi.java new file mode 100644 index 0000000000..6b3153117f --- /dev/null +++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v2_0/extensions/FloatingIPPoolApi.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.openstack.nova.v2_0.extensions; + +import com.google.common.annotations.Beta; +import com.google.common.collect.FluentIterable; +import org.jclouds.Fallbacks; +import org.jclouds.openstack.keystone.v2_0.filters.AuthenticateRequest; +import org.jclouds.openstack.nova.v2_0.domain.FloatingIPPool; +import org.jclouds.openstack.v2_0.ServiceType; +import org.jclouds.openstack.v2_0.services.Extension; +import org.jclouds.rest.annotations.Fallback; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.SelectJson; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.core.MediaType; + +@Beta +@Extension(of = ServiceType.COMPUTE, namespace = ExtensionNamespaces.FLOATING_IP_POOLS) +@Consumes(MediaType.APPLICATION_JSON) +@Path("/os-floating-ip-pools") +@RequestFilters(AuthenticateRequest.class) +public interface FloatingIPPoolApi { + + /** + * Lists all Floating IP Pools + * + * @return all Floating IP Pools + */ + @GET + @SelectJson("floating_ip_pools") + @Fallback(Fallbacks.EmptyFluentIterableOnNotFoundOr404.class) + FluentIterable list(); +} diff --git a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/extensions/FloatingIPPoolApiLiveTest.java b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/extensions/FloatingIPPoolApiLiveTest.java new file mode 100644 index 0000000000..c6086b47ea --- /dev/null +++ b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/extensions/FloatingIPPoolApiLiveTest.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.openstack.nova.v2_0.extensions; + +import com.google.common.base.Optional; +import com.google.common.collect.FluentIterable; +import org.jclouds.openstack.nova.v2_0.domain.FloatingIPPool; +import org.jclouds.openstack.nova.v2_0.internal.BaseNovaApiLiveTest; +import org.testng.annotations.Test; + +import static org.testng.Assert.assertTrue; + +/** + * Tests for the {@code FloatingIPPoolApi} + */ +@Test(groups = "live", testName = "FloatingIPPoolApiLiveTest") +public class FloatingIPPoolApiLiveTest extends BaseNovaApiLiveTest { + + @Test + public void testListFloatingIPPools() throws Exception { + for (String region : regions) { + Optional apiOption = api.getFloatingIPPoolApi(region); + + if (!apiOption.isPresent()) { + continue; + } + + FloatingIPPoolApi api = apiOption.get(); + FluentIterable response = api.list(); + assertTrue(!response.toSet().isEmpty()); + } + } +} diff --git a/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/parse/ParseFloatingIPPoolListTest.java b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/parse/ParseFloatingIPPoolListTest.java new file mode 100644 index 0000000000..599338fe4b --- /dev/null +++ b/apis/openstack-nova/src/test/java/org/jclouds/openstack/nova/v2_0/parse/ParseFloatingIPPoolListTest.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.openstack.nova.v2_0.parse; + +import com.google.common.collect.ImmutableSet; +import com.google.inject.Guice; +import com.google.inject.Injector; +import org.jclouds.json.BaseSetParserTest; +import org.jclouds.json.config.GsonModule; +import org.jclouds.openstack.nova.v2_0.config.NovaParserModule; +import org.jclouds.openstack.nova.v2_0.domain.FloatingIPPool; +import org.jclouds.rest.annotations.SelectJson; +import org.testng.annotations.Test; + +import javax.ws.rs.Consumes; +import javax.ws.rs.core.MediaType; +import java.util.Set; + +@Test(groups = "unit", testName = "ParseFloatingIPPoolListTest") +public class ParseFloatingIPPoolListTest extends BaseSetParserTest { + + @Override + public String resource() { + return "/floatingippool_list.json"; + } + + @Override + @SelectJson("floating_ip_pools") + @Consumes(MediaType.APPLICATION_JSON) + public Set expected() { + return ImmutableSet.of(FloatingIPPool.builder().name("VLAN867").build()); + } + + protected Injector injector() { + return Guice.createInjector(new NovaParserModule(), new GsonModule()); + } +} diff --git a/apis/openstack-nova/src/test/resources/floatingippool_list.json b/apis/openstack-nova/src/test/resources/floatingippool_list.json new file mode 100644 index 0000000000..2a3a603797 --- /dev/null +++ b/apis/openstack-nova/src/test/resources/floatingippool_list.json @@ -0,0 +1,7 @@ +{ + "floating_ip_pools": [ + { + "name": "VLAN867" + } + ] +}