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.
This commit is contained in:
Vijayendra Bhamidipati 2012-06-22 13:31:56 -07:00 committed by Sheng Yang
parent 8dd4197cd8
commit 361ca9643d
4 changed files with 857 additions and 817 deletions

View File

@ -31,8 +31,10 @@ import com.cloud.api.ServerApiException;
import com.cloud.api.response.ClusterResponse; import com.cloud.api.response.ClusterResponse;
import com.cloud.api.response.ListResponse; import com.cloud.api.response.ListResponse;
import com.cloud.exception.DiscoveryException; import com.cloud.exception.DiscoveryException;
import com.cloud.exception.ResourceInUseException;
import com.cloud.org.Cluster; import com.cloud.org.Cluster;
import com.cloud.user.Account; import com.cloud.user.Account;
import com.cloud.utils.IdentityProxy;
@Implementation(description="Adds a new cluster", responseObject=ClusterResponse.class) @Implementation(description="Adds a new cluster", responseObject=ClusterResponse.class)
public class AddClusterCmd extends BaseCmd { public class AddClusterCmd extends BaseCmd {
@ -167,6 +169,13 @@ public class AddClusterCmd extends BaseCmd {
} catch (DiscoveryException ex) { } catch (DiscoveryException ex) {
s_logger.warn("Exception: ", ex); s_logger.warn("Exception: ", ex);
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, ex.getMessage()); 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;
} }
} }
} }

View File

@ -31,6 +31,7 @@ import com.cloud.api.commands.UpdateHostCmd;
import com.cloud.api.commands.UpdateHostPasswordCmd; import com.cloud.api.commands.UpdateHostPasswordCmd;
import com.cloud.exception.DiscoveryException; import com.cloud.exception.DiscoveryException;
import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceInUseException;
import com.cloud.host.Host; import com.cloud.host.Host;
import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.org.Cluster; import com.cloud.org.Cluster;
@ -61,7 +62,7 @@ public interface ResourceService {
* @throws IllegalArgumentException * @throws IllegalArgumentException
* @throws DiscoveryException * @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); boolean deleteCluster(DeleteClusterCmd cmd);

View File

@ -79,6 +79,7 @@ import com.cloud.exception.AgentUnavailableException;
import com.cloud.exception.DiscoveryException; import com.cloud.exception.DiscoveryException;
import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.PermissionDeniedException;
import com.cloud.exception.ResourceInUseException;
import com.cloud.ha.HighAvailabilityManager; import com.cloud.ha.HighAvailabilityManager;
import com.cloud.ha.HighAvailabilityManager.WorkType; import com.cloud.ha.HighAvailabilityManager.WorkType;
import com.cloud.host.DetailVO; import com.cloud.host.DetailVO;
@ -324,7 +325,7 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma
@DB @DB
@Override @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 dcId = cmd.getZoneId();
long podId = cmd.getPodId(); long podId = cmd.getPodId();
String clusterName = cmd.getClusterName(); String clusterName = cmd.getClusterName();
@ -433,6 +434,7 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma
clusterId = cluster.getId(); clusterId = cluster.getId();
result.add(cluster); result.add(cluster);
// Check if we're associating a Cisco Nexus VSM with a vmware cluster.
if (hypervisorType == HypervisorType.VMware && if (hypervisorType == HypervisorType.VMware &&
Boolean.parseBoolean(_configDao.getValue(Config.VmwareUseNexusVSwitch.toString()))) { Boolean.parseBoolean(_configDao.getValue(Config.VmwareUseNexusVSwitch.toString()))) {
String vsmIp = cmd.getVSMIpaddress(); String vsmIp = cmd.getVSMIpaddress();
@ -450,10 +452,25 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma
_clusterDao.remove(clusterId); _clusterDao.remove(clusterId);
throw new CloudRuntimeException(msg); throw new CloudRuntimeException(msg);
} }
// persist credentials to database
CiscoNexusVSMDeviceVO vsm = new CiscoNexusVSMDeviceVO(vsmIp, vsmUser, vsmPassword);
Transaction txn = Transaction.currentTxn(); Transaction txn;
// 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 { try {
txn.start(); txn.start();
vsm = _vsmDao.persist(vsm); vsm = _vsmDao.persist(vsm);
@ -465,7 +482,10 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma
_clusterDao.remove(clusterId); _clusterDao.remove(clusterId);
throw new CloudRuntimeException(e.getMessage()); 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()); ClusterVSMMapVO connectorObj = new ClusterVSMMapVO(clusterId, vsm.getId());
txn = Transaction.currentTxn(); txn = Transaction.currentTxn();
try { try {
@ -478,6 +498,7 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma
_clusterDao.remove(clusterId); _clusterDao.remove(clusterId);
throw new CloudRuntimeException(e.getMessage()); throw new CloudRuntimeException(e.getMessage());
} }
}
} else { } else {
String msg; String msg;
msg = "The global parameter " + Config.VmwareUseNexusVSwitch.toString() + msg = "The global parameter " + Config.VmwareUseNexusVSwitch.toString() +
@ -1209,6 +1230,7 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma
return true; return true;
} }
@Override
public boolean maintain(final long hostId) throws AgentUnavailableException { public boolean maintain(final long hostId) throws AgentUnavailableException {
Boolean result = _clusterMgr.propagateResourceEvent(hostId, ResourceState.Event.AdminAskMaintenace); Boolean result = _clusterMgr.propagateResourceEvent(hostId, ResourceState.Event.AdminAskMaintenace);
if (result != null) { if (result != null) {

View File

@ -194,6 +194,7 @@ public class HypervisorHostHelper {
netconfClient.disconnect(); netconfClient.disconnect();
s_logger.debug("Disconnected Nexus 1000v session."); s_logger.debug("Disconnected Nexus 1000v session.");
} }
throw new CloudRuntimeException(msg);
} }
List<Pair<OperationType, String>> params = new ArrayList<Pair<OperationType, String>>(); List<Pair<OperationType, String>> params = new ArrayList<Pair<OperationType, String>>();
@ -212,6 +213,7 @@ public class HypervisorHostHelper {
netconfClient.disconnect(); netconfClient.disconnect();
s_logger.debug("Disconnected Nexus 1000v session."); s_logger.debug("Disconnected Nexus 1000v session.");
} }
throw new CloudRuntimeException(msg);
} }
} }
@ -230,6 +232,7 @@ public class HypervisorHostHelper {
netconfClient.disconnect(); netconfClient.disconnect();
s_logger.debug("Disconnected Nexus 1000v session."); s_logger.debug("Disconnected Nexus 1000v session.");
} }
throw new CloudRuntimeException(msg);
} }
try { try {
@ -242,6 +245,7 @@ public class HypervisorHostHelper {
msg = "Failed to associate policy map " + policyName + " with port profile " + networkName msg = "Failed to associate policy map " + policyName + " with port profile " + networkName
+ ". Exception: " + e.toString(); + ". Exception: " + e.toString();
s_logger.error(msg); s_logger.error(msg);
throw new CloudRuntimeException(msg);
} finally { } finally {
if (netconfClient != null) { if (netconfClient != null) {
netconfClient.disconnect(); netconfClient.disconnect();
@ -301,6 +305,7 @@ public class HypervisorHostHelper {
netconfClient.disconnect(); netconfClient.disconnect();
s_logger.debug("Disconnected Nexus 1000v session."); s_logger.debug("Disconnected Nexus 1000v session.");
} }
throw new CloudRuntimeException(msg);
} }
try { try {
@ -315,6 +320,7 @@ public class HypervisorHostHelper {
netconfClient.disconnect(); netconfClient.disconnect();
s_logger.debug("Disconnected Nexus 1000v session."); s_logger.debug("Disconnected Nexus 1000v session.");
} }
throw new CloudRuntimeException(msg);
} }
} }
} }
@ -352,6 +358,7 @@ public class HypervisorHostHelper {
netconfClient.disconnect(); netconfClient.disconnect();
s_logger.debug("Disconnected Nexus 1000v session."); s_logger.debug("Disconnected Nexus 1000v session.");
} }
throw new CloudRuntimeException(msg);
} }
try { try {
@ -364,6 +371,7 @@ public class HypervisorHostHelper {
netconfClient.disconnect(); netconfClient.disconnect();
s_logger.debug("Disconnected Nexus 1000v session."); s_logger.debug("Disconnected Nexus 1000v session.");
} }
throw new CloudRuntimeException(msg);
} }
} }