You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by ev...@apache.org on 2013/09/12 22:52:34 UTC

[5/5] git commit: OpenStack Neutron v2.0 implementation

OpenStack Neutron v2.0 implementation


Project: http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/commit/895476f1
Tree: http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/tree/895476f1
Diff: http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/diff/895476f1

Branch: refs/heads/master
Commit: 895476f11f41b706a02b3f3a8d2275db8220893a
Parents: 46f493a
Author: Kris Sterckx <tw...@gmail.com>
Authored: Tue Aug 27 09:39:32 2013 +0200
Committer: Everett Toews <ev...@rackspace.com>
Committed: Thu Sep 12 15:52:08 2013 -0500

----------------------------------------------------------------------
 openstack-neutron/pom.xml                       | 125 +++++++++
 .../openstack/neutron/v2_0/NeutronApi.java      |  74 +++++
 .../neutron/v2_0/NeutronApiMetadata.java        | 102 +++++++
 .../v2_0/config/NeutronHttpApiModule.java       |  84 ++++++
 .../neutron/v2_0/domain/AllocationPool.java     | 127 +++++++++
 .../neutron/v2_0/domain/BulkNetwork.java        | 211 ++++++++++++++
 .../openstack/neutron/v2_0/domain/BulkPort.java | 233 ++++++++++++++++
 .../neutron/v2_0/domain/BulkSubnet.java         | 276 +++++++++++++++++++
 .../neutron/v2_0/domain/HostRoute.java          | 128 +++++++++
 .../openstack/neutron/v2_0/domain/IP.java       | 124 +++++++++
 .../openstack/neutron/v2_0/domain/Network.java  | 257 +++++++++++++++++
 .../neutron/v2_0/domain/NetworkType.java        |  46 ++++
 .../openstack/neutron/v2_0/domain/Port.java     | 234 ++++++++++++++++
 .../neutron/v2_0/domain/Reference.java          | 129 +++++++++
 .../neutron/v2_0/domain/ReferenceWithName.java  | 111 ++++++++
 .../openstack/neutron/v2_0/domain/State.java    |  29 ++
 .../openstack/neutron/v2_0/domain/Subnet.java   | 264 ++++++++++++++++++
 .../neutron/v2_0/features/NetworkApi.java       | 172 ++++++++++++
 .../neutron/v2_0/features/PortApi.java          | 175 ++++++++++++
 .../neutron/v2_0/features/SubnetApi.java        | 174 ++++++++++++
 .../v2_0/functions/ParseNetworkDetails.java     |  91 ++++++
 .../neutron/v2_0/functions/ParseNetworks.java   |  91 ++++++
 .../v2_0/functions/ParsePortDetails.java        |  92 +++++++
 .../neutron/v2_0/functions/ParsePorts.java      |  92 +++++++
 .../v2_0/functions/ParseSubnetDetails.java      |  91 ++++++
 .../neutron/v2_0/functions/ParseSubnets.java    |  91 ++++++
 .../v2_0/handlers/NeutronErrorHandler.java      |  62 +++++
 .../v2_0/options/CreateNetworkBulkOptions.java  | 142 ++++++++++
 .../v2_0/options/CreateNetworkOptions.java      | 244 ++++++++++++++++
 .../v2_0/options/CreatePortBulkOptions.java     | 137 +++++++++
 .../neutron/v2_0/options/CreatePortOptions.java | 245 ++++++++++++++++
 .../v2_0/options/CreateSubnetBulkOptions.java   | 143 ++++++++++
 .../v2_0/options/CreateSubnetOptions.java       | 261 ++++++++++++++++++
 .../v2_0/options/UpdateNetworkOptions.java      | 132 +++++++++
 .../neutron/v2_0/options/UpdatePortOptions.java | 219 +++++++++++++++
 .../v2_0/options/UpdateSubnetOptions.java       | 219 +++++++++++++++
 .../services/org.jclouds.apis.ApiMetadata       |  18 ++
 .../neutron/v2_0/NeutronApiMetadataTest.java    |  35 +++
 .../v2_0/features/NetworkApiExpectTest.java     | 241 ++++++++++++++++
 .../v2_0/features/NetworkApiLiveTest.java       | 113 ++++++++
 .../v2_0/features/PortApiExpectTest.java        | 242 ++++++++++++++++
 .../neutron/v2_0/features/PortApiLiveTest.java  | 140 ++++++++++
 .../v2_0/features/SubnetApiExpectTest.java      | 251 +++++++++++++++++
 .../v2_0/features/SubnetApiLiveTest.java        | 126 +++++++++
 .../v2_0/internal/BaseNeutronApiExpectTest.java |  69 +++++
 .../v2_0/internal/BaseNeutronApiLiveTest.java   |  47 ++++
 .../v2_0/internal/BaseNeutronExpectTest.java    |  67 +++++
 .../neutron/v2_0/parse/ParseNetworkTest.java    |  54 ++++
 .../neutron/v2_0/parse/ParsePortTest.java       |  53 ++++
 .../neutron/v2_0/parse/ParseSubnetTest.java     |  53 ++++
 .../src/test/resources/list_networks.json       |  62 +++++
 .../src/test/resources/list_ports.json          |  86 ++++++
 .../src/test/resources/list_subnets.json        |  98 +++++++
 .../src/test/resources/logback.xml              |  69 +++++
 .../src/test/resources/network.json             |   7 +
 openstack-neutron/src/test/resources/port.json  |   7 +
 .../src/test/resources/subnet.json              |   8 +
 openstack-quantum/pom.xml                       | 125 ---------
 .../openstack/quantum/v1_0/QuantumApi.java      |  72 -----
 .../quantum/v1_0/QuantumApiMetadata.java        |  91 ------
 .../v1_0/config/QuantumHttpApiModule.java       |  85 ------
 .../quantum/v1_0/config/QuantumProperties.java  |  26 --
 .../quantum/v1_0/domain/Attachment.java         |  63 -----
 .../openstack/quantum/v1_0/domain/Network.java  | 102 -------
 .../quantum/v1_0/domain/NetworkDetails.java     | 108 --------
 .../openstack/quantum/v1_0/domain/Port.java     | 108 --------
 .../quantum/v1_0/domain/PortDetails.java        | 103 -------
 .../quantum/v1_0/domain/Reference.java          | 108 --------
 .../quantum/v1_0/features/NetworkApi.java       | 122 --------
 .../quantum/v1_0/features/PortApi.java          | 147 ----------
 .../v1_0/handlers/QuantumErrorHandler.java      |  63 -----
 .../services/org.jclouds.apis.ApiMetadata       |  18 --
 .../quantum/v1_0/QuantumApiMetadataTest.java    |  35 ---
 .../v1_0/features/NetworkApiExpectTest.java     | 235 ----------------
 .../v1_0/features/NetworkApiLiveTest.java       |  91 ------
 .../v1_0/features/PortApiExpectTest.java        | 245 ----------------
 .../quantum/v1_0/features/PortApiLiveTest.java  | 137 ---------
 .../v1_0/internal/BaseQuantumApiExpectTest.java |  28 --
 .../v1_0/internal/BaseQuantumApiLiveTest.java   |  44 ---
 .../v1_0/internal/BaseQuantumExpectTest.java    |  57 ----
 .../quantum/v1_0/parse/ParseAttachmentTest.java |  45 ---
 .../v1_0/parse/ParseNetworkDetailsTest.java     |  49 ----
 .../quantum/v1_0/parse/ParseNetworkTest.java    |  45 ---
 .../v1_0/parse/ParsePortDetailsTest.java        |  47 ----
 .../quantum/v1_0/parse/ParsePortTest.java       |  45 ---
 .../src/test/resources/attachment.json          |   1 -
 .../src/test/resources/list_network_refs.json   |  14 -
 .../src/test/resources/list_networks.json       |  14 -
 .../src/test/resources/logback.xml              |  69 -----
 .../src/test/resources/network.json             |   1 -
 .../src/test/resources/network_details.json     |   1 -
 openstack-quantum/src/test/resources/port.json  |   1 -
 .../src/test/resources/port_details.json        |   1 -
 pom.xml                                         |   2 +-
 94 files changed, 7274 insertions(+), 2547 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/895476f1/openstack-neutron/pom.xml
----------------------------------------------------------------------
diff --git a/openstack-neutron/pom.xml b/openstack-neutron/pom.xml
new file mode 100644
index 0000000..ba96317
--- /dev/null
+++ b/openstack-neutron/pom.xml
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.jclouds</groupId>
+    <artifactId>jclouds-project</artifactId>
+    <version>1.7.0-SNAPSHOT</version>
+  </parent>
+
+  <!-- TODO: when out of labs, switch to org.jclouds.api -->
+  <groupId>org.apache.jclouds.labs</groupId>
+  <artifactId>openstack-neutron</artifactId>
+  <version>1.7.0-SNAPSHOT</version>
+  <name>jclouds openstack-neutron api</name>
+  <description>jclouds components to access an implementation of OpenStack Neutron</description>
+  <packaging>bundle</packaging>
+
+  <properties>
+    <!-- keystone endpoint -->
+    <test.openstack-neutron.endpoint>http://localhost:5000/v2.0/</test.openstack-neutron.endpoint>
+    <!-- keystone version -->
+    <test.openstack-neutron.api-version>2.0</test.openstack-neutron.api-version>
+    <test.openstack-neutron.build-version />
+    <test.openstack-neutron.identity>FIXME_IDENTITY</test.openstack-neutron.identity>
+    <test.openstack-neutron.credential>FIXME_CREDENTIALS</test.openstack-neutron.credential>
+    <test.jclouds.keystone.credential-type>passwordCredentials</test.jclouds.keystone.credential-type>
+    <jclouds.osgi.export>org.jclouds.openstack.neutron.v2_0*;version="${project.version}"</jclouds.osgi.export>
+    <jclouds.osgi.import>
+      org.jclouds.rest.internal;version="${jclouds.version}",
+      org.jclouds.labs*;version="${project.version}",
+      org.jclouds*;version="${jclouds.version}",
+      *
+    </jclouds.osgi.import>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.jclouds.api</groupId>
+      <artifactId>openstack-keystone</artifactId>
+      <version>${project.parent.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.jclouds</groupId>
+      <artifactId>jclouds-core</artifactId>
+      <version>${project.parent.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.jclouds</groupId>
+      <artifactId>jclouds-core</artifactId>
+      <version>${project.parent.version}</version>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.jclouds.api</groupId>
+      <artifactId>openstack-keystone</artifactId>
+      <version>${project.parent.version}</version>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.jclouds.driver</groupId>
+      <artifactId>jclouds-slf4j</artifactId>
+      <version>${project.parent.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>ch.qos.logback</groupId>
+      <artifactId>logback-classic</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <profiles>
+    <profile>
+      <id>live</id>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-surefire-plugin</artifactId>
+            <executions>
+              <execution>
+                <id>integration</id>
+                <phase>integration-test</phase>
+                <goals>
+                  <goal>test</goal>
+                </goals>
+                <configuration>
+                  <systemPropertyVariables>
+                    <test.openstack-neutron.endpoint>${test.openstack-neutron.endpoint}</test.openstack-neutron.endpoint>
+                    <test.openstack-neutron.api-version>${test.openstack-neutron.api-version}</test.openstack-neutron.api-version>
+                    <test.openstack-neutron.build-version>${test.openstack-neutron.build-version}</test.openstack-neutron.build-version>
+                    <test.openstack-neutron.identity>${test.openstack-neutron.identity}</test.openstack-neutron.identity>
+                    <test.openstack-neutron.credential>${test.openstack-neutron.credential}</test.openstack-neutron.credential>
+                    <test.jclouds.keystone.credential-type>${test.jclouds.keystone.credential-type}</test.jclouds.keystone.credential-type>
+                  </systemPropertyVariables>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
+
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/895476f1/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/NeutronApi.java
----------------------------------------------------------------------
diff --git a/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/NeutronApi.java b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/NeutronApi.java
new file mode 100644
index 0000000..1e3ca7c
--- /dev/null
+++ b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/NeutronApi.java
@@ -0,0 +1,74 @@
+/**
+ * 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.openstack.neutron.v2_0;
+
+import com.google.inject.Provides;
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.location.Zone;
+import org.jclouds.location.functions.ZoneToEndpoint;
+import org.jclouds.openstack.neutron.v2_0.features.NetworkApi;
+import org.jclouds.openstack.neutron.v2_0.features.PortApi;
+import org.jclouds.openstack.neutron.v2_0.features.SubnetApi;
+import org.jclouds.openstack.v2_0.features.ExtensionApi;
+import org.jclouds.rest.annotations.Delegate;
+import org.jclouds.rest.annotations.EndpointParam;
+
+import java.io.Closeable;
+import java.util.Set;
+
+/**
+ * Provides synchronous access to Neutron.
+ * <p/>
+ *
+ * @author Nick Livens
+ * @see <a href="http://docs.openstack.org/api/openstack-network/2.0/content/">api doc</a>
+ */
+public interface NeutronApi extends Closeable {
+   /**
+    * @return the Zone codes configured
+    */
+   @Provides
+   @Zone
+   Set<String> getConfiguredZones();
+
+   /**
+    * Provides synchronous access to Extension features.
+    */
+   @Delegate
+   ExtensionApi getExtensionApiForZone(
+           @EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
+
+   /**
+    * Provides synchronous access to Network features.
+    */
+   @Delegate
+   NetworkApi getNetworkApiForZone(@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
+
+   /**
+    * Provides synchronous access to Subnet features
+    */
+   @Delegate
+   SubnetApi getSubnetApiForZone(@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
+
+   /**
+    * Provides synchronous access to Port features.
+    */
+   @Delegate
+   PortApi getPortApiForZone(@EndpointParam(parser = ZoneToEndpoint.class) @Nullable String zone);
+}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/895476f1/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/NeutronApiMetadata.java
----------------------------------------------------------------------
diff --git a/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/NeutronApiMetadata.java b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/NeutronApiMetadata.java
new file mode 100644
index 0000000..8ae1a94
--- /dev/null
+++ b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/NeutronApiMetadata.java
@@ -0,0 +1,102 @@
+/**
+ * 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.openstack.neutron.v2_0;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.inject.Module;
+import org.jclouds.apis.ApiMetadata;
+import org.jclouds.openstack.keystone.v2_0.config.AuthenticationApiModule;
+import org.jclouds.openstack.keystone.v2_0.config.CredentialTypes;
+import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule;
+import org.jclouds.openstack.keystone.v2_0.config.KeystoneAuthenticationModule.ZoneModule;
+import org.jclouds.openstack.neutron.v2_0.config.NeutronHttpApiModule;
+import org.jclouds.openstack.v2_0.ServiceType;
+import org.jclouds.rest.internal.BaseHttpApiMetadata;
+
+import java.net.URI;
+import java.util.Properties;
+
+import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.CREDENTIAL_TYPE;
+import static org.jclouds.openstack.keystone.v2_0.config.KeystoneProperties.SERVICE_TYPE;
+
+/**
+ * Implementation of {@link org.jclouds.apis.ApiMetadata} for Neutron 2.0 API
+ *
+ * @author Nick Livens
+ */
+public class NeutronApiMetadata extends BaseHttpApiMetadata<NeutronApi> {
+
+   @Override
+   public Builder toBuilder() {
+      return new Builder().fromApiMetadata(this);
+   }
+
+   public NeutronApiMetadata() {
+      this(new Builder());
+   }
+
+   protected NeutronApiMetadata(Builder builder) {
+      super(builder);
+   }
+
+   public static Properties defaultProperties() {
+      Properties properties = BaseHttpApiMetadata.defaultProperties();
+      properties.setProperty(SERVICE_TYPE, ServiceType.NETWORK);
+      properties.setProperty(CREDENTIAL_TYPE, CredentialTypes.PASSWORD_CREDENTIALS);
+      return properties;
+   }
+
+   public static class Builder extends BaseHttpApiMetadata.Builder<NeutronApi, Builder> {
+
+      protected Builder() {
+         super(NeutronApi.class);
+         id("openstack-neutron")
+            .name("OpenStack Neutron API")
+            .identityName("${tenantName}:${userName} or ${userName}, if your keystone supports a default tenant")
+            .credentialName("${password}")
+            .endpointName("KeyStone base url ending in /v2.0/")
+            .documentation(URI.create("http://docs.openstack.org/api/openstack-network/2.0/content/"))
+            .version("2.0")
+            .defaultEndpoint("http://localhost:5000/v2.0/")
+            .defaultProperties(NeutronApiMetadata.defaultProperties())
+            .defaultModules(ImmutableSet.<Class<? extends Module>>builder()
+               .add(AuthenticationApiModule.class)
+               .add(KeystoneAuthenticationModule.class)
+               .add(ZoneModule.class)
+               .add(NeutronHttpApiModule.class).build());
+      }
+
+      @Override
+      public NeutronApiMetadata build() {
+         return new NeutronApiMetadata(this);
+      }
+
+      @Override
+      public Builder fromApiMetadata(ApiMetadata in) {
+         super.fromApiMetadata(in);
+         return this;
+      }
+
+      @Override
+      protected Builder self() {
+         return this;
+      }
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/895476f1/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/config/NeutronHttpApiModule.java
----------------------------------------------------------------------
diff --git a/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/config/NeutronHttpApiModule.java b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/config/NeutronHttpApiModule.java
new file mode 100644
index 0000000..dd4bdb1
--- /dev/null
+++ b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/config/NeutronHttpApiModule.java
@@ -0,0 +1,84 @@
+/*
+ * 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.neutron.v2_0.config;
+
+import java.net.URI;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import javax.inject.Provider;
+import javax.inject.Singleton;
+import org.jclouds.http.HttpErrorHandler;
+import org.jclouds.http.annotation.ClientError;
+import org.jclouds.http.annotation.Redirection;
+import org.jclouds.http.annotation.ServerError;
+import org.jclouds.json.config.GsonModule.DateAdapter;
+import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
+import org.jclouds.openstack.neutron.v2_0.NeutronApi;
+import org.jclouds.openstack.neutron.v2_0.handlers.NeutronErrorHandler;
+import org.jclouds.openstack.v2_0.domain.Extension;
+import org.jclouds.openstack.v2_0.functions.PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet;
+import org.jclouds.rest.ConfiguresHttpApi;
+import org.jclouds.rest.config.HttpApiModule;
+import org.jclouds.rest.functions.ImplicitOptionalConverter;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.Multimap;
+import com.google.inject.Provides;
+
+/**
+ * Configures the Neutron connection.
+ * 
+ * @author Nick Livens
+ */
+@ConfiguresHttpApi
+public class NeutronHttpApiModule extends HttpApiModule<NeutronApi> {
+   
+   @Override
+   protected void configure() {
+      bind(DateAdapter.class).to(Iso8601DateAdapter.class);
+      bind(ImplicitOptionalConverter.class).to(PresentWhenExtensionAnnotationNamespaceEqualsAnyNamespaceInExtensionsSet.class);
+      super.configure();
+   }
+   
+   @Provides
+   @Singleton
+   public Multimap<URI, URI> aliases() {
+       return ImmutableMultimap.<URI, URI>builder()
+          .build();
+   }
+
+   @Provides
+   @Singleton
+   public LoadingCache<String, Set<? extends Extension>> provideExtensionsByZone(final Provider<NeutronApi> quantumApi) {
+      return CacheBuilder.newBuilder().expireAfterWrite(23, TimeUnit.HOURS)
+            .build(new CacheLoader<String, Set<? extends Extension>>() {
+               @Override
+               public Set<? extends Extension> load(String key) throws Exception {
+                  return quantumApi.get().getExtensionApiForZone(key).list();
+               }
+            });
+   }
+   
+   @Override
+   protected void bindErrorHandlers() {
+      bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(NeutronErrorHandler.class);
+      bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(NeutronErrorHandler.class);
+      bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(NeutronErrorHandler.class);
+   }
+}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/895476f1/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/domain/AllocationPool.java
----------------------------------------------------------------------
diff --git a/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/domain/AllocationPool.java b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/domain/AllocationPool.java
new file mode 100644
index 0000000..e0bb862
--- /dev/null
+++ b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/domain/AllocationPool.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.openstack.neutron.v2_0.domain;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Objects.ToStringHelper;
+
+import java.beans.ConstructorProperties;
+
+/**
+ * A Neutron Subnet Allocation Pool
+ *
+ * @author Nick Livens
+ * @see <a href="http://docs.openstack.org/api/openstack-network/2.0/content/Subnets.html">api doc</a>
+ */
+public class AllocationPool {
+
+   private final String start;
+   private final String end;
+
+   @ConstructorProperties({
+      "start", "end"
+   })
+   protected AllocationPool(String start, String end) {
+      this.start = start;
+      this.end = end;
+   }
+
+   /**
+    * @return the start ip
+    */
+   public String getStart() {
+      return start;
+   }
+
+   /**
+    * @return the end ip
+    */
+   public String getEnd() {
+      return end;
+   }
+
+   @Override
+   public int hashCode() {
+      return Objects.hashCode(start, end);
+   }
+
+   @Override
+   public boolean equals(Object obj) {
+      if (this == obj) return true;
+      if (obj == null || getClass() != obj.getClass()) return false;
+      AllocationPool that = AllocationPool.class.cast(obj);
+      return Objects.equal(this.start, that.start) && Objects.equal(this.end, that.end);
+   }
+
+   protected ToStringHelper string() {
+      return Objects.toStringHelper(this).add("start", start).add("end", end);
+   }
+
+   @Override
+   public String toString() {
+      return string().toString();
+   }
+
+   public static Builder builder() {
+      return new ConcreteBuilder();
+   }
+
+   public Builder toBuilder() {
+      return new ConcreteBuilder().fromAllocationPool(this);
+   }
+
+   public static abstract class Builder {
+      protected abstract Builder self();
+
+      protected String start;
+      protected String end;
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.AllocationPool#getStart()
+       */
+      public Builder start(String start) {
+         this.start = start;
+         return self();
+      }
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.AllocationPool#getEnd()
+       */
+      public Builder end(String end) {
+         this.end = end;
+         return self();
+      }
+
+      public AllocationPool build() {
+         return new AllocationPool(start, end);
+      }
+
+      public Builder fromAllocationPool(AllocationPool in) {
+         return this.start(in.getStart()).end(in.getEnd());
+      }
+   }
+
+   private static class ConcreteBuilder extends Builder {
+      @Override
+      protected ConcreteBuilder self() {
+         return this;
+      }
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/895476f1/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/domain/BulkNetwork.java
----------------------------------------------------------------------
diff --git a/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/domain/BulkNetwork.java b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/domain/BulkNetwork.java
new file mode 100644
index 0000000..4ac706f
--- /dev/null
+++ b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/domain/BulkNetwork.java
@@ -0,0 +1,211 @@
+/*
+ * 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.openstack.neutron.v2_0.domain;
+
+import com.google.common.base.Objects;
+
+import java.beans.ConstructorProperties;
+
+/**
+ * A Neutron network used for creating networks in bulk
+ * The only difference between this and the actual network are the missing fields id, tenantId, state & shared
+ *
+ * @author Nick Livens
+ */
+public class BulkNetwork {
+
+   private final String name;
+   private final Boolean adminStateUp;
+   private final Boolean external;
+   private final NetworkType networkType;
+   private final String physicalNetworkName;
+   private final Integer segmentationId;
+
+   @ConstructorProperties({
+      "name", "admin_state_up", "router:external", "provider:network_type", "provider:physical_network", "provider:segmentation_id"
+   })
+   protected BulkNetwork(String name, Boolean adminStateUp, Boolean external, String networkType, String physicalNetworkName, Integer segmentationId) {
+      this.name = name;
+      this.adminStateUp = adminStateUp;
+      this.external = external;
+      this.networkType = NetworkType.fromValue(networkType);
+      this.physicalNetworkName = physicalNetworkName;
+      this.segmentationId = segmentationId;
+   }
+
+   /**
+    * @return the name of the network
+    */
+   public String getName() {
+      return name;
+   }
+
+   /**
+    * @return the administrative state of network. If false, the network does not forward packets.
+    */
+   public Boolean getAdminStateUp() {
+      return adminStateUp;
+   }
+
+   /**
+    * @return true if network is external, false if not
+    */
+   public Boolean getExternal() {
+      return external;
+   }
+
+   /**
+    * @return the type of network
+    */
+   public NetworkType getNetworkType() {
+      return networkType;
+   }
+
+   /**
+    * @return the physical network name
+    */
+   public String getPhysicalNetworkName() {
+      return physicalNetworkName;
+   }
+
+   /**
+    * @return the segmentation id of the network
+    */
+   public Integer getSegmentationId() {
+      return segmentationId;
+   }
+
+   @Override
+   public int hashCode() {
+      return Objects.hashCode(name, adminStateUp, external, networkType, physicalNetworkName, segmentationId);
+   }
+
+   @Override
+   public boolean equals(Object obj) {
+      if (this == obj) return true;
+      if (obj == null || getClass() != obj.getClass()) return false;
+      BulkNetwork that = BulkNetwork.class.cast(obj);
+      return Objects.equal(this.name, that.name)
+         && Objects.equal(this.adminStateUp, that.adminStateUp)
+         && Objects.equal(this.external, that.external)
+         && Objects.equal(this.networkType, that.networkType)
+         && Objects.equal(this.physicalNetworkName, that.physicalNetworkName)
+         && Objects.equal(this.segmentationId, that.segmentationId);
+   }
+
+   protected Objects.ToStringHelper string() {
+      return Objects.toStringHelper(this)
+         .add("name", name).add("adminStateUp", adminStateUp).add("external", external)
+         .add("networkType", networkType).add("physicalNetworkName", physicalNetworkName)
+         .add("segmentationId", segmentationId);
+   }
+
+   @Override
+   public String toString() {
+      return string().toString();
+   }
+
+   public static Builder builder() {
+      return new ConcreteBuilder();
+   }
+
+   public Builder toBuilder() {
+      return new ConcreteBuilder().fromBulkNetwork(this);
+   }
+
+   public static abstract class Builder {
+      protected abstract Builder self();
+
+      protected String name;
+      protected Boolean adminStateUp;
+      protected Boolean external;
+      protected NetworkType networkType;
+      protected String physcialNetworkName;
+      protected Integer segmentationId;
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.BulkNetwork#getName()
+       */
+      public Builder name(String name) {
+         this.name = name;
+         return self();
+      }
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.BulkNetwork#getAdminStateUp()
+       */
+      public Builder adminStateUp(Boolean adminStateUp) {
+         this.adminStateUp = adminStateUp;
+         return self();
+      }
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.BulkNetwork#getExternal()
+       */
+      public Builder external(Boolean external) {
+         this.external = external;
+         return self();
+      }
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.BulkNetwork#getNetworkType()
+       */
+      public Builder networkType(NetworkType networkType) {
+         this.networkType = networkType;
+         return self();
+      }
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.BulkNetwork#getPhysicalNetworkName()
+       */
+      public Builder physicalNetworkName(String physicalNetworkName) {
+         this.physcialNetworkName = physicalNetworkName;
+         return self();
+      }
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.BulkNetwork#getSegmentationId()
+       */
+      public Builder segmentationId(Integer segmentationId) {
+         this.segmentationId = segmentationId;
+         return self();
+      }
+
+      public BulkNetwork build() {
+         return new BulkNetwork(name, adminStateUp, external, networkType == null ? null : networkType.getValue(), physcialNetworkName, segmentationId);
+      }
+
+      public Builder fromBulkNetwork(BulkNetwork in) {
+         return this.name(in.getName())
+               .adminStateUp(in.getAdminStateUp())
+               .external(in.getExternal())
+               .networkType(in.getNetworkType())
+               .physicalNetworkName(in.getPhysicalNetworkName())
+               .segmentationId(in.getSegmentationId());
+      }
+   }
+
+   private static class ConcreteBuilder extends Builder {
+      @Override
+      protected ConcreteBuilder self() {
+         return this;
+      }
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/895476f1/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/domain/BulkPort.java
----------------------------------------------------------------------
diff --git a/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/domain/BulkPort.java b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/domain/BulkPort.java
new file mode 100644
index 0000000..df1c4e3
--- /dev/null
+++ b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/domain/BulkPort.java
@@ -0,0 +1,233 @@
+/*
+ * 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.openstack.neutron.v2_0.domain;
+
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableSet;
+
+import java.beans.ConstructorProperties;
+import java.util.Collection;
+import java.util.Set;
+
+/**
+ * A Neutron port used for creating ports in bulk
+ * The only difference between this and the actual port are the missing fields id, tenantId & state
+ *
+ * @author Nick Livens
+ */
+public class BulkPort {
+
+   private final String name;
+   private final String networkId;
+   private final Boolean adminStateUp;
+   private final String deviceId;
+   private final String deviceOwner;
+   private final Set<IP> fixedIps;
+   private final String macAddress;
+
+   @ConstructorProperties({
+      "name", "network_id", "admin_state_up", "device_id", "device_owner", "fixed_ips", "mac_address"
+   })
+   protected BulkPort(String name, String networkId, Boolean adminStateUp, String deviceId, String deviceOwner, Set<IP> fixedIps, String macAddress) {
+      this.name = name;
+      this.networkId = networkId;
+      this.adminStateUp = adminStateUp;
+      this.deviceId = deviceId;
+      this.deviceOwner = deviceOwner;
+      this.fixedIps = fixedIps != null ? ImmutableSet.copyOf(fixedIps) : ImmutableSet.<IP>of();
+      this.macAddress = macAddress;
+   }
+
+   /**
+    * @return the name of the port
+    */
+   public String getName() {
+      return name;
+   }
+
+   /**
+    * @return the id of the network where this port is associated with
+    */
+   public String getNetworkId() {
+      return networkId;
+   }
+
+   /**
+    * @return the administrative state of port. If false, port does not forward packets
+    */
+   public Boolean getAdminStateUp() {
+      return adminStateUp;
+   }
+
+   /**
+    * @return the id of the device (e.g. server) using this port.
+    */
+   public String getDeviceId() {
+      return deviceId;
+   }
+
+   /**
+    * @return the entity (e.g.: dhcp agent) using this port.
+    */
+   public String getDeviceOwner() {
+      return deviceOwner;
+   }
+
+   /**
+    * @return the set of fixed ips this port has been assigned
+    */
+   public Set<IP> getFixedIps() {
+      return fixedIps;
+   }
+
+   /**
+    * @return the mac address of this port
+    */
+   public String getMacAddress() {
+      return macAddress;
+   }
+
+   @Override
+   public int hashCode() {
+      return Objects.hashCode(name, networkId, adminStateUp, deviceId, deviceOwner, fixedIps, macAddress);
+   }
+
+   @Override
+   public boolean equals(Object obj) {
+      if (this == obj) return true;
+      if (obj == null || getClass() != obj.getClass()) return false;
+      BulkPort that = BulkPort.class.cast(obj);
+      return Objects.equal(this.name, that.name)
+         && Objects.equal(this.networkId, that.networkId)
+         && Objects.equal(this.adminStateUp, that.adminStateUp)
+         && Objects.equal(this.deviceId, that.deviceId)
+         && Objects.equal(this.deviceOwner, that.deviceOwner)
+         && Objects.equal(this.fixedIps, that.fixedIps)
+         && Objects.equal(this.macAddress, that.macAddress);
+   }
+
+   protected Objects.ToStringHelper string() {
+      return Objects.toStringHelper(this)
+         .add("name", name).add("networkId", networkId).add("adminStateUp", adminStateUp)
+         .add("deviceId", deviceId).add("deviceOwner", deviceOwner).add("fixedIps", fixedIps).add("macAddress", macAddress);
+   }
+
+   @Override
+   public String toString() {
+      return string().toString();
+   }
+
+   public static Builder builder() {
+      return new ConcreteBuilder();
+   }
+
+   public Builder toBuilder() {
+      return new ConcreteBuilder().fromBulkPort(this);
+   }
+
+   public static abstract class Builder {
+      protected abstract Builder self();
+
+      protected String name;
+      protected String networkId;
+      protected String deviceId;
+      protected String deviceOwner;
+      protected String macAddress;
+      protected Set<IP> fixedIps;
+      protected Boolean adminStateUp;
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.BulkPort#getName()
+       */
+      public Builder name(String name) {
+         this.name = name;
+         return self();
+      }
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.BulkPort#getNetworkId()
+       */
+      public Builder networkId(String networkId) {
+         this.networkId = networkId;
+         return self();
+      }
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.BulkPort#getDeviceId()
+       */
+      public Builder deviceId(String deviceId) {
+         this.deviceId = deviceId;
+         return self();
+      }
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.BulkPort#getDeviceOwner()
+       */
+      public Builder deviceOwner(String deviceOwner) {
+         this.deviceOwner = deviceOwner;
+         return self();
+      }
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.BulkPort#getMacAddress()
+       */
+      public Builder macAddress(String macAddress) {
+         this.macAddress = macAddress;
+         return self();
+      }
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.BulkPort#getFixedIps()
+       */
+      public Builder fixedIps(Collection<IP> fixedIps) {
+         this.fixedIps = ImmutableSet.copyOf(fixedIps);
+         return self();
+      }
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.BulkPort#getAdminStateUp()
+       */
+      public Builder adminStateUp(Boolean adminStateUp) {
+         this.adminStateUp = adminStateUp;
+         return self();
+      }
+
+      public BulkPort build() {
+         return new BulkPort(name, networkId, adminStateUp, deviceId, deviceOwner, fixedIps, macAddress);
+      }
+
+      public Builder fromBulkPort(BulkPort in) {
+         return this.name(in.getName())
+               .networkId(in.getNetworkId())
+               .adminStateUp(in.getAdminStateUp())
+               .deviceId(in.getDeviceId())
+               .deviceOwner(in.getDeviceOwner())
+               .fixedIps(in.getFixedIps())
+               .macAddress(in.getMacAddress());
+      }
+   }
+
+   private static class ConcreteBuilder extends Builder {
+      @Override
+      protected ConcreteBuilder self() {
+         return this;
+      }
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/895476f1/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/domain/BulkSubnet.java
----------------------------------------------------------------------
diff --git a/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/domain/BulkSubnet.java b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/domain/BulkSubnet.java
new file mode 100644
index 0000000..f1d60b2
--- /dev/null
+++ b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/domain/BulkSubnet.java
@@ -0,0 +1,276 @@
+/*
+ * 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.openstack.neutron.v2_0.domain;
+
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableSet;
+
+import java.beans.ConstructorProperties;
+import java.util.Collection;
+import java.util.Set;
+
+/**
+ * A Neutron subnet used for creating subnets in bulk
+ * The only difference between this and the actual subnet are the missing fields id & tenantId
+ *
+ * @author Nick Livens
+ */
+public class BulkSubnet {
+
+   protected String name;
+   protected String networkId;
+   protected String gatewayIp;
+   protected Integer ipVersion;
+   protected String cidr;
+   protected Set<AllocationPool> allocationPools;
+   protected Boolean enableDhcp;
+   protected Set<String> dnsNameServers;
+   protected Set<HostRoute> hostRoutes;
+
+   @ConstructorProperties({
+      "name", "network_id", "gateway_ip", "ip_version", "cidr", "allocation_pools", "enable_dhcp", "dns_nameservers", "host_routes"
+   })
+   protected BulkSubnet(String name, String networkId, String gatewayIp, Integer ipVersion, String cidr,
+                     Set<AllocationPool> allocationPools, Boolean enableDhcp, Set<String> dnsNameServers, Set<HostRoute> hostRoutes) {
+      this.name = name;
+      this.networkId = networkId;
+      this.gatewayIp = gatewayIp;
+      this.ipVersion = ipVersion;
+      this.cidr = cidr;
+      this.allocationPools = allocationPools != null ? ImmutableSet.copyOf(allocationPools) : ImmutableSet.<AllocationPool>of();
+      this.enableDhcp = enableDhcp;
+      this.dnsNameServers = dnsNameServers != null ? ImmutableSet.copyOf(dnsNameServers) : ImmutableSet.<String>of();
+      this.hostRoutes = hostRoutes != null ? ImmutableSet.copyOf(hostRoutes) : ImmutableSet.<HostRoute>of();
+   }
+
+   /**
+    * @return the name of the subnet
+    */
+   public String getName() {
+      return name;
+   }
+
+   /**
+    * @return the id of the network this subnet is associated with
+    */
+   public String getNetworkId() {
+      return networkId;
+   }
+
+   /**
+    * @return the default gateway used by devices in this subnet
+    */
+   public String getGatewayIp() {
+      return gatewayIp;
+   }
+
+   /**
+    * @return the ip version used by this subnet
+    */
+   public Integer getIpVersion() {
+      return ipVersion;
+   }
+
+   /**
+    * @return the cidr representing the IP range for this subnet, based on IP version
+    */
+   public String getCidr() {
+      return cidr;
+   }
+
+   /**
+    * @return the sub-ranges of cidr available for dynamic allocation to ports
+    */
+   public Set<AllocationPool> getAllocationPools() {
+      return allocationPools;
+   }
+
+   /**
+    * @return true if DHCP is enabled for this subnet, false if not.
+    */
+   public Boolean getEnableDhcp() {
+      return enableDhcp;
+   }
+
+   /**
+    * @return the set of DNS name servers used by hosts in this subnet.
+    */
+   public Set<String> getDnsNameServers() {
+      return dnsNameServers;
+   }
+
+   /**
+    * @return the set of routes that should be used by devices with IPs from this subnet
+    */
+   public Set<HostRoute> getHostRoutes() {
+      return hostRoutes;
+   }
+
+   @Override
+   public int hashCode() {
+      return Objects.hashCode(name, networkId, gatewayIp, ipVersion, cidr,
+         allocationPools, enableDhcp, dnsNameServers, hostRoutes);
+   }
+
+   @Override
+   public boolean equals(Object obj) {
+      if (this == obj) return true;
+      if (obj == null || getClass() != obj.getClass()) return false;
+      BulkSubnet that = BulkSubnet.class.cast(obj);
+      return Objects.equal(this.name, that.name)
+         && Objects.equal(this.networkId, that.networkId)
+         && Objects.equal(this.gatewayIp, that.gatewayIp)
+         && Objects.equal(this.ipVersion, that.ipVersion)
+         && Objects.equal(this.cidr, that.cidr)
+         && Objects.equal(this.allocationPools, that.allocationPools)
+         && Objects.equal(this.enableDhcp, that.enableDhcp)
+         && Objects.equal(this.dnsNameServers, that.dnsNameServers)
+         && Objects.equal(this.hostRoutes, that.hostRoutes);
+   }
+
+   protected Objects.ToStringHelper string() {
+      return Objects.toStringHelper(this)
+         .add("name", name).add("networkId", networkId).add("gatewayIp", gatewayIp).add("ipVersion", ipVersion)
+         .add("cidr", cidr).add("enableDhcp", enableDhcp).add("allocationPools", allocationPools)
+         .add("dnsNameServers", dnsNameServers).add("hostRoutes", hostRoutes);
+   }
+
+   @Override
+   public String toString() {
+      return string().toString();
+   }
+
+   public static Builder builder() {
+      return new ConcreteBuilder();
+   }
+
+   public Builder toBuilder() {
+      return new ConcreteBuilder().fromBulkSubnet(this);
+   }
+
+   public static abstract class Builder {
+      protected abstract Builder self();
+
+      protected String name;
+      protected String networkId;
+      protected String gatewayIp;
+      protected Integer ipVersion;
+      protected String cidr;
+      protected Set<AllocationPool> allocationPools;
+      protected Boolean enableDhcp;
+      protected Set<String> dnsNameServers;
+      protected Set<HostRoute> hostRoutes;
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.BulkSubnet#getName()
+       */
+      public Builder name(String name) {
+         this.name = name;
+         return self();
+      }
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.BulkSubnet#getNetworkId()
+       */
+      public Builder networkId(String networkId) {
+         this.networkId = networkId;
+         return self();
+      }
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.BulkSubnet#getGatewayIp()
+       */
+      public Builder gatewayIp(String gatewayIp) {
+         this.gatewayIp = gatewayIp;
+         return self();
+      }
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.BulkSubnet#getIpVersion()
+       */
+      public Builder ipVersion(Integer ipVersion) {
+         this.ipVersion = ipVersion;
+         return self();
+      }
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.BulkSubnet#getCidr()
+       */
+      public Builder cidr(String cidr) {
+         this.cidr = cidr;
+         return self();
+      }
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.BulkSubnet#getAllocationPools()
+       */
+      public Builder allocationPools(Collection<AllocationPool> allocationPools) {
+         this.allocationPools = ImmutableSet.copyOf(allocationPools);
+         return self();
+      }
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.BulkSubnet#getEnableDhcp()
+       */
+      public Builder enableDhcp(Boolean enableDhcp) {
+         this.enableDhcp = enableDhcp;
+         return self();
+      }
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.BulkSubnet#getDnsNameServers()
+       */
+      public Builder dnsNameServers(Collection<String> dnsNameServers) {
+         this.dnsNameServers = ImmutableSet.copyOf(dnsNameServers);
+         return self();
+      }
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.BulkSubnet#getHostRoutes()
+       */
+      public Builder hostRoutes(Collection<HostRoute> hostRoutes) {
+         this.hostRoutes = ImmutableSet.copyOf(hostRoutes);
+         return self();
+      }
+
+      public BulkSubnet build() {
+         return new BulkSubnet(name, networkId, gatewayIp, ipVersion, cidr, allocationPools, enableDhcp, dnsNameServers, hostRoutes);
+      }
+
+      public Builder fromBulkSubnet(BulkSubnet in) {
+         return this.name(in.getName())
+               .networkId(in.getNetworkId())
+               .gatewayIp(in.getGatewayIp())
+               .ipVersion(in.getIpVersion())
+               .cidr(in.getCidr())
+               .allocationPools(in.getAllocationPools())
+               .enableDhcp(in.getEnableDhcp())
+               .dnsNameServers(in.getDnsNameServers())
+               .hostRoutes(in.getHostRoutes());
+      }
+   }
+
+   private static class ConcreteBuilder extends Builder {
+      @Override
+      protected ConcreteBuilder self() {
+         return this;
+      }
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/895476f1/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/domain/HostRoute.java
----------------------------------------------------------------------
diff --git a/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/domain/HostRoute.java b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/domain/HostRoute.java
new file mode 100644
index 0000000..5bb6ac8
--- /dev/null
+++ b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/domain/HostRoute.java
@@ -0,0 +1,128 @@
+/*
+ * 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.openstack.neutron.v2_0.domain;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Objects.ToStringHelper;
+
+import java.beans.ConstructorProperties;
+
+/**
+ * A Neutron Subnet Host Route
+ *
+ * @author Nick Livens
+ * @see <a href="http://docs.openstack.org/api/openstack-network/2.0/content/Subnets.html">api doc</a>
+ */
+public class HostRoute {
+
+   private final String destinationCidr;
+   private final String nextHop;
+
+   @ConstructorProperties({
+      "destination", "nexthop"
+   })
+   protected HostRoute(String destinationCidr, String nextHop) {
+      this.destinationCidr = destinationCidr;
+      this.nextHop = nextHop;
+   }
+
+   /**
+    * @return the destination cidr for this route
+    */
+   public String getDestinationCidr() {
+      return destinationCidr;
+   }
+
+   /**
+    * @return the ip of the next hop to forward traffic to
+    */
+   public String getNextHop() {
+      return nextHop;
+   }
+
+   @Override
+   public int hashCode() {
+      return Objects.hashCode(destinationCidr, nextHop);
+   }
+
+   @Override
+   public boolean equals(Object obj) {
+      if (this == obj) return true;
+      if (obj == null || getClass() != obj.getClass()) return false;
+      HostRoute that = HostRoute.class.cast(obj);
+      return Objects.equal(this.destinationCidr, that.destinationCidr) && Objects.equal(this.nextHop, that.nextHop);
+   }
+
+   protected ToStringHelper string() {
+      return Objects.toStringHelper(this)
+         .add("destinationCidr", destinationCidr).add("nextHop", nextHop);
+   }
+
+   @Override
+   public String toString() {
+      return string().toString();
+   }
+
+   public static Builder builder() {
+      return new ConcreteBuilder();
+   }
+
+   public Builder toBuilder() {
+      return new ConcreteBuilder().fromHostRoute(this);
+   }
+
+   public static abstract class Builder {
+      protected abstract Builder self();
+
+      protected String destinationCidr;
+      protected String nextHop;
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.HostRoute#getDestinationCidr()
+       */
+      public Builder destinationCidr(String destinationCidr) {
+         this.destinationCidr = destinationCidr;
+         return self();
+      }
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.HostRoute#getNextHop()
+       */
+      public Builder nextHop(String nextHop) {
+         this.nextHop = nextHop;
+         return self();
+      }
+
+      public HostRoute build() {
+         return new HostRoute(destinationCidr, nextHop);
+      }
+
+      public Builder fromHostRoute(HostRoute in) {
+         return this.destinationCidr(in.getDestinationCidr()).nextHop(in.getNextHop());
+      }
+   }
+
+   private static class ConcreteBuilder extends Builder {
+      @Override
+      protected ConcreteBuilder self() {
+         return this;
+      }
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/895476f1/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/domain/IP.java
----------------------------------------------------------------------
diff --git a/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/domain/IP.java b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/domain/IP.java
new file mode 100644
index 0000000..26ab719
--- /dev/null
+++ b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/domain/IP.java
@@ -0,0 +1,124 @@
+/*
+ * 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.openstack.neutron.v2_0.domain;
+
+import com.google.common.base.Objects;
+
+import java.beans.ConstructorProperties;
+
+/**
+ * @author Nick Livens
+ */
+public class IP {
+
+   private String ipAddress;
+   private String subnetId;
+
+   @ConstructorProperties({
+      "ip_address", "subnet_id"
+   })
+   protected IP(String ipAddress, String subnetId) {
+      this.ipAddress = ipAddress;
+      this.subnetId = subnetId;
+   }
+
+   /**
+    * @return the fixed ip address
+    */
+   public String getIpAddress() {
+      return ipAddress;
+   }
+
+   /**
+    * @return the id of the subnet of this ip
+    */
+   public String getSubnetId() {
+      return subnetId;
+   }
+
+   @Override
+   public int hashCode() {
+      return Objects.hashCode(ipAddress, subnetId);
+   }
+
+   @Override
+   public boolean equals(Object obj) {
+      if (this == obj) return true;
+      if (obj == null || getClass() != obj.getClass()) return false;
+      IP that = IP.class.cast(obj);
+      return Objects.equal(this.ipAddress, that.ipAddress) && Objects.equal(this.subnetId, that.subnetId);
+   }
+
+   protected Objects.ToStringHelper string() {
+      return Objects.toStringHelper(this)
+         .add("ipAddress", ipAddress).add("subnetId", subnetId);
+   }
+
+   @Override
+   public String toString() {
+      return string().toString();
+   }
+
+   public static Builder builder() {
+      return new ConcreteBuilder();
+   }
+
+   public Builder toBuilder() {
+      return new ConcreteBuilder().fromIP(this);
+   }
+
+   public static abstract class Builder {
+      protected abstract Builder self();
+
+      protected String ipAddress;
+      protected String subnetId;
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.IP#getIpAddress
+       */
+      public Builder ipAddress(String ipAddress) {
+         this.ipAddress = ipAddress;
+         return self();
+      }
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.IP#getSubnetId
+       */
+      public Builder subnetId(String subnetId) {
+         this.subnetId = subnetId;
+         return self();
+      }
+
+      public IP build() {
+         return new IP(ipAddress, subnetId);
+      }
+
+      public Builder fromIP(IP in) {
+         return this.ipAddress(in.getIpAddress()).subnetId(in.getSubnetId());
+      }
+   }
+
+   private static class ConcreteBuilder extends Builder {
+      @Override
+      protected ConcreteBuilder self() {
+         return this;
+      }
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/895476f1/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/domain/Network.java
----------------------------------------------------------------------
diff --git a/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/domain/Network.java b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/domain/Network.java
new file mode 100644
index 0000000..294de8c
--- /dev/null
+++ b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/domain/Network.java
@@ -0,0 +1,257 @@
+/*
+ * 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.openstack.neutron.v2_0.domain;
+
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableSet;
+
+import java.beans.ConstructorProperties;
+import java.util.Set;
+
+/**
+ * A Neutron network
+ *
+ * @author Nick Livens
+ * @see <a href="http://docs.openstack.org/api/openstack-network/2.0/content/Networks.html">api doc</a>
+ */
+public class Network extends ReferenceWithName {
+
+   private final State state;
+   private final Set<String> subnets;
+   private final Boolean adminStateUp;
+   private final Boolean shared;
+   private final Boolean external;
+   private final NetworkType networkType;
+   private final String physicalNetworkName;
+   private final Integer segmentationId;
+
+   @ConstructorProperties({
+      "id", "tenant_id", "name", "status", "subnets", "admin_state_up", "shared", "router:external",
+      "provider:network_type", "provider:physical_network", "provider:segmentation_id"
+   })
+   protected Network(String id, String tenantId, String name, State state,
+                     Set<String> subnets, Boolean adminStateUp, Boolean shared, Boolean external,
+                     String networkType, String physicalNetworkName, Integer segmentationId) {
+      super(id, tenantId, name);
+      this.state = state;
+      this.subnets = subnets != null ? ImmutableSet.copyOf(subnets) : ImmutableSet.<String>of();
+      this.adminStateUp = adminStateUp;
+      this.shared = shared;
+      this.external = external;
+      this.networkType = NetworkType.fromValue(networkType);
+      this.physicalNetworkName = physicalNetworkName;
+      this.segmentationId = segmentationId;
+   }
+
+   /**
+    * @return the current state of the network
+    */
+   public State getState() {
+      return state;
+   }
+
+   /**
+    * @return set of subnet ids that are associated with this network
+    */
+   public Set<String> getSubnets() {
+      return subnets;
+   }
+
+   /**
+    * @return the administrative state of network. If false, the network does not forward packets.
+    */
+   public Boolean getAdminStateUp() {
+      return adminStateUp;
+   }
+
+   /**
+    * @return true if the network resource can be accessed by any tenant or not, false if not
+    */
+   public Boolean getShared() {
+      return shared;
+   }
+
+   /**
+    * @return true if network is external, false if not
+    */
+   public Boolean getExternal() {
+      return external;
+   }
+
+   /**
+    * @return the type of network
+    */
+   public NetworkType getNetworkType() {
+      return networkType;
+   }
+
+   /**
+    * @return the physical network name
+    */
+   public String getPhysicalNetworkName() {
+      return physicalNetworkName;
+   }
+
+   /**
+    * @return the segmentation id of the network
+    */
+   public Integer getSegmentationId() {
+      return segmentationId;
+   }
+
+   @Override
+   public int hashCode() {
+      return Objects.hashCode(super.hashCode(), state, subnets, adminStateUp, shared, external,
+         networkType, physicalNetworkName, segmentationId);
+   }
+
+   @Override
+   public boolean equals(Object obj) {
+      if (this == obj) return true;
+      if (obj == null || getClass() != obj.getClass()) return false;
+      Network that = Network.class.cast(obj);
+      return super.equals(obj)
+         && Objects.equal(this.state, that.state)
+         && Objects.equal(this.subnets, that.subnets)
+         && Objects.equal(this.adminStateUp, that.adminStateUp)
+         && Objects.equal(this.shared, that.shared)
+         && Objects.equal(this.external, that.external)
+         && Objects.equal(this.networkType, that.networkType)
+         && Objects.equal(this.physicalNetworkName, that.physicalNetworkName)
+         && Objects.equal(this.segmentationId, that.segmentationId);
+   }
+
+   protected Objects.ToStringHelper string() {
+      return super.string()
+         .add("state", state).add("subnets", subnets).add("adminStateUp", adminStateUp).add("shared", shared).add("external", external)
+         .add("networkType", networkType).add("physicalNetworkName", physicalNetworkName).add("segmentationId", segmentationId);
+   }
+
+   @Override
+   public String toString() {
+      return string().toString();
+   }
+
+   public static Builder<?> builder() {
+      return new ConcreteBuilder();
+   }
+
+   public Builder<?> toBuilder() {
+      return new ConcreteBuilder().fromNetwork(this);
+   }
+
+   public static abstract class Builder<T extends Builder<T>> extends ReferenceWithName.Builder<T> {
+      protected State state;
+      protected Set<String> subnets;
+      protected Boolean adminStateUp;
+      protected Boolean shared;
+      protected Boolean external;
+      protected NetworkType networkType;
+      protected String physicalNetworkName;
+      protected Integer segmentationId;
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.Network#getState()
+       */
+      public T state(State state) {
+         this.state = state;
+         return self();
+      }
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.Network#getSubnets()
+       */
+      public T subnets(Set<String> subnets) {
+         this.subnets = subnets;
+         return self();
+      }
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.Network#getAdminStateUp()
+       */
+      public T adminStateUp(Boolean adminStateUp) {
+         this.adminStateUp = adminStateUp;
+         return self();
+      }
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.Network#getShared()
+       */
+      public T shared(Boolean shared) {
+         this.shared = shared;
+         return self();
+      }
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.Network#getExternal()
+       */
+      public T external(Boolean external) {
+         this.external = external;
+         return self();
+      }
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.Network#getNetworkType()
+       */
+      public T networkType(NetworkType networkType) {
+         this.networkType = networkType;
+         return self();
+      }
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.Network#getPhysicalNetworkName()
+       */
+      public T physicalNetworkName(String physicalNetworkName) {
+         this.physicalNetworkName = physicalNetworkName;
+         return self();
+      }
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.Network#getSegmentationId()
+       */
+      public T segmentationId(Integer segmentationId) {
+         this.segmentationId = segmentationId;
+         return self();
+      }
+
+      public Network build() {
+         return new Network(id, tenantId, name, state, subnets, adminStateUp, shared, external, networkType == null ? null : networkType.getValue(), physicalNetworkName, segmentationId);
+      }
+
+      public T fromNetwork(Network in) {
+         return super.fromReference(in)
+               .state(in.getState())
+               .subnets(in.getSubnets())
+               .adminStateUp(in.getAdminStateUp())
+               .shared(in.getShared())
+               .external(in.getExternal())
+               .networkType(in.getNetworkType())
+               .physicalNetworkName(in.getPhysicalNetworkName())
+               .segmentationId(in.getSegmentationId());
+      }
+   }
+
+   private static class ConcreteBuilder extends Builder<ConcreteBuilder> {
+      @Override
+      protected ConcreteBuilder self() {
+         return this;
+      }
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/895476f1/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/domain/NetworkType.java
----------------------------------------------------------------------
diff --git a/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/domain/NetworkType.java b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/domain/NetworkType.java
new file mode 100644
index 0000000..ba7e886
--- /dev/null
+++ b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/domain/NetworkType.java
@@ -0,0 +1,46 @@
+/*
+ * 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.openstack.neutron.v2_0.domain;
+
+/**
+ * The type of Network
+ *
+ * @author Nick Livens
+ */
+public enum NetworkType {
+   LOCAL("local"), FLAT("flat"), VLAN("vlan"), GRE("gre");
+
+   private String value;
+
+   private NetworkType(String value) {
+      this.value = value;
+   }
+
+   public String getValue() {
+      return value;
+   }
+
+   public static NetworkType fromValue(String value) {
+      for (NetworkType networkType : values()) {
+         if (networkType.getValue().equalsIgnoreCase(value))
+            return networkType;
+      }
+      return null;
+   }
+}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/895476f1/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/domain/Port.java
----------------------------------------------------------------------
diff --git a/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/domain/Port.java b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/domain/Port.java
new file mode 100644
index 0000000..b04a52c
--- /dev/null
+++ b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/domain/Port.java
@@ -0,0 +1,234 @@
+/*
+ * 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.openstack.neutron.v2_0.domain;
+
+import com.google.common.base.Objects;
+
+import java.beans.ConstructorProperties;
+import java.util.Set;
+
+/**
+ * A Neutron port
+ *
+ * @author Nick Livens
+ * @see <a href="http://docs.openstack.org/api/openstack-network/1.0/content/Ports.html">api doc</a>
+ */
+public class Port extends ReferenceWithName {
+
+   private final State state;
+   private final Boolean adminStateUp;
+   private final String networkId;
+   private final String deviceId;
+   private final String deviceOwner;
+   private final String macAddress;
+   private final Set<IP> fixedIps;
+
+   @ConstructorProperties({
+      "id", "tenant_id", "name", "status", "network_id", "admin_state_up", "device_id", "device_owner", "fixed_ips", "mac_address"
+   })
+   protected Port(String id, String tenantId, String name, State state, String networkId, Boolean adminStateUp,
+                  String deviceId, String deviceOwner, Set<IP> fixedIps, String macAddress) {
+      super(id, tenantId, name);
+      this.adminStateUp = adminStateUp;
+      this.state = state;
+      this.networkId = networkId;
+      this.deviceId = deviceId;
+      this.deviceOwner = deviceOwner;
+      this.fixedIps = fixedIps;
+      this.macAddress = macAddress;
+   }
+
+   /**
+    * @return the current state of the port
+    */
+   public State getState() {
+      return this.state;
+   }
+
+   /**
+    * @return the administrative state of port. If false, port does not forward packets.
+    */
+   public Boolean getAdminStateUp() {
+      return adminStateUp;
+   }
+
+   /**
+    * @return the id of the network where this port is associated with
+    */
+   public String getNetworkId() {
+      return networkId;
+   }
+
+   /**
+    * @return the id of the device (e.g. server) using this port.
+    */
+   public String getDeviceId() {
+      return deviceId;
+   }
+
+   /**
+    * @return the entity (e.g.: dhcp agent) using this port.
+    */
+   public String getDeviceOwner() {
+      return deviceOwner;
+   }
+
+   /**
+    * @return the set of fixed ips this port has been assigned
+    */
+   public Set<IP> getFixedIps() {
+      return fixedIps;
+   }
+
+   /**
+    * @return the mac address of this port
+    */
+   public String getMacAddress() {
+      return macAddress;
+   }
+
+   @Override
+   public int hashCode() {
+      return Objects.hashCode(super.hashCode(), state, adminStateUp, networkId, deviceId, deviceOwner, fixedIps, macAddress);
+   }
+
+   @Override
+   public boolean equals(Object obj) {
+      if (this == obj) return true;
+      if (obj == null || getClass() != obj.getClass()) return false;
+      Port that = Port.class.cast(obj);
+      return super.equals(obj)
+         && Objects.equal(this.state, that.state)
+         && Objects.equal(this.adminStateUp, that.adminStateUp)
+         && Objects.equal(this.networkId, that.networkId)
+         && Objects.equal(this.deviceId, that.deviceId)
+         && Objects.equal(this.deviceOwner, that.deviceOwner)
+         && Objects.equal(this.fixedIps, that.fixedIps)
+         && Objects.equal(this.macAddress, that.macAddress);
+   }
+
+   protected Objects.ToStringHelper string() {
+      return super.string()
+         .add("state", state).add("adminStateUp", adminStateUp).add("networkId", networkId).add("deviceId", deviceId)
+         .add("deviceOwner", deviceOwner).add("fixedIps", fixedIps).add("macAddress", macAddress);
+   }
+
+   @Override
+   public String toString() {
+      return string().toString();
+   }
+
+   public static Builder<?> builder() {
+      return new ConcreteBuilder();
+   }
+
+   public Builder<?> toBuilder() {
+      return new ConcreteBuilder().fromPort(this);
+   }
+
+   public static abstract class Builder<T extends Builder<T>> extends ReferenceWithName.Builder<T> {
+      protected String networkId;
+      protected String deviceId;
+      protected String deviceOwner;
+      protected String macAddress;
+      protected Set<IP> fixedIps;
+      protected State state;
+      protected Boolean adminStateUp;
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.Port#getState()
+       */
+      public T state(State state) {
+         this.state = state;
+         return self();
+      }
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.Port#getNetworkId()
+       */
+      public T networkId(String networkId) {
+         this.networkId = networkId;
+         return self();
+      }
+
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.Port#getAdminStateUp()
+       */
+      public T adminStateUp(Boolean adminStateUp) {
+         this.adminStateUp = adminStateUp;
+         return self();
+      }
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.Port#getDeviceId()
+       */
+      public T deviceId(String deviceId) {
+         this.deviceId = deviceId;
+         return self();
+      }
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.Port#getDeviceOwner()
+       */
+      public T deviceOwner(String deviceOwner) {
+         this.deviceOwner = deviceOwner;
+         return self();
+      }
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.Port#getDeviceId()
+       */
+      public T fixedIps(Set<IP> fixedIps) {
+         this.fixedIps = fixedIps;
+         return self();
+      }
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.Port#getMacAddress()
+       */
+      public T macAddress(String macAddress) {
+         this.macAddress = macAddress;
+         return self();
+      }
+
+      public Port build() {
+         return new Port(id, tenantId, name, state, networkId, adminStateUp, deviceId, deviceOwner, fixedIps, macAddress);
+      }
+
+      public T fromPort(Port in) {
+         return super.fromReference(in)
+               .state(in.getState())
+               .networkId(in.getNetworkId())
+               .adminStateUp(in.getAdminStateUp())
+               .deviceId(in.getDeviceId())
+               .deviceOwner(in.getDeviceOwner())
+               .fixedIps(in.getFixedIps())
+               .macAddress(in.getMacAddress());
+      }
+   }
+
+   private static class ConcreteBuilder extends Builder<ConcreteBuilder> {
+      @Override
+      protected ConcreteBuilder self() {
+         return this;
+      }
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/895476f1/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/domain/Reference.java
----------------------------------------------------------------------
diff --git a/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/domain/Reference.java b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/domain/Reference.java
new file mode 100644
index 0000000..b8d57cc
--- /dev/null
+++ b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/domain/Reference.java
@@ -0,0 +1,129 @@
+/*
+ * 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.openstack.neutron.v2_0.domain;
+
+import com.google.common.base.Objects;
+
+import java.beans.ConstructorProperties;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Base class for beans in the Neutron v2.0 api
+ *
+ * @author Nick Livens
+ * @see <a href="http://docs.openstack.org/api/openstack-network/2.0/content/Networks.html">api doc</a>
+ */
+public class Reference {
+
+   private final String id;
+   private final String tenantId;
+
+   @ConstructorProperties({
+      "id", "tenant_id"
+   })
+   protected Reference(String id, String tenantId) {
+      this.id = checkNotNull(id, "id");
+      this.tenantId = checkNotNull(tenantId, "tenantId");
+   }
+
+   /**
+    * @return the id of the entity
+    */
+   public String getId() {
+      return this.id;
+   }
+
+   /**
+    * @return the id of the tenant where this entity is associated with
+    */
+   public String getTenantId() {
+      return tenantId;
+   }
+
+   @Override
+   public int hashCode() {
+      return Objects.hashCode(id, tenantId);
+   }
+
+   @Override
+   public boolean equals(Object obj) {
+      if (this == obj) return true;
+      if (obj == null || getClass() != obj.getClass()) return false;
+      Reference that = Reference.class.cast(obj);
+      return Objects.equal(this.id, that.id) && Objects.equal(this.tenantId, that.tenantId);
+   }
+
+   protected Objects.ToStringHelper string() {
+      return Objects.toStringHelper(this)
+         .add("id", id).add("tenantId", tenantId);
+   }
+
+   @Override
+   public String toString() {
+      return string().toString();
+   }
+
+   public static Builder<?> builder() {
+      return new ConcreteBuilder();
+   }
+
+   public Builder<?> toBuilder() {
+      return new ConcreteBuilder().fromReference(this);
+   }
+
+   public static abstract class Builder<T extends Builder<T>> {
+      protected abstract T self();
+
+      protected String id;
+      protected String tenantId;
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.Reference#getId()
+       */
+      public T id(String id) {
+         this.id = id;
+         return self();
+      }
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.Reference#getTenantId()
+       */
+      public T tenantId(String tenantId) {
+         this.tenantId = tenantId;
+         return self();
+      }
+
+      public Reference build() {
+         return new Reference(id, tenantId);
+      }
+
+      public T fromReference(Reference in) {
+         return this.id(in.getId()).tenantId(in.getTenantId());
+      }
+   }
+
+   private static class ConcreteBuilder extends Builder<ConcreteBuilder> {
+      @Override
+      protected ConcreteBuilder self() {
+         return this;
+      }
+   }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-openstack/blob/895476f1/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/domain/ReferenceWithName.java
----------------------------------------------------------------------
diff --git a/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/domain/ReferenceWithName.java b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/domain/ReferenceWithName.java
new file mode 100644
index 0000000..e1eb758
--- /dev/null
+++ b/openstack-neutron/src/main/java/org/jclouds/openstack/neutron/v2_0/domain/ReferenceWithName.java
@@ -0,0 +1,111 @@
+/*
+ * 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.openstack.neutron.v2_0.domain;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Objects.ToStringHelper;
+import com.google.common.base.Strings;
+
+import java.beans.ConstructorProperties;
+
+/**
+ * Base class for beans in the Neutron v2.0 api
+ *
+ * @author Nick Livens
+ * @see <a href="http://docs.openstack.org/api/openstack-network/2.0/content/Networks.html">api doc</a>
+ */
+public class ReferenceWithName extends Reference {
+
+   private final String name;
+
+   @ConstructorProperties({
+      "id", "tenant_id", "name"
+   })
+   protected ReferenceWithName(String id, String tenantId, String name) {
+      super(id, tenantId);
+      this.name = Strings.nullToEmpty(name);
+   }
+
+   /**
+    * @return the name of the entity
+    */
+   public String getName() {
+      return name;
+   }
+
+   @Override
+   public int hashCode() {
+      return Objects.hashCode(super.hashCode(), name);
+   }
+
+   @Override
+   public boolean equals(Object obj) {
+      if (this == obj) return true;
+      if (obj == null || getClass() != obj.getClass()) return false;
+      ReferenceWithName that = ReferenceWithName.class.cast(obj);
+      return super.equals(obj) && Objects.equal(this.name, that.name);
+   }
+
+   protected ToStringHelper string() {
+      return super.string().add("name", name);
+   }
+
+   @Override
+   public String toString() {
+      return string().toString();
+   }
+
+   public static Builder<?> builder() {
+      return new ConcreteBuilder();
+   }
+
+   public Builder<?> toBuilder() {
+      return new ConcreteBuilder().fromReferenceWithName(this);
+   }
+
+   public static abstract class Builder<T extends Builder<T>> extends Reference.Builder<T> {
+      protected abstract T self();
+
+      protected String name;
+
+      /**
+       * @see org.jclouds.openstack.neutron.v2_0.domain.ReferenceWithName#getName()
+       */
+      public T name(String name) {
+         this.name = name;
+         return self();
+      }
+
+      public ReferenceWithName build() {
+         return new ReferenceWithName(id, tenantId, name);
+      }
+
+      public T fromReferenceWithName(ReferenceWithName in) {
+         return super.fromReference(in).name(in.getName());
+      }
+   }
+
+   private static class ConcreteBuilder extends Builder<ConcreteBuilder> {
+      @Override
+      protected ConcreteBuilder self() {
+         return this;
+      }
+   }
+
+}