cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From chipchild...@apache.org
Subject [6/6] git commit: updated refs/heads/contrail to 7099686
Date Tue, 08 Oct 2013 13:38:38 GMT
Contrail network virtualization plugin.


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/7099686b
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/7099686b
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/7099686b

Branch: refs/heads/contrail
Commit: 7099686b7094d272cb55f30da116f48f05caf185
Parents: f6c6f03
Author: Pedro Marques <roque@juniper.net>
Authored: Fri Sep 20 03:17:19 2013 -0700
Committer: Chip Childers <chipchilders@apache.org>
Committed: Tue Oct 8 09:38:06 2013 -0400

----------------------------------------------------------------------
 api/src/com/cloud/network/Network.java          |   1 +
 client/pom.xml                                  |   5 +
 client/tomcatconf/applicationContext.xml.in     |   2 +
 client/tomcatconf/commands.properties.in        |   3 +
 client/tomcatconf/componentContext.xml.in       |  23 +
 .../xen/resource/CitrixResourceBase.java        |  13 +-
 .../network-elements/juniper-contrail/pom.xml   | 139 +++
 .../api/command/CreateServiceInstanceCmd.java   | 166 ++++
 .../api/response/ServiceInstanceResponse.java   |  66 ++
 .../contrail/management/ContrailElement.java    |  11 +
 .../management/ContrailElementImpl.java         | 425 +++++++++
 .../contrail/management/ContrailGuru.java       | 316 +++++++
 .../contrail/management/ContrailManager.java    |  74 ++
 .../management/ContrailManagerImpl.java         | 717 ++++++++++++++
 .../contrail/management/DBSyncGeneric.java      | 305 ++++++
 .../juniper/contrail/management/EventUtils.java | 104 ++
 .../management/ManagementNetworkGuru.java       | 100 ++
 .../contrail/management/ModelDatabase.java      |  72 ++
 .../contrail/management/ServerDBSync.java       |  22 +
 .../contrail/management/ServerDBSyncImpl.java   | 948 +++++++++++++++++++
 .../contrail/management/ServerEventHandler.java |   5 +
 .../management/ServerEventHandlerImpl.java      | 223 +++++
 .../contrail/management/ServiceManager.java     |  23 +
 .../contrail/management/ServiceManagerImpl.java | 232 +++++
 .../management/ServiceVirtualMachine.java       |  13 +
 .../juniper/contrail/model/FloatingIpModel.java | 195 ++++
 .../contrail/model/FloatingIpPoolModel.java     | 152 +++
 .../juniper/contrail/model/InstanceIpModel.java | 157 +++
 .../juniper/contrail/model/ModelController.java |  67 ++
 .../net/juniper/contrail/model/ModelObject.java | 101 ++
 .../juniper/contrail/model/ModelObjectBase.java |  94 ++
 .../contrail/model/ServiceInstanceModel.java    | 303 ++++++
 .../contrail/model/VMInterfaceModel.java        | 248 +++++
 .../contrail/model/VirtualMachineModel.java     | 332 +++++++
 .../contrail/model/VirtualNetworkModel.java     | 477 ++++++++++
 .../contrail/management/MockAccountManager.java | 354 +++++++
 .../management/NetworkProviderTest.java         | 789 +++++++++++++++
 .../contrail/management/TestConfiguration.java  | 803 ++++++++++++++++
 .../contrail/management/TestDbSetup.java        | 141 +++
 .../management/VirtualNetworkModelTest.java     |  44 +
 .../test/resources/contrail.properties          |   2 +
 .../test/resources/db.properties                |  50 +
 .../test/resources/log4j.properties             |  35 +
 .../test/resources/mysql_db_start.sh            |  23 +
 .../test/resources/mysql_db_stop.sh             |  14 +
 .../test/resources/serviceContext.xml           | 200 ++++
 plugins/pom.xml                                 |   1 +
 47 files changed, 8586 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7099686b/api/src/com/cloud/network/Network.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/network/Network.java b/api/src/com/cloud/network/Network.java
index 49f380b..bda3326 100644
--- a/api/src/com/cloud/network/Network.java
+++ b/api/src/com/cloud/network/Network.java
@@ -114,6 +114,7 @@ public interface Network extends ControlledEntity, StateObject<Network.State>, I
         private static List<Provider> supportedProviders = new ArrayList<Provider>();
 
         public static final Provider VirtualRouter = new Provider("VirtualRouter", false);
+        public static final Provider JuniperContrail = new Provider("JuniperContrail", false);
         public static final Provider JuniperSRX = new Provider("JuniperSRX", true);
         public static final Provider F5BigIp = new Provider("F5BigIp", true);
         public static final Provider Netscaler = new Provider("Netscaler", true);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7099686b/client/pom.xml
----------------------------------------------------------------------
diff --git a/client/pom.xml b/client/pom.xml
index fd1f13a..4a0dd3f 100644
--- a/client/pom.xml
+++ b/client/pom.xml
@@ -77,6 +77,11 @@
     </dependency>
     <dependency>
       <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-plugin-network-contrail</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
       <artifactId>cloud-plugin-network-ovs</artifactId>
       <version>${project.version}</version>
     </dependency>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7099686b/client/tomcatconf/applicationContext.xml.in
----------------------------------------------------------------------
diff --git a/client/tomcatconf/applicationContext.xml.in b/client/tomcatconf/applicationContext.xml.in
index 6dda5c7..0ab2515 100644
--- a/client/tomcatconf/applicationContext.xml.in
+++ b/client/tomcatconf/applicationContext.xml.in
@@ -42,12 +42,14 @@
   <bean id="componentContext" class="com.cloud.utils.component.ComponentContext" />
   <bean id="transactionContextBuilder" class="com.cloud.utils.db.TransactionContextBuilder" />
   <bean id="actionEventInterceptor" class="com.cloud.event.ActionEventInterceptor" />
+  <bean id="contrailEventInterceptor" class="net.juniper.contrail.management.EventUtils.EventInterceptor" />
 
   <bean id="instantiatePostProcessor" class="com.cloud.utils.component.ComponentInstantiationPostProcessor">
     <property name="Interceptors">
         <list>
             <ref bean="transactionContextBuilder" />
             <ref bean="actionEventInterceptor" />
+            <ref bean="contrailEventInterceptor" />
         </list>
     </property>
   </bean>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7099686b/client/tomcatconf/commands.properties.in
----------------------------------------------------------------------
diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in
index 58c770d..588092e 100644
--- a/client/tomcatconf/commands.properties.in
+++ b/client/tomcatconf/commands.properties.in
@@ -678,3 +678,6 @@ addLdapConfiguration=3
 deleteLdapConfiguration=3
 listLdapUsers=3
 ldapCreateAccount=3
+
+#### juniper-contrail commands
+createServiceInstance=1

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7099686b/client/tomcatconf/componentContext.xml.in
----------------------------------------------------------------------
diff --git a/client/tomcatconf/componentContext.xml.in b/client/tomcatconf/componentContext.xml.in
index df5b002..157ad5a 100644
--- a/client/tomcatconf/componentContext.xml.in
+++ b/client/tomcatconf/componentContext.xml.in
@@ -235,6 +235,26 @@
     </property>
   </bean>
 
+  <bean id="messageBus" class = "org.apache.cloudstack.framework.messagebus.MessageBusBase" />
+
+  <!--
+      Juniper Contrail support components
+  -->
+  <bean id="ContrailManager"
+	class="net.juniper.contrail.management.ContrailManagerImpl"/>
+  <bean id="ContrailElement"
+	class="net.juniper.contrail.management.ContrailElementImpl"/>
+  <bean id="ContrailGuru"
+	class="net.juniper.contrail.management.ContrailGuru"/>
+  <bean id="ServerDBSync"
+	class="net.juniper.contrail.management.ServerDBSyncImpl"/>
+  <bean id="ServerEventHandler"
+	class="net.juniper.contrail.management.ServerEventHandlerImpl"/>
+  <bean id="EventUtils"
+	class="net.juniper.contrail.management.EventUtils"/>
+  <bean id="ServiceManager"
+	class="net.juniper.contrail.management.ServiceManagerImpl"/>
+
   <!-- Networking adapters -->
   <bean id="ipDeployers" class="com.cloud.utils.component.AdapterList">
     <property name="Adapters">
@@ -244,6 +264,7 @@
           <ref bean="VpcVirtualRouter"/>
           <ref bean="NiciraNvp"/>
           <ref bean="InternalLbVm"/>
+	  <ref bean="ContrailElement"/>
       </list>
     </property>
   </bean>
@@ -269,6 +290,7 @@
           <ref bean="ControlNetworkGuru"/>
           <ref bean="DirectNetworkGuru"/>
           <ref bean="OvsGuestNetworkGuru"/>
+	  <ref bean="ContrailGuru"/>
           <ref bean="PrivateNetworkGuru"/>
           <ref bean="NiciraNvpGuestNetworkGuru"/>
           <ref bean="MidoNetGuestNetworkGuru"/>
@@ -282,6 +304,7 @@
     <property name="Adapters">
       <list>
           <ref bean="VirtualRouter"/>
+          <ref bean="ContrailElement"/>
           <ref bean="Ovs"/>
           <ref bean="SecurityGroupProvider"/>
           <ref bean="VpcVirtualRouter"/>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7099686b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
index 92fbab2..137d04e 100644
--- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
+++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
@@ -1070,7 +1070,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
         throw new CloudRuntimeException("Unable to support this type of network broadcast domain: " + nic.getBroadcastUri());
     }
 
-    protected VIF createVif(Connection conn, String vmName, VM vm, NicTO nic) throws XmlRpcException, XenAPIException {
+    protected VIF createVif(Connection conn, String vmName, VM vm, VirtualMachineTO vmSpec, NicTO nic) throws XmlRpcException, XenAPIException {
         assert(nic.getUuid() != null) : "Nic should have a uuid value";
 
         if (s_logger.isDebugEnabled()) {
@@ -1085,6 +1085,11 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
         vifr.otherConfig = new HashMap<String, String>();
         vifr.otherConfig.put("nicira-iface-id", nic.getUuid());
         vifr.otherConfig.put("nicira-vm-id", vm.getUuid(conn));
+        // Provide XAPI with the cloudstack vm and nic uids.
+        vifr.otherConfig.put("cloudstack-nic-id", nic.getUuid());
+	if (vmSpec != null) {
+	    vifr.otherConfig.put("cloudstack-vm-id", vmSpec.getUuid()); 
+	}
 
         vifr.network = getNetwork(conn, nic);
 
@@ -1633,7 +1638,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
             }
 
             for (NicTO nic : vmSpec.getNics()) {
-                createVif(conn, vmName, vm, nic);
+                createVif(conn, vmName, vm, vmSpec, nic);
             }
 
             startVM(conn, host, vm, vmName);
@@ -2292,7 +2297,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
 
                 nic.setDeviceId(Integer.parseInt(vifDeviceNum));
 
-                correctVif = createVif(conn, vmName, router, nic);
+                correctVif = createVif(conn, vmName, router, null, nic);
                 correctVif.plug(conn);
                 // Add iptables rule for network usage
                 networkUsage(conn, privateIpAddress, "addVif", "eth" + correctVif.getDevice(conn));
@@ -8209,7 +8214,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
             }
             String deviceId = getLowestAvailableVIFDeviceNum(conn, vm);
             nic.setDeviceId(Integer.parseInt(deviceId));
-            vif = createVif(conn, vmName, vm, nic);
+            vif = createVif(conn, vmName, vm, null, nic);
             vif.plug(conn);
             return new PlugNicAnswer(cmd, true, "success");
         } catch (Exception e) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7099686b/plugins/network-elements/juniper-contrail/pom.xml
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/pom.xml b/plugins/network-elements/juniper-contrail/pom.xml
new file mode 100644
index 0000000..60ce059
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/pom.xml
@@ -0,0 +1,139 @@
+<!--
+  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/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>cloud-plugin-network-contrail</artifactId>
+  <name>Apache CloudStack Plugin - Network Juniper Contrail</name>
+  <parent>
+    <groupId>org.apache.cloudstack</groupId>
+    <artifactId>cloudstack-plugins</artifactId>
+    <version>4.3.0-SNAPSHOT</version>
+    <relativePath>../../pom.xml</relativePath>
+  </parent>
+  <repositories>
+    <repository>
+      <id>juniper-contrail</id>
+      <url>http://juniper.github.io/contrail-maven/snapshots</url>
+    </repository>
+  </repositories>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-api</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-server</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-plugin-hypervisor-xen</artifactId>
+      <version>${project.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-plugin-network-internallb</artifactId>
+      <version>${project.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-engine-orchestration</artifactId>
+      <version>${project.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-engine-api</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-engine-schema</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-framework-config</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cloudstack</groupId>
+      <artifactId>cloud-framework-events</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+      <version>${cs.guava.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>net.juniper.contrail</groupId>
+      <artifactId>juniper-contrail-api</artifactId>
+      <version>1.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>mysql</groupId>
+      <artifactId>mysql-connector-java</artifactId>
+      <version>${cs.mysql.version}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+        <groupId>org.apache.commons</groupId>
+        <artifactId>commons-exec</artifactId>
+        <version>1.1</version>
+    </dependency>
+    <dependency>
+        <groupId>org.mockito</groupId>
+        <artifactId>mockito-all</artifactId>
+        <version>1.9.5</version>
+    </dependency>
+  </dependencies>
+  <build>
+    <defaultGoal>install</defaultGoal>
+    <sourceDirectory>src</sourceDirectory>
+    <testSourceDirectory>test</testSourceDirectory>
+    <testResources>
+      <testResource>
+        <directory>test/resources</directory>
+      </testResource>
+    </testResources>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <configuration>
+          <argLine>-Xmx1024m</argLine>
+	  <excludes>
+	    <!--<exclude>**/NetworkProviderTest.java</exclude> -->
+	    </excludes>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+  <organization>
+  	<name>Juniper Networks</name>
+  	<url>http://www.juniper.net</url>
+  </organization>
+</project>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7099686b/plugins/network-elements/juniper-contrail/src/net/juniper/contrail/api/command/CreateServiceInstanceCmd.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/src/net/juniper/contrail/api/command/CreateServiceInstanceCmd.java b/plugins/network-elements/juniper-contrail/src/net/juniper/contrail/api/command/CreateServiceInstanceCmd.java
new file mode 100644
index 0000000..9a84d31
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/src/net/juniper/contrail/api/command/CreateServiceInstanceCmd.java
@@ -0,0 +1,166 @@
+package net.juniper.contrail.api.command;
+
+import javax.inject.Inject;
+
+import net.juniper.contrail.api.response.ServiceInstanceResponse;
+import net.juniper.contrail.management.ServiceManager;
+import net.juniper.contrail.management.ServiceVirtualMachine;
+
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCreateCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.DomainResponse;
+import org.apache.cloudstack.api.response.NetworkResponse;
+import org.apache.cloudstack.api.response.ProjectResponse;
+import org.apache.cloudstack.api.response.ServiceOfferingResponse;
+import org.apache.cloudstack.api.response.TemplateResponse;
+import org.apache.cloudstack.api.response.ZoneResponse;
+
+import com.cloud.dc.DataCenter;
+import com.cloud.event.EventTypes;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.NetworkRuleConflictException;
+import com.cloud.exception.ResourceAllocationException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.Network;
+import com.cloud.offering.ServiceOffering;
+import com.cloud.template.VirtualMachineTemplate;
+import com.cloud.user.Account;
+
+@APICommand(name = "createServiceInstance",
+    description="Creates a system virtual-machine that implements network services",
+    responseObject=ServiceInstanceResponse.class)
+public class CreateServiceInstanceCmd extends BaseAsyncCreateCmd {
+    private static final String s_name = "createserviceinstanceresponse";
+    
+    /// API parameters
+    @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class,
+            required = true, description = "Availability zone for the service instance")
+    private Long zoneId;
+
+    //Owner information
+    @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING,
+            description="An optional account for the virtual machine. Must be used with domainId.")
+    private String accountName;
+
+    @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.UUID, entityType=DomainResponse.class,
+            description="An optional domainId for the virtual machine. If the account parameter is used, domainId must also be used.")
+    private Long domainId;
+
+    @Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, entityType = ProjectResponse.class,
+            description = "Project ID for the service instance")
+    private Long projectId;
+    
+    @Parameter(name = "leftnetworkid", type = CommandType.UUID, entityType = NetworkResponse.class,
+            required = true, description = "The left (inside) network for service instance")
+    private Long leftNetworkId;
+    
+    @Parameter(name = "rightnetworkid", type = CommandType.UUID, entityType = NetworkResponse.class,
+            required = true, description = "The right (outside) network ID for the service instance")
+    private Long rightNetworkId;
+    
+    @Parameter(name = ApiConstants.TEMPLATE_ID, type = CommandType.UUID, entityType = TemplateResponse.class,
+            required = true, description = "The template ID that specifies the image for the service appliance")
+    private Long templateId;
+    
+    @Parameter(name = ApiConstants.SERVICE_OFFERING_ID, type = CommandType.UUID,
+            entityType = ServiceOfferingResponse.class, required = true,
+            description = "The service offering ID that defines the resources consumed by the service appliance")
+    private Long serviceOfferingId;
+
+    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING)
+    private String name;
+    
+    /// Implementation
+    @Inject ServiceManager _vrouterService;
+    @Override
+    public void create() throws ResourceAllocationException {
+        // Parameter validation
+        try {
+            DataCenter zone = _entityMgr.findById(DataCenter.class, zoneId);
+            if (zone == null) {
+                throw new InvalidParameterValueException("Unable to find zone ID " + zoneId);
+            }
+            
+            Account owner = _accountService.getActiveAccountById(getEntityOwnerId());
+
+            VirtualMachineTemplate template = _entityMgr.findById(VirtualMachineTemplate.class, templateId);
+            if (template == null) {
+                throw new InvalidParameterValueException("Invalid template ID " + templateId);
+            }
+            
+            ServiceOffering serviceOffering = _entityMgr.findById(ServiceOffering.class, serviceOfferingId);
+            if (serviceOffering == null) {
+                throw new InvalidParameterValueException("Invalid service offering ID " + serviceOfferingId);
+            }
+            
+            Network left = _networkService.getNetwork(leftNetworkId);
+            if (left == null) {
+                throw new InvalidParameterValueException("Invalid ID for left network " + leftNetworkId);
+            }
+            
+            Network right = _networkService.getNetwork(rightNetworkId);
+            if (right == null) {
+                throw new InvalidParameterValueException("Invalid ID for right network " + rightNetworkId);
+            }
+
+            ServiceVirtualMachine svm = _vrouterService.createServiceInstance(zone, owner, template, serviceOffering,
+                                                                              name, left, right);
+            if (svm == null) {
+                throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Unable to create service instance");
+            }
+            setEntityId(svm.getId());
+            setEntityUuid(svm.getUuid());
+        } catch (Exception ex) {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
+        }
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_VM_CREATE;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "Create service instance";
+    }
+
+    @Override
+    public void execute() throws ResourceUnavailableException,
+            InsufficientCapacityException, ServerApiException,
+            ConcurrentOperationException, ResourceAllocationException,
+            NetworkRuleConflictException {
+        try {
+            _vrouterService.startServiceInstance(getEntityId());
+            ServiceInstanceResponse response = _vrouterService.createServiceInstanceResponse(getEntityId());
+            response.setObjectName("serviceinstance");
+            response.setResponseName(getCommandName());
+            this.setResponseObject(response);
+        } catch (Exception ex) {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
+        }
+    }
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        Long accountId = finalyzeAccountId(accountName, domainId, projectId, true);
+        if (accountId == null) {
+            return CallContext.current().getCallingAccount().getId();
+        }
+
+        return accountId;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7099686b/plugins/network-elements/juniper-contrail/src/net/juniper/contrail/api/response/ServiceInstanceResponse.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/src/net/juniper/contrail/api/response/ServiceInstanceResponse.java b/plugins/network-elements/juniper-contrail/src/net/juniper/contrail/api/response/ServiceInstanceResponse.java
new file mode 100644
index 0000000..00fe7d3
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/src/net/juniper/contrail/api/response/ServiceInstanceResponse.java
@@ -0,0 +1,66 @@
+package net.juniper.contrail.api.response;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseResponse;
+import org.apache.cloudstack.api.response.ControlledEntityResponse;
+
+import com.cloud.serializer.Param;
+import com.google.gson.annotations.SerializedName;
+
+public class ServiceInstanceResponse extends BaseResponse implements
+        ControlledEntityResponse {
+    
+    @SerializedName(ApiConstants.ID) @Param(description="the ID of the virtual machine")
+    private String id;
+
+    @SerializedName(ApiConstants.NAME) @Param(description="the name of the virtual machine")
+    private String name;
+
+    @SerializedName("displayname") @Param(description="user generated name. The name of the virtual machine is returned if no displayname exists.")
+    private String displayName;
+
+    @SerializedName(ApiConstants.ACCOUNT) @Param(description="the account associated with the virtual machine")
+    private String accountName;
+
+    @SerializedName(ApiConstants.PROJECT_ID) @Param(description="the project id of the vm")
+    private String projectId;
+
+    @SerializedName(ApiConstants.PROJECT) @Param(description="the project name of the vm")
+    private String projectName;
+
+    @SerializedName(ApiConstants.DOMAIN_ID) @Param(description="the ID of the domain in which the virtual machine exists")
+    private String domainId;
+
+    @SerializedName(ApiConstants.DOMAIN) @Param(description="the name of the domain in which the virtual machine exists")
+    private String domainName;
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    @Override
+    public void setAccountName(String accountName) {
+        this.accountName = accountName;
+    }
+
+    @Override
+    public void setProjectId(String projectId) {
+        this.projectId = projectId;
+    }
+
+    @Override
+    public void setProjectName(String projectName) {
+        this.projectName = projectName;
+    }
+
+    @Override
+    public void setDomainId(String domainId) {
+        this.domainId = domainId;
+    }
+
+    @Override
+    public void setDomainName(String domainName) {
+        this.domainName = domainName;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7099686b/plugins/network-elements/juniper-contrail/src/net/juniper/contrail/management/ContrailElement.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/src/net/juniper/contrail/management/ContrailElement.java b/plugins/network-elements/juniper-contrail/src/net/juniper/contrail/management/ContrailElement.java
new file mode 100644
index 0000000..bd2bdbc
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/src/net/juniper/contrail/management/ContrailElement.java
@@ -0,0 +1,11 @@
+package net.juniper.contrail.management;
+
+import com.cloud.utils.component.PluggableService;
+
+// Network Provider plugin
+public interface ContrailElement extends PluggableService {
+    /**
+     * TODO:
+     * define APIs to configure the Network Virtualization service.
+     */
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7099686b/plugins/network-elements/juniper-contrail/src/net/juniper/contrail/management/ContrailElementImpl.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/src/net/juniper/contrail/management/ContrailElementImpl.java b/plugins/network-elements/juniper-contrail/src/net/juniper/contrail/management/ContrailElementImpl.java
new file mode 100644
index 0000000..d407edd
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/src/net/juniper/contrail/management/ContrailElementImpl.java
@@ -0,0 +1,425 @@
+package net.juniper.contrail.management;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+
+import net.juniper.contrail.api.command.CreateServiceInstanceCmd;
+import net.juniper.contrail.model.InstanceIpModel;
+import net.juniper.contrail.model.VMInterfaceModel;
+import net.juniper.contrail.model.VirtualMachineModel;
+import net.juniper.contrail.model.VirtualNetworkModel;
+
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.deploy.DeployDestination;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientCapacityException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.Network;
+import com.cloud.network.Network.Capability;
+import com.cloud.network.Network.Provider;
+import com.cloud.network.Network.Service;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.PhysicalNetworkServiceProvider;
+import com.cloud.network.PublicIpAddress;
+import com.cloud.network.element.DhcpServiceProvider;
+import com.cloud.network.element.IpDeployer;
+import com.cloud.network.element.NetworkACLServiceProvider;
+import com.cloud.network.element.SourceNatServiceProvider;
+import com.cloud.network.element.StaticNatServiceProvider;
+import com.cloud.network.element.VpcProvider;
+import com.cloud.network.rules.StaticNat;
+import com.cloud.network.vpc.NetworkACLItem;
+import com.cloud.network.vpc.PrivateGateway;
+import com.cloud.network.vpc.StaticRouteProfile;
+import com.cloud.network.vpc.Vpc;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.utils.component.AdapterBase;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.dao.NicDao;
+import com.cloud.network.IpAddress;
+
+@Component
+@Local(value = {NetworkACLServiceProvider.class, VpcProvider.class, ContrailElement.class,
+                StaticNatServiceProvider.class, IpDeployer.class, SourceNatServiceProvider.class})
+public class ContrailElementImpl extends AdapterBase
+        implements NetworkACLServiceProvider, VpcProvider,
+        ContrailElement, StaticNatServiceProvider, IpDeployer, SourceNatServiceProvider, DhcpServiceProvider {
+
+	private static final Map<Service, Map<Capability, String>> _capabilities = InitCapabilities();
+
+	@Inject ContrailManager _manager;
+	@Inject NicDao _nicDao;
+	@Inject ServerDBSync  _dbSync;
+	private static final Logger s_logger =
+			Logger.getLogger(ContrailElement.class);
+	
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+    	s_logger.debug("configure");
+    	return true;
+    }
+
+    // PluggableService
+    @Override
+    public List<Class<?>> getCommands() {
+    	List<Class<?>> cmdList = new ArrayList<Class<?>>();
+        cmdList.add(CreateServiceInstanceCmd.class);
+        return cmdList;
+    }
+
+    // NetworkElement API
+    @Override
+    public Provider getProvider() {
+        return Provider.JuniperContrail;
+    }
+
+    private static Map<Service, Map<Capability, String>> InitCapabilities() {
+    	Map<Service, Map<Capability, String>> capabilities = new HashMap<Service, Map<Capability, String>>();
+    	capabilities.put(Service.Connectivity, null);
+    	capabilities.put(Service.Dhcp, new HashMap<Capability, String>());
+        capabilities.put(Service.StaticNat, null);
+        capabilities.put(Service.SourceNat, null);
+
+    	return capabilities;
+    }
+
+	@Override
+	public Map<Service, Map<Capability, String>> getCapabilities() {
+		// TODO Auto-generated method stub
+		return _capabilities;
+	}
+
+	/**
+	 * Network add/update.
+	 */
+	@Override
+	public boolean implement(Network network, NetworkOffering offering,
+			DeployDestination dest, ReservationContext context)
+			throws ConcurrentOperationException, ResourceUnavailableException,
+			InsufficientCapacityException {
+	    s_logger.debug("NetworkElement implement: " + network.getName() + ", traffic type: " + network.getTrafficType());
+	    if (network.getTrafficType() == TrafficType.Guest) {
+	        s_logger.debug("ignore network " + network.getName());
+	        return true;        
+	    }
+	    VirtualNetworkModel vnModel = _manager.getDatabase().lookupVirtualNetwork(network.getUuid(), 
+	            _manager.getCanonicalName(network), network.getTrafficType());
+
+	    if (vnModel == null) {
+	        vnModel = new VirtualNetworkModel(network, network.getUuid(), 
+	                _manager.getCanonicalName(network), network.getTrafficType());
+	        vnModel.setProperties(_manager.getModelController(), network);
+	    }
+	    try {
+	        if (!vnModel.verify(_manager.getModelController())) {
+	            vnModel.update(_manager.getModelController());
+	        }
+	        _manager.getDatabase().getVirtualNetworks().add(vnModel);   
+	    } catch (Exception ex) {
+	        s_logger.warn("virtual-network update: ", ex);
+	    }
+	    return true;
+	}
+
+	@Override
+	public boolean prepare(Network network, NicProfile nicProfile,
+			VirtualMachineProfile vm,
+			DeployDestination dest, ReservationContext context)
+			throws ConcurrentOperationException, ResourceUnavailableException,
+			InsufficientCapacityException {
+
+	    s_logger.debug("NetworkElement prepare: " + network.getName() + ", traffic type: " + network.getTrafficType());
+
+	    if (network.getTrafficType() == TrafficType.Guest) {
+	        s_logger.debug("ignore network " + network.getName());
+	        return true;
+	    }
+
+	    s_logger.debug("network: " + network.getId());
+	    
+	    VirtualNetworkModel vnModel = _manager.getDatabase().lookupVirtualNetwork(network.getUuid(), 
+                _manager.getCanonicalName(network), network.getTrafficType());
+	    
+	    if (vnModel == null) {
+	        // There is no notification after a physical network is associated with the VRouter NetworkOffering
+	        // this may be the first time we see this network.
+	        return false;
+	    }
+
+	    VirtualMachineModel vmModel = _manager.getDatabase().lookupVirtualMachine(vm.getUuid());
+	    if (vmModel == null) {
+	        VMInstanceVO vmVo = (VMInstanceVO) vm.getVirtualMachine();
+	        vmModel = new VirtualMachineModel(vmVo, vm.getUuid());
+	        vmModel.setProperties(_manager.getModelController(), vmVo);
+	    }
+
+	    NicVO nic = _nicDao.findById(nicProfile.getId());
+	    assert nic != null;
+
+	    VMInterfaceModel vmiModel = vmModel.getVMInterface(nic.getUuid());
+	    if (vmiModel == null) {
+	        vmiModel = new VMInterfaceModel(nic.getUuid());
+	        vmiModel.addToVirtualMachine(vmModel);	
+                vmiModel.addToVirtualNetwork(vnModel);          
+	    }
+	    
+	    try {
+	        vmiModel.build(_manager.getModelController(), (VMInstanceVO) vm.getVirtualMachine(), nic);
+	    } catch (IOException ex) {
+	        s_logger.warn("vm interface set", ex);
+	        return false;
+	    }
+
+	    InstanceIpModel ipModel = vmiModel.getInstanceIp();
+	    if (ipModel == null) {
+	        ipModel = new InstanceIpModel(vm.getInstanceName(), nic.getDeviceId());
+	        ipModel.addToVMInterface(vmiModel);
+	    }
+	    ipModel.setAddress(nicProfile.getIp4Address());
+
+	    try {
+	        vmModel.update(_manager.getModelController());
+	    } catch (Exception ex) {
+	        s_logger.warn("virtual-machine-update", ex);
+	        return false;
+	    }
+	    _manager.getDatabase().getVirtualMachines().add(vmModel);   
+
+	    return true;
+	}
+
+	@Override
+	public boolean release(Network network, NicProfile nicProfile,
+			VirtualMachineProfile vm,
+			ReservationContext context) throws ConcurrentOperationException,
+			ResourceUnavailableException {
+	    if (network.getTrafficType() == TrafficType.Guest) {
+	        return true;
+	    } else if (!_manager.isManagedPhysicalNetwork(network)) {
+	        s_logger.debug("release ignore network " + network.getId());
+	        return true;
+	    }
+
+	    NicVO nic = _nicDao.findById(nicProfile.getId());
+	    assert nic != null;
+
+	    VirtualMachineModel vmModel = _manager.getDatabase().lookupVirtualMachine(vm.getUuid());
+	    if (vmModel == null) {
+	        s_logger.debug("vm " + vm.getInstanceName() + " not in local database");
+	        return true;
+	    }
+	    VMInterfaceModel vmiModel = vmModel.getVMInterface(nic.getUuid());
+	    if (vmiModel != null) {
+	        try {
+	            vmiModel.destroy(_manager.getModelController());
+	        } catch (IOException ex) {
+	            s_logger.warn("virtual-machine-interface delete", ex);
+	        }
+	        vmModel.removeSuccessor(vmiModel);
+	    }
+
+	    if (!vmModel.hasDescendents()) {
+	        _manager.getDatabase().getVirtualMachines().remove(vmModel);
+	        try {
+	            vmModel.delete(_manager.getModelController());
+	        } catch (IOException e) {
+	            return false;
+	        }
+	    }
+
+	    return true;
+	}
+
+	/**
+	 * Network disable
+	 */
+	@Override
+	public boolean shutdown(Network network, ReservationContext context,
+			boolean cleanup) throws ConcurrentOperationException,
+			ResourceUnavailableException {
+		// TODO Auto-generated method stub
+		s_logger.debug("NetworkElement shutdown");
+		return true;
+	}
+
+	/**
+	 * Network delete
+	 */
+	@Override
+	public boolean destroy(Network network, ReservationContext context)
+			throws ConcurrentOperationException, ResourceUnavailableException {
+		// TODO Auto-generated method stub
+		s_logger.debug("NetworkElement destroy");
+		return true;
+	}
+
+	@Override
+	public boolean isReady(PhysicalNetworkServiceProvider provider) {
+		return true;
+	}
+
+	@Override
+	public boolean shutdownProviderInstances(
+			PhysicalNetworkServiceProvider provider, ReservationContext context)
+			throws ConcurrentOperationException, ResourceUnavailableException {
+		// TODO Auto-generated method stub
+		s_logger.debug("NetworkElement shutdown ProviderInstances");
+		return true;
+	}
+
+	@Override
+	public boolean canEnableIndividualServices() {
+		return true;
+	}
+
+	@Override
+	public boolean verifyServicesCombination(Set<Service> services) {
+		// TODO Auto-generated method stub
+		s_logger.debug("NetworkElement verifyServices");
+		s_logger.debug("Services: " + services);
+		return true;
+	}
+
+	@Override
+	public boolean implementVpc(Vpc vpc, DeployDestination dest,
+			ReservationContext context) throws ConcurrentOperationException,
+			ResourceUnavailableException, InsufficientCapacityException {
+		// TODO Auto-generated method stub
+		s_logger.debug("NetworkElement implementVpc");
+		return true;
+	}
+
+	@Override
+	public boolean shutdownVpc(Vpc vpc, ReservationContext context)
+			throws ConcurrentOperationException, ResourceUnavailableException {
+		// TODO Auto-generated method stub
+		s_logger.debug("NetworkElement shutdownVpc");
+		return true;
+	}
+
+	@Override
+	public boolean createPrivateGateway(PrivateGateway gateway)
+			throws ConcurrentOperationException, ResourceUnavailableException {
+		// TODO Auto-generated method stub
+		s_logger.debug("NetworkElement createPrivateGateway");
+		return false;
+	}
+
+	@Override
+	public boolean deletePrivateGateway(PrivateGateway privateGateway)
+			throws ConcurrentOperationException, ResourceUnavailableException {
+		// TODO Auto-generated method stub
+		s_logger.debug("NetworkElement deletePrivateGateway");
+		return false;
+	}
+
+	@Override
+	public boolean applyStaticRoutes(Vpc vpc, List<StaticRouteProfile> routes)
+			throws ResourceUnavailableException {
+		// TODO Auto-generated method stub
+		s_logger.debug("NetworkElement applyStaticRoutes");
+		return false;
+	}
+
+	@Override
+	public boolean applyNetworkACLs(Network config,
+			List<? extends NetworkACLItem> rules)
+			throws ResourceUnavailableException {
+		// TODO Auto-generated method stub
+		s_logger.debug("NetworkElement applyNetworkACLs");
+		return false;
+	}
+
+	@Override
+	public boolean applyACLItemsToPrivateGw(PrivateGateway privateGateway,
+			List<? extends NetworkACLItem> rules)
+			throws ResourceUnavailableException {
+		// TODO Auto-generated method stub
+		s_logger.debug("NetworkElement applyACLItemsToPrivateGw");
+		return false;
+	}
+	
+    @Override
+    public IpDeployer getIpDeployer(Network network) {
+        return this;
+    }
+
+    @Override
+    public boolean applyIps(Network network,
+            List<? extends PublicIpAddress> ipAddress, Set<Service> services)
+                    throws ResourceUnavailableException {
+
+        for (PublicIpAddress ip: ipAddress) {
+            if (ip.isSourceNat()) {
+                continue;
+            }
+            if (isFloatingIpCreate(ip)) {
+                if (_manager.createFloatingIp(ip)) {
+                    s_logger.debug("Successfully created floating ip: " + ip.getAddress().addr());
+                }
+            } else {
+                if (_manager.deleteFloatingIp(ip)) {
+                    s_logger.debug("Successfully deleted floating ip: " + ip.getAddress().addr());
+                }
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public boolean applyStaticNats(Network config,
+            List<? extends StaticNat> rules)
+                    throws ResourceUnavailableException {
+        return true;
+    }
+    
+    private boolean isFloatingIpCreate(PublicIpAddress ip) {        
+        if (ip.getState() == IpAddress.State.Allocated && ip.getAssociatedWithVmId() != null && !ip.isSourceNat()) {
+            return true;
+        }
+        return false;        
+    }
+
+    @Override
+    public boolean addDhcpEntry(Network network, NicProfile nic,
+    		VirtualMachineProfile vm,
+    		DeployDestination dest, ReservationContext context)
+    				throws ConcurrentOperationException, InsufficientCapacityException,
+    				ResourceUnavailableException {
+    	// TODO Auto-generated method stub
+    	return false;
+    }
+
+    @Override
+    public boolean configDhcpSupportForSubnet(Network network, NicProfile nic,
+    		VirtualMachineProfile vm,
+    		DeployDestination dest, ReservationContext context)
+    				throws ConcurrentOperationException, InsufficientCapacityException,
+    				ResourceUnavailableException {
+    	// TODO Auto-generated method stub
+    	return false;
+    }
+
+    @Override
+    public boolean removeDhcpSupportForSubnet(Network network)
+    		throws ResourceUnavailableException {
+    	// TODO Auto-generated method stub
+    	return false;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7099686b/plugins/network-elements/juniper-contrail/src/net/juniper/contrail/management/ContrailGuru.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/src/net/juniper/contrail/management/ContrailGuru.java b/plugins/network-elements/juniper-contrail/src/net/juniper/contrail/management/ContrailGuru.java
new file mode 100644
index 0000000..d555577
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/src/net/juniper/contrail/management/ContrailGuru.java
@@ -0,0 +1,316 @@
+package net.juniper.contrail.management;
+
+
+import java.io.IOException;
+
+import javax.inject.Inject;
+
+import net.juniper.contrail.api.types.MacAddressesType;
+import net.juniper.contrail.api.types.VirtualMachineInterface;
+import net.juniper.contrail.model.InstanceIpModel;
+import net.juniper.contrail.model.VMInterfaceModel;
+import net.juniper.contrail.model.VirtualMachineModel;
+import net.juniper.contrail.model.VirtualNetworkModel;
+
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.deploy.DeployDestination;
+import com.cloud.deploy.DeploymentPlan;
+import com.cloud.exception.ConcurrentOperationException;
+import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InsufficientVirtualNetworkCapcityException;
+import com.cloud.network.Network;
+import com.cloud.network.Network.State;
+import com.cloud.network.NetworkProfile;
+import com.cloud.network.Networks.AddressFormat;
+import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.Networks.Mode;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.guru.NetworkGuru;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.user.Account;
+import com.cloud.utils.component.AdapterBase;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.Nic.ReservationStrategy;
+import com.cloud.vm.NicProfile;
+import com.cloud.vm.ReservationContext;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachineProfile;
+import com.cloud.vm.dao.NicDao;
+import com.cloud.vm.NicVO;
+
+@Component
+public class ContrailGuru extends AdapterBase implements NetworkGuru {
+    @Inject NetworkDao _networkDao;
+    @Inject ContrailManager _manager;
+    @Inject NicDao _nicDao;
+
+    private static final Logger s_logger = Logger.getLogger(ContrailGuru.class);
+    private static final TrafficType[] _trafficTypes = {TrafficType.Guest};
+
+    private boolean canHandle(NetworkOffering offering) {
+        return (offering.getName().equals(ContrailManager.offeringName));
+    }
+
+    @Override
+    public String getName() {
+	return "ContrailGuru";
+    }
+
+    @Override
+    public Network design(NetworkOffering offering, DeploymentPlan plan,
+            Network userSpecified, Account owner) {
+        if (!canHandle(offering)) {
+            return null;
+        }
+        NetworkVO network = new NetworkVO(offering.getTrafficType(), Mode.Dhcp, BroadcastDomainType.Lswitch,
+                offering.getId(), State.Allocated, plan.getDataCenterId(), plan.getPhysicalNetworkId());
+        if (userSpecified.getCidr() != null) {
+            network.setCidr(userSpecified.getCidr());
+            network.setGateway(userSpecified.getGateway());
+        }
+        s_logger.debug("Allocated network " + userSpecified.getName() +
+                (network.getCidr() == null ? "" : " subnet: " + network.getCidr()));
+        return network;
+    }
+
+    @Override
+    public Network implement(Network network, NetworkOffering offering,
+            DeployDestination destination, ReservationContext context)
+                    throws InsufficientVirtualNetworkCapcityException {
+        s_logger.debug("Implement network: " + network.getName() + ", traffic type: " + network.getTrafficType());
+
+        VirtualNetworkModel vnModel = _manager.getDatabase().lookupVirtualNetwork(
+                network.getUuid(), _manager.getCanonicalName(network), network.getTrafficType());
+        if (vnModel == null) {
+            vnModel = new VirtualNetworkModel(network, network.getUuid(), 
+                    _manager.getCanonicalName(network), network.getTrafficType());
+            vnModel.setProperties(_manager.getModelController(), network);
+        }
+
+        try {
+            if (!vnModel.verify(_manager.getModelController())) {
+                vnModel.update(_manager.getModelController());
+            }
+        } catch (Exception ex) {
+            s_logger.warn("virtual-network update: ", ex);
+            return network;
+        }
+        _manager.getDatabase().getVirtualNetworks().add(vnModel);   
+        return network;
+    }
+
+    /**
+     * Allocate the NicProfile object.
+     * At this point the UUID of the nic is not yet known. We defer allocating the VMI and instance-ip objects
+     * until the reserve API is called because of this reason. 
+     */
+    @Override
+    public NicProfile allocate(Network network, NicProfile profile,
+            VirtualMachineProfile vm)
+                    throws InsufficientVirtualNetworkCapcityException,
+                    InsufficientAddressCapacityException, ConcurrentOperationException {
+        s_logger.debug("allocate NicProfile on " + network.getName());
+
+        if (profile != null && profile.getRequestedIpv4() != null) {
+            throw new CloudRuntimeException("Does not support custom ip allocation at this time: " + profile);
+        }
+        if (profile == null) {
+            profile = new NicProfile(ReservationStrategy.Create, null, null, null, null);
+        }
+
+        profile.setStrategy(ReservationStrategy.Start);
+        
+        return profile;
+    }
+
+    /**
+     * Allocate the ip address (and mac) for the specified VM device.
+     */
+    @Override
+    public void reserve(NicProfile nic, Network network,
+            VirtualMachineProfile vm,
+            DeployDestination dest, ReservationContext context)
+                    throws InsufficientVirtualNetworkCapcityException,
+                    InsufficientAddressCapacityException, ConcurrentOperationException {
+        s_logger.debug("reserve NicProfile on network id: " + network.getId() +
+                " " + network.getName());
+        s_logger.debug("deviceId: " + nic.getDeviceId());
+
+        NicVO nicVO = _nicDao.findById(nic.getId());
+        assert nicVO != null;
+
+        VirtualNetworkModel vnModel = _manager.getDatabase().lookupVirtualNetwork(
+                network.getUuid(), _manager.getCanonicalName(network), network.getTrafficType());
+        /* Network must have been implemented */
+        assert vnModel != null;
+        
+        VirtualMachineModel vmModel = _manager.getDatabase().lookupVirtualMachine(vm.getUuid());
+        if (vmModel == null) {
+            VMInstanceVO vmVo = (VMInstanceVO) vm.getVirtualMachine();
+            vmModel = new VirtualMachineModel(vmVo, vm.getUuid());
+            vmModel.setProperties(_manager.getModelController(), vmVo);
+        }
+
+        VMInterfaceModel vmiModel = vmModel.getVMInterface(nicVO.getUuid());
+        if (vmiModel == null) {
+            vmiModel = new VMInterfaceModel(nicVO.getUuid());
+            vmiModel.addToVirtualMachine(vmModel);
+            vmiModel.addToVirtualNetwork(vnModel);
+        }
+        try {
+            vmiModel.build(_manager.getModelController(), (VMInstanceVO) vm.getVirtualMachine(), nicVO);
+            vmiModel.setActive();
+        } catch (IOException ex) {
+            s_logger.error("virtual-machine-interface set", ex);
+            return;
+        }
+
+        InstanceIpModel ipModel = vmiModel.getInstanceIp();
+        if (ipModel == null) {
+            ipModel = new InstanceIpModel(vm.getInstanceName(), nic.getDeviceId());
+            ipModel.addToVMInterface(vmiModel);
+        } else {
+            s_logger.debug("Reuse existing instance-ip object on " + ipModel.getName());
+        }
+        if (nic.getIp4Address() != null) {
+            s_logger.debug("Nic using existing IP address " +  nic.getIp4Address());
+            ipModel.setAddress(nic.getIp4Address());
+        }
+
+        try {
+            vmModel.update(_manager.getModelController());
+        } catch (Exception ex) {
+            s_logger.warn("virtual-machine update", ex);
+            return;
+        }
+
+        _manager.getDatabase().getVirtualMachines().add(vmModel);   
+
+        VirtualMachineInterface vmi = vmiModel.getVMInterface();
+        // allocate mac address
+        if (nic.getMacAddress() == null) {
+            MacAddressesType macs = vmi.getMacAddresses();
+            if (macs == null) {
+                s_logger.debug("no mac address is allocated for Nic " + nicVO.getUuid());
+            } else {
+                s_logger.info("VMI " + _manager.getVifNameByVmUuid(vm.getUuid(), nicVO.getDeviceId()) + " got mac address: " +
+                        macs.getMacAddress().get(0));
+                nic.setMacAddress(macs.getMacAddress().get(0));
+            }
+        }
+
+        if (nic.getIp4Address() == null) {
+            s_logger.debug("Allocated IP address " + ipModel.getAddress());
+            nic.setIp4Address(ipModel.getAddress());
+            nic.setNetmask(NetUtils.cidr2Netmask(network.getCidr()));
+            nic.setGateway(network.getGateway());
+            nic.setFormat(AddressFormat.Ip4);
+        }
+    }
+
+    /**
+     * When a VM is stopped this API is called to release transient resources.
+     */
+    @Override
+    public boolean release(NicProfile nic,
+            VirtualMachineProfile vm,
+            String reservationId) {
+
+        s_logger.debug("release NicProfile " + nic.getId());
+
+        return true;
+    }
+
+    /**
+     * Release permanent resources of a Nic (VMI and addresses).
+     */
+    @Override
+    public void deallocate(Network network, NicProfile nic,
+            VirtualMachineProfile vm) {
+        s_logger.debug("deallocate NicProfile " + nic.getId() + " on " + network.getName());
+        NicVO nicVO = _nicDao.findById(nic.getId());
+        assert nicVO != null;
+
+        VirtualMachineModel vmModel = _manager.getDatabase().lookupVirtualMachine(vm.getUuid());
+        if (vmModel == null) {
+            return;
+        }
+        VMInterfaceModel vmiModel = vmModel.getVMInterface(nicVO.getUuid());
+        if (vmiModel == null) {
+            return;
+        }
+        try {
+            vmiModel.destroy(_manager.getModelController());
+        } catch (IOException ex) {
+            return;
+        }
+        vmModel.removeSuccessor(vmiModel);
+        
+        if (!vmModel.hasDescendents()) {
+            _manager.getDatabase().getVirtualMachines().remove(vmModel);
+            try {
+                vmModel.delete(_manager.getModelController());
+            } catch (IOException ex) {
+                s_logger.warn("virtual-machine delete", ex);
+                return;
+            }
+        }
+
+    }
+
+    @Override
+    public void updateNicProfile(NicProfile profile, Network network) {
+        // TODO Auto-generated method stub
+        s_logger.debug("update NicProfile " + profile.getId() + " on " + network.getName());
+    }
+
+    @Override
+    public void shutdown(NetworkProfile network, NetworkOffering offering)  {
+        s_logger.debug("NetworkGuru shutdown");
+        VirtualNetworkModel vnModel = _manager.getDatabase().lookupVirtualNetwork(network.getUuid(), 
+                _manager.getCanonicalName(network), network.getTrafficType());
+        if (vnModel == null) {
+            return;
+        }
+        try {
+            vnModel.delete(_manager.getModelController());
+        } catch (IOException e) {
+            s_logger.warn("virtual-network delete", e);
+        }
+    }
+
+    @Override
+    public boolean trash(Network network, NetworkOffering offering) {
+        // TODO Auto-generated method stub
+        s_logger.debug("NetworkGuru trash");
+        return true;
+    }
+
+    @Override
+    public void updateNetworkProfile(NetworkProfile networkProfile) {
+        // TODO Auto-generated method stub
+        s_logger.debug("NetworkGuru updateNetworkProfile");
+    }
+
+    @Override
+    public TrafficType[] getSupportedTrafficType() {
+        return _trafficTypes;
+    }
+
+    @Override
+    public boolean isMyTrafficType(TrafficType type) {
+        for (TrafficType t : _trafficTypes) {
+            if (t == type) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7099686b/plugins/network-elements/juniper-contrail/src/net/juniper/contrail/management/ContrailManager.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/src/net/juniper/contrail/management/ContrailManager.java b/plugins/network-elements/juniper-contrail/src/net/juniper/contrail/management/ContrailManager.java
new file mode 100644
index 0000000..c517660
--- /dev/null
+++ b/plugins/network-elements/juniper-contrail/src/net/juniper/contrail/management/ContrailManager.java
@@ -0,0 +1,74 @@
+package net.juniper.contrail.management;
+
+import java.util.List;
+import java.io.IOException;
+
+import net.juniper.contrail.api.ApiConnector;
+import net.juniper.contrail.api.types.FloatingIp;
+import net.juniper.contrail.api.types.VirtualNetwork;
+import net.juniper.contrail.model.ModelController;
+import net.juniper.contrail.model.VirtualNetworkModel;
+
+import com.cloud.network.Network;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.PublicIpAddress;
+import com.cloud.offering.NetworkOffering;
+import com.cloud.network.dao.IPAddressVO;
+import com.cloud.network.dao.PhysicalNetworkVO;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.domain.DomainVO;
+import com.cloud.projects.ProjectVO;
+
+public interface ContrailManager {
+    public static final String offeringName = "Juniper Contrail offering";
+    public static final String offeringDisplayText = "Juniper Contrail network offering";
+    public static final int DB_SYNC_INTERVAL_DEFAULT = 600000;
+    public static final String VNC_ROOT_DOMAIN = "default-domain";
+    public static final String VNC_DEFAULT_PROJECT = "default-project";
+    public static final String managementNetworkName = "ip-fabric";
+
+    public NetworkOffering getOffering();
+    public void syncNetworkDB(short syncMode) throws IOException;
+
+    public boolean isManagedPhysicalNetwork(Network network);
+
+    /**
+     * Lookup the virtual network that implements the CloudStack network object.
+     * @param net_id internal identifier of the NetworkVO object.
+     * @return the uuid of the virtual network that corresponds to the
+     * specified CloudStack network.
+     */
+    public String findVirtualNetworkId(Network net) throws IOException;
+    public void findInfrastructureNetworks(PhysicalNetworkVO phys, List<NetworkVO> dbList);
+    public String getPhysicalNetworkName(PhysicalNetworkVO phys_net);
+    public String getCanonicalName(Network net);
+    public String getDomainCanonicalName(DomainVO domain);
+    public String getProjectCanonicalName(ProjectVO project);
+    public String getFQN(Network net);
+    public String getDomainName(long domainId);
+    public String getProjectName(long accountId);
+    public String getDefaultPublicNetworkFQN();
+    public String getProjectId(long domainId, long accountId) throws IOException;
+    public net.juniper.contrail.api.types.Project getVncProject(long domainId, long accountId) throws IOException;
+    public boolean isSystemRootDomain(net.juniper.contrail.api.types.Domain vnc);
+    public boolean isSystemRootDomain(DomainVO domain);
+    public boolean isSystemDefaultProject(net.juniper.contrail.api.types.Project project);
+    public boolean isSystemDefaultProject(ProjectVO project);
+    public boolean isSystemDefaultNetwork(VirtualNetwork vnet);
+    public boolean isSystemDefaultNetwork(NetworkVO dbNet);
+    public String getVifNameByVmName(String vm_name, Integer device_id);
+    public String getVifNameByVmUuid(String vm_uuid, Integer device_id);
+    
+    public ApiConnector getApiConnector();
+    public ModelDatabase getDatabase();
+    public ModelController getModelController(); 
+    public List<NetworkVO> findJuniperManagedNetworks(List<TrafficType> types);
+    public List<IPAddressVO> findJuniperManagedPublicIps();
+    public VirtualNetwork findDefaultVirtualNetwork(TrafficType trafficType)
+            throws IOException;
+    public List<FloatingIp> getFloatingIps();
+    public VirtualNetworkModel lookupPublicNetworkModel();
+    public boolean createFloatingIp(PublicIpAddress ip);
+    public boolean deleteFloatingIp(PublicIpAddress ip);
+}
+  


Mime
View raw message