CLOUDSTACK-301 Nexus 1000v DVS integration is not functional

Moved validateVSMCluster method from CiscoNexusVSMDeviceManagerImpl to CiscoNexusVSMElement.

Signed-off-by: Sateesh Chodapuneedi <sateesh@apache.org>
This commit is contained in:
Sateesh Chodapuneedi 2013-03-20 04:44:59 +05:30
parent 3d8afb0cfb
commit 009749fb79
4 changed files with 122 additions and 98 deletions

View File

@ -45,6 +45,7 @@ import com.cloud.dc.dao.DataCenterDao;
import com.cloud.exception.DiscoveredWithErrorException;
import com.cloud.exception.DiscoveryException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.ResourceInUseException;
import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao;
import com.cloud.hypervisor.Hypervisor;
@ -62,6 +63,8 @@ import com.cloud.network.Networks.TrafficType;
import com.cloud.network.PhysicalNetwork;
import com.cloud.network.VmwareTrafficLabel;
import com.cloud.network.dao.CiscoNexusVSMDeviceDao;
import com.cloud.network.element.CiscoNexusVSMElement;
import com.cloud.network.element.CiscoNexusVSMElementService;
import com.cloud.resource.Discoverer;
import com.cloud.resource.DiscovererBase;
import com.cloud.resource.ResourceManager;
@ -104,6 +107,8 @@ public class VmwareServerDiscoverer extends DiscovererBase implements
@Inject
CiscoNexusVSMDeviceDao _nexusDao;
@Inject
CiscoNexusVSMElementService _nexusElement;
@Inject
NetworkModel _netmgr;
@Inject
HypervisorCapabilitiesDao _hvCapabilitiesDao;
@ -255,7 +260,17 @@ public class VmwareServerDiscoverer extends DiscovererBase implements
guestTrafficLabel = _netmgr.getDefaultGuestTrafficLabel(dcId, HypervisorType.VMware);
if (guestTrafficLabel != null) {
s_logger.info("Detected guest network label : " + guestTrafficLabel);
}
}
String vsmIp = _urlParams.get("vsmipaddress");
String vsmUser = _urlParams.get("vsmusername");
String vsmPassword = _urlParams.get("vsmpassword");
String clusterName = cluster.getName();
try {
_nexusElement.validateVsmCluster(vsmIp, vsmUser, vsmPassword, clusterId, clusterName);
} catch(ResourceInUseException ex) {
DiscoveryException discEx = new DiscoveryException(ex.getLocalizedMessage() + ". The resource is " + ex.getResourceName());
throw discEx;
}
vsmCredentials = _vmwareMgr.getNexusVSMCredentialsByClusterId(clusterId);
}

View File

@ -23,8 +23,6 @@ import javax.inject.Inject;
import org.apache.log4j.Logger;
import com.cloud.agent.api.StartupCommand;
import com.cloud.configuration.Config;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.dc.ClusterDetailsDao;
import com.cloud.dc.ClusterVO;
import com.cloud.dc.ClusterVSMMapVO;
@ -64,8 +62,6 @@ public abstract class CiscoNexusVSMDeviceManagerImpl extends AdapterBase {
HostDetailsDao _hostDetailDao;
@Inject
PortProfileDao _ppDao;
@Inject
ConfigurationDao _configDao;
private static final org.apache.log4j.Logger s_logger = Logger.getLogger(ExternalLoadBalancerDeviceManagerImpl.class);
@ -315,96 +311,4 @@ public abstract class CiscoNexusVSMDeviceManagerImpl extends AdapterBase {
// TODO Auto-generated method stub
return null;
}
@DB
public boolean vliadateVsmCluster(String vsmIp, String vsmUser, String vsmPassword, long clusterId, String clusterName) throws ResourceInUseException {
// Check if we're associating a Cisco Nexus VSM with a vmware cluster.
if (Boolean.parseBoolean(_configDao.getValue(Config.VmwareUseNexusVSwitch.toString()))) {
if(vsmIp != null && vsmUser != null && vsmPassword != null) {
NetconfHelper netconfClient;
try {
netconfClient = new NetconfHelper(vsmIp, vsmUser, vsmPassword);
netconfClient.disconnect();
} catch (CloudRuntimeException e) {
String msg = "Invalid credentials supplied for user " + vsmUser + " for Cisco Nexus 1000v VSM at " + vsmIp;
s_logger.error(msg);
_clusterDao.remove(clusterId);
throw new CloudRuntimeException(msg);
}
Transaction txn;
// If VSM already exists and is mapped to a cluster, fail this operation.
CiscoNexusVSMDeviceVO vsm = _ciscoNexusVSMDeviceDao.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");
// get clusterUuid to report error
ClusterVO cluster = _clusterDao.findById(clusterList.get(0).getClusterId());
ex.addProxyObject(cluster.getUuid());
throw ex;
}
}
// persist credentials to database if the VSM entry is not already in the db.
if (_ciscoNexusVSMDeviceDao.getVSMbyIpaddress(vsmIp) == null) {
vsm = new CiscoNexusVSMDeviceVO(vsmIp, vsmUser, vsmPassword);
txn = Transaction.currentTxn();
try {
txn.start();
vsm = _ciscoNexusVSMDeviceDao.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 = _ciscoNexusVSMDeviceDao.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;
msg = "The global parameter " + Config.VmwareUseNexusVSwitch.toString() +
" is set to \"true\". Following mandatory parameters are not specified. ";
if(vsmIp == null) {
msg += "vsmipaddress: Management IP address of Cisco Nexus 1000v dvSwitch. ";
}
if(vsmUser == null) {
msg += "vsmusername: Name of a user account with admin privileges over Cisco Nexus 1000v dvSwitch. ";
}
if(vsmPassword == null) {
if(vsmUser != null) {
msg += "vsmpassword: Password of user account " + vsmUser + ". ";
} else {
msg += "vsmpassword: Password of user account with admin privileges over Cisco Nexus 1000v dvSwitch. ";
}
}
s_logger.error(msg);
// Cleaning up the cluster record as addCluster operation failed because Nexus dvSwitch credentials are supplied.
_clusterDao.remove(clusterId);
throw new CloudRuntimeException(msg);
}
return true;
}
return false;
}
}

View File

@ -34,6 +34,11 @@ import com.cloud.api.commands.EnableCiscoNexusVSMCmd;
import com.cloud.api.commands.DisableCiscoNexusVSMCmd;
import com.cloud.api.commands.ListCiscoNexusVSMsCmd;
import com.cloud.api.response.CiscoNexusVSMResponse;
import com.cloud.configuration.Config;
import com.cloud.dc.ClusterVO;
import com.cloud.dc.ClusterVSMMapVO;
import com.cloud.dc.dao.ClusterDao;
import com.cloud.dc.dao.ClusterVSMMapDao;
import com.cloud.deploy.DeployDestination;
import com.cloud.event.ActionEvent;
import com.cloud.event.EventTypes;
@ -55,7 +60,10 @@ import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineProfile;
import com.cloud.offering.NetworkOffering;
import com.cloud.org.Cluster;
import com.cloud.utils.cisco.n1kv.vsm.NetconfHelper;
import com.cloud.utils.component.Manager;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.Transaction;
import com.cloud.exception.ResourceInUseException;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.server.ManagementService;
@ -66,7 +74,11 @@ public class CiscoNexusVSMElement extends CiscoNexusVSMDeviceManagerImpl impleme
private static final Logger s_logger = Logger.getLogger(CiscoNexusVSMElement.class);
@Inject
CiscoNexusVSMDeviceDao _vsmDao;
CiscoNexusVSMDeviceDao _vsmDao;
@Inject
ClusterDao _clusterDao;
@Inject
ClusterVSMMapDao _clusterVSMDao;
@Override
public Map<Service, Map<Capability, String>> getCapabilities() {
@ -247,4 +259,90 @@ public class CiscoNexusVSMElement extends CiscoNexusVSMDeviceManagerImpl impleme
cmdList.add(DeleteCiscoNexusVSMCmd.class);
return cmdList;
}
@DB
public boolean validateVsmCluster(String vsmIp, String vsmUser, String vsmPassword, long clusterId, String clusterName) throws ResourceInUseException {
if(vsmIp != null && vsmUser != null && vsmPassword != null) {
NetconfHelper netconfClient;
try {
netconfClient = new NetconfHelper(vsmIp, vsmUser, vsmPassword);
netconfClient.disconnect();
} catch (CloudRuntimeException e) {
String msg = "Invalid credentials supplied for user " + vsmUser + " for Cisco Nexus 1000v VSM at " + vsmIp;
s_logger.error(msg);
_clusterDao.remove(clusterId);
throw new CloudRuntimeException(msg);
}
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");
ResourceInUseException ex = new ResourceInUseException("Failed to add cluster: specified Nexus VSM is already associated with another cluster with specified Id");
// get clusterUuid to report error
ClusterVO cluster = _clusterDao.findById(clusterList.get(0).getClusterId());
ex.addProxyObject(cluster.getUuid());
_clusterDao.remove(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());
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());
_vsmDao.remove(vsm.getId()); // Removing VSM from virtual_supervisor_module table because association with cluster failed.
// Cluster would be deleted from cluster table by callee.
throw new CloudRuntimeException(e.getMessage());
}
}
} else {
String msg;
msg = "The global parameter " + Config.VmwareUseNexusVSwitch.toString() +
" is set to \"true\". Following mandatory parameters are not specified. ";
if(vsmIp == null) {
msg += "vsmipaddress: Management IP address of Cisco Nexus 1000v dvSwitch. ";
}
if(vsmUser == null) {
msg += "vsmusername: Name of a user account with admin privileges over Cisco Nexus 1000v dvSwitch. ";
}
if(vsmPassword == null) {
if(vsmUser != null) {
msg += "vsmpassword: Password of user account " + vsmUser + ". ";
} else {
msg += "vsmpassword: Password of user account with admin privileges over Cisco Nexus 1000v dvSwitch. ";
}
}
s_logger.error(msg);
// Cleaning up the cluster record as addCluster operation failed because of invalid credentials of Nexus dvSwitch.
_clusterDao.remove(clusterId);
throw new CloudRuntimeException(msg);
}
return true;
}
}

View File

@ -24,6 +24,7 @@ import com.cloud.api.commands.EnableCiscoNexusVSMCmd;
import com.cloud.api.commands.DisableCiscoNexusVSMCmd;
import com.cloud.api.commands.ListCiscoNexusVSMsCmd;
import com.cloud.api.response.CiscoNexusVSMResponse;
import com.cloud.exception.ResourceInUseException;
import com.cloud.network.CiscoNexusVSMDeviceVO;
import com.cloud.network.CiscoNexusVSMDevice;
import com.cloud.utils.component.PluggableService;
@ -68,4 +69,10 @@ public interface CiscoNexusVSMElementService extends PluggableService {
* @return CiscoNexusVSMResponse
*/
public CiscoNexusVSMResponse createCiscoNexusVSMDetailedResponse(CiscoNexusVSMDevice vsmDeviceVO);
/**
* Validate Cisco Nexus VSM before associating with cluster
*
*/
public boolean validateVsmCluster(String vsmIp, String vsmUser, String vsmPassword, long clusterId, String clusterName) throws ResourceInUseException;
}