You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by mu...@apache.org on 2014/03/13 14:52:52 UTC

[01/31] git commit: updated refs/heads/distributedrouter to a8d43ba

Repository: cloudstack
Updated Branches:
  refs/heads/distributedrouter 68ce921fa -> a8d43ba4b (forced update)


CLOUDSTACK-6225: Check libvirt version and volume format before
adding flag VIR_STORAGE_VOL_RESIZE_ALLOCATE to resize volume
libvirt call


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

Branch: refs/heads/distributedrouter
Commit: c874e20c24e8bcf7b606c55ef924606b857c1f6d
Parents: 991e1eb
Author: Marcus Sorensen <ma...@betterservers.com>
Authored: Tue Mar 11 11:13:12 2014 -0600
Committer: Marcus Sorensen <ma...@betterservers.com>
Committed: Tue Mar 11 11:13:12 2014 -0600

----------------------------------------------------------------------
 .../cloud/hypervisor/kvm/resource/LibvirtComputingResource.java | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c874e20c/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
index 5912dd3..f4f6c74 100755
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
@@ -1804,8 +1804,11 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
                 try {
                     Connect conn = LibvirtConnection.getConnection();
                     StorageVol v = conn.storageVolLookupByPath(path);
+                    int flags = 0;
 
-                    int flags = 1;
+                    if (conn.getLibVirVersion() > 1001000 && vol.getFormat() == PhysicalDiskFormat.RAW) {
+                        flags = 1;
+                    }
                     if (shrinkOk) {
                         flags = 4;
                     }


[18/31] git commit: updated refs/heads/distributedrouter to a8d43ba

Posted by mu...@apache.org.
CLOUDSTACK-6217:
Add APIs for ability to add new guest OS types, and their hypervisor specific mappings.
The table guest_os_hypervisor is currently maintained but not used, and the APIs reuse the same

Signed off by: Nitin Mehta <ni...@citrix.com>


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

Branch: refs/heads/distributedrouter
Commit: 3ee1fc28deafc575dedd655bc6af37c274142275
Parents: cd8af6a
Author: amogh.vasekar <am...@citrix.com>
Authored: Wed Mar 12 15:15:18 2014 -0700
Committer: Nitin Mehta <ni...@citrix.com>
Committed: Wed Mar 12 17:03:38 2014 -0700

----------------------------------------------------------------------
 api/src/com/cloud/event/EventTypes.java         |  18 ++
 api/src/com/cloud/server/ManagementService.java |  73 ++++++
 api/src/com/cloud/storage/GuestOS.java          |   6 +
 .../com/cloud/storage/GuestOSHypervisor.java    |  10 +
 .../cloudstack/api/ApiCommandJobType.java       |   6 +-
 .../org/apache/cloudstack/api/ApiConstants.java |   2 +
 .../cloudstack/api/ResponseGenerator.java       |   4 +
 .../api/command/admin/guest/AddGuestOsCmd.java  | 136 +++++++++++
 .../admin/guest/AddGuestOsMappingCmd.java       | 146 +++++++++++
 .../admin/guest/ListGuestOsMappingCmd.java      | 101 ++++++++
 .../command/admin/guest/RemoveGuestOsCmd.java   |  98 ++++++++
 .../admin/guest/RemoveGuestOsMappingCmd.java    |  98 ++++++++
 .../command/admin/guest/UpdateGuestOsCmd.java   | 104 ++++++++
 .../admin/guest/UpdateGuestOsMappingCmd.java    | 102 ++++++++
 .../api/response/GuestOsMappingResponse.java    | 102 ++++++++
 client/tomcatconf/commands.properties.in        |   9 +
 .../com/cloud/storage/GuestOSHypervisorVO.java  |  62 ++++-
 .../schema/src/com/cloud/storage/GuestOSVO.java |  25 +-
 .../cloud/storage/dao/GuestOSHypervisorDao.java |   3 +
 .../storage/dao/GuestOSHypervisorDaoImpl.java   |  27 +++
 server/src/com/cloud/api/ApiResponseHelper.java |  23 +-
 .../src/com/cloud/server/ManagementServer.java  |   3 +
 .../com/cloud/server/ManagementServerImpl.java  | 240 ++++++++++++++++++-
 setup/db/db/schema-430to440.sql                 |  10 +
 24 files changed, 1401 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ee1fc28/api/src/com/cloud/event/EventTypes.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/event/EventTypes.java b/api/src/com/cloud/event/EventTypes.java
index a5fc0f0..39ef710 100755
--- a/api/src/com/cloud/event/EventTypes.java
+++ b/api/src/com/cloud/event/EventTypes.java
@@ -50,6 +50,8 @@ import com.cloud.offering.DiskOffering;
 import com.cloud.offering.NetworkOffering;
 import com.cloud.offering.ServiceOffering;
 import com.cloud.projects.Project;
+import com.cloud.storage.GuestOS;
+import com.cloud.storage.GuestOSHypervisor;
 import com.cloud.storage.Snapshot;
 import com.cloud.storage.Volume;
 import com.cloud.template.VirtualMachineTemplate;
@@ -479,6 +481,14 @@ public class EventTypes {
     public static final String EVENT_EXTERNAL_OPENDAYLIGHT_DELETE_CONTROLLER = "PHYSICAL.ODLCONTROLLER.DELETE";
     public static final String EVENT_EXTERNAL_OPENDAYLIGHT_CONFIGURE_CONTROLLER = "PHYSICAL.ODLCONTROLLER.CONFIGURE";
 
+    //Guest OS related events
+    public static final String EVENT_GUEST_OS_ADD = "GUEST.OS.ADD";
+    public static final String EVENT_GUEST_OS_REMOVE = "GUEST.OS.REMOVE";
+    public static final String EVENT_GUEST_OS_UPDATE = "GUEST.OS.UPDATE";
+    public static final String EVENT_GUEST_OS_MAPPING_ADD = "GUEST.OS.MAPPING.ADD";
+    public static final String EVENT_GUEST_OS_MAPPING_REMOVE = "GUEST.OS.MAPPING.REMOVE";
+    public static final String EVENT_GUEST_OS_MAPPING_UPDATE = "GUEST.OS.MAPPING.UPDATE";
+
     static {
 
         // TODO: need a way to force author adding event types to declare the entity details as well, with out braking
@@ -795,6 +805,14 @@ public class EventTypes {
         entityEventDetails.put(EVENT_EXTERNAL_OPENDAYLIGHT_ADD_CONTROLLER, "OpenDaylightController");
         entityEventDetails.put(EVENT_EXTERNAL_OPENDAYLIGHT_DELETE_CONTROLLER, "OpenDaylightController");
         entityEventDetails.put(EVENT_EXTERNAL_OPENDAYLIGHT_CONFIGURE_CONTROLLER, "OpenDaylightController");
+
+        //Guest OS
+        entityEventDetails.put(EVENT_GUEST_OS_ADD, GuestOS.class.getName());
+        entityEventDetails.put(EVENT_GUEST_OS_REMOVE, GuestOS.class.getName());
+        entityEventDetails.put(EVENT_GUEST_OS_UPDATE, GuestOS.class.getName());
+        entityEventDetails.put(EVENT_GUEST_OS_MAPPING_ADD, GuestOSHypervisor.class.getName());
+        entityEventDetails.put(EVENT_GUEST_OS_MAPPING_REMOVE, GuestOSHypervisor.class.getName());
+        entityEventDetails.put(EVENT_GUEST_OS_MAPPING_UPDATE, GuestOSHypervisor.class.getName());
     }
 
     public static String getEntityForEvent(String eventName) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ee1fc28/api/src/com/cloud/server/ManagementService.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/server/ManagementService.java b/api/src/com/cloud/server/ManagementService.java
index 5fcf0b5..abe6e2c 100755
--- a/api/src/com/cloud/server/ManagementService.java
+++ b/api/src/com/cloud/server/ManagementService.java
@@ -23,6 +23,13 @@ import java.util.Map;
 import org.apache.cloudstack.api.command.admin.cluster.ListClustersCmd;
 import org.apache.cloudstack.api.command.admin.config.ListCfgsByCmd;
 import org.apache.cloudstack.api.command.admin.domain.UpdateDomainCmd;
+import org.apache.cloudstack.api.command.admin.guest.AddGuestOsCmd;
+import org.apache.cloudstack.api.command.admin.guest.AddGuestOsMappingCmd;
+import org.apache.cloudstack.api.command.admin.guest.ListGuestOsMappingCmd;
+import org.apache.cloudstack.api.command.admin.guest.RemoveGuestOsCmd;
+import org.apache.cloudstack.api.command.admin.guest.RemoveGuestOsMappingCmd;
+import org.apache.cloudstack.api.command.admin.guest.UpdateGuestOsCmd;
+import org.apache.cloudstack.api.command.admin.guest.UpdateGuestOsMappingCmd;
 import org.apache.cloudstack.api.command.admin.host.ListHostsCmd;
 import org.apache.cloudstack.api.command.admin.host.UpdateHostPasswordCmd;
 import org.apache.cloudstack.api.command.admin.pod.ListPodsByCmd;
@@ -67,6 +74,7 @@ import com.cloud.hypervisor.HypervisorCapabilities;
 import com.cloud.network.IpAddress;
 import com.cloud.org.Cluster;
 import com.cloud.storage.GuestOS;
+import com.cloud.storage.GuestOSHypervisor;
 import com.cloud.storage.GuestOsCategory;
 import com.cloud.storage.StoragePool;
 import com.cloud.user.SSHKeyPair;
@@ -146,6 +154,69 @@ public interface ManagementService {
      */
     Pair<List<? extends GuestOsCategory>, Integer> listGuestOSCategoriesByCriteria(ListGuestOsCategoriesCmd cmd);
 
+    /**
+     * Obtains a list of all guest OS mappings
+     *
+     * @return list of GuestOSHypervisor
+     */
+    Pair<List<? extends GuestOSHypervisor>, Integer> listGuestOSMappingByCriteria(ListGuestOsMappingCmd cmd);
+
+    /**
+     * Adds a new guest OS mapping
+     *
+     * @return A VO containing the new mapping, with its hypervisor, hypervisor type, guest OS name, and the name of guest OS specific to hypervisor
+     */
+    GuestOSHypervisor addGuestOsMapping(AddGuestOsMappingCmd addGuestOsMappingCmd);
+
+    /**
+     * Find newly added guest OS mapping by ID
+     *
+     * @return A VO containing the guest OS mapping specified by ID, with its hypervisor, hypervisor type, guest OS name, and the name of guest OS specific to hypervisor
+     */
+    GuestOSHypervisor getAddedGuestOsMapping(Long guestOsHypervisorId);
+
+    /**
+     * Adds a new guest OS
+     *
+     * @return A VO containing the new guest OS, with its category ID, name and display name
+     */
+    GuestOS addGuestOs(AddGuestOsCmd addGuestOsCmd);
+
+    /**
+     * Find newly added guest OS by ID
+     *
+     * @return A VO containing the guest OS specified by ID, with its category ID, name and display name
+     */
+    GuestOS getAddedGuestOs(Long guestOsId);
+
+    /**
+     * Updates an existing guest OS
+     *
+     * @return A VO containing the updated display name
+     */
+    GuestOS updateGuestOs(UpdateGuestOsCmd updateGuestOsCmd);
+
+    /**
+     * Updates an existing guest OS mapping
+     *
+     * @return A VO containing the updated OS name for hypervisor
+     */
+    GuestOSHypervisor updateGuestOsMapping(UpdateGuestOsMappingCmd updateGuestOsMappingCmd);
+
+    /**
+     * Removes an existing guest OS
+     *
+     * @return True is successfully marked for delete, false otherwise
+     */
+    boolean removeGuestOs(RemoveGuestOsCmd removeGuestOsCmd);
+
+    /**
+     * Removes an existing guest OS mapping
+     *
+     * @return True is successfully marked for delete, false otherwise
+     */
+    boolean removeGuestOsMapping(RemoveGuestOsMappingCmd removeGuestOsMappingCmd);
+
     VirtualMachine stopSystemVM(StopSystemVmCmd cmd) throws ResourceUnavailableException, ConcurrentOperationException;
 
     VirtualMachine startSystemVM(long vmId);
@@ -361,4 +432,6 @@ public interface ManagementService {
         ConcurrentOperationException;
 
     void cleanupVMReservations();
+
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ee1fc28/api/src/com/cloud/storage/GuestOS.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/storage/GuestOS.java b/api/src/com/cloud/storage/GuestOS.java
index 437cd37..767a60e 100644
--- a/api/src/com/cloud/storage/GuestOS.java
+++ b/api/src/com/cloud/storage/GuestOS.java
@@ -16,6 +16,8 @@
 // under the License.
 package com.cloud.storage;
 
+import java.util.Date;
+
 import org.apache.cloudstack.api.Identity;
 import org.apache.cloudstack.api.InternalIdentity;
 
@@ -26,4 +28,8 @@ public interface GuestOS extends InternalIdentity, Identity {
     String getDisplayName();
 
     long getCategoryId();
+
+    Date getCreated();
+
+    Date getRemoved();
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ee1fc28/api/src/com/cloud/storage/GuestOSHypervisor.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/storage/GuestOSHypervisor.java b/api/src/com/cloud/storage/GuestOSHypervisor.java
index f022722..1cfc3a1 100644
--- a/api/src/com/cloud/storage/GuestOSHypervisor.java
+++ b/api/src/com/cloud/storage/GuestOSHypervisor.java
@@ -16,6 +16,8 @@
 // under the License.
 package com.cloud.storage;
 
+import java.util.Date;
+
 import org.apache.cloudstack.api.InternalIdentity;
 
 public interface GuestOSHypervisor extends InternalIdentity {
@@ -25,4 +27,12 @@ public interface GuestOSHypervisor extends InternalIdentity {
     String getGuestOsName();
 
     long getGuestOsId();
+
+    String getHypervisorVersion();
+
+    String getUuid();
+
+    Date getRemoved();
+
+    Date getCreated();
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ee1fc28/api/src/org/apache/cloudstack/api/ApiCommandJobType.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/ApiCommandJobType.java b/api/src/org/apache/cloudstack/api/ApiCommandJobType.java
index f27f001..227fb30 100644
--- a/api/src/org/apache/cloudstack/api/ApiCommandJobType.java
+++ b/api/src/org/apache/cloudstack/api/ApiCommandJobType.java
@@ -51,5 +51,7 @@ public enum ApiCommandJobType {
     InternalLbVm,
     DedicatedGuestVlanRange,
     IAMPolicy,
-    IAMGroup
-}
\ No newline at end of file
+    IAMGroup,
+    GuestOs,
+    GuestOsMapping
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ee1fc28/api/src/org/apache/cloudstack/api/ApiConstants.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java
index 0a3fafd..089affb 100755
--- a/api/src/org/apache/cloudstack/api/ApiConstants.java
+++ b/api/src/org/apache/cloudstack/api/ApiConstants.java
@@ -171,6 +171,8 @@ public class ApiConstants {
     public static final String OP = "op";
     public static final String OS_CATEGORY_ID = "oscategoryid";
     public static final String OS_TYPE_ID = "ostypeid";
+    public static final String OS_DISPLAY_NAME = "osdisplayname";
+    public static final String OS_NAME_FOR_HYPERVISOR = "osnameforhypervisor";
     public static final String PARAMS = "params";
     public static final String PARENT_DOMAIN_ID = "parentdomainid";
     public static final String PASSWORD = "password";

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ee1fc28/api/src/org/apache/cloudstack/api/ResponseGenerator.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/ResponseGenerator.java b/api/src/org/apache/cloudstack/api/ResponseGenerator.java
index 1cb5388..b846d3f 100644
--- a/api/src/org/apache/cloudstack/api/ResponseGenerator.java
+++ b/api/src/org/apache/cloudstack/api/ResponseGenerator.java
@@ -47,6 +47,7 @@ import org.apache.cloudstack.api.response.FirewallResponse;
 import org.apache.cloudstack.api.response.FirewallRuleResponse;
 import org.apache.cloudstack.api.response.GlobalLoadBalancerResponse;
 import org.apache.cloudstack.api.response.GuestOSResponse;
+import org.apache.cloudstack.api.response.GuestOsMappingResponse;
 import org.apache.cloudstack.api.response.GuestVlanRangeResponse;
 import org.apache.cloudstack.api.response.HostForMigrationResponse;
 import org.apache.cloudstack.api.response.HostResponse;
@@ -175,6 +176,7 @@ import com.cloud.projects.ProjectInvitation;
 import com.cloud.region.ha.GlobalLoadBalancerRule;
 import com.cloud.server.ResourceTag;
 import com.cloud.storage.GuestOS;
+import com.cloud.storage.GuestOSHypervisor;
 import com.cloud.storage.ImageStore;
 import com.cloud.storage.Snapshot;
 import com.cloud.storage.StoragePool;
@@ -424,6 +426,8 @@ public interface ResponseGenerator {
 
     GuestOSResponse createGuestOSResponse(GuestOS os);
 
+    GuestOsMappingResponse createGuestOSMappingResponse(GuestOSHypervisor osHypervisor);
+
     SnapshotScheduleResponse createSnapshotScheduleResponse(SnapshotSchedule sched);
 
     UsageRecordResponse createUsageResponse(Usage usageRecord);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ee1fc28/api/src/org/apache/cloudstack/api/command/admin/guest/AddGuestOsCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/admin/guest/AddGuestOsCmd.java b/api/src/org/apache/cloudstack/api/command/admin/guest/AddGuestOsCmd.java
new file mode 100644
index 0000000..3ba9669
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/command/admin/guest/AddGuestOsCmd.java
@@ -0,0 +1,136 @@
+// 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.apache.cloudstack.api.command.admin.guest;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+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.GuestOSCategoryResponse;
+import org.apache.cloudstack.api.response.GuestOSResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.storage.GuestOS;
+import com.cloud.user.Account;
+
+@APICommand(name = "addGuestOs", description = "Add a new guest OS type", responseObject = GuestOSResponse.class,
+        since = "4.4.0", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class AddGuestOsCmd extends BaseAsyncCreateCmd {
+    public static final Logger s_logger = Logger.getLogger(AddGuestOsCmd.class.getName());
+
+    private static final String s_name = "addguestosresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.OS_CATEGORY_ID, type = CommandType.UUID, entityType = GuestOSCategoryResponse.class, required = true, description = "ID of Guest OS category")
+    private Long osCategoryId;
+
+    @Parameter(name = ApiConstants.OS_DISPLAY_NAME, type = CommandType.STRING, required = true, description = "Unique display name for Guest OS")
+    private String osDisplayName;
+
+    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = false, description = "Optional name for Guest OS")
+    private String osName;
+
+
+/////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getOsCategoryId() {
+        return osCategoryId;
+    }
+
+    public String getOsDisplayName() {
+        return osDisplayName;
+    }
+
+    public String getOsName() {
+        return osName;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        return Account.ACCOUNT_ID_SYSTEM;
+    }
+
+    @Override
+    public void create() {
+        GuestOS guestOs = _mgr.addGuestOs(this);
+        if (guestOs != null) {
+            setEntityId(guestOs.getId());
+            setEntityUuid(guestOs.getUuid());
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add new guest OS type entity");
+        }
+    }
+
+    @Override
+    public void execute() {
+        CallContext.current().setEventDetails("Guest OS Id: " + getEntityId());
+        GuestOS guestOs = _mgr.getAddedGuestOs(getEntityId());
+        if (guestOs != null) {
+            GuestOSResponse response = _responseGenerator.createGuestOSResponse(guestOs);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add new guest OS type");
+        }
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_GUEST_OS_ADD;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "adding a new guest OS type Id: " + getEntityId();
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.GuestOs;
+    }
+
+    @Override
+    public String getCreateEventType() {
+        return EventTypes.EVENT_GUEST_OS_ADD;
+    }
+
+    @Override
+    public String getCreateEventDescription() {
+        return "adding new guest OS type";
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ee1fc28/api/src/org/apache/cloudstack/api/command/admin/guest/AddGuestOsMappingCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/admin/guest/AddGuestOsMappingCmd.java b/api/src/org/apache/cloudstack/api/command/admin/guest/AddGuestOsMappingCmd.java
new file mode 100644
index 0000000..8af50a1
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/command/admin/guest/AddGuestOsMappingCmd.java
@@ -0,0 +1,146 @@
+// 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.apache.cloudstack.api.command.admin.guest;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+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.GuestOSResponse;
+import org.apache.cloudstack.api.response.GuestOsMappingResponse;
+
+import com.cloud.event.EventTypes;
+import com.cloud.storage.GuestOSHypervisor;
+import com.cloud.user.Account;
+
+@APICommand(name = "addGuestOsMapping", description = "Adds a guest OS name to hypervisor OS name mapping", responseObject = GuestOsMappingResponse.class,
+        since = "4.4.0", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class AddGuestOsMappingCmd extends BaseAsyncCreateCmd {
+    public static final Logger s_logger = Logger.getLogger(AddGuestOsMappingCmd.class.getName());
+
+    private static final String s_name = "addguestosmappingresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.OS_TYPE_ID, type = CommandType.UUID, required = false, entityType = GuestOSResponse.class, description = "UUID of Guest OS type. Either the UUID or Display Name must be passed")
+    private Long osTypeId;
+
+    @Parameter(name = ApiConstants.OS_DISPLAY_NAME, type = CommandType.STRING, required = false, description = "Display Name of Guest OS standard type. Either Display Name or UUID must be passed")
+    private String osStdName;
+
+    @Parameter(name = ApiConstants.HYPERVISOR, type = CommandType.STRING, required = true, description = "Hypervisor type. One of : XenServer, KVM, VMWare")
+    private String hypervisor;
+
+    @Parameter(name = ApiConstants.HYPERVISOR_VERSION, type = CommandType.STRING, required = true, description = "Hypervisor version to create the mapping for. Use 'default' for default versions")
+    private String hypervisorVersion;
+
+    @Parameter(name = ApiConstants.OS_NAME_FOR_HYPERVISOR, type = CommandType.STRING, required = true, description = "OS name specific to the hypervisor")
+    private String osNameForHypervisor;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getOsTypeId() {
+        return osTypeId;
+    }
+
+    public String getOsStdName() {
+        return osStdName;
+    }
+
+    public String getHypervisor() {
+        return hypervisor;
+    }
+
+    public String getHypervisorVersion() {
+        return hypervisorVersion;
+    }
+
+    public String getOsNameForHypervisor() {
+        return osNameForHypervisor;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        return Account.ACCOUNT_ID_SYSTEM;
+    }
+
+    @Override
+    public void create() {
+        GuestOSHypervisor guestOsMapping = _mgr.addGuestOsMapping(this);
+        if (guestOsMapping != null) {
+            setEntityId(guestOsMapping.getId());
+            setEntityUuid(guestOsMapping.getUuid());
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add guest OS mapping entity");
+        }
+    }
+
+    @Override
+    public void execute() {
+        GuestOSHypervisor guestOsMapping = _mgr.getAddedGuestOsMapping(getEntityId());
+        if (guestOsMapping != null) {
+            GuestOsMappingResponse response = _responseGenerator.createGuestOSMappingResponse(guestOsMapping);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add guest OS mapping");
+        }
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_GUEST_OS_MAPPING_ADD;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "adding a new guest OS mapping Id: " + getEntityId();
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.GuestOsMapping;
+    }
+
+    @Override
+    public String getCreateEventType() {
+        return EventTypes.EVENT_GUEST_OS_MAPPING_ADD;
+    }
+
+    @Override
+    public String getCreateEventDescription() {
+        return "adding new guest OS mapping";
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ee1fc28/api/src/org/apache/cloudstack/api/command/admin/guest/ListGuestOsMappingCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/admin/guest/ListGuestOsMappingCmd.java b/api/src/org/apache/cloudstack/api/command/admin/guest/ListGuestOsMappingCmd.java
new file mode 100644
index 0000000..a7fc9e0
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/command/admin/guest/ListGuestOsMappingCmd.java
@@ -0,0 +1,101 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.admin.guest;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseListCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.response.GuestOSResponse;
+import org.apache.cloudstack.api.response.GuestOsMappingResponse;
+import org.apache.cloudstack.api.response.ListResponse;
+
+import com.cloud.storage.GuestOSHypervisor;
+import com.cloud.utils.Pair;
+
+@APICommand(name = "listGuestOsMapping", description = "Lists all available OS mappings for given hypervisor", responseObject = GuestOsMappingResponse.class,
+        since = "4.4.0", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class ListGuestOsMappingCmd extends BaseListCmd {
+    public static final Logger s_logger = Logger.getLogger(ListGuestOsMappingCmd.class.getName());
+
+    private static final String s_name = "listguestosmappingresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = GuestOsMappingResponse.class, required = false, description = "list mapping by its UUID")
+    private Long id;
+
+    @Parameter(name = ApiConstants.OS_TYPE_ID, type = CommandType.UUID, entityType = GuestOSResponse.class, required = false, description = "list mapping by Guest OS Type UUID")
+    private Long osTypeId;
+
+    @Parameter(name = ApiConstants.HYPERVISOR, type = CommandType.STRING, required = false, description = "list Guest OS mapping by hypervisor")
+    private String hypervisor;
+
+    @Parameter(name = ApiConstants.HYPERVISOR_VERSION, type = CommandType.STRING, required = false, description = "list Guest OS mapping by hypervisor version. Must be used with hypervisor parameter")
+    private String hypervisorVersion;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    public Long getOsTypeId() {
+        return osTypeId;
+    }
+
+    public String getHypervisor() {
+        return hypervisor;
+    }
+
+    public String getHypervisorVersion() {
+        return hypervisorVersion;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public void execute() {
+        Pair<List<? extends GuestOSHypervisor>, Integer> result = _mgr.listGuestOSMappingByCriteria(this);
+        ListResponse<GuestOsMappingResponse> response = new ListResponse<GuestOsMappingResponse>();
+        List<GuestOsMappingResponse> osMappingResponses = new ArrayList<GuestOsMappingResponse>();
+        for (GuestOSHypervisor guestOSHypervisor : result.first()) {
+            GuestOsMappingResponse guestOsMappingResponse = _responseGenerator.createGuestOSMappingResponse(guestOSHypervisor);
+            osMappingResponses.add(guestOsMappingResponse);
+        }
+
+        response.setResponses(osMappingResponses, result.second());
+        response.setResponseName(getCommandName());
+        setResponseObject(response);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ee1fc28/api/src/org/apache/cloudstack/api/command/admin/guest/RemoveGuestOsCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/admin/guest/RemoveGuestOsCmd.java b/api/src/org/apache/cloudstack/api/command/admin/guest/RemoveGuestOsCmd.java
new file mode 100644
index 0000000..3de7f7a
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/command/admin/guest/RemoveGuestOsCmd.java
@@ -0,0 +1,98 @@
+// 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.apache.cloudstack.api.command.admin.guest;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.GuestOSResponse;
+import org.apache.cloudstack.api.response.SuccessResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.user.Account;
+
+@APICommand(name = "removeGuestOs", description = "Removes a Guest OS from listing.", responseObject = SuccessResponse.class, since = "4.4.0",
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class RemoveGuestOsCmd extends BaseAsyncCmd {
+
+    public static final Logger s_logger = Logger.getLogger(RemoveGuestOsCmd.class.getName());
+    private static final String s_name = "removeguestosresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = GuestOSResponse.class, required = true, description = "ID of the guest OS")
+    private Long id;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        return Account.ACCOUNT_ID_SYSTEM;
+    }
+
+    @Override
+    public void execute() {
+        CallContext.current().setEventDetails("Guest OS Id: " + id);
+        boolean result = _mgr.removeGuestOs(this);
+        if (result) {
+            SuccessResponse response = new SuccessResponse(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to remove guest OS");
+        }
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "Removing Guest OS: " + getId();
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_GUEST_OS_REMOVE;
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.GuestOs;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ee1fc28/api/src/org/apache/cloudstack/api/command/admin/guest/RemoveGuestOsMappingCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/admin/guest/RemoveGuestOsMappingCmd.java b/api/src/org/apache/cloudstack/api/command/admin/guest/RemoveGuestOsMappingCmd.java
new file mode 100644
index 0000000..ddd4539
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/command/admin/guest/RemoveGuestOsMappingCmd.java
@@ -0,0 +1,98 @@
+// 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.apache.cloudstack.api.command.admin.guest;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.GuestOsMappingResponse;
+import org.apache.cloudstack.api.response.SuccessResponse;
+import org.apache.cloudstack.context.CallContext;
+
+import com.cloud.event.EventTypes;
+import com.cloud.user.Account;
+
+@APICommand(name = "removeGuestOsMapping", description = "Removes a Guest OS Mapping.", responseObject = SuccessResponse.class, since = "4.4.0",
+        requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class RemoveGuestOsMappingCmd extends BaseAsyncCmd {
+
+    public static final Logger s_logger = Logger.getLogger(RemoveGuestOsMappingCmd.class.getName());
+    private static final String s_name = "removeguestosmappingresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = GuestOsMappingResponse.class, required = true, description = "ID of the guest OS mapping")
+    private Long id;
+
+    /////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        return Account.ACCOUNT_ID_SYSTEM;
+    }
+
+    @Override
+    public void execute() {
+        CallContext.current().setEventDetails("Guest OS Mapping Id: " + id);
+        boolean result = _mgr.removeGuestOsMapping(this);
+        if (result) {
+            SuccessResponse response = new SuccessResponse(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to remove guest OS mapping");
+        }
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "Removing Guest OS Mapping: " + getId();
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_GUEST_OS_MAPPING_REMOVE;
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.GuestOsMapping;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ee1fc28/api/src/org/apache/cloudstack/api/command/admin/guest/UpdateGuestOsCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/admin/guest/UpdateGuestOsCmd.java b/api/src/org/apache/cloudstack/api/command/admin/guest/UpdateGuestOsCmd.java
new file mode 100644
index 0000000..e4b1ecd
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/command/admin/guest/UpdateGuestOsCmd.java
@@ -0,0 +1,104 @@
+// 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.apache.cloudstack.api.command.admin.guest;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.GuestOSResponse;
+
+import com.cloud.event.EventTypes;
+import com.cloud.storage.GuestOS;
+import com.cloud.user.Account;
+
+@APICommand(name = "updateGuestOs", description = "Updates the information about Guest OS", responseObject = GuestOSResponse.class,
+        since = "4.4.0", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class UpdateGuestOsCmd extends BaseAsyncCmd {
+
+    public static final Logger s_logger = Logger.getLogger(UpdateGuestOsCmd.class.getName());
+
+    private static final String s_name = "updateguestosresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = GuestOSResponse.class, required = true, description = "UUID of the Guest OS")
+    private Long id;
+
+    @Parameter(name = ApiConstants.OS_DISPLAY_NAME, type = CommandType.STRING, required = true, description = "Unique display name for Guest OS")
+    private String osDisplayName;
+
+/////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    public String getOsDisplayName() {
+        return osDisplayName;
+    }
+
+    /////////////////////////////////////////////////////
+    /////////////// API Implementation///////////////////
+    /////////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        return Account.ACCOUNT_ID_SYSTEM;
+    }
+
+    @Override
+    public void execute() {
+        GuestOS guestOs = _mgr.updateGuestOs(this);
+        if (guestOs != null) {
+            GuestOSResponse response = _responseGenerator.createGuestOSResponse(guestOs);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        } else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update guest OS type");
+        }
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "Updating guest OS: " + getId();
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_GUEST_OS_UPDATE;
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.GuestOs;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ee1fc28/api/src/org/apache/cloudstack/api/command/admin/guest/UpdateGuestOsMappingCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/admin/guest/UpdateGuestOsMappingCmd.java b/api/src/org/apache/cloudstack/api/command/admin/guest/UpdateGuestOsMappingCmd.java
new file mode 100644
index 0000000..d760d53
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/command/admin/guest/UpdateGuestOsMappingCmd.java
@@ -0,0 +1,102 @@
+// 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.apache.cloudstack.api.command.admin.guest;
+
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiCommandJobType;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseAsyncCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.GuestOsMappingResponse;
+
+import com.cloud.event.EventTypes;
+import com.cloud.storage.GuestOSHypervisor;
+import com.cloud.user.Account;
+
+@APICommand(name = "updateGuestOsMapping", description = "Updates the information about Guest OS to Hypervisor specific name mapping", responseObject = GuestOsMappingResponse.class,
+        since = "4.4.0", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
+public class UpdateGuestOsMappingCmd extends BaseAsyncCmd {
+    public static final Logger s_logger = Logger.getLogger(UpdateGuestOsMappingCmd.class.getName());
+
+    private static final String s_name = "updateguestosmappingresponse";
+
+    /////////////////////////////////////////////////////
+    //////////////// API parameters /////////////////////
+    /////////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = GuestOsMappingResponse.class, required = true, description = "UUID of the Guest OS to hypervisor name Mapping")
+    private Long id;
+
+    @Parameter(name = ApiConstants.OS_NAME_FOR_HYPERVISOR, type = CommandType.STRING, required = true, description = "Hypervisor specific name for this Guest OS")
+    private String osNameForHypervisor;
+
+/////////////////////////////////////////////////////
+    /////////////////// Accessors ///////////////////////
+    /////////////////////////////////////////////////////
+
+    public Long getId() {
+        return id;
+    }
+
+    public String getOsNameForHypervisor() {
+        return osNameForHypervisor;
+    }
+
+    @Override
+    public void execute() {
+        GuestOSHypervisor guestOsMapping = _mgr.updateGuestOsMapping(this);
+        if (guestOsMapping != null) {
+            GuestOsMappingResponse response = _responseGenerator.createGuestOSMappingResponse(guestOsMapping);
+            response.setResponseName(getCommandName());
+            setResponseObject(response);
+        }
+        else {
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update guest OS mapping");
+        }
+
+    }
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        return Account.ACCOUNT_ID_SYSTEM;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "Updating Guest OS Mapping: " + getId();
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_GUEST_OS_MAPPING_UPDATE;
+    }
+
+    @Override
+    public ApiCommandJobType getInstanceType() {
+        return ApiCommandJobType.GuestOsMapping;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ee1fc28/api/src/org/apache/cloudstack/api/response/GuestOsMappingResponse.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/response/GuestOsMappingResponse.java b/api/src/org/apache/cloudstack/api/response/GuestOsMappingResponse.java
new file mode 100644
index 0000000..a0f7d1d
--- /dev/null
+++ b/api/src/org/apache/cloudstack/api/response/GuestOsMappingResponse.java
@@ -0,0 +1,102 @@
+// 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.apache.cloudstack.api.response;
+
+import com.google.gson.annotations.SerializedName;
+
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseResponse;
+import org.apache.cloudstack.api.EntityReference;
+
+import com.cloud.serializer.Param;
+import com.cloud.storage.GuestOSHypervisor;
+
+@EntityReference(value = GuestOSHypervisor.class)
+public class GuestOsMappingResponse extends BaseResponse {
+    @SerializedName(ApiConstants.ID)
+    @Param(description = "the ID of the Guest OS mapping")
+    private String id;
+
+    @SerializedName(ApiConstants.HYPERVISOR)
+    @Param(description = "the hypervisor")
+    private String hypervisor;
+
+    @SerializedName(ApiConstants.HYPERVISOR_VERSION)
+    @Param(description = "version of the hypervisor for mapping")
+    private String hypervisorVersion;
+
+    @SerializedName(ApiConstants.OS_TYPE_ID)
+    @Param(description = "the ID of the Guest OS type")
+    private String osTypeId;
+
+    @SerializedName(ApiConstants.OS_DISPLAY_NAME)
+    @Param(description = "standard display name for the Guest OS")
+    private String osStdName;
+
+    @SerializedName(ApiConstants.OS_NAME_FOR_HYPERVISOR)
+    @Param(description = "hypervisor specific name for the Guest OS")
+    private String osNameForHypervisor;
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getHypervisor() {
+        return hypervisor;
+    }
+
+    public void setHypervisor(String hypervisor) {
+        this.hypervisor = hypervisor;
+    }
+
+    public String getHypervisorVersion() {
+        return hypervisorVersion;
+    }
+
+    public void setHypervisorVersion(String hypervisorVersion) {
+        this.hypervisorVersion = hypervisorVersion;
+    }
+
+    public String getOsTypeId() {
+        return osTypeId;
+    }
+
+    public void setOsTypeId(String osTypeId) {
+        this.osTypeId = osTypeId;
+    }
+
+    public String getOsStdName() {
+        return osStdName;
+    }
+
+    public void setOsStdName(String osStdName) {
+        this.osStdName = osStdName;
+    }
+
+    public String getOsNameForHypervisor() {
+        return osNameForHypervisor;
+    }
+
+    public void setOsNameForHypervisor(String osNameForHypervisor) {
+        this.osNameForHypervisor = osNameForHypervisor;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ee1fc28/client/tomcatconf/commands.properties.in
----------------------------------------------------------------------
diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in
index 879c58d..0a06c4d 100644
--- a/client/tomcatconf/commands.properties.in
+++ b/client/tomcatconf/commands.properties.in
@@ -110,6 +110,15 @@ extractIso=15
 #### guest OS commands
 listOsTypes=15
 listOsCategories=15
+addGuestOs=1
+updateGuestOs=1
+removeGuestOs=1
+
+#### guest OS mapping commands
+listGuestOsMapping=1
+addGuestOsMapping=1
+updateGuestOsMapping=1
+removeGuestOsMapping=1
 
 #### service offering commands
 createServiceOffering=1

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ee1fc28/engine/schema/src/com/cloud/storage/GuestOSHypervisorVO.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/storage/GuestOSHypervisorVO.java b/engine/schema/src/com/cloud/storage/GuestOSHypervisorVO.java
index 8210abf..1fbc9d7 100644
--- a/engine/schema/src/com/cloud/storage/GuestOSHypervisorVO.java
+++ b/engine/schema/src/com/cloud/storage/GuestOSHypervisorVO.java
@@ -16,6 +16,9 @@
 // under the License.
 package com.cloud.storage;
 
+import java.util.Date;
+import java.util.UUID;
+
 import javax.persistence.Column;
 import javax.persistence.Entity;
 import javax.persistence.GeneratedValue;
@@ -23,6 +26,8 @@ import javax.persistence.GenerationType;
 import javax.persistence.Id;
 import javax.persistence.Table;
 
+import com.cloud.utils.db.GenericDao;
+
 @Entity
 @Table(name = "guest_os_hypervisor")
 public class GuestOSHypervisorVO implements GuestOSHypervisor {
@@ -32,7 +37,7 @@ public class GuestOSHypervisorVO implements GuestOSHypervisor {
     long id;
 
     @Column(name = "guest_os_id")
-    private long guestOsId;
+    long guestOsId;
 
     @Column(name = "guest_os_name")
     String guestOsName;
@@ -40,12 +45,29 @@ public class GuestOSHypervisorVO implements GuestOSHypervisor {
     @Column(name = "hypervisor_type")
     String hypervisorType;
 
+    @Column(name = "hypervisor_version")
+    String hypervisorVersion;
+
+    @Column(name = "uuid")
+    String uuid = UUID.randomUUID().toString();
+
+    @Column(name = GenericDao.REMOVED_COLUMN)
+    Date removed;
+
+    @Column(name = GenericDao.CREATED_COLUMN)
+    Date created;
+
     @Override
     public long getId() {
         return id;
     }
 
     @Override
+    public String getHypervisorVersion() {
+        return hypervisorVersion;
+    }
+
+    @Override
     public String getHypervisorType() {
         return hypervisorType;
     }
@@ -60,4 +82,42 @@ public class GuestOSHypervisorVO implements GuestOSHypervisor {
         return guestOsId;
     }
 
+    @Override
+    public String getUuid() {
+        return uuid;
+    }
+
+    @Override
+    public Date getRemoved() {
+        return removed;
+    }
+
+    @Override
+    public Date getCreated() {
+        return created;
+    }
+
+    public void setGuestOsId(long guestOsId) {
+        this.guestOsId = guestOsId;
+    }
+
+    public void setGuestOsName(String guestOsName) {
+        this.guestOsName = guestOsName;
+    }
+
+    public void setHypervisorType(String hypervisorType) {
+        this.hypervisorType = hypervisorType;
+    }
+
+    public void setHypervisorVersion(String hypervisorVersion) {
+        this.hypervisorVersion = hypervisorVersion;
+    }
+
+    public void setUuid(String uuid) {
+        this.uuid = uuid;
+    }
+
+    public void setRemoved(Date removed) {
+        this.removed = removed;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ee1fc28/engine/schema/src/com/cloud/storage/GuestOSVO.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/storage/GuestOSVO.java b/engine/schema/src/com/cloud/storage/GuestOSVO.java
index 57b8529..a0040be 100644
--- a/engine/schema/src/com/cloud/storage/GuestOSVO.java
+++ b/engine/schema/src/com/cloud/storage/GuestOSVO.java
@@ -16,6 +16,7 @@
 // under the License.
 package com.cloud.storage;
 
+import java.util.Date;
 import java.util.UUID;
 
 import javax.persistence.Column;
@@ -25,6 +26,8 @@ import javax.persistence.GenerationType;
 import javax.persistence.Id;
 import javax.persistence.Table;
 
+import com.cloud.utils.db.GenericDao;
+
 @Entity
 @Table(name = "guest_os")
 public class GuestOSVO implements GuestOS {
@@ -45,6 +48,12 @@ public class GuestOSVO implements GuestOS {
     @Column(name = "uuid")
     String uuid = UUID.randomUUID().toString();
 
+    @Column(name = GenericDao.REMOVED_COLUMN)
+    private Date removed;
+
+    @Column(name = GenericDao.CREATED_COLUMN)
+    private Date created;
+
     @Override
     public long getId() {
         return id;
@@ -79,10 +88,24 @@ public class GuestOSVO implements GuestOS {
 
     @Override
     public String getUuid() {
-        return this.uuid;
+        return uuid;
     }
 
     public void setUuid(String uuid) {
         this.uuid = uuid;
     }
+
+    @Override
+    public Date getCreated() {
+        return created;
+    }
+
+    public void setRemoved(Date removed) {
+        this.removed = removed;
+    }
+
+    @Override
+    public Date getRemoved() {
+        return removed;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ee1fc28/engine/schema/src/com/cloud/storage/dao/GuestOSHypervisorDao.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/storage/dao/GuestOSHypervisorDao.java b/engine/schema/src/com/cloud/storage/dao/GuestOSHypervisorDao.java
index 651cfb5..5b6e719 100644
--- a/engine/schema/src/com/cloud/storage/dao/GuestOSHypervisorDao.java
+++ b/engine/schema/src/com/cloud/storage/dao/GuestOSHypervisorDao.java
@@ -24,4 +24,7 @@ public interface GuestOSHypervisorDao extends GenericDao<GuestOSHypervisorVO, Lo
 
     HypervisorType findHypervisorTypeByGuestOsId(long guestOsId);
 
+    GuestOSHypervisorVO findByOsIdAndHypervisor(long guestOsId, String hypervisorType, String hypervisorVersion);
+
+    boolean removeGuestOsMapping(Long id);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ee1fc28/engine/schema/src/com/cloud/storage/dao/GuestOSHypervisorDaoImpl.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/storage/dao/GuestOSHypervisorDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/GuestOSHypervisorDaoImpl.java
index be680dc..3b05120 100644
--- a/engine/schema/src/com/cloud/storage/dao/GuestOSHypervisorDaoImpl.java
+++ b/engine/schema/src/com/cloud/storage/dao/GuestOSHypervisorDaoImpl.java
@@ -16,6 +16,8 @@
 // under the License.
 package com.cloud.storage.dao;
 
+import java.util.Date;
+
 import javax.ejb.Local;
 
 import org.springframework.stereotype.Component;
@@ -31,11 +33,18 @@ import com.cloud.utils.db.SearchCriteria;
 public class GuestOSHypervisorDaoImpl extends GenericDaoBase<GuestOSHypervisorVO, Long> implements GuestOSHypervisorDao {
 
     protected final SearchBuilder<GuestOSHypervisorVO> guestOsSearch;
+    protected final SearchBuilder<GuestOSHypervisorVO> mappingSearch;
 
     protected GuestOSHypervisorDaoImpl() {
         guestOsSearch = createSearchBuilder();
         guestOsSearch.and("guest_os_id", guestOsSearch.entity().getGuestOsId(), SearchCriteria.Op.EQ);
         guestOsSearch.done();
+
+        mappingSearch = createSearchBuilder();
+        mappingSearch.and("guest_os_id", mappingSearch.entity().getGuestOsId(), SearchCriteria.Op.EQ);
+        mappingSearch.and("hypervisor_type", mappingSearch.entity().getHypervisorType(), SearchCriteria.Op.EQ);
+        mappingSearch.and("hypervisor_version", mappingSearch.entity().getHypervisorVersion(), SearchCriteria.Op.EQ);
+        mappingSearch.done();
     }
 
     @Override
@@ -46,4 +55,22 @@ public class GuestOSHypervisorDaoImpl extends GenericDaoBase<GuestOSHypervisorVO
         return HypervisorType.getType(goh.getHypervisorType());
     }
 
+    @Override
+    public GuestOSHypervisorVO findByOsIdAndHypervisor(long guestOsId, String hypervisorType, String hypervisorVersion) {
+        SearchCriteria<GuestOSHypervisorVO> sc = mappingSearch.create();
+        sc.setParameters("guest_os_id", guestOsId);
+        sc.setParameters("hypervisor_type", hypervisorType);
+        sc.setParameters("hypervisor_version", hypervisorVersion);
+        return findOneBy(sc);
+    }
+
+    @Override
+    public boolean removeGuestOsMapping(Long id) {
+        GuestOSHypervisorVO guestOsHypervisor = findById(id);
+        createForUpdate(id);
+        guestOsHypervisor.setRemoved(new Date());
+        update(id, guestOsHypervisor);
+        return super.remove(id);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ee1fc28/server/src/com/cloud/api/ApiResponseHelper.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java
index 2deaa50..a2cc352 100755
--- a/server/src/com/cloud/api/ApiResponseHelper.java
+++ b/server/src/com/cloud/api/ApiResponseHelper.java
@@ -30,6 +30,8 @@ import java.util.TimeZone;
 
 import javax.inject.Inject;
 
+import org.apache.log4j.Logger;
+
 import org.apache.cloudstack.acl.ControlledEntity;
 import org.apache.cloudstack.acl.ControlledEntity.ACLType;
 import org.apache.cloudstack.affinity.AffinityGroup;
@@ -64,6 +66,7 @@ import org.apache.cloudstack.api.response.FirewallResponse;
 import org.apache.cloudstack.api.response.FirewallRuleResponse;
 import org.apache.cloudstack.api.response.GlobalLoadBalancerResponse;
 import org.apache.cloudstack.api.response.GuestOSResponse;
+import org.apache.cloudstack.api.response.GuestOsMappingResponse;
 import org.apache.cloudstack.api.response.GuestVlanRangeResponse;
 import org.apache.cloudstack.api.response.HostForMigrationResponse;
 import org.apache.cloudstack.api.response.HostResponse;
@@ -145,7 +148,6 @@ import org.apache.cloudstack.region.Region;
 import org.apache.cloudstack.usage.Usage;
 import org.apache.cloudstack.usage.UsageService;
 import org.apache.cloudstack.usage.UsageTypes;
-import org.apache.log4j.Logger;
 
 import com.cloud.api.query.ViewResponseHelper;
 import com.cloud.api.query.vo.AccountJoinVO;
@@ -263,6 +265,7 @@ import com.cloud.storage.DataStoreRole;
 import com.cloud.storage.DiskOfferingVO;
 import com.cloud.storage.GuestOS;
 import com.cloud.storage.GuestOSCategoryVO;
+import com.cloud.storage.GuestOSHypervisor;
 import com.cloud.storage.ImageStore;
 import com.cloud.storage.Snapshot;
 import com.cloud.storage.SnapshotVO;
@@ -3137,6 +3140,23 @@ public class ApiResponseHelper implements ResponseGenerator {
     }
 
     @Override
+    public GuestOsMappingResponse createGuestOSMappingResponse(GuestOSHypervisor guestOSHypervisor) {
+        GuestOsMappingResponse response = new GuestOsMappingResponse();
+        response.setId(guestOSHypervisor.getUuid());
+        response.setHypervisor(guestOSHypervisor.getHypervisorType());
+        response.setHypervisorVersion(guestOSHypervisor.getHypervisorVersion());
+        response.setOsNameForHypervisor((guestOSHypervisor.getGuestOsName()));
+        GuestOS guestOs = ApiDBUtils.findGuestOSById(guestOSHypervisor.getGuestOsId());
+        if (guestOs != null) {
+            response.setOsStdName(guestOs.getDisplayName());
+            response.setOsTypeId(guestOs.getUuid());
+        }
+
+        response.setObjectName("guestosmapping");
+        return response;
+    }
+
+    @Override
     public SnapshotScheduleResponse createSnapshotScheduleResponse(SnapshotSchedule snapshotSchedule) {
         SnapshotScheduleResponse response = new SnapshotScheduleResponse();
         response.setId(snapshotSchedule.getUuid());
@@ -3698,4 +3718,5 @@ public class ApiResponseHelper implements ResponseGenerator {
         response.setResponses(responses);
         return response;
     }
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ee1fc28/server/src/com/cloud/server/ManagementServer.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/server/ManagementServer.java b/server/src/com/cloud/server/ManagementServer.java
index 3b5f5ff..4e58a4f 100755
--- a/server/src/com/cloud/server/ManagementServer.java
+++ b/server/src/com/cloud/server/ManagementServer.java
@@ -18,6 +18,7 @@ package com.cloud.server;
 
 import com.cloud.host.DetailVO;
 import com.cloud.host.HostVO;
+import com.cloud.storage.GuestOSHypervisorVO;
 import com.cloud.storage.GuestOSVO;
 import com.cloud.utils.Pair;
 import com.cloud.utils.component.PluggableService;
@@ -54,6 +55,8 @@ public interface ManagementServer extends ManagementService, PluggableService {
 
     GuestOSVO getGuestOs(Long guestOsId);
 
+    GuestOSHypervisorVO getGuestOsHypervisor(Long guestOsHypervisorId);
+
     /**
      * Returns the vnc port of the vm.
      *

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ee1fc28/server/src/com/cloud/server/ManagementServerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java
index 663d4e5..cb73519 100755
--- a/server/src/com/cloud/server/ManagementServerImpl.java
+++ b/server/src/com/cloud/server/ManagementServerImpl.java
@@ -40,6 +40,9 @@ import javax.crypto.spec.SecretKeySpec;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
+import org.apache.commons.codec.binary.Base64;
+import org.apache.log4j.Logger;
+
 import org.apache.cloudstack.acl.ControlledEntity;
 import org.apache.cloudstack.acl.SecurityChecker.AccessType;
 import org.apache.cloudstack.affinity.AffinityGroupProcessor;
@@ -69,6 +72,13 @@ import org.apache.cloudstack.api.command.admin.domain.DeleteDomainCmd;
 import org.apache.cloudstack.api.command.admin.domain.ListDomainChildrenCmd;
 import org.apache.cloudstack.api.command.admin.domain.ListDomainsCmd;
 import org.apache.cloudstack.api.command.admin.domain.UpdateDomainCmd;
+import org.apache.cloudstack.api.command.admin.guest.AddGuestOsCmd;
+import org.apache.cloudstack.api.command.admin.guest.AddGuestOsMappingCmd;
+import org.apache.cloudstack.api.command.admin.guest.ListGuestOsMappingCmd;
+import org.apache.cloudstack.api.command.admin.guest.RemoveGuestOsCmd;
+import org.apache.cloudstack.api.command.admin.guest.RemoveGuestOsMappingCmd;
+import org.apache.cloudstack.api.command.admin.guest.UpdateGuestOsCmd;
+import org.apache.cloudstack.api.command.admin.guest.UpdateGuestOsMappingCmd;
 import org.apache.cloudstack.api.command.admin.host.AddHostCmd;
 import org.apache.cloudstack.api.command.admin.host.AddSecondaryStorageCmd;
 import org.apache.cloudstack.api.command.admin.host.CancelMaintenanceCmd;
@@ -455,8 +465,6 @@ import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
 import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
 import org.apache.cloudstack.utils.identity.ManagementServerNode;
-import org.apache.commons.codec.binary.Base64;
-import org.apache.log4j.Logger;
 
 import com.cloud.agent.AgentManager;
 import com.cloud.agent.api.GetVncPortAnswer;
@@ -544,6 +552,8 @@ import com.cloud.service.dao.ServiceOfferingDetailsDao;
 import com.cloud.storage.DiskOfferingVO;
 import com.cloud.storage.GuestOS;
 import com.cloud.storage.GuestOSCategoryVO;
+import com.cloud.storage.GuestOSHypervisor;
+import com.cloud.storage.GuestOSHypervisorVO;
 import com.cloud.storage.GuestOSVO;
 import com.cloud.storage.GuestOsCategory;
 import com.cloud.storage.Storage.ImageFormat;
@@ -556,6 +566,7 @@ import com.cloud.storage.VolumeVO;
 import com.cloud.storage.dao.DiskOfferingDao;
 import com.cloud.storage.dao.GuestOSCategoryDao;
 import com.cloud.storage.dao.GuestOSDao;
+import com.cloud.storage.dao.GuestOSHypervisorDao;
 import com.cloud.storage.dao.VMTemplateDao;
 import com.cloud.storage.dao.VolumeDao;
 import com.cloud.storage.secondary.SecondaryStorageVmManager;
@@ -671,6 +682,8 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
     @Inject
     private GuestOSCategoryDao _guestOSCategoryDao;
     @Inject
+    private GuestOSHypervisorDao _guestOSHypervisorDao;
+    @Inject
     private PrimaryDataStoreDao _poolDao;
     @Inject
     private NetworkDao _networkDao;
@@ -2109,6 +2122,216 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
         return new Pair<List<? extends GuestOsCategory>, Integer>(result.first(), result.second());
     }
 
+    @Override
+    public Pair<List<? extends GuestOSHypervisor>, Integer> listGuestOSMappingByCriteria(ListGuestOsMappingCmd cmd) {
+        Filter searchFilter = new Filter(GuestOSHypervisorVO.class, "hypervisorType", true, cmd.getStartIndex(), cmd.getPageSizeVal());
+        Long id = cmd.getId();
+        Long osTypeId = cmd.getOsTypeId();
+        String hypervisor = cmd.getHypervisor();
+        String hypervisorVersion = cmd.getHypervisorVersion();
+
+        //throw exception if hypervisor name is not passed, but version is
+        if (hypervisorVersion != null && (hypervisor == null || hypervisor.isEmpty())) {
+            throw new InvalidParameterValueException("Hypervisor version parameter cannot be used without specifying a hypervisor : XenServer, KVM or VMware");
+        }
+
+        SearchCriteria<GuestOSHypervisorVO> sc = _guestOSHypervisorDao.createSearchCriteria();
+
+        if (id != null) {
+            sc.addAnd("id", SearchCriteria.Op.EQ, id);
+        }
+
+        if (osTypeId != null) {
+            sc.addAnd("guestOsId", SearchCriteria.Op.EQ, osTypeId);
+        }
+
+        if (hypervisor != null) {
+            sc.addAnd("hypervisorType", SearchCriteria.Op.EQ, hypervisor);
+        }
+
+        if (hypervisorVersion != null) {
+            sc.addAnd("hypervisorVersion", SearchCriteria.Op.EQ, hypervisorVersion);
+        }
+
+        Pair<List<GuestOSHypervisorVO>, Integer> result = _guestOSHypervisorDao.searchAndCount(sc, searchFilter);
+        return new Pair<List<? extends GuestOSHypervisor>, Integer>(result.first(), result.second());
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_GUEST_OS_MAPPING_ADD, eventDescription = "Adding new guest OS to hypervisor name mapping", create = true)
+    public GuestOSHypervisor addGuestOsMapping(AddGuestOsMappingCmd cmd) {
+        Long osTypeId = cmd.getOsTypeId();
+        String osStdName = cmd.getOsStdName();
+        String hypervisor = cmd.getHypervisor();
+        String hypervisorVersion = cmd.getHypervisorVersion();
+        String osNameForHypervisor = cmd.getOsNameForHypervisor();
+        GuestOS guestOs = null;
+
+        if ((osTypeId == null) && (osStdName == null || osStdName.isEmpty())) {
+            throw new InvalidParameterValueException("Please specify either a guest OS name or UUID");
+        }
+
+        HypervisorType hypervisorType = HypervisorType.getType(hypervisor);
+
+        if (!(hypervisorType == HypervisorType.KVM || hypervisorType == HypervisorType.XenServer || hypervisorType == HypervisorType.VMware)) {
+            throw new InvalidParameterValueException("Please specify a valid hypervisor : XenServer, KVM or VMware");
+        }
+
+        HypervisorCapabilitiesVO hypervisorCapabilities = _hypervisorCapabilitiesDao.findByHypervisorTypeAndVersion(hypervisorType, hypervisorVersion);
+        if (hypervisorCapabilities == null) {
+            throw new InvalidParameterValueException("Please specify a valid hypervisor and supported version");
+        }
+
+        //by this point either osTypeId or osStdType is non-empty. Find by either of them. ID takes preference if both are specified
+        if (osTypeId != null) {
+            guestOs = ApiDBUtils.findGuestOSById(osTypeId);
+        }
+        else if (osStdName != null) {
+            guestOs = ApiDBUtils.findGuestOSByDisplayName(osStdName);
+        }
+
+        if (guestOs == null) {
+            throw new InvalidParameterValueException("Unable to find the guest OS by name or UUID");
+        }
+        //check for duplicates
+        GuestOSHypervisorVO duplicate = _guestOSHypervisorDao.findByOsIdAndHypervisor(osTypeId.longValue(), hypervisorType.toString(), hypervisorVersion);
+
+        if (duplicate != null) {
+            throw new InvalidParameterValueException("Mapping from hypervisor : " + hypervisorType.toString() + ", version : " + hypervisorVersion + " and guest OS : "
+                    + guestOs.getDisplayName() + " already exists!");
+        }
+        GuestOSHypervisorVO guestOsMapping = new GuestOSHypervisorVO();
+        guestOsMapping.setGuestOsId(guestOs.getId());
+        guestOsMapping.setGuestOsName(osNameForHypervisor);
+        guestOsMapping.setHypervisorType(hypervisorType.toString());
+        guestOsMapping.setHypervisorVersion(hypervisorVersion);
+        return _guestOSHypervisorDao.persist(guestOsMapping);
+
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_GUEST_OS_MAPPING_ADD, eventDescription = "Adding a new guest OS to hypervisor name mapping", async = true)
+    public GuestOSHypervisor getAddedGuestOsMapping(Long guestOsMappingId) {
+        return getGuestOsHypervisor(guestOsMappingId);
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_GUEST_OS_ADD, eventDescription = "Adding new guest OS type", create = true)
+    public GuestOS addGuestOs(AddGuestOsCmd cmd) {
+        Long categoryId = cmd.getOsCategoryId();
+        String displayName = cmd.getOsDisplayName();
+        String name = cmd.getOsName();
+
+        GuestOSCategoryVO guestOsCategory = ApiDBUtils.findGuestOsCategoryById(categoryId);
+        if (guestOsCategory == null) {
+            throw new InvalidParameterValueException("Guest OS category not found. Please specify a valid Guest OS category");
+        }
+
+        GuestOS guestOs = ApiDBUtils.findGuestOSByDisplayName(displayName);
+        if (guestOs != null) {
+            throw new InvalidParameterValueException("The specified Guest OS name : " + displayName + " already exists. Please specify a unique name");
+        }
+
+        GuestOSVO guestOsVo = new GuestOSVO();
+        guestOsVo.setCategoryId(categoryId.longValue());
+        guestOsVo.setDisplayName(displayName);
+        guestOsVo.setName(name);
+        return _guestOSDao.persist(guestOsVo);
+    }
+
+    @Override
+    @ActionEvent(eventType = EventTypes.EVENT_GUEST_OS_ADD, eventDescription = "Adding a new guest OS type", async = true)
+    public GuestOS getAddedGuestOs(Long guestOsId) {
+        return getGuestOs(guestOsId);
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_GUEST_OS_UPDATE, eventDescription = "updating guest OS type", async = true)
+    public GuestOS updateGuestOs(UpdateGuestOsCmd cmd) {
+        Long id = cmd.getId();
+        String displayName = cmd.getOsDisplayName();
+
+        //check if guest OS exists
+        GuestOS guestOsHandle = ApiDBUtils.findGuestOSById(id);
+        if (guestOsHandle == null) {
+            throw new InvalidParameterValueException("Guest OS not found. Please specify a valid ID for the Guest OS");
+        }
+
+        //Check if update is needed
+        if (displayName.equals(guestOsHandle.getDisplayName())) {
+            return guestOsHandle;
+        }
+
+        //Check if another Guest OS by same name exists
+        GuestOS duplicate = ApiDBUtils.findGuestOSByDisplayName(displayName);
+        if(duplicate != null) {
+            throw new InvalidParameterValueException("The specified Guest OS name : " + displayName + " already exists. Please specify a unique guest OS name");
+        }
+        GuestOSVO guestOs = _guestOSDao.createForUpdate(id);
+        guestOs.setDisplayName(displayName);
+        if (_guestOSDao.update(id, guestOs)) {
+            return _guestOSDao.findById(id);
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_GUEST_OS_REMOVE, eventDescription = "removing guest OS type", async = true)
+    public boolean removeGuestOs(RemoveGuestOsCmd cmd) {
+        Long id = cmd.getId();
+
+        //check if guest OS exists
+        GuestOS guestOs = ApiDBUtils.findGuestOSById(id);
+        if (guestOs == null) {
+            throw new InvalidParameterValueException("Guest OS not found. Please specify a valid ID for the Guest OS");
+        }
+
+        return _guestOSDao.remove(id);
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_GUEST_OS_MAPPING_UPDATE, eventDescription = "updating guest OS mapping", async = true)
+    public GuestOSHypervisor updateGuestOsMapping(UpdateGuestOsMappingCmd cmd) {
+        Long id = cmd.getId();
+        String osNameForHypervisor = cmd.getOsNameForHypervisor();
+
+        //check if mapping exists
+        GuestOSHypervisor guestOsHypervisorHandle = _guestOSHypervisorDao.findById(id);
+        if (guestOsHypervisorHandle == null) {
+            throw new InvalidParameterValueException("Guest OS Mapping not found. Please specify a valid ID for the Guest OS Mapping");
+        }
+
+        GuestOSHypervisorVO guestOsHypervisor = _guestOSHypervisorDao.createForUpdate(id);
+        guestOsHypervisor.setGuestOsName(osNameForHypervisor);
+        if (_guestOSHypervisorDao.update(id, guestOsHypervisor)) {
+            return _guestOSHypervisorDao.findById(id);
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_GUEST_OS_MAPPING_REMOVE, eventDescription = "removing guest OS mapping", async = true)
+    public boolean removeGuestOsMapping(RemoveGuestOsMappingCmd cmd) {
+        Long id = cmd.getId();
+
+        //check if mapping exists
+        GuestOSHypervisor guestOsHypervisorHandle = _guestOSHypervisorDao.findById(id);
+        if (guestOsHypervisorHandle == null) {
+            throw new InvalidParameterValueException("Guest OS Mapping not found. Please specify a valid ID for the Guest OS Mapping");
+        }
+
+        return _guestOSHypervisorDao.removeGuestOsMapping(id);
+
+    }
+
     protected ConsoleProxyInfo getConsoleProxyForVm(long dataCenterId, long userVmId) {
         return _consoleProxyMgr.assignProxy(dataCenterId, userVmId);
     }
@@ -2663,6 +2886,13 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
         cmdList.add(UpdatePortForwardingRuleCmd.class);
         cmdList.add(ListGuestOsCategoriesCmd.class);
         cmdList.add(ListGuestOsCmd.class);
+        cmdList.add(ListGuestOsMappingCmd.class);
+        cmdList.add(AddGuestOsCmd.class);
+        cmdList.add(AddGuestOsMappingCmd.class);
+        cmdList.add(UpdateGuestOsCmd.class);
+        cmdList.add(UpdateGuestOsMappingCmd.class);
+        cmdList.add(RemoveGuestOsCmd.class);
+        cmdList.add(RemoveGuestOsMappingCmd.class);
         cmdList.add(AttachIsoCmd.class);
         cmdList.add(CopyIsoCmd.class);
         cmdList.add(DeleteIsoCmd.class);
@@ -3272,6 +3502,11 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
     }
 
     @Override
+    public GuestOSHypervisorVO getGuestOsHypervisor(Long guestOsHypervisorId) {
+        return _guestOSHypervisorDao.findById(guestOsHypervisorId);
+    }
+
+    @Override
     public InstanceGroupVO updateVmGroup(UpdateVMGroupCmd cmd) {
         Account caller = CallContext.current().getCallingAccount();
         Long groupId = cmd.getId();
@@ -3789,4 +4024,5 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
     public void setLockMasterListener(LockMasterListener lockMasterListener) {
         _lockMasterListener = lockMasterListener;
     }
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3ee1fc28/setup/db/db/schema-430to440.sql
----------------------------------------------------------------------
diff --git a/setup/db/db/schema-430to440.sql b/setup/db/db/schema-430to440.sql
index ee4cf21..ab6bc98 100644
--- a/setup/db/db/schema-430to440.sql
+++ b/setup/db/db/schema-430to440.sql
@@ -611,3 +611,13 @@ CREATE TABLE `cloud`.`vgpu_types` (
   CONSTRAINT `fk_vgpu_types__gpu_group_id` FOREIGN KEY (`gpu_group_id`) REFERENCES `host_gpu_groups` (`id`) ON DELETE CASCADE
 ) ENGINE=InnoDB CHARSET=utf8;
 
+ALTER TABLE `cloud`.`guest_os_hypervisor` ADD COLUMN `hypervisor_version` varchar(32) NOT NULL DEFAULT 'default' COMMENT 'Hypervisor version for this mapping';
+ALTER TABLE `cloud`.`guest_os_hypervisor` ADD COLUMN `uuid` varchar(40) COMMENT 'UUID of the mapping';
+ALTER TABLE `cloud`.`guest_os_hypervisor` ADD CONSTRAINT `uc_guest_os_hypervisor__uuid` UNIQUE (`uuid`);
+ALTER TABLE `cloud`.`guest_os_hypervisor` ADD COLUMN `created` datetime COMMENT 'Time when mapping was created';
+ALTER TABLE `cloud`.`guest_os_hypervisor` ADD COLUMN `removed` datetime COMMENT 'Time when mapping was removed if deleted, else NULL';
+UPDATE `cloud`.`guest_os_hypervisor` SET `uuid` = UUID();
+UPDATE `cloud`.`guest_os_hypervisor` SET `created` = now();
+ALTER TABLE `cloud`.`guest_os` ADD COLUMN `created` datetime COMMENT 'Time when Guest OS was created in system';
+ALTER TABLE `cloud`.`guest_os` ADD COLUMN `removed` datetime COMMENT 'Time when Guest OS was removed if deleted, else NULL';
+UPDATE `cloud`.`guest_os` SET `created` = now();


[29/31] git commit: updated refs/heads/distributedrouter to a8d43ba

Posted by mu...@apache.org.
adding distributed routing support for KVM OVS

some check style error fixes


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

Branch: refs/heads/distributedrouter
Commit: bc274826782a1527352a0b6be88394423c44fb98
Parents: a572711
Author: Murali Reddy <mu...@gmail.com>
Authored: Tue Mar 11 13:05:03 2014 +0530
Committer: Murali Reddy <mu...@gmail.com>
Committed: Thu Mar 13 19:22:10 2014 +0530

----------------------------------------------------------------------
 .../kvm/resource/LibvirtComputingResource.java  |  47 ++++
 .../xen/resource/CitrixResourceBase.java        |   3 +-
 .../api/OvsVpcRoutingPolicyConfigCommand.java   |   1 -
 .../cloud/network/ovs/OvsTunnelManagerImpl.java |  21 +-
 scripts/vm/network/vnet/cloudstack_pluginlib.py | 226 +++++++++++++++++++
 scripts/vm/network/vnet/ovstunnel.py            |  86 ++++++-
 6 files changed, 373 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bc274826/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
index e44bd87..79b2aa2 100755
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
@@ -78,6 +78,8 @@ import com.cloud.agent.api.OvsDestroyTunnelCommand;
 import com.cloud.agent.api.OvsFetchInterfaceAnswer;
 import com.cloud.agent.api.OvsFetchInterfaceCommand;
 import com.cloud.agent.api.OvsSetupBridgeCommand;
+import com.cloud.agent.api.OvsVpcPhysicalTopologyConfigCommand;
+import com.cloud.agent.api.OvsVpcRoutingPolicyConfigCommand;
 import com.cloud.agent.api.PingCommand;
 import com.cloud.agent.api.PingRoutingCommand;
 import com.cloud.agent.api.PingRoutingWithNwGroupsCommand;
@@ -1360,6 +1362,10 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
                 return execute((OvsCreateTunnelCommand)cmd);
             } else if (cmd instanceof OvsDestroyTunnelCommand) {
                 return execute((OvsDestroyTunnelCommand)cmd);
+            } else if (cmd instanceof OvsVpcPhysicalTopologyConfigCommand) {
+                return execute((OvsVpcPhysicalTopologyConfigCommand) cmd);
+            } else if (cmd instanceof OvsVpcRoutingPolicyConfigCommand) {
+                return execute((OvsVpcRoutingPolicyConfigCommand) cmd);
             } else {
                 s_logger.warn("Unsupported command ");
                 return Answer.createUnsupportedCommandAnswer(cmd);
@@ -1401,6 +1407,47 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
         return new Answer(cmd, true, null);
     }
 
+    public Answer execute(OvsVpcPhysicalTopologyConfigCommand cmd) {
+
+        String bridge = cmd.getBridgeName();
+        try {
+            Script command = new Script(_ovsTunnelPath, _timeout, s_logger);
+            command.add("configure_ovs_bridge_for_network_topology");
+            command.add("--bridge", bridge);
+            command.add("--config", cmd.getVpcConfigInJson());
+
+            String result = command.execute();
+            if (result.equalsIgnoreCase("SUCCESS")) {
+                return new Answer(cmd, true, result);
+            } else {
+                return new Answer(cmd, false, result);
+            }
+        } catch  (Exception e) {
+            s_logger.warn("caught exception while updating host with latest routing polcies", e);
+            return new Answer(cmd, false, e.getMessage());
+        }
+    }
+
+    public Answer execute(OvsVpcRoutingPolicyConfigCommand cmd) {
+
+        try {
+            Script command = new Script(_ovsTunnelPath, _timeout, s_logger);
+            command.add("configure_ovs_bridge_for_routing_policies");
+            command.add("--bridge", cmd.getBridgeName());
+            command.add("--config", cmd.getVpcConfigInJson());
+
+            String result = command.execute();
+            if (result.equalsIgnoreCase("SUCCESS")) {
+                return new Answer(cmd, true, result);
+            } else {
+                return new Answer(cmd, false, result);
+            }
+        } catch  (Exception e) {
+            s_logger.warn("caught exception while updating host with latest VPC topology", e);
+            return new Answer(cmd, false, e.getMessage());
+        }
+    }
+
     private synchronized void destroyTunnelNetwork(String bridge) {
         try {
             findOrCreateTunnelNetwork(bridge);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bc274826/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 da92e1e..d637443 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
@@ -16,7 +16,6 @@
 // under the License.
 package com.cloud.hypervisor.xen.resource;
 
-import com.cloud.agent.api.*;
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileInputStream;
@@ -89,7 +88,6 @@ import org.apache.cloudstack.storage.to.TemplateObjectTO;
 import org.apache.cloudstack.storage.to.VolumeObjectTO;
 
 import com.cloud.agent.IAgentControl;
-
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.AttachIsoCommand;
 import com.cloud.agent.api.AttachVolumeAnswer;
@@ -150,6 +148,7 @@ import com.cloud.agent.api.OvsSetTagAndFlowAnswer;
 import com.cloud.agent.api.OvsSetTagAndFlowCommand;
 import com.cloud.agent.api.OvsSetupBridgeCommand;
 import com.cloud.agent.api.OvsVpcPhysicalTopologyConfigCommand;
+import com.cloud.agent.api.OvsVpcRoutingPolicyConfigCommand;
 import com.cloud.agent.api.PerformanceMonitorAnswer;
 import com.cloud.agent.api.PerformanceMonitorCommand;
 import com.cloud.agent.api.PingCommand;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bc274826/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcRoutingPolicyConfigCommand.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcRoutingPolicyConfigCommand.java b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcRoutingPolicyConfigCommand.java
index 8e4d5d1..50f1fdd 100644
--- a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcRoutingPolicyConfigCommand.java
+++ b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcRoutingPolicyConfigCommand.java
@@ -18,7 +18,6 @@ package com.cloud.agent.api;
 
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
-import java.util.UUID;
 
 /**
  * This command represents logical view of VM's connectivity in VPC.

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bc274826/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
index 35b0035..eeb22b1 100644
--- a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
+++ b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
@@ -16,11 +16,25 @@
 // under the License.
 package com.cloud.network.ovs;
 
-import com.amazonaws.services.ec2.model.NetworkAcl;
-import com.cloud.agent.api.*;
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+import com.cloud.agent.api.OvsCreateTunnelAnswer;
+import com.cloud.agent.api.OvsCreateTunnelCommand;
+import com.cloud.agent.api.OvsDestroyBridgeCommand;
+import com.cloud.agent.api.OvsDestroyTunnelCommand;
+import com.cloud.agent.api.OvsFetchInterfaceAnswer;
+import com.cloud.agent.api.OvsFetchInterfaceCommand;
+import com.cloud.agent.api.OvsSetupBridgeCommand;
+import com.cloud.agent.api.OvsVpcPhysicalTopologyConfigCommand;
+import com.cloud.agent.api.OvsVpcRoutingPolicyConfigCommand;
 import com.cloud.network.dao.NetworkDao;
 import com.cloud.network.dao.NetworkVO;
-import com.cloud.network.vpc.*;
+import com.cloud.network.vpc.NetworkACLVO;
+import com.cloud.network.vpc.NetworkACLItemDao;
+import com.cloud.network.vpc.NetworkACLItemVO;
+import com.cloud.network.vpc.dao.VpcDao;
+import com.cloud.network.vpc.VpcManager;
+import com.cloud.network.vpc.VpcVO;
 import com.cloud.network.vpc.dao.NetworkACLDao;
 import com.cloud.vm.dao.VMInstanceDao;
 import com.cloud.vm.Nic;
@@ -63,7 +77,6 @@ import com.cloud.network.ovs.dao.OvsTunnelInterfaceVO;
 import com.cloud.network.ovs.dao.OvsTunnelNetworkDao;
 import com.cloud.network.ovs.dao.OvsTunnelNetworkVO;
 import com.cloud.network.ovs.dao.OvsTunnel;
-import com.cloud.network.vpc.dao.VpcDao;
 import com.cloud.utils.component.ManagerBase;
 import com.cloud.utils.concurrency.NamedThreadFactory;
 import com.cloud.utils.db.DB;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bc274826/scripts/vm/network/vnet/cloudstack_pluginlib.py
----------------------------------------------------------------------
diff --git a/scripts/vm/network/vnet/cloudstack_pluginlib.py b/scripts/vm/network/vnet/cloudstack_pluginlib.py
index f886aa3..6c24917 100755
--- a/scripts/vm/network/vnet/cloudstack_pluginlib.py
+++ b/scripts/vm/network/vnet/cloudstack_pluginlib.py
@@ -174,6 +174,7 @@ def _build_flow_expr(**kwargs):
     dl_dst = 'dl_dst' in kwargs and ",dl_dst=%s" % kwargs['dl_dst'] or ''
     nw_src = 'nw_src' in kwargs and ",nw_src=%s" % kwargs['nw_src'] or ''
     nw_dst = 'nw_dst' in kwargs and ",nw_dst=%s" % kwargs['nw_dst'] or ''
+    table = 'table' in kwargs and ",table=%s" % kwargs['table'] or ''
     proto = 'proto' in kwargs and ",%s" % kwargs['proto'] or ''
     ip = ('nw_src' in kwargs or 'nw_dst' in kwargs) and ',ip' or ''
     flow = (flow + in_port + dl_type + dl_src + dl_dst +
@@ -217,3 +218,228 @@ def del_all_flows(bridge):
 def del_port(bridge, port):
     delPort = [VSCTL_PATH, "del-port", bridge, port]
     do_cmd(delPort)
+
+
+def get_network_id_for_vif(vif_name):
+    domain_id, device_id = vif_name[3:len(vif_name)].split(".")
+    dom_uuid = do_cmd([XE_PATH, "vm-list", "dom-id=%s" % domain_id, "--minimal"])
+    vif_uuid = do_cmd([XE_PATH, "vif-list", "vm-uuid=%s" % dom_uuid, "device=%s" % device_id, "--minimal"])
+    vnet = do_cmd([XE_PATH, "vif-param-get", "uuid=%s" % vif_uuid,  "param-name=other-config",
+                             "param-key=cloudstack-network-id"])
+    return vnet
+
+def get_network_id_for_tunnel_port(tunnelif_name):
+    vnet = do_cmd([VSCTL_PATH, "get", "interface", tunnelif_name, "options:cloudstack-network-id"])
+    return vnet
+
+def clear_flooding_rules_for_port(bridge, ofport):
+        del_flows(bridge, in_port=ofport, table=2)
+
+def add_flooding_rules_for_port(bridge, in_ofport, out_ofports):
+        action = "".join("output:%s," %ofport for ofport in out_ofports)[:-1]
+        add_flow(bridge, priority=1100, in_port=in_ofport, table=1, actions=action)
+
+def get_ofport_for_vif(vif_name):
+    return do_cmd([VSCTL_PATH, "get", "interface", vif_name, "ofport"])
+
+def get_macaddress_of_vif(vif_name):
+    domain_id, device_id = vif_name[3:len(vif_name)].split(".")
+    dom_uuid = do_cmd([XE_PATH, "vm-list", "dom-id=%s" % domain_id, "--minimal"])
+    vif_uuid = do_cmd([XE_PATH, "vif-list", "vm-uuid=%s" % dom_uuid, "device=%s" % device_id, "--minimal"])
+    mac = do_cmd([XE_PATH, "vif-param-get", "uuid=%s" % vif_uuid,  "param-name=MAC"])
+    return mac
+
+def get_vif_name_from_macaddress(macaddress):
+    vif_uuid = do_cmd([XE_PATH, "vif-list", "MAC=%s" % macaddress, "--minimal"])
+    vif_device_id = do_cmd([XE_PATH, "vif-param-get", "uuid=%s" % vif_uuid,  "param-name=device"])
+    vm_uuid = do_cmd([XE_PATH, "vif-param-get", "uuid=%s" % vif_uuid,  "param-name=vm-uuid"])
+    vm_domain_id = do_cmd([XE_PATH, "vm-param-get", "uuid=%s" % vm_uuid,  "param-name=dom-id"])
+    return "vif"+vm_domain_id+"."+vif_device_id
+
+def add_mac_lookup_table_entry(bridge, mac_address, out_of_port):
+    add_flow(bridge, priority=1100, dl_dst=mac_address, table=1, actions="output:%s" % out_of_port)
+
+def delete_mac_lookup_table_entry(bridge, mac_address):
+    del_flows(bridge, dl_dst=mac_address, table=1)
+
+def add_ip_lookup_table_entry(bridge, ip, dst_tier_gateway_mac, dst_vm_mac):
+    action_str = "mod_dl_sr:%s" % dst_tier_gateway_mac + ",mod_dl_dst:%s" % dst_vm_mac +",resubmit(,5)"
+    addflow = [OFCTL_PATH, "add-flow", bridge, "table=4", "nw_dst=%s" % ip, "actions=%s" %action_str]
+    do_cmd(addflow)
+
+def get_vms_on_host(vpc, host_id):
+    all_vms = vpc.vms
+    vms_on_host = []
+    for vm in all_vms:
+      if vm.hostid == host_id:
+        vms_on_host.append(vm)
+    return vms_on_host
+
+def get_network_details(vpc, network_uuid):
+    tiers = vpc.tiers
+    for tier in tiers:
+      if tier.networkuuid == network_uuid:
+        return tier
+    return None
+
+class jsonLoader(object):
+  def __init__(self, obj):
+        for k in obj:
+            v = obj[k]
+            if isinstance(v, dict):
+                setattr(self, k, jsonLoader(v))
+            elif isinstance(v, (list, tuple)):
+                if len(v) > 0 and isinstance(v[0], dict):
+                    setattr(self, k, [jsonLoader(elem) for elem in v])
+                else:
+                    setattr(self, k, v)
+            else:
+                setattr(self, k, v)
+
+  def __getattr__(self, val):
+        if val in self.__dict__:
+            return self.__dict__[val]
+        else:
+            return None
+
+  def __repr__(self):
+        return '{%s}' % str(', '.join('%s : %s' % (k, repr(v)) for (k, v)
+                                      in self.__dict__.iteritems()))
+
+  def __str__(self):
+        return '{%s}' % str(', '.join('%s : %s' % (k, repr(v)) for (k, v)
+                                      in self.__dict__.iteritems()))
+
+def configure_bridge_for_network_topology(bridge, this_host_id, json_config):
+    vpconfig = jsonLoader(json.loads(json_config)).vpc
+
+    if vpconfig is None:
+        logging.debug("WARNING:Can't find VPC info in json config file")
+        return "FAILURE:IMPROPER_JSON_CONFG_FILE"
+
+    # get the list of Vm's in the VPC from the JSON config
+    this_host_vms = get_vms_on_host(vpconfig, this_host_id)
+
+    for vm in this_host_vms:
+        for nic in vm.nics:
+            mac_addr = nic.macaddress
+            ip = nic.ipaddress
+            vif_name = get_vif_name_from_macaddress(mac_addr)
+            of_port = get_ofport_for_vif(vif_name)
+            network = get_network_details(vpconfig, nic.networkuuid)
+
+            # Add flow rule in L2 look up table, if the destination mac = MAC of the nic send packet on the found OFPORT
+            add_mac_lookup_table_entry(bridge, mac_addr, of_port)
+
+            # Add flow rule in L3 look up table: if the destination IP = VM's IP then modify the packet
+            # to set DST MAC = VM's MAC, SRC MAC=tier gateway MAC and send to egress table
+            add_ip_lookup_table_entry(bridge, ip, network.gatewaymac, mac_addr)
+
+            # Add flow entry to send with intra tier traffic from the NIC to L2 lookup path)
+            addflow = [OFCTL_PATH, "add-flow", bridge, "table=0", "in_port=%s" % of_port,
+                       "nw_dst=%s" %network.cidr, "actions=resubmit(,1)"]
+            do_cmd(addflow)
+
+            #add flow entry to send inter-tier traffic from the NIC to egress ACL table(to L3 lookup path)
+            addflow = [OFCTL_PATH, "add-flow", bridge, "table=0", "in_port=%s" % of_port,
+                       "dl_dst=%s" %network.gatewaymac, "nw_dst=%s" %vpconfig.cidr, "actions=resubmit(,3)"]
+            do_cmd(addflow)
+
+    # get the list of hosts on which VPC spans from the JSON config
+    vpc_spanning_hosts = vpconfig.hosts
+
+    for host in vpc_spanning_hosts:
+        if this_host_id == host.hostid:
+            continue
+        other_host_vms = get_vms_on_host(vpconfig, host.hostid)
+        for vm in other_host_vms:
+            for nic in vm.nics:
+                mac_addr = nic.macaddress
+                ip = nic.ipaddress
+                network = get_network_details(vpconfig, nic.networkuuid)
+                gre_key = network.grekey
+
+                # generate tunnel name from tunnel naming convention
+                tunnel_name = "t%s-%s-%s" % (gre_key, this_host_id, host.hostid)
+                of_port = get_ofport_for_vif(tunnel_name)
+
+                # Add flow rule in L2 look up table, if the destination mac = MAC of the nic send packet tunnel port
+                add_mac_lookup_table_entry(bridge, mac_addr, of_port)
+
+                # Add flow tule in L3 look up table: if the destination IP = VM's IP then modify the packet
+                # set DST MAC = VM's MAC, SRC MAC=tier gateway MAC and send to egress table
+                add_ip_lookup_table_entry(bridge, ip, network.gatewaymac, mac_addr)
+
+    return "SUCCESS: successfully configured bridge as per the VPC topology"
+
+def get_acl(vpcconfig, required_acl_id):
+    acls = vpcconfig.acls
+    for acl in acls:
+        if acl.id == required_acl_id:
+            return acl
+    return None
+
+def configure_ovs_bridge_for_routing_policies(bridge, json_config):
+    vpconfig = jsonLoader(json.loads(json_config)).vpc
+
+    if vpconfig is None:
+        logging.debug("WARNING:Can't find VPC info in json config file")
+        return "FAILURE:IMPROPER_JSON_CONFG_FILE"
+
+    # First flush current egress ACL's before re-applying the ACL's
+    del_flows(bridge, table=3)
+
+    egress_rules_added = False
+    ingress_rules_added = False
+
+    tiers = vpconfig.tiers
+    for tier in tiers:
+        tier_cidr = tier.cidr
+        acl = get_acl(vpconfig, tier.aclid)
+        acl_items = acl.aclitems
+
+        for acl_item in acl_items:
+            number = acl_item.number
+            action = acl_item.action
+            direction = acl_item.direction
+            source_port_start = acl_item.sourceportstart
+            source_port_end = acl_item.sourceportend
+            protocol = acl_item.protocol
+            source_cidrs = acl_item.sourcecidrs
+            acl_priority = 1000 + number
+            for source_cidr in source_cidrs:
+                if direction is "ingress":
+                    ingress_rules_added = True
+                    # add flow rule to do action (allow/deny) for flows where source IP of the packet is in
+                    # source_cidr and destination ip is in tier_cidr
+                    port = source_port_start
+                    while (port < source_port_end):
+                        if action is "deny":
+                            add_flow(bridge, priority= acl_priority, table=5, nw_src=source_cidr, nw_dst=tier_cidr, tp_dst=port,
+                                     nw_proto=protocol, actions='drop')
+                        if action is "allow":
+                            add_flow(bridge, priority= acl_priority,table=5, nw_src=source_cidr, nw_dst=tier_cidr, tp_dst=port,
+                                     nw_proto=protocol, actions='resubmit(,1)')
+                        port = port + 1
+
+                elif direction in "egress":
+                    egress_rules_added = True
+                    # add flow rule to do action (allow/deny) for flows where destination IP of the packet is in
+                    # source_cidr and source ip is in tier_cidr
+                    port = source_port_start
+                    while (port < source_port_end):
+                        if action is "deny":
+                            add_flow(bridge, priority= acl_priority, table=5, nw_src=tier_cidr, nw_dst=source_cidr, tp_dst=port,
+                                     nw_proto=protocol, actions='drop')
+                        if action is "allow":
+                            add_flow(bridge, priority= acl_priority, table=5, nw_src=tier_cidr, nw_dst=source_cidr, tp_dst=port,
+                                     nw_proto=protocol, actions='resubmit(,1)')
+                        port = port + 1
+
+    if egress_rules_added is False:
+        # add a default rule in egress table to forward packet to L3 lookup table
+        add_flow(bridge, priority=0, table=3, actions='resubmit(,4)')
+
+    if ingress_rules_added is False:
+        # add a default rule in egress table drop packets
+        add_flow(bridge, priority=0, table=5, actions='drop')

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bc274826/scripts/vm/network/vnet/ovstunnel.py
----------------------------------------------------------------------
diff --git a/scripts/vm/network/vnet/ovstunnel.py b/scripts/vm/network/vnet/ovstunnel.py
index 9e05413..57085d8 100755
--- a/scripts/vm/network/vnet/ovstunnel.py
+++ b/scripts/vm/network/vnet/ovstunnel.py
@@ -27,6 +27,7 @@ import os
 import sys
 import subprocess
 import time
+import simplejson as json
 from optparse import OptionParser, OptionGroup, OptParseError, BadOptionError, OptionError, OptionConflictError, OptionValueError
 
 from time import localtime as _localtime, asctime as _asctime
@@ -72,6 +73,58 @@ def setup_ovs_bridge(bridge, key, cs_host_id):
     logging.debug("Setup_ovs_bridge completed with result:%s" % result)
     return result
 
+@echo
+def setup_ovs_bridge_for_distributed_routing(bridge, cs_host_id):
+
+    res = lib.check_switch()
+    if res != "SUCCESS":
+        return "FAILURE:%s" % res
+
+    logging.debug("About to manually create the bridge:%s" % bridge)
+    res = lib.do_cmd([lib.VSCTL_PATH, "--", "--may-exist", "add-br", bridge])
+    logging.debug("Bridge has been manually created:%s" % res)
+
+    # Non empty result means something went wrong
+    if res:
+        result = "FAILURE:%s" % res
+    else:
+        # Verify the bridge actually exists
+        res = lib.do_cmd([lib.VSCTL_PATH, "list", "bridge", bridge])
+
+        res = lib.do_cmd([lib.VSCTL_PATH, "set", "bridge", bridge, "other_config:is-ovs_vpc_distributed_vr_network=True"])
+        conf_hosts = lib.do_cmd([lib.VSCTL_PATH, "get","bridge", bridge,"other:ovs-host-setup"])
+        conf_hosts = cs_host_id + (conf_hosts and ',%s' % conf_hosts or '')
+        lib.do_cmd([lib.VSCTL_PATH, "set", "bridge", bridge,
+                   "other_config:ovs-host-setup=%s" % conf_hosts])
+
+        # add a default flow rule to send broadcast and multi-cast packets to L2 flooding table
+        lib.add_flow(bridge, priority=1000, dl_dst='ff:ff:ff:ff:ff:ff', table=0, actions='resubmit(,2)')
+        lib.add_flow(bridge, priority=1000, nw_dst='224.0.0.0/24', table=0, actions='resubmit(,2)')
+
+        # add a default flow rule to send uni-cast traffic to L2 lookup table
+        lib.add_flow(bridge, priority=0, table=0, actions='resubmit(,1)')
+
+        # add a default rule to send unknown mac address to L2 flooding table
+        lib.add_flow(bridge, priority=0, table=1, actions='resubmit(,2)')
+
+        # add a default rule in L2 flood table to drop packet
+        lib.add_flow(bridge, priority=0, table=2, actions='drop')
+
+        # add a default rule in egress table to forward packet to L3 lookup table
+        lib.add_flow(bridge, priority=0, table=3, actions='resubmit(,4)')
+
+        # add a default rule in L3 lookup table to forward packet to L2 lookup table
+        lib.add_flow(bridge, priority=0, table=4, actions='resubmit(,1)')
+
+        # add a default rule in ingress table to drop in bound packets
+        lib.add_flow(bridge, priority=0, table=5, actions='drop')
+
+        result = "SUCCESS: successfully setup bridge with flow rules"
+
+        logging.debug("Setup_ovs_bridge completed with result:%s" % result)
+
+    return result
+
 def destroy_ovs_bridge(bridge):
 
     res = lib.check_switch()
@@ -163,12 +216,30 @@ def create_tunnel(bridge, remote_ip, key, src_host, dst_host):
         # Ensure no trailing LF
         if tun_ofport.endswith('\n'):
             tun_ofport = tun_ofport[:-1]
-        # add flow entryies for dropping broadcast coming in from gre tunnel
-        lib.add_flow(bridge, priority=1000, in_port=tun_ofport,
+
+        ovs_tunnel_network = lib.do_cmd([lib.VSCTL_PATH, "get", "bridge", bridge, "other_config:is-ovs-tun-network"])
+        ovs_vpc_distributed_vr_network = lib.do_cmd([lib.VSCTL_PATH, "get", "bridge", bridge,
+                                                     "other_config:is-ovs_vpc_distributed_vr_network"])
+
+        if ovs_tunnel_network == 'True':
+            # add flow entryies for dropping broadcast coming in from gre tunnel
+            lib.add_flow(bridge, priority=1000, in_port=tun_ofport,
+                         dl_dst='ff:ff:ff:ff:ff:ff', actions='drop')
+            lib.add_flow(bridge, priority=1000, in_port=tun_ofport,
+                     nw_dst='224.0.0.0/24', actions='drop')
+            drop_flow_setup = True
+
+        if ovs_vpc_distributed_vr_network == 'True':
+            # add flow rules for dropping broadcast coming in from tunnel ports
+            lib.add_flow(bridge, priority=1000, in_port=tun_ofport, table=0,
                          dl_dst='ff:ff:ff:ff:ff:ff', actions='drop')
-        lib.add_flow(bridge, priority=1000, in_port=tun_ofport,
+            lib.add_flow(bridge, priority=1000, in_port=tun_ofport, table=0,
                      nw_dst='224.0.0.0/24', actions='drop')
-        drop_flow_setup = True
+
+            # add flow rule to send the traffic from tunnel ports to L2 switching table only
+            lib.add_flow(bridge, priority=1000, in_port=tun_ofport, table=0, actions='resubmit(,1)')
+            lib.do_cmd([lib.VSCTL_PATH, "set", "interface", name, "options:cloudstack-network-id=%s" % network_uuid])
+
         logging.debug("Broadcast drop rules added")
 #        return "SUCCESS:%s" % name
         return 'true'
@@ -210,6 +281,7 @@ if __name__ == '__main__':
     parser.add_option("--src_host", dest="src_host")
     parser.add_option("--dst_host", dest="dst_host")
     parser.add_option("--iface_name", dest="iface_name")
+    parser.ad_option("--config", dest="config")
     (option, args) = parser.parse_args()
     if len(args) == 0:
         logging.debug("No command to execute")
@@ -223,6 +295,12 @@ if __name__ == '__main__':
         create_tunnel(option.bridge, option.remote_ip, option.key, option.src_host, option.dst_host)
     elif cmd == "destroy_tunnel":
         destroy_tunnel(option.bridge, option.iface_name)
+    elif cmd == "setup_ovs_bridge_for_distributed_routing":
+        setup_ovs_bridge_for_distributed_routing(bridge, cs_host_id)
+    elif cmd == "configure_ovs_bridge_for_network_topology":
+        configure_bridge_for_network_topology(brdige, cs_host_id, config)
+    elif cmd == "configure_ovs_bridge_for_routing_policies":
+        configure_ovs_bridge_for_routing_policies(bridge, config)
     else:
         logging.debug("Unknown command: " + cmd)
         sys.exit(1)


[16/31] git commit: updated refs/heads/distributedrouter to a8d43ba

Posted by mu...@apache.org.
CLOUDSTACK-6235 - return gateway/netmask of publicVlan, along with the EIP information, for system vms in EIP/ELB setup


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

Branch: refs/heads/distributedrouter
Commit: 40192cd8a1ee33ec784cfcbdb7c4c78483a8f1eb
Parents: b5c8a56
Author: Alena Prokharchyk <al...@citrix.com>
Authored: Wed Mar 12 14:36:43 2014 -0700
Committer: Alena Prokharchyk <al...@citrix.com>
Committed: Wed Mar 12 15:11:01 2014 -0700

----------------------------------------------------------------------
 server/src/com/cloud/api/ApiResponseHelper.java | 3 +++
 1 file changed, 3 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/40192cd8/server/src/com/cloud/api/ApiResponseHelper.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java
index 81bfe21..2deaa50 100755
--- a/server/src/com/cloud/api/ApiResponseHelper.java
+++ b/server/src/com/cloud/api/ApiResponseHelper.java
@@ -1192,8 +1192,11 @@ public class ApiResponseHelper implements ResponseGenerator {
                         NetworkOffering networkOffering = ApiDBUtils.findNetworkOfferingById(network.getNetworkOfferingId());
                         if (networkOffering.getElasticIp()) {
                             IpAddress ip = ApiDBUtils.findIpByAssociatedVmId(vm.getId());
+                            Vlan vlan = ApiDBUtils.findVlanById(ip.getVlanId());
                             if (ip != null) {
                                 vmResponse.setPublicIp(ip.getAddress().addr());
+                                vmResponse.setPublicNetmask(vlan.getVlanNetmask());
+                                vmResponse.setGateway(vlan.getVlanGateway());
                             }
                         } else {
                             vmResponse.setPublicIp(singleNicProfile.getIp4Address());


[08/31] git commit: updated refs/heads/distributedrouter to a8d43ba

Posted by mu...@apache.org.
CLOUDSTACK-5779: Clean up leftover VR script in Xen


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

Branch: refs/heads/distributedrouter
Commit: 3e097a0fb289971dc2fc509e0ab5ed78b64cf81b
Parents: f45de30
Author: Sheng Yang <sh...@citrix.com>
Authored: Tue Mar 11 13:22:14 2014 -0700
Committer: Sheng Yang <sh...@citrix.com>
Committed: Tue Mar 11 13:22:14 2014 -0700

----------------------------------------------------------------------
 .../vm/hypervisor/xenserver/createipAlias.sh    | 25 --------------------
 .../vm/hypervisor/xenserver/deleteipAlias.sh    | 24 -------------------
 scripts/vm/hypervisor/xenserver/vmops           | 16 -------------
 scripts/vm/hypervisor/xenserver/xcposs/patch    | 12 ----------
 scripts/vm/hypervisor/xenserver/xcpserver/patch |  9 -------
 .../vm/hypervisor/xenserver/xenserver56/patch   |  7 ------
 .../hypervisor/xenserver/xenserver56fp1/patch   |  7 ------
 .../vm/hypervisor/xenserver/xenserver60/patch   |  7 ------
 .../vm/hypervisor/xenserver/xenserver62/patch   |  7 ------
 9 files changed, 114 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3e097a0f/scripts/vm/hypervisor/xenserver/createipAlias.sh
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/xenserver/createipAlias.sh b/scripts/vm/hypervisor/xenserver/createipAlias.sh
deleted file mode 100755
index 4ef6618..0000000
--- a/scripts/vm/hypervisor/xenserver/createipAlias.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/usr/bin/env bash
-# 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.
-
-
-usage() {
-  printf " %s  routerip  <alias_count:ip:netmask;alias_count2:ip2:netmask2;....> \n" $(basename $0) >&2
-}
-
-cert="/root/.ssh/id_rsa.cloud"
-ssh -p 3922 -q -o StrictHostKeyChecking=no -i $cert root@$1 "/root/createIpAlias.sh $2"

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3e097a0f/scripts/vm/hypervisor/xenserver/deleteipAlias.sh
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/xenserver/deleteipAlias.sh b/scripts/vm/hypervisor/xenserver/deleteipAlias.sh
deleted file mode 100644
index 7604172..0000000
--- a/scripts/vm/hypervisor/xenserver/deleteipAlias.sh
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/usr/bin/env bash
-# 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.
-
-usage() {
-  printf " %s  routerip  <alias_count:ip:netmask;alias_count2:ip2:netmask2;....> \n" $(basename $0) >&2
-}
-
-cert="/root/.ssh/id_rsa.cloud"
-ssh -p 3922 -q -o StrictHostKeyChecking=no -i $cert root@$1 "/root/deleteIpAlias.sh $2 $3"

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3e097a0f/scripts/vm/hypervisor/xenserver/vmops
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/xenserver/vmops b/scripts/vm/hypervisor/xenserver/vmops
index 2f0f347..4174ef2 100755
--- a/scripts/vm/hypervisor/xenserver/vmops
+++ b/scripts/vm/hypervisor/xenserver/vmops
@@ -163,21 +163,6 @@ def pingtest(session, args):
     return txt
 
 @echo
-def savePassword(session, args):
-    sargs = args['args']
-    cmd = sargs.split(' ')
-    cmd.insert(0, "/opt/cloud/bin/save_password_to_domr.sh")
-    cmd.insert(0, "/bin/bash")
-    try:
-        txt = util.pread2(cmd)
-        txt = 'success'
-    except:
-        logging.debug("  save password to domr failed "  )
-        txt = '' 
-
-    return txt
-
-@echo
 def setLinkLocalIP(session, args):
     brName = args['brName']
     try:
@@ -1520,7 +1505,6 @@ if __name__ == "__main__":
      XenAPIPlugin.dispatch({"pingtest": pingtest, "setup_iscsi":setup_iscsi, "gethostvmstats": gethostvmstats, 
                             "getgateway": getgateway, "preparemigration": preparemigration, 
                             "setIptables": setIptables, "pingdomr": pingdomr, "pingxenserver": pingxenserver,  
-                            "savePassword": savePassword, 
                             "routerProxy": routerProxy, 
                             "createFile": createFile, "deleteFile": deleteFile,
                             "network_rules":network_rules, 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3e097a0f/scripts/vm/hypervisor/xenserver/xcposs/patch
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/xenserver/xcposs/patch b/scripts/vm/hypervisor/xenserver/xcposs/patch
index 2f902c2..08da883 100644
--- a/scripts/vm/hypervisor/xenserver/xcposs/patch
+++ b/scripts/vm/hypervisor/xenserver/xcposs/patch
@@ -39,13 +39,6 @@ setupxenserver.sh=..,0755,/opt/cloud/bin
 make_migratable.sh=..,0755,/opt/cloud/bin
 setup_iscsi.sh=..,0755,/opt/cloud/bin
 pingtest.sh=../../..,0755,/opt/cloud/bin
-dhcp_entry.sh=../../../../network/domr/,0755,/opt/cloud/bin
-ipassoc.sh=../../../../network/domr/,0755,/opt/cloud/bin
-save_password_to_domr.sh=../../../../network/domr/,0755,/opt/cloud/bin
-networkUsage.sh=../../../../network/domr/,0755,/opt/cloud/bin
-call_firewall.sh=../../../../network/domr/,0755,/opt/cloud/bin
-call_loadbalancer.sh=../../../../network/domr/,0755,/opt/cloud/bin
-l2tp_vpn.sh=../../../../network/domr/,0755,/opt/cloud/bin
 cloud-setup-bonding.sh=..,0755,/opt/cloud/bin
 copy_vhd_to_secondarystorage.sh=..,0755,/opt/cloud/bin
 copy_vhd_from_secondarystorage.sh=..,0755,/opt/cloud/bin
@@ -60,12 +53,7 @@ create_privatetemplate_from_snapshot.sh=..,0755,/opt/cloud/bin
 upgrade_snapshot.sh=..,0755,/opt/cloud/bin
 cloud-clean-vlan.sh=..,0755,/opt/cloud/bin
 cloud-prepare-upgrade.sh=..,0755,/opt/cloud/bin
-getRouterStatus.sh=../../../../network/domr/,0755,/opt/cloud/bin
-bumpUpPriority.sh=../../../../network/domr/,0755,/opt/cloud/bin
-getDomRVersion.sh=../../../../network/domr/,0755,/opt/cloud/bin
 router_proxy.sh=../../../../network/domr/,0755,/opt/cloud/bin
-createipAlias.sh=..,0755,/opt/cloud/bin
-deleteipAlias.sh=..,0755,/opt/cloud/bin
 
 ###add cloudstack plugin script for XCP
 cloudstack_plugins.conf=..,0644,/etc/xensource

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3e097a0f/scripts/vm/hypervisor/xenserver/xcpserver/patch
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/xenserver/xcpserver/patch b/scripts/vm/hypervisor/xenserver/xcpserver/patch
index 01cd73b..2376424 100644
--- a/scripts/vm/hypervisor/xenserver/xcpserver/patch
+++ b/scripts/vm/hypervisor/xenserver/xcpserver/patch
@@ -39,13 +39,7 @@ setupxenserver.sh=..,0755,/opt/cloud/bin
 make_migratable.sh=..,0755,/opt/cloud/bin
 setup_iscsi.sh=..,0755,/opt/cloud/bin
 pingtest.sh=../../..,0755,/opt/cloud/bin
-dhcp_entry.sh=../../../../network/domr/,0755,/opt/cloud/bin
-createipAlias.sh=..,0755,/opt/cloud/bin
-deleteipAlias.sh=..,0755,/opt/cloud/bin
 router_proxy.sh=../../../../network/domr/,0755,/opt/cloud/bin
-save_password_to_domr.sh=../../../../network/domr/,0755,/opt/cloud/bin
-call_firewall.sh=../../../../network/domr/,0755,/opt/cloud/bin
-call_loadbalancer.sh=../../../../network/domr/,0755,/opt/cloud/bin
 cloud-setup-bonding.sh=..,0755,/opt/cloud/bin
 copy_vhd_to_secondarystorage.sh=..,0755,/opt/cloud/bin
 copy_vhd_from_secondarystorage.sh=..,0755,/opt/cloud/bin
@@ -60,9 +54,6 @@ create_privatetemplate_from_snapshot.sh=..,0755,/opt/cloud/bin
 upgrade_snapshot.sh=..,0755,/opt/cloud/bin
 cloud-clean-vlan.sh=..,0755,/opt/cloud/bin
 cloud-prepare-upgrade.sh=..,0755,/opt/cloud/bin
-getRouterStatus.sh=../../../../network/domr/,0755,/opt/cloud/bin
-bumpUpPriority.sh=../../../../network/domr/,0755,/opt/cloud/bin
-getDomRVersion.sh=../../../../network/domr/,0755,/opt/cloud/bin
 add_to_vcpus_params_live.sh=..,0755,/opt/cloud/bin
 
 ###add cloudstack plugin script for XCP

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3e097a0f/scripts/vm/hypervisor/xenserver/xenserver56/patch
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/xenserver/xenserver56/patch b/scripts/vm/hypervisor/xenserver/xenserver56/patch
index 9473bca..16dcb57 100644
--- a/scripts/vm/hypervisor/xenserver/xenserver56/patch
+++ b/scripts/vm/hypervisor/xenserver/xenserver56/patch
@@ -39,12 +39,6 @@ make_migratable.sh=..,0755,/opt/cloud/bin
 setup_iscsi.sh=..,0755,/opt/cloud/bin
 cloud-setup-bonding.sh=..,0755,/opt/cloud/bin
 pingtest.sh=../../..,0755,/opt/cloud/bin
-createipAlias.sh=..,0755,/opt/cloud/bin
-deleteipAlias.sh=..,0755,/opt/cloud/bin
-dhcp_entry.sh=../../../../network/domr/,0755,/opt/cloud/bin
-save_password_to_domr.sh=../../../../network/domr/,0755,/opt/cloud/bin
-call_firewall.sh=../../../../network/domr/,0755,/opt/cloud/bin
-call_loadbalancer.sh=../../../../network/domr/,0755,/opt/cloud/bin
 router_proxy.sh=../../../../network/domr/,0755,/opt/cloud/bin
 copy_vhd_to_secondarystorage.sh=..,0755,/opt/cloud/bin
 copy_vhd_from_secondarystorage.sh=..,0755,/opt/cloud/bin
@@ -61,7 +55,6 @@ create_privatetemplate_from_snapshot.sh=..,0755,/opt/cloud/bin
 upgrade_snapshot.sh=..,0755,/opt/cloud/bin
 cloud-clean-vlan.sh=..,0755,/opt/cloud/bin
 cloud-prepare-upgrade.sh=..,0755,/opt/cloud/bin
-bumpUpPriority.sh=../../../../network/domr/,0755,/opt/cloud/bin
 swift=..,0755,/opt/cloud/bin
 swiftxen=..,0755,/etc/xapi.d/plugins
 s3xen=..,0755,/etc/xapi.d/plugins

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3e097a0f/scripts/vm/hypervisor/xenserver/xenserver56fp1/patch
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/xenserver/xenserver56fp1/patch b/scripts/vm/hypervisor/xenserver/xenserver56fp1/patch
index c91aa73..11bda07 100644
--- a/scripts/vm/hypervisor/xenserver/xenserver56fp1/patch
+++ b/scripts/vm/hypervisor/xenserver/xenserver56fp1/patch
@@ -38,12 +38,6 @@ setupxenserver.sh=..,0755,/opt/cloud/bin
 make_migratable.sh=..,0755,/opt/cloud/bin
 setup_iscsi.sh=..,0755,/opt/cloud/bin
 pingtest.sh=../../..,0755,/opt/cloud/bin
-createipAlias.sh=..,0755,/opt/cloud/bin
-deleteipAlias.sh=..,0755,/opt/cloud/bin
-dhcp_entry.sh=../../../../network/domr/,0755,/opt/cloud/bin
-save_password_to_domr.sh=../../../../network/domr/,0755,/opt/cloud/bin
-call_firewall.sh=../../../../network/domr/,0755,/opt/cloud/bin
-call_loadbalancer.sh=../../../../network/domr/,0755,/opt/cloud/bin
 router_proxy.sh=../../../../network/domr/,0755,/opt/cloud/bin
 cloud-setup-bonding.sh=..,0755,/opt/cloud/bin
 copy_vhd_to_secondarystorage.sh=..,0755,/opt/cloud/bin
@@ -60,7 +54,6 @@ create_privatetemplate_from_snapshot.sh=..,0755,/opt/cloud/bin
 upgrade_snapshot.sh=..,0755,/opt/cloud/bin
 cloud-clean-vlan.sh=..,0755,/opt/cloud/bin
 cloud-prepare-upgrade.sh=..,0755,/opt/cloud/bin
-bumpUpPriority.sh=../../../../network/domr/,0755,/opt/cloud/bin
 swift=..,0755,/opt/cloud/bin
 swiftxen=..,0755,/etc/xapi.d/plugins
 s3xen=..,0755,/etc/xapi.d/plugins

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3e097a0f/scripts/vm/hypervisor/xenserver/xenserver60/patch
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/xenserver/xenserver60/patch b/scripts/vm/hypervisor/xenserver/xenserver60/patch
index 5a648e0..662327b 100644
--- a/scripts/vm/hypervisor/xenserver/xenserver60/patch
+++ b/scripts/vm/hypervisor/xenserver/xenserver60/patch
@@ -40,14 +40,8 @@ id_rsa.cloud=../../../systemvm,0600,/root/.ssh
 network_info.sh=..,0755,/opt/cloud/bin
 setupxenserver.sh=..,0755,/opt/cloud/bin
 make_migratable.sh=..,0755,/opt/cloud/bin
-createipAlias.sh=..,0755,/opt/cloud/bin
-deleteipAlias.sh=..,0755,/opt/cloud/bin
 setup_iscsi.sh=..,0755,/opt/cloud/bin
 pingtest.sh=../../..,0755,/opt/cloud/bin
-dhcp_entry.sh=../../../../network/domr/,0755,/opt/cloud/bin
-save_password_to_domr.sh=../../../../network/domr/,0755,/opt/cloud/bin
-call_firewall.sh=../../../../network/domr/,0755,/opt/cloud/bin
-call_loadbalancer.sh=../../../../network/domr/,0755,/opt/cloud/bin
 router_proxy.sh=../../../../network/domr/,0755,/opt/cloud/bin
 cloud-setup-bonding.sh=..,0755,/opt/cloud/bin
 copy_vhd_to_secondarystorage.sh=..,0755,/opt/cloud/bin
@@ -64,7 +58,6 @@ create_privatetemplate_from_snapshot.sh=..,0755,/opt/cloud/bin
 upgrade_snapshot.sh=..,0755,/opt/cloud/bin
 cloud-clean-vlan.sh=..,0755,/opt/cloud/bin
 cloud-prepare-upgrade.sh=..,0755,/opt/cloud/bin
-bumpUpPriority.sh=../../../../network/domr/,0755,/opt/cloud/bin
 swift=..,0755,/opt/cloud/bin
 swiftxen=..,0755,/etc/xapi.d/plugins
 s3xen=..,0755,/etc/xapi.d/plugins

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/3e097a0f/scripts/vm/hypervisor/xenserver/xenserver62/patch
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/xenserver/xenserver62/patch b/scripts/vm/hypervisor/xenserver/xenserver62/patch
index 70b86b4..05c619b 100644
--- a/scripts/vm/hypervisor/xenserver/xenserver62/patch
+++ b/scripts/vm/hypervisor/xenserver/xenserver62/patch
@@ -40,14 +40,8 @@ id_rsa.cloud=../../../systemvm,0600,/root/.ssh
 network_info.sh=..,0755,/opt/cloud/bin
 setupxenserver.sh=..,0755,/opt/cloud/bin
 make_migratable.sh=..,0755,/opt/cloud/bin
-createipAlias.sh=..,0755,/opt/cloud/bin
-deleteipAlias.sh=..,0755,/opt/cloud/bin
 setup_iscsi.sh=..,0755,/opt/cloud/bin
 pingtest.sh=../../..,0755,/opt/cloud/bin
-dhcp_entry.sh=../../../../network/domr/,0755,/opt/cloud/bin
-save_password_to_domr.sh=../../../../network/domr/,0755,/opt/cloud/bin
-call_firewall.sh=../../../../network/domr/,0755,/opt/cloud/bin
-call_loadbalancer.sh=../../../../network/domr/,0755,/opt/cloud/bin
 router_proxy.sh=../../../../network/domr/,0755,/opt/cloud/bin
 cloud-setup-bonding.sh=..,0755,/opt/cloud/bin
 kill_copy_process.sh=..,0755,/opt/cloud/bin
@@ -60,7 +54,6 @@ vhd-util=..,0755,/opt/cloud/bin
 upgrade_snapshot.sh=..,0755,/opt/cloud/bin
 cloud-clean-vlan.sh=..,0755,/opt/cloud/bin
 cloud-prepare-upgrade.sh=..,0755,/opt/cloud/bin
-bumpUpPriority.sh=../../../../network/domr/,0755,/opt/cloud/bin
 swift=..,0755,/opt/cloud/bin
 swiftxen=..,0755,/etc/xapi.d/plugins
 s3xen=..,0755,/etc/xapi.d/plugins


[02/31] git commit: updated refs/heads/distributedrouter to a8d43ba

Posted by mu...@apache.org.
CLOUDSTACK-6226: UI > multi widget > dropdown field > translate option value.


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

Branch: refs/heads/distributedrouter
Commit: 415e4bffd652d0a92b36cc6ff1bec0e3ea0462da
Parents: c874e20
Author: Jessica Wang <je...@apache.org>
Authored: Tue Mar 11 11:18:49 2014 -0700
Committer: Jessica Wang <je...@apache.org>
Committed: Tue Mar 11 11:19:00 2014 -0700

----------------------------------------------------------------------
 ui/scripts/ui/widgets/multiEdit.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/415e4bff/ui/scripts/ui/widgets/multiEdit.js
----------------------------------------------------------------------
diff --git a/ui/scripts/ui/widgets/multiEdit.js b/ui/scripts/ui/widgets/multiEdit.js
index 873775d..713ebde 100755
--- a/ui/scripts/ui/widgets/multiEdit.js
+++ b/ui/scripts/ui/widgets/multiEdit.js
@@ -927,7 +927,7 @@
                     response: {
                         success: function(args) {
                             $(args.data).each(function() {
-                                $('<option>').val(this.name).html(_s(this.description))
+                                $('<option>').val(this.name).html(_l(_s(this.description)))
                                     .appendTo($select);
                             });
                             _medit.refreshItemWidths($multi);


[19/31] git commit: updated refs/heads/distributedrouter to a8d43ba

Posted by mu...@apache.org.
findbugs: impossible cast in CreateServiceOfferingCmd file.


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

Branch: refs/heads/distributedrouter
Commit: bc4c8052fdd5bd962d107a9796f422867c8cfeb3
Parents: 3ee1fc2
Author: Sanjay Tripathi <sa...@citrix.com>
Authored: Thu Mar 13 15:02:08 2014 +0530
Committer: Sanjay Tripathi <sa...@citrix.com>
Committed: Thu Mar 13 15:04:18 2014 +0530

----------------------------------------------------------------------
 .../command/admin/offering/CreateServiceOfferingCmd.java    | 8 +++-----
 ui/scripts/configuration.js                                 | 9 ++++++---
 2 files changed, 9 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bc4c8052/api/src/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java b/api/src/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java
index 42bd95d..78101fb 100644
--- a/api/src/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/admin/offering/CreateServiceOfferingCmd.java
@@ -21,17 +21,15 @@ import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
 
-import org.apache.log4j.Logger;
-
 import org.apache.cloudstack.api.APICommand;
 import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.ApiErrorCode;
 import org.apache.cloudstack.api.BaseCmd;
 import org.apache.cloudstack.api.Parameter;
 import org.apache.cloudstack.api.ServerApiException;
-import org.apache.cloudstack.api.BaseCmd.CommandType;
 import org.apache.cloudstack.api.response.DomainResponse;
 import org.apache.cloudstack.api.response.ServiceOfferingResponse;
+import org.apache.log4j.Logger;
 
 import com.cloud.offering.ServiceOffering;
 import com.cloud.user.Account;
@@ -106,7 +104,7 @@ public class CreateServiceOfferingCmd extends BaseCmd {
     private String deploymentPlanner;
 
     @Parameter(name = ApiConstants.SERVICE_OFFERING_DETAILS, type = CommandType.MAP, description = "details for planner, used to store specific parameters")
-    private Map<String, String> details;
+    private Map details;
 
     @Parameter(name = ApiConstants.BYTES_READ_RATE, type = CommandType.LONG, required = false, description = "bytes read rate of the disk offering")
     private Long bytesReadRate;
@@ -215,7 +213,7 @@ public class CreateServiceOfferingCmd extends BaseCmd {
             Iterator<?> iter = props.iterator();
             while (iter.hasNext()) {
                 HashMap<String, String> detail = (HashMap<String, String>) iter.next();
-                detailsMap.putAll(detail);
+                detailsMap.put(detail.get("key"), detail.get("value"));
             }
         }
         return detailsMap;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/bc4c8052/ui/scripts/configuration.js
----------------------------------------------------------------------
diff --git a/ui/scripts/configuration.js b/ui/scripts/configuration.js
index 8666042..7b2f4e9 100644
--- a/ui/scripts/configuration.js
+++ b/ui/scripts/configuration.js
@@ -490,15 +490,18 @@
 
                                 var array1 = [];
                                 if (args.data.deploymentPlanner == "ImplicitDedicationPlanner" && args.data.plannerMode != "") {
-                                    array1.push("&serviceofferingdetails[0].ImplicitDedicationMode" + "=" + args.data.plannerMode);
+                                    array1.push("&serviceofferingdetails[0].key" + "=" + "ImplicitDedicationMode");
+                                    array1.push("&serviceofferingdetails[0].value" + "=" + args.data.plannerMode);
                                 }
 
                                 if (args.data.pciDevice != "") {
-                                    array1.push("&serviceofferingdetails[1].pciDevice" + "=" + args.data.pciDevice);
+                                    array1.push("&serviceofferingdetails[1].key" + "=" + "pciDevice");
+                                    array1.push("&serviceofferingdetails[1].value" + "=" + args.data.pciDevice);
                                 }
 
                                 if (args.data.pciDevice == "VGPU") {
-                                    array1.push("&serviceofferingdetails[2].vgpuType" + "=" + args.data.vgpuType);
+                                    array1.push("&serviceofferingdetails[2].key" + "=" + "vgpuType");
+                                    array1.push("&serviceofferingdetails[2].value" + "=" + args.data.vgpuType);
                                 }
 
                                 if (args.data.networkRate != null && args.data.networkRate.length > 0) {


[21/31] git commit: updated refs/heads/distributedrouter to a8d43ba

Posted by mu...@apache.org.
-add check to ensure 'Connectivity' service provider specified in
createVpcOffering actually supports 'DistributedRouter' capability

- enable OVS to support 'DistributedRouter' capability


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

Branch: refs/heads/distributedrouter
Commit: 6c1a158cd9021e6f467ff46cae226d41f4dea009
Parents: 85c9b09
Author: Murali Reddy <mu...@gmail.com>
Authored: Tue Mar 4 17:17:18 2014 +0530
Committer: Murali Reddy <mu...@gmail.com>
Committed: Thu Mar 13 19:22:06 2014 +0530

----------------------------------------------------------------------
 .../com/cloud/network/element/OvsElement.java   |  5 +-
 .../com/cloud/network/vpc/VpcManagerImpl.java   | 52 ++++++++++++++++++++
 2 files changed, 56 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6c1a158c/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java b/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java
index 03eeedd..05e81a1 100644
--- a/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java
+++ b/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java
@@ -246,7 +246,10 @@ StaticNatServiceProvider, IpDeployer {
         Map<Service, Map<Capability, String>> capabilities = new HashMap<Service, Map<Capability, String>>();
 
         // L2 Support : SDN provisioning
-        capabilities.put(Service.Connectivity, null);
+        Map<Capability, String> connectivityCapabilities = new HashMap<Capability, String>();
+        connectivityCapabilities.put(Capability.DistributedRouter, null);
+        capabilities.put(Service.Connectivity, connectivityCapabilities);
+
 
         // L3 Support : Port Forwarding
         capabilities.put(Service.PortForwarding, null);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6c1a158c/server/src/com/cloud/network/vpc/VpcManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java
index ac82041..36eb444 100644
--- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java
+++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java
@@ -65,6 +65,7 @@ import com.cloud.exception.PermissionDeniedException;
 import com.cloud.exception.ResourceAllocationException;
 import com.cloud.exception.ResourceUnavailableException;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.network.element.NetworkElement;
 import com.cloud.network.IpAddress;
 import com.cloud.network.IpAddressManager;
 import com.cloud.network.Network;
@@ -376,6 +377,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
             }
         }
 
+        validateConnectivtyServiceCapablitlies(svcProviderMap.get(Service.Connectivity), serviceCapabilitystList);
         boolean supportsDistributedRouter = isVpcOfferingSupportsDistributedRouter(serviceCapabilitystList);
 
         VpcOffering offering = createVpcOffering(name, displayText, svcProviderMap, false, null,
@@ -460,6 +462,56 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
         return supportsDistributedRouter;
     }
 
+    private void validateConnectivtyServiceCapablitlies(Set<Provider> providers, Map serviceCapabilitystList) {
+
+        if (serviceCapabilitystList != null && !serviceCapabilitystList.isEmpty()) {
+            Collection serviceCapabilityCollection = serviceCapabilitystList.values();
+            Iterator iter = serviceCapabilityCollection.iterator();
+            Map<Network.Capability, String> capabilityMap = null;
+
+            while (iter.hasNext()) {
+                HashMap<String, String> svcCapabilityMap = (HashMap<String, String>)iter.next();
+                Network.Capability capability = null;
+                String svc = svcCapabilityMap.get("service");
+                String capabilityName = svcCapabilityMap.get("capabilitytype");
+                String capabilityValue = svcCapabilityMap.get("capabilityvalue");
+                if (capabilityName != null) {
+                    capability = Network.Capability.getCapability(capabilityName);
+                }
+
+                if ((capability == null) || (capabilityName == null) || (capabilityValue == null)) {
+                    throw new InvalidParameterValueException("Invalid capability:" + capabilityName + " capability value:" + capabilityValue);
+                }
+
+                if (!svc.equalsIgnoreCase(Service.Connectivity.getName())) {
+                    throw new InvalidParameterValueException("Invalid Service:" + svc + " specified. Only for 'Connectivity' service capabilities can be specified");
+                }
+
+                if (!capabilityName.equalsIgnoreCase("DistributedRouter")) {
+                    throw new InvalidParameterValueException("Invalid Capability:" + capabilityName + " specified. Only 'DistributedRouter' capability can be specified.");
+                }
+
+                if (!capabilityValue.equalsIgnoreCase("true") && capabilityValue.equalsIgnoreCase("false")) {
+                    throw new InvalidParameterValueException("Invalid Capability value:" + capabilityValue + " specified.");
+                }
+            }
+
+            if (providers != null && !providers.isEmpty()) {
+                for (Provider provider: providers) {
+                    NetworkElement element = _ntwkModel.getElementImplementingProvider(provider.getName());
+                    Map<Service, Map<Network.Capability, String>> capabilities = element.getCapabilities();
+                    if (capabilities != null && !capabilities.isEmpty()) {
+                        Map<Network.Capability, String> connectivityCapabilities =  capabilities.get(Service.Connectivity);
+                        if (connectivityCapabilities == null || (connectivityCapabilities != null && !connectivityCapabilities.keySet().contains(Network.Capability.DistributedRouter))) {
+                            throw new InvalidParameterValueException("Provider: " + provider.getName() + " does not support "
+                                    + Network.Capability.DistributedRouter.getName() + " capability.");
+                        }
+                    }
+                }
+            }
+        }
+    }
+
     @Override
     public Vpc getActiveVpc(long vpcId) {
         return _vpcDao.getActiveVpcById(vpcId);


[25/31] git commit: updated refs/heads/distributedrouter to a8d43ba

Posted by mu...@apache.org.
introduce OvsNetworkTopologyGuru that has convinenace functions to
   - get the hosts on which VPC spans given vpc id
   - get the VM's in the VPC
   - get the hosts on which a network spans
   - get the VPC's to which a hosts is part of
   - get VM's of a VPC on a hosts

introduces capability to build a physical toplogy representation of a
VPC. This json file is encapsulated in
OvsVpcPhysicalTopologyConfigCommand, and is used to send full topology
to hypervisor hosts. On hypervisor this json config can be used to setup
tunnels, configure bridge, add flow rules etc

Ovs GURU, to use different broasdcast scheme VS://vpcid.gerkey for the
networks in VPC that use distributed routing

each VIF and tunnel interface to carry the network UUID in other/options
config


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

Branch: refs/heads/distributedrouter
Commit: b080611afa13c341bea3812c97b0957190bc9b3b
Parents: 136796e
Author: Murali Reddy <mu...@gmail.com>
Authored: Mon Mar 10 12:52:30 2014 +0530
Committer: Murali Reddy <mu...@gmail.com>
Committed: Thu Mar 13 19:22:08 2014 +0530

----------------------------------------------------------------------
 api/src/com/cloud/agent/api/to/NicTO.java       |   8 +
 .../kvm/resource/LibvirtComputingResource.java  |  34 +-
 .../xen/resource/CitrixResourceBase.java        |  95 +++--
 .../cloudstack/ovs/spring-ovs-context.xml       |   2 +-
 .../cloud/agent/api/OvsCreateTunnelCommand.java |  19 +-
 .../agent/api/OvsDestroyBridgeCommand.java      |  10 +-
 .../agent/api/OvsDestroyTunnelCommand.java      |  10 +-
 .../cloud/agent/api/OvsSetupBridgeCommand.java  |  10 +-
 .../OvsVpcPhysicalTopologyConfigCommand.java    | 127 +++++++
 .../com/cloud/network/element/OvsElement.java   |  35 +-
 .../cloud/network/guru/OvsGuestNetworkGuru.java |  17 +-
 .../network/ovs/OvsNetworkTopologyGuru.java     |  49 +++
 .../network/ovs/OvsNetworkTopologyGuruImpl.java |  74 ++++
 .../com/cloud/network/ovs/OvsTunnelManager.java |  16 +-
 .../cloud/network/ovs/OvsTunnelManagerImpl.java | 356 ++++++++++++++-----
 .../com/cloud/network/ovs/dao/OvsTunnel.java    |  24 ++
 .../network/ovs/dao/OvsTunnelNetworkVO.java     |   2 +-
 scripts/vm/hypervisor/xenserver/ovstunnel       |   2 +
 .../cloud/hypervisor/HypervisorGuruBase.java    |   7 +
 19 files changed, 737 insertions(+), 160 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b080611a/api/src/com/cloud/agent/api/to/NicTO.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/agent/api/to/NicTO.java b/api/src/com/cloud/agent/api/to/NicTO.java
index bd8f24e..67660c8 100644
--- a/api/src/com/cloud/agent/api/to/NicTO.java
+++ b/api/src/com/cloud/agent/api/to/NicTO.java
@@ -80,4 +80,12 @@ public class NicTO extends NetworkTO {
     public List<String> getNicSecIps() {
         return nicSecIps;
     }
+
+    public String getNetworkUuid() {
+        return super.getUuid();
+    }
+
+    public void setNetworkUuid(String uuid) {
+        super.setUuid(uuid);
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b080611a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
index 3a5d27c..e44bd87 100755
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
@@ -1388,23 +1388,22 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
     }
 
     private Answer execute(OvsSetupBridgeCommand cmd) {
-        findOrCreateTunnelNetwork(cmd.getKey());
+        findOrCreateTunnelNetwork(cmd.getBridgeName());
         configureTunnelNetwork(cmd.getNetworkId(), cmd.getHostId(),
-                cmd.getKey());
+                cmd.getBridgeName());
         s_logger.debug("OVS Bridge configured");
         return new Answer(cmd, true, null);
     }
 
     private Answer execute(OvsDestroyBridgeCommand cmd) {
-        destroyTunnelNetwork(cmd.getKey());
+        destroyTunnelNetwork(cmd.getBridgeName());
         s_logger.debug("OVS Bridge destroyed");
         return new Answer(cmd, true, null);
     }
 
-    private synchronized void destroyTunnelNetwork(int key) {
+    private synchronized void destroyTunnelNetwork(String bridge) {
         try {
-            findOrCreateTunnelNetwork(key);
-            String bridge = "OVSTunnel" + key;
+            findOrCreateTunnelNetwork(bridge);
             Script cmd = new Script(_ovsTunnelPath, _timeout, s_logger);
             cmd.add("destroy_ovs_bridge");
             cmd.add("--bridge", bridge);
@@ -1423,9 +1422,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
         }
     }
 
-    private synchronized boolean findOrCreateTunnelNetwork(long key) {
+    private synchronized boolean findOrCreateTunnelNetwork(String nwName) {
         try {
-            String nwName = "OVSTunnel" + key;
             if (checkNetwork(nwName)) {
                 return true;
             }
@@ -1443,10 +1441,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
     }
 
     private synchronized boolean configureTunnelNetwork(long networkId,
-            long hostId, int key) {
+            long hostId, String nwName) {
         try {
-            findOrCreateTunnelNetwork(key);
-            String nwName = "OVSTunnel" + key;
+            findOrCreateTunnelNetwork(nwName);
             String configuredHosts = Script
                     .runSimpleBashScript("ovs-vsctl get bridge " + nwName
                             + " other_config:ovs_host_setup");
@@ -1463,7 +1460,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
             if (!configured) {
                 Script cmd = new Script(_ovsTunnelPath, _timeout, s_logger);
                 cmd.add("setup_ovs_bridge");
-                cmd.add("--key", String.valueOf(key));
+                cmd.add("--key", nwName);
                 cmd.add("--cs_host_id", ((Long)hostId).toString());
                 cmd.add("--bridge", nwName);
                 String result = cmd.execute();
@@ -1481,16 +1478,16 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
     }
 
     private OvsCreateTunnelAnswer execute(OvsCreateTunnelCommand cmd) {
-        String bridge = "OVSTunnel" + cmd.getKey();
+        String bridge = cmd.getNetworkName();
         try {
-            if (!findOrCreateTunnelNetwork(cmd.getKey())) {
+            if (!findOrCreateTunnelNetwork(bridge)) {
                 s_logger.debug("Error during bridge setup");
                 return new OvsCreateTunnelAnswer(cmd, false,
                         "Cannot create network", bridge);
             }
 
             configureTunnelNetwork(cmd.getNetworkId(), cmd.getFrom(),
-                    cmd.getKey());
+                    cmd.getNetworkName());
             Script command = new Script(_ovsTunnelPath, _timeout, s_logger);
             command.add("create_tunnel");
             command.add("--bridge", bridge);
@@ -1515,16 +1512,15 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
 
     private Answer execute(OvsDestroyTunnelCommand cmd) {
         try {
-            if (!findOrCreateTunnelNetwork(cmd.getKey())) {
+            if (!findOrCreateTunnelNetwork(cmd.getBridgeName())) {
                 s_logger.warn("Unable to find tunnel network for GRE key:"
-                        + cmd.getKey());
+                        + cmd.getBridgeName());
                 return new Answer(cmd, false, "No network found");
             }
 
-            String bridge = "OVSTunnel" + cmd.getKey();
             Script command = new Script(_ovsTunnelPath, _timeout, s_logger);
             command.add("destroy_tunnel");
-            command.add("--bridge", bridge);
+            command.add("--bridge", cmd.getBridgeName());
             command.add("--iface_name", cmd.getInPortName());
             String result = command.execute();
             if (result == null) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b080611a/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 d80bddc..8585996 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
@@ -147,6 +147,7 @@ import com.cloud.agent.api.OvsFetchInterfaceCommand;
 import com.cloud.agent.api.OvsSetTagAndFlowAnswer;
 import com.cloud.agent.api.OvsSetTagAndFlowCommand;
 import com.cloud.agent.api.OvsSetupBridgeCommand;
+import com.cloud.agent.api.OvsVpcPhysicalTopologyConfigCommand;
 import com.cloud.agent.api.PerformanceMonitorAnswer;
 import com.cloud.agent.api.PerformanceMonitorCommand;
 import com.cloud.agent.api.PingCommand;
@@ -506,6 +507,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
             return execute((OvsSetTagAndFlowCommand)cmd);
         } else if (clazz == OvsDeleteFlowCommand.class) {
             return execute((OvsDeleteFlowCommand)cmd);
+        } else if (clazz == OvsVpcPhysicalTopologyConfigCommand.class) {
+            return execute((OvsVpcPhysicalTopologyConfigCommand) cmd);
         } else if (clazz == CleanupNetworkRulesCmd.class) {
             return execute((CleanupNetworkRulesCmd)cmd);
         } else if (clazz == NetworkRulesSystemVmCommand.class) {
@@ -963,15 +966,14 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
     /**
      * This method just creates a XenServer network following the tunnel network naming convention
      */
-    private synchronized Network findOrCreateTunnelNetwork(Connection conn, long key) {
+    private synchronized Network findOrCreateTunnelNetwork(Connection conn, String nwName) {
         try {
-            String nwName = "OVSTunnel" + key;
             Network nw = null;
             Network.Record rec = new Network.Record();
             Set<Network> networks = Network.getByNameLabel(conn, nwName);
 
             if (networks.size() == 0) {
-                rec.nameDescription = "tunnel network id# " + key;
+                rec.nameDescription = "tunnel network id# " + nwName;
                 rec.nameLabel = nwName;
                 //Initialize the ovs-host-setup to avoid error when doing get-param in plugin
                 Map<String, String> otherConfig = new HashMap<String, String>();
@@ -980,7 +982,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
                 nw = Network.create(conn, rec);
                 // Plug dom0 vif only when creating network
                 if (!is_xcp())
-                    enableXenServerNetwork(conn, nw, nwName, "tunnel network for account " + key);
+                    enableXenServerNetwork(conn, nw, nwName, "tunnel network for account " + nwName);
                 s_logger.debug("### Xen Server network for tunnels created:" + nwName);
             } else {
                 nw = networks.iterator().next();
@@ -996,10 +998,10 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
     /**
      * This method creates a XenServer network and configures it for being used as a L2-in-L3 tunneled network
      */
-    private synchronized Network configureTunnelNetwork(Connection conn, long networkId, long hostId, int key) {
+    private synchronized Network configureTunnelNetwork(Connection conn, long networkId, long hostId, String bridgeName) {
         try {
-            Network nw = findOrCreateTunnelNetwork(conn, key);
-            String nwName = "OVSTunnel" + key;
+            Network nw = findOrCreateTunnelNetwork(conn, bridgeName);
+            String nwName = bridgeName;
             //Invoke plugin to setup the bridge which will be used by this network
             String bridge = nw.getBridge(conn);
             Map<String, String> nwOtherConfig = nw.getOtherConfig(conn);
@@ -1017,11 +1019,20 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
             if (!configured) {
                 // Plug dom0 vif only if not done before for network and host
                 if (!is_xcp())
-                    enableXenServerNetwork(conn, nw, nwName, "tunnel network for account " + key);
-                String result = callHostPlugin(conn, "ovstunnel", "setup_ovs_bridge", "bridge", bridge,
-                        "key", String.valueOf(key),
-                        "xs_nw_uuid", nw.getUuid(conn),
-                        "cs_host_id", ((Long)hostId).toString());
+                    enableXenServerNetwork(conn, nw, nwName, "tunnel network for account " + bridgeName);
+                String result;
+                if (bridgeName.startsWith("OVS-DR-VPC-Bridge")) {
+                    result = callHostPlugin(conn, "ovstunnel", "setup_ovs_bridge_for_distributed_routing", "bridge", bridge,
+                            "key", bridgeName,
+                            "xs_nw_uuid", nw.getUuid(conn),
+                            "cs_host_id", ((Long)hostId).toString());
+                } else {
+                    result = callHostPlugin(conn, "ovstunnel", "setup_ovs_bridge", "bridge", bridge,
+                            "key", bridgeName,
+                            "xs_nw_uuid", nw.getUuid(conn),
+                            "cs_host_id", ((Long)hostId).toString());
+                }
+
                 //Note down the fact that the ovs bridge has been setup
                 String[] res = result.split(":");
                 if (res.length != 2 || !res[0].equalsIgnoreCase("SUCCESS")) {
@@ -1036,9 +1047,9 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
         }
     }
 
-    private synchronized void destroyTunnelNetwork(Connection conn, int key) {
+    private synchronized void destroyTunnelNetwork(Connection conn, String bridgeName) {
         try {
-            Network nw = findOrCreateTunnelNetwork(conn, key);
+            Network nw = findOrCreateTunnelNetwork(conn, bridgeName);
             String bridge = nw.getBridge(conn);
             String result = callHostPlugin(conn, "ovstunnel", "destroy_ovs_bridge", "bridge", bridge);
             String[] res = result.split(":");
@@ -1078,8 +1089,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
                 _isOvs = true;
                 return setupvSwitchNetwork(conn);
             } else {
-                long vnetId = Long.parseLong(BroadcastDomainType.getValue(uri));
-                return findOrCreateTunnelNetwork(conn, vnetId);
+                return findOrCreateTunnelNetwork(conn, getOvsTunnelNetworkName(BroadcastDomainType.getValue(uri)));
             }
         } else if (type == BroadcastDomainType.Storage) {
             if (uri == null) {
@@ -1101,6 +1111,19 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
         throw new CloudRuntimeException("Unable to support this type of network broadcast domain: " + nic.getBroadcastUri());
     }
 
+    private String getOvsTunnelNetworkName(String broadcastUri) {
+        if (broadcastUri.contains(".")) {
+            String[] parts = broadcastUri.split(".");
+            return "OVS-DR-VPC-Bridge"+parts[0];
+         } else {
+            try {
+                return "OVSTunnel" + broadcastUri;
+            } catch (Exception e) {
+                return null;
+            }
+         }
+    }
+
     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";
 
@@ -1121,7 +1144,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
         if (vmSpec != null) {
             vifr.otherConfig.put("cloudstack-vm-id", vmSpec.getUuid());
         }
-
+        vifr.otherConfig.put("cloudstack-network-id", nic.getNetworkUuid());
         vifr.network = getNetwork(conn, nic);
 
         if (nic.getNetworkRateMbps() != null && nic.getNetworkRateMbps().intValue() != -1) {
@@ -5219,15 +5242,15 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
 
     private Answer execute(OvsSetupBridgeCommand cmd) {
         Connection conn = getConnection();
-        findOrCreateTunnelNetwork(conn, cmd.getKey());
-        configureTunnelNetwork(conn, cmd.getNetworkId(), cmd.getHostId(), cmd.getKey());
+        findOrCreateTunnelNetwork(conn, cmd.getBridgeName());
+        configureTunnelNetwork(conn, cmd.getNetworkId(), cmd.getHostId(), cmd.getBridgeName());
         s_logger.debug("OVS Bridge configured");
         return new Answer(cmd, true, null);
     }
 
     private Answer execute(OvsDestroyBridgeCommand cmd) {
         Connection conn = getConnection();
-        destroyTunnelNetwork(conn, cmd.getKey());
+        destroyTunnelNetwork(conn, cmd.getBridgeName());
         s_logger.debug("OVS Bridge destroyed");
         return new Answer(cmd, true, null);
     }
@@ -5235,14 +5258,14 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
     private Answer execute(OvsDestroyTunnelCommand cmd) {
         Connection conn = getConnection();
         try {
-            Network nw = findOrCreateTunnelNetwork(conn, cmd.getNetworkId());
+            Network nw = findOrCreateTunnelNetwork(conn, cmd.getBridgeName());
             if (nw == null) {
-                s_logger.warn("Unable to find tunnel network for GRE key:" + cmd.getKey());
+                s_logger.warn("Unable to find tunnel network for GRE key:" + cmd.getBridgeName());
                 return new Answer(cmd, false, "No network found");
             }
 
             String bridge = nw.getBridge(conn);
-            String result = callHostPlugin(conn, "ovstunnel", "destroy_tunnel", "bridge", bridge, "in_port", cmd.getInPortName());
+            String result = callHostPlugin(conn, "ovstunnel", "configure_ovs_bridge_for_network_topology", "bridge", bridge, "in_port", cmd.getInPortName());
             if (result.equalsIgnoreCase("SUCCESS")) {
                 return new Answer(cmd, true, result);
             } else {
@@ -5254,6 +5277,22 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
         }
     }
 
+    public Answer execute(OvsVpcPhysicalTopologyConfigCommand cmd) {
+        Connection conn = getConnection();
+        try {
+            String result = callHostPlugin(conn, "ovstunnel", "configure_ovs_bridge_for_network_topology", "bridge",
+                    cmd.getBridgeName(), "host-id", ((Long)cmd.getHostId()).toString());
+            if (result.equalsIgnoreCase("SUCCESS")) {
+                return new Answer(cmd, true, result);
+            } else {
+                return new Answer(cmd, false, result);
+            }
+        } catch  (Exception e) {
+            s_logger.warn("caught exception while updating host with latest VPC topology", e);
+            return new Answer(cmd, false, e.getMessage());
+        }
+    }
+
     private Answer execute(UpdateHostPasswordCommand cmd) {
         _password.add(cmd.getNewPassword());
         return new Answer(cmd, true, null);
@@ -5263,17 +5302,19 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
         Connection conn = getConnection();
         String bridge = "unknown";
         try {
-            Network nw = findOrCreateTunnelNetwork(conn, cmd.getKey());
+            Network nw = findOrCreateTunnelNetwork(conn, cmd.getNetworkName());
             if (nw == null) {
                 s_logger.debug("Error during bridge setup");
                 return new OvsCreateTunnelAnswer(cmd, false, "Cannot create network", bridge);
             }
 
-            configureTunnelNetwork(conn, cmd.getNetworkId(), cmd.getFrom(), cmd.getKey());
+            configureTunnelNetwork(conn, cmd.getNetworkId(), cmd.getFrom(), cmd.getNetworkName());
             bridge = nw.getBridge(conn);
             String result =
-                    callHostPlugin(conn, "ovstunnel", "create_tunnel", "bridge", bridge, "remote_ip", cmd.getRemoteIp(), "key", cmd.getKey().toString(), "from",
-                            cmd.getFrom().toString(), "to", cmd.getTo().toString());
+                    callHostPlugin(conn, "ovstunnel", "create_tunnel", "bridge", bridge, "remote_ip", cmd.getRemoteIp(),
+                            "key", cmd.getKey().toString(), "from",
+                            cmd.getFrom().toString(), "to", cmd.getTo().toString(), "cloudstack-network-id",
+                            cmd.getNetworkUuid());
             String[] res = result.split(":");
             if (res.length == 2 && res[0].equalsIgnoreCase("SUCCESS")) {
                 return new OvsCreateTunnelAnswer(cmd, true, result, res[1], bridge);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b080611a/plugins/network-elements/ovs/resources/META-INF/cloudstack/ovs/spring-ovs-context.xml
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/resources/META-INF/cloudstack/ovs/spring-ovs-context.xml b/plugins/network-elements/ovs/resources/META-INF/cloudstack/ovs/spring-ovs-context.xml
index e60d93e..fa56d5d 100644
--- a/plugins/network-elements/ovs/resources/META-INF/cloudstack/ovs/spring-ovs-context.xml
+++ b/plugins/network-elements/ovs/resources/META-INF/cloudstack/ovs/spring-ovs-context.xml
@@ -38,5 +38,5 @@
     <bean id="ovsTunnelManagerImpl" class="com.cloud.network.ovs.OvsTunnelManagerImpl" />
     <bean id="ovsTunnelInterfaceDaoImpl" class="com.cloud.network.ovs.dao.OvsTunnelInterfaceDaoImpl" />
     <bean id="ovsTunnelNetworkDaoImpl" class="com.cloud.network.ovs.dao.OvsTunnelNetworkDaoImpl" />
-    
+    <bean id="ovsNetworkTopologyGuruImpl" class="com.cloud.network.ovs.OvsNetworkTopologyGuruImpl"/>
 </beans>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b080611a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsCreateTunnelCommand.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsCreateTunnelCommand.java b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsCreateTunnelCommand.java
index 7f151fb..3e08531 100644
--- a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsCreateTunnelCommand.java
+++ b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsCreateTunnelCommand.java
@@ -20,10 +20,13 @@ package com.cloud.agent.api;
 public class OvsCreateTunnelCommand extends Command {
     Integer key;
     String remoteIp;
+    String networkName;
     Long from;
     Long to;
     long networkId;
 
+    String networkUuid;
+
     // for debug info
     String fromIp;
 
@@ -33,13 +36,15 @@ public class OvsCreateTunnelCommand extends Command {
     }
 
     public OvsCreateTunnelCommand(String remoteIp, Integer key, Long from,
-            Long to, long networkId, String fromIp) {
+            Long to, long networkId, String fromIp, String networkName, String networkUuid) {
         this.remoteIp = remoteIp;
         this.key = key;
         this.from = from;
         this.to = to;
         this.networkId = networkId;
         this.fromIp = fromIp;
+        this.networkName = networkName;
+        this.networkUuid = networkUuid;
     }
 
     public Integer getKey() {
@@ -66,4 +71,16 @@ public class OvsCreateTunnelCommand extends Command {
         return fromIp;
     }
 
+    public String getNetworkName() {
+        return networkName;
+    }
+
+
+    public String getNetworkUuid() {
+        return networkUuid;
+    }
+
+    public void setNetworkUuid(String networkUuid) {
+        this.networkUuid = networkUuid;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b080611a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsDestroyBridgeCommand.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsDestroyBridgeCommand.java b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsDestroyBridgeCommand.java
index 59b50be..f9205c5 100644
--- a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsDestroyBridgeCommand.java
+++ b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsDestroyBridgeCommand.java
@@ -21,19 +21,19 @@ package com.cloud.agent.api;
 public class OvsDestroyBridgeCommand extends Command {
 
     Long networkId;
-    Integer key;
+    String name;
 
-    public OvsDestroyBridgeCommand(Long networkId, Integer key) {
+    public OvsDestroyBridgeCommand(Long networkId, String name) {
         this.networkId = networkId;
-        this.key = key;
+        this.name = name;
     }
 
     public Long getNetworkId() {
         return networkId;
     }
 
-    public Integer getKey() {
-        return key;
+    public String getBridgeName() {
+        return name;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b080611a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsDestroyTunnelCommand.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsDestroyTunnelCommand.java b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsDestroyTunnelCommand.java
index 4776a07..9fc6c37 100644
--- a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsDestroyTunnelCommand.java
+++ b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsDestroyTunnelCommand.java
@@ -20,14 +20,14 @@ package com.cloud.agent.api;
 public class OvsDestroyTunnelCommand extends Command {
 
     Long networkId;
-    Integer key;
+    String networkName;
     String inPortName;
 
-    public OvsDestroyTunnelCommand(Long networkId, Integer key,
+    public OvsDestroyTunnelCommand(Long networkId, String networkName,
             String inPortName) {
         this.networkId = networkId;
         this.inPortName = inPortName;
-        this.key = key;
+        this.networkName = networkName;
     }
 
     public Long getNetworkId() {
@@ -38,8 +38,8 @@ public class OvsDestroyTunnelCommand extends Command {
         return inPortName;
     }
 
-    public Integer getKey() {
-        return key;
+    public String getBridgeName() {
+        return networkName;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b080611a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsSetupBridgeCommand.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsSetupBridgeCommand.java b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsSetupBridgeCommand.java
index e3390f3..a104598 100644
--- a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsSetupBridgeCommand.java
+++ b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsSetupBridgeCommand.java
@@ -19,7 +19,7 @@ package com.cloud.agent.api;
 
 
 public class OvsSetupBridgeCommand extends Command {
-    Integer key;
+    String name;
     Long hostId;
     Long networkId;
 
@@ -28,14 +28,14 @@ public class OvsSetupBridgeCommand extends Command {
         return true;
     }
 
-    public OvsSetupBridgeCommand(Integer key, Long hostId, Long networkId) {
-        this.key = key;
+    public OvsSetupBridgeCommand(String name, Long hostId, Long networkId) {
+        this.name = name;
         this.hostId = hostId;
         this.networkId = networkId;
     }
 
-    public Integer getKey() {
-        return key;
+    public String getBridgeName() {
+        return name;
     }
 
     public Long getHostId() {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b080611a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcPhysicalTopologyConfigCommand.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcPhysicalTopologyConfigCommand.java b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcPhysicalTopologyConfigCommand.java
new file mode 100644
index 0000000..35d4c6e
--- /dev/null
+++ b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcPhysicalTopologyConfigCommand.java
@@ -0,0 +1,127 @@
+// 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 com.cloud.agent.api;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+/**
+ * This command represents view of how a VPC is laid out (on which hosts, which VM is on which host etc)
+ * on the physical infrastructure.
+ */
+public class OvsVpcPhysicalTopologyConfigCommand extends Command {
+
+    VpcConfig vpcConfig =null;
+    long hostId;
+    String bridgeName;
+
+    public static class Host {
+        long hostId;
+        String ipAddress;
+
+        public Host (long hostId, String ipAddress) {
+            this.hostId = hostId;
+            this.ipAddress = ipAddress;
+        }
+    }
+
+    public static class Nic {
+        String ipAddress;
+        String macAddress;
+        String networkUuid;
+        public Nic (String ipAddress, String macAddress, String networkUuid) {
+            this.ipAddress = ipAddress;
+            this.macAddress = macAddress;
+            this.networkUuid = networkUuid;
+        }
+    }
+
+    public static class Tier {
+        long greKey;
+        String networkUuid;
+        String gatewayIp;
+        String gatewayMac;
+        String cidr;
+        public Tier(long greKey, String networkUuid, String gatewayIp, String gatewayMac, String cidr) {
+            this.greKey = greKey;
+            this.networkUuid = networkUuid;
+            this.gatewayIp = gatewayIp;
+            this.gatewayMac = gatewayMac;
+            this.cidr = cidr;
+        }
+    }
+
+    public static class Vm {
+        long hostId;
+        Nic[] nics;
+        public Vm(long hostId, Nic[] nics) {
+            this.hostId = hostId;
+            this.nics = nics;
+        }
+    }
+
+    public static class Vpc {
+        String cidr;
+        Host[] hosts;
+        Tier[] tiers;
+        Vm[]  vms;
+        public Vpc(Host[] hosts, Tier[] tiers, Vm[] vms, String cidr) {
+            this.hosts = hosts;
+            this.tiers = tiers;
+            this.vms = vms;
+            this.cidr = cidr;
+        }
+    }
+
+    public static class VpcConfig {
+        Vpc vpc;
+        public VpcConfig(Vpc vpc) {
+            this.vpc = vpc;
+        }
+    }
+
+    public OvsVpcPhysicalTopologyConfigCommand(Host[] hosts, Tier[] tiers, Vm[] vms, String cidr) {
+        Vpc vpc = new Vpc(hosts, tiers, vms, cidr);
+        vpcConfig = new VpcConfig(vpc);
+    }
+
+    public String getjsonVpcConfig() {
+        Gson gson = new GsonBuilder().create();
+        return gson.toJson(vpcConfig).toLowerCase();
+    }
+
+    @Override
+    public boolean executeInSequence() {
+        return false;
+    }
+
+    public void setHostId(long hostId) {
+        this.hostId = hostId;
+    }
+
+    public long getHostId() {
+        return hostId;
+    }
+
+    public String getBridgeName() {
+        return bridgeName;
+    }
+
+    public void setBridgeName(String bridgeName) {
+        this.bridgeName = bridgeName;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b080611a/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java b/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java
index 05e81a1..c28d908 100644
--- a/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java
+++ b/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java
@@ -16,6 +16,8 @@
 // under the License.
 package com.cloud.network.element;
 
+import com.cloud.host.dao.HostDao;
+import com.cloud.vm.dao.UserVmDao;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -73,6 +75,8 @@ import com.cloud.vm.NicProfile;
 import com.cloud.vm.ReservationContext;
 import com.cloud.vm.VirtualMachineProfile;
 import com.cloud.vm.dao.DomainRouterDao;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.VirtualMachine;
 
 @Local(value = {NetworkElement.class, ConnectivityProvider.class,
         SourceNatServiceProvider.class, StaticNatServiceProvider.class,
@@ -93,6 +97,10 @@ StaticNatServiceProvider, IpDeployer {
     DomainRouterDao _routerDao;
     @Inject
     VpcVirtualNetworkApplianceManager _routerMgr;
+    @Inject
+    UserVmDao _userVmDao;
+    @Inject
+    HostDao _hostDao;
 
     private static final Logger s_logger = Logger.getLogger(OvsElement.class);
     private static final Map<Service, Map<Capability, String>> capabilities = setCapabilities();
@@ -171,7 +179,12 @@ StaticNatServiceProvider, IpDeployer {
             return false;
         }
 
-        _ovsTunnelMgr.vmCheckAndCreateTunnel(vm, network, dest);
+        if (vm.getType() != VirtualMachine.Type.User && vm.getType() != VirtualMachine.Type.DomainRouter) {
+            return false;
+        }
+
+        // prepare the tunnel network on the host, in order for VM to get launched
+        _ovsTunnelMgr.checkAndPrepareHostForTunnelNetwork(network, dest.getHost());
 
         return true;
     }
@@ -192,7 +205,25 @@ StaticNatServiceProvider, IpDeployer {
             return false;
         }
 
-        _ovsTunnelMgr.checkAndDestroyTunnel(vm.getVirtualMachine(), network);
+        List<UserVmVO> userVms = _userVmDao.listByAccountIdAndHostId(vm.getVirtualMachine().getAccountId(),
+                vm.getVirtualMachine().getHostId());
+        if (vm.getType() == VirtualMachine.Type.User) {
+            if (userVms.size() > 1) {
+                return true;
+            }
+
+            List<DomainRouterVO> routers = _routerDao.findByNetwork(network.getId());
+            for (DomainRouterVO router : routers) {
+                if (router.getHostId().equals(vm.getVirtualMachine().getHostId())) {
+                    return true;
+                }
+            }
+        } else if (vm.getType() == VirtualMachine.Type.DomainRouter && userVms.size() != 0) {
+            return true;
+        }
+
+        HostVO host = _hostDao.findById(vm.getVirtualMachine().getHostId());
+        _ovsTunnelMgr.checkAndRemoveHostFromTunnelNetwork(network, host);
         return true;
     }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b080611a/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java b/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java
index 8fa636d..2814c2a 100644
--- a/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java
+++ b/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java
@@ -16,6 +16,8 @@
 // under the License.
 package com.cloud.network.guru;
 
+import com.cloud.network.vpc.VpcVO;
+import com.cloud.network.vpc.dao.VpcDao;
 import javax.ejb.Local;
 import javax.inject.Inject;
 
@@ -61,6 +63,8 @@ public class OvsGuestNetworkGuru extends GuestNetworkGuru {
     OvsTunnelManager _ovsTunnelMgr;
     @Inject
     NetworkOfferingServiceMapDao _ntwkOfferingSrvcDao;
+    @Inject
+    VpcDao _vpcDao;
 
     OvsGuestNetworkGuru() {
         super();
@@ -145,10 +149,14 @@ public class OvsGuestNetworkGuru extends GuestNetworkGuru {
             implemented.setCidr(network.getCidr());
         }
 
-        // do we need to create switch right now?
-
         implemented.setBroadcastDomainType(BroadcastDomainType.Vswitch);
 
+        if (network.getVpcId() != null && isVpcEnabledForDistributedRouter(network.getVpcId())) {
+            String keyStr = BroadcastDomainType.getValue(implemented.getBroadcastUri());
+            Long vpcid= network.getVpcId();
+            implemented.setBroadcastUri(BroadcastDomainType.Vswitch.toUri(vpcid.toString()+keyStr));
+        }
+
         return implemented;
     }
 
@@ -215,4 +223,9 @@ public class OvsGuestNetworkGuru extends GuestNetworkGuru {
             implemented.setBroadcastUri(network.getBroadcastUri());
         }
     }
+
+    boolean isVpcEnabledForDistributedRouter(long vpcId) {
+        VpcVO vpc = _vpcDao.findById(vpcId);
+        return vpc.usesDistributedRouter();
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b080611a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuru.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuru.java b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuru.java
new file mode 100644
index 0000000..c410d10
--- /dev/null
+++ b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuru.java
@@ -0,0 +1,49 @@
+// 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 com.cloud.network.ovs;
+
+import com.cloud.utils.component.Manager;
+
+import java.util.List;
+
+public interface OvsNetworkTopologyGuru extends Manager {
+
+    /**
+     * get the list of hypervisor hosts id's on which VM's belonging to the network currently spans
+     */
+    public  List<Long> getNetworkSpanedHosts(long networkId);
+
+    /**
+     * get the list of hypervisor hosts id's on which VM's belonging to a VPC spans
+     */
+    public  List<Long> getVpcSpannedHosts(long vpId);
+
+    /**
+     * get the list of VPC id's of the vpc's for which one or more VM's from the VPC are running on the host
+     */
+    public  List<Long> getVpcOnHost(long hostId);
+
+    /**
+     * get the list of all active Vm id's in the VPC for all ther tiers
+     */
+    public List<Long> getAllActiveVmsInVpc(long vpcId);
+
+    /**
+     * get the list of all Vm id's in the VPC for all the tiers that are running on the host
+     */
+    public List<Long> getActiveVmsInVpcOnHost(long vpcId, long hostId);
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b080611a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuruImpl.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuruImpl.java b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuruImpl.java
new file mode 100644
index 0000000..7560e35
--- /dev/null
+++ b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuruImpl.java
@@ -0,0 +1,74 @@
+package com.cloud.network.ovs;
+
+import com.cloud.utils.component.ManagerBase;
+import com.cloud.vm.DomainRouterVO;
+import com.cloud.vm.UserVmVO;
+import com.cloud.vm.VMInstanceVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.dao.DomainRouterDao;
+import com.cloud.vm.dao.UserVmDao;
+import java.util.ArrayList;
+import java.util.List;
+import javax.ejb.Local;
+import javax.inject.Inject;
+import org.springframework.stereotype.Component;
+
+@Component
+@Local(value = {OvsNetworkTopologyGuru.class})
+public class OvsNetworkTopologyGuruImpl extends ManagerBase implements OvsNetworkTopologyGuru {
+
+    @Inject
+    UserVmDao _userVmDao;
+    @Inject
+    DomainRouterDao _routerDao;
+
+    /**
+     * get the list of hypervisor hosts on which VM's belonging to a network currently spans
+     */
+    public  List<Long> getNetworkSpanedHosts(long networkId) {
+        List<Long> hostIds = new ArrayList<Long>();
+        // Find active VMs with a NIC on the target network
+        List<UserVmVO> vms = _userVmDao.listByNetworkIdAndStates(networkId,
+                VirtualMachine.State.Running, VirtualMachine.State.Starting, VirtualMachine.State.Stopping, VirtualMachine.State.Unknown,
+                VirtualMachine.State.Migrating);
+        // Find routers for the network
+        List<DomainRouterVO> routers = _routerDao.findByNetwork(networkId);
+        List<VMInstanceVO> ins = new ArrayList<VMInstanceVO>();
+        if (vms != null) {
+            ins.addAll(vms);
+        }
+        if (routers.size() != 0) {
+            ins.addAll(routers);
+        }
+        for (VMInstanceVO v : ins) {
+            Long rh = v.getHostId();
+            if (rh == null) {
+                continue;
+            }
+            if (!hostIds.contains(rh)) {
+                hostIds.add(rh);
+            }
+        }
+        return  hostIds;
+    }
+
+    @Override
+    public List<Long> getVpcSpannedHosts(long vpId) {
+        return null;
+    }
+
+    @Override
+    public List<Long> getVpcOnHost(long hostId) {
+        return null;
+    }
+
+    @Override
+    public List<Long> getAllActiveVmsInVpc(long vpcId) {
+        return null;
+    }
+
+    @Override
+    public List<Long> getActiveVmsInVpcOnHost(long vpcId, long hostId) {
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b080611a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManager.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManager.java b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManager.java
index 118beeb..cd88136 100644
--- a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManager.java
+++ b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManager.java
@@ -16,18 +16,24 @@
 // under the License.
 package com.cloud.network.ovs;
 
-import com.cloud.deploy.DeployDestination;
+import com.cloud.host.Host;
 import com.cloud.network.Network;
 import com.cloud.utils.component.Manager;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachineProfile;
 
 public interface OvsTunnelManager extends Manager {
 
     boolean isOvsTunnelEnabled();
 
-    public void vmCheckAndCreateTunnel(VirtualMachineProfile vm, Network nw, DeployDestination dest);
+    /**
+     *  create a bridge on the host if not already created for the network and establish full tunnel mesh with
+     *  the rest of the hosts on which network spans
+     */
+    public void checkAndPrepareHostForTunnelNetwork(Network nw, Host host);
 
-    public void checkAndDestroyTunnel(VirtualMachine vm, Network nw);
+    /**
+     * remove the bridge and tunnels to the hosts on which network spans if there are no other VM's
+     * belonging to the network are running on the host
+     */
+    public void checkAndRemoveHostFromTunnelNetwork(Network nw, Host host);
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b080611a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
index 320568b..ae37095 100644
--- a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
+++ b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
@@ -16,6 +16,12 @@
 // under the License.
 package com.cloud.network.ovs;
 
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.vpc.VpcManager;
+import com.cloud.vm.Nic;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.dao.VMInstanceDao;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
@@ -42,9 +48,9 @@ import com.cloud.agent.api.OvsDestroyTunnelCommand;
 import com.cloud.agent.api.OvsFetchInterfaceAnswer;
 import com.cloud.agent.api.OvsFetchInterfaceCommand;
 import com.cloud.agent.api.OvsSetupBridgeCommand;
+import com.cloud.agent.api.OvsVpcPhysicalTopologyConfigCommand;
 import com.cloud.agent.manager.Commands;
 import com.cloud.configuration.Config;
-import com.cloud.deploy.DeployDestination;
 import com.cloud.exception.AgentUnavailableException;
 import com.cloud.exception.OperationTimedoutException;
 import com.cloud.host.Host;
@@ -60,19 +66,15 @@ import com.cloud.network.ovs.dao.OvsTunnelInterfaceDao;
 import com.cloud.network.ovs.dao.OvsTunnelInterfaceVO;
 import com.cloud.network.ovs.dao.OvsTunnelNetworkDao;
 import com.cloud.network.ovs.dao.OvsTunnelNetworkVO;
+import com.cloud.network.ovs.dao.OvsTunnel;
+import com.cloud.network.vpc.dao.VpcDao;
+import com.cloud.network.vpc.VpcVO;
 import com.cloud.utils.component.ManagerBase;
 import com.cloud.utils.concurrency.NamedThreadFactory;
 import com.cloud.utils.db.DB;
 import com.cloud.utils.exception.CloudRuntimeException;
-import com.cloud.vm.DomainRouterVO;
-import com.cloud.vm.UserVmVO;
-import com.cloud.vm.VMInstanceVO;
-import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.VirtualMachine.State;
-import com.cloud.vm.VirtualMachineProfile;
 import com.cloud.vm.dao.DomainRouterDao;
 import com.cloud.vm.dao.NicDao;
-import com.cloud.vm.dao.UserVmDao;
 
 @Component
 @Local(value = {OvsTunnelManager.class})
@@ -91,8 +93,7 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
     HostDao _hostDao;
     @Inject
     PhysicalNetworkTrafficTypeDao _physNetTTDao;
-    @Inject
-    UserVmDao _userVmDao;
+
     @Inject
     DomainRouterDao _routerDao;
     @Inject
@@ -101,6 +102,16 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
     OvsTunnelInterfaceDao _tunnelInterfaceDao;
     @Inject
     AgentManager _agentMgr;
+    @Inject
+    OvsNetworkTopologyGuru _ovsNetworkToplogyGuru;
+    @Inject
+    VpcDao _vpcDao;
+    @Inject
+    VpcManager _vpcMgr;
+    @Inject
+    protected VMInstanceDao _vmInstanceDao;
+    @Inject
+    NetworkDao _networkDao;
 
     @Override
     public boolean configure(String name, Map<String, Object> params)
@@ -182,13 +193,13 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
                             from, to, networkId));
         }
         if (!r.getResult()) {
-            tunnel.setState("FAILED");
-            s_logger.warn("Create GRE tunnel failed due to " + r.getDetails()
+            tunnel.setState(OvsTunnel.State.Failed.name());
+            s_logger.warn("Create GRE tunnel from " + from + " to " + to + " failed due to " + r.getDetails()
                     + s);
         } else {
-            tunnel.setState("SUCCESS");
+            tunnel.setState(OvsTunnel.State.Established.name());
             tunnel.setPortName(r.getInPortName());
-            s_logger.warn("Create GRE tunnel " + r.getDetails() + s);
+            s_logger.info("Create GRE tunnel from " + from + " to " + to + " succeeded." + r.getDetails() + s);
         }
         _tunnelNetworkDao.update(tunnel.getId(), tunnel);
     }
@@ -249,13 +260,14 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
         int key = 0;
         try {
             //The GRE key is actually in the host part of the URI
-            // this is not true for lswitch/NiciraNvp!
             String keyStr = BroadcastDomainType.getValue(network.getBroadcastUri());
-            // The key is most certainly and int if network is a vlan.
-            // !! not in the case of lswitch/pvlan/(possibly)vswitch
-            // So we now feel quite safe in converting it into a string
-            // by calling the appropriate BroadcastDomainType method
-            key = Integer.parseInt(keyStr);
+            if (keyStr.contains(".")) {
+                String[] parts = keyStr.split(".");
+                key = Integer.parseInt(parts[1]);
+            } else {
+                key = Integer.parseInt(keyStr);
+            }
+
             return key;
         } catch (NumberFormatException e) {
             s_logger.debug("Well well, how did '" + key
@@ -268,41 +280,23 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
     }
 
     @DB
-    protected void checkAndCreateTunnel(VirtualMachine instance, Network nw, DeployDestination dest) {
+    protected void checkAndCreateTunnel(Network nw, Host host) {
 
         s_logger.debug("Creating tunnels with OVS tunnel manager");
-        if (instance.getType() != VirtualMachine.Type.User
-                && instance.getType() != VirtualMachine.Type.DomainRouter) {
-            s_logger.debug("Will not work if you're not"
-                    + "an instance or a virtual router");
-            return;
-        }
 
-        long hostId = dest.getHost().getId();
+        long hostId = host.getId();
         int key = getGreKey(nw);
-        // Find active VMs with a NIC on the target network
-        List<UserVmVO> vms = _userVmDao.listByNetworkIdAndStates(nw.getId(),
-                State.Running, State.Starting, State.Stopping, State.Unknown,
-                State.Migrating);
-        // Find routers for the network
-        List<DomainRouterVO> routers = _routerDao.findByNetwork(nw.getId());
-        List<VMInstanceVO> ins = new ArrayList<VMInstanceVO>();
-        if (vms != null) {
-            ins.addAll(vms);
-        }
-        if (routers.size() != 0) {
-            ins.addAll(routers);
-        }
+        String bridgeName = generateBridgeName(nw, key);
         List<Long> toHostIds = new ArrayList<Long>();
         List<Long> fromHostIds = new ArrayList<Long>();
-        for (VMInstanceVO v : ins) {
-            Long rh = v.getHostId();
-            if (rh == null || rh.longValue() == hostId) {
+        List<Long> networkSpannedHosts = _ovsNetworkToplogyGuru.getNetworkSpanedHosts(nw.getId());
+        for (Long rh : networkSpannedHosts) {
+            if (rh == hostId) {
                 continue;
             }
             OvsTunnelNetworkVO ta = _tunnelNetworkDao.getByFromToNetwork(hostId, rh.longValue(), nw.getId());
             // Try and create the tunnel even if a previous attempt failed
-            if (ta == null || ta.getState().equals("FAILED")) {
+            if (ta == null || ta.getState().equals(OvsTunnel.State.Failed.name())) {
                 s_logger.debug("Attempting to create tunnel from:" + hostId + " to:" + rh.longValue());
                 if (ta == null) {
                     createTunnelRecord(hostId, rh.longValue(), nw.getId(), key);
@@ -315,7 +309,7 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
             ta = _tunnelNetworkDao.getByFromToNetwork(rh.longValue(),
                     hostId, nw.getId());
             // Try and create the tunnel even if a previous attempt failed
-            if (ta == null || ta.getState().equals("FAILED")) {
+            if (ta == null || ta.getState().equals(OvsTunnel.State.Failed.name())) {
                 s_logger.debug("Attempting to create tunnel from:" +
                         rh.longValue() + " to:" + hostId);
                 if (ta == null) {
@@ -329,9 +323,9 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
         }
         //TODO: Should we propagate the exception here?
         try {
-            String myIp = getGreEndpointIP(dest.getHost(), nw);
+            String myIp = getGreEndpointIP(host, nw);
             if (myIp == null)
-                throw new GreTunnelException("Unable to retrieve the source " + "endpoint for the GRE tunnel." + "Failure is on host:" + dest.getHost().getId());
+                throw new GreTunnelException("Unable to retrieve the source " + "endpoint for the GRE tunnel." + "Failure is on host:" + host.getId());
             boolean noHost = true;
             for (Long i : toHostIds) {
                 HostVO rHost = _hostDao.findById(i);
@@ -343,7 +337,8 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
                                     + "Failure is on host:" + rHost.getId());
                 Commands cmds = new Commands(
                         new OvsCreateTunnelCommand(otherIp, key,
-                                Long.valueOf(hostId), i, nw.getId(), myIp));
+                                Long.valueOf(hostId), i, nw.getId(), myIp, bridgeName, nw.getUuid()));
+                s_logger.debug("Attempting to create tunnel from:" + hostId + " to:" + i + " for the network " + nw.getId());
                 s_logger.debug("Ask host " + hostId
                         + " to create gre tunnel to " + i);
                 Answer[] answers = _agentMgr.send(hostId, cmds);
@@ -355,21 +350,19 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
                 HostVO rHost = _hostDao.findById(i);
                 String otherIp = getGreEndpointIP(rHost, nw);
                 Commands cmds = new Commands(new OvsCreateTunnelCommand(myIp,
-                        key, i, Long.valueOf(hostId), nw.getId(), otherIp));
+                        key, i, Long.valueOf(hostId), nw.getId(), otherIp, bridgeName, nw.getUuid()));
                 s_logger.debug("Ask host " + i + " to create gre tunnel to "
                         + hostId);
                 Answer[] answers = _agentMgr.send(i, cmds);
                 handleCreateTunnelAnswer(answers);
                 noHost = false;
             }
+
             // If no tunnels have been configured, perform the bridge setup
-            // anyway
-            // This will ensure VIF rules will be triggered
+            // anyway. This will ensure VIF rules will be triggered
             if (noHost) {
-                Commands cmds = new Commands(new OvsSetupBridgeCommand(key,
-                        hostId, nw.getId()));
-                s_logger.debug("Ask host " + hostId
-                        + " to configure bridge for network:" + nw.getId());
+                Commands cmds = new Commands(new OvsSetupBridgeCommand(bridgeName, hostId, nw.getId()));
+                s_logger.debug("Ask host " + hostId + " to configure bridge for network:" + nw.getId());
                 Answer[] answers = _agentMgr.send(hostId, cmds);
                 handleSetupBridgeAnswer(answers);
             }
@@ -384,10 +377,20 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
         return true;
     }
 
+    boolean isVpcEnabledForDistributedRouter(long vpcId) {
+        VpcVO vpc = _vpcDao.findById(vpcId);
+        return vpc.usesDistributedRouter();
+    }
+
     @Override
-    public void vmCheckAndCreateTunnel(VirtualMachineProfile vm,
-            Network nw, DeployDestination dest) {
-        checkAndCreateTunnel(vm.getVirtualMachine(), nw, dest);
+    public void checkAndPrepareHostForTunnelNetwork(Network nw, Host host) {
+        if (nw.getVpcId() != null && isVpcEnabledForDistributedRouter(nw.getVpcId())) {
+            // check and setup host to be in full tunnel mesh with each of the network in the VPC
+            checkAndCreateVpcTunnelNetworks(host, nw.getVpcId());
+        } else {
+            // check and setup host to be in full tunnel mesh with the network
+            checkAndCreateTunnel(nw, host);
+        }
     }
 
     @DB
@@ -440,45 +443,28 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
     }
 
     @Override
-    public void checkAndDestroyTunnel(VirtualMachine vm, Network nw) {
-        // if (!_isEnabled) {
-        // return;
-        // }
-
-        List<UserVmVO> userVms = _userVmDao.listByAccountIdAndHostId(vm.getAccountId(), vm.getHostId());
-        if (vm.getType() == VirtualMachine.Type.User) {
-            if (userVms.size() > 1) {
-                return;
-            }
+    public void checkAndRemoveHostFromTunnelNetwork(Network nw, Host host) {
 
-            List<DomainRouterVO> routers = _routerDao.findByNetwork(nw.getId());
-            for (DomainRouterVO router : routers) {
-                if (router.getHostId().equals(vm.getHostId())) {
-                    return;
-                }
-            }
-        } else if (vm.getType() == VirtualMachine.Type.DomainRouter && userVms.size() != 0) {
-            return;
-        }
         try {
             /* Now we are last one on host, destroy the bridge with all
              * the tunnels for this network  */
             int key = getGreKey(nw);
-            Command cmd = new OvsDestroyBridgeCommand(nw.getId(), key);
-            s_logger.debug("Destroying bridge for network " + nw.getId() + " on host:" + vm.getHostId());
-            Answer ans = _agentMgr.send(vm.getHostId(), cmd);
-            handleDestroyBridgeAnswer(ans, vm.getHostId(), nw.getId());
+            String bridgeName = generateBridgeName(nw, key);
+            Command cmd = new OvsDestroyBridgeCommand(nw.getId(), bridgeName);
+            s_logger.debug("Destroying bridge for network " + nw.getId() + " on host:" + host.getId());
+            Answer ans = _agentMgr.send(host.getId(), cmd);
+            handleDestroyBridgeAnswer(ans, host.getId(), nw.getId());
 
             /* Then ask hosts have peer tunnel with me to destroy them */
             List<OvsTunnelNetworkVO> peers =
-                    _tunnelNetworkDao.listByToNetwork(vm.getHostId(),
+                    _tunnelNetworkDao.listByToNetwork(host.getId(),
                             nw.getId());
             for (OvsTunnelNetworkVO p : peers) {
                 // If the tunnel was not successfully created don't bother to remove it
-                if (p.getState().equals("SUCCESS")) {
-                    cmd = new OvsDestroyTunnelCommand(p.getNetworkId(), key,
+                if (p.getState().equals(OvsTunnel.State.Established.name())) {
+                    cmd = new OvsDestroyTunnelCommand(p.getNetworkId(), bridgeName,
                             p.getPortName());
-                    s_logger.debug("Destroying tunnel to " + vm.getHostId() +
+                    s_logger.debug("Destroying tunnel to " + host.getId() +
                             " from " + p.getFrom());
                     ans = _agentMgr.send(p.getFrom(), cmd);
                     handleDestroyTunnelAnswer(ans, p.getFrom(),
@@ -486,8 +472,204 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
                 }
             }
         } catch (Exception e) {
-            s_logger.warn(String.format("Destroy tunnel(account:%1$s," + "hostId:%2$s) failed", vm.getAccountId(), vm.getHostId()), e);
+            s_logger.warn(String.format("Destroy tunnel failed", e));
+        }
+    }
+
+    private String generateBridgeName(Network nw, int key) {
+        if (nw.getVpcId() != null && isVpcEnabledForDistributedRouter(nw.getVpcId())) {
+            return "OVS-DR-VPC-Bridge" + nw.getVpcId();
+        } else {
+            return "OVSTunnel"+key;
+        }
+    }
+    private String generateBridgeNameForVpc(long vpcId) {
+        return "OVS-DR-VPC-Bridge" + vpcId;
+    }
+
+    public boolean sendVpcTopologyChangeUpdate(OvsVpcPhysicalTopologyConfigCommand updateCmd, long hostId, String bridgeName) {
+        try {
+            s_logger.debug("Sending VPC topology update to the host " + hostId);
+            updateCmd.setHostId(hostId);
+            updateCmd.setBridgeName(bridgeName);
+            Answer ans = _agentMgr.send(hostId, updateCmd);
+            if (ans.getResult()) {
+                s_logger.debug("Successfully updated the host " + hostId + " with latest VPC topology." );
+                return true;
+            }  else {
+                s_logger.debug("Failed to update the host " + hostId + " with latest VPC topology." );
+                return false;
+            }
+        } catch (Exception e) {
+            s_logger.debug("Failed to updated the host " + hostId + " with latest VPC topology." );
+            return false;
         }
     }
 
+    OvsVpcPhysicalTopologyConfigCommand prepareVpcTopologyUpdate(long vpcId) {
+        VpcVO vpc = _vpcDao.findById(vpcId);
+        assert (vpc != null): "invalid vpc id";
+
+        List<? extends Network> vpcNetworks =  _vpcMgr.getVpcNetworks(vpcId);
+        List<Long> hostIds = _ovsNetworkToplogyGuru.getVpcSpannedHosts(vpcId);
+        List<Long> vmIds = _ovsNetworkToplogyGuru.getAllActiveVmsInVpc(vpcId);
+
+        List<OvsVpcPhysicalTopologyConfigCommand.Host> hosts = new ArrayList<OvsVpcPhysicalTopologyConfigCommand.Host>();
+        List<OvsVpcPhysicalTopologyConfigCommand.Tier> tiers = new ArrayList<OvsVpcPhysicalTopologyConfigCommand.Tier>();
+        List<OvsVpcPhysicalTopologyConfigCommand.Vm> vms = new ArrayList<OvsVpcPhysicalTopologyConfigCommand.Vm>();
+
+        for (Long hostId : hostIds) {
+            HostVO hostDetails = _hostDao.findById(hostId);
+            String remoteIp = null;
+            for (Network network: vpcNetworks) {
+                try {
+                    remoteIp = getGreEndpointIP(hostDetails, network);
+                } catch (Exception e) {
+
+                }
+            }
+            OvsVpcPhysicalTopologyConfigCommand.Host host = new OvsVpcPhysicalTopologyConfigCommand.Host(hostId, remoteIp);
+            hosts.add(host);
+        }
+
+        for (Network network: vpcNetworks) {
+            String key = BroadcastDomainType.getValue(network.getBroadcastUri());
+            long gre_key;
+            if (key.contains(".")) {
+                String[] parts = key.split(".");
+                gre_key = Long.parseLong(parts[1]);
+            } else {
+                try {
+                    gre_key = Long.parseLong(BroadcastDomainType.getValue(key));
+                } catch (Exception e) {
+                    return null;
+                }
+            }
+            NicVO nic = _nicDao.findByIp4AddressAndNetworkId(network.getGateway(), network.getId());
+            OvsVpcPhysicalTopologyConfigCommand.Tier tier = new OvsVpcPhysicalTopologyConfigCommand.Tier(gre_key,
+                    network.getUuid(), network.getGateway(), nic.getMacAddress(), network.getCidr());
+            tiers.add(tier);
+        }
+
+        for (long vmId: vmIds) {
+            VirtualMachine vmInstance = _vmInstanceDao.findById(vmId);
+            List<OvsVpcPhysicalTopologyConfigCommand.Nic>  vmNics = new ArrayList<OvsVpcPhysicalTopologyConfigCommand.Nic>();
+            for (Nic vmNic :_nicDao.listByVmId(vmId)) {
+                Network network = _networkDao.findById(vmNic.getNetworkId());
+                if (network.getTrafficType() == TrafficType.Guest) {
+                    OvsVpcPhysicalTopologyConfigCommand.Nic nic =  new OvsVpcPhysicalTopologyConfigCommand.Nic(
+                            vmNic.getIp4Address(), vmNic.getMacAddress(), ((Long)vmNic.getNetworkId()).toString());
+                    vmNics.add(nic);
+                }
+            }
+            OvsVpcPhysicalTopologyConfigCommand.Vm vm = new OvsVpcPhysicalTopologyConfigCommand.Vm(
+                    vmInstance.getHostId(), vmNics.toArray(new OvsVpcPhysicalTopologyConfigCommand.Nic[vmNics.size()]));
+            vms.add(vm);
+        }
+        return new OvsVpcPhysicalTopologyConfigCommand(
+                hosts.toArray(new OvsVpcPhysicalTopologyConfigCommand.Host[hosts.size()]),
+                tiers.toArray(new OvsVpcPhysicalTopologyConfigCommand.Tier[tiers.size()]),
+                vms.toArray(new OvsVpcPhysicalTopologyConfigCommand.Vm[vms.size()]),
+                vpc.getCidr());
+    }
+
+    @DB
+    protected void checkAndCreateVpcTunnelNetworks(Host host, long vpcId) {
+
+        long hostId = host.getId();
+        List<? extends Network> vpcNetworks =  _vpcMgr.getVpcNetworks(vpcId);
+        List<Long> vpcSpannedHostIds = _ovsNetworkToplogyGuru.getVpcSpannedHosts(vpcId);
+        String bridgeName=generateBridgeNameForVpc(vpcId);
+
+        for (Network vpcNetwork: vpcNetworks) {
+            int key = getGreKey(vpcNetwork);
+            List<Long> toHostIds = new ArrayList<Long>();
+            List<Long> fromHostIds = new ArrayList<Long>();
+
+            for (Long rh : vpcSpannedHostIds) {
+                if (rh == hostId) {
+                    continue;
+                }
+                OvsTunnelNetworkVO ta = _tunnelNetworkDao.getByFromToNetwork(hostId, rh.longValue(), vpcNetwork.getId());
+                // Try and create the tunnel even if a previous attempt failed
+                if (ta == null || ta.getState().equals(OvsTunnel.State.Failed.name())) {
+                    s_logger.debug("Attempting to create tunnel from:" + hostId + " to:" + rh.longValue());
+                    if (ta == null) {
+                        createTunnelRecord(hostId, rh.longValue(), vpcNetwork.getId(), key);
+                    }
+                    if (!toHostIds.contains(rh)) {
+                        toHostIds.add(rh);
+                    }
+                }
+
+                ta = _tunnelNetworkDao.getByFromToNetwork(rh.longValue(),
+                        hostId, vpcNetwork.getId());
+                // Try and create the tunnel even if a previous attempt failed
+                if (ta == null || ta.getState().equals(OvsTunnel.State.Failed.name())) {
+                    s_logger.debug("Attempting to create tunnel from:" +
+                            rh.longValue() + " to:" + hostId);
+                    if (ta == null) {
+                        createTunnelRecord(rh.longValue(), hostId,
+                                vpcNetwork.getId(), key);
+                    }
+                    if (!fromHostIds.contains(rh)) {
+                        fromHostIds.add(rh);
+                    }
+                }
+            }
+
+            try {
+                String myIp = getGreEndpointIP(host, vpcNetwork);
+                if (myIp == null)
+                    throw new GreTunnelException("Unable to retrieve the source " + "endpoint for the GRE tunnel."
+                            + "Failure is on host:" + host.getId());
+                boolean noHost = true;
+
+                for (Long i : toHostIds) {
+                    HostVO rHost = _hostDao.findById(i);
+                    String otherIp = getGreEndpointIP(rHost, vpcNetwork);
+                    if (otherIp == null)
+                        throw new GreTunnelException(
+                                "Unable to retrieve the remote "
+                                        + "endpoint for the GRE tunnel."
+                                        + "Failure is on host:" + rHost.getId());
+                    Commands cmds = new Commands(
+                            new OvsCreateTunnelCommand(otherIp, key,
+                                    Long.valueOf(hostId), i, vpcNetwork.getId(), myIp, bridgeName,
+                                    vpcNetwork.getUuid()));
+                    s_logger.debug("Attempting to create tunnel from:" + hostId + " to:" + i + " for the network "
+                            + vpcNetwork.getId());
+                    s_logger.debug("Ask host " + hostId
+                            + " to create gre tunnel to " + i);
+                    Answer[] answers = _agentMgr.send(hostId, cmds);
+                    handleCreateTunnelAnswer(answers);
+                    noHost = false;
+                }
+
+                for (Long i : fromHostIds) {
+                    HostVO rHost = _hostDao.findById(i);
+                    String otherIp = getGreEndpointIP(rHost, vpcNetwork);
+                    Commands cmds = new Commands(new OvsCreateTunnelCommand(myIp,
+                            key, i, Long.valueOf(hostId), vpcNetwork.getId(), otherIp, bridgeName,
+                            vpcNetwork.getUuid()));
+                    s_logger.debug("Ask host " + i + " to create gre tunnel to "
+                            + hostId);
+                    Answer[] answers = _agentMgr.send(i, cmds);
+                    handleCreateTunnelAnswer(answers);
+                    noHost = false;
+                }
+            } catch (GreTunnelException | OperationTimedoutException | AgentUnavailableException e) {
+                // I really thing we should do a better handling of these exceptions
+                s_logger.warn("Ovs Tunnel network created tunnel failed", e);
+            }
+        }
+
+        OvsVpcPhysicalTopologyConfigCommand topologyConfigCommand = prepareVpcTopologyUpdate(vpcId);
+        for (Long id: vpcSpannedHostIds) {
+            if (!sendVpcTopologyChangeUpdate(topologyConfigCommand, id, bridgeName)) {
+                s_logger.debug("Failed to send VPC topology change update to host : " + id + ". Moving on with rest of" +
+                        "the host update.");
+            }
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b080611a/plugins/network-elements/ovs/src/com/cloud/network/ovs/dao/OvsTunnel.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/ovs/dao/OvsTunnel.java b/plugins/network-elements/ovs/src/com/cloud/network/ovs/dao/OvsTunnel.java
new file mode 100644
index 0000000..3216ac7
--- /dev/null
+++ b/plugins/network-elements/ovs/src/com/cloud/network/ovs/dao/OvsTunnel.java
@@ -0,0 +1,24 @@
+// 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 com.cloud.network.ovs.dao;
+
+public interface OvsTunnel {
+    public enum State {
+        Created, Established, Failed
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b080611a/plugins/network-elements/ovs/src/com/cloud/network/ovs/dao/OvsTunnelNetworkVO.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/ovs/dao/OvsTunnelNetworkVO.java b/plugins/network-elements/ovs/src/com/cloud/network/ovs/dao/OvsTunnelNetworkVO.java
index 2826912..88a7591 100644
--- a/plugins/network-elements/ovs/src/com/cloud/network/ovs/dao/OvsTunnelNetworkVO.java
+++ b/plugins/network-elements/ovs/src/com/cloud/network/ovs/dao/OvsTunnelNetworkVO.java
@@ -62,7 +62,7 @@ public class OvsTunnelNetworkVO implements InternalIdentity {
         this.key = key;
         this.networkId = networkId;
         this.portName = "[]";
-        this.state = "FAILED";
+        this.state = OvsTunnel.State.Created.name();
     }
 
     public void setKey(int key) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b080611a/scripts/vm/hypervisor/xenserver/ovstunnel
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/xenserver/ovstunnel b/scripts/vm/hypervisor/xenserver/ovstunnel
index d558e97..64a2d36 100755
--- a/scripts/vm/hypervisor/xenserver/ovstunnel
+++ b/scripts/vm/hypervisor/xenserver/ovstunnel
@@ -224,6 +224,7 @@ def create_tunnel(session, args):
     gre_key = args.pop("key")
     src_host = args.pop("from")
     dst_host = args.pop("to")
+    network_uuid = args.pop("cloudstack-network-id")
 
     logging.debug("Entering create_tunnel")
 
@@ -318,6 +319,7 @@ def create_tunnel(session, args):
 
             # add flow rule to send the traffic from tunnel ports to L2 switching table only
             lib.add_flow(bridge, priority=1000, in_port=tun_ofport, table=0, actions='resubmit(,1)')
+            lib.do_cmd([lib.VSCTL_PATH, "set", "interface", name, "options:cloudstack-network-id=%s" % network_uuid])
 
         return "SUCCESS:%s" % name
     except:

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b080611a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java
index 4af20c6..b643ec4 100644
--- a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java
+++ b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java
@@ -16,6 +16,7 @@
 // under the License.
 package com.cloud.hypervisor;
 
+import com.cloud.network.dao.NetworkVO;
 import java.util.List;
 import java.util.Map;
 
@@ -41,6 +42,7 @@ 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.dao.NetworkDao;
 import com.cloud.vm.dao.NicSecondaryIpDao;
 import com.cloud.vm.dao.UserVmDetailsDao;
 import com.cloud.vm.dao.VMInstanceDao;
@@ -52,6 +54,8 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
     @Inject
     NicDao _nicDao;
     @Inject
+    NetworkDao  _networkDao;
+    @Inject
     VMInstanceDao _virtualMachineDao;
     @Inject
     UserVmDetailsDao _userVmDetailsDao;
@@ -87,6 +91,9 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
         to.setName(profile.getName());
         to.setSecurityGroupEnabled(profile.isSecurityGroupEnabled());
 
+        NetworkVO network = _networkDao.findById(profile.getNetworkId());
+        to.setNetworkUuid(network.getUuid());
+
         // Workaround to make sure the TO has the UUID we need for Niciri integration
         NicVO nicVO = _nicDao.findById(profile.getId());
         to.setUuid(nicVO.getUuid());


[03/31] git commit: updated refs/heads/distributedrouter to a8d43ba

Posted by mu...@apache.org.
CLOUDSTACK-6122: Add LXC to supported hypervisor list for VPC


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

Branch: refs/heads/distributedrouter
Commit: c63f43a9ccf13466e355902916020ddd2b7e72cb
Parents: 6d4b979
Author: Kishan Kavala <ki...@cloud.com>
Authored: Tue Mar 11 23:00:24 2014 +0530
Committer: Kishan Kavala <ki...@cloud.com>
Committed: Tue Mar 11 23:49:28 2014 +0530

----------------------------------------------------------------------
 server/src/com/cloud/network/vpc/VpcManagerImpl.java | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c63f43a9/server/src/com/cloud/network/vpc/VpcManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java
index 762cc6f..fe49981 100644
--- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java
+++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java
@@ -2179,6 +2179,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
         hTypes.add(HypervisorType.VMware);
         hTypes.add(HypervisorType.KVM);
         hTypes.add(HypervisorType.Simulator);
+        hTypes.add(HypervisorType.LXC);
         return hTypes;
     }
 


[23/31] git commit: updated refs/heads/distributedrouter to a8d43ba

Posted by mu...@apache.org.
mark VPC to be using distributed router if VPC offerign supports
distributedrouter capability.


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

Branch: refs/heads/distributedrouter
Commit: 0b9a6891e89f6f401e62a040b79bf9e69157cc9d
Parents: 6c1a158
Author: Murali Reddy <mu...@gmail.com>
Authored: Tue Mar 4 18:17:02 2014 +0530
Committer: Murali Reddy <mu...@gmail.com>
Committed: Thu Mar 13 19:22:07 2014 +0530

----------------------------------------------------------------------
 api/src/com/cloud/network/vpc/Vpc.java                 |  6 ++++++
 .../apache/cloudstack/api/response/VpcResponse.java    |  9 +++++++++
 engine/schema/src/com/cloud/network/vpc/VpcVO.java     | 13 +++++++++++--
 server/src/com/cloud/api/ApiResponseHelper.java        |  1 +
 server/src/com/cloud/network/vpc/VpcManagerImpl.java   |  9 +++++----
 server/test/com/cloud/vpc/VpcApiUnitTest.java          |  2 +-
 server/test/com/cloud/vpc/dao/MockVpcDaoImpl.java      |  4 ++--
 setup/db/db/schema-430to440.sql                        |  1 +
 8 files changed, 36 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b9a6891/api/src/com/cloud/network/vpc/Vpc.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/network/vpc/Vpc.java b/api/src/com/cloud/network/vpc/Vpc.java
index eb7e391..4bc8c98 100644
--- a/api/src/com/cloud/network/vpc/Vpc.java
+++ b/api/src/com/cloud/network/vpc/Vpc.java
@@ -73,4 +73,10 @@ public interface Vpc extends ControlledEntity, Identity, InternalIdentity {
     boolean isRestartRequired();
 
     boolean isDisplay();
+
+    /**
+     *
+     * @return true if VPC is configured to use distributed router to provides one-hop forwarding and hypervisor based ACL
+     */
+    boolean usesDistributedRouter();
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b9a6891/api/src/org/apache/cloudstack/api/response/VpcResponse.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/response/VpcResponse.java b/api/src/org/apache/cloudstack/api/response/VpcResponse.java
index eeafb40..e3b44f2 100644
--- a/api/src/org/apache/cloudstack/api/response/VpcResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/VpcResponse.java
@@ -111,6 +111,11 @@ public class VpcResponse extends BaseResponse implements ControlledEntityRespons
     @Param(description = "is vpc for display to the regular user", since = "4.4", authorized = {RoleType.Admin})
     private Boolean forDisplay;
 
+
+    @SerializedName(ApiConstants.DISTRIBUTED_VPC_ROUTER)
+    @Param(description = "is VPC uses distributed router for one hop forwarding and host based network ACL's")
+    private boolean usesDistributedRouter;
+
     public void setId(String id) {
         this.id = id;
     }
@@ -199,4 +204,8 @@ public class VpcResponse extends BaseResponse implements ControlledEntityRespons
     public void setForDisplay(Boolean forDisplay) {
         this.forDisplay = forDisplay;
     }
+
+    public void setUsesDistributedRouter(Boolean usesDistributedRouter) {
+        this.usesDistributedRouter = usesDistributedRouter;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b9a6891/engine/schema/src/com/cloud/network/vpc/VpcVO.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/network/vpc/VpcVO.java b/engine/schema/src/com/cloud/network/vpc/VpcVO.java
index d1cfd7c..5cf8aed 100644
--- a/engine/schema/src/com/cloud/network/vpc/VpcVO.java
+++ b/engine/schema/src/com/cloud/network/vpc/VpcVO.java
@@ -81,11 +81,15 @@ public class VpcVO implements Vpc {
     @Column(name = "display", updatable = true, nullable = false)
     protected boolean display = true;
 
+    @Column(name="uses_distributed_router")
+    boolean usesDistributedRouter = false;
+
     public VpcVO() {
         uuid = UUID.randomUUID().toString();
     }
 
-    public VpcVO(long zoneId, String name, String displayText, long accountId, long domainId, long vpcOffId, String cidr, String networkDomain) {
+    public VpcVO(long zoneId, String name, String displayText, long accountId, long domainId, long vpcOffId, String cidr,
+                 String networkDomain, boolean useDistributedRouter) {
         this.zoneId = zoneId;
         this.name = name;
         this.displayText = displayText;
@@ -95,7 +99,8 @@ public class VpcVO implements Vpc {
         uuid = UUID.randomUUID().toString();
         state = State.Enabled;
         this.networkDomain = networkDomain;
-        vpcOfferingId = vpcOffId;
+        this.vpcOfferingId = vpcOffId;
+        this.usesDistributedRouter = useDistributedRouter;
     }
 
     @Override
@@ -200,5 +205,9 @@ public class VpcVO implements Vpc {
     @Override
     public IAMEntityType getEntityType() {
         return IAMEntityType.Vpc;
+
+    @Override
+    public boolean usesDistributedRouter() {
+        return usesDistributedRouter;
     }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b9a6891/server/src/com/cloud/api/ApiResponseHelper.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java
index 5f1320d..a647861 100755
--- a/server/src/com/cloud/api/ApiResponseHelper.java
+++ b/server/src/com/cloud/api/ApiResponseHelper.java
@@ -2797,6 +2797,7 @@ public class ApiResponseHelper implements ResponseGenerator {
         response.setRestartRequired(vpc.isRestartRequired());
         response.setNetworkDomain(vpc.getNetworkDomain());
         response.setForDisplay(vpc.isDisplay());
+        response.setUsesDistributedRouter(vpc.usesDistributedRouter());
 
         Map<Service, Set<Provider>> serviceProviderMap = ApiDBUtils.listVpcOffServices(vpc.getVpcOfferingId());
         List<ServiceResponse> serviceResponses = new ArrayList<ServiceResponse>();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b9a6891/server/src/com/cloud/network/vpc/VpcManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java
index 36eb444..1ff4358 100644
--- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java
+++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java
@@ -728,13 +728,13 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
                 networkDomain = "cs" + Long.toHexString(owner.getId()) + NetworkOrchestrationService.GuestDomainSuffix.valueIn(zoneId);
             }
         }
-
-        return createVpc(zoneId, vpcOffId, owner, vpcName, displayText, cidr, networkDomain, displayVpc);
+        boolean useDistributedRouter = vpcOff.supportsDistributedRouter();
+        return createVpc(zoneId, vpcOffId, owner, vpcName, displayText, cidr, networkDomain, displayVpc, useDistributedRouter);
     }
 
     @DB
     protected Vpc createVpc(final long zoneId, final long vpcOffId, final Account vpcOwner, final String vpcName, final String displayText, final String cidr,
-            final String networkDomain, final Boolean displayVpc) {
+            final String networkDomain, final Boolean displayVpc, final boolean useDistributedRouter) {
 
         //Validate CIDR
         if (!NetUtils.isValidCIDR(cidr)) {
@@ -756,7 +756,8 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
         return Transaction.execute(new TransactionCallback<VpcVO>() {
             @Override
             public VpcVO doInTransaction(TransactionStatus status) {
-                VpcVO vpc = new VpcVO(zoneId, vpcName, displayText, vpcOwner.getId(), vpcOwner.getDomainId(), vpcOffId, cidr, networkDomain);
+                VpcVO vpc = new VpcVO(zoneId, vpcName, displayText, vpcOwner.getId(), vpcOwner.getDomainId(), vpcOffId,
+                        cidr, networkDomain, useDistributedRouter);
                 if (displayVpc != null) {
                     vpc.setDisplay(displayVpc);
                 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b9a6891/server/test/com/cloud/vpc/VpcApiUnitTest.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/vpc/VpcApiUnitTest.java b/server/test/com/cloud/vpc/VpcApiUnitTest.java
index bc982a9..5e28374 100644
--- a/server/test/com/cloud/vpc/VpcApiUnitTest.java
+++ b/server/test/com/cloud/vpc/VpcApiUnitTest.java
@@ -85,7 +85,7 @@ public class VpcApiUnitTest extends TestCase {
     public void validateNtwkOffForVpc() {
         //validate network offering
         //1) correct network offering
-        VpcVO vo = new VpcVO(1, "new vpc", "new vpc", 1, 1, 1, "0.0.0.0/0", "vpc domain");
+        VpcVO vo = new VpcVO(1, "new vpc", "new vpc", 1, 1, 1, "0.0.0.0/0", "vpc domain", false);
         boolean result = false;
         try {
             _vpcService.validateNtwkOffForNtwkInVpc(2L, 1, "0.0.0.0", "111-", vo, "10.1.1.1", new AccountVO(), null);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b9a6891/server/test/com/cloud/vpc/dao/MockVpcDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/vpc/dao/MockVpcDaoImpl.java b/server/test/com/cloud/vpc/dao/MockVpcDaoImpl.java
index 7a0c7a0..e1a6ac2 100644
--- a/server/test/com/cloud/vpc/dao/MockVpcDaoImpl.java
+++ b/server/test/com/cloud/vpc/dao/MockVpcDaoImpl.java
@@ -98,9 +98,9 @@ public class MockVpcDaoImpl extends GenericDaoBase<VpcVO, Long> implements VpcDa
     public VpcVO findById(Long id) {
         VpcVO vo = null;
         if (id.longValue() == 1) {
-            vo = new VpcVO(1, "new vpc", "new vpc", 1, 1, 1, "0.0.0.0/0", "vpc domain");
+            vo = new VpcVO(1, "new vpc", "new vpc", 1, 1, 1, "0.0.0.0/0", "vpc domain", false);
         } else if (id.longValue() == 2) {
-            vo = new VpcVO(1, "new vpc", "new vpc", 1, 1, 1, "0.0.0.0/0", "vpc domain");
+            vo = new VpcVO(1, "new vpc", "new vpc", 1, 1, 1, "0.0.0.0/0", "vpc domain", false);
             vo.setState(State.Inactive);
         }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/0b9a6891/setup/db/db/schema-430to440.sql
----------------------------------------------------------------------
diff --git a/setup/db/db/schema-430to440.sql b/setup/db/db/schema-430to440.sql
index 17c255a..e9bc2ba 100644
--- a/setup/db/db/schema-430to440.sql
+++ b/setup/db/db/schema-430to440.sql
@@ -622,3 +622,4 @@ ALTER TABLE `cloud`.`guest_os` ADD COLUMN `created` datetime COMMENT 'Time when
 ALTER TABLE `cloud`.`guest_os` ADD COLUMN `removed` datetime COMMENT 'Time when Guest OS was removed if deleted, else NULL';
 UPDATE `cloud`.`guest_os` SET `created` = now();
 ALTER TABLE `cloud`.`vpc_offerings` ADD COLUMN supports_distributed_router boolean default false;
+ALTER TABLE `cloud`.`vpc` ADD COLUMN uses_distributed_router  boolean default false;


[13/31] git commit: updated refs/heads/distributedrouter to a8d43ba

Posted by mu...@apache.org.
[CLOUDSTACK-6232] bridging allowed in isolated networks


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

Branch: refs/heads/distributedrouter
Commit: 5685d145373ea05c7ceb152c4553953599b7369a
Parents: 1dc2bbd
Author: Daan Hoogland <dh...@schubergphilis.com>
Authored: Wed Mar 5 20:16:55 2014 +0100
Committer: Daan Hoogland <dh...@schubergphilis.com>
Committed: Wed Mar 12 17:47:55 2014 +0100

----------------------------------------------------------------------
 server/src/com/cloud/network/NetworkServiceImpl.java | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5685d145/server/src/com/cloud/network/NetworkServiceImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java b/server/src/com/cloud/network/NetworkServiceImpl.java
index ebeb31a..cc932ef 100755
--- a/server/src/com/cloud/network/NetworkServiceImpl.java
+++ b/server/src/com/cloud/network/NetworkServiceImpl.java
@@ -40,6 +40,8 @@ import javax.ejb.Local;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
+import org.apache.log4j.Logger;
+
 import org.apache.cloudstack.acl.ControlledEntity.ACLType;
 import org.apache.cloudstack.acl.SecurityChecker.AccessType;
 import org.apache.cloudstack.api.command.admin.network.DedicateGuestVlanRangeCmd;
@@ -53,7 +55,6 @@ import org.apache.cloudstack.context.CallContext;
 import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
 import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
 import org.apache.cloudstack.network.element.InternalLoadBalancerElementService;
-import org.apache.log4j.Logger;
 
 import com.cloud.api.ApiDBUtils;
 import com.cloud.configuration.Config;
@@ -1233,7 +1234,10 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
 
         // Vlan is created in 1 cases - works in Advance zone only:
         // 1) GuestType is Shared
-        boolean createVlan = (startIP != null && endIP != null && zone.getNetworkType() == NetworkType.Advanced && (ntwkOff.getGuestType() == Network.GuestType.Shared));
+        boolean createVlan = (startIP != null && endIP != null && zone.getNetworkType() == NetworkType.Advanced
+                && ((ntwkOff.getGuestType() == Network.GuestType.Shared)
+                		|| (ntwkOff.getGuestType() == GuestType.Isolated &&
+                		!areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat))));
 
         if (!createVlan) {
             // Only support advance shared network in IPv6, which means createVlan is a must
@@ -4030,7 +4034,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
 
     @Inject
     public void setNetworkGurus(List<NetworkGuru> networkGurus) {
-        this._networkGurus = networkGurus;
+        _networkGurus = networkGurus;
     }
 
     @Override


[04/31] git commit: updated refs/heads/distributedrouter to a8d43ba

Posted by mu...@apache.org.
CLOUDSTACK-6122: LXC systemVms run on KVM. If they are not included in the VmState report, MS assumes that system Vms are not running. MS will stop these Vms and spin new ones. So on LXC hosts, KVM Vms also have to be included in the Vmlist


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

Branch: refs/heads/distributedrouter
Commit: 6d4b979c4d0afee85d3244e07e6233ee8784db4f
Parents: 415e4bf
Author: Kishan Kavala <ki...@cloud.com>
Authored: Tue Mar 11 22:58:41 2014 +0530
Committer: Kishan Kavala <ki...@cloud.com>
Committed: Tue Mar 11 23:49:28 2014 +0530

----------------------------------------------------------------------
 .../cloud/hypervisor/kvm/resource/LibvirtComputingResource.java  | 4 ++++
 1 file changed, 4 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6d4b979c/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
index f4f6c74..3a5d27c 100755
--- a/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
+++ b/plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java
@@ -4384,6 +4384,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
             try {
                 conn = LibvirtConnection.getConnectionByType(HypervisorType.LXC.toString());
                 vmStates.putAll(getAllVms(conn));
+                conn = LibvirtConnection.getConnectionByType(HypervisorType.KVM.toString());
+                vmStates.putAll(getAllVms(conn));
             } catch (LibvirtException e) {
                 s_logger.debug("Failed to get connection: " + e.getMessage());
             }
@@ -4480,6 +4482,8 @@ public class LibvirtComputingResource extends ServerResourceBase implements Serv
             try {
                 conn = LibvirtConnection.getConnectionByType(HypervisorType.LXC.toString());
                 vmStates.putAll(getHostVmStateReport(conn));
+                conn = LibvirtConnection.getConnectionByType(HypervisorType.KVM.toString());
+                vmStates.putAll(getHostVmStateReport(conn));
             } catch (LibvirtException e) {
                 s_logger.debug("Failed to get connection: " + e.getMessage());
             }


[06/31] git commit: updated refs/heads/distributedrouter to a8d43ba

Posted by mu...@apache.org.
CLOUDSTACK-6218: Serialize VR commands in VR resource


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

Branch: refs/heads/distributedrouter
Commit: b399c315a3fceae699fa24dc1ff2bbae191ddd07
Parents: 36558e4
Author: Sheng Yang <sh...@citrix.com>
Authored: Mon Mar 10 12:52:07 2014 -0700
Committer: Sheng Yang <sh...@citrix.com>
Committed: Tue Mar 11 11:58:56 2014 -0700

----------------------------------------------------------------------
 .../virtualnetwork/VirtualRoutingResource.java       | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b399c315/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
index f22a0db..29a176a 100755
--- a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
+++ b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
@@ -77,6 +77,8 @@ import java.util.Map;
 import java.util.Queue;
 import java.util.UUID;
 import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
 
 /**
  * VirtualNetworkResource controls and configures virtual networking
@@ -123,6 +125,7 @@ public class VirtualRoutingResource {
     private static final Logger s_logger = Logger.getLogger(VirtualRoutingResource.class);
     private VirtualRouterDeployer _vrDeployer;
     private Map <String, Queue> _vrAggregateCommandsSet;
+    protected Map<String, Lock> _vrLockMap = new HashMap<String, Lock>();
 
     private String _name;
     private int _sleep;
@@ -137,13 +140,22 @@ public class VirtualRoutingResource {
 
     public Answer executeRequest(final NetworkElementCommand cmd) {
         boolean aggregated = false;
+        String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
+        Lock lock;
+        if (_vrLockMap.containsKey(routerName)) {
+            lock = _vrLockMap.get(routerName);
+        } else {
+            lock = new ReentrantLock();
+            _vrLockMap.put(routerName, lock);
+        }
+        lock.lock();
+
         try {
             ExecutionResult rc = _vrDeployer.prepareCommand(cmd);
             if (!rc.isSuccess()) {
                 s_logger.error("Failed to prepare VR command due to " + rc.getDetails());
                 return new Answer(cmd, false, rc.getDetails());
             }
-            String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
 
             assert cmd.getRouterAccessIp() != null : "Why there is no access IP for VR?";
 
@@ -174,6 +186,7 @@ public class VirtualRoutingResource {
         } catch (final IllegalArgumentException e) {
             return new Answer(cmd, false, e.getMessage());
         } finally {
+            lock.unlock();
             if (!aggregated) {
                 ExecutionResult rc = _vrDeployer.cleanupCommand(cmd);
                 if (!rc.isSuccess()) {


[09/31] git commit: updated refs/heads/distributedrouter to a8d43ba

Posted by mu...@apache.org.
CLOUDSTACK-6229: UI > Delete Host action > if hypervisor is XenServer, display 'The host has been deleted. Please eject the host from XenServer Pool'.


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

Branch: refs/heads/distributedrouter
Commit: e7ad33c456d79cab6241c7f3ab83415cd7f3e942
Parents: 3e097a0
Author: Jessica Wang <je...@apache.org>
Authored: Tue Mar 11 15:15:17 2014 -0700
Committer: Jessica Wang <je...@apache.org>
Committed: Tue Mar 11 15:15:17 2014 -0700

----------------------------------------------------------------------
 ui/scripts/system.js | 28 ++++++++++++++++++----------
 1 file changed, 18 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/e7ad33c4/ui/scripts/system.js
----------------------------------------------------------------------
diff --git a/ui/scripts/system.js b/ui/scripts/system.js
index bfdc8d5..cdd02b2 100644
--- a/ui/scripts/system.js
+++ b/ui/scripts/system.js
@@ -14762,9 +14762,9 @@
                                         return 'label.action.remove.host';
                                     }
                                 },
-                                preFilter: function (args) {
-                                    if (isAdmin()) {
-                                        args.$form.find('.form-item[rel=isForced]').css('display', 'inline-block');
+                                preFilter: function(args) { //bug to fix: preFilter is not picked up from here                              
+                                	if (!isAdmin()) {
+                                        args.$form.find('.form-item[rel=isForced]').hide();
                                     }
                                 },
                                 createForm: {
@@ -14774,25 +14774,33 @@
                                         isForced: {
                                             label: 'force.remove',
                                             isBoolean: true,
-                                            isHidden: true
+                                            isHidden: false
                                         }
                                     }
                                 },
                                 action: function (args) {
-                                    var array1 =[];
-                                    //if(args.$form.find('.form-item[rel=isForced]').css("display") != "none") //uncomment after Brian fix it to include $form in args
-                                    array1.push("&forced=" + (args.data.isForced == "on"));
+                                    var data = {
+                                    	id: args.context.hosts[0].id
+                                    };                                    
+                                    if(args.$form.find('.form-item[rel=isForced]').css("display") != "none") {
+                                    	$.extend(data, {
+                                    		forced: (args.data.isForced == "on")
+                                    	});                                    	
+                                    }
                                     
                                     $.ajax({
-                                        url: createURL("deleteHost&id=" + args.context.hosts[0].id + array1.join("")),
-                                        dataType: "json",
-                                        async: true,
+                                        url: createURL("deleteHost"),
+                                        data: data,
                                         success: function (json) {
                                             //{ "deletehostresponse" : { "success" : "true"}  }
                                             args.response.success({
                                                 data: {
                                                 }
                                             });
+                                            
+                                            if (args.context.hosts[0].hypervisor == "XenServer"){
+                                            	cloudStack.dialog.notice({ message: _s("The host has been deleted. Please eject the host from XenServer Pool") })
+                                            }                                            
                                         }
                                     });
                                 },


[22/31] git commit: updated refs/heads/distributedrouter to a8d43ba

Posted by mu...@apache.org.
-introduces 'DistributedRouter' as capability to 'Connectivity' service.
-create VPC offering to permit 'DistributedRouter' as capability to
connectivity service


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

Branch: refs/heads/distributedrouter
Commit: 85c9b09cb85b7a8863e8989aa7f0ce5abefc01a7
Parents: 5779292
Author: Murali Reddy <mu...@gmail.com>
Authored: Tue Mar 4 16:42:17 2014 +0530
Committer: Murali Reddy <mu...@gmail.com>
Committed: Thu Mar 13 19:22:06 2014 +0530

----------------------------------------------------------------------
 api/src/com/cloud/network/Network.java          |  3 +-
 api/src/com/cloud/network/vpc/VpcOffering.java  |  5 ++
 .../network/vpc/VpcProvisioningService.java     |  6 +-
 .../org/apache/cloudstack/api/ApiConstants.java |  1 +
 .../command/admin/vpc/CreateVPCOfferingCmd.java | 10 +++-
 .../api/response/VpcOfferingResponse.java       |  8 +++
 .../com/cloud/network/vpc/VpcOfferingVO.java    | 12 +++-
 .../management/ContrailManagerImpl.java         |  2 +-
 server/src/com/cloud/api/ApiResponseHelper.java |  1 +
 .../com/cloud/network/vpc/VpcManagerImpl.java   | 63 +++++++++++++++++---
 setup/db/db/schema-430to440.sql                 |  1 +
 11 files changed, 98 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/85c9b09c/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 6dc6752..3283a55 100644
--- a/api/src/com/cloud/network/Network.java
+++ b/api/src/com/cloud/network/Network.java
@@ -57,7 +57,7 @@ public interface Network extends ControlledEntity, StateObject<Network.State>, I
         public static final Service PortForwarding = new Service("PortForwarding");
         public static final Service SecurityGroup = new Service("SecurityGroup");
         public static final Service NetworkACL = new Service("NetworkACL", Capability.SupportedProtocols);
-        public static final Service Connectivity = new Service("Connectivity");
+        public static final Service Connectivity = new Service("Connectivity", Capability.DistributedRouter);
 
         private final String name;
         private final Capability[] caps;
@@ -186,6 +186,7 @@ public interface Network extends ControlledEntity, StateObject<Network.State>, I
         public static final Capability SslTermination = new Capability("SslTermination");
         public static final Capability LbSchemes = new Capability("LbSchemes");
         public static final Capability DhcpAccrossMultipleSubnets = new Capability("DhcpAccrossMultipleSubnets");
+        public static final Capability DistributedRouter = new Capability("DistributedRouter");
 
         private final String name;
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/85c9b09c/api/src/com/cloud/network/vpc/VpcOffering.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/network/vpc/VpcOffering.java b/api/src/com/cloud/network/vpc/VpcOffering.java
index 6e75a2f..a0a1b15 100644
--- a/api/src/com/cloud/network/vpc/VpcOffering.java
+++ b/api/src/com/cloud/network/vpc/VpcOffering.java
@@ -55,4 +55,9 @@ public interface VpcOffering extends InternalIdentity, Identity {
      */
     Long getServiceOfferingId();
 
+    /**
+     *
+     * @return true if the offering provides a distributed router capable of one-hop forwarding
+     */
+    boolean supportsDistributedRouter();
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/85c9b09c/api/src/com/cloud/network/vpc/VpcProvisioningService.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/network/vpc/VpcProvisioningService.java b/api/src/com/cloud/network/vpc/VpcProvisioningService.java
index 174b71f..e545275 100644
--- a/api/src/com/cloud/network/vpc/VpcProvisioningService.java
+++ b/api/src/com/cloud/network/vpc/VpcProvisioningService.java
@@ -23,8 +23,10 @@ public interface VpcProvisioningService {
 
     public VpcOffering getVpcOffering(long vpcOfferingId);
 
-    public VpcOffering createVpcOffering(String name, String displayText, List<String> supportedServices, Map<String, List<String>> serviceProviders,
-        Long serviceOfferingId);
+    public VpcOffering createVpcOffering(String name, String displayText, List<String> supportedServices,
+                                         Map<String, List<String>> serviceProviders,
+                                         Map serviceCapabilitystList,
+                                         Long serviceOfferingId);
 
     List<? extends VpcOffering> listVpcOfferings(Long id, String name, String displayText, List<String> supportedServicesStr, Boolean isDefault, String keyword,
         String state, Long startIndex, Long pageSizeVal);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/85c9b09c/api/src/org/apache/cloudstack/api/ApiConstants.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java
index 089affb..643a374 100755
--- a/api/src/org/apache/cloudstack/api/ApiConstants.java
+++ b/api/src/org/apache/cloudstack/api/ApiConstants.java
@@ -588,6 +588,7 @@ public class ApiConstants {
     public static final String VGPU = "vgpu";
     public static final String VGPUTYPE = "vgputype";
     public static final String REMAININGCAPACITY = "remainingcapacity";
+    public static final String DISTRIBUTED_VPC_ROUTER = "distributedvpcrouter";
 
     public enum HostDetails {
         all, capacity, events, stats, min;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/85c9b09c/api/src/org/apache/cloudstack/api/command/admin/vpc/CreateVPCOfferingCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/admin/vpc/CreateVPCOfferingCmd.java b/api/src/org/apache/cloudstack/api/command/admin/vpc/CreateVPCOfferingCmd.java
index 6b2c4ba..5b3090b 100644
--- a/api/src/org/apache/cloudstack/api/command/admin/vpc/CreateVPCOfferingCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/admin/vpc/CreateVPCOfferingCmd.java
@@ -66,6 +66,9 @@ public class CreateVPCOfferingCmd extends BaseAsyncCreateCmd {
         + "If not specified, the provider for the service will be mapped to the default provider on the physical network")
     private Map<String, String> serviceProviderList;
 
+    @Parameter(name = ApiConstants.SERVICE_CAPABILITY_LIST, type = CommandType.MAP, description = "desired service capabilities as part of vpc offering")
+    private Map serviceCapabilitystList;
+
     @Parameter(name = ApiConstants.SERVICE_OFFERING_ID,
                type = CommandType.UUID,
                entityType = ServiceOfferingResponse.class,
@@ -112,13 +115,18 @@ public class CreateVPCOfferingCmd extends BaseAsyncCreateCmd {
         return serviceProviderMap;
     }
 
+    public Map<String, List<String>> getServiceCapabilitystList() {
+        return serviceCapabilitystList;
+    }
+
     public Long getServiceOfferingId() {
         return serviceOfferingId;
     }
 
     @Override
     public void create() throws ResourceAllocationException {
-        VpcOffering vpcOff = _vpcProvSvc.createVpcOffering(getVpcOfferingName(), getDisplayText(), getSupportedServices(), getServiceProviders(), getServiceOfferingId());
+        VpcOffering vpcOff = _vpcProvSvc.createVpcOffering(getVpcOfferingName(), getDisplayText(),
+                getSupportedServices(), getServiceProviders(), getServiceCapabilitystList(), getServiceOfferingId());
         if (vpcOff != null) {
             setEntityId(vpcOff.getId());
             setEntityUuid(vpcOff.getUuid());

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/85c9b09c/api/src/org/apache/cloudstack/api/response/VpcOfferingResponse.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/response/VpcOfferingResponse.java b/api/src/org/apache/cloudstack/api/response/VpcOfferingResponse.java
index 17e4dfd..89697f0 100644
--- a/api/src/org/apache/cloudstack/api/response/VpcOfferingResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/VpcOfferingResponse.java
@@ -59,6 +59,10 @@ public class VpcOfferingResponse extends BaseResponse {
     @Param(description = "the list of supported services", responseObject = ServiceResponse.class)
     private List<ServiceResponse> services;
 
+    @SerializedName(ApiConstants.DISTRIBUTED_VPC_ROUTER)
+    @Param(description = " indicates if the vpc offering supports distributed router for one-hop forwarding")
+    private Boolean supportsDistributedRouter;
+
     public void setId(String id) {
         this.id = id;
     }
@@ -86,4 +90,8 @@ public class VpcOfferingResponse extends BaseResponse {
     public void setState(String state) {
         this.state = state;
     }
+
+    public void setSupportsDistributedRouter(Boolean supportsDistributedRouter) {
+        this.supportsDistributedRouter = supportsDistributedRouter;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/85c9b09c/engine/schema/src/com/cloud/network/vpc/VpcOfferingVO.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/network/vpc/VpcOfferingVO.java b/engine/schema/src/com/cloud/network/vpc/VpcOfferingVO.java
index 3a676e6..53f6f60 100644
--- a/engine/schema/src/com/cloud/network/vpc/VpcOfferingVO.java
+++ b/engine/schema/src/com/cloud/network/vpc/VpcOfferingVO.java
@@ -67,6 +67,9 @@ public class VpcOfferingVO implements VpcOffering {
     @Column(name = "service_offering_id")
     Long serviceOfferingId;
 
+    @Column(name = "supports_distributed_router")
+    boolean supportsDistributedRouter=false;
+
     public VpcOfferingVO() {
         this.uuid = UUID.randomUUID().toString();
     }
@@ -80,9 +83,11 @@ public class VpcOfferingVO implements VpcOffering {
         this.state = State.Disabled;
     }
 
-    public VpcOfferingVO(String name, String displayText, boolean isDefault, Long serviceOfferingId) {
+    public VpcOfferingVO(String name, String displayText, boolean isDefault, Long serviceOfferingId,
+                         boolean supportsDistributedRouter) {
         this(name, displayText, serviceOfferingId);
         this.isDefault = isDefault;
+        this.supportsDistributedRouter = supportsDistributedRouter;
     }
 
     @Override
@@ -145,4 +150,9 @@ public class VpcOfferingVO implements VpcOffering {
     public Long getServiceOfferingId() {
         return serviceOfferingId;
     }
+
+    @Override
+    public boolean supportsDistributedRouter() {
+        return supportsDistributedRouter;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/85c9b09c/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManagerImpl.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManagerImpl.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManagerImpl.java
index 01be7db..bf083fd 100644
--- a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManagerImpl.java
+++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManagerImpl.java
@@ -281,7 +281,7 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager
         for (String svc: services) {
             serviceProviderMap.put(svc, providerSet);
         }
-        vpcOffer = _vpcProvSvc.createVpcOffering(juniperVPCOfferingName, juniperVPCOfferingDisplayText, services, serviceProviderMap, null);
+        vpcOffer = _vpcProvSvc.createVpcOffering(juniperVPCOfferingName, juniperVPCOfferingDisplayText, services, serviceProviderMap, null, null);
         ((VpcOfferingVO)vpcOffer).setState(VpcOffering.State.Enabled);
         long id = vpcOffer.getId();
         _vpcOffDao.update(id, (VpcOfferingVO)vpcOffer);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/85c9b09c/server/src/com/cloud/api/ApiResponseHelper.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java
index a2cc352..5f1320d 100755
--- a/server/src/com/cloud/api/ApiResponseHelper.java
+++ b/server/src/com/cloud/api/ApiResponseHelper.java
@@ -2754,6 +2754,7 @@ public class ApiResponseHelper implements ResponseGenerator {
         response.setDisplayText(offering.getDisplayText());
         response.setIsDefault(offering.isDefault());
         response.setState(offering.getState().name());
+        response.setSupportsDistributedRouter(offering.supportsDistributedRouter());
 
         Map<Service, Set<Provider>> serviceProviderMap = ApiDBUtils.listVpcOffServices(offering.getId());
         List<ServiceResponse> serviceResponses = new ArrayList<ServiceResponse>();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/85c9b09c/server/src/com/cloud/network/vpc/VpcManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java
index fe49981..ac82041 100644
--- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java
+++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java
@@ -18,8 +18,10 @@ package com.cloud.network.vpc;
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -231,7 +233,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
                             svcProviderMap.put(svc, defaultProviders);
                         }
                     }
-                    createVpcOffering(VpcOffering.defaultVPCOfferingName, VpcOffering.defaultVPCOfferingName, svcProviderMap, true, State.Enabled, null);
+                    createVpcOffering(VpcOffering.defaultVPCOfferingName, VpcOffering.defaultVPCOfferingName, svcProviderMap, true, State.Enabled, null, false);
                 }
 
                 //configure default vpc offering with Netscaler as LB Provider
@@ -250,7 +252,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
                             svcProviderMap.put(svc, defaultProviders);
                         }
                     }
-                    createVpcOffering(VpcOffering.defaultVPCNSOfferingName, VpcOffering.defaultVPCNSOfferingName, svcProviderMap, false, State.Enabled, null);
+                    createVpcOffering(VpcOffering.defaultVPCNSOfferingName, VpcOffering.defaultVPCNSOfferingName, svcProviderMap, false, State.Enabled, null, false);
                 }
             }
         });
@@ -299,8 +301,10 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
 
     @Override
     @ActionEvent(eventType = EventTypes.EVENT_VPC_OFFERING_CREATE, eventDescription = "creating vpc offering", create = true)
-    public VpcOffering createVpcOffering(String name, String displayText, List<String> supportedServices, Map<String, List<String>> serviceProviders,
-        Long serviceOfferingId) {
+    public VpcOffering createVpcOffering(String name, String displayText, List<String> supportedServices,
+                                         Map<String, List<String>> serviceProviders,
+                                         Map serviceCapabilitystList,
+                                         Long serviceOfferingId) {
         Map<Network.Service, Set<Network.Provider>> svcProviderMap = new HashMap<Network.Service, Set<Network.Provider>>();
         Set<Network.Provider> defaultProviders = new HashSet<Network.Provider>();
         defaultProviders.add(Provider.VPCVirtualRouter);
@@ -372,20 +376,25 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
             }
         }
 
-        VpcOffering offering = createVpcOffering(name, displayText, svcProviderMap, false, null, serviceOfferingId);
+        boolean supportsDistributedRouter = isVpcOfferingSupportsDistributedRouter(serviceCapabilitystList);
+
+        VpcOffering offering = createVpcOffering(name, displayText, svcProviderMap, false, null,
+                serviceOfferingId,supportsDistributedRouter);
         CallContext.current().setEventDetails(" Id: " + offering.getId() + " Name: " + name);
 
         return offering;
     }
 
     @DB
-    protected VpcOffering createVpcOffering(final String name, final String displayText, final Map<Network.Service, Set<Network.Provider>> svcProviderMap,
-        final boolean isDefault, final State state, final Long serviceOfferingId) {
+    protected VpcOffering createVpcOffering(final String name, final String displayText,
+                                            final Map<Network.Service, Set<Network.Provider>> svcProviderMap,
+                                            final boolean isDefault, final State state, final Long serviceOfferingId,
+                                            final boolean supportsDistributedRouter) {
         return Transaction.execute(new TransactionCallback<VpcOffering>() {
             @Override
             public VpcOffering doInTransaction(TransactionStatus status) {
                 // create vpc offering object
-                VpcOfferingVO offering = new VpcOfferingVO(name, displayText, isDefault, serviceOfferingId);
+                VpcOfferingVO offering = new VpcOfferingVO(name, displayText, isDefault, serviceOfferingId, supportsDistributedRouter);
 
                 if (state != null) {
                     offering.setState(state);
@@ -413,6 +422,44 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
         });
     }
 
+    private boolean isVpcOfferingSupportsDistributedRouter(Map serviceCapabilitystList) {
+        boolean supportsDistributedRouter = false;
+        if (serviceCapabilitystList != null && !serviceCapabilitystList.isEmpty()) {
+            Collection serviceCapabilityCollection = serviceCapabilitystList.values();
+            Iterator iter = serviceCapabilityCollection.iterator();
+            Map<Network.Capability, String> capabilityMap = null;
+
+            while (iter.hasNext()) {
+                HashMap<String, String> svcCapabilityMap = (HashMap<String, String>)iter.next();
+                Network.Capability capability = null;
+                String svc = svcCapabilityMap.get("service");
+                String capabilityName = svcCapabilityMap.get("capabilitytype");
+                String capabilityValue = svcCapabilityMap.get("capabilityvalue");
+                if (capabilityName != null) {
+                    capability = Network.Capability.getCapability(capabilityName);
+                }
+
+                if ((capability == null) || (capabilityName == null) || (capabilityValue == null)) {
+                    throw new InvalidParameterValueException("Invalid capability:" + capabilityName + " capability value:" + capabilityValue);
+                }
+
+                if (!svc.equalsIgnoreCase(Service.Connectivity.getName())) {
+                    throw new InvalidParameterValueException("Invalid Service:" + svc + " specified. Only for 'Connectivity' service capabilities can be specified");
+                }
+
+                if (!capabilityName.equalsIgnoreCase("DistributedRouter")) {
+                    throw new InvalidParameterValueException("Invalid Capability:" + capabilityName + " specified. Only 'DistributedRouter' capability can be specified.");
+                }
+
+                if (!capabilityValue.equalsIgnoreCase("true") && capabilityValue.equalsIgnoreCase("false")) {
+                    throw new InvalidParameterValueException("Invalid Capability value:" + capabilityValue + " specified.");
+                }
+                supportsDistributedRouter = capabilityValue.equalsIgnoreCase("true");
+            }
+        }
+        return supportsDistributedRouter;
+    }
+
     @Override
     public Vpc getActiveVpc(long vpcId) {
         return _vpcDao.getActiveVpcById(vpcId);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/85c9b09c/setup/db/db/schema-430to440.sql
----------------------------------------------------------------------
diff --git a/setup/db/db/schema-430to440.sql b/setup/db/db/schema-430to440.sql
index ab6bc98..17c255a 100644
--- a/setup/db/db/schema-430to440.sql
+++ b/setup/db/db/schema-430to440.sql
@@ -621,3 +621,4 @@ UPDATE `cloud`.`guest_os_hypervisor` SET `created` = now();
 ALTER TABLE `cloud`.`guest_os` ADD COLUMN `created` datetime COMMENT 'Time when Guest OS was created in system';
 ALTER TABLE `cloud`.`guest_os` ADD COLUMN `removed` datetime COMMENT 'Time when Guest OS was removed if deleted, else NULL';
 UPDATE `cloud`.`guest_os` SET `created` = now();
+ALTER TABLE `cloud`.`vpc_offerings` ADD COLUMN supports_distributed_router boolean default false;


[11/31] git commit: updated refs/heads/distributedrouter to a8d43ba

Posted by mu...@apache.org.
CLOUDSTACK-6047: Enable VR aggregation commands for VPC


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

Branch: refs/heads/distributedrouter
Commit: 467986321a602f79e63205168c58a2410caeeddc
Parents: e7ad33c
Author: Sheng Yang <sh...@citrix.com>
Authored: Tue Mar 11 15:55:45 2014 -0700
Committer: Sheng Yang <sh...@citrix.com>
Committed: Tue Mar 11 16:14:33 2014 -0700

----------------------------------------------------------------------
 .../VpcVirtualNetworkApplianceManagerImpl.java  | 40 +++++++++++---------
 1 file changed, 23 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/46798632/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java
index f7fdd08..8296460 100644
--- a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java
+++ b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java
@@ -17,29 +17,14 @@
 package com.cloud.network.router;
 
 
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.TreeSet;
-
-import javax.ejb.Local;
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.log4j.Logger;
-import org.springframework.stereotype.Component;
-
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.Command;
 import com.cloud.agent.api.Command.OnError;
 import com.cloud.agent.api.NetworkUsageCommand;
 import com.cloud.agent.api.PlugNicCommand;
 import com.cloud.agent.api.SetupGuestNetworkCommand;
+import com.cloud.agent.api.routing.AggregationControlCommand;
+import com.cloud.agent.api.routing.AggregationControlCommand.Action;
 import com.cloud.agent.api.routing.IpAssocVpcCommand;
 import com.cloud.agent.api.routing.NetworkElementCommand;
 import com.cloud.agent.api.routing.SetNetworkACLCommand;
@@ -128,6 +113,21 @@ import com.cloud.vm.VirtualMachine.State;
 import com.cloud.vm.VirtualMachineProfile;
 import com.cloud.vm.VirtualMachineProfile.Param;
 import com.cloud.vm.dao.VMInstanceDao;
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeSet;
 
 @Component
 @Local(value = {VpcVirtualNetworkApplianceManager.class, VpcVirtualNetworkApplianceService.class})
@@ -861,12 +861,18 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian
 
         for (Pair<Nic, Network> nicNtwk : guestNics) {
             Nic guestNic = nicNtwk.first();
+            AggregationControlCommand startCmd = new AggregationControlCommand(Action.Start, router.getInstanceName(), controlNic.getIp4Address(),
+                    getRouterIpInNetwork(guestNic.getNetworkId(), router.getId()));
+            cmds.addCommand(startCmd);
             if (reprogramGuestNtwks) {
                 finalizeIpAssocForNetwork(cmds, router, provider, guestNic.getNetworkId(), vlanMacAddress);
                 finalizeNetworkRulesForNetwork(cmds, router, provider, guestNic.getNetworkId());
             }
 
             finalizeUserDataAndDhcpOnStart(cmds, router, provider, guestNic.getNetworkId());
+            AggregationControlCommand finishCmd = new AggregationControlCommand(Action.Finish, router.getInstanceName(), controlNic.getIp4Address(),
+                    getRouterIpInNetwork(guestNic.getNetworkId(), router.getId()));
+            cmds.addCommand(finishCmd);
         }
 
         //Add network usage commands


[27/31] git commit: updated refs/heads/distributedrouter to a8d43ba

Posted by mu...@apache.org.
adds hypervisor script to convert JSON routing polcies (ACL) config in
to flow rules and applies them on the bridge

add event subscriber in OvsTunnelManager, that listens to
replaceNetworkAcl events. On event sends the updated policy info to all
the hosts in the VPC


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

Branch: refs/heads/distributedrouter
Commit: a572711bfae476280816f19131a2b489069f8c08
Parents: 9964688
Author: Murali Reddy <mu...@gmail.com>
Authored: Tue Mar 11 04:07:13 2014 +0530
Committer: Murali Reddy <mu...@gmail.com>
Committed: Thu Mar 13 19:22:09 2014 +0530

----------------------------------------------------------------------
 .../xen/resource/CitrixResourceBase.java        |  24 +++-
 .../api/OvsVpcLogicalTopologyConfigCommand.java |  33 -----
 .../OvsVpcPhysicalTopologyConfigCommand.java    |   6 +-
 .../api/OvsVpcRoutingPolicyConfigCommand.java   | 124 +++++++++++++++++++
 .../cloud/network/ovs/OvsTunnelManagerImpl.java | 104 ++++++++++++++--
 .../xenserver/cloudstack_pluginlib.py           |  76 +++++++++++-
 scripts/vm/hypervisor/xenserver/ovstunnel       |  14 ++-
 .../network/vpc/NetworkACLManagerImpl.java      |  12 +-
 8 files changed, 337 insertions(+), 56 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a572711b/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 2315b31..da92e1e 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
@@ -16,6 +16,7 @@
 // under the License.
 package com.cloud.hypervisor.xen.resource;
 
+import com.cloud.agent.api.*;
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileInputStream;
@@ -88,6 +89,7 @@ import org.apache.cloudstack.storage.to.TemplateObjectTO;
 import org.apache.cloudstack.storage.to.VolumeObjectTO;
 
 import com.cloud.agent.IAgentControl;
+
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.AttachIsoCommand;
 import com.cloud.agent.api.AttachVolumeAnswer;
@@ -509,6 +511,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
             return execute((OvsDeleteFlowCommand)cmd);
         } else if (clazz == OvsVpcPhysicalTopologyConfigCommand.class) {
             return execute((OvsVpcPhysicalTopologyConfigCommand) cmd);
+        } else if (clazz == OvsVpcRoutingPolicyConfigCommand.class) {
+            return execute((OvsVpcRoutingPolicyConfigCommand) cmd);
         } else if (clazz == CleanupNetworkRulesCmd.class) {
             return execute((CleanupNetworkRulesCmd)cmd);
         } else if (clazz == NetworkRulesSystemVmCommand.class) {
@@ -532,7 +536,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
         } else if (clazz == PlugNicCommand.class) {
             return execute((PlugNicCommand)cmd);
         } else if (clazz == UnPlugNicCommand.class) {
-            return execute((UnPlugNicCommand)cmd);
+            return execute((UnPlugNicCommand) cmd);
         } else if (cmd instanceof StorageSubSystemCommand) {
             return storageHandler.handleStorageCommands((StorageSubSystemCommand) cmd);
         } else if (clazz == CreateVMSnapshotCommand.class) {
@@ -5282,8 +5286,24 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
         Connection conn = getConnection();
         try {
             String result = callHostPlugin(conn, "ovstunnel", "configure_ovs_bridge_for_network_topology", "bridge",
+                    cmd.getBridgeName(), "config", cmd.getVpcConfigInJson());
+            if (result.equalsIgnoreCase("SUCCESS")) {
+                return new Answer(cmd, true, result);
+            } else {
+                return new Answer(cmd, false, result);
+            }
+        } catch  (Exception e) {
+            s_logger.warn("caught exception while updating host with latest routing polcies", e);
+            return new Answer(cmd, false, e.getMessage());
+        }
+    }
+
+    public Answer execute(OvsVpcRoutingPolicyConfigCommand cmd) {
+        Connection conn = getConnection();
+        try {
+            String result = callHostPlugin(conn, "ovstunnel", "configure_ovs_bridge_for_routing_policies", "bridge",
                     cmd.getBridgeName(), "host-id", ((Long)cmd.getHostId()).toString(), "config",
-                    cmd.getjsonVpcConfig());
+                    cmd.getVpcConfigInJson());
             if (result.equalsIgnoreCase("SUCCESS")) {
                 return new Answer(cmd, true, result);
             } else {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a572711b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcLogicalTopologyConfigCommand.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcLogicalTopologyConfigCommand.java b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcLogicalTopologyConfigCommand.java
deleted file mode 100644
index 2fafb6e..0000000
--- a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcLogicalTopologyConfigCommand.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// 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 com.cloud.agent.api;
-
-/**
- * This command represents view of how a VPC is laid out (on which hosts, which VM is on which host etc)
- * on the physical infrastructure.
- */
-public class OvsVpcLogicalTopologyConfigCommand extends Command {
-
-    public OvsVpcLogicalTopologyConfigCommand() {
-
-    }
-
-    @Override
-    public boolean executeInSequence() {
-        return false;
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a572711b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcPhysicalTopologyConfigCommand.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcPhysicalTopologyConfigCommand.java b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcPhysicalTopologyConfigCommand.java
index e6f4383..17299d3 100644
--- a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcPhysicalTopologyConfigCommand.java
+++ b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcPhysicalTopologyConfigCommand.java
@@ -20,8 +20,8 @@ import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 
 /**
- * This command represents physical view of how a VPC is laid out on the physical infrastructure.
- *   - on which hypervisor hosts VPC spans (host is running in at least one VM from the VPC)
+ * This command represents physical view of how a VPC is laid out on the physical infrastructure. Contains information:
+ *   - on which hypervisor hosts VPC spans (host running at least one VM from the VPC)
  *   - information of tiers, so we can figure how one VM can talk to a different VM in same tier or different tier
  *   - information on all the VM's in the VPC.
  *   - information of NIC's of each VM in the VPC
@@ -102,7 +102,7 @@ public class OvsVpcPhysicalTopologyConfigCommand extends Command {
         vpcConfig = new VpcConfig(vpc);
     }
 
-    public String getjsonVpcConfig() {
+    public String getVpcConfigInJson() {
         Gson gson = new GsonBuilder().create();
         return gson.toJson(vpcConfig).toLowerCase();
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a572711b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcRoutingPolicyConfigCommand.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcRoutingPolicyConfigCommand.java b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcRoutingPolicyConfigCommand.java
new file mode 100644
index 0000000..8e4d5d1
--- /dev/null
+++ b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcRoutingPolicyConfigCommand.java
@@ -0,0 +1,124 @@
+// 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 com.cloud.agent.api;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import java.util.UUID;
+
+/**
+ * This command represents logical view of VM's connectivity in VPC.
+ */
+public class OvsVpcRoutingPolicyConfigCommand extends Command {
+
+    VpcConfig vpcConfig =null;
+    long hostId;
+    String bridgeName;
+
+    public static class AclItem {
+        int number;
+        String uuid;
+        String action;
+        String direction;
+        String sourcePortStart;
+        String sourcePortEnd;
+        String protocol;
+        String[] sourceCidrs;
+        public AclItem(int number, String uuid, String action, String direction, String sourcePortStart,
+                       String sourcePortEnd, String protocol, String[] sourceCidrs) {
+            this.number = number;
+            this.uuid =uuid;
+            this.action = action;
+            this.direction = direction;
+            this.sourceCidrs = sourceCidrs;
+            this.sourcePortStart = sourcePortStart;
+            this.sourcePortEnd = sourcePortEnd;
+            this.protocol = protocol;
+        }
+    }
+
+    public static class Acl {
+        String id;
+        AclItem[] aclItems;
+        public Acl(String uuid, AclItem[] aclItems) {
+            this.id = uuid;
+            this.aclItems = aclItems;
+        }
+    }
+
+    public static class Tier {
+        String id;
+        String cidr;
+        String aclId;
+        public Tier(String uuid, String cidr, String aclId) {
+            this.id = uuid;
+            this.cidr = cidr;
+            this.aclId = aclId;
+        }
+    }
+
+    public class Vpc {
+        String cidr;
+        String id;
+        Acl[] acls;
+        Tier[] tiers;
+        public Vpc(String id, String cidr, Acl[] acls, Tier[] tiers) {
+            this.id = id;
+            this.cidr = cidr;
+            this.acls = acls;
+            this.tiers = tiers;
+        }
+    }
+
+    public static class VpcConfig {
+        Vpc vpc;
+        public VpcConfig(Vpc vpc) {
+            this.vpc = vpc;
+        }
+    }
+
+    public OvsVpcRoutingPolicyConfigCommand(String id, String cidr, Acl[] acls, Tier[] tiers) {
+        Vpc vpc = new Vpc(id, cidr, acls, tiers);
+        vpcConfig = new VpcConfig(vpc);
+    }
+
+    public String getVpcConfigInJson() {
+        Gson gson = new GsonBuilder().create();
+        return gson.toJson(vpcConfig).toLowerCase();
+    }
+
+    public void setHostId(long hostId) {
+        this.hostId = hostId;
+    }
+
+    public long getHostId() {
+        return hostId;
+    }
+
+    public String getBridgeName() {
+        return bridgeName;
+    }
+
+    public void setBridgeName(String bridgeName) {
+        this.bridgeName = bridgeName;
+    }
+
+    @Override
+    public boolean executeInSequence() {
+        return false;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a572711b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
index 82dbfed..35b0035 100644
--- a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
+++ b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
@@ -16,8 +16,12 @@
 // under the License.
 package com.cloud.network.ovs;
 
+import com.amazonaws.services.ec2.model.NetworkAcl;
+import com.cloud.agent.api.*;
 import com.cloud.network.dao.NetworkDao;
-import com.cloud.network.vpc.VpcManager;
+import com.cloud.network.dao.NetworkVO;
+import com.cloud.network.vpc.*;
+import com.cloud.network.vpc.dao.NetworkACLDao;
 import com.cloud.vm.dao.VMInstanceDao;
 import com.cloud.vm.Nic;
 import com.cloud.vm.NicVO;
@@ -33,22 +37,14 @@ import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 import javax.persistence.EntityExistsException;
 
+import org.apache.cloudstack.framework.messagebus.MessageBus;
+import org.apache.cloudstack.framework.messagebus.MessageSubscriber;
 import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
 
 import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
 
 import com.cloud.agent.AgentManager;
-import com.cloud.agent.api.Answer;
-import com.cloud.agent.api.Command;
-import com.cloud.agent.api.OvsCreateTunnelAnswer;
-import com.cloud.agent.api.OvsCreateTunnelCommand;
-import com.cloud.agent.api.OvsDestroyBridgeCommand;
-import com.cloud.agent.api.OvsDestroyTunnelCommand;
-import com.cloud.agent.api.OvsFetchInterfaceAnswer;
-import com.cloud.agent.api.OvsFetchInterfaceCommand;
-import com.cloud.agent.api.OvsSetupBridgeCommand;
-import com.cloud.agent.api.OvsVpcPhysicalTopologyConfigCommand;
 import com.cloud.agent.manager.Commands;
 import com.cloud.configuration.Config;
 import com.cloud.exception.AgentUnavailableException;
@@ -68,7 +64,6 @@ import com.cloud.network.ovs.dao.OvsTunnelNetworkDao;
 import com.cloud.network.ovs.dao.OvsTunnelNetworkVO;
 import com.cloud.network.ovs.dao.OvsTunnel;
 import com.cloud.network.vpc.dao.VpcDao;
-import com.cloud.network.vpc.VpcVO;
 import com.cloud.utils.component.ManagerBase;
 import com.cloud.utils.concurrency.NamedThreadFactory;
 import com.cloud.utils.db.DB;
@@ -112,6 +107,12 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
     protected VMInstanceDao _vmInstanceDao;
     @Inject
     NetworkDao _networkDao;
+    @Inject
+    MessageBus _messageBus;
+    @Inject
+    NetworkACLDao _networkACLDao;
+    @Inject
+    NetworkACLItemDao _networkACLItemDao;
 
     @Override
     public boolean configure(String name, Map<String, Object> params)
@@ -119,6 +120,7 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
         _executorPool = Executors.newScheduledThreadPool(10, new NamedThreadFactory("OVS"));
         _cleanupExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("OVS-Cleanup"));
 
+        _messageBus.subscribe("Network_ACL_Replaced", new NetworkAclEventsSubscriber());
         return true;
     }
 
@@ -725,4 +727,82 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
             }
         }
     }
+
+    // Subscriber to ACL replace events. On acl replace event, if the vpc is enabled for distributed routing
+    // send the ACL update to all the hosts on which VPC spans
+    public class NetworkAclEventsSubscriber implements MessageSubscriber {
+        @Override
+        public void onPublishMessage(String senderAddress, String subject, Object args) {
+            NetworkVO network = (NetworkVO) args;
+            String bridgeName=generateBridgeNameForVpc(network.getVpcId());
+            if (network.getVpcId() != null & isVpcEnabledForDistributedRouter(network.getVpcId())) {
+                long vpcId = network.getVpcId();
+                OvsVpcRoutingPolicyConfigCommand cmd = prepareVpcRoutingPolicyUpdate(vpcId);
+                List<Long> vpcSpannedHostIds = _ovsNetworkToplogyGuru.getVpcSpannedHosts(vpcId);
+                for (Long id: vpcSpannedHostIds) {
+                    if (!sendVpcRoutingPolicyChangeUpdate(cmd, id, bridgeName)) {
+                        s_logger.debug("Failed to send VPC routing policy change update to host : " + id +
+                                ". Moving on with rest of the host updates.");
+                    }
+                }
+            }
+        }
+    }
+
+    OvsVpcRoutingPolicyConfigCommand prepareVpcRoutingPolicyUpdate(long vpcId) {
+        VpcVO vpc = _vpcDao.findById(vpcId);
+        assert (vpc != null): "invalid vpc id";
+        List<OvsVpcRoutingPolicyConfigCommand.Acl> acls = new ArrayList<>();
+        List<OvsVpcRoutingPolicyConfigCommand.Tier> tiers = new ArrayList<>();
+
+        List<? extends Network> vpcNetworks =  _vpcMgr.getVpcNetworks(vpcId);
+        for (Network network : vpcNetworks) {
+            Long networkAclId = network.getNetworkACLId();
+            NetworkACLVO networkAcl = _networkACLDao.findById(networkAclId);
+
+            List<OvsVpcRoutingPolicyConfigCommand.AclItem> aclItems = new ArrayList<>();
+            List<NetworkACLItemVO> aclItemVos = _networkACLItemDao.listByACL(networkAclId);
+            for (NetworkACLItemVO aclItem : aclItemVos) {
+                String[] sourceCidrs = aclItem.getSourceCidrList().toArray(new String[aclItem.getSourceCidrList().size()]);
+                aclItems.add(new OvsVpcRoutingPolicyConfigCommand.AclItem(
+                        aclItem.getNumber(), aclItem.getUuid(), aclItem.getAction().name(),
+                        aclItem.getTrafficType().name(),
+                        aclItem.getSourcePortStart().toString(), aclItem.getSourcePortEnd().toString(),
+                        aclItem.getProtocol(), sourceCidrs));
+            }
+
+            OvsVpcRoutingPolicyConfigCommand.Acl acl = new OvsVpcRoutingPolicyConfigCommand.Acl(networkAcl.getUuid(),
+                    aclItems.toArray(new OvsVpcRoutingPolicyConfigCommand.AclItem[aclItems.size()]));
+            acls.add(acl);
+
+            OvsVpcRoutingPolicyConfigCommand.Tier tier = new OvsVpcRoutingPolicyConfigCommand.Tier(network.getUuid(),
+                    network.getCidr(), networkAcl.getUuid());
+            tiers.add(tier);
+        }
+
+        OvsVpcRoutingPolicyConfigCommand cmd = new OvsVpcRoutingPolicyConfigCommand(vpc.getUuid(), vpc.getCidr(),
+                acls.toArray(new OvsVpcRoutingPolicyConfigCommand.Acl[acls.size()]),
+                tiers.toArray(new OvsVpcRoutingPolicyConfigCommand.Tier[tiers.size()]));
+        return cmd;
+    }
+
+
+    public boolean sendVpcRoutingPolicyChangeUpdate(OvsVpcRoutingPolicyConfigCommand updateCmd, long hostId, String bridgeName) {
+        try {
+            s_logger.debug("Sending VPC routing policy change update to the host " + hostId);
+            updateCmd.setHostId(hostId);
+            updateCmd.setBridgeName(bridgeName);
+            Answer ans = _agentMgr.send(hostId, updateCmd);
+            if (ans.getResult()) {
+                s_logger.debug("Successfully updated the host " + hostId + " with latest VPC routing policies." );
+                return true;
+            }  else {
+                s_logger.debug("Failed to update the host " + hostId + " with latest routing policy." );
+                return false;
+            }
+        } catch (Exception e) {
+            s_logger.debug("Failed to updated the host " + hostId + " with latest routing policy." );
+            return false;
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a572711b/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py b/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py
index dbcc288..ac8a11d 100644
--- a/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py
+++ b/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py
@@ -312,7 +312,7 @@ class jsonLoader(object):
         return '{%s}' % str(', '.join('%s : %s' % (k, repr(v)) for (k, v)
                                       in self.__dict__.iteritems()))
 
-def configure_bridge_for_topology(bridge, this_host_id, json_config):
+def configure_bridge_for_network_topology(bridge, this_host_id, json_config):
     vpconfig = jsonLoader(json.loads(json_config)).vpc
 
     if vpconfig is None:
@@ -372,4 +372,76 @@ def configure_bridge_for_topology(bridge, this_host_id, json_config):
                 # set DST MAC = VM's MAC, SRC MAC=tier gateway MAC and send to egress table
                 add_ip_lookup_table_entry(bridge, ip, network.gatewaymac, mac_addr)
 
-    return "SUCCESS: successfully configured bridge as per the VPC toplogy"
\ No newline at end of file
+    return "SUCCESS: successfully configured bridge as per the VPC topology"
+
+def get_acl(vpcconfig, required_acl_id):
+    acls = vpcconfig.acls
+    for acl in acls:
+        if acl.id == required_acl_id:
+            return acl
+    return None
+
+def configure_ovs_bridge_for_routing_policies(bridge, json_config):
+    vpconfig = jsonLoader(json.loads(json_config)).vpc
+
+    if vpconfig is None:
+        logging.debug("WARNING:Can't find VPC info in json config file")
+        return "FAILURE:IMPROPER_JSON_CONFG_FILE"
+
+    # First flush current egress ACL's before re-applying the ACL's
+    del_flows(bridge, table=3)
+
+    egress_rules_added = False
+    ingress_rules_added = False
+
+    tiers = vpconfig.tiers
+    for tier in tiers:
+        tier_cidr = tier.cidr
+        acl = get_acl(vpconfig, tier.aclid)
+        acl_items = acl.aclitems
+
+        for acl_item in acl_items:
+            number = acl_item.number
+            action = acl_item.action
+            direction = acl_item.direction
+            source_port_start = acl_item.sourceportstart
+            source_port_end = acl_item.sourceportend
+            protocol = acl_item.protocol
+            source_cidrs = acl_item.sourcecidrs
+            acl_priority = 1000 + number
+            for source_cidr in source_cidrs:
+                if direction is "ingress":
+                    ingress_rules_added = True
+                    # add flow rule to do action (allow/deny) for flows where source IP of the packet is in
+                    # source_cidr and destination ip is in tier_cidr
+                    port = source_port_start
+                    while (port < source_port_end):
+                        if action is "deny":
+                            add_flow(bridge, priority= acl_priority, table=5, nw_src=source_cidr, nw_dst=tier_cidr, tp_dst=port,
+                                     nw_proto=protocol, actions='drop')
+                        if action is "allow":
+                            add_flow(bridge, priority= acl_priority,table=5, nw_src=source_cidr, nw_dst=tier_cidr, tp_dst=port,
+                                     nw_proto=protocol, actions='resubmit(,1)')
+                        port = port + 1
+
+                elif direction in "egress":
+                    egress_rules_added = True
+                    # add flow rule to do action (allow/deny) for flows where destination IP of the packet is in
+                    # source_cidr and source ip is in tier_cidr
+                    port = source_port_start
+                    while (port < source_port_end):
+                        if action is "deny":
+                            add_flow(bridge, priority= acl_priority, table=5, nw_src=tier_cidr, nw_dst=source_cidr, tp_dst=port,
+                                     nw_proto=protocol, actions='drop')
+                        if action is "allow":
+                            add_flow(bridge, priority= acl_priority, table=5, nw_src=tier_cidr, nw_dst=source_cidr, tp_dst=port,
+                                     nw_proto=protocol, actions='resubmit(,1)')
+                        port = port + 1
+
+    if egress_rules_added is False:
+        # add a default rule in egress table to forward packet to L3 lookup table
+        add_flow(bridge, priority=0, table=3, actions='resubmit(,4)')
+
+    if ingress_rules_added is False:
+        # add a default rule in egress table drop packets
+        add_flow(bridge, priority=0, table=5, actions='drop')
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a572711b/scripts/vm/hypervisor/xenserver/ovstunnel
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/xenserver/ovstunnel b/scripts/vm/hypervisor/xenserver/ovstunnel
index 9ef0f7b..98a9d0b 100755
--- a/scripts/vm/hypervisor/xenserver/ovstunnel
+++ b/scripts/vm/hypervisor/xenserver/ovstunnel
@@ -184,7 +184,7 @@ def setup_ovs_bridge_for_distributed_routing(session, args):
         # add a default rule in L3 lookup table to forward packet to L2 lookup table
         lib.add_flow(bridge, priority=0, table=4, actions='resubmit(,1)')
 
-        # add a default rule in egress table to forward packet to L3 lookup table
+        # add a default rule in ingress table to drop in bound packets
         lib.add_flow(bridge, priority=0, table=5, actions='drop')
 
         result = "SUCCESS: successfully setup bridge with flow rules"
@@ -391,7 +391,14 @@ def configure_ovs_bridge_for_network_topology(session, args):
     json_config = args.pop("config")
     this_host_id = args.pop("host-id")
 
-    return lib.configure_bridge_for_topology(bridge, this_host_id, json_config)
+    return lib.configure_bridge_for_network_topology(bridge, this_host_id, json_config)
+
+@echo
+def configure_ovs_bridge_for_routing_policies(session, args):
+    bridge = args.pop("bridge")
+    json_config = args.pop("config")
+
+    return lib.configure_ovs_bridge_for_router_policies(bridge, json_config)
 
 if __name__ == "__main__":
     XenAPIPlugin.dispatch({"create_tunnel": create_tunnel,
@@ -401,4 +408,5 @@ if __name__ == "__main__":
                            "is_xcp": is_xcp,
                            "getLabel": getLabel,
                            "setup_ovs_bridge_for_distributed_routing": setup_ovs_bridge_for_distributed_routing,
-                           "configure_ovs_bridge_for_network_topology": configure_ovs_bridge_for_network_topology})
+                           "configure_ovs_bridge_for_network_topology": configure_ovs_bridge_for_network_topology,
+                           "configure_ovs_bridge_for_routing_policies": "configure_ovs_bridge_for_routing_policies"})

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a572711b/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java b/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java
index 82f1216..ad47df1 100644
--- a/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java
+++ b/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java
@@ -23,6 +23,8 @@ import javax.ejb.Local;
 import javax.inject.Inject;
 
 import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.framework.messagebus.MessageBus;
+import org.apache.cloudstack.framework.messagebus.PublishScope;
 import org.apache.log4j.Logger;
 
 import com.cloud.configuration.ConfigurationManager;
@@ -82,6 +84,8 @@ public class NetworkACLManagerImpl extends ManagerBase implements NetworkACLMana
     EntityManager _entityMgr;
     @Inject
     VpcService _vpcSvc;
+    @Inject
+    MessageBus _messageBus;
 
     @Override
     public NetworkACL createNetworkACL(String name, String description, long vpcId, Boolean forDisplay) {
@@ -210,7 +214,13 @@ public class NetworkACLManagerImpl extends ManagerBase implements NetworkACLMana
         if (_networkDao.update(network.getId(), network)) {
             s_logger.debug("Updated network: " + network.getId() + " with Network ACL Id: " + acl.getId() + ", Applying ACL items");
             //Apply ACL to network
-            return applyACLToNetwork(network.getId());
+            Boolean result = applyACLToNetwork(network.getId());
+            if (result) {
+                // public message on message bus, so that network elements implementing distributed routing capability
+                // can act on the event
+                _messageBus.publish(_name, "Network_ACL_Replaced", PublishScope.LOCAL, network);
+            }
+            return result;
         }
         return false;
     }


[12/31] git commit: updated refs/heads/distributedrouter to a8d43ba

Posted by mu...@apache.org.
CLOUDSTACK-6231 allow for cidr list entry of more than 256 chars

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

Branch: refs/heads/distributedrouter
Commit: 1dc2bbdc37faa9cb007c3e0446efc078255f3f76
Parents: 8937434
Author: Daan Hoogland <dh...@schubergphilis.com>
Authored: Wed Mar 12 15:50:43 2014 +0100
Committer: Daan Hoogland <dh...@schubergphilis.com>
Committed: Wed Mar 12 15:50:43 2014 +0100

----------------------------------------------------------------------
 .../src/com/cloud/network/vpc/NetworkACLItemVO.java   | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1dc2bbdc/engine/schema/src/com/cloud/network/vpc/NetworkACLItemVO.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/network/vpc/NetworkACLItemVO.java b/engine/schema/src/com/cloud/network/vpc/NetworkACLItemVO.java
index 24ec1b9..8031b00 100644
--- a/engine/schema/src/com/cloud/network/vpc/NetworkACLItemVO.java
+++ b/engine/schema/src/com/cloud/network/vpc/NetworkACLItemVO.java
@@ -71,7 +71,7 @@ public class NetworkACLItemVO implements NetworkACLItem {
     @Enumerated(value = EnumType.STRING)
     TrafficType trafficType;
 
-    @Column(name = "cidr")
+    @Column(name = "cidr", length = 2048)
     String sourceCidrs;
 
     @Column(name = "uuid")
@@ -88,20 +88,20 @@ public class NetworkACLItemVO implements NetworkACLItem {
     protected boolean display = true;
 
     public NetworkACLItemVO() {
-        this.uuid = UUID.randomUUID().toString();
+        uuid = UUID.randomUUID().toString();
     }
 
     public NetworkACLItemVO(Integer portStart, Integer portEnd, String protocol, long aclId, List<String> sourceCidrs, Integer icmpCode, Integer icmpType,
             TrafficType trafficType, Action action, int number) {
-        this.sourcePortStart = portStart;
-        this.sourcePortEnd = portEnd;
+        sourcePortStart = portStart;
+        sourcePortEnd = portEnd;
         this.protocol = protocol;
         this.aclId = aclId;
-        this.state = State.Staged;
+        state = State.Staged;
         this.icmpCode = icmpCode;
         this.icmpType = icmpType;
         setSourceCidrList(sourceCidrs);
-        this.uuid = UUID.randomUUID().toString();
+        uuid = UUID.randomUUID().toString();
         this.trafficType = trafficType;
         this.action = action;
         this.number = number;
@@ -191,7 +191,7 @@ public class NetworkACLItemVO implements NetworkACLItem {
 
     @Override
     public String getUuid() {
-        return this.uuid;
+        return uuid;
     }
 
     @Override


[15/31] git commit: updated refs/heads/distributedrouter to a8d43ba

Posted by mu...@apache.org.
CLOUDSTACK-6232 allow expansion of ip on isolated networks as well

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

Branch: refs/heads/distributedrouter
Commit: b5c8a56eeaa62cb1295993b43b11f1fb916949af
Parents: 6c03524
Author: Daan Hoogland <dh...@schubergphilis.com>
Authored: Wed Mar 12 19:36:11 2014 +0100
Committer: Daan Hoogland <dh...@schubergphilis.com>
Committed: Wed Mar 12 19:36:11 2014 +0100

----------------------------------------------------------------------
 .../src/com/cloud/configuration/ConfigurationManagerImpl.java | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b5c8a56e/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
index 863d71b..2d4539c 100755
--- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
+++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
@@ -36,6 +36,8 @@ import javax.ejb.Local;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
+import org.apache.log4j.Logger;
+
 import org.apache.cloudstack.acl.SecurityChecker;
 import org.apache.cloudstack.affinity.AffinityGroup;
 import org.apache.cloudstack.affinity.AffinityGroupService;
@@ -83,7 +85,6 @@ import org.apache.cloudstack.region.dao.RegionDao;
 import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
 import org.apache.cloudstack.storage.datastore.db.StoragePoolDetailsDao;
 import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.apache.log4j.Logger;
 
 import com.cloud.alert.AlertManager;
 import com.cloud.api.ApiDBUtils;
@@ -2623,7 +2624,9 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
                     networkId = network.getId();
                     zoneId = network.getDataCenterId();
                 }
-            } else if (network.getGuestType() == null || network.getGuestType() == Network.GuestType.Isolated) {
+            } else if (network.getGuestType() == null ||
+                    (network.getGuestType() == Network.GuestType.Isolated
+                    && _ntwkOffServiceMapDao.areServicesSupportedByNetworkOffering(network.getNetworkOfferingId(), Service.SourceNat))) {
                 throw new InvalidParameterValueException("Can't create direct vlan for network id=" + networkId + " with type: " + network.getGuestType());
             }
         }


[26/31] git commit: updated refs/heads/distributedrouter to a8d43ba

Posted by mu...@apache.org.
make Ovs as VPC provider


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

Branch: refs/heads/distributedrouter
Commit: cb37d770444b0045dd94c0341c099dabb0759338
Parents: 0b9a689
Author: Murali Reddy <mu...@gmail.com>
Authored: Wed Mar 5 01:26:53 2014 +0530
Committer: Murali Reddy <mu...@gmail.com>
Committed: Thu Mar 13 19:22:08 2014 +0530

----------------------------------------------------------------------
 server/src/com/cloud/network/vpc/VpcManagerImpl.java | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/cb37d770/server/src/com/cloud/network/vpc/VpcManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java
index 1ff4358..74854b2 100644
--- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java
+++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java
@@ -205,7 +205,9 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
     private final ScheduledExecutorService _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("VpcChecker"));
     private List<VpcProvider> vpcElements = null;
     private final List<Service> nonSupportedServices = Arrays.asList(Service.SecurityGroup, Service.Firewall);
-    private final List<Provider> supportedProviders = Arrays.asList(Provider.VPCVirtualRouter, Provider.NiciraNvp, Provider.InternalLbVm, Provider.Netscaler, Provider.JuniperContrailVpcRouter);
+    private final List<Provider> supportedProviders = Arrays.asList(Provider.VPCVirtualRouter,
+            Provider.NiciraNvp, Provider.InternalLbVm, Provider.Netscaler, Provider.JuniperContrailVpcRouter,
+            Provider.Ovs);
 
     int _cleanupInterval;
     int _maxNetworks;


[28/31] git commit: updated refs/heads/distributedrouter to a8d43ba

Posted by mu...@apache.org.
some bug fixes


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

Branch: refs/heads/distributedrouter
Commit: 9964688a463f0132b12e14302cad9102cc4d145e
Parents: b080611
Author: Murali Reddy <mu...@gmail.com>
Authored: Mon Mar 10 22:16:46 2014 +0530
Committer: Murali Reddy <mu...@gmail.com>
Committed: Thu Mar 13 19:22:09 2014 +0530

----------------------------------------------------------------------
 .../xen/resource/CitrixResourceBase.java        |  14 ++-
 .../api/OvsVpcLogicalTopologyConfigCommand.java |  33 +++++
 .../OvsVpcPhysicalTopologyConfigCommand.java    |   7 +-
 .../com/cloud/network/element/OvsElement.java   |  18 ---
 .../cloud/network/guru/OvsGuestNetworkGuru.java |   2 +-
 .../network/ovs/OvsNetworkTopologyGuru.java     |  10 ++
 .../network/ovs/OvsNetworkTopologyGuruImpl.java | 126 ++++++++++++++++++-
 .../cloud/network/ovs/OvsTunnelManagerImpl.java | 125 ++++++++++++------
 .../xenserver/cloudstack_pluginlib.py           |   4 +-
 scripts/vm/hypervisor/xenserver/ovstunnel       |  14 +--
 .../network/guru/ExternalGuestNetworkGuru.java  |   4 +
 11 files changed, 279 insertions(+), 78 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/9964688a/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 8585996..2315b31 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
@@ -998,7 +998,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
     /**
      * This method creates a XenServer network and configures it for being used as a L2-in-L3 tunneled network
      */
-    private synchronized Network configureTunnelNetwork(Connection conn, long networkId, long hostId, String bridgeName) {
+    private synchronized Network configureTunnelNetwork(Connection conn, Long networkId, long hostId, String bridgeName) {
         try {
             Network nw = findOrCreateTunnelNetwork(conn, bridgeName);
             String nwName = bridgeName;
@@ -1037,7 +1037,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
                 String[] res = result.split(":");
                 if (res.length != 2 || !res[0].equalsIgnoreCase("SUCCESS")) {
                     //TODO: Should make this error not fatal?
-                    throw new CloudRuntimeException("Unable to pre-configure OVS bridge " + bridge + " for network ID:" + networkId + " - " + res);
+                    throw new CloudRuntimeException("Unable to pre-configure OVS bridge " + bridge );
                 }
             }
             return nw;
@@ -1089,7 +1089,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
                 _isOvs = true;
                 return setupvSwitchNetwork(conn);
             } else {
-                return findOrCreateTunnelNetwork(conn, getOvsTunnelNetworkName(BroadcastDomainType.getValue(uri)));
+                return findOrCreateTunnelNetwork(conn, getOvsTunnelNetworkName(uri.getAuthority()));
             }
         } else if (type == BroadcastDomainType.Storage) {
             if (uri == null) {
@@ -1113,7 +1113,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
 
     private String getOvsTunnelNetworkName(String broadcastUri) {
         if (broadcastUri.contains(".")) {
-            String[] parts = broadcastUri.split(".");
+            String[] parts = broadcastUri.split("\\.");
             return "OVS-DR-VPC-Bridge"+parts[0];
          } else {
             try {
@@ -5265,7 +5265,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
             }
 
             String bridge = nw.getBridge(conn);
-            String result = callHostPlugin(conn, "ovstunnel", "configure_ovs_bridge_for_network_topology", "bridge", bridge, "in_port", cmd.getInPortName());
+            String result = callHostPlugin(conn, "ovstunnel", "destroy_tunnel", "bridge", bridge, "in_port", cmd.getInPortName());
+
             if (result.equalsIgnoreCase("SUCCESS")) {
                 return new Answer(cmd, true, result);
             } else {
@@ -5281,7 +5282,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
         Connection conn = getConnection();
         try {
             String result = callHostPlugin(conn, "ovstunnel", "configure_ovs_bridge_for_network_topology", "bridge",
-                    cmd.getBridgeName(), "host-id", ((Long)cmd.getHostId()).toString());
+                    cmd.getBridgeName(), "host-id", ((Long)cmd.getHostId()).toString(), "config",
+                    cmd.getjsonVpcConfig());
             if (result.equalsIgnoreCase("SUCCESS")) {
                 return new Answer(cmd, true, result);
             } else {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/9964688a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcLogicalTopologyConfigCommand.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcLogicalTopologyConfigCommand.java b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcLogicalTopologyConfigCommand.java
new file mode 100644
index 0000000..2fafb6e
--- /dev/null
+++ b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcLogicalTopologyConfigCommand.java
@@ -0,0 +1,33 @@
+// 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 com.cloud.agent.api;
+
+/**
+ * This command represents view of how a VPC is laid out (on which hosts, which VM is on which host etc)
+ * on the physical infrastructure.
+ */
+public class OvsVpcLogicalTopologyConfigCommand extends Command {
+
+    public OvsVpcLogicalTopologyConfigCommand() {
+
+    }
+
+    @Override
+    public boolean executeInSequence() {
+        return false;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/9964688a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcPhysicalTopologyConfigCommand.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcPhysicalTopologyConfigCommand.java b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcPhysicalTopologyConfigCommand.java
index 35d4c6e..e6f4383 100644
--- a/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcPhysicalTopologyConfigCommand.java
+++ b/plugins/network-elements/ovs/src/com/cloud/agent/api/OvsVpcPhysicalTopologyConfigCommand.java
@@ -20,8 +20,11 @@ import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 
 /**
- * This command represents view of how a VPC is laid out (on which hosts, which VM is on which host etc)
- * on the physical infrastructure.
+ * This command represents physical view of how a VPC is laid out on the physical infrastructure.
+ *   - on which hypervisor hosts VPC spans (host is running in at least one VM from the VPC)
+ *   - information of tiers, so we can figure how one VM can talk to a different VM in same tier or different tier
+ *   - information on all the VM's in the VPC.
+ *   - information of NIC's of each VM in the VPC
  */
 public class OvsVpcPhysicalTopologyConfigCommand extends Command {
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/9964688a/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java b/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java
index c28d908..036c319 100644
--- a/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java
+++ b/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java
@@ -75,7 +75,6 @@ import com.cloud.vm.NicProfile;
 import com.cloud.vm.ReservationContext;
 import com.cloud.vm.VirtualMachineProfile;
 import com.cloud.vm.dao.DomainRouterDao;
-import com.cloud.vm.UserVmVO;
 import com.cloud.vm.VirtualMachine;
 
 @Local(value = {NetworkElement.class, ConnectivityProvider.class,
@@ -205,23 +204,6 @@ StaticNatServiceProvider, IpDeployer {
             return false;
         }
 
-        List<UserVmVO> userVms = _userVmDao.listByAccountIdAndHostId(vm.getVirtualMachine().getAccountId(),
-                vm.getVirtualMachine().getHostId());
-        if (vm.getType() == VirtualMachine.Type.User) {
-            if (userVms.size() > 1) {
-                return true;
-            }
-
-            List<DomainRouterVO> routers = _routerDao.findByNetwork(network.getId());
-            for (DomainRouterVO router : routers) {
-                if (router.getHostId().equals(vm.getVirtualMachine().getHostId())) {
-                    return true;
-                }
-            }
-        } else if (vm.getType() == VirtualMachine.Type.DomainRouter && userVms.size() != 0) {
-            return true;
-        }
-
         HostVO host = _hostDao.findById(vm.getVirtualMachine().getHostId());
         _ovsTunnelMgr.checkAndRemoveHostFromTunnelNetwork(network, host);
         return true;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/9964688a/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java b/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java
index 2814c2a..9d2efe6 100644
--- a/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java
+++ b/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java
@@ -154,7 +154,7 @@ public class OvsGuestNetworkGuru extends GuestNetworkGuru {
         if (network.getVpcId() != null && isVpcEnabledForDistributedRouter(network.getVpcId())) {
             String keyStr = BroadcastDomainType.getValue(implemented.getBroadcastUri());
             Long vpcid= network.getVpcId();
-            implemented.setBroadcastUri(BroadcastDomainType.Vswitch.toUri(vpcid.toString()+keyStr));
+            implemented.setBroadcastUri(BroadcastDomainType.Vswitch.toUri(vpcid.toString() + "." + keyStr));
         }
 
         return implemented;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/9964688a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuru.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuru.java b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuru.java
index c410d10..122175c 100644
--- a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuru.java
+++ b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuru.java
@@ -38,6 +38,11 @@ public interface OvsNetworkTopologyGuru extends Manager {
     public  List<Long> getVpcOnHost(long hostId);
 
     /**
+     * get the list of all active Vm id's in a network
+     */
+    public List<Long> getAllActiveVmsInNetwork(long networkId);
+
+    /**
      * get the list of all active Vm id's in the VPC for all ther tiers
      */
     public List<Long> getAllActiveVmsInVpc(long vpcId);
@@ -46,4 +51,9 @@ public interface OvsNetworkTopologyGuru extends Manager {
      * get the list of all Vm id's in the VPC for all the tiers that are running on the host
      */
     public List<Long> getActiveVmsInVpcOnHost(long vpcId, long hostId);
+
+    /**
+     * get the list of all Vm id's in the network that are running on the host
+     */
+    public List<Long> getActiveVmsInNetworkOnHost(long vpcId, long hostId);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/9964688a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuruImpl.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuruImpl.java b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuruImpl.java
index 7560e35..7715641 100644
--- a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuruImpl.java
+++ b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuruImpl.java
@@ -1,14 +1,24 @@
 package com.cloud.network.ovs;
 
+import com.cloud.network.Network;
+import com.cloud.network.Networks;
+import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.vpc.VpcManager;
 import com.cloud.utils.component.ManagerBase;
 import com.cloud.vm.DomainRouterVO;
 import com.cloud.vm.UserVmVO;
 import com.cloud.vm.VMInstanceVO;
 import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.NicVO;
+import com.cloud.vm.Nic;
 import com.cloud.vm.dao.DomainRouterDao;
+import com.cloud.vm.dao.NicDao;
 import com.cloud.vm.dao.UserVmDao;
+import com.cloud.vm.dao.VMInstanceDao;
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 import javax.ejb.Local;
 import javax.inject.Inject;
 import org.springframework.stereotype.Component;
@@ -21,6 +31,14 @@ public class OvsNetworkTopologyGuruImpl extends ManagerBase implements OvsNetwor
     UserVmDao _userVmDao;
     @Inject
     DomainRouterDao _routerDao;
+    @Inject
+    VpcManager _vpcMgr;
+    @Inject
+    VMInstanceDao _vmInstanceDao;
+    @Inject
+    NicDao _nicDao;
+    @Inject
+    NetworkDao _networkDao;
 
     /**
      * get the list of hypervisor hosts on which VM's belonging to a network currently spans
@@ -52,23 +70,121 @@ public class OvsNetworkTopologyGuruImpl extends ManagerBase implements OvsNetwor
         return  hostIds;
     }
 
+    /**
+     * get the list of hypervisor hosts on which VM's belonging to a VPC currently spans
+     */
     @Override
-    public List<Long> getVpcSpannedHosts(long vpId) {
-        return null;
+    public List<Long> getVpcSpannedHosts(long vpcId) {
+        List<? extends Network> vpcNetworks =  _vpcMgr.getVpcNetworks(vpcId);
+        List<Long> vpcHostIds = new ArrayList<>();
+        for (Network vpcNetwork : vpcNetworks) {
+            List<Long> networkHostIds = new ArrayList<Long>();
+            networkHostIds = getNetworkSpanedHosts(vpcNetwork.getId());
+            if (networkHostIds != null && !networkHostIds.isEmpty()) {
+                for (Long hostId : networkHostIds) {
+                    if (!vpcHostIds.contains(hostId)) {
+                        vpcHostIds.add(hostId);
+                    }
+                }
+            }
+        }
+        return vpcHostIds;
     }
 
     @Override
     public List<Long> getVpcOnHost(long hostId) {
-        return null;
+        List<Long> vpcIds = new ArrayList<>();
+        List<VMInstanceVO> vmInstances = _vmInstanceDao.listByHostId(hostId);
+        for (VMInstanceVO instance : vmInstances) {
+            List<NicVO> nics = _nicDao.listByVmId(instance.getId());
+            for (Nic nic: nics) {
+                Network network = _networkDao.findById(nic.getNetworkId());
+                if (network.getTrafficType() == Networks.TrafficType.Guest && network.getVpcId() != null) {
+                    if (!vpcIds.contains(network.getVpcId())) {
+                        vpcIds.add(network.getVpcId());
+                    }
+                }
+            }
+        }
+        return vpcIds;
+    }
+
+    @Override
+    public List<Long> getAllActiveVmsInNetwork(long networkId) {
+        List <Long> vmIds = new ArrayList<>();
+        List<UserVmVO> vms = _userVmDao.listByNetworkIdAndStates(networkId,
+                VirtualMachine.State.Running, VirtualMachine.State.Starting, VirtualMachine.State.Stopping, VirtualMachine.State.Unknown,
+                VirtualMachine.State.Migrating);
+        // Find routers for the network
+        List<DomainRouterVO> routers = _routerDao.findByNetwork(networkId);
+        List<VMInstanceVO> ins = new ArrayList<VMInstanceVO>();
+
+        if (vms != null) {
+            for (UserVmVO vm : vms) {
+                vmIds.add(vm.getId());
+            }
+        }
+        if (routers.size() != 0) {
+            for (DomainRouterVO router: routers) {
+                vmIds.add(router.getId());
+            }
+        }
+        return  vmIds;
     }
 
     @Override
     public List<Long> getAllActiveVmsInVpc(long vpcId) {
-        return null;
+
+        Set<Long> vmIdsSet = new HashSet<>();
+        List<? extends Network> vpcNetworks =  _vpcMgr.getVpcNetworks(vpcId);
+        for (Network network : vpcNetworks) {
+            List<Long> networkVmIds = getAllActiveVmsInNetwork(network.getId());
+            if (networkVmIds  != null && !networkVmIds.isEmpty()) {
+                vmIdsSet.addAll(networkVmIds);
+            }
+        }
+        List<Long> vmIds = new ArrayList<>();
+        vmIds.addAll(vmIdsSet);
+        return vmIds;
     }
 
     @Override
     public List<Long> getActiveVmsInVpcOnHost(long vpcId, long hostId) {
-        return null;
+        Set<Long> vmIdsSet = new HashSet<>();
+        List<? extends Network> vpcNetworks =  _vpcMgr.getVpcNetworks(vpcId);
+        for (Network network : vpcNetworks) {
+            List<Long> networkVmIds = getActiveVmsInNetworkOnHost(network.getId(), hostId);
+            if (networkVmIds  != null && !networkVmIds.isEmpty()) {
+                vmIdsSet.addAll(networkVmIds);
+            }
+        }
+        List<Long> vmIds = new ArrayList<>();
+        vmIds.addAll(vmIdsSet);
+        return vmIds;
+    }
+
+    @Override
+    public List<Long> getActiveVmsInNetworkOnHost(long networkId, long hostId) {
+        List <Long> vmIds = new ArrayList<>();
+        List<UserVmVO> vms = _userVmDao.listByNetworkIdAndStates(networkId,
+                VirtualMachine.State.Running, VirtualMachine.State.Starting, VirtualMachine.State.Stopping, VirtualMachine.State.Unknown,
+                VirtualMachine.State.Migrating);
+        // Find routers for the network
+        List<DomainRouterVO> routers = _routerDao.findByNetwork(networkId);
+        List<VMInstanceVO> ins = new ArrayList<VMInstanceVO>();
+
+        if (vms != null) {
+            for (UserVmVO vm : vms) {
+                if (vm.getHostId() == hostId)
+                    vmIds.add(vm.getId());
+            }
+        }
+        if (routers.size() != 0) {
+            for (DomainRouterVO router: routers) {
+                if (router.getHostId() == hostId)
+                    vmIds.add(router.getId());
+            }
+        }
+        return  vmIds;
     }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/9964688a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
index ae37095..82dbfed 100644
--- a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
+++ b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
@@ -18,10 +18,10 @@ package com.cloud.network.ovs;
 
 import com.cloud.network.dao.NetworkDao;
 import com.cloud.network.vpc.VpcManager;
+import com.cloud.vm.dao.VMInstanceDao;
 import com.cloud.vm.Nic;
 import com.cloud.vm.NicVO;
 import com.cloud.vm.VirtualMachine;
-import com.cloud.vm.dao.VMInstanceDao;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
@@ -260,9 +260,9 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
         int key = 0;
         try {
             //The GRE key is actually in the host part of the URI
-            String keyStr = BroadcastDomainType.getValue(network.getBroadcastUri());
+            String keyStr = network.getBroadcastUri().getAuthority();
             if (keyStr.contains(".")) {
-                String[] parts = keyStr.split(".");
+                String[] parts = keyStr.split("\\.");
                 key = Integer.parseInt(parts[1]);
             } else {
                 key = Integer.parseInt(keyStr);
@@ -445,34 +445,72 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
     @Override
     public void checkAndRemoveHostFromTunnelNetwork(Network nw, Host host) {
 
-        try {
-            /* Now we are last one on host, destroy the bridge with all
-             * the tunnels for this network  */
-            int key = getGreKey(nw);
-            String bridgeName = generateBridgeName(nw, key);
-            Command cmd = new OvsDestroyBridgeCommand(nw.getId(), bridgeName);
-            s_logger.debug("Destroying bridge for network " + nw.getId() + " on host:" + host.getId());
-            Answer ans = _agentMgr.send(host.getId(), cmd);
-            handleDestroyBridgeAnswer(ans, host.getId(), nw.getId());
-
-            /* Then ask hosts have peer tunnel with me to destroy them */
-            List<OvsTunnelNetworkVO> peers =
-                    _tunnelNetworkDao.listByToNetwork(host.getId(),
-                            nw.getId());
-            for (OvsTunnelNetworkVO p : peers) {
-                // If the tunnel was not successfully created don't bother to remove it
-                if (p.getState().equals(OvsTunnel.State.Established.name())) {
-                    cmd = new OvsDestroyTunnelCommand(p.getNetworkId(), bridgeName,
-                            p.getPortName());
-                    s_logger.debug("Destroying tunnel to " + host.getId() +
-                            " from " + p.getFrom());
-                    ans = _agentMgr.send(p.getFrom(), cmd);
-                    handleDestroyTunnelAnswer(ans, p.getFrom(),
-                            p.getTo(), p.getNetworkId());
+        if (nw.getVpcId() != null && isVpcEnabledForDistributedRouter(nw.getVpcId())) {
+            List<Long> vmIds = _ovsNetworkToplogyGuru.getActiveVmsInVpcOnHost(nw.getVpcId(), host.getId());
+            if (vmIds != null && !vmIds.isEmpty()) {
+                return;
+            }
+            List<? extends Network> vpcNetworks =  _vpcMgr.getVpcNetworks(nw.getVpcId());
+            try {
+                for (Network network: vpcNetworks) {
+                    int key = getGreKey(nw);
+                    String bridgeName = generateBridgeName(nw, key);
+                    /* Then ask hosts have peer tunnel with me to destroy them */
+                    List<OvsTunnelNetworkVO> peers = _tunnelNetworkDao.listByToNetwork(host.getId(),nw.getId());
+                    for (OvsTunnelNetworkVO p : peers) {
+                        // If the tunnel was not successfully created don't bother to remove it
+                        if (p.getState().equals(OvsTunnel.State.Established.name())) {
+                            Command cmd= new OvsDestroyTunnelCommand(p.getNetworkId(), bridgeName,
+                                    p.getPortName());
+                            s_logger.debug("Destroying tunnel to " + host.getId() +
+                                    " from " + p.getFrom());
+                            Answer ans = _agentMgr.send(p.getFrom(), cmd);
+                            handleDestroyTunnelAnswer(ans, p.getFrom(), p.getTo(), p.getNetworkId());
+                        }
+                    }
                 }
+
+                Command cmd = new OvsDestroyBridgeCommand(nw.getId(), generateBridgeNameForVpc(nw.getVpcId()));
+                s_logger.debug("Destroying bridge for network " + nw.getId() + " on host:" + host.getId());
+                Answer ans = _agentMgr.send(host.getId(), cmd);
+                handleDestroyBridgeAnswer(ans, host.getId(), nw.getId());
+            } catch (Exception e) {
+
+            }
+        } else {
+            List<Long> vmIds = _ovsNetworkToplogyGuru.getActiveVmsInNetworkOnHost(nw.getId(), host.getId());
+            if (vmIds != null && !vmIds.isEmpty()) {
+                return;
+            }
+            try {
+                /* Now we are last one on host, destroy the bridge with all
+                * the tunnels for this network  */
+                int key = getGreKey(nw);
+                String bridgeName = generateBridgeName(nw, key);
+                Command cmd = new OvsDestroyBridgeCommand(nw.getId(), bridgeName);
+                s_logger.debug("Destroying bridge for network " + nw.getId() + " on host:" + host.getId());
+                Answer ans = _agentMgr.send(host.getId(), cmd);
+                handleDestroyBridgeAnswer(ans, host.getId(), nw.getId());
+
+                /* Then ask hosts have peer tunnel with me to destroy them */
+                List<OvsTunnelNetworkVO> peers =
+                        _tunnelNetworkDao.listByToNetwork(host.getId(),
+                                nw.getId());
+                for (OvsTunnelNetworkVO p : peers) {
+                    // If the tunnel was not successfully created don't bother to remove it
+                    if (p.getState().equals(OvsTunnel.State.Established.name())) {
+                        cmd = new OvsDestroyTunnelCommand(p.getNetworkId(), bridgeName,
+                                p.getPortName());
+                        s_logger.debug("Destroying tunnel to " + host.getId() +
+                                " from " + p.getFrom());
+                        ans = _agentMgr.send(p.getFrom(), cmd);
+                        handleDestroyTunnelAnswer(ans, p.getFrom(),
+                                p.getTo(), p.getNetworkId());
+                    }
+                }
+            } catch (Exception e) {
+                s_logger.warn(String.format("Destroy tunnel failed", e));
             }
-        } catch (Exception e) {
-            s_logger.warn(String.format("Destroy tunnel failed", e));
         }
     }
 
@@ -514,9 +552,9 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
         List<Long> hostIds = _ovsNetworkToplogyGuru.getVpcSpannedHosts(vpcId);
         List<Long> vmIds = _ovsNetworkToplogyGuru.getAllActiveVmsInVpc(vpcId);
 
-        List<OvsVpcPhysicalTopologyConfigCommand.Host> hosts = new ArrayList<OvsVpcPhysicalTopologyConfigCommand.Host>();
-        List<OvsVpcPhysicalTopologyConfigCommand.Tier> tiers = new ArrayList<OvsVpcPhysicalTopologyConfigCommand.Tier>();
-        List<OvsVpcPhysicalTopologyConfigCommand.Vm> vms = new ArrayList<OvsVpcPhysicalTopologyConfigCommand.Vm>();
+        List<OvsVpcPhysicalTopologyConfigCommand.Host> hosts = new ArrayList<>();
+        List<OvsVpcPhysicalTopologyConfigCommand.Tier> tiers = new ArrayList<>();
+        List<OvsVpcPhysicalTopologyConfigCommand.Vm> vms = new ArrayList<>();
 
         for (Long hostId : hostIds) {
             HostVO hostDetails = _hostDao.findById(hostId);
@@ -533,10 +571,10 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
         }
 
         for (Network network: vpcNetworks) {
-            String key = BroadcastDomainType.getValue(network.getBroadcastUri());
+            String key = network.getBroadcastUri().getAuthority();
             long gre_key;
             if (key.contains(".")) {
-                String[] parts = key.split(".");
+                String[] parts = key.split("\\.");
                 gre_key = Long.parseLong(parts[1]);
             } else {
                 try {
@@ -580,6 +618,7 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
         List<? extends Network> vpcNetworks =  _vpcMgr.getVpcNetworks(vpcId);
         List<Long> vpcSpannedHostIds = _ovsNetworkToplogyGuru.getVpcSpannedHosts(vpcId);
         String bridgeName=generateBridgeNameForVpc(vpcId);
+        boolean bridgeNotSetup = true;
 
         for (Network vpcNetwork: vpcNetworks) {
             int key = getGreKey(vpcNetwork);
@@ -643,7 +682,7 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
                             + " to create gre tunnel to " + i);
                     Answer[] answers = _agentMgr.send(hostId, cmds);
                     handleCreateTunnelAnswer(answers);
-                    noHost = false;
+                    bridgeNotSetup = false;
                 }
 
                 for (Long i : fromHostIds) {
@@ -656,7 +695,7 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
                             + hostId);
                     Answer[] answers = _agentMgr.send(i, cmds);
                     handleCreateTunnelAnswer(answers);
-                    noHost = false;
+                    bridgeNotSetup = false;
                 }
             } catch (GreTunnelException | OperationTimedoutException | AgentUnavailableException e) {
                 // I really thing we should do a better handling of these exceptions
@@ -664,6 +703,20 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
             }
         }
 
+        // If no tunnels have been configured, perform the bridge setup
+        // anyway. This will ensure VIF rules will be triggered
+        if (bridgeNotSetup) {
+            try {
+                Commands cmds = new Commands(new OvsSetupBridgeCommand(bridgeName, hostId, null));
+                s_logger.debug("Ask host " + hostId + " to configure bridge for vpc");
+                Answer[] answers = _agentMgr.send(hostId, cmds);
+                handleSetupBridgeAnswer(answers);
+            } catch (OperationTimedoutException | AgentUnavailableException e) {
+                // I really thing we should do a better handling of these exceptions
+                s_logger.warn("Ovs Tunnel network created tunnel failed", e);
+            }
+        }
+
         OvsVpcPhysicalTopologyConfigCommand topologyConfigCommand = prepareVpcTopologyUpdate(vpcId);
         for (Long id: vpcSpannedHostIds) {
             if (!sendVpcTopologyChangeUpdate(topologyConfigCommand, id, bridgeName)) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/9964688a/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py b/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py
index d2b95dc..dbcc288 100644
--- a/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py
+++ b/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py
@@ -21,7 +21,7 @@ import ConfigParser
 import logging
 import os
 import subprocess
-import json
+import simplejson as json
 
 from time import localtime, asctime
 
@@ -181,7 +181,7 @@ def _build_flow_expr(**kwargs):
     proto = 'proto' in kwargs and ",%s" % kwargs['proto'] or ''
     ip = ('nw_src' in kwargs or 'nw_dst' in kwargs) and ',ip' or ''
     flow = (flow + in_port + dl_type + dl_src + dl_dst +
-            (ip or proto) + nw_src + nw_dst)
+            (ip or proto) + nw_src + nw_dst + table)
     return flow
 
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/9964688a/scripts/vm/hypervisor/xenserver/ovstunnel
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/xenserver/ovstunnel b/scripts/vm/hypervisor/xenserver/ovstunnel
index 64a2d36..9ef0f7b 100755
--- a/scripts/vm/hypervisor/xenserver/ovstunnel
+++ b/scripts/vm/hypervisor/xenserver/ovstunnel
@@ -137,8 +137,8 @@ def setup_ovs_bridge_for_distributed_routing(session, args):
 
     logging.debug("About to manually create the bridge:%s" % bridge)
     # create a bridge with the same name as the xapi network
-    res = lib.do_cmd([lib.VSCTL_PATH, "--", "--may-exist", "add-br", bridge,
-                                     "--", "set", "bridge", bridge])
+    res = lib.do_cmd([lib.VSCTL_PATH, "--", "--may-exist", "add-br", bridge])
+
     logging.debug("Bridge has been manually created:%s" % res)
     # TODO: Make sure xs-network-uuid is set into external_ids
     lib.do_cmd([lib.VSCTL_PATH, "set", "Bridge", bridge,
@@ -149,12 +149,8 @@ def setup_ovs_bridge_for_distributed_routing(session, args):
         result = "FAILURE:%s" % res
     else:
         # Verify the bridge actually exists, with the gre_key properly set
-        res = lib.do_cmd([lib.VSCTL_PATH, "get", "bridge",
-                                          bridge, "other_config:gre_key"])
-        if key in res:
-            result = "SUCCESS:%s" % bridge
-        else:
-            result = "FAILURE:%s" % res
+        res = lib.do_cmd([lib.VSCTL_PATH, "list", "bridge", bridge])
+
         # Finally note in the xenapi network object that the network has
         # been configured
         xs_nw_uuid = lib.do_cmd([lib.XE_PATH, "network-list",
@@ -191,6 +187,8 @@ def setup_ovs_bridge_for_distributed_routing(session, args):
         # add a default rule in egress table to forward packet to L3 lookup table
         lib.add_flow(bridge, priority=0, table=5, actions='drop')
 
+        result = "SUCCESS: successfully setup bridge with flow rules"
+
     logging.debug("Setup_ovs_bridge completed with result:%s" % result)
     return result
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/9964688a/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java b/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java
index 414eb7b..13246a7 100644
--- a/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java
+++ b/server/src/com/cloud/network/guru/ExternalGuestNetworkGuru.java
@@ -107,6 +107,10 @@ public class ExternalGuestNetworkGuru extends GuestNetworkGuru {
     @Override
     public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) {
 
+        if (_networkModel.areServicesSupportedByNetworkOffering(offering.getId(), Network.Service.Connectivity)) {
+            return null;
+        }
+
         NetworkVO config = (NetworkVO)super.design(offering, plan, userSpecified, owner);
         if (config == null) {
             return null;


[30/31] git commit: updated refs/heads/distributedrouter to a8d43ba

Posted by mu...@apache.org.
integration tests for VPC's enabled for distributed routing


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

Branch: refs/heads/distributedrouter
Commit: f70383b30b5bf85b8e71b9b9be6b95ace315c638
Parents: bc27482
Author: Murali Reddy <mu...@gmail.com>
Authored: Tue Mar 11 18:29:36 2014 +0530
Committer: Murali Reddy <mu...@gmail.com>
Committed: Thu Mar 13 19:22:10 2014 +0530

----------------------------------------------------------------------
 build/simulator.properties                      |  28 -
 .../test_vpc_distributed_routing_offering.py    | 512 +++++++++++++++++++
 tools/marvin/marvin/integration/lib/base.py     |  15 +
 3 files changed, 527 insertions(+), 28 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f70383b3/build/simulator.properties
----------------------------------------------------------------------
diff --git a/build/simulator.properties b/build/simulator.properties
deleted file mode 100644
index d65d05c..0000000
--- a/build/simulator.properties
+++ /dev/null
@@ -1,28 +0,0 @@
-# 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.
-
-DBUSER=cloud
-DBPW=cloud
-MSLOG=vmops.log
-APISERVERLOG=api.log
-DBHOST=localhost
-DBROOTPW=
-AGENTLOGDIR=logs
-AGENTLOG=logs/agent.log
-MSMNTDIR=/mnt
-COMPONENTS-SPEC=components-simulator.xml
-AWSAPILOG=awsapi.log

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f70383b3/test/integration/component/test_vpc_distributed_routing_offering.py
----------------------------------------------------------------------
diff --git a/test/integration/component/test_vpc_distributed_routing_offering.py b/test/integration/component/test_vpc_distributed_routing_offering.py
new file mode 100644
index 0000000..0fa7de7
--- /dev/null
+++ b/test/integration/component/test_vpc_distributed_routing_offering.py
@@ -0,0 +1,512 @@
+# 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.
+import unittest
+
+""" Component tests for inter VLAN functionality
+"""
+#Import Local Modules
+import marvin
+from nose.plugins.attrib import attr
+from marvin.cloudstackTestCase import *
+from marvin.cloudstackAPI import *
+from marvin.integration.lib.utils import *
+from marvin.integration.lib.base import *
+from marvin.integration.lib.common import *
+from marvin.sshClient import SshClient
+import datetime
+
+
+class Services:
+    """Test inter VLAN services
+    """
+
+    def __init__(self):
+        self.services = {
+                         "account": {
+                                    "email": "test@test.com",
+                                    "firstname": "Test",
+                                    "lastname": "User",
+                                    "username": "test",
+                                    # Random characters are appended for unique
+                                    # username
+                                    "password": "password",
+                                    },
+                         "service_offering": {
+                                    "name": "Tiny Instance",
+                                    "displaytext": "Tiny Instance",
+                                    "cpunumber": 1,
+                                    "cpuspeed": 100,
+                                    "memory": 128,
+                                    },
+                         "network_offering": {
+                                    "name": 'VPC Network offering',
+                                    "displaytext": 'VPC Network off',
+                                    "guestiptype": 'Isolated',
+                                    "supportedservices": 'Vpn,Dhcp,Dns,SourceNat,PortForwarding,Lb,UserData,StaticNat,NetworkACL, Connectivity',
+                                    "traffictype": 'GUEST',
+                                    "availability": 'Optional',
+                                    "useVpc": 'on',
+                                    "serviceProviderList": {
+                                            "Vpn": 'VpcVirtualRouter',
+                                            "Dhcp": 'VpcVirtualRouter',
+                                            "Dns": 'VpcVirtualRouter',
+                                            "SourceNat": 'VpcVirtualRouter',
+                                            "PortForwarding": 'VpcVirtualRouter',
+                                            "Lb": 'VpcVirtualRouter',
+                                            "UserData": 'VpcVirtualRouter',
+                                            "StaticNat": 'VpcVirtualRouter',
+                                            "NetworkACL": 'VpcVirtualRouter',
+                                            "Connectivity": 'Ovs'
+                                        },
+                                },
+                         "vpc_offering": {
+                                    "name": 'VPC off',
+                                    "displaytext": 'VPC off',
+                                    "supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Lb,UserData,StaticNat,Connectivity',
+                                    "serviceProviderList": {
+                                            "Vpn": 'VpcVirtualRouter',
+                                            "Dhcp": 'VpcVirtualRouter',
+                                            "Dns": 'VpcVirtualRouter',
+                                            "SourceNat": 'VpcVirtualRouter',
+                                            "PortForwarding": 'VpcVirtualRouter',
+                                            "Lb": 'VpcVirtualRouter',
+                                            "UserData": 'VpcVirtualRouter',
+                                            "StaticNat": 'VpcVirtualRouter',
+                                            "Connectivity": 'Ovs'
+                                        },
+                                    "serviceCapabilityList": {
+                                        "Connectivity": {
+                                            "DistributedRouter": "true"
+                                        },
+                                    },
+                                },
+                         "vpc": {
+                                 "name": "TestVPC",
+                                 "displaytext": "TestVPC",
+                                 "cidr": '10.0.0.1/24'
+                                 },
+                         "network": {
+                                  "name": "Test Network",
+                                  "displaytext": "Test Network",
+                                  "netmask": '255.255.255.0'
+                                },
+                         "lbrule": {
+                                    "name": "SSH",
+                                    "alg": "leastconn",
+                                    # Algorithm used for load balancing
+                                    "privateport": 22,
+                                    "publicport": 2222,
+                                    "openfirewall": False,
+                                    "startport": 2222,
+                                    "endport": 2222,
+                                    "cidrlist": '0.0.0.0/0',
+                                    "protocol": 'TCP'
+                                },
+                         "natrule": {
+                                    "privateport": 22,
+                                    "publicport": 22,
+                                    "startport": 22,
+                                    "endport": 22,
+                                    "protocol": "TCP",
+                                    "cidrlist": '0.0.0.0/0',
+                                },
+                         "fw_rule": {
+                                    "startport": 1,
+                                    "endport": 6000,
+                                    "cidr": '0.0.0.0/0',
+                                    # Any network (For creating FW rule)
+                                    "protocol": "TCP"
+                                },
+                         "virtual_machine": {
+                                    "displayname": "Test VM",
+                                    "username": "root",
+                                    "password": "password",
+                                    "ssh_port": 22,
+                                    "hypervisor": 'XenServer',
+                                    # Hypervisor type should be same as
+                                    # hypervisor type of cluster
+                                    "privateport": 22,
+                                    "publicport": 22,
+                                    "protocol": 'TCP',
+                                },
+                         "ostype": 'CentOS 5.3 (64-bit)',
+                         # Cent OS 5.3 (64 bit)
+                         "sleep": 60,
+                         "timeout": 10,
+                    }
+
+
+class TestVPCDistributedRouterOffering(cloudstackTestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        cls.api_client = super(
+                               TestVPCDistributedRouterOffering,
+                               cls
+                               ).getClsTestClient().getApiClient()
+        cls.services = Services().services
+        # Get Zone, Domain and templates
+        cls.domain = get_domain(cls.api_client, cls.services)
+        cls.zone = get_zone(cls.api_client, cls.services)
+        cls.template = get_template(
+                            cls.api_client,
+                            cls.zone.id,
+                            cls.services["ostype"]
+                            )
+        cls.services["virtual_machine"]["zoneid"] = cls.zone.id
+        cls.services["virtual_machine"]["template"] = cls.template.id
+
+        cls.service_offering = ServiceOffering.create(
+                                            cls.api_client,
+                                            cls.services["service_offering"]
+                                            )
+        cls._cleanup = [
+                        cls.service_offering,
+                        ]
+        return
+
+    @classmethod
+    def tearDownClass(cls):
+        try:
+            #Cleanup resources used
+            cleanup_resources(cls.api_client, cls._cleanup)
+        except Exception as e:
+            raise Exception("Warning: Exception during cleanup : %s" % e)
+        return
+
+    def setUp(self):
+        self.apiclient = self.testClient.getApiClient()
+        self.dbclient = self.testClient.getDbConnection()
+        self.account = Account.create(
+                                     self.apiclient,
+                                     self.services["account"],
+                                     admin=True,
+                                     domainid=self.domain.id
+                                     )
+        self.cleanup = []
+        self.cleanup.insert(0, self.account)
+        return
+
+    def tearDown(self):
+        try:
+            cleanup_resources(self.apiclient, self.cleanup)
+        except Exception as e:
+            raise Exception("Warning: Exception during cleanup : %s" % e)
+        return
+
+    def validate_vpc_offering(self, vpc_offering):
+        """Validates the VPC offering"""
+
+        self.debug("Check if the VPC offering is created successfully?")
+        vpc_offs = VpcOffering.list(
+                                    self.apiclient,
+                                    id=vpc_offering.id
+                                    )
+        self.assertEqual(
+                         isinstance(vpc_offs, list),
+                         True,
+                         "List VPC offerings should return a valid list"
+                         )
+        self.assertEqual(
+                 vpc_offering.name,
+                 vpc_offs[0].name,
+                "Name of the VPC offering should match with listVPCOff data"
+                )
+        self.assertEqual(
+                 vpc_offering.name,
+                 vpc_offs[0].name,
+                "Name of the VPC offering should match with listVPCOff data"
+                )
+        self.assertEqual(
+                 vpc_offs[0].distributedvpcrouter,True,
+                 "VPC offering is not set up for Distributed routing"
+                )
+        self.debug(
+                "VPC offering is created successfully - %s" %
+                                                        vpc_offering.name)
+        return
+
+    def validate_vpc_network(self, network):
+        """Validates the VPC network"""
+
+        self.debug("Check if the VPC network is created successfully?")
+        vpc_networks = VPC.list(
+                                    self.apiclient,
+                                    id=network.id
+                          )
+        self.assertEqual(
+                         isinstance(vpc_networks, list),
+                         True,
+                         "List VPC network should return a valid list"
+                         )
+        self.assertEqual(
+                 network.name,
+                 vpc_networks[0].name,
+                 "Name of the VPC network should match with listVPC data"
+                )
+        self.debug("VPC network created successfully - %s" % network.name)
+        return
+
+    @attr(tags=["advanced", "intervlan"])
+    def test_01_create_vpc_offering_with_distributedrouter_service_capability(self):
+        """ Test create VPC offering
+        """
+
+        # Steps for validation
+        # 1. Create VPC Offering by specifying all supported Services
+        # 2. VPC offering should be created successfully.
+
+        self.debug("Creating inter VPC offering")
+        vpc_off = VpcOffering.create(
+                                     self.apiclient,
+                                     self.services["vpc_offering"]
+                                     )
+
+        self.debug("Check if the VPC offering is created successfully?")
+        self.cleanup.append(vpc_off)
+        self.validate_vpc_offering(vpc_off)
+        return
+
+    @attr(tags=["advanced", "intervlan"])
+    def test_02_create_vpc_from_offering_with_distributedrouter_service_capability(self):
+        """ Test create VPC offering
+        """
+
+        # Steps for validation
+        # 1. Create VPC Offering by specifying all supported Services
+        # 2. VPC offering should be created successfully.
+
+        self.debug("Creating inter VPC offering")
+        vpc_off = VpcOffering.create(
+                                     self.apiclient,
+                                     self.services["vpc_offering"]
+                                     )
+        vpc_off.update(self.apiclient, state='Enabled')
+        vpc = VPC.create(
+                         self.apiclient,
+                         self.services["vpc"],
+                         vpcofferingid=vpc_off.id,
+                         zoneid=self.zone.id,
+                         account=self.account.name,
+                         domainid=self.account.domainid
+                         )
+        self.assertEqual(vpc.distributedvpcrouter, True, "VPC created should have 'distributedvpcrouter' set to True")
+
+        try:
+            vpc.delete(self.apiclient)
+        except Exception as e:
+            self.fail("Failed to delete VPC network - %s" % e)
+        return
+
+    @attr(tags=["advanced", "intervlan"])
+    def test_03_deploy_vms_in_vpc_with_distributedrouter(self):
+        """Test deploy virtual machines in VPC networks"""
+
+        # 1. Create VPC Offering by specifying all supported Services
+        #   (Vpn,dhcpdns,UserData, SourceNat,Static NAT and PF,LB,NetworkAcl)
+        # 2. Create a VPC using the above VPC offering
+        # 3. Create a network as part of this VPC.
+        # 4. Deploy few Vms.
+        # 5. Create a LB rule for this VM.
+        # 6. Create a PF rule for this VM.
+        # 7. Create a  Static Nat rule for this VM.
+        # 8. Create Ingress rules on the network to open the above created
+        #    LB PF and Static Nat rule
+        # 9. Create Egress Network ACL for this network to access google.com.
+        # 10. Enable VPN services
+
+        self.debug("Creating a VPC offering..")
+        vpc_off = VpcOffering.create(
+                                     self.apiclient,
+                                     self.services["vpc_offering"]
+                                     )
+
+        vpc_off.update(self.apiclient, state='Enabled')
+
+        self.debug("creating a VPC network in the account: %s" %
+                                                    self.account.name)
+        vpc = VPC.create(
+                         self.apiclient,
+                         self.services["vpc"],
+                         vpcofferingid=vpc_off.id,
+                         zoneid=self.zone.id,
+                         account=self.account.name,
+                         domainid=self.account.domainid
+                         )
+        self.validate_vpc_network(vpc)
+
+        self.network_offering = NetworkOffering.create(
+                                            self.apiclient,
+                                            self.services["network_offering"],
+                                            conservemode=False
+                                            )
+        # Enable Network offering
+        self.network_offering.update(self.apiclient, state='Enabled')
+
+        gateway = vpc.cidr.split('/')[0]
+        # Split the cidr to retrieve gateway
+        # for eg. cidr = 10.0.0.1/24
+        # Gateway = 10.0.0.1
+
+        # Creating network using the network offering created
+        self.debug("Creating network with network offering: %s" %
+                                                    self.network_offering.id)
+        network = Network.create(
+                                self.apiclient,
+                                self.services["network"],
+                                accountid=self.account.name,
+                                domainid=self.account.domainid,
+                                networkofferingid=self.network_offering.id,
+                                zoneid=self.zone.id,
+                                gateway=gateway,
+                                vpcid=vpc.id
+                                )
+        self.debug("Created network with ID: %s" % network.id)
+        # Spawn an instance in that network
+        virtual_machine = VirtualMachine.create(
+                                  self.apiclient,
+                                  self.services["virtual_machine"],
+                                  accountid=self.account.name,
+                                  domainid=self.account.domainid,
+                                  serviceofferingid=self.service_offering.id,
+                                  networkids=[str(network.id)]
+                                  )
+        self.debug("Deployed VM in network: %s" % network.id)
+
+        self.debug("Associating public IP for network: %s" % network.name)
+        public_ip = PublicIPAddress.create(
+                                self.apiclient,
+                                accountid=self.account.name,
+                                zoneid=self.zone.id,
+                                domainid=self.account.domainid,
+                                networkid=network.id,
+                                vpcid=vpc.id
+                                )
+        self.debug("Associated %s with network %s" % (
+                                        public_ip.ipaddress.ipaddress,
+                                        network.id
+                                        ))
+
+        self.debug("Creating LB rule for IP address: %s" %
+                                        public_ip.ipaddress.ipaddress)
+
+        lb_rule = LoadBalancerRule.create(
+                                    self.apiclient,
+                                    self.services["lbrule"],
+                                    ipaddressid=public_ip.ipaddress.id,
+                                    accountid=self.account.name,
+                                    networkid=network.id,
+                                    vpcid=vpc.id,
+                                    domainid=self.account.domainid
+                                )
+
+        self.debug("Associating public IP for network: %s" % vpc.name)
+        public_ip_2 = PublicIPAddress.create(
+                                self.apiclient,
+                                accountid=self.account.name,
+                                zoneid=self.zone.id,
+                                domainid=self.account.domainid,
+                                networkid=network.id,
+                                vpcid=vpc.id
+                                )
+        self.debug("Associated %s with network %s" % (
+                                        public_ip_2.ipaddress.ipaddress,
+                                        network.id
+                                        ))
+
+        nat_rule = NATRule.create(
+                                  self.apiclient,
+                                  virtual_machine,
+                                  self.services["natrule"],
+                                  ipaddressid=public_ip_2.ipaddress.id,
+                                  openfirewall=False,
+                                  networkid=network.id,
+                                  vpcid=vpc.id
+                                  )
+
+        self.debug("Adding NetwrokACl rules to make PF and LB accessible")
+        networkacl_1 = NetworkACL.create(
+                self.apiclient,
+                networkid=network.id,
+                services=self.services["natrule"],
+                traffictype='Ingress'
+                )
+
+        networkacl_2 = NetworkACL.create(
+                                self.apiclient,
+                                networkid=network.id,
+                                services=self.services["lbrule"],
+                                traffictype='Ingress'
+                                )
+        self.debug("Checking if we can SSH into VM?")
+        try:
+            virtual_machine.get_ssh_client(
+                ipaddress=public_ip_2.ipaddress.ipaddress,
+                )
+            self.debug("SSH into VM is successfully")
+        except Exception as e:
+            self.fail("Failed to SSH into VM - %s, %s" %
+                    (public_ip_2.ipaddress.ipaddress, e))
+
+        self.debug("Associating public IP for network: %s" % network.name)
+        public_ip_3 = PublicIPAddress.create(
+                                self.apiclient,
+                                accountid=self.account.name,
+                                zoneid=self.zone.id,
+                                domainid=self.account.domainid,
+                                networkid=network.id,
+                                vpcid=vpc.id
+                                )
+        self.debug("Associated %s with network %s" % (
+                                        public_ip_3.ipaddress.ipaddress,
+                                        network.id
+                                        ))
+        self.debug("Enabling static NAT for IP: %s" %
+                                            public_ip_3.ipaddress.ipaddress)
+        try:
+            StaticNATRule.enable(
+                              self.apiclient,
+                              ipaddressid=public_ip_3.ipaddress.id,
+                              virtualmachineid=virtual_machine.id,
+                              networkid=network.id
+                              )
+            self.debug("Static NAT enabled for IP: %s" %
+                                            public_ip_3.ipaddress.ipaddress)
+        except Exception as e:
+            self.fail("Failed to enable static NAT on IP: %s - %s" % (
+                                            public_ip_3.ipaddress.ipaddress, e))
+
+        public_ips = PublicIPAddress.list(
+                                          self.apiclient,
+                                          networkid=network.id,
+                                          listall=True,
+                                          isstaticnat=True,
+                                          account=self.account.name,
+                                          domainid=self.account.domainid
+                                          )
+        self.assertEqual(
+                         isinstance(public_ips, list),
+                         True,
+                         "List public Ip for network should list the Ip addr"
+                         )
+        self.assertEqual(
+                         public_ips[0].ipaddress,
+                         public_ip_3.ipaddress.ipaddress,
+                         "List public Ip for network should list the Ip addr"
+                         )
+        # TODO: Remote Access VPN is not yet supported in VPC
+        return
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f70383b3/tools/marvin/marvin/integration/lib/base.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/integration/lib/base.py b/tools/marvin/marvin/integration/lib/base.py
index 27a26b8..d2181fb 100755
--- a/tools/marvin/marvin/integration/lib/base.py
+++ b/tools/marvin/marvin/integration/lib/base.py
@@ -3081,6 +3081,21 @@ class VpcOffering:
         cmd.name = "-".join([services["name"], random_gen()])
         cmd.displaytext = services["displaytext"]
         cmd.supportedServices = services["supportedservices"]
+        if "serviceProviderList" in services:
+            for service, provider in services["serviceProviderList"].items():
+                cmd.serviceproviderlist.append({
+                                            'service': service,
+                                            'provider': provider
+                                           })
+        if "serviceCapabilityList" in services:
+            cmd.servicecapabilitylist = []
+            for service, capability in services["serviceCapabilityList"].items():
+                for ctype, value in capability.items():
+                    cmd.servicecapabilitylist.append({
+                                            'service': service,
+                                            'capabilitytype': ctype,
+                                            'capabilityvalue': value
+                                           })
         return VpcOffering(apiclient.createVPCOffering(cmd).__dict__)
 
     def update(self, apiclient, name=None, displaytext=None, state=None):


RE: [20/31] git commit: updated refs/heads/distributedrouter to a8d43ba

Posted by Konstantina Chremmou <ko...@citrix.com>.
Hi,

This commit adds a new parameter to ListVMsCmd, but no 'since' has been specified in the parameter annotation. Please rectify.

Thanks,
Tina

---------------------------------------------------------------------------------------
Guidelines for writing/modifying CS APIs:

https://cwiki.apache.org/confluence/display/CLOUDSTACK/CloudStack+API+Coding+Guidelines
---------------------------------------------------------------------------------------



> -----Original Message-----
> From: muralireddy@apache.org [mailto:muralireddy@apache.org]
> Sent: 13 March 2014 1:53 PM
> To: commits@cloudstack.apache.org
> Subject: [20/31] git commit: updated refs/heads/distributedrouter to
> a8d43ba
> 
> CLOUDSTACK-6052: List VM enhancement to support querying with multiple
> VM IDs New parameter 'ids' added to listVirtualMachine API. The syntax
> looks like
> http://localhost:8096/api?command=listVirtualMachines&listAll=true&ids=e
> ddac053-9b12-4d2e-acb7-233de2e98112,009966fc-4d7b-4f84-8609-
> 254979ba0134
> The new parameter will be mutually exclusive with the existing 'id'
> parameter.
> 
> 
> Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
> Commit: http://git-wip-
> us.apache.org/repos/asf/cloudstack/commit/5779292e
> Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/5779292e
> Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/5779292e
> 
> Branch: refs/heads/distributedrouter
> Commit: 5779292e93fe52a7fb5ec0abffe1e3f6b9c10121
> Parents: bc4c805
> Author: Koushik Das <ko...@apache.org>
> Authored: Tue Mar 11 11:49:13 2014 +0530
> Committer: Koushik Das <ko...@apache.org>
> Committed: Thu Mar 13 17:05:35 2014 +0530
> 
> ----------------------------------------------------------------------
>  .../api/command/user/vm/ListVMsCmd.java         |  8 +++
>  .../com/cloud/api/query/QueryManagerImpl.java   | 20 ++++++--
>  test/integration/smoke/test_deploy_vm.py        | 52
> +++++++++++++++++++-
>  3 files changed, 76 insertions(+), 4 deletions(-)
> ----------------------------------------------------------------------
> 
> 
> http://git-wip-
> us.apache.org/repos/asf/cloudstack/blob/5779292e/api/src/org/apache/clo
> udstack/api/command/user/vm/ListVMsCmd.java
> ----------------------------------------------------------------------
> diff --git
> a/api/src/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java
> b/api/src/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java
> index 1a564f6..1ba2b23 100644
> ---
> a/api/src/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java
> +++
> b/api/src/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java
> @@ -64,6 +64,10 @@ public class ListVMsCmd extends
> BaseListTaggedResourcesCmd {
>      @Parameter(name = ApiConstants.ID, type = CommandType.UUID,
> entityType = UserVmResponse.class, description = "the ID of the virtual
> machine")
>      private Long id;
> 
> +    @Parameter(name=ApiConstants.IDS, type=CommandType.LIST,
> collectionType=CommandType.UUID, entityType=UserVmResponse.class,
> +               description="the IDs of the virtual machines, mutually exclusive with
> id")
> +    private List<Long> ids;
> +
>      @Parameter(name = ApiConstants.NAME, type = CommandType.STRING,
> description = "name of the virtual machine")
>      private String name;
> 
> @@ -135,6 +139,10 @@ public class ListVMsCmd extends
> BaseListTaggedResourcesCmd {
>          return id;
>      }
> 
> +    public List<Long> getIds() {
> +        return ids;
> +    }
> +
>      public String getName() {
>          return name;
>      }
> 
> http://git-wip-
> us.apache.org/repos/asf/cloudstack/blob/5779292e/server/src/com/cloud/a
> pi/query/QueryManagerImpl.java
> ----------------------------------------------------------------------
> diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java
> b/server/src/com/cloud/api/query/QueryManagerImpl.java
> index 4200799..47d2aec 100644
> --- a/server/src/com/cloud/api/query/QueryManagerImpl.java
> +++ b/server/src/com/cloud/api/query/QueryManagerImpl.java
> @@ -728,11 +728,22 @@ public class QueryManagerImpl extends
> ManagerBase implements QueryService {
>          Boolean isRecursive = domainIdRecursiveListProject.second();
>          ListProjectResourcesCriteria listProjectResourcesCriteria =
> domainIdRecursiveListProject.third();
> 
> +        List<Long> ids = null;
> +        if (cmd.getId() != null) {
> +            if (cmd.getIds() != null && !cmd.getIds().isEmpty()) {
> +                throw new InvalidParameterValueException("Specify either id or
> ids but not both parameters");
> +            }
> +            ids = new ArrayList<Long>();
> +            ids.add(cmd.getId());
> +        } else {
> +            ids = cmd.getIds();
> +        }
> +
>          Criteria c = new Criteria("id", Boolean.TRUE, cmd.getStartIndex(),
> cmd.getPageSizeVal());
>          // Criteria c = new Criteria(null, Boolean.FALSE, cmd.getStartIndex(),
>          // cmd.getPageSizeVal()); //version without default sorting
>          c.addCriteria(Criteria.KEYWORD, cmd.getKeyword());
> -        c.addCriteria(Criteria.ID, cmd.getId());
> +        c.addCriteria(Criteria.ID, ids);
>          c.addCriteria(Criteria.NAME, cmd.getName());
>          c.addCriteria(Criteria.STATE, cmd.getState());
>          c.addCriteria(Criteria.DATACENTERID, cmd.getZoneId()); @@ -805,7
> +816,7 @@ public class QueryManagerImpl extends ManagerBase
> implements QueryService {
>          Object display = c.getCriteria(Criteria.DISPLAY);
> 
>          sb.and("displayName", sb.entity().getDisplayName(),
> SearchCriteria.Op.LIKE);
> -        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
> +        sb.and("idIN", sb.entity().getId(), SearchCriteria.Op.IN);
>          sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE);
>          sb.and("stateEQ", sb.entity().getState(), SearchCriteria.Op.EQ);
>          sb.and("stateNEQ", sb.entity().getState(), SearchCriteria.Op.NEQ); @@
> -889,7 +900,10 @@ public class QueryManagerImpl extends ManagerBase
> implements QueryService {
>          }
> 
>          if (id != null) {
> -            sc.setParameters("id", id);
> +            List<?> idList = (id instanceof List<?> ? (List<?>)id : null);
> +            if (idList != null && !idList.isEmpty()) {
> +                sc.setParameters("idIN", idList.toArray());
> +            }
>          }
> 
>          if (templateId != null) {
> 
> http://git-wip-
> us.apache.org/repos/asf/cloudstack/blob/5779292e/test/integration/smoke
> /test_deploy_vm.py
> ----------------------------------------------------------------------
> diff --git a/test/integration/smoke/test_deploy_vm.py
> b/test/integration/smoke/test_deploy_vm.py
> index 425aeb7..fcde229 100644
> --- a/test/integration/smoke/test_deploy_vm.py
> +++ b/test/integration/smoke/test_deploy_vm.py
> @@ -51,6 +51,11 @@ class TestData(object):
>                  "name" : "testvm",
>                  "displayname" : "Test VM",
>              },
> +            #data reqd for virtual machine creation
> +            "virtual_machine2" : {
> +                "name" : "testvm2",
> +                "displayname" : "Test VM2",
> +            },
>              #small service offering
>              "service_offering": {
>                  "small": {
> @@ -149,8 +154,53 @@ class TestDeployVM(cloudstackTestCase):
>              msg="VM is not in Running state"
>          )
> 
> +    @attr(tags = ['advanced', 'simulator', 'basic', 'sg'])
> +    def test_deploy_vm_multiple(self):
> +        """Test Multiple Deploy Virtual Machine
> +
> +        # Validate the following:
> +        # 1. deploy 2 virtual machines
> +        # 2. listVirtualMachines using 'ids' parameter returns accurate
> information
> +        """
> +        self.virtual_machine = VirtualMachine.create(
> +            self.apiclient,
> +            self.testdata["virtual_machine"],
> +            accountid=self.account.name,
> +            zoneid=self.zone.id,
> +            domainid=self.account.domainid,
> +            serviceofferingid=self.service_offering.id,
> +            templateid=self.template.id
> +        )
> +
> +        self.virtual_machine2 = VirtualMachine.create(
> +            self.apiclient,
> +            self.testdata["virtual_machine2"],
> +            accountid=self.account.name,
> +            zoneid=self.zone.id,
> +            domainid=self.account.domainid,
> +            serviceofferingid=self.service_offering.id,
> +            templateid=self.template.id
> +        )
> +
> +        list_vms = VirtualMachine.list(self.apiclient,
> ids=[self.virtual_machine.id, self.virtual_machine2.id], listAll=True)
> +        self.debug(
> +            "Verify listVirtualMachines response for virtual machines: %s, %s" %
> (self.virtual_machine.id, self.virtual_machine2.id)
> +        )
> +
> +        self.assertEqual(
> +            isinstance(list_vms, list),
> +            True,
> +            "List VM response was not a valid list"
> +        )
> +        self.assertEqual(
> +            len(list_vms),
> +            2,
> +            "List VM response was empty, expected 2 VMs"
> +        )
> +
>      def tearDown(self):
>          try:
>              cleanup_resources(self.apiclient, self.cleanup)
>          except Exception as e:
> -            self.debug("Warning! Exception in tearDown: %s" % e)
> \ No newline at end of file
> +            self.debug("Warning! Exception in tearDown: %s" % e)
> +


Re: [20/31] git commit: updated refs/heads/distributedrouter to a8d43ba

Posted by Koushik Das <ko...@citrix.com>.
Fixed with commit 16ddc3414ae0269ecb8903f670496e45f68d6ef6

On 13-Mar-2014, at 11:34 PM, David Nalley <da...@gnsa.us> wrote:

> Better yet, feel free to submit a patch that fixes it in addition to
> the Jira :)
> 
> --David
> 
> On Thu, Mar 13, 2014 at 2:00 PM, Alena Prokharchyk
> <Al...@citrix.com> wrote:
>> Konstantina, feel free to raise the Jira ticket for it.
>> 
>> Thanks,
>> Alena.
>> 
>> On 3/13/14, 8:46 AM, "Konstantina Chremmou"
>> <ko...@citrix.com> wrote:
>> 
>>> Hi,
>>> 
>>> This commit adds a new parameter to ListVMsCmd, but no 'since' has been
>>> specified in the parameter annotation. Please rectify.
>>> 
>>> Thanks,
>>> Tina
>>> 
>>> --------------------------------------------------------------------------
>>> -------------
>>> Guidelines for writing/modifying CS APIs:
>>> 
>>> https://cwiki.apache.org/confluence/display/CLOUDSTACK/CloudStack+API+Codi
>>> ng+Guidelines
>>> --------------------------------------------------------------------------
>>> -------------
>>> 
>>>> -----Original Message-----
>>>> From: muralireddy@apache.org [mailto:muralireddy@apache.org]
>>>> Sent: 13 March 2014 1:53 PM
>>>> To: commits@cloudstack.apache.org
>>>> Subject: [20/31] git commit: updated refs/heads/distributedrouter to
>>>> a8d43ba
>>>> 
>>>> CLOUDSTACK-6052: List VM enhancement to support querying with multiple
>>>> VM IDs New parameter 'ids' added to listVirtualMachine API. The syntax
>>>> looks like
>>>> http://localhost:8096/api?command=listVirtualMachines&listAll=true&ids=e
>>>> ddac053-9b12-4d2e-acb7-233de2e98112,009966fc-4d7b-4f84-8609-
>>>> 254979ba0134
>>>> The new parameter will be mutually exclusive with the existing 'id'
>>>> parameter.
>>>> 
>>>> 
>>>> Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
>>>> Commit: http://git-wip-
>>>> us.apache.org/repos/asf/cloudstack/commit/5779292e
>>>> Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/5779292e
>>>> Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/5779292e
>>>> 
>>>> Branch: refs/heads/distributedrouter
>>>> Commit: 5779292e93fe52a7fb5ec0abffe1e3f6b9c10121
>>>> Parents: bc4c805
>>>> Author: Koushik Das <ko...@apache.org>
>>>> Authored: Tue Mar 11 11:49:13 2014 +0530
>>>> Committer: Koushik Das <ko...@apache.org>
>>>> Committed: Thu Mar 13 17:05:35 2014 +0530
>>>> 
>>>> ----------------------------------------------------------------------
>>>> .../api/command/user/vm/ListVMsCmd.java         |  8 +++
>>>> .../com/cloud/api/query/QueryManagerImpl.java   | 20 ++++++--
>>>> test/integration/smoke/test_deploy_vm.py        | 52
>>>> +++++++++++++++++++-
>>>> 3 files changed, 76 insertions(+), 4 deletions(-)
>>>> ----------------------------------------------------------------------
>>>> 
>>>> 
>>>> http://git-wip-
>>>> us.apache.org/repos/asf/cloudstack/blob/5779292e/api/src/org/apache/clo
>>>> udstack/api/command/user/vm/ListVMsCmd.java
>>>> ----------------------------------------------------------------------
>>>> diff --git
>>>> a/api/src/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java
>>>> b/api/src/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java
>>>> index 1a564f6..1ba2b23 100644
>>>> ---
>>>> a/api/src/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java
>>>> +++
>>>> b/api/src/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java
>>>> @@ -64,6 +64,10 @@ public class ListVMsCmd extends
>>>> BaseListTaggedResourcesCmd {
>>>>     @Parameter(name = ApiConstants.ID, type = CommandType.UUID,
>>>> entityType = UserVmResponse.class, description = "the ID of the virtual
>>>> machine")
>>>>     private Long id;
>>>> 
>>>> +    @Parameter(name=ApiConstants.IDS, type=CommandType.LIST,
>>>> collectionType=CommandType.UUID, entityType=UserVmResponse.class,
>>>> +               description="the IDs of the virtual machines, mutually
>>>> exclusive with
>>>> id")
>>>> +    private List<Long> ids;
>>>> +
>>>>     @Parameter(name = ApiConstants.NAME, type = CommandType.STRING,
>>>> description = "name of the virtual machine")
>>>>     private String name;
>>>> 
>>>> @@ -135,6 +139,10 @@ public class ListVMsCmd extends
>>>> BaseListTaggedResourcesCmd {
>>>>         return id;
>>>>     }
>>>> 
>>>> +    public List<Long> getIds() {
>>>> +        return ids;
>>>> +    }
>>>> +
>>>>     public String getName() {
>>>>         return name;
>>>>     }
>>>> 
>>>> http://git-wip-
>>>> us.apache.org/repos/asf/cloudstack/blob/5779292e/server/src/com/cloud/a
>>>> pi/query/QueryManagerImpl.java
>>>> ----------------------------------------------------------------------
>>>> diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java
>>>> b/server/src/com/cloud/api/query/QueryManagerImpl.java
>>>> index 4200799..47d2aec 100644
>>>> --- a/server/src/com/cloud/api/query/QueryManagerImpl.java
>>>> +++ b/server/src/com/cloud/api/query/QueryManagerImpl.java
>>>> @@ -728,11 +728,22 @@ public class QueryManagerImpl extends
>>>> ManagerBase implements QueryService {
>>>>         Boolean isRecursive = domainIdRecursiveListProject.second();
>>>>         ListProjectResourcesCriteria listProjectResourcesCriteria =
>>>> domainIdRecursiveListProject.third();
>>>> 
>>>> +        List<Long> ids = null;
>>>> +        if (cmd.getId() != null) {
>>>> +            if (cmd.getIds() != null && !cmd.getIds().isEmpty()) {
>>>> +                throw new InvalidParameterValueException("Specify
>>>> either id or
>>>> ids but not both parameters");
>>>> +            }
>>>> +            ids = new ArrayList<Long>();
>>>> +            ids.add(cmd.getId());
>>>> +        } else {
>>>> +            ids = cmd.getIds();
>>>> +        }
>>>> +
>>>>         Criteria c = new Criteria("id", Boolean.TRUE,
>>>> cmd.getStartIndex(),
>>>> cmd.getPageSizeVal());
>>>>         // Criteria c = new Criteria(null, Boolean.FALSE,
>>>> cmd.getStartIndex(),
>>>>         // cmd.getPageSizeVal()); //version without default sorting
>>>>         c.addCriteria(Criteria.KEYWORD, cmd.getKeyword());
>>>> -        c.addCriteria(Criteria.ID, cmd.getId());
>>>> +        c.addCriteria(Criteria.ID, ids);
>>>>         c.addCriteria(Criteria.NAME, cmd.getName());
>>>>         c.addCriteria(Criteria.STATE, cmd.getState());
>>>>         c.addCriteria(Criteria.DATACENTERID, cmd.getZoneId()); @@
>>>> -805,7
>>>> +816,7 @@ public class QueryManagerImpl extends ManagerBase
>>>> implements QueryService {
>>>>         Object display = c.getCriteria(Criteria.DISPLAY);
>>>> 
>>>>         sb.and("displayName", sb.entity().getDisplayName(),
>>>> SearchCriteria.Op.LIKE);
>>>> -        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
>>>> +        sb.and("idIN", sb.entity().getId(), SearchCriteria.Op.IN);
>>>>         sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE);
>>>>         sb.and("stateEQ", sb.entity().getState(),
>>>> SearchCriteria.Op.EQ);
>>>>         sb.and("stateNEQ", sb.entity().getState(),
>>>> SearchCriteria.Op.NEQ); @@
>>>> -889,7 +900,10 @@ public class QueryManagerImpl extends ManagerBase
>>>> implements QueryService {
>>>>         }
>>>> 
>>>>         if (id != null) {
>>>> -            sc.setParameters("id", id);
>>>> +            List<?> idList = (id instanceof List<?> ? (List<?>)id :
>>>> null);
>>>> +            if (idList != null && !idList.isEmpty()) {
>>>> +                sc.setParameters("idIN", idList.toArray());
>>>> +            }
>>>>         }
>>>> 
>>>>         if (templateId != null) {
>>>> 
>>>> http://git-wip-
>>>> us.apache.org/repos/asf/cloudstack/blob/5779292e/test/integration/smoke
>>>> /test_deploy_vm.py
>>>> ----------------------------------------------------------------------
>>>> diff --git a/test/integration/smoke/test_deploy_vm.py
>>>> b/test/integration/smoke/test_deploy_vm.py
>>>> index 425aeb7..fcde229 100644
>>>> --- a/test/integration/smoke/test_deploy_vm.py
>>>> +++ b/test/integration/smoke/test_deploy_vm.py
>>>> @@ -51,6 +51,11 @@ class TestData(object):
>>>>                 "name" : "testvm",
>>>>                 "displayname" : "Test VM",
>>>>             },
>>>> +            #data reqd for virtual machine creation
>>>> +            "virtual_machine2" : {
>>>> +                "name" : "testvm2",
>>>> +                "displayname" : "Test VM2",
>>>> +            },
>>>>             #small service offering
>>>>             "service_offering": {
>>>>                 "small": {
>>>> @@ -149,8 +154,53 @@ class TestDeployVM(cloudstackTestCase):
>>>>             msg="VM is not in Running state"
>>>>         )
>>>> 
>>>> +    @attr(tags = ['advanced', 'simulator', 'basic', 'sg'])
>>>> +    def test_deploy_vm_multiple(self):
>>>> +        """Test Multiple Deploy Virtual Machine
>>>> +
>>>> +        # Validate the following:
>>>> +        # 1. deploy 2 virtual machines
>>>> +        # 2. listVirtualMachines using 'ids' parameter returns accurate
>>>> information
>>>> +        """
>>>> +        self.virtual_machine = VirtualMachine.create(
>>>> +            self.apiclient,
>>>> +            self.testdata["virtual_machine"],
>>>> +            accountid=self.account.name,
>>>> +            zoneid=self.zone.id,
>>>> +            domainid=self.account.domainid,
>>>> +            serviceofferingid=self.service_offering.id,
>>>> +            templateid=self.template.id
>>>> +        )
>>>> +
>>>> +        self.virtual_machine2 = VirtualMachine.create(
>>>> +            self.apiclient,
>>>> +            self.testdata["virtual_machine2"],
>>>> +            accountid=self.account.name,
>>>> +            zoneid=self.zone.id,
>>>> +            domainid=self.account.domainid,
>>>> +            serviceofferingid=self.service_offering.id,
>>>> +            templateid=self.template.id
>>>> +        )
>>>> +
>>>> +        list_vms = VirtualMachine.list(self.apiclient,
>>>> ids=[self.virtual_machine.id, self.virtual_machine2.id], listAll=True)
>>>> +        self.debug(
>>>> +            "Verify listVirtualMachines response for virtual machines:
>>>> %s, %s" %
>>>> (self.virtual_machine.id, self.virtual_machine2.id)
>>>> +        )
>>>> +
>>>> +        self.assertEqual(
>>>> +            isinstance(list_vms, list),
>>>> +            True,
>>>> +            "List VM response was not a valid list"
>>>> +        )
>>>> +        self.assertEqual(
>>>> +            len(list_vms),
>>>> +            2,
>>>> +            "List VM response was empty, expected 2 VMs"
>>>> +        )
>>>> +
>>>>     def tearDown(self):
>>>>         try:
>>>>             cleanup_resources(self.apiclient, self.cleanup)
>>>>         except Exception as e:
>>>> -            self.debug("Warning! Exception in tearDown: %s" % e)
>>>> \ No newline at end of file
>>>> +            self.debug("Warning! Exception in tearDown: %s" % e)
>>>> +
>>> 
>> 


Re: [20/31] git commit: updated refs/heads/distributedrouter to a8d43ba

Posted by David Nalley <da...@gnsa.us>.
Better yet, feel free to submit a patch that fixes it in addition to
the Jira :)

--David

On Thu, Mar 13, 2014 at 2:00 PM, Alena Prokharchyk
<Al...@citrix.com> wrote:
> Konstantina, feel free to raise the Jira ticket for it.
>
> Thanks,
> Alena.
>
> On 3/13/14, 8:46 AM, "Konstantina Chremmou"
> <ko...@citrix.com> wrote:
>
>>Hi,
>>
>>This commit adds a new parameter to ListVMsCmd, but no 'since' has been
>>specified in the parameter annotation. Please rectify.
>>
>>Thanks,
>>Tina
>>
>>--------------------------------------------------------------------------
>>-------------
>>Guidelines for writing/modifying CS APIs:
>>
>>https://cwiki.apache.org/confluence/display/CLOUDSTACK/CloudStack+API+Codi
>>ng+Guidelines
>>--------------------------------------------------------------------------
>>-------------
>>
>>> -----Original Message-----
>>> From: muralireddy@apache.org [mailto:muralireddy@apache.org]
>>> Sent: 13 March 2014 1:53 PM
>>> To: commits@cloudstack.apache.org
>>> Subject: [20/31] git commit: updated refs/heads/distributedrouter to
>>> a8d43ba
>>>
>>> CLOUDSTACK-6052: List VM enhancement to support querying with multiple
>>> VM IDs New parameter 'ids' added to listVirtualMachine API. The syntax
>>> looks like
>>> http://localhost:8096/api?command=listVirtualMachines&listAll=true&ids=e
>>> ddac053-9b12-4d2e-acb7-233de2e98112,009966fc-4d7b-4f84-8609-
>>> 254979ba0134
>>> The new parameter will be mutually exclusive with the existing 'id'
>>> parameter.
>>>
>>>
>>> Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
>>> Commit: http://git-wip-
>>> us.apache.org/repos/asf/cloudstack/commit/5779292e
>>> Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/5779292e
>>> Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/5779292e
>>>
>>> Branch: refs/heads/distributedrouter
>>> Commit: 5779292e93fe52a7fb5ec0abffe1e3f6b9c10121
>>> Parents: bc4c805
>>> Author: Koushik Das <ko...@apache.org>
>>> Authored: Tue Mar 11 11:49:13 2014 +0530
>>> Committer: Koushik Das <ko...@apache.org>
>>> Committed: Thu Mar 13 17:05:35 2014 +0530
>>>
>>> ----------------------------------------------------------------------
>>>  .../api/command/user/vm/ListVMsCmd.java         |  8 +++
>>>  .../com/cloud/api/query/QueryManagerImpl.java   | 20 ++++++--
>>>  test/integration/smoke/test_deploy_vm.py        | 52
>>> +++++++++++++++++++-
>>>  3 files changed, 76 insertions(+), 4 deletions(-)
>>> ----------------------------------------------------------------------
>>>
>>>
>>> http://git-wip-
>>> us.apache.org/repos/asf/cloudstack/blob/5779292e/api/src/org/apache/clo
>>> udstack/api/command/user/vm/ListVMsCmd.java
>>> ----------------------------------------------------------------------
>>> diff --git
>>> a/api/src/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java
>>> b/api/src/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java
>>> index 1a564f6..1ba2b23 100644
>>> ---
>>> a/api/src/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java
>>> +++
>>> b/api/src/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java
>>> @@ -64,6 +64,10 @@ public class ListVMsCmd extends
>>> BaseListTaggedResourcesCmd {
>>>      @Parameter(name = ApiConstants.ID, type = CommandType.UUID,
>>> entityType = UserVmResponse.class, description = "the ID of the virtual
>>> machine")
>>>      private Long id;
>>>
>>> +    @Parameter(name=ApiConstants.IDS, type=CommandType.LIST,
>>> collectionType=CommandType.UUID, entityType=UserVmResponse.class,
>>> +               description="the IDs of the virtual machines, mutually
>>>exclusive with
>>> id")
>>> +    private List<Long> ids;
>>> +
>>>      @Parameter(name = ApiConstants.NAME, type = CommandType.STRING,
>>> description = "name of the virtual machine")
>>>      private String name;
>>>
>>> @@ -135,6 +139,10 @@ public class ListVMsCmd extends
>>> BaseListTaggedResourcesCmd {
>>>          return id;
>>>      }
>>>
>>> +    public List<Long> getIds() {
>>> +        return ids;
>>> +    }
>>> +
>>>      public String getName() {
>>>          return name;
>>>      }
>>>
>>> http://git-wip-
>>> us.apache.org/repos/asf/cloudstack/blob/5779292e/server/src/com/cloud/a
>>> pi/query/QueryManagerImpl.java
>>> ----------------------------------------------------------------------
>>> diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java
>>> b/server/src/com/cloud/api/query/QueryManagerImpl.java
>>> index 4200799..47d2aec 100644
>>> --- a/server/src/com/cloud/api/query/QueryManagerImpl.java
>>> +++ b/server/src/com/cloud/api/query/QueryManagerImpl.java
>>> @@ -728,11 +728,22 @@ public class QueryManagerImpl extends
>>> ManagerBase implements QueryService {
>>>          Boolean isRecursive = domainIdRecursiveListProject.second();
>>>          ListProjectResourcesCriteria listProjectResourcesCriteria =
>>> domainIdRecursiveListProject.third();
>>>
>>> +        List<Long> ids = null;
>>> +        if (cmd.getId() != null) {
>>> +            if (cmd.getIds() != null && !cmd.getIds().isEmpty()) {
>>> +                throw new InvalidParameterValueException("Specify
>>>either id or
>>> ids but not both parameters");
>>> +            }
>>> +            ids = new ArrayList<Long>();
>>> +            ids.add(cmd.getId());
>>> +        } else {
>>> +            ids = cmd.getIds();
>>> +        }
>>> +
>>>          Criteria c = new Criteria("id", Boolean.TRUE,
>>>cmd.getStartIndex(),
>>> cmd.getPageSizeVal());
>>>          // Criteria c = new Criteria(null, Boolean.FALSE,
>>>cmd.getStartIndex(),
>>>          // cmd.getPageSizeVal()); //version without default sorting
>>>          c.addCriteria(Criteria.KEYWORD, cmd.getKeyword());
>>> -        c.addCriteria(Criteria.ID, cmd.getId());
>>> +        c.addCriteria(Criteria.ID, ids);
>>>          c.addCriteria(Criteria.NAME, cmd.getName());
>>>          c.addCriteria(Criteria.STATE, cmd.getState());
>>>          c.addCriteria(Criteria.DATACENTERID, cmd.getZoneId()); @@
>>>-805,7
>>> +816,7 @@ public class QueryManagerImpl extends ManagerBase
>>> implements QueryService {
>>>          Object display = c.getCriteria(Criteria.DISPLAY);
>>>
>>>          sb.and("displayName", sb.entity().getDisplayName(),
>>> SearchCriteria.Op.LIKE);
>>> -        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
>>> +        sb.and("idIN", sb.entity().getId(), SearchCriteria.Op.IN);
>>>          sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE);
>>>          sb.and("stateEQ", sb.entity().getState(),
>>>SearchCriteria.Op.EQ);
>>>          sb.and("stateNEQ", sb.entity().getState(),
>>>SearchCriteria.Op.NEQ); @@
>>> -889,7 +900,10 @@ public class QueryManagerImpl extends ManagerBase
>>> implements QueryService {
>>>          }
>>>
>>>          if (id != null) {
>>> -            sc.setParameters("id", id);
>>> +            List<?> idList = (id instanceof List<?> ? (List<?>)id :
>>>null);
>>> +            if (idList != null && !idList.isEmpty()) {
>>> +                sc.setParameters("idIN", idList.toArray());
>>> +            }
>>>          }
>>>
>>>          if (templateId != null) {
>>>
>>> http://git-wip-
>>> us.apache.org/repos/asf/cloudstack/blob/5779292e/test/integration/smoke
>>> /test_deploy_vm.py
>>> ----------------------------------------------------------------------
>>> diff --git a/test/integration/smoke/test_deploy_vm.py
>>> b/test/integration/smoke/test_deploy_vm.py
>>> index 425aeb7..fcde229 100644
>>> --- a/test/integration/smoke/test_deploy_vm.py
>>> +++ b/test/integration/smoke/test_deploy_vm.py
>>> @@ -51,6 +51,11 @@ class TestData(object):
>>>                  "name" : "testvm",
>>>                  "displayname" : "Test VM",
>>>              },
>>> +            #data reqd for virtual machine creation
>>> +            "virtual_machine2" : {
>>> +                "name" : "testvm2",
>>> +                "displayname" : "Test VM2",
>>> +            },
>>>              #small service offering
>>>              "service_offering": {
>>>                  "small": {
>>> @@ -149,8 +154,53 @@ class TestDeployVM(cloudstackTestCase):
>>>              msg="VM is not in Running state"
>>>          )
>>>
>>> +    @attr(tags = ['advanced', 'simulator', 'basic', 'sg'])
>>> +    def test_deploy_vm_multiple(self):
>>> +        """Test Multiple Deploy Virtual Machine
>>> +
>>> +        # Validate the following:
>>> +        # 1. deploy 2 virtual machines
>>> +        # 2. listVirtualMachines using 'ids' parameter returns accurate
>>> information
>>> +        """
>>> +        self.virtual_machine = VirtualMachine.create(
>>> +            self.apiclient,
>>> +            self.testdata["virtual_machine"],
>>> +            accountid=self.account.name,
>>> +            zoneid=self.zone.id,
>>> +            domainid=self.account.domainid,
>>> +            serviceofferingid=self.service_offering.id,
>>> +            templateid=self.template.id
>>> +        )
>>> +
>>> +        self.virtual_machine2 = VirtualMachine.create(
>>> +            self.apiclient,
>>> +            self.testdata["virtual_machine2"],
>>> +            accountid=self.account.name,
>>> +            zoneid=self.zone.id,
>>> +            domainid=self.account.domainid,
>>> +            serviceofferingid=self.service_offering.id,
>>> +            templateid=self.template.id
>>> +        )
>>> +
>>> +        list_vms = VirtualMachine.list(self.apiclient,
>>> ids=[self.virtual_machine.id, self.virtual_machine2.id], listAll=True)
>>> +        self.debug(
>>> +            "Verify listVirtualMachines response for virtual machines:
>>>%s, %s" %
>>> (self.virtual_machine.id, self.virtual_machine2.id)
>>> +        )
>>> +
>>> +        self.assertEqual(
>>> +            isinstance(list_vms, list),
>>> +            True,
>>> +            "List VM response was not a valid list"
>>> +        )
>>> +        self.assertEqual(
>>> +            len(list_vms),
>>> +            2,
>>> +            "List VM response was empty, expected 2 VMs"
>>> +        )
>>> +
>>>      def tearDown(self):
>>>          try:
>>>              cleanup_resources(self.apiclient, self.cleanup)
>>>          except Exception as e:
>>> -            self.debug("Warning! Exception in tearDown: %s" % e)
>>> \ No newline at end of file
>>> +            self.debug("Warning! Exception in tearDown: %s" % e)
>>> +
>>
>

Re: [20/31] git commit: updated refs/heads/distributedrouter to a8d43ba

Posted by Alena Prokharchyk <Al...@citrix.com>.
Konstantina, feel free to raise the Jira ticket for it.

Thanks,
Alena.

On 3/13/14, 8:46 AM, "Konstantina Chremmou"
<ko...@citrix.com> wrote:

>Hi,
>
>This commit adds a new parameter to ListVMsCmd, but no 'since' has been
>specified in the parameter annotation. Please rectify.
>
>Thanks,
>Tina
>
>--------------------------------------------------------------------------
>-------------
>Guidelines for writing/modifying CS APIs:
>
>https://cwiki.apache.org/confluence/display/CLOUDSTACK/CloudStack+API+Codi
>ng+Guidelines
>--------------------------------------------------------------------------
>-------------
>
>> -----Original Message-----
>> From: muralireddy@apache.org [mailto:muralireddy@apache.org]
>> Sent: 13 March 2014 1:53 PM
>> To: commits@cloudstack.apache.org
>> Subject: [20/31] git commit: updated refs/heads/distributedrouter to
>> a8d43ba
>> 
>> CLOUDSTACK-6052: List VM enhancement to support querying with multiple
>> VM IDs New parameter 'ids' added to listVirtualMachine API. The syntax
>> looks like
>> http://localhost:8096/api?command=listVirtualMachines&listAll=true&ids=e
>> ddac053-9b12-4d2e-acb7-233de2e98112,009966fc-4d7b-4f84-8609-
>> 254979ba0134
>> The new parameter will be mutually exclusive with the existing 'id'
>> parameter.
>> 
>> 
>> Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
>> Commit: http://git-wip-
>> us.apache.org/repos/asf/cloudstack/commit/5779292e
>> Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/5779292e
>> Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/5779292e
>> 
>> Branch: refs/heads/distributedrouter
>> Commit: 5779292e93fe52a7fb5ec0abffe1e3f6b9c10121
>> Parents: bc4c805
>> Author: Koushik Das <ko...@apache.org>
>> Authored: Tue Mar 11 11:49:13 2014 +0530
>> Committer: Koushik Das <ko...@apache.org>
>> Committed: Thu Mar 13 17:05:35 2014 +0530
>> 
>> ----------------------------------------------------------------------
>>  .../api/command/user/vm/ListVMsCmd.java         |  8 +++
>>  .../com/cloud/api/query/QueryManagerImpl.java   | 20 ++++++--
>>  test/integration/smoke/test_deploy_vm.py        | 52
>> +++++++++++++++++++-
>>  3 files changed, 76 insertions(+), 4 deletions(-)
>> ----------------------------------------------------------------------
>> 
>> 
>> http://git-wip-
>> us.apache.org/repos/asf/cloudstack/blob/5779292e/api/src/org/apache/clo
>> udstack/api/command/user/vm/ListVMsCmd.java
>> ----------------------------------------------------------------------
>> diff --git
>> a/api/src/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java
>> b/api/src/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java
>> index 1a564f6..1ba2b23 100644
>> ---
>> a/api/src/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java
>> +++
>> b/api/src/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java
>> @@ -64,6 +64,10 @@ public class ListVMsCmd extends
>> BaseListTaggedResourcesCmd {
>>      @Parameter(name = ApiConstants.ID, type = CommandType.UUID,
>> entityType = UserVmResponse.class, description = "the ID of the virtual
>> machine")
>>      private Long id;
>> 
>> +    @Parameter(name=ApiConstants.IDS, type=CommandType.LIST,
>> collectionType=CommandType.UUID, entityType=UserVmResponse.class,
>> +               description="the IDs of the virtual machines, mutually
>>exclusive with
>> id")
>> +    private List<Long> ids;
>> +
>>      @Parameter(name = ApiConstants.NAME, type = CommandType.STRING,
>> description = "name of the virtual machine")
>>      private String name;
>> 
>> @@ -135,6 +139,10 @@ public class ListVMsCmd extends
>> BaseListTaggedResourcesCmd {
>>          return id;
>>      }
>> 
>> +    public List<Long> getIds() {
>> +        return ids;
>> +    }
>> +
>>      public String getName() {
>>          return name;
>>      }
>> 
>> http://git-wip-
>> us.apache.org/repos/asf/cloudstack/blob/5779292e/server/src/com/cloud/a
>> pi/query/QueryManagerImpl.java
>> ----------------------------------------------------------------------
>> diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java
>> b/server/src/com/cloud/api/query/QueryManagerImpl.java
>> index 4200799..47d2aec 100644
>> --- a/server/src/com/cloud/api/query/QueryManagerImpl.java
>> +++ b/server/src/com/cloud/api/query/QueryManagerImpl.java
>> @@ -728,11 +728,22 @@ public class QueryManagerImpl extends
>> ManagerBase implements QueryService {
>>          Boolean isRecursive = domainIdRecursiveListProject.second();
>>          ListProjectResourcesCriteria listProjectResourcesCriteria =
>> domainIdRecursiveListProject.third();
>> 
>> +        List<Long> ids = null;
>> +        if (cmd.getId() != null) {
>> +            if (cmd.getIds() != null && !cmd.getIds().isEmpty()) {
>> +                throw new InvalidParameterValueException("Specify
>>either id or
>> ids but not both parameters");
>> +            }
>> +            ids = new ArrayList<Long>();
>> +            ids.add(cmd.getId());
>> +        } else {
>> +            ids = cmd.getIds();
>> +        }
>> +
>>          Criteria c = new Criteria("id", Boolean.TRUE,
>>cmd.getStartIndex(),
>> cmd.getPageSizeVal());
>>          // Criteria c = new Criteria(null, Boolean.FALSE,
>>cmd.getStartIndex(),
>>          // cmd.getPageSizeVal()); //version without default sorting
>>          c.addCriteria(Criteria.KEYWORD, cmd.getKeyword());
>> -        c.addCriteria(Criteria.ID, cmd.getId());
>> +        c.addCriteria(Criteria.ID, ids);
>>          c.addCriteria(Criteria.NAME, cmd.getName());
>>          c.addCriteria(Criteria.STATE, cmd.getState());
>>          c.addCriteria(Criteria.DATACENTERID, cmd.getZoneId()); @@
>>-805,7
>> +816,7 @@ public class QueryManagerImpl extends ManagerBase
>> implements QueryService {
>>          Object display = c.getCriteria(Criteria.DISPLAY);
>> 
>>          sb.and("displayName", sb.entity().getDisplayName(),
>> SearchCriteria.Op.LIKE);
>> -        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
>> +        sb.and("idIN", sb.entity().getId(), SearchCriteria.Op.IN);
>>          sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE);
>>          sb.and("stateEQ", sb.entity().getState(),
>>SearchCriteria.Op.EQ);
>>          sb.and("stateNEQ", sb.entity().getState(),
>>SearchCriteria.Op.NEQ); @@
>> -889,7 +900,10 @@ public class QueryManagerImpl extends ManagerBase
>> implements QueryService {
>>          }
>> 
>>          if (id != null) {
>> -            sc.setParameters("id", id);
>> +            List<?> idList = (id instanceof List<?> ? (List<?>)id :
>>null);
>> +            if (idList != null && !idList.isEmpty()) {
>> +                sc.setParameters("idIN", idList.toArray());
>> +            }
>>          }
>> 
>>          if (templateId != null) {
>> 
>> http://git-wip-
>> us.apache.org/repos/asf/cloudstack/blob/5779292e/test/integration/smoke
>> /test_deploy_vm.py
>> ----------------------------------------------------------------------
>> diff --git a/test/integration/smoke/test_deploy_vm.py
>> b/test/integration/smoke/test_deploy_vm.py
>> index 425aeb7..fcde229 100644
>> --- a/test/integration/smoke/test_deploy_vm.py
>> +++ b/test/integration/smoke/test_deploy_vm.py
>> @@ -51,6 +51,11 @@ class TestData(object):
>>                  "name" : "testvm",
>>                  "displayname" : "Test VM",
>>              },
>> +            #data reqd for virtual machine creation
>> +            "virtual_machine2" : {
>> +                "name" : "testvm2",
>> +                "displayname" : "Test VM2",
>> +            },
>>              #small service offering
>>              "service_offering": {
>>                  "small": {
>> @@ -149,8 +154,53 @@ class TestDeployVM(cloudstackTestCase):
>>              msg="VM is not in Running state"
>>          )
>> 
>> +    @attr(tags = ['advanced', 'simulator', 'basic', 'sg'])
>> +    def test_deploy_vm_multiple(self):
>> +        """Test Multiple Deploy Virtual Machine
>> +
>> +        # Validate the following:
>> +        # 1. deploy 2 virtual machines
>> +        # 2. listVirtualMachines using 'ids' parameter returns accurate
>> information
>> +        """
>> +        self.virtual_machine = VirtualMachine.create(
>> +            self.apiclient,
>> +            self.testdata["virtual_machine"],
>> +            accountid=self.account.name,
>> +            zoneid=self.zone.id,
>> +            domainid=self.account.domainid,
>> +            serviceofferingid=self.service_offering.id,
>> +            templateid=self.template.id
>> +        )
>> +
>> +        self.virtual_machine2 = VirtualMachine.create(
>> +            self.apiclient,
>> +            self.testdata["virtual_machine2"],
>> +            accountid=self.account.name,
>> +            zoneid=self.zone.id,
>> +            domainid=self.account.domainid,
>> +            serviceofferingid=self.service_offering.id,
>> +            templateid=self.template.id
>> +        )
>> +
>> +        list_vms = VirtualMachine.list(self.apiclient,
>> ids=[self.virtual_machine.id, self.virtual_machine2.id], listAll=True)
>> +        self.debug(
>> +            "Verify listVirtualMachines response for virtual machines:
>>%s, %s" %
>> (self.virtual_machine.id, self.virtual_machine2.id)
>> +        )
>> +
>> +        self.assertEqual(
>> +            isinstance(list_vms, list),
>> +            True,
>> +            "List VM response was not a valid list"
>> +        )
>> +        self.assertEqual(
>> +            len(list_vms),
>> +            2,
>> +            "List VM response was empty, expected 2 VMs"
>> +        )
>> +
>>      def tearDown(self):
>>          try:
>>              cleanup_resources(self.apiclient, self.cleanup)
>>          except Exception as e:
>> -            self.debug("Warning! Exception in tearDown: %s" % e)
>> \ No newline at end of file
>> +            self.debug("Warning! Exception in tearDown: %s" % e)
>> +
>


RE: [20/31] git commit: updated refs/heads/distributedrouter to a8d43ba

Posted by Konstantina Chremmou <ko...@citrix.com>.
Hi,

This commit adds a new parameter to ListVMsCmd, but no 'since' has been specified in the parameter annotation. Please rectify.

Thanks,
Tina

---------------------------------------------------------------------------------------
Guidelines for writing/modifying CS APIs:

https://cwiki.apache.org/confluence/display/CLOUDSTACK/CloudStack+API+Coding+Guidelines
---------------------------------------------------------------------------------------

> -----Original Message-----
> From: muralireddy@apache.org [mailto:muralireddy@apache.org]
> Sent: 13 March 2014 1:53 PM
> To: commits@cloudstack.apache.org
> Subject: [20/31] git commit: updated refs/heads/distributedrouter to
> a8d43ba
> 
> CLOUDSTACK-6052: List VM enhancement to support querying with multiple
> VM IDs New parameter 'ids' added to listVirtualMachine API. The syntax
> looks like
> http://localhost:8096/api?command=listVirtualMachines&listAll=true&ids=e
> ddac053-9b12-4d2e-acb7-233de2e98112,009966fc-4d7b-4f84-8609-
> 254979ba0134
> The new parameter will be mutually exclusive with the existing 'id'
> parameter.
> 
> 
> Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
> Commit: http://git-wip-
> us.apache.org/repos/asf/cloudstack/commit/5779292e
> Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/5779292e
> Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/5779292e
> 
> Branch: refs/heads/distributedrouter
> Commit: 5779292e93fe52a7fb5ec0abffe1e3f6b9c10121
> Parents: bc4c805
> Author: Koushik Das <ko...@apache.org>
> Authored: Tue Mar 11 11:49:13 2014 +0530
> Committer: Koushik Das <ko...@apache.org>
> Committed: Thu Mar 13 17:05:35 2014 +0530
> 
> ----------------------------------------------------------------------
>  .../api/command/user/vm/ListVMsCmd.java         |  8 +++
>  .../com/cloud/api/query/QueryManagerImpl.java   | 20 ++++++--
>  test/integration/smoke/test_deploy_vm.py        | 52
> +++++++++++++++++++-
>  3 files changed, 76 insertions(+), 4 deletions(-)
> ----------------------------------------------------------------------
> 
> 
> http://git-wip-
> us.apache.org/repos/asf/cloudstack/blob/5779292e/api/src/org/apache/clo
> udstack/api/command/user/vm/ListVMsCmd.java
> ----------------------------------------------------------------------
> diff --git
> a/api/src/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java
> b/api/src/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java
> index 1a564f6..1ba2b23 100644
> ---
> a/api/src/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java
> +++
> b/api/src/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java
> @@ -64,6 +64,10 @@ public class ListVMsCmd extends
> BaseListTaggedResourcesCmd {
>      @Parameter(name = ApiConstants.ID, type = CommandType.UUID,
> entityType = UserVmResponse.class, description = "the ID of the virtual
> machine")
>      private Long id;
> 
> +    @Parameter(name=ApiConstants.IDS, type=CommandType.LIST,
> collectionType=CommandType.UUID, entityType=UserVmResponse.class,
> +               description="the IDs of the virtual machines, mutually exclusive with
> id")
> +    private List<Long> ids;
> +
>      @Parameter(name = ApiConstants.NAME, type = CommandType.STRING,
> description = "name of the virtual machine")
>      private String name;
> 
> @@ -135,6 +139,10 @@ public class ListVMsCmd extends
> BaseListTaggedResourcesCmd {
>          return id;
>      }
> 
> +    public List<Long> getIds() {
> +        return ids;
> +    }
> +
>      public String getName() {
>          return name;
>      }
> 
> http://git-wip-
> us.apache.org/repos/asf/cloudstack/blob/5779292e/server/src/com/cloud/a
> pi/query/QueryManagerImpl.java
> ----------------------------------------------------------------------
> diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java
> b/server/src/com/cloud/api/query/QueryManagerImpl.java
> index 4200799..47d2aec 100644
> --- a/server/src/com/cloud/api/query/QueryManagerImpl.java
> +++ b/server/src/com/cloud/api/query/QueryManagerImpl.java
> @@ -728,11 +728,22 @@ public class QueryManagerImpl extends
> ManagerBase implements QueryService {
>          Boolean isRecursive = domainIdRecursiveListProject.second();
>          ListProjectResourcesCriteria listProjectResourcesCriteria =
> domainIdRecursiveListProject.third();
> 
> +        List<Long> ids = null;
> +        if (cmd.getId() != null) {
> +            if (cmd.getIds() != null && !cmd.getIds().isEmpty()) {
> +                throw new InvalidParameterValueException("Specify either id or
> ids but not both parameters");
> +            }
> +            ids = new ArrayList<Long>();
> +            ids.add(cmd.getId());
> +        } else {
> +            ids = cmd.getIds();
> +        }
> +
>          Criteria c = new Criteria("id", Boolean.TRUE, cmd.getStartIndex(),
> cmd.getPageSizeVal());
>          // Criteria c = new Criteria(null, Boolean.FALSE, cmd.getStartIndex(),
>          // cmd.getPageSizeVal()); //version without default sorting
>          c.addCriteria(Criteria.KEYWORD, cmd.getKeyword());
> -        c.addCriteria(Criteria.ID, cmd.getId());
> +        c.addCriteria(Criteria.ID, ids);
>          c.addCriteria(Criteria.NAME, cmd.getName());
>          c.addCriteria(Criteria.STATE, cmd.getState());
>          c.addCriteria(Criteria.DATACENTERID, cmd.getZoneId()); @@ -805,7
> +816,7 @@ public class QueryManagerImpl extends ManagerBase
> implements QueryService {
>          Object display = c.getCriteria(Criteria.DISPLAY);
> 
>          sb.and("displayName", sb.entity().getDisplayName(),
> SearchCriteria.Op.LIKE);
> -        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
> +        sb.and("idIN", sb.entity().getId(), SearchCriteria.Op.IN);
>          sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE);
>          sb.and("stateEQ", sb.entity().getState(), SearchCriteria.Op.EQ);
>          sb.and("stateNEQ", sb.entity().getState(), SearchCriteria.Op.NEQ); @@
> -889,7 +900,10 @@ public class QueryManagerImpl extends ManagerBase
> implements QueryService {
>          }
> 
>          if (id != null) {
> -            sc.setParameters("id", id);
> +            List<?> idList = (id instanceof List<?> ? (List<?>)id : null);
> +            if (idList != null && !idList.isEmpty()) {
> +                sc.setParameters("idIN", idList.toArray());
> +            }
>          }
> 
>          if (templateId != null) {
> 
> http://git-wip-
> us.apache.org/repos/asf/cloudstack/blob/5779292e/test/integration/smoke
> /test_deploy_vm.py
> ----------------------------------------------------------------------
> diff --git a/test/integration/smoke/test_deploy_vm.py
> b/test/integration/smoke/test_deploy_vm.py
> index 425aeb7..fcde229 100644
> --- a/test/integration/smoke/test_deploy_vm.py
> +++ b/test/integration/smoke/test_deploy_vm.py
> @@ -51,6 +51,11 @@ class TestData(object):
>                  "name" : "testvm",
>                  "displayname" : "Test VM",
>              },
> +            #data reqd for virtual machine creation
> +            "virtual_machine2" : {
> +                "name" : "testvm2",
> +                "displayname" : "Test VM2",
> +            },
>              #small service offering
>              "service_offering": {
>                  "small": {
> @@ -149,8 +154,53 @@ class TestDeployVM(cloudstackTestCase):
>              msg="VM is not in Running state"
>          )
> 
> +    @attr(tags = ['advanced', 'simulator', 'basic', 'sg'])
> +    def test_deploy_vm_multiple(self):
> +        """Test Multiple Deploy Virtual Machine
> +
> +        # Validate the following:
> +        # 1. deploy 2 virtual machines
> +        # 2. listVirtualMachines using 'ids' parameter returns accurate
> information
> +        """
> +        self.virtual_machine = VirtualMachine.create(
> +            self.apiclient,
> +            self.testdata["virtual_machine"],
> +            accountid=self.account.name,
> +            zoneid=self.zone.id,
> +            domainid=self.account.domainid,
> +            serviceofferingid=self.service_offering.id,
> +            templateid=self.template.id
> +        )
> +
> +        self.virtual_machine2 = VirtualMachine.create(
> +            self.apiclient,
> +            self.testdata["virtual_machine2"],
> +            accountid=self.account.name,
> +            zoneid=self.zone.id,
> +            domainid=self.account.domainid,
> +            serviceofferingid=self.service_offering.id,
> +            templateid=self.template.id
> +        )
> +
> +        list_vms = VirtualMachine.list(self.apiclient,
> ids=[self.virtual_machine.id, self.virtual_machine2.id], listAll=True)
> +        self.debug(
> +            "Verify listVirtualMachines response for virtual machines: %s, %s" %
> (self.virtual_machine.id, self.virtual_machine2.id)
> +        )
> +
> +        self.assertEqual(
> +            isinstance(list_vms, list),
> +            True,
> +            "List VM response was not a valid list"
> +        )
> +        self.assertEqual(
> +            len(list_vms),
> +            2,
> +            "List VM response was empty, expected 2 VMs"
> +        )
> +
>      def tearDown(self):
>          try:
>              cleanup_resources(self.apiclient, self.cleanup)
>          except Exception as e:
> -            self.debug("Warning! Exception in tearDown: %s" % e)
> \ No newline at end of file
> +            self.debug("Warning! Exception in tearDown: %s" % e)
> +


[20/31] git commit: updated refs/heads/distributedrouter to a8d43ba

Posted by mu...@apache.org.
CLOUDSTACK-6052: List VM enhancement to support querying with multiple VM IDs
New parameter 'ids' added to listVirtualMachine API. The syntax looks like
http://localhost:8096/api?command=listVirtualMachines&listAll=true&ids=eddac053-9b12-4d2e-acb7-233de2e98112,009966fc-4d7b-4f84-8609-254979ba0134
The new parameter will be mutually exclusive with the existing 'id' parameter.


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

Branch: refs/heads/distributedrouter
Commit: 5779292e93fe52a7fb5ec0abffe1e3f6b9c10121
Parents: bc4c805
Author: Koushik Das <ko...@apache.org>
Authored: Tue Mar 11 11:49:13 2014 +0530
Committer: Koushik Das <ko...@apache.org>
Committed: Thu Mar 13 17:05:35 2014 +0530

----------------------------------------------------------------------
 .../api/command/user/vm/ListVMsCmd.java         |  8 +++
 .../com/cloud/api/query/QueryManagerImpl.java   | 20 ++++++--
 test/integration/smoke/test_deploy_vm.py        | 52 +++++++++++++++++++-
 3 files changed, 76 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5779292e/api/src/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java b/api/src/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java
index 1a564f6..1ba2b23 100644
--- a/api/src/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/vm/ListVMsCmd.java
@@ -64,6 +64,10 @@ public class ListVMsCmd extends BaseListTaggedResourcesCmd {
     @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = UserVmResponse.class, description = "the ID of the virtual machine")
     private Long id;
 
+    @Parameter(name=ApiConstants.IDS, type=CommandType.LIST, collectionType=CommandType.UUID, entityType=UserVmResponse.class,
+               description="the IDs of the virtual machines, mutually exclusive with id")
+    private List<Long> ids;
+
     @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "name of the virtual machine")
     private String name;
 
@@ -135,6 +139,10 @@ public class ListVMsCmd extends BaseListTaggedResourcesCmd {
         return id;
     }
 
+    public List<Long> getIds() {
+        return ids;
+    }
+
     public String getName() {
         return name;
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5779292e/server/src/com/cloud/api/query/QueryManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/query/QueryManagerImpl.java b/server/src/com/cloud/api/query/QueryManagerImpl.java
index 4200799..47d2aec 100644
--- a/server/src/com/cloud/api/query/QueryManagerImpl.java
+++ b/server/src/com/cloud/api/query/QueryManagerImpl.java
@@ -728,11 +728,22 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
         Boolean isRecursive = domainIdRecursiveListProject.second();
         ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
 
+        List<Long> ids = null;
+        if (cmd.getId() != null) {
+            if (cmd.getIds() != null && !cmd.getIds().isEmpty()) {
+                throw new InvalidParameterValueException("Specify either id or ids but not both parameters");
+            }
+            ids = new ArrayList<Long>();
+            ids.add(cmd.getId());
+        } else {
+            ids = cmd.getIds();
+        }
+
         Criteria c = new Criteria("id", Boolean.TRUE, cmd.getStartIndex(), cmd.getPageSizeVal());
         // Criteria c = new Criteria(null, Boolean.FALSE, cmd.getStartIndex(),
         // cmd.getPageSizeVal()); //version without default sorting
         c.addCriteria(Criteria.KEYWORD, cmd.getKeyword());
-        c.addCriteria(Criteria.ID, cmd.getId());
+        c.addCriteria(Criteria.ID, ids);
         c.addCriteria(Criteria.NAME, cmd.getName());
         c.addCriteria(Criteria.STATE, cmd.getState());
         c.addCriteria(Criteria.DATACENTERID, cmd.getZoneId());
@@ -805,7 +816,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
         Object display = c.getCriteria(Criteria.DISPLAY);
 
         sb.and("displayName", sb.entity().getDisplayName(), SearchCriteria.Op.LIKE);
-        sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
+        sb.and("idIN", sb.entity().getId(), SearchCriteria.Op.IN);
         sb.and("name", sb.entity().getName(), SearchCriteria.Op.LIKE);
         sb.and("stateEQ", sb.entity().getState(), SearchCriteria.Op.EQ);
         sb.and("stateNEQ", sb.entity().getState(), SearchCriteria.Op.NEQ);
@@ -889,7 +900,10 @@ public class QueryManagerImpl extends ManagerBase implements QueryService {
         }
 
         if (id != null) {
-            sc.setParameters("id", id);
+            List<?> idList = (id instanceof List<?> ? (List<?>)id : null);
+            if (idList != null && !idList.isEmpty()) {
+                sc.setParameters("idIN", idList.toArray());
+            }
         }
 
         if (templateId != null) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/5779292e/test/integration/smoke/test_deploy_vm.py
----------------------------------------------------------------------
diff --git a/test/integration/smoke/test_deploy_vm.py b/test/integration/smoke/test_deploy_vm.py
index 425aeb7..fcde229 100644
--- a/test/integration/smoke/test_deploy_vm.py
+++ b/test/integration/smoke/test_deploy_vm.py
@@ -51,6 +51,11 @@ class TestData(object):
                 "name" : "testvm",
                 "displayname" : "Test VM",
             },
+            #data reqd for virtual machine creation
+            "virtual_machine2" : {
+                "name" : "testvm2",
+                "displayname" : "Test VM2",
+            },
             #small service offering
             "service_offering": {
                 "small": {
@@ -149,8 +154,53 @@ class TestDeployVM(cloudstackTestCase):
             msg="VM is not in Running state"
         )
 
+    @attr(tags = ['advanced', 'simulator', 'basic', 'sg'])
+    def test_deploy_vm_multiple(self):
+        """Test Multiple Deploy Virtual Machine
+
+        # Validate the following:
+        # 1. deploy 2 virtual machines 
+        # 2. listVirtualMachines using 'ids' parameter returns accurate information
+        """
+        self.virtual_machine = VirtualMachine.create(
+            self.apiclient,
+            self.testdata["virtual_machine"],
+            accountid=self.account.name,
+            zoneid=self.zone.id,
+            domainid=self.account.domainid,
+            serviceofferingid=self.service_offering.id,
+            templateid=self.template.id
+        )
+
+        self.virtual_machine2 = VirtualMachine.create(
+            self.apiclient,
+            self.testdata["virtual_machine2"],
+            accountid=self.account.name,
+            zoneid=self.zone.id,
+            domainid=self.account.domainid,
+            serviceofferingid=self.service_offering.id,
+            templateid=self.template.id
+        )
+
+        list_vms = VirtualMachine.list(self.apiclient, ids=[self.virtual_machine.id, self.virtual_machine2.id], listAll=True)
+        self.debug(
+            "Verify listVirtualMachines response for virtual machines: %s, %s" % (self.virtual_machine.id, self.virtual_machine2.id)
+        )
+
+        self.assertEqual(
+            isinstance(list_vms, list),
+            True,
+            "List VM response was not a valid list"
+        )
+        self.assertEqual(
+            len(list_vms),
+            2,
+            "List VM response was empty, expected 2 VMs"
+        )
+
     def tearDown(self):
         try:
             cleanup_resources(self.apiclient, self.cleanup)
         except Exception as e:
-            self.debug("Warning! Exception in tearDown: %s" % e)
\ No newline at end of file
+            self.debug("Warning! Exception in tearDown: %s" % e)
+


[24/31] git commit: updated refs/heads/distributedrouter to a8d43ba

Posted by mu...@apache.org.
Scripts that use ovs-vsctl and ovs-ofctl to setup a bridge for VPC in
distributed routing mode, and setup flows appropriatley

script to handle the VPC topology sent from management server in JSOn
format. From the JSON file, reqired configuration (tunnel setup and flow
rules setup) is setup on the bridge


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

Branch: refs/heads/distributedrouter
Commit: 136796e52b3109f8948ecf8cc1868be5ca35cca1
Parents: cb37d77
Author: Murali Reddy <mu...@gmail.com>
Authored: Mon Mar 10 11:58:37 2014 +0530
Committer: Murali Reddy <mu...@gmail.com>
Committed: Thu Mar 13 19:22:08 2014 +0530

----------------------------------------------------------------------
 .../xenserver/cloudstack_pluginlib.py           | 154 +++++++++++++++++++
 .../vm/hypervisor/xenserver/ovs-vif-flows.py    | 128 +++++++++++----
 scripts/vm/hypervisor/xenserver/ovstunnel       | 114 +++++++++++++-
 3 files changed, 362 insertions(+), 34 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/136796e5/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py b/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py
index 422111f..d2b95dc 100644
--- a/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py
+++ b/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py
@@ -21,6 +21,7 @@ import ConfigParser
 import logging
 import os
 import subprocess
+import json
 
 from time import localtime, asctime
 
@@ -176,6 +177,7 @@ def _build_flow_expr(**kwargs):
     dl_dst = 'dl_dst' in kwargs and ",dl_dst=%s" % kwargs['dl_dst'] or ''
     nw_src = 'nw_src' in kwargs and ",nw_src=%s" % kwargs['nw_src'] or ''
     nw_dst = 'nw_dst' in kwargs and ",nw_dst=%s" % kwargs['nw_dst'] or ''
+    table = 'table' in kwargs and ",table=%s" % kwargs['table'] or ''
     proto = 'proto' in kwargs and ",%s" % kwargs['proto'] or ''
     ip = ('nw_src' in kwargs or 'nw_dst' in kwargs) and ',ip' or ''
     flow = (flow + in_port + dl_type + dl_src + dl_dst +
@@ -219,3 +221,155 @@ def del_all_flows(bridge):
 def del_port(bridge, port):
     delPort = [VSCTL_PATH, "del-port", bridge, port]
     do_cmd(delPort)
+
+def get_network_id_for_vif(vif_name):
+    domain_id, device_id = vif_name[3:len(vif_name)].split(".")
+    dom_uuid = do_cmd([XE_PATH, "vm-list", "dom-id=%s" % domain_id, "--minimal"])
+    vif_uuid = do_cmd([XE_PATH, "vif-list", "vm-uuid=%s" % dom_uuid, "device=%s" % device_id, "--minimal"])
+    vnet = do_cmd([XE_PATH, "vif-param-get", "uuid=%s" % vif_uuid,  "param-name=other-config",
+                             "param-key=cloudstack-network-id"])
+    return vnet
+
+def get_network_id_for_tunnel_port(tunnelif_name):
+    vnet = do_cmd([VSCTL_PATH, "get", "interface", tunnelif_name, "options:cloudstack-network-id"])
+    return vnet
+
+def clear_flooding_rules_for_port(bridge, ofport):
+        del_flows(bridge, in_port=ofport, table=2)
+
+def add_flooding_rules_for_port(bridge, in_ofport, out_ofports):
+        action = "".join("output:%s," %ofport for ofport in out_ofports)[:-1]
+        add_flow(bridge, priority=1100, in_port=in_ofport, table=1, actions=action)
+
+def get_ofport_for_vif(vif_name):
+    return do_cmd([VSCTL_PATH, "get", "interface", vif_name, "ofport"])
+
+def get_macaddress_of_vif(vif_name):
+    domain_id, device_id = vif_name[3:len(vif_name)].split(".")
+    dom_uuid = do_cmd([XE_PATH, "vm-list", "dom-id=%s" % domain_id, "--minimal"])
+    vif_uuid = do_cmd([XE_PATH, "vif-list", "vm-uuid=%s" % dom_uuid, "device=%s" % device_id, "--minimal"])
+    mac = do_cmd([XE_PATH, "vif-param-get", "uuid=%s" % vif_uuid,  "param-name=MAC"])
+    return mac
+
+def get_vif_name_from_macaddress(macaddress):
+    vif_uuid = do_cmd([XE_PATH, "vif-list", "MAC=%s" % macaddress, "--minimal"])
+    vif_device_id = do_cmd([XE_PATH, "vif-param-get", "uuid=%s" % vif_uuid,  "param-name=device"])
+    vm_uuid = do_cmd([XE_PATH, "vif-param-get", "uuid=%s" % vif_uuid,  "param-name=vm-uuid"])
+    vm_domain_id = do_cmd([XE_PATH, "vm-param-get", "uuid=%s" % vm_uuid,  "param-name=dom-id"])
+    return "vif"+vm_domain_id+"."+vif_device_id
+
+def add_mac_lookup_table_entry(bridge, mac_address, out_of_port):
+    add_flow(bridge, priority=1100, dl_dst=mac_address, table=1, actions="output:%s" % out_of_port)
+
+def delete_mac_lookup_table_entry(bridge, mac_address):
+    del_flows(bridge, dl_dst=mac_address, table=1)
+
+def add_ip_lookup_table_entry(bridge, ip, dst_tier_gateway_mac, dst_vm_mac):
+    action_str = "mod_dl_sr:%s" % dst_tier_gateway_mac + ",mod_dl_dst:%s" % dst_vm_mac +",resubmit(,5)"
+    addflow = [OFCTL_PATH, "add-flow", bridge, "table=4", "nw_dst=%s" % ip, "actions=%s" %action_str]
+    do_cmd(addflow)
+
+def get_vms_on_host(vpc, host_id):
+    all_vms = vpc.vms
+    vms_on_host = []
+    for vm in all_vms:
+      if vm.hostid == host_id:
+        vms_on_host.append(vm)
+    return vms_on_host
+
+def get_network_details(vpc, network_uuid):
+    tiers = vpc.tiers
+    for tier in tiers:
+      if tier.networkuuid == network_uuid:
+        return tier
+    return None
+
+class jsonLoader(object):
+  def __init__(self, obj):
+        for k in obj:
+            v = obj[k]
+            if isinstance(v, dict):
+                setattr(self, k, jsonLoader(v))
+            elif isinstance(v, (list, tuple)):
+                if len(v) > 0 and isinstance(v[0], dict):
+                    setattr(self, k, [jsonLoader(elem) for elem in v])
+                else:
+                    setattr(self, k, v)
+            else:
+                setattr(self, k, v)
+
+  def __getattr__(self, val):
+        if val in self.__dict__:
+            return self.__dict__[val]
+        else:
+            return None
+
+  def __repr__(self):
+        return '{%s}' % str(', '.join('%s : %s' % (k, repr(v)) for (k, v)
+                                      in self.__dict__.iteritems()))
+
+  def __str__(self):
+        return '{%s}' % str(', '.join('%s : %s' % (k, repr(v)) for (k, v)
+                                      in self.__dict__.iteritems()))
+
+def configure_bridge_for_topology(bridge, this_host_id, json_config):
+    vpconfig = jsonLoader(json.loads(json_config)).vpc
+
+    if vpconfig is None:
+        logging.debug("WARNING:Can't find VPC info in json config file")
+        return "FAILURE:IMPROPER_JSON_CONFG_FILE"
+
+    # get the list of Vm's in the VPC from the JSON config
+    this_host_vms = get_vms_on_host(vpconfig, this_host_id)
+
+    for vm in this_host_vms:
+        for nic in vm.nics:
+            mac_addr = nic.macaddress
+            ip = nic.ipaddress
+            vif_name = get_vif_name_from_macaddress(mac_addr)
+            of_port = get_ofport_for_vif(vif_name)
+            network = get_network_details(vpconfig, nic.networkuuid)
+
+            # Add flow rule in L2 look up table, if the destination mac = MAC of the nic send packet on the found OFPORT
+            add_mac_lookup_table_entry(bridge, mac_addr, of_port)
+
+            # Add flow rule in L3 look up table: if the destination IP = VM's IP then modify the packet
+            # to set DST MAC = VM's MAC, SRC MAC=tier gateway MAC and send to egress table
+            add_ip_lookup_table_entry(bridge, ip, network.gatewaymac, mac_addr)
+
+            # Add flow entry to send with intra tier traffic from the NIC to L2 lookup path)
+            addflow = [OFCTL_PATH, "add-flow", bridge, "table=0", "in_port=%s" % of_port,
+                       "nw_dst=%s" %network.cidr, "actions=resubmit(,1)"]
+            do_cmd(addflow)
+
+            #add flow entry to send inter-tier traffic from the NIC to egress ACL table(to L3 lookup path)
+            addflow = [OFCTL_PATH, "add-flow", bridge, "table=0", "in_port=%s" % of_port,
+                       "dl_dst=%s" %network.gatewaymac, "nw_dst=%s" %vpconfig.cidr, "actions=resubmit(,3)"]
+            do_cmd(addflow)
+
+    # get the list of hosts on which VPC spans from the JSON config
+    vpc_spanning_hosts = vpconfig.hosts
+
+    for host in vpc_spanning_hosts:
+        if this_host_id == host.hostid:
+            continue
+        other_host_vms = get_vms_on_host(vpconfig, host.hostid)
+        for vm in other_host_vms:
+            for nic in vm.nics:
+                mac_addr = nic.macaddress
+                ip = nic.ipaddress
+                network = get_network_details(vpconfig, nic.networkuuid)
+                gre_key = network.grekey
+
+                # generate tunnel name from tunnel naming convention
+                tunnel_name = "t%s-%s-%s" % (gre_key, this_host_id, host.hostid)
+                of_port = get_ofport_for_vif(tunnel_name)
+
+                # Add flow rule in L2 look up table, if the destination mac = MAC of the nic send packet tunnel port
+                add_mac_lookup_table_entry(bridge, mac_addr, of_port)
+
+                # Add flow tule in L3 look up table: if the destination IP = VM's IP then modify the packet
+                # set DST MAC = VM's MAC, SRC MAC=tier gateway MAC and send to egress table
+                add_ip_lookup_table_entry(bridge, ip, network.gatewaymac, mac_addr)
+
+    return "SUCCESS: successfully configured bridge as per the VPC toplogy"
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/136796e5/scripts/vm/hypervisor/xenserver/ovs-vif-flows.py
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/xenserver/ovs-vif-flows.py b/scripts/vm/hypervisor/xenserver/ovs-vif-flows.py
index 8452dae..ae37525 100644
--- a/scripts/vm/hypervisor/xenserver/ovs-vif-flows.py
+++ b/scripts/vm/hypervisor/xenserver/ovs-vif-flows.py
@@ -18,6 +18,7 @@
 # A simple script for enabling and disabling per-vif rules for explicitly
 # allowing broadcast/multicast traffic on the port where the VIF is attached
 
+import copy
 import os
 import sys
 
@@ -65,7 +66,6 @@ def clear_rules(vif):
     except:
         pass
 
-
 def main(command, vif_raw):
     if command not in ('online', 'offline'):
         return
@@ -86,38 +86,110 @@ def main(command, vif_raw):
 	# find xs network for this bridge, verify is used for ovs tunnel network
     xs_nw_uuid = pluginlib.do_cmd([pluginlib.XE_PATH, "network-list",
 								   "bridge=%s" % bridge, "--minimal"])
-    result = pluginlib.do_cmd([pluginlib.XE_PATH,"network-param-get",
+    ovs_tunnel_network = pluginlib.do_cmd([pluginlib.XE_PATH,"network-param-get",
 						       "uuid=%s" % xs_nw_uuid,
 						       "param-name=other-config",
 						       "param-key=is-ovs-tun-network", "--minimal"])
 
-    if result != 'True':
-		return
-    
-    vlan = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'br-to-vlan', bridge])
-    if vlan != '0':
-            # We need the REAL bridge name
-            bridge = pluginlib.do_cmd([pluginlib.VSCTL_PATH,
-                                       'br-to-parent', bridge])
-
-    vsctl_output = pluginlib.do_cmd([pluginlib.VSCTL_PATH,
-                                     'list-ports', bridge])
-    vifs = vsctl_output.split('\n')
-    vif_ofports = []
-    for vif in vifs:
-    	vif_ofport = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'get',
-                                       'Interface', vif, 'ofport'])
-    	if this_vif == vif:
-    		this_vif_ofport = vif_ofport
-        if vif.startswith('vif'): 
-            vif_ofports.append(vif_ofport)
-
-    if command == 'offline':
-        clear_flows(bridge,  this_vif_ofport, vif_ofports)
-
-    if command == 'online':
-        apply_flows(bridge,  this_vif_ofport, vif_ofports)
+    ovs_vpc_distributed_vr_network = pluginlib.do_cmd([pluginlib.XE_PATH,"network-param-get",
+						       "uuid=%s" % xs_nw_uuid,
+						       "param-name=other-config",
+						       "param-key=is-ovs_vpc_distributed_vr_network", "--minimal"])
+
+    if ovs_tunnel_network == 'True':
+        vlan = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'br-to-vlan', bridge])
+        if vlan != '0':
+                # We need the REAL bridge name
+                bridge = pluginlib.do_cmd([pluginlib.VSCTL_PATH,
+                                           'br-to-parent', bridge])
+        vsctl_output = pluginlib.do_cmd([pluginlib.VSCTL_PATH,
+                                         'list-ports', bridge])
+        vifs = vsctl_output.split('\n')
+        vif_ofports = []
+        for vif in vifs:
+            vif_ofport = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'get',
+                                           'Interface', vif, 'ofport'])
+            if this_vif == vif:
+                this_vif_ofport = vif_ofport
+            if vif.startswith('vif'):
+                vif_ofports.append(vif_ofport)
 
+        if command == 'offline':
+            clear_flows(bridge,  this_vif_ofport, vif_ofports)
+
+        if command == 'online':
+            apply_flows(bridge,  this_vif_ofport, vif_ofports)
+
+
+    if ovs_vpc_distributed_vr_network == 'True':
+        vlan = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'br-to-vlan', bridge])
+        if vlan != '0':
+                # We need the REAL bridge name
+                bridge = pluginlib.do_cmd([pluginlib.VSCTL_PATH,
+                                           'br-to-parent', bridge])
+        vsctl_output = pluginlib.do_cmd([pluginlib.VSCTL_PATH,
+                                         'list-ports', bridge])
+        vif_network_id = pluginlib.get_network_id_for_vif(this_vif)
+        vnet_vif_ofports = []
+        vnet_tunnelif_ofports = []
+        vnet_all_ofports = []
+
+        ports = vsctl_output.split('\n')
+        for port in ports:
+            if_ofport = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'get', 'Interface', vif, 'ofport'])
+            if vif.startswith('vif'):
+                # check VIF is in same network as that of plugged vif
+                if vif_network_id != pluginlib.get_network_id_for_vif(port):
+                    continue
+                vnet_vif_ofports.append(if_ofport)
+                vnet_all_ofports.append(if_ofport)
+
+            if vif.startswith('t'):
+                # check tunnel port is in same network as that of plugged vif
+                if vif_network_id != pluginlib.get_network_id_for_tunnel_port(port):
+                    continue
+                vnet_tunnelif_ofports.append(if_ofport)
+                vnet_all_ofports.append(if_ofport)
+
+        if command == 'online':
+            for port in vnet_all_ofports:
+                pluginlib.clear_flooding_rules_for_port(bridge, port)
+
+            # for a packet arrived from tunnel port, flood only on VIF ports
+            for port in vnet_tunnelif_ofports:
+                pluginlib.add_flooding_rules_for_port(bridge, port, vnet_vif_ofports)
+
+            # send on all VIF and tunnel port excluding the port on which packet arrived
+            for port in vnet_vif_ofports:
+                vnet_all_ofports_copy = copy.copy(vnet_all_ofports)
+                vnet_all_ofports_copy.remove(port)
+                pluginlib.add_flooding_rules_for_port(bridge, port, vnet_all_ofports_copy)
+
+            #learn that MAC is reachable through the VIF port
+            mac = pluginlib.get_macaddress_of_vif(this_vif)
+            pluginlib.add_mac_lookup_table_entry(bridge, mac, this_vif_ofport)
+
+        if command == 'offline':
+            for port in vnet_all_ofports:
+                pluginlib.clear_flooding_rules_for_port(bridge, port)
+            vnet_all_ofports.remove(this_vif_ofport)
+            vnet_vif_ofports.remove(this_vif_ofport)
+
+            # for a packet arrived from tunnel port, flood only on VIF ports
+            for port in vnet_tunnelif_ofports:
+                pluginlib.add_flooding_rules_for_port(bridge, port, vnet_vif_ofports)
+
+            # for a packet from VIF port send on all VIF's and tunnel ports excluding the port on which packet arrived
+            for port in vnet_vif_ofports:
+                vnet_all_ofports_copy = copy.copy(vnet_all_ofports)
+                vnet_all_ofports_copy.remove(port)
+                pluginlib.add_flooding_rules_for_port(bridge, port, vnet_all_ofports_copy)
+
+            #un-learn that MAC is reachable through the VIF port
+            mac = pluginlib.get_macaddress_of_vif(this_vif)
+            pluginlib.delete_mac_lookup_table_entry(bridge, mac)
+
+    return
 
 if __name__ == "__main__":
     if len(sys.argv) != 3:

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/136796e5/scripts/vm/hypervisor/xenserver/ovstunnel
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/xenserver/ovstunnel b/scripts/vm/hypervisor/xenserver/ovstunnel
index 106be04..d558e97 100755
--- a/scripts/vm/hypervisor/xenserver/ovstunnel
+++ b/scripts/vm/hypervisor/xenserver/ovstunnel
@@ -124,6 +124,75 @@ def setup_ovs_bridge(session, args):
     logging.debug("Setup_ovs_bridge completed with result:%s" % result)
     return result
 
+@echo
+def setup_ovs_bridge_for_distributed_routing(session, args):
+    bridge = args.pop("bridge")
+    key = args.pop("key")
+    xs_nw_uuid = args.pop("xs_nw_uuid")
+    cs_host_id = args.pop("cs_host_id")
+
+    res = lib.check_switch()
+    if res != "SUCCESS":
+        return "FAILURE:%s" % res
+
+    logging.debug("About to manually create the bridge:%s" % bridge)
+    # create a bridge with the same name as the xapi network
+    res = lib.do_cmd([lib.VSCTL_PATH, "--", "--may-exist", "add-br", bridge,
+                                     "--", "set", "bridge", bridge])
+    logging.debug("Bridge has been manually created:%s" % res)
+    # TODO: Make sure xs-network-uuid is set into external_ids
+    lib.do_cmd([lib.VSCTL_PATH, "set", "Bridge", bridge,
+                            "external_ids:xs-network-uuid=%s" % xs_nw_uuid])
+
+    # Non empty result means something went wrong
+    if res:
+        result = "FAILURE:%s" % res
+    else:
+        # Verify the bridge actually exists, with the gre_key properly set
+        res = lib.do_cmd([lib.VSCTL_PATH, "get", "bridge",
+                                          bridge, "other_config:gre_key"])
+        if key in res:
+            result = "SUCCESS:%s" % bridge
+        else:
+            result = "FAILURE:%s" % res
+        # Finally note in the xenapi network object that the network has
+        # been configured
+        xs_nw_uuid = lib.do_cmd([lib.XE_PATH, "network-list",
+                                "bridge=%s" % bridge, "--minimal"])
+        lib.do_cmd([lib.XE_PATH, "network-param-set", "uuid=%s" % xs_nw_uuid,
+                   "other-config:is-ovs_vpc_distributed_vr_network=True"])
+        conf_hosts = lib.do_cmd([lib.XE_PATH, "network-param-get",
+                                "uuid=%s" % xs_nw_uuid,
+                                "param-name=other-config",
+                                "param-key=ovs-host-setup", "--minimal"])
+        conf_hosts = cs_host_id + (conf_hosts and ',%s' % conf_hosts or '')
+        lib.do_cmd([lib.XE_PATH, "network-param-set", "uuid=%s" % xs_nw_uuid,
+                   "other-config:ovs-host-setup=%s" % conf_hosts])
+
+        # add a default flow rule to send broadcast and multi-cast packets to L2 flooding table
+        lib.add_flow(bridge, priority=1000, dl_dst='ff:ff:ff:ff:ff:ff', table=0, actions='resubmit(,2)')
+        lib.add_flow(bridge, priority=1000, nw_dst='224.0.0.0/24', table=0, actions='resubmit(,2)')
+
+        # add a default flow rule to send uni-cast traffic to L2 lookup table
+        lib.add_flow(bridge, priority=0, table=0, actions='resubmit(,1)')
+
+        # add a default rule to send unknown mac address to L2 flooding table
+        lib.add_flow(bridge, priority=0, table=1, actions='resubmit(,2)')
+
+        # add a default rule in L2 flood table to drop packet
+        lib.add_flow(bridge, priority=0, table=2, actions='drop')
+
+        # add a default rule in egress table to forward packet to L3 lookup table
+        lib.add_flow(bridge, priority=0, table=3, actions='resubmit(,4)')
+
+        # add a default rule in L3 lookup table to forward packet to L2 lookup table
+        lib.add_flow(bridge, priority=0, table=4, actions='resubmit(,1)')
+
+        # add a default rule in egress table to forward packet to L3 lookup table
+        lib.add_flow(bridge, priority=0, table=5, actions='drop')
+
+    logging.debug("Setup_ovs_bridge completed with result:%s" % result)
+    return result
 
 @echo
 def destroy_ovs_bridge(session, args):
@@ -220,13 +289,36 @@ def create_tunnel(session, args):
         # Ensure no trailing LF
         if tun_ofport.endswith('\n'):
             tun_ofport = tun_ofport[:-1]
-        # add flow entryies for dropping broadcast coming in from gre tunnel
-        lib.add_flow(bridge, priority=1000, in_port=tun_ofport,
+        # find xs network for this bridge, verify is used for ovs tunnel network
+        xs_nw_uuid = lib.do_cmd([lib.XE_PATH, "network-list",
+								   "bridge=%s" % bridge, "--minimal"])
+        ovs_tunnel_network = lib.do_cmd([lib.XE_PATH,"network-param-get",
+						       "uuid=%s" % xs_nw_uuid,
+						       "param-name=other-config",
+						       "param-key=is-ovs-tun-network", "--minimal"])
+        ovs_vpc_distributed_vr_network = lib.do_cmd([lib.XE_PATH,"network-param-get",
+                           "uuid=%s" % xs_nw_uuid,
+                           "param-name=other-config",
+                           "param-key=is-ovs_vpc_distributed_vr_network", "--minimal"])
+        if ovs_tunnel_network == 'True':
+            # add flow entryies for dropping broadcast coming in from gre tunnel
+            lib.add_flow(bridge, priority=1000, in_port=tun_ofport,
                          dl_dst='ff:ff:ff:ff:ff:ff', actions='drop')
-        lib.add_flow(bridge, priority=1000, in_port=tun_ofport,
+            lib.add_flow(bridge, priority=1000, in_port=tun_ofport,
                      nw_dst='224.0.0.0/24', actions='drop')
-        drop_flow_setup = True
-        logging.debug("Broadcast drop rules added")
+            drop_flow_setup = True
+            logging.debug("Broadcast drop rules added")
+
+        if ovs_vpc_distributed_vr_network == 'True':
+            # add flow rules for dropping broadcast coming in from tunnel ports
+            lib.add_flow(bridge, priority=1000, in_port=tun_ofport, table=0,
+                         dl_dst='ff:ff:ff:ff:ff:ff', actions='drop')
+            lib.add_flow(bridge, priority=1000, in_port=tun_ofport, table=0,
+                     nw_dst='224.0.0.0/24', actions='drop')
+
+            # add flow rule to send the traffic from tunnel ports to L2 switching table only
+            lib.add_flow(bridge, priority=1000, in_port=tun_ofport, table=0, actions='resubmit(,1)')
+
         return "SUCCESS:%s" % name
     except:
         logging.debug("An unexpected error occured. Rolling back")
@@ -293,10 +385,20 @@ def getLabel(session, args):
     	return label
     return False
 
+@echo
+def configure_ovs_bridge_for_network_topology(session, args):
+    bridge = args.pop("bridge")
+    json_config = args.pop("config")
+    this_host_id = args.pop("host-id")
+
+    return lib.configure_bridge_for_topology(bridge, this_host_id, json_config)
+
 if __name__ == "__main__":
     XenAPIPlugin.dispatch({"create_tunnel": create_tunnel,
                            "destroy_tunnel": destroy_tunnel,
                            "setup_ovs_bridge": setup_ovs_bridge,
                            "destroy_ovs_bridge": destroy_ovs_bridge,
                            "is_xcp": is_xcp,
-                           "getLabel": getLabel})
+                           "getLabel": getLabel,
+                           "setup_ovs_bridge_for_distributed_routing": setup_ovs_bridge_for_distributed_routing,
+                           "configure_ovs_bridge_for_network_topology": configure_ovs_bridge_for_network_topology})


[17/31] git commit: updated refs/heads/distributedrouter to a8d43ba

Posted by mu...@apache.org.
CLOUDSTACK-6236:Negative ref_cnt of template(snapshot/volume)_store_ref results in out-of-range error in Mysql


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

Branch: refs/heads/distributedrouter
Commit: cd8af6a3e2a180ea4d2cfea8a273dbb0929e0a87
Parents: 40192cd
Author: Min Chen <mi...@citrix.com>
Authored: Wed Mar 12 15:44:18 2014 -0700
Committer: Min Chen <mi...@citrix.com>
Committed: Wed Mar 12 16:17:53 2014 -0700

----------------------------------------------------------------------
 .../storage/datastore/db/SnapshotDataStoreVO.java        | 11 ++++++++++-
 .../storage/datastore/db/TemplateDataStoreVO.java        | 11 ++++++++++-
 .../storage/datastore/db/VolumeDataStoreVO.java          | 11 ++++++++++-
 3 files changed, 30 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/cd8af6a3/engine/schema/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java b/engine/schema/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java
index 8b68d6c..75b1d75 100644
--- a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java
+++ b/engine/schema/src/org/apache/cloudstack/storage/datastore/db/SnapshotDataStoreVO.java
@@ -29,6 +29,8 @@ import javax.persistence.Table;
 import javax.persistence.Temporal;
 import javax.persistence.TemporalType;
 
+import org.apache.log4j.Logger;
+
 import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
 import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
 import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State;
@@ -44,6 +46,8 @@ import com.cloud.utils.fsm.StateObject;
 @Entity
 @Table(name = "snapshot_store_ref")
 public class SnapshotDataStoreVO implements StateObject<ObjectInDataStoreStateMachine.State>, DataObjectInStore {
+    private static final Logger s_logger = Logger.getLogger(SnapshotDataStoreVO.class);
+
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     Long id;
@@ -272,7 +276,12 @@ public class SnapshotDataStoreVO implements StateObject<ObjectInDataStoreStateMa
     }
 
     public void decrRefCnt() {
-        refCnt--;
+        if (refCnt > 0) {
+            refCnt--;
+        }
+        else {
+            s_logger.warn("We should not try to decrement a zero reference count even though our code has guarded");
+        }
     }
 
     public Long getVolumeId() {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/cd8af6a3/engine/schema/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java b/engine/schema/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java
index 897fee0..bb40bf5 100755
--- a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java
+++ b/engine/schema/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreVO.java
@@ -29,6 +29,8 @@ import javax.persistence.Table;
 import javax.persistence.Temporal;
 import javax.persistence.TemporalType;
 
+import org.apache.log4j.Logger;
+
 import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
 import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
 import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State;
@@ -45,6 +47,8 @@ import com.cloud.utils.fsm.StateObject;
 @Entity
 @Table(name = "template_store_ref")
 public class TemplateDataStoreVO implements StateObject<ObjectInDataStoreStateMachine.State>, DataObjectInStore {
+    private static final Logger s_logger = Logger.getLogger(TemplateDataStoreVO.class);
+
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     Long id;
@@ -367,7 +371,12 @@ public class TemplateDataStoreVO implements StateObject<ObjectInDataStoreStateMa
     }
 
     public void decrRefCnt() {
-        refCnt--;
+        if (refCnt > 0) {
+            refCnt--;
+        }
+        else{
+            s_logger.warn("We should not try to decrement a zero reference count even though our code has guarded");
+        }
     }
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/cd8af6a3/engine/schema/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java b/engine/schema/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java
index fe6aca4..588eae8 100755
--- a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java
+++ b/engine/schema/src/org/apache/cloudstack/storage/datastore/db/VolumeDataStoreVO.java
@@ -29,6 +29,8 @@ import javax.persistence.Table;
 import javax.persistence.Temporal;
 import javax.persistence.TemporalType;
 
+import org.apache.log4j.Logger;
+
 import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
 import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
 import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.State;
@@ -44,6 +46,8 @@ import com.cloud.utils.fsm.StateObject;
 @Entity
 @Table(name = "volume_store_ref")
 public class VolumeDataStoreVO implements StateObject<ObjectInDataStoreStateMachine.State>, DataObjectInStore {
+    private static final Logger s_logger = Logger.getLogger(VolumeDataStoreVO.class);
+
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     Long id;
@@ -342,7 +346,12 @@ public class VolumeDataStoreVO implements StateObject<ObjectInDataStoreStateMach
     }
 
     public void setRefCnt(Long refCnt) {
-        this.refCnt = refCnt;
+        if (refCnt > 0) {
+            refCnt--;
+        }
+        else {
+            s_logger.warn("We should not try to decrement a zero reference count even though our code has guarded");
+        }
     }
 
     public void incrRefCnt() {


[31/31] git commit: updated refs/heads/distributedrouter to a8d43ba

Posted by mu...@apache.org.
couple of bug fixes


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

Branch: refs/heads/distributedrouter
Commit: a8d43ba4bbb6945412c6ee4c77d7c1f7d725101f
Parents: f70383b
Author: Murali Reddy <mu...@gmail.com>
Authored: Thu Mar 13 19:18:41 2014 +0530
Committer: Murali Reddy <mu...@gmail.com>
Committed: Thu Mar 13 19:22:10 2014 +0530

----------------------------------------------------------------------
 .../schema/src/com/cloud/network/vpc/VpcVO.java |   1 +
 .../xen/resource/CitrixResourceBase.java        |  12 +-
 .../network/ovs/OvsNetworkTopologyGuru.java     |   5 +
 .../network/ovs/OvsNetworkTopologyGuruImpl.java |  18 ++
 .../cloud/network/ovs/OvsTunnelManagerImpl.java | 251 ++++++++++++-------
 .../xenserver/cloudstack_pluginlib.py           |  26 +-
 .../vm/hypervisor/xenserver/ovs-vif-flows.py    |  27 +-
 7 files changed, 223 insertions(+), 117 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a8d43ba4/engine/schema/src/com/cloud/network/vpc/VpcVO.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/network/vpc/VpcVO.java b/engine/schema/src/com/cloud/network/vpc/VpcVO.java
index 5cf8aed..8beaeef 100644
--- a/engine/schema/src/com/cloud/network/vpc/VpcVO.java
+++ b/engine/schema/src/com/cloud/network/vpc/VpcVO.java
@@ -205,6 +205,7 @@ public class VpcVO implements Vpc {
     @Override
     public IAMEntityType getEntityType() {
         return IAMEntityType.Vpc;
+    }
 
     @Override
     public boolean usesDistributedRouter() {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a8d43ba4/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 d637443..32e5da7 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
@@ -5284,15 +5284,17 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
     public Answer execute(OvsVpcPhysicalTopologyConfigCommand cmd) {
         Connection conn = getConnection();
         try {
+            Network nw = findOrCreateTunnelNetwork(conn, cmd.getBridgeName());
+            String bridgeName = nw.getBridge(conn);;
             String result = callHostPlugin(conn, "ovstunnel", "configure_ovs_bridge_for_network_topology", "bridge",
-                    cmd.getBridgeName(), "config", cmd.getVpcConfigInJson());
-            if (result.equalsIgnoreCase("SUCCESS")) {
+                    bridgeName, "config", cmd.getVpcConfigInJson(), "host-id", ((Long)cmd.getHostId()).toString());
+                if (result.startsWith("SUCCESS")) {
                 return new Answer(cmd, true, result);
             } else {
                 return new Answer(cmd, false, result);
             }
         } catch  (Exception e) {
-            s_logger.warn("caught exception while updating host with latest routing polcies", e);
+            s_logger.warn("caught exception while updating host with latest VPC topology", e);
             return new Answer(cmd, false, e.getMessage());
         }
     }
@@ -5303,13 +5305,13 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
             String result = callHostPlugin(conn, "ovstunnel", "configure_ovs_bridge_for_routing_policies", "bridge",
                     cmd.getBridgeName(), "host-id", ((Long)cmd.getHostId()).toString(), "config",
                     cmd.getVpcConfigInJson());
-            if (result.equalsIgnoreCase("SUCCESS")) {
+            if (result.startsWith("SUCCESS")) {
                 return new Answer(cmd, true, result);
             } else {
                 return new Answer(cmd, false, result);
             }
         } catch  (Exception e) {
-            s_logger.warn("caught exception while updating host with latest VPC topology", e);
+            s_logger.warn("caught exception while updating host with latest routing policies", e);
             return new Answer(cmd, false, e.getMessage());
         }
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a8d43ba4/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuru.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuru.java b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuru.java
index 122175c..a9b62bf 100644
--- a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuru.java
+++ b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuru.java
@@ -56,4 +56,9 @@ public interface OvsNetworkTopologyGuru extends Manager {
      * get the list of all Vm id's in the network that are running on the host
      */
     public List<Long> getActiveVmsInNetworkOnHost(long vpcId, long hostId);
+
+    /**
+     * get the list of all Vpc id's in which, a VM has a nic in the network that is part of VPC
+     */
+    public List<Long> getVpcIdsVmIsPartOf(long vmId);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a8d43ba4/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuruImpl.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuruImpl.java b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuruImpl.java
index 7715641..740df80 100644
--- a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuruImpl.java
+++ b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsNetworkTopologyGuruImpl.java
@@ -187,4 +187,22 @@ public class OvsNetworkTopologyGuruImpl extends ManagerBase implements OvsNetwor
         }
         return  vmIds;
     }
+
+    @Override
+    public List<Long> getVpcIdsVmIsPartOf(long vmId) {
+        List<Long> vpcIds = new ArrayList<>();
+        List<NicVO> nics = _nicDao.listByVmId(vmId);
+        if (nics == null)
+            return null;
+
+        for (Nic nic: nics) {
+            Network network = _networkDao.findById(nic.getNetworkId());
+            if (network != null && network.getTrafficType() == Networks.TrafficType.Guest && network.getVpcId() != null) {
+                if (!vpcIds.contains(network.getVpcId())) {
+                    vpcIds.add(network.getVpcId());
+                }
+            }
+        }
+        return  vpcIds;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a8d43ba4/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
index eeb22b1..30088aa 100644
--- a/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
+++ b/plugins/network-elements/ovs/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
@@ -36,6 +36,7 @@ import com.cloud.network.vpc.dao.VpcDao;
 import com.cloud.network.vpc.VpcManager;
 import com.cloud.network.vpc.VpcVO;
 import com.cloud.network.vpc.dao.NetworkACLDao;
+import com.cloud.vm.VMInstanceVO;
 import com.cloud.vm.dao.VMInstanceDao;
 import com.cloud.vm.Nic;
 import com.cloud.vm.NicVO;
@@ -80,13 +81,14 @@ import com.cloud.network.ovs.dao.OvsTunnel;
 import com.cloud.utils.component.ManagerBase;
 import com.cloud.utils.concurrency.NamedThreadFactory;
 import com.cloud.utils.db.DB;
+import com.cloud.utils.fsm.StateListener;
 import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.vm.dao.DomainRouterDao;
 import com.cloud.vm.dao.NicDao;
 
 @Component
 @Local(value = {OvsTunnelManager.class})
-public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManager {
+public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManager, StateListener<VirtualMachine.State, VirtualMachine.Event, VirtualMachine> {
     public static final Logger s_logger = Logger.getLogger(OvsTunnelManagerImpl.class.getName());
 
     // boolean _isEnabled;
@@ -133,7 +135,12 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
         _executorPool = Executors.newScheduledThreadPool(10, new NamedThreadFactory("OVS"));
         _cleanupExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("OVS-Cleanup"));
 
+        // register for network ACL updated for a VPC.
         _messageBus.subscribe("Network_ACL_Replaced", new NetworkAclEventsSubscriber());
+
+        // register for VM state transition updates
+        VirtualMachine.State.getStateMachine().registerListener(this);
+
         return true;
     }
 
@@ -540,92 +547,6 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
         return "OVS-DR-VPC-Bridge" + vpcId;
     }
 
-    public boolean sendVpcTopologyChangeUpdate(OvsVpcPhysicalTopologyConfigCommand updateCmd, long hostId, String bridgeName) {
-        try {
-            s_logger.debug("Sending VPC topology update to the host " + hostId);
-            updateCmd.setHostId(hostId);
-            updateCmd.setBridgeName(bridgeName);
-            Answer ans = _agentMgr.send(hostId, updateCmd);
-            if (ans.getResult()) {
-                s_logger.debug("Successfully updated the host " + hostId + " with latest VPC topology." );
-                return true;
-            }  else {
-                s_logger.debug("Failed to update the host " + hostId + " with latest VPC topology." );
-                return false;
-            }
-        } catch (Exception e) {
-            s_logger.debug("Failed to updated the host " + hostId + " with latest VPC topology." );
-            return false;
-        }
-    }
-
-    OvsVpcPhysicalTopologyConfigCommand prepareVpcTopologyUpdate(long vpcId) {
-        VpcVO vpc = _vpcDao.findById(vpcId);
-        assert (vpc != null): "invalid vpc id";
-
-        List<? extends Network> vpcNetworks =  _vpcMgr.getVpcNetworks(vpcId);
-        List<Long> hostIds = _ovsNetworkToplogyGuru.getVpcSpannedHosts(vpcId);
-        List<Long> vmIds = _ovsNetworkToplogyGuru.getAllActiveVmsInVpc(vpcId);
-
-        List<OvsVpcPhysicalTopologyConfigCommand.Host> hosts = new ArrayList<>();
-        List<OvsVpcPhysicalTopologyConfigCommand.Tier> tiers = new ArrayList<>();
-        List<OvsVpcPhysicalTopologyConfigCommand.Vm> vms = new ArrayList<>();
-
-        for (Long hostId : hostIds) {
-            HostVO hostDetails = _hostDao.findById(hostId);
-            String remoteIp = null;
-            for (Network network: vpcNetworks) {
-                try {
-                    remoteIp = getGreEndpointIP(hostDetails, network);
-                } catch (Exception e) {
-
-                }
-            }
-            OvsVpcPhysicalTopologyConfigCommand.Host host = new OvsVpcPhysicalTopologyConfigCommand.Host(hostId, remoteIp);
-            hosts.add(host);
-        }
-
-        for (Network network: vpcNetworks) {
-            String key = network.getBroadcastUri().getAuthority();
-            long gre_key;
-            if (key.contains(".")) {
-                String[] parts = key.split("\\.");
-                gre_key = Long.parseLong(parts[1]);
-            } else {
-                try {
-                    gre_key = Long.parseLong(BroadcastDomainType.getValue(key));
-                } catch (Exception e) {
-                    return null;
-                }
-            }
-            NicVO nic = _nicDao.findByIp4AddressAndNetworkId(network.getGateway(), network.getId());
-            OvsVpcPhysicalTopologyConfigCommand.Tier tier = new OvsVpcPhysicalTopologyConfigCommand.Tier(gre_key,
-                    network.getUuid(), network.getGateway(), nic.getMacAddress(), network.getCidr());
-            tiers.add(tier);
-        }
-
-        for (long vmId: vmIds) {
-            VirtualMachine vmInstance = _vmInstanceDao.findById(vmId);
-            List<OvsVpcPhysicalTopologyConfigCommand.Nic>  vmNics = new ArrayList<OvsVpcPhysicalTopologyConfigCommand.Nic>();
-            for (Nic vmNic :_nicDao.listByVmId(vmId)) {
-                Network network = _networkDao.findById(vmNic.getNetworkId());
-                if (network.getTrafficType() == TrafficType.Guest) {
-                    OvsVpcPhysicalTopologyConfigCommand.Nic nic =  new OvsVpcPhysicalTopologyConfigCommand.Nic(
-                            vmNic.getIp4Address(), vmNic.getMacAddress(), ((Long)vmNic.getNetworkId()).toString());
-                    vmNics.add(nic);
-                }
-            }
-            OvsVpcPhysicalTopologyConfigCommand.Vm vm = new OvsVpcPhysicalTopologyConfigCommand.Vm(
-                    vmInstance.getHostId(), vmNics.toArray(new OvsVpcPhysicalTopologyConfigCommand.Nic[vmNics.size()]));
-            vms.add(vm);
-        }
-        return new OvsVpcPhysicalTopologyConfigCommand(
-                hosts.toArray(new OvsVpcPhysicalTopologyConfigCommand.Host[hosts.size()]),
-                tiers.toArray(new OvsVpcPhysicalTopologyConfigCommand.Tier[tiers.size()]),
-                vms.toArray(new OvsVpcPhysicalTopologyConfigCommand.Vm[vms.size()]),
-                vpc.getCidr());
-    }
-
     @DB
     protected void checkAndCreateVpcTunnelNetworks(Host host, long vpcId) {
 
@@ -731,16 +652,158 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
                 s_logger.warn("Ovs Tunnel network created tunnel failed", e);
             }
         }
+    }
+
+    @Override
+    public boolean preStateTransitionEvent(VirtualMachine.State oldState,
+                                           VirtualMachine.Event event, VirtualMachine.State newState,
+                                           VirtualMachine vo, boolean status, Object opaque) {
+        return true;
+    }
+
+    @Override
+    public boolean postStateTransitionEvent(VirtualMachine.State oldState, VirtualMachine.Event event,
+                                            VirtualMachine.State newState, VirtualMachine vm,
+                                            boolean status, Object opaque) {
+
+        if (!status) {
+            return false;
+        }
+
+        if (VirtualMachine.State.isVmStarted(oldState, event, newState)) {
+            if (s_logger.isTraceEnabled()) {
+                s_logger.trace("Security Group Mgr: handling start of vm id" + vm.getId());
+            }
+            handleVmStateChange((VMInstanceVO)vm);
+        } else if (VirtualMachine.State.isVmStopped(oldState, event, newState)) {
+            if (s_logger.isTraceEnabled()) {
+                s_logger.trace("Security Group Mgr: handling stop of vm id" + vm.getId());
+            }
+            handleVmStateChange((VMInstanceVO)vm);
+        } else if (VirtualMachine.State.isVmMigrated(oldState, event, newState)) {
+            if (s_logger.isTraceEnabled()) {
+                s_logger.trace("Security Group Mgr: handling migration of vm id" + vm.getId());
+            }
+            handleVmStateChange((VMInstanceVO)vm);
+        }
+
+        return true;
+    }
+
+    public void handleVmStateChange(VMInstanceVO vm) {
+
+        // get the VPC's impacted with the VM start
+        List<Long> vpcIds = _ovsNetworkToplogyGuru.getVpcIdsVmIsPartOf(vm.getId());
+        if (vpcIds == null || vpcIds.isEmpty()) {
+            return;
+        }
+
+        for (Long vpcId: vpcIds) {
+            VpcVO vpc = _vpcDao.findById(vpcId);
+            if (vpc == null || !vpc.usesDistributedRouter()) {
+                return;
+            }
+
+            // get the list of hosts on which VPC spans (i.e hosts that need to be aware of VPC topology change update)
+            List<Long> vpcSpannedHostIds = _ovsNetworkToplogyGuru.getVpcSpannedHosts(vpcId);
+            String bridgeName=generateBridgeNameForVpc(vpcId);
 
-        OvsVpcPhysicalTopologyConfigCommand topologyConfigCommand = prepareVpcTopologyUpdate(vpcId);
-        for (Long id: vpcSpannedHostIds) {
-            if (!sendVpcTopologyChangeUpdate(topologyConfigCommand, id, bridgeName)) {
-                s_logger.debug("Failed to send VPC topology change update to host : " + id + ". Moving on with rest of" +
-                        "the host update.");
+            OvsVpcPhysicalTopologyConfigCommand topologyConfigCommand = prepareVpcTopologyUpdate(vpcId);
+            for (Long id: vpcSpannedHostIds) {
+                if (!sendVpcTopologyChangeUpdate(topologyConfigCommand, id, bridgeName)) {
+                    s_logger.debug("Failed to send VPC topology change update to host : " + id + ". Moving on " +
+                            "with rest of the host update.");
+                }
+            }
+        }
+    }
+
+    public boolean sendVpcTopologyChangeUpdate(OvsVpcPhysicalTopologyConfigCommand updateCmd, long hostId, String bridgeName) {
+        try {
+            s_logger.debug("Sending VPC topology update to the host " + hostId);
+            updateCmd.setHostId(hostId);
+            updateCmd.setBridgeName(bridgeName);
+            Answer ans = _agentMgr.send(hostId, updateCmd);
+            if (ans.getResult()) {
+                s_logger.debug("Successfully updated the host " + hostId + " with latest VPC topology." );
+                return true;
+            }  else {
+                s_logger.debug("Failed to update the host " + hostId + " with latest VPC topology." );
+                return false;
             }
+        } catch (Exception e) {
+            s_logger.debug("Failed to updated the host " + hostId + " with latest VPC topology." );
+            return false;
         }
     }
 
+    OvsVpcPhysicalTopologyConfigCommand prepareVpcTopologyUpdate(long vpcId) {
+        VpcVO vpc = _vpcDao.findById(vpcId);
+        assert (vpc != null): "invalid vpc id";
+
+        List<? extends Network> vpcNetworks =  _vpcMgr.getVpcNetworks(vpcId);
+        List<Long> hostIds = _ovsNetworkToplogyGuru.getVpcSpannedHosts(vpcId);
+        List<Long> vmIds = _ovsNetworkToplogyGuru.getAllActiveVmsInVpc(vpcId);
+
+        List<OvsVpcPhysicalTopologyConfigCommand.Host> hosts = new ArrayList<>();
+        List<OvsVpcPhysicalTopologyConfigCommand.Tier> tiers = new ArrayList<>();
+        List<OvsVpcPhysicalTopologyConfigCommand.Vm> vms = new ArrayList<>();
+
+        for (Long hostId : hostIds) {
+            HostVO hostDetails = _hostDao.findById(hostId);
+            String remoteIp = null;
+            for (Network network: vpcNetworks) {
+                try {
+                    remoteIp = getGreEndpointIP(hostDetails, network);
+                } catch (Exception e) {
+
+                }
+            }
+            OvsVpcPhysicalTopologyConfigCommand.Host host = new OvsVpcPhysicalTopologyConfigCommand.Host(hostId, remoteIp);
+            hosts.add(host);
+        }
+
+        for (Network network: vpcNetworks) {
+            String key = network.getBroadcastUri().getAuthority();
+            long gre_key;
+            if (key.contains(".")) {
+                String[] parts = key.split("\\.");
+                gre_key = Long.parseLong(parts[1]);
+            } else {
+                try {
+                    gre_key = Long.parseLong(BroadcastDomainType.getValue(key));
+                } catch (Exception e) {
+                    return null;
+                }
+            }
+            NicVO nic = _nicDao.findByIp4AddressAndNetworkId(network.getGateway(), network.getId());
+            OvsVpcPhysicalTopologyConfigCommand.Tier tier = new OvsVpcPhysicalTopologyConfigCommand.Tier(gre_key,
+                    network.getUuid(), network.getGateway(), nic.getMacAddress(), network.getCidr());
+            tiers.add(tier);
+        }
+
+        for (long vmId: vmIds) {
+            VirtualMachine vmInstance = _vmInstanceDao.findById(vmId);
+            List<OvsVpcPhysicalTopologyConfigCommand.Nic>  vmNics = new ArrayList<OvsVpcPhysicalTopologyConfigCommand.Nic>();
+            for (Nic vmNic :_nicDao.listByVmId(vmId)) {
+                Network network = _networkDao.findById(vmNic.getNetworkId());
+                if (network.getTrafficType() == TrafficType.Guest) {
+                    OvsVpcPhysicalTopologyConfigCommand.Nic nic =  new OvsVpcPhysicalTopologyConfigCommand.Nic(
+                            vmNic.getIp4Address(), vmNic.getMacAddress(), network.getUuid());
+                    vmNics.add(nic);
+                }
+            }
+            OvsVpcPhysicalTopologyConfigCommand.Vm vm = new OvsVpcPhysicalTopologyConfigCommand.Vm(
+                    vmInstance.getHostId(), vmNics.toArray(new OvsVpcPhysicalTopologyConfigCommand.Nic[vmNics.size()]));
+            vms.add(vm);
+        }
+        return new OvsVpcPhysicalTopologyConfigCommand(
+                hosts.toArray(new OvsVpcPhysicalTopologyConfigCommand.Host[hosts.size()]),
+                tiers.toArray(new OvsVpcPhysicalTopologyConfigCommand.Tier[tiers.size()]),
+                vms.toArray(new OvsVpcPhysicalTopologyConfigCommand.Vm[vms.size()]),
+                vpc.getCidr());
+    }
+
     // Subscriber to ACL replace events. On acl replace event, if the vpc is enabled for distributed routing
     // send the ACL update to all the hosts on which VPC spans
     public class NetworkAclEventsSubscriber implements MessageSubscriber {
@@ -755,14 +818,14 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
                 for (Long id: vpcSpannedHostIds) {
                     if (!sendVpcRoutingPolicyChangeUpdate(cmd, id, bridgeName)) {
                         s_logger.debug("Failed to send VPC routing policy change update to host : " + id +
-                                ". Moving on with rest of the host updates.");
+                                ". But moving on with sending the host updates to the rest of the hosts.");
                     }
                 }
             }
         }
     }
 
-    OvsVpcRoutingPolicyConfigCommand prepareVpcRoutingPolicyUpdate(long vpcId) {
+    private OvsVpcRoutingPolicyConfigCommand prepareVpcRoutingPolicyUpdate(long vpcId) {
         VpcVO vpc = _vpcDao.findById(vpcId);
         assert (vpc != null): "invalid vpc id";
         List<OvsVpcRoutingPolicyConfigCommand.Acl> acls = new ArrayList<>();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a8d43ba4/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py b/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py
index ac8a11d..1c9d513 100644
--- a/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py
+++ b/scripts/vm/hypervisor/xenserver/cloudstack_pluginlib.py
@@ -239,7 +239,7 @@ def clear_flooding_rules_for_port(bridge, ofport):
 
 def add_flooding_rules_for_port(bridge, in_ofport, out_ofports):
         action = "".join("output:%s," %ofport for ofport in out_ofports)[:-1]
-        add_flow(bridge, priority=1100, in_port=in_ofport, table=1, actions=action)
+        add_flow(bridge, priority=1100, in_port=in_ofport, table=2, actions=action)
 
 def get_ofport_for_vif(vif_name):
     return do_cmd([VSCTL_PATH, "get", "interface", vif_name, "ofport"])
@@ -259,28 +259,30 @@ def get_vif_name_from_macaddress(macaddress):
     return "vif"+vm_domain_id+"."+vif_device_id
 
 def add_mac_lookup_table_entry(bridge, mac_address, out_of_port):
-    add_flow(bridge, priority=1100, dl_dst=mac_address, table=1, actions="output:%s" % out_of_port)
+    action = "output=%s" %out_of_port
+    add_flow(bridge, priority=1100, dl_dst=mac_address, table=1, actions=action)
 
 def delete_mac_lookup_table_entry(bridge, mac_address):
     del_flows(bridge, dl_dst=mac_address, table=1)
 
 def add_ip_lookup_table_entry(bridge, ip, dst_tier_gateway_mac, dst_vm_mac):
-    action_str = "mod_dl_sr:%s" % dst_tier_gateway_mac + ",mod_dl_dst:%s" % dst_vm_mac +",resubmit(,5)"
-    addflow = [OFCTL_PATH, "add-flow", bridge, "table=4", "nw_dst=%s" % ip, "actions=%s" %action_str]
+    action_str = "mod_dl_src:%s" % dst_tier_gateway_mac + ",mod_dl_dst:%s" % dst_vm_mac + ",resubmit(,5)"
+    action_str = "table=4, ip, nw_dst=%s" % ip + ",  actions=%s" %action_str
+    addflow = [OFCTL_PATH, "add-flow", bridge, action_str]
     do_cmd(addflow)
 
 def get_vms_on_host(vpc, host_id):
     all_vms = vpc.vms
     vms_on_host = []
     for vm in all_vms:
-      if vm.hostid == host_id:
+      if str(vm.hostid) == (host_id):
         vms_on_host.append(vm)
     return vms_on_host
 
 def get_network_details(vpc, network_uuid):
     tiers = vpc.tiers
     for tier in tiers:
-      if tier.networkuuid == network_uuid:
+      if str(tier.networkuuid) == (network_uuid):
         return tier
     return None
 
@@ -338,20 +340,22 @@ def configure_bridge_for_network_topology(bridge, this_host_id, json_config):
             add_ip_lookup_table_entry(bridge, ip, network.gatewaymac, mac_addr)
 
             # Add flow entry to send with intra tier traffic from the NIC to L2 lookup path)
-            addflow = [OFCTL_PATH, "add-flow", bridge, "table=0", "in_port=%s" % of_port,
-                       "nw_dst=%s" %network.cidr, "actions=resubmit(,1)"]
+            action_str = "table=0, in_port=%s," %of_port + " ip, nw_dst=%s," %network.cidr + " actions=resubmit(,1)"
+            addflow = [OFCTL_PATH, "add-flow", bridge, action_str]
             do_cmd(addflow)
 
             #add flow entry to send inter-tier traffic from the NIC to egress ACL table(to L3 lookup path)
-            addflow = [OFCTL_PATH, "add-flow", bridge, "table=0", "in_port=%s" % of_port,
-                       "dl_dst=%s" %network.gatewaymac, "nw_dst=%s" %vpconfig.cidr, "actions=resubmit(,3)"]
+            action_str = "table=0, in_port=%s," % of_port + " ip, dl_dst=%s," %network.gatewaymac +\
+                         "nw_dst=%s," %vpconfig.cidr + "actions=resubmit(,3)"
+            addflow = [OFCTL_PATH, "add-flow", bridge, action_str]
+
             do_cmd(addflow)
 
     # get the list of hosts on which VPC spans from the JSON config
     vpc_spanning_hosts = vpconfig.hosts
 
     for host in vpc_spanning_hosts:
-        if this_host_id == host.hostid:
+        if str(this_host_id) == str(host.hostid):
             continue
         other_host_vms = get_vms_on_host(vpconfig, host.hostid)
         for vm in other_host_vms:

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a8d43ba4/scripts/vm/hypervisor/xenserver/ovs-vif-flows.py
----------------------------------------------------------------------
diff --git a/scripts/vm/hypervisor/xenserver/ovs-vif-flows.py b/scripts/vm/hypervisor/xenserver/ovs-vif-flows.py
index ae37525..1445d94 100644
--- a/scripts/vm/hypervisor/xenserver/ovs-vif-flows.py
+++ b/scripts/vm/hypervisor/xenserver/ovs-vif-flows.py
@@ -21,9 +21,11 @@
 import copy
 import os
 import sys
+import logging
 
 import cloudstack_pluginlib as pluginlib
 
+pluginlib.setup_logging("/var/log/cloud/ovstunnel.log")
 
 def clear_flows(bridge, this_vif_ofport, vif_ofports):
     # Remove flow entries originating from given ofport
@@ -83,18 +85,26 @@ def main(command, vif_raw):
 
     bridge = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'iface-to-br', this_vif])
     
-	# find xs network for this bridge, verify is used for ovs tunnel network
+    # find xs network for this bridge, verify is used for ovs tunnel network
     xs_nw_uuid = pluginlib.do_cmd([pluginlib.XE_PATH, "network-list",
 								   "bridge=%s" % bridge, "--minimal"])
-    ovs_tunnel_network = pluginlib.do_cmd([pluginlib.XE_PATH,"network-param-get",
+    ovs_tunnel_network = False
+    try:
+        ovs_tunnel_network = pluginlib.do_cmd([pluginlib.XE_PATH,"network-param-get",
 						       "uuid=%s" % xs_nw_uuid,
 						       "param-name=other-config",
 						       "param-key=is-ovs-tun-network", "--minimal"])
+    except:
+        pass
 
-    ovs_vpc_distributed_vr_network = pluginlib.do_cmd([pluginlib.XE_PATH,"network-param-get",
+    ovs_vpc_distributed_vr_network = False
+    try:
+        ovs_vpc_distributed_vr_network = pluginlib.do_cmd([pluginlib.XE_PATH,"network-param-get",
 						       "uuid=%s" % xs_nw_uuid,
 						       "param-name=other-config",
 						       "param-key=is-ovs_vpc_distributed_vr_network", "--minimal"])
+    except:
+        pass
 
     if ovs_tunnel_network == 'True':
         vlan = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'br-to-vlan', bridge])
@@ -121,6 +131,7 @@ def main(command, vif_raw):
             apply_flows(bridge,  this_vif_ofport, vif_ofports)
 
 
+    # handle case where brdige is setup for VPC and VPC is enabled for distributed routing
     if ovs_vpc_distributed_vr_network == 'True':
         vlan = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'br-to-vlan', bridge])
         if vlan != '0':
@@ -136,15 +147,15 @@ def main(command, vif_raw):
 
         ports = vsctl_output.split('\n')
         for port in ports:
-            if_ofport = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'get', 'Interface', vif, 'ofport'])
-            if vif.startswith('vif'):
+            if_ofport = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'get', 'Interface', port, 'ofport'])
+            if port.startswith('vif'):
                 # check VIF is in same network as that of plugged vif
                 if vif_network_id != pluginlib.get_network_id_for_vif(port):
                     continue
                 vnet_vif_ofports.append(if_ofport)
                 vnet_all_ofports.append(if_ofport)
 
-            if vif.startswith('t'):
+            if port.startswith('t'):
                 # check tunnel port is in same network as that of plugged vif
                 if vif_network_id != pluginlib.get_network_id_for_tunnel_port(port):
                     continue
@@ -159,7 +170,8 @@ def main(command, vif_raw):
             for port in vnet_tunnelif_ofports:
                 pluginlib.add_flooding_rules_for_port(bridge, port, vnet_vif_ofports)
 
-            # send on all VIF and tunnel port excluding the port on which packet arrived
+            # for a packet arrived from VIF port send on all VIF and tunnel port excluding the port
+            # on which packet arrived
             for port in vnet_vif_ofports:
                 vnet_all_ofports_copy = copy.copy(vnet_all_ofports)
                 vnet_all_ofports_copy.remove(port)
@@ -167,6 +179,7 @@ def main(command, vif_raw):
 
             #learn that MAC is reachable through the VIF port
             mac = pluginlib.get_macaddress_of_vif(this_vif)
+            this_vif_ofport = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'get', 'Interface', this_vif, 'ofport'])
             pluginlib.add_mac_lookup_table_entry(bridge, mac, this_vif_ofport)
 
         if command == 'offline':


[10/31] git commit: updated refs/heads/distributedrouter to a8d43ba

Posted by mu...@apache.org.
CLOUDSTACK-5986: Fix dnsmasq lease for VPC


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

Branch: refs/heads/distributedrouter
Commit: 8937434fce6958155e9871caa1648504b7c34999
Parents: 4679863
Author: Sheng Yang <sh...@citrix.com>
Authored: Tue Mar 11 16:13:30 2014 -0700
Committer: Sheng Yang <sh...@citrix.com>
Committed: Tue Mar 11 16:14:33 2014 -0700

----------------------------------------------------------------------
 .../patches/debian/config/etc/init.d/cloud-early-config   | 10 ++++++++++
 1 file changed, 10 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8937434f/systemvm/patches/debian/config/etc/init.d/cloud-early-config
----------------------------------------------------------------------
diff --git a/systemvm/patches/debian/config/etc/init.d/cloud-early-config b/systemvm/patches/debian/config/etc/init.d/cloud-early-config
index c287d43..5751f09 100755
--- a/systemvm/patches/debian/config/etc/init.d/cloud-early-config
+++ b/systemvm/patches/debian/config/etc/init.d/cloud-early-config
@@ -1042,6 +1042,16 @@ EOF
   sed -r -i s/^[#]?domain=.*$/domain=$DOMAIN/ /etc/dnsmasq.conf
   #answer all local domain queries
   sed  -i -e "s/^[#]*local=.*$/local=\/$DOMAIN\//" /etc/dnsmasq.conf
+
+  command -v dhcp_release > /dev/null 2>&1
+  no_dhcp_release=$?
+  if [ $no_dhcp_release -eq 0 ]
+  then
+      echo 1 > /var/cache/cloud/dnsmasq_managed_lease
+      sed -i -e "/^leasefile-ro/d" /etc/dnsmasq.conf
+  else
+      echo 0 > /var/cache/cloud/dnsmasq_managed_lease
+  fi
 }
 
 


[14/31] git commit: updated refs/heads/distributedrouter to a8d43ba

Posted by mu...@apache.org.
check-style: tabs to spaces

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

Branch: refs/heads/distributedrouter
Commit: 6c035240ba4c28b8551a4a6aafe1f4a5b7709e13
Parents: 5685d14
Author: Daan Hoogland <dh...@schubergphilis.com>
Authored: Wed Mar 12 18:04:22 2014 +0100
Committer: Daan Hoogland <dh...@schubergphilis.com>
Committed: Wed Mar 12 18:04:22 2014 +0100

----------------------------------------------------------------------
 server/src/com/cloud/network/NetworkServiceImpl.java | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/6c035240/server/src/com/cloud/network/NetworkServiceImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java b/server/src/com/cloud/network/NetworkServiceImpl.java
index cc932ef..6671bed 100755
--- a/server/src/com/cloud/network/NetworkServiceImpl.java
+++ b/server/src/com/cloud/network/NetworkServiceImpl.java
@@ -1236,8 +1236,8 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
         // 1) GuestType is Shared
         boolean createVlan = (startIP != null && endIP != null && zone.getNetworkType() == NetworkType.Advanced
                 && ((ntwkOff.getGuestType() == Network.GuestType.Shared)
-                		|| (ntwkOff.getGuestType() == GuestType.Isolated &&
-                		!areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat))));
+                || (ntwkOff.getGuestType() == GuestType.Isolated &&
+                !areServicesSupportedByNetworkOffering(ntwkOff.getId(), Service.SourceNat))));
 
         if (!createVlan) {
             // Only support advance shared network in IPv6, which means createVlan is a must


[07/31] git commit: updated refs/heads/distributedrouter to a8d43ba

Posted by mu...@apache.org.
CLOUDSTACK-6047: Enable VR aggregation commands for VR start/reboot


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

Branch: refs/heads/distributedrouter
Commit: f45de30d1b94df8bb32f9aa724521209f1ae6eb0
Parents: b399c31
Author: Sheng Yang <sh...@citrix.com>
Authored: Thu Mar 6 19:29:20 2014 -0800
Committer: Sheng Yang <sh...@citrix.com>
Committed: Tue Mar 11 13:04:26 2014 -0700

----------------------------------------------------------------------
 .../element/AggregatedCommandExecutor.java      |  28 +++++
 .../api/routing/AggregationControlCommand.java  |  44 +++++++
 .../api/routing/FinishAggregationCommand.java   |  31 -----
 .../api/routing/StartAggregationCommand.java    |  31 -----
 .../virtualnetwork/VirtualRoutingResource.java  | 108 +++++++++--------
 .../VirtualRoutingResourceTest.java             |  29 ++---
 .../orchestration/NetworkOrchestrator.java      | 105 +++++++++-------
 .../network/element/VirtualRouterElement.java   |  71 +++++++----
 .../router/VirtualNetworkApplianceManager.java  |  16 ++-
 .../VirtualNetworkApplianceManagerImpl.java     | 119 ++++++++++++-------
 .../MockVpcVirtualNetworkApplianceManager.java  |  34 ++++--
 11 files changed, 367 insertions(+), 249 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f45de30d/api/src/com/cloud/network/element/AggregatedCommandExecutor.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/network/element/AggregatedCommandExecutor.java b/api/src/com/cloud/network/element/AggregatedCommandExecutor.java
new file mode 100644
index 0000000..012908f
--- /dev/null
+++ b/api/src/com/cloud/network/element/AggregatedCommandExecutor.java
@@ -0,0 +1,28 @@
+// 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 com.cloud.network.element;
+
+import com.cloud.deploy.DeployDestination;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.Network;
+
+public interface AggregatedCommandExecutor {
+    public boolean prepareAggregatedExecution(Network network, DeployDestination dest) throws ResourceUnavailableException;
+    public boolean completeAggregatedExecution(Network network, DeployDestination dest) throws ResourceUnavailableException;
+    public boolean cleanupAggregatedExecution(Network network, DeployDestination dest) throws ResourceUnavailableException;
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f45de30d/core/src/com/cloud/agent/api/routing/AggregationControlCommand.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/api/routing/AggregationControlCommand.java b/core/src/com/cloud/agent/api/routing/AggregationControlCommand.java
new file mode 100644
index 0000000..ef75360
--- /dev/null
+++ b/core/src/com/cloud/agent/api/routing/AggregationControlCommand.java
@@ -0,0 +1,44 @@
+// 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 com.cloud.agent.api.routing;
+
+public class AggregationControlCommand extends NetworkElementCommand{
+    public enum Action {
+        Start,
+        Finish,
+        Cleanup,
+    }
+
+    private Action action;
+
+    protected AggregationControlCommand() {
+        super();
+    }
+
+    public AggregationControlCommand(Action action, String name, String ip, String guestIp) {
+        super();
+        this.action = action;
+        this.setAccessDetail(NetworkElementCommand.ROUTER_NAME, name);
+        this.setAccessDetail(NetworkElementCommand.ROUTER_IP, ip);
+        this.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, guestIp);
+    }
+
+    public Action getAction() {
+        return action;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f45de30d/core/src/com/cloud/agent/api/routing/FinishAggregationCommand.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/api/routing/FinishAggregationCommand.java b/core/src/com/cloud/agent/api/routing/FinishAggregationCommand.java
deleted file mode 100644
index bfafccd..0000000
--- a/core/src/com/cloud/agent/api/routing/FinishAggregationCommand.java
+++ /dev/null
@@ -1,31 +0,0 @@
-// 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 com.cloud.agent.api.routing;
-
-public class FinishAggregationCommand extends NetworkElementCommand{
-    protected FinishAggregationCommand() {
-        super();
-    }
-
-    public FinishAggregationCommand(String name, String ip, String guestIp) {
-        super();
-        this.setAccessDetail(NetworkElementCommand.ROUTER_NAME, name);
-        this.setAccessDetail(NetworkElementCommand.ROUTER_IP, ip);
-        this.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, guestIp);
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f45de30d/core/src/com/cloud/agent/api/routing/StartAggregationCommand.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/api/routing/StartAggregationCommand.java b/core/src/com/cloud/agent/api/routing/StartAggregationCommand.java
deleted file mode 100644
index fbf97a8..0000000
--- a/core/src/com/cloud/agent/api/routing/StartAggregationCommand.java
+++ /dev/null
@@ -1,31 +0,0 @@
-// 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 com.cloud.agent.api.routing;
-
-public class StartAggregationCommand extends NetworkElementCommand{
-    protected StartAggregationCommand() {
-        super();
-    }
-
-    public StartAggregationCommand(String name, String ip, String guestIp) {
-        super();
-        this.setAccessDetail(NetworkElementCommand.ROUTER_NAME, name);
-        this.setAccessDetail(NetworkElementCommand.ROUTER_IP, ip);
-        this.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, guestIp);
-    }
-}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f45de30d/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
index 29a176a..3712aba 100755
--- a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
+++ b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
@@ -25,11 +25,12 @@ import com.cloud.agent.api.CheckS2SVpnConnectionsCommand;
 import com.cloud.agent.api.GetDomRVersionAnswer;
 import com.cloud.agent.api.GetDomRVersionCmd;
 import com.cloud.agent.api.SetupGuestNetworkCommand;
+import com.cloud.agent.api.routing.AggregationControlCommand;
+import com.cloud.agent.api.routing.AggregationControlCommand.Action;
 import com.cloud.agent.api.routing.CreateIpAliasCommand;
 import com.cloud.agent.api.routing.DeleteIpAliasCommand;
 import com.cloud.agent.api.routing.DhcpEntryCommand;
 import com.cloud.agent.api.routing.DnsMasqConfigCommand;
-import com.cloud.agent.api.routing.FinishAggregationCommand;
 import com.cloud.agent.api.routing.GroupAnswer;
 import com.cloud.agent.api.routing.IpAliasTO;
 import com.cloud.agent.api.routing.IpAssocCommand;
@@ -47,7 +48,6 @@ import com.cloud.agent.api.routing.SetSourceNatCommand;
 import com.cloud.agent.api.routing.SetStaticNatRulesCommand;
 import com.cloud.agent.api.routing.SetStaticRouteCommand;
 import com.cloud.agent.api.routing.Site2SiteVpnCfgCommand;
-import com.cloud.agent.api.routing.StartAggregationCommand;
 import com.cloud.agent.api.routing.VmDataCommand;
 import com.cloud.agent.api.routing.VpnUsersCfgCommand;
 import com.cloud.agent.api.to.DhcpTO;
@@ -163,10 +163,8 @@ public class VirtualRoutingResource {
                 return executeQueryCommand(cmd);
             }
 
-            if (cmd instanceof StartAggregationCommand) {
-                return execute((StartAggregationCommand)cmd);
-            } else if (cmd instanceof FinishAggregationCommand) {
-                return execute((FinishAggregationCommand)cmd);
+            if (cmd instanceof AggregationControlCommand) {
+                return execute((AggregationControlCommand)cmd);
             }
 
             if (_vrAggregateCommandsSet.containsKey(routerName)) {
@@ -1032,15 +1030,6 @@ public class VirtualRoutingResource {
         return false;
     }
 
-    private Answer execute(StartAggregationCommand cmd) {
-        // Access IP would be used as ID for router
-        String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
-        assert routerName != null;
-        Queue<NetworkElementCommand> queue = new LinkedBlockingQueue<>();
-        _vrAggregateCommandsSet.put(routerName, queue);
-        return new Answer(cmd);
-    }
-
     private List<ConfigItem> generateCommandCfg(NetworkElementCommand cmd) {
         List<ConfigItem> cfg;
         if (cmd instanceof SetPortForwardingRulesVpcCommand) {
@@ -1091,51 +1080,70 @@ public class VirtualRoutingResource {
         return cfg;
     }
 
-    private Answer execute(FinishAggregationCommand cmd) {
+    private Answer execute(AggregationControlCommand cmd) {
+        Action action = cmd.getAction();
         String routerName = cmd.getAccessDetail(NetworkElementCommand.ROUTER_NAME);
         assert routerName != null;
         assert cmd.getRouterAccessIp() != null;
-        Queue<NetworkElementCommand> queue = _vrAggregateCommandsSet.get(routerName);
-        try {
-            StringBuilder sb = new StringBuilder();
-            sb.append("#Apache CloudStack Virtual Router Config File\n");
-            sb.append("<version>\n" + _cfgVersion + "\n</version>\n");
-            for (NetworkElementCommand command : queue) {
-                List<ConfigItem> cfg = generateCommandCfg(command);
-                if (cfg == null) {
-                    s_logger.warn("Unknown commands for VirtualRoutingResource, but continue: " + cmd.toString());
-                    continue;
-                }
 
-                for (ConfigItem c : cfg) {
-                    if (c.isFile()) {
-                        sb.append("<file>\n");
-                        sb.append(c.getFilePath() + c.getFileName() + "\n");
-                        sb.append(c.getFileContents() + "\n");
-                        sb.append("</file>\n");
-                    } else {
-                        sb.append("<script>\n");
-                        sb.append("/opt/cloud/bin/" + c.getScript() + " " + c.getArgs() + "\n");
-                        sb.append("</script>\n");
+        if (action == Action.Start) {
+            assert (!_vrAggregateCommandsSet.containsKey(routerName));
+
+            Queue<NetworkElementCommand> queue = new LinkedBlockingQueue<>();
+            _vrAggregateCommandsSet.put(routerName, queue);
+            return new Answer(cmd);
+        } else if (action == Action.Finish) {
+            Queue<NetworkElementCommand> queue = _vrAggregateCommandsSet.get(routerName);
+            try {
+                StringBuilder sb = new StringBuilder();
+                sb.append("#Apache CloudStack Virtual Router Config File\n");
+                sb.append("<version>\n" + _cfgVersion + "\n</version>\n");
+                for (NetworkElementCommand command : queue) {
+                    List<ConfigItem> cfg = generateCommandCfg(command);
+                    if (cfg == null) {
+                        s_logger.warn("Unknown commands for VirtualRoutingResource, but continue: " + cmd.toString());
+                        continue;
+                    }
+
+                    for (ConfigItem c : cfg) {
+                        if (c.isFile()) {
+                            sb.append("<file>\n");
+                            sb.append(c.getFilePath() + c.getFileName() + "\n");
+                            sb.append(c.getFileContents() + "\n");
+                            sb.append("</file>\n");
+                        } else {
+                            sb.append("<script>\n");
+                            sb.append("/opt/cloud/bin/" + c.getScript() + " " + c.getArgs() + "\n");
+                            sb.append("</script>\n");
+                        }
                     }
                 }
+                String cfgFilePath = "/var/cache/cloud/";
+                String cfgFileName = "VR-"+ UUID.randomUUID().toString() + ".cfg";
+                ExecutionResult result = _vrDeployer.createFileInVR(cmd.getRouterAccessIp(), cfgFilePath, cfgFileName, sb.toString());
+                if (!result.isSuccess()) {
+                    return new Answer(cmd, false, result.getDetails());
+                }
+
+                result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), VRScripts.VR_CFG, "-c " + cfgFilePath + cfgFileName);
+                if (!result.isSuccess()) {
+                    return new Answer(cmd, false, result.getDetails());
+                }
+                return new Answer(cmd);
+            } finally {
+                queue.clear();
+                _vrAggregateCommandsSet.remove(routerName);
             }
-            String cfgFilePath = "/var/cache/cloud/";
-            String cfgFileName = "VR-"+ UUID.randomUUID().toString() + ".cfg";
-            ExecutionResult result = _vrDeployer.createFileInVR(cmd.getRouterAccessIp(), cfgFilePath, cfgFileName, sb.toString());
-            if (!result.isSuccess()) {
-                return new Answer(cmd, false, result.getDetails());
+        } else if (action == Action.Cleanup) {
+            assert (_vrAggregateCommandsSet.containsKey(routerName));
+            Queue<NetworkElementCommand> queue = _vrAggregateCommandsSet.get(routerName);
+            if (queue != null) {
+                queue.clear();
             }
+            _vrAggregateCommandsSet.remove(routerName);
 
-            result = _vrDeployer.executeInVR(cmd.getRouterAccessIp(), VRScripts.VR_CFG, "-c " + cfgFilePath + cfgFileName);
-            if (!result.isSuccess()) {
-                return new Answer(cmd, false, result.getDetails());
-            }
             return new Answer(cmd);
-        } finally {
-            queue.clear();
-            _vrAggregateCommandsSet.remove(routerName);
         }
+        return new Answer(cmd, false, "Fail to recongize aggregation action " + action.toString());
     }
-
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f45de30d/core/test/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResourceTest.java
----------------------------------------------------------------------
diff --git a/core/test/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResourceTest.java b/core/test/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResourceTest.java
index 4737019..48da1bb 100644
--- a/core/test/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResourceTest.java
+++ b/core/test/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResourceTest.java
@@ -19,11 +19,12 @@ package com.cloud.agent.resource.virtualnetwork;
 import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.BumpUpPriorityCommand;
 import com.cloud.agent.api.SetupGuestNetworkCommand;
+import com.cloud.agent.api.routing.AggregationControlCommand;
+import com.cloud.agent.api.routing.AggregationControlCommand.Action;
 import com.cloud.agent.api.routing.CreateIpAliasCommand;
 import com.cloud.agent.api.routing.DeleteIpAliasCommand;
 import com.cloud.agent.api.routing.DhcpEntryCommand;
 import com.cloud.agent.api.routing.DnsMasqConfigCommand;
-import com.cloud.agent.api.routing.FinishAggregationCommand;
 import com.cloud.agent.api.routing.GroupAnswer;
 import com.cloud.agent.api.routing.IpAliasTO;
 import com.cloud.agent.api.routing.IpAssocCommand;
@@ -41,7 +42,6 @@ import com.cloud.agent.api.routing.SetSourceNatCommand;
 import com.cloud.agent.api.routing.SetStaticNatRulesCommand;
 import com.cloud.agent.api.routing.SetStaticRouteCommand;
 import com.cloud.agent.api.routing.Site2SiteVpnCfgCommand;
-import com.cloud.agent.api.routing.StartAggregationCommand;
 import com.cloud.agent.api.routing.VmDataCommand;
 import com.cloud.agent.api.routing.VpnUsersCfgCommand;
 import com.cloud.agent.api.to.DhcpTO;
@@ -84,7 +84,6 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
     NetworkElementCommand _currentCmd;
     int _count;
     String _file;
-    boolean _aggregated = false;
 
     String ROUTERIP = "169.254.3.4";
     String ROUTERGUESTIP = "10.200.1.1";
@@ -138,8 +137,8 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
     }
 
     private void verifyFile(NetworkElementCommand cmd, String path, String filename, String content) {
-        if (cmd instanceof FinishAggregationCommand) {
-            verifyFile((FinishAggregationCommand)cmd, path, filename, content);
+        if (cmd instanceof AggregationControlCommand) {
+            verifyFile((AggregationControlCommand)cmd, path, filename, content);
         } else if (cmd instanceof LoadBalancerConfigCommand) {
             verifyFile((LoadBalancerConfigCommand)cmd, path, filename, content);
         }
@@ -190,10 +189,8 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
             verifyArgs((IpAssocCommand)cmd, script, args);
         }
 
-        if (cmd instanceof StartAggregationCommand) {
-            return;
-        } else if (cmd instanceof FinishAggregationCommand) {
-            verifyArgs((FinishAggregationCommand)cmd, script, args);
+        if (cmd instanceof AggregationControlCommand) {
+            verifyArgs((AggregationControlCommand)cmd, script, args);
         }
     }
 
@@ -948,7 +945,7 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
     @Test
     public void testAggregationCommands() {
         List<NetworkElementCommand> cmds = new LinkedList<>();
-        StartAggregationCommand startCmd = new StartAggregationCommand(ROUTERNAME, ROUTERIP, ROUTERGUESTIP);
+        AggregationControlCommand startCmd = new AggregationControlCommand(Action.Start, ROUTERNAME, ROUTERIP, ROUTERGUESTIP);
         cmds.add(startCmd);
         cmds.add(generateIpAssocCommand());
         cmds.add(generateIpAssocVpcCommand());
@@ -979,26 +976,22 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
         cmds.add(generateSavePasswordCommand());
         cmds.add(generateVmDataCommand());
 
-        FinishAggregationCommand finishCmd = new FinishAggregationCommand(ROUTERNAME, ROUTERIP, ROUTERGUESTIP);
+        AggregationControlCommand finishCmd = new AggregationControlCommand(Action.Finish, ROUTERNAME, ROUTERIP, ROUTERGUESTIP);
         cmds.add(finishCmd);
 
         for (NetworkElementCommand cmd : cmds) {
             Answer answer = _resource.executeRequest(cmd);
-            if (!(cmd instanceof FinishAggregationCommand)) {
-                assertTrue(answer.getResult());
-            } else {
-
-            }
+            assertTrue(answer.getResult());
         }
     }
 
-    private void verifyArgs(FinishAggregationCommand cmd, String script, String args) {
+    private void verifyArgs(AggregationControlCommand cmd, String script, String args) {
         assertEquals(script, VRScripts.VR_CFG);
         assertTrue(args.startsWith("-c /var/cache/cloud/VR-"));
         assertTrue(args.endsWith(".cfg"));
     }
 
-    protected void verifyFile(FinishAggregationCommand cmd, String path, String filename, String content) {
+    protected void verifyFile(AggregationControlCommand cmd, String path, String filename, String content) {
         assertEquals(path, "/var/cache/cloud/");
         assertTrue(filename.startsWith("VR-"));
         assertTrue(filename.endsWith(".cfg"));

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f45de30d/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
----------------------------------------------------------------------
diff --git a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
index 7853c3b..e36dc62 100755
--- a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
+++ b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
@@ -16,37 +16,6 @@
 // under the License.
 package org.apache.cloudstack.engine.orchestration;
 
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import javax.ejb.Local;
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.acl.ControlledEntity.ACLType;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
-import org.apache.cloudstack.framework.config.ConfigDepot;
-import org.apache.cloudstack.framework.config.ConfigKey;
-import org.apache.cloudstack.framework.config.Configurable;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.managed.context.ManagedContextRunnable;
-import org.apache.cloudstack.region.PortableIpDao;
-import org.apache.log4j.Logger;
-
 import com.cloud.agent.AgentManager;
 import com.cloud.agent.Listener;
 import com.cloud.agent.api.AgentControlAnswer;
@@ -127,6 +96,7 @@ import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
 import com.cloud.network.dao.PhysicalNetworkTrafficTypeDao;
 import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO;
 import com.cloud.network.dao.PhysicalNetworkVO;
+import com.cloud.network.element.AggregatedCommandExecutor;
 import com.cloud.network.element.DhcpServiceProvider;
 import com.cloud.network.element.IpDeployer;
 import com.cloud.network.element.LoadBalancingServiceProvider;
@@ -199,6 +169,35 @@ import com.cloud.vm.dao.NicSecondaryIpDao;
 import com.cloud.vm.dao.NicSecondaryIpVO;
 import com.cloud.vm.dao.UserVmDao;
 import com.cloud.vm.dao.VMInstanceDao;
+import org.apache.cloudstack.acl.ControlledEntity.ACLType;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+import org.apache.cloudstack.framework.config.ConfigDepot;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.framework.config.Configurable;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.managed.context.ManagedContextRunnable;
+import org.apache.cloudstack.region.PortableIpDao;
+import org.apache.log4j.Logger;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
 
 /**
  * NetworkManagerImpl implements NetworkManager.
@@ -1068,15 +1067,41 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
             }
         }
 
-        // reapply all the firewall/staticNat/lb rules
-        s_logger.debug("Reprogramming network " + network + " as a part of network implement");
-        if (!reprogramNetworkRules(network.getId(), CallContext.current().getCallingAccount(), network)) {
-            s_logger.warn("Failed to re-program the network as a part of network " + network + " implement");
-            // see DataCenterVO.java
-            ResourceUnavailableException ex = new ResourceUnavailableException("Unable to apply network rules as a part of network " + network + " implement", DataCenter.class,
-                    network.getDataCenterId());
-            ex.addProxyObject(_entityMgr.findById(DataCenter.class, network.getDataCenterId()).getUuid());
-            throw ex;
+        for (NetworkElement element : networkElements) {
+            if ((element instanceof AggregatedCommandExecutor) && (providersToImplement.contains(element.getProvider()))) {
+                ((AggregatedCommandExecutor)element).prepareAggregatedExecution(network, dest);
+            }
+        }
+
+        try {
+            // reapply all the firewall/staticNat/lb rules
+            s_logger.debug("Reprogramming network " + network + " as a part of network implement");
+            if (!reprogramNetworkRules(network.getId(), CallContext.current().getCallingAccount(), network)) {
+                s_logger.warn("Failed to re-program the network as a part of network " + network + " implement");
+                // see DataCenterVO.java
+                ResourceUnavailableException ex = new ResourceUnavailableException("Unable to apply network rules as a part of network " + network + " implement", DataCenter.class,
+                        network.getDataCenterId());
+                ex.addProxyObject(_entityMgr.findById(DataCenter.class, network.getDataCenterId()).getUuid());
+                throw ex;
+            }
+            for (NetworkElement element : networkElements) {
+                if ((element instanceof AggregatedCommandExecutor) && (providersToImplement.contains(element.getProvider()))) {
+                    if (!((AggregatedCommandExecutor)element).completeAggregatedExecution(network, dest)) {
+                        s_logger.warn("Failed to re-program the network as a part of network " + network + " implement due to aggregated commands execution failure!");
+                        // see DataCenterVO.java
+                        ResourceUnavailableException ex = new ResourceUnavailableException("Unable to apply network rules as a part of network " + network + " implement", DataCenter.class,
+                                network.getDataCenterId());
+                        ex.addProxyObject(_entityMgr.findById(DataCenter.class, network.getDataCenterId()).getUuid());
+                        throw ex;
+                    }
+                }
+            }
+        } finally {
+            for (NetworkElement element : networkElements) {
+                if ((element instanceof AggregatedCommandExecutor) && (providersToImplement.contains(element.getProvider()))) {
+                    ((AggregatedCommandExecutor)element).cleanupAggregatedExecution(network, dest);
+                }
+            }
         }
     }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f45de30d/server/src/com/cloud/network/element/VirtualRouterElement.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/element/VirtualRouterElement.java b/server/src/com/cloud/network/element/VirtualRouterElement.java
index 455e75f..3f4ba5b 100755
--- a/server/src/com/cloud/network/element/VirtualRouterElement.java
+++ b/server/src/com/cloud/network/element/VirtualRouterElement.java
@@ -16,26 +16,6 @@
 // under the License.
 package com.cloud.network.element;
 
-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 org.apache.log4j.Logger;
-
-import com.google.gson.Gson;
-
-import org.apache.cloudstack.api.command.admin.router.ConfigureOvsElementCmd;
-import org.apache.cloudstack.api.command.admin.router.ConfigureVirtualRouterElementCmd;
-import org.apache.cloudstack.api.command.admin.router.CreateVirtualRouterElementCmd;
-import org.apache.cloudstack.api.command.admin.router.ListOvsElementsCmd;
-import org.apache.cloudstack.api.command.admin.router.ListVirtualRouterElementsCmd;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-
 import com.cloud.agent.api.to.LoadBalancerTO;
 import com.cloud.configuration.ConfigurationManager;
 import com.cloud.dc.DataCenter;
@@ -101,6 +81,22 @@ import com.cloud.vm.VirtualMachine.State;
 import com.cloud.vm.VirtualMachineProfile;
 import com.cloud.vm.dao.DomainRouterDao;
 import com.cloud.vm.dao.UserVmDao;
+import com.google.gson.Gson;
+import org.apache.cloudstack.api.command.admin.router.ConfigureOvsElementCmd;
+import org.apache.cloudstack.api.command.admin.router.ConfigureVirtualRouterElementCmd;
+import org.apache.cloudstack.api.command.admin.router.CreateVirtualRouterElementCmd;
+import org.apache.cloudstack.api.command.admin.router.ListOvsElementsCmd;
+import org.apache.cloudstack.api.command.admin.router.ListVirtualRouterElementsCmd;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.log4j.Logger;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 @Local(value = {NetworkElement.class, FirewallServiceProvider.class,
     DhcpServiceProvider.class, UserDataServiceProvider.class,
@@ -110,7 +106,7 @@ import com.cloud.vm.dao.UserVmDao;
 public class VirtualRouterElement extends AdapterBase implements VirtualRouterElementService, DhcpServiceProvider,
         UserDataServiceProvider, SourceNatServiceProvider, StaticNatServiceProvider, FirewallServiceProvider,
         LoadBalancingServiceProvider, PortForwardingServiceProvider, RemoteAccessVPNServiceProvider, IpDeployer,
-        NetworkMigrationResponder {
+        NetworkMigrationResponder, AggregatedCommandExecutor {
     private static final Logger s_logger = Logger.getLogger(VirtualRouterElement.class);
     public static final AutoScaleCounterType AutoScaleCounterCpu = new AutoScaleCounterType("cpu");
     public static final AutoScaleCounterType AutoScaleCounterMemory = new AutoScaleCounterType("memory");
@@ -1091,4 +1087,37 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl
             _userVmMgr.setupVmForPvlan(true, userVm.getHostId(), nic);
         }
     }
+
+    @Override
+    public boolean prepareAggregatedExecution(Network network, DeployDestination dest) throws ResourceUnavailableException {
+        List<DomainRouterVO> routers = getRouters(network, dest);
+
+        if ((routers == null) || (routers.size() == 0)) {
+            throw new ResourceUnavailableException("Can't find at least one router!", DataCenter.class, network.getDataCenterId());
+        }
+
+        return _routerMgr.prepareAggregatedExecution(network, routers);
+    }
+
+    @Override
+    public boolean completeAggregatedExecution(Network network, DeployDestination dest) throws ResourceUnavailableException {
+        List<DomainRouterVO> routers = getRouters(network, dest);
+
+        if ((routers == null) || (routers.size() == 0)) {
+            throw new ResourceUnavailableException("Can't find at least one router!", DataCenter.class, network.getDataCenterId());
+        }
+
+        return _routerMgr.completeAggregatedExecution(network, routers);
+    }
+
+    @Override
+    public boolean cleanupAggregatedExecution(Network network, DeployDestination dest) throws ResourceUnavailableException {
+        List<DomainRouterVO> routers = getRouters(network, dest);
+
+        if ((routers == null) || (routers.size() == 0)) {
+            throw new ResourceUnavailableException("Can't find at least one router!", DataCenter.class, network.getDataCenterId());
+        }
+
+        return _routerMgr.cleanupAggregatedExecution(network, routers);
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f45de30d/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java
index 9097b87..e3597ac 100644
--- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java
+++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java
@@ -16,12 +16,8 @@
 // under the License.
 package com.cloud.network.router;
 
-import java.util.List;
-import java.util.Map;
-
-import org.apache.cloudstack.framework.config.ConfigKey;
-
 import com.cloud.deploy.DeployDestination;
+import com.cloud.exception.AgentUnavailableException;
 import com.cloud.exception.ConcurrentOperationException;
 import com.cloud.exception.InsufficientCapacityException;
 import com.cloud.exception.ResourceUnavailableException;
@@ -39,6 +35,10 @@ import com.cloud.utils.component.Manager;
 import com.cloud.vm.DomainRouterVO;
 import com.cloud.vm.NicProfile;
 import com.cloud.vm.VirtualMachineProfile;
+import org.apache.cloudstack.framework.config.ConfigKey;
+
+import java.util.List;
+import java.util.Map;
 
 /**
  * NetworkManager manages the network for the different end users.
@@ -129,4 +129,10 @@ public interface VirtualNetworkApplianceManager extends Manager, VirtualNetworkA
     boolean removeDhcpSupportForSubnet(Network network, List<DomainRouterVO> routers) throws ResourceUnavailableException;
 
     boolean setupDhcpForPvlan(boolean add, DomainRouterVO router, Long hostId, NicProfile nic);
+
+    public boolean prepareAggregatedExecution(Network network, List<DomainRouterVO> routers) throws AgentUnavailableException;
+
+    public boolean completeAggregatedExecution(Network network, List<DomainRouterVO> routers) throws AgentUnavailableException;
+
+    public boolean cleanupAggregatedExecution(Network network, List<DomainRouterVO> routers) throws AgentUnavailableException;
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f45de30d/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
index 3c99867..74cfd74 100755
--- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
+++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
@@ -17,47 +17,6 @@
 
 package com.cloud.network.router;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TimeZone;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import javax.ejb.Local;
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.api.command.admin.router.RebootRouterCmd;
-import org.apache.cloudstack.api.command.admin.router.UpgradeRouterCmd;
-import org.apache.cloudstack.api.command.admin.router.UpgradeRouterTemplateCmd;
-import org.apache.cloudstack.config.ApiServiceConfiguration;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
-import org.apache.cloudstack.framework.config.ConfigDepot;
-import org.apache.cloudstack.framework.config.ConfigKey;
-import org.apache.cloudstack.framework.config.Configurable;
-import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
-import org.apache.cloudstack.framework.jobs.AsyncJobManager;
-import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
-import org.apache.cloudstack.managed.context.ManagedContextRunnable;
-import org.apache.cloudstack.utils.identity.ManagementServerNode;
-import org.apache.log4j.Logger;
-
 import com.cloud.agent.AgentManager;
 import com.cloud.agent.Listener;
 import com.cloud.agent.api.AgentControlAnswer;
@@ -78,6 +37,8 @@ import com.cloud.agent.api.PvlanSetupCommand;
 import com.cloud.agent.api.StartupCommand;
 import com.cloud.agent.api.check.CheckSshAnswer;
 import com.cloud.agent.api.check.CheckSshCommand;
+import com.cloud.agent.api.routing.AggregationControlCommand;
+import com.cloud.agent.api.routing.AggregationControlCommand.Action;
 import com.cloud.agent.api.routing.CreateIpAliasCommand;
 import com.cloud.agent.api.routing.DeleteIpAliasCommand;
 import com.cloud.agent.api.routing.DhcpEntryCommand;
@@ -277,6 +238,45 @@ import com.cloud.vm.dao.NicIpAliasVO;
 import com.cloud.vm.dao.UserVmDao;
 import com.cloud.vm.dao.UserVmDetailsDao;
 import com.cloud.vm.dao.VMInstanceDao;
+import org.apache.cloudstack.api.command.admin.router.RebootRouterCmd;
+import org.apache.cloudstack.api.command.admin.router.UpgradeRouterCmd;
+import org.apache.cloudstack.api.command.admin.router.UpgradeRouterTemplateCmd;
+import org.apache.cloudstack.config.ApiServiceConfiguration;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
+import org.apache.cloudstack.framework.config.ConfigDepot;
+import org.apache.cloudstack.framework.config.ConfigKey;
+import org.apache.cloudstack.framework.config.Configurable;
+import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
+import org.apache.cloudstack.framework.jobs.AsyncJobManager;
+import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
+import org.apache.cloudstack.managed.context.ManagedContextRunnable;
+import org.apache.cloudstack.utils.identity.ManagementServerNode;
+import org.apache.log4j.Logger;
+
+import javax.ejb.Local;
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TimeZone;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
 
 /**
  * VirtualNetworkApplianceManagerImpl manages the different types of virtual network appliances available in the Cloud Stack.
@@ -2320,12 +2320,20 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V
 
         final List<Long> routerGuestNtwkIds = _routerDao.getRouterNetworks(router.getId());
         for (final Long guestNetworkId : routerGuestNtwkIds) {
+            AggregationControlCommand startCmd = new AggregationControlCommand(Action.Start, router.getInstanceName(), controlNic.getIp4Address(),
+                    getRouterIpInNetwork(guestNetworkId, router.getId()));
+            cmds.addCommand(startCmd);
+
             if (reprogramGuestNtwks) {
                 finalizeIpAssocForNetwork(cmds, router, provider, guestNetworkId, null);
                 finalizeNetworkRulesForNetwork(cmds, router, provider, guestNetworkId);
             }
 
             finalizeUserDataAndDhcpOnStart(cmds, router, provider, guestNetworkId);
+
+            AggregationControlCommand finishCmd = new AggregationControlCommand(Action.Finish, router.getInstanceName(), controlNic.getIp4Address(),
+                    getRouterIpInNetwork(guestNetworkId, router.getId()));
+            cmds.addCommand(finishCmd);
         }
 
 
@@ -2338,8 +2346,6 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V
             finalizeMonitorServiceOnStrat(cmds, profile, router, provider, routerGuestNtwkIds.get(0), false);
         }
 
-
-
         return true;
     }
 
@@ -4259,4 +4265,31 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V
             }
         }
     }
+
+    protected boolean aggregationExecution(AggregationControlCommand.Action action, Network network, List<DomainRouterVO> routers) throws AgentUnavailableException {
+        for (DomainRouterVO router : routers) {
+            AggregationControlCommand cmd = new AggregationControlCommand(action, router.getInstanceName(), getRouterControlIp(router.getId()),
+                    getRouterIpInNetwork(network.getId(), router.getId()));
+            Commands cmds = new Commands(cmd);
+            if (!sendCommandsToRouter(router, cmds)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public boolean prepareAggregatedExecution(Network network, List<DomainRouterVO> routers) throws AgentUnavailableException {
+        return aggregationExecution(Action.Start, network, routers);
+    }
+
+    @Override
+    public boolean completeAggregatedExecution(Network network, List<DomainRouterVO> routers) throws AgentUnavailableException {
+        return aggregationExecution(Action.Finish, network, routers);
+    }
+
+    @Override
+    public boolean cleanupAggregatedExecution(Network network, List<DomainRouterVO> routers) throws AgentUnavailableException {
+        return aggregationExecution(Action.Cleanup, network, routers);
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/f45de30d/server/test/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java b/server/test/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java
index e0c599d..cbed4ca 100644
--- a/server/test/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java
+++ b/server/test/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java
@@ -17,17 +17,8 @@
 
 package com.cloud.vpc;
 
-import java.util.List;
-import java.util.Map;
-
-import javax.ejb.Local;
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.api.command.admin.router.UpgradeRouterCmd;
-import org.apache.cloudstack.api.command.admin.router.UpgradeRouterTemplateCmd;
-import org.springframework.stereotype.Component;
-
 import com.cloud.deploy.DeployDestination;
+import com.cloud.exception.AgentUnavailableException;
 import com.cloud.exception.ConcurrentOperationException;
 import com.cloud.exception.InsufficientCapacityException;
 import com.cloud.exception.ResourceUnavailableException;
@@ -53,6 +44,14 @@ import com.cloud.vm.DomainRouterVO;
 import com.cloud.vm.NicProfile;
 import com.cloud.vm.VirtualMachineProfile;
 import com.cloud.vm.VirtualMachineProfile.Param;
+import org.apache.cloudstack.api.command.admin.router.UpgradeRouterCmd;
+import org.apache.cloudstack.api.command.admin.router.UpgradeRouterTemplateCmd;
+import org.springframework.stereotype.Component;
+
+import javax.ejb.Local;
+import javax.naming.ConfigurationException;
+import java.util.List;
+import java.util.Map;
 
 @Component
 @Local(value = {VpcVirtualNetworkApplianceManager.class, VpcVirtualNetworkApplianceService.class})
@@ -420,6 +419,21 @@ public class MockVpcVirtualNetworkApplianceManager extends ManagerBase implement
     }
 
     @Override
+    public boolean prepareAggregatedExecution(Network network, List<DomainRouterVO> routers) throws AgentUnavailableException {
+        return true;  //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    public boolean completeAggregatedExecution(Network network, List<DomainRouterVO> routers) throws AgentUnavailableException {
+        return true;  //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
+    public boolean cleanupAggregatedExecution(Network network, List<DomainRouterVO> routers) throws AgentUnavailableException {
+        return true;  //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    @Override
     public boolean startRemoteAccessVpn(RemoteAccessVpn vpn, VirtualRouter router) throws ResourceUnavailableException {
         // TODO Auto-generated method stub
         return false;


[05/31] git commit: updated refs/heads/distributedrouter to a8d43ba

Posted by mu...@apache.org.
Corrected the value of label.no.grouping in the resource files. An extra backspace at the end of the string caused incorrect text to be shown in the Select view dropdown on Virtual Routers page: "(no grouping)\label.create.nfs.secondary.staging.storage=Create NFS Secondary Staging Store" instead of "(no grouping)"

Signed-off-by: Mihaela Stoica <mi...@citrix.com>


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

Branch: refs/heads/distributedrouter
Commit: 36558e461973e85aa6270fb15886f727f6fb6560
Parents: c63f43a
Author: Mihaela Stoica <mi...@citrix.com>
Authored: Tue Mar 11 14:44:36 2014 +0000
Committer: Brian Federle <br...@citrix.com>
Committed: Tue Mar 11 11:25:18 2014 -0700

----------------------------------------------------------------------
 client/WEB-INF/classes/resources/messages.properties       | 2 +-
 client/WEB-INF/classes/resources/messages_ja_JP.properties | 2 +-
 client/WEB-INF/classes/resources/messages_zh_CN.properties | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/36558e46/client/WEB-INF/classes/resources/messages.properties
----------------------------------------------------------------------
diff --git a/client/WEB-INF/classes/resources/messages.properties b/client/WEB-INF/classes/resources/messages.properties
index cb4d292..c46361a 100644
--- a/client/WEB-INF/classes/resources/messages.properties
+++ b/client/WEB-INF/classes/resources/messages.properties
@@ -1441,7 +1441,7 @@ label.group.by.zone=group by zone
 label.group.by.pod=group by pod
 label.group.by.cluster=group by cluster
 label.group.by.account=group by account
-label.no.grouping=(no grouping)\
+label.no.grouping=(no grouping)
 label.create.nfs.secondary.staging.storage=Create NFS Secondary Staging Store
 label.username.lower=username
 label.password.lower=password

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/36558e46/client/WEB-INF/classes/resources/messages_ja_JP.properties
----------------------------------------------------------------------
diff --git a/client/WEB-INF/classes/resources/messages_ja_JP.properties b/client/WEB-INF/classes/resources/messages_ja_JP.properties
index da4851a..d3d50f0 100644
--- a/client/WEB-INF/classes/resources/messages_ja_JP.properties
+++ b/client/WEB-INF/classes/resources/messages_ja_JP.properties
@@ -1440,7 +1440,7 @@ label.group.by.zone=\u30be\u30fc\u30f3\u5225\u30b0\u30eb\u30fc\u30d7
 label.group.by.pod=\u30dd\u30c3\u30c9\u5225\u30b0\u30eb\u30fc\u30d7
 label.group.by.cluster=\u30af\u30e9\u30b9\u30bf\u30fc\u5225\u30b0\u30eb\u30fc\u30d7
 label.group.by.account=\u30a2\u30ab\u30a6\u30f3\u30c8\u5225\u30b0\u30eb\u30fc\u30d7
-label.no.grouping=(\u30b0\u30eb\u30fc\u30d7\u306a\u3057)\
+label.no.grouping=(\u30b0\u30eb\u30fc\u30d7\u306a\u3057)
 label.create.nfs.secondary.staging.storage=NFS \u30bb\u30ab\u30f3\u30c0\u30ea \u30b9\u30c6\u30fc\u30b8\u30f3\u30b0 \u30b9\u30c8\u30a2\u3092\u4f5c\u6210\u3059\u308b
 label.username.lower=\u30e6\u30fc\u30b6\u30fc\u540d
 label.password.lower=\u30d1\u30b9\u30ef\u30fc\u30c9

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/36558e46/client/WEB-INF/classes/resources/messages_zh_CN.properties
----------------------------------------------------------------------
diff --git a/client/WEB-INF/classes/resources/messages_zh_CN.properties b/client/WEB-INF/classes/resources/messages_zh_CN.properties
index bb3e50c..ea7bfd4 100644
--- a/client/WEB-INF/classes/resources/messages_zh_CN.properties
+++ b/client/WEB-INF/classes/resources/messages_zh_CN.properties
@@ -1440,7 +1440,7 @@ label.group.by.zone=\u6309\u8d44\u6e90\u57df\u5206\u7ec4
 label.group.by.pod=\u6309\u63d0\u4f9b\u70b9\u5206\u7ec4
 label.group.by.cluster=\u6309\u7fa4\u96c6\u5206\u7ec4
 label.group.by.account=\u6309\u5e10\u6237\u5206\u7ec4
-label.no.grouping=(\u4e0d\u5206\u7ec4)\
+label.no.grouping=(\u4e0d\u5206\u7ec4)
 label.create.nfs.secondary.staging.storage=\u521b\u5efa NFS \u4e8c\u7ea7\u6682\u5b58\u5b58\u50a8
 label.username.lower=\u7528\u6237\u540d
 label.password.lower=\u5bc6\u7801