incubator-cloudstack-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Vijayendra Bhamidipati <vijayendra.bhamidip...@citrix.com>
Subject Patch for review and merge into Apache master: Bug CS-15173
Date Tue, 19 Jun 2012 00:28:00 GMT
Hi Team,

Please find attached the ASF master git patch for Bug CS-15173 (http://bugs.cloudstack.org/browse/CS-15173
). Also, pasting the contents of the patch below for quicker review.

Regards,
Vijay



>From 89753db2ef5411e81de6c28d57794d8acda87efd Mon Sep 17 00:00:00 2001
From: Vijayendra Bhamidipati <vijayendra.bhamidipati@citrix.com>
Date: Mon, 18 Jun 2012 16:41:06 -0700
Subject: [PATCH] CS-15173: Additional Cluster is allowed to add with the same
 VSM IPaddress as the previous cluster

Description:

        Restricting association of a Cisco Nexus VSM to a single
        cluster.
---
 api/src/com/cloud/api/commands/AddClusterCmd.java  |   11 +++-
 api/src/com/cloud/resource/ResourceService.java    |    3 +-
 .../com/cloud/resource/ResourceManagerImpl.java    |   73 +++++++++++++-------
 .../hypervisor/vmware/mo/HypervisorHostHelper.java |   10 +++-
 4 files changed, 68 insertions(+), 29 deletions(-)

diff --git a/api/src/com/cloud/api/commands/AddClusterCmd.java b/api/src/com/cloud/api/commands/AddClusterCmd.java
index 6688dee..39fa63d 100755
--- a/api/src/com/cloud/api/commands/AddClusterCmd.java
+++ b/api/src/com/cloud/api/commands/AddClusterCmd.java
@@ -31,8 +31,10 @@ import com.cloud.api.ServerApiException;
 import com.cloud.api.response.ClusterResponse;
 import com.cloud.api.response.ListResponse;
 import com.cloud.exception.DiscoveryException;
+import com.cloud.exception.ResourceInUseException;
 import com.cloud.org.Cluster;
 import com.cloud.user.Account;
+import com.cloud.utils.IdentityProxy;
 ^M
 @Implementation(description="Adds a new cluster", responseObject=ClusterResponse.class)^M
 public class AddClusterCmd extends BaseCmd {^M
@@ -166,7 +168,14 @@ public class AddClusterCmd extends BaseCmd {
             this.setResponseObject(response);^M
         } catch (DiscoveryException ex) {^M
             s_logger.warn("Exception: ", ex);^M
-            throw new ServerApiException(BaseCmd.INTERNAL_ERROR, ex.getMessage());^M
+            throw new ServerApiException(BaseCmd.INTERNAL_ERROR, ex.getMessage());
+        } catch (ResourceInUseException ex) {
+               s_logger.warn("Exception: ", ex);
+               ServerApiException e = new ServerApiException(BaseCmd.INTERNAL_ERROR, ex.getMessage());
+               for (IdentityProxy proxyObj : ex.getIdProxyList()) {
+                       e.addProxyObject(proxyObj.getTableName(), proxyObj.getValue(), proxyObj.getidFieldName());
+               }
+               throw e;
         }^M
     }^M
 }
diff --git a/api/src/com/cloud/resource/ResourceService.java b/api/src/com/cloud/resource/ResourceService.java
index d971a40..1065453 100755
--- a/api/src/com/cloud/resource/ResourceService.java
+++ b/api/src/com/cloud/resource/ResourceService.java
@@ -31,6 +31,7 @@ import com.cloud.api.commands.UpdateHostCmd;
 import com.cloud.api.commands.UpdateHostPasswordCmd;
 import com.cloud.exception.DiscoveryException;
 import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.ResourceInUseException;
 import com.cloud.host.Host;
 import com.cloud.hypervisor.Hypervisor.HypervisorType;
 import com.cloud.org.Cluster;
@@ -61,7 +62,7 @@ public interface ResourceService {
      * @throws IllegalArgumentException
      * @throws DiscoveryException
      */
-    List<? extends Cluster> discoverCluster(AddClusterCmd cmd) throws IllegalArgumentException,
DiscoveryException;
+    List<? extends Cluster> discoverCluster(AddClusterCmd cmd) throws IllegalArgumentException,
DiscoveryException, ResourceInUseException;

     boolean deleteCluster(DeleteClusterCmd cmd);

diff --git a/server/src/com/cloud/resource/ResourceManagerImpl.java b/server/src/com/cloud/resource/ResourceManagerImpl.java
index 3380972..357dca3 100755
--- a/server/src/com/cloud/resource/ResourceManagerImpl.java
+++ b/server/src/com/cloud/resource/ResourceManagerImpl.java
@@ -79,6 +79,7 @@ import com.cloud.exception.AgentUnavailableException;
 import com.cloud.exception.DiscoveryException;
 import com.cloud.exception.InvalidParameterValueException;
 import com.cloud.exception.PermissionDeniedException;
+import com.cloud.exception.ResourceInUseException;
 import com.cloud.ha.HighAvailabilityManager;
 import com.cloud.ha.HighAvailabilityManager.WorkType;
 import com.cloud.host.DetailVO;
@@ -324,7 +325,7 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService,
Ma

     @DB
     @Override
-    public List<? extends Cluster> discoverCluster(AddClusterCmd cmd) throws IllegalArgumentException,
DiscoveryException {
+    public List<? extends Cluster> discoverCluster(AddClusterCmd cmd) throws IllegalArgumentException,
DiscoveryException, ResourceInUseException {
         long dcId = cmd.getZoneId();
         long podId = cmd.getPodId();
         String clusterName = cmd.getClusterName();
@@ -433,6 +434,7 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService,
Ma
         clusterId = cluster.getId();
         result.add(cluster);

+        // Check if we're associating a Cisco Nexus VSM with a vmware cluster.
         if (hypervisorType == HypervisorType.VMware &&
                        Boolean.parseBoolean(_configDao.getValue(Config.VmwareUseNexusVSwitch.toString())))
{
                String vsmIp = cmd.getVSMIpaddress();
@@ -450,33 +452,52 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService,
Ma
                            _clusterDao.remove(clusterId);
                        throw new CloudRuntimeException(msg);
                    }
-                   // persist credentials to database
-                   CiscoNexusVSMDeviceVO vsm = new CiscoNexusVSMDeviceVO(vsmIp, vsmUser,
vsmPassword);

-                   Transaction txn = Transaction.currentTxn();
-                   try {
-                       txn.start();
-                       vsm = _vsmDao.persist(vsm);
-                       txn.commit();
-                   } catch (Exception e) {
-                       txn.rollback();
-                       s_logger.error("Failed to persist Cisco Nexus 1000v VSM details to
database. Exception: " + e.getMessage());
-                       // Removing the cluster record which was added already because the
persistence of Nexus VSM credentials has failed.
-                           _clusterDao.remove(clusterId);
-                       throw new CloudRuntimeException(e.getMessage());
-                   }
+                   Transaction txn;

-                   ClusterVSMMapVO connectorObj = new ClusterVSMMapVO(clusterId, vsm.getId());
-                   txn = Transaction.currentTxn();
-                   try {
-                       txn.start();
-                       _clusterVSMDao.persist(connectorObj);
-                       txn.commit();
-                   } catch (Exception e) {
-                       txn.rollback();
-                       s_logger.error("Failed to associate Cisco Nexus 1000v VSM with cluster:
" + clusterName + ". Exception: " + e.getMessage());
-                       _clusterDao.remove(clusterId);
-                       throw new CloudRuntimeException(e.getMessage());
+                   // If VSM already exists and is mapped to a cluster, fail this operation.
+                   CiscoNexusVSMDeviceVO vsm = _vsmDao.getVSMbyIpaddress(vsmIp);
+                   if(vsm != null) {
+                       List<ClusterVSMMapVO> clusterList = _clusterVSMDao.listByVSMId(vsm.getId());
+                       if (clusterList != null && !clusterList.isEmpty()) {
+                               s_logger.error("Failed to add cluster: specified Nexus VSM
is already associated with another cluster");
+                               _clusterDao.remove(clusterId);
+                               ResourceInUseException ex = new ResourceInUseException("Failed
to add cluster: specified Nexus VSM is already associated with another cluster with specified
Id");
+                               ex.addProxyObject("cluster", clusterList.get(0).getClusterId(),
"clusterId");
+                               throw ex;
+                       }
+                   }
+                   // persist credentials to database if the VSM entry is not already in
the db.
+                   if (_vsmDao.getVSMbyIpaddress(vsmIp) == null) {
+                       vsm = new CiscoNexusVSMDeviceVO(vsmIp, vsmUser, vsmPassword);
+                       txn = Transaction.currentTxn();
+                       try {
+                               txn.start();
+                               vsm = _vsmDao.persist(vsm);
+                               txn.commit();
+                       } catch (Exception e) {
+                               txn.rollback();
+                               s_logger.error("Failed to persist Cisco Nexus 1000v VSM details
to database. Exception: " + e.getMessage());
+                               // Removing the cluster record which was added already because
the persistence of Nexus VSM credentials has failed.
+                               _clusterDao.remove(clusterId);
+                               throw new CloudRuntimeException(e.getMessage());
+                       }
+                   }
+                   // Create a mapping between the cluster and the vsm.
+                   vsm = _vsmDao.getVSMbyIpaddress(vsmIp);
+                   if (vsm != null) {
+                       ClusterVSMMapVO connectorObj = new ClusterVSMMapVO(clusterId, vsm.getId());
+                       txn = Transaction.currentTxn();
+                       try {
+                               txn.start();
+                               _clusterVSMDao.persist(connectorObj);
+                               txn.commit();
+                       } catch (Exception e) {
+                               txn.rollback();
+                               s_logger.error("Failed to associate Cisco Nexus 1000v VSM
with cluster: " + clusterName + ". Exception: " + e.getMessage());
+                               _clusterDao.remove(clusterId);
+                               throw new CloudRuntimeException(e.getMessage());
+                       }
                    }
                } else {
                        String msg;
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java
index 4437519..cfbdc56 100755
--- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java
+++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java
@@ -194,6 +194,7 @@ public class HypervisorHostHelper {
                 netconfClient.disconnect();
                 s_logger.debug("Disconnected Nexus 1000v session.");
             }
+            throw new CloudRuntimeException(msg);
         }

         List<Pair<OperationType, String>> params = new ArrayList<Pair<OperationType,
String>>();
@@ -212,6 +213,7 @@ public class HypervisorHostHelper {
                        netconfClient.disconnect();
                        s_logger.debug("Disconnected Nexus 1000v session.");
                 }
+                throw new CloudRuntimeException(msg);
             }
         }

@@ -230,6 +232,7 @@ public class HypervisorHostHelper {
                 netconfClient.disconnect();
                 s_logger.debug("Disconnected Nexus 1000v session.");
             }
+            throw new CloudRuntimeException(msg);
         }

         try {
@@ -241,7 +244,8 @@ public class HypervisorHostHelper {
         catch(CloudRuntimeException e) {
             msg = "Failed to associate policy map " + policyName + " with port profile "
+ networkName
                     + ". Exception: " + e.toString();
-            s_logger.error(msg);
+            s_logger.error(msg);
+            throw new CloudRuntimeException(msg);
         } finally {
             if (netconfClient != null) {
                 netconfClient.disconnect();
@@ -301,6 +305,7 @@ public class HypervisorHostHelper {
                         netconfClient.disconnect();
                         s_logger.debug("Disconnected Nexus 1000v session.");
                     }
+                    throw new CloudRuntimeException(msg);
                 }

                 try {
@@ -315,6 +320,7 @@ public class HypervisorHostHelper {
                         netconfClient.disconnect();
                         s_logger.debug("Disconnected Nexus 1000v session.");
                     }
+                    throw new CloudRuntimeException(msg);
                 }
             }
         }
@@ -352,6 +358,7 @@ public class HypervisorHostHelper {
                 netconfClient.disconnect();
                 s_logger.debug("Disconnected Nexus 1000v session.");
             }
+            throw new CloudRuntimeException(msg);
         }

         try {
@@ -364,6 +371,7 @@ public class HypervisorHostHelper {
                 netconfClient.disconnect();
                 s_logger.debug("Disconnected Nexus 1000v session.");
             }
+            throw new CloudRuntimeException(msg);
         }
     }

Mime
  • Unnamed multipart/mixed (inline, None, 0 bytes)
View raw message