Bug CS-9919: Support for Nexus Swiches (Cisco Vswitches)

Description:

        1. Changed AddCiscoNexusVSMCmd to:
             a. Extend BaseCmd instead of BaseAsyncCmd.
             b. Take in more required parameters (viz
                vCenterDCName and vCenterIpAddress)

        1a. Changed DeleteCiscoNexusVSMCmd to also
            extend BaseCmd.

        2. Put in changes that will ensure that
           When a VSM is added, it is disabled by default.

        3. Fixed code that was leading to exceptions
           related to DB reads/writes to VSM related tables.

        4. Added new API Constants in ApiConstants.java.
           NOTE - Always initialize new attributes in
           ApiConstants.java to values in small case.
           Never put in upper case there. Also regardless
           of what names you give attributes in the
           *Cmd.java's class, you pass in parameters via
           API calls by specifying <key>=<value> where the
           <key> is taken from the value you specified in
           ApiConstants.java.

        5. Modified the addCiscoNexusVSM() function in
           CiscoNexusVSMDeviceManagerImpl.java to write VSM
           records to the db.
This commit is contained in:
Vijayendra Bhamidipati 2012-05-07 18:17:55 -07:00
parent 441a811927
commit 037ac6592e
10 changed files with 90 additions and 87 deletions

View File

@ -340,6 +340,9 @@ public class ApiConstants {
public static final String EXTERNAL_SWITCH_MGMT_DEVICE_STATE = "vsmdevicestate";
// Would we need to have a capacity field for Cisco N1KV VSM? Max hosts managed by it perhaps? May remove this later.
public static final String EXTERNAL_SWITCH_MGMT_DEVICE_CAPACITY = "vsmdevicecapacity";
public static final String VCENTER_IP_ADDRESS = "vcenteripaddr";
public static final String VCENTER_DC_NAME = "vcenterdcname";
public static final String CISCO_NEXUS_VSM_NAME = "vsmname";
public enum HostDetails {
all, capacity, events, stats, min;

View File

@ -47,7 +47,7 @@ public class CiscoNexusVSMResponse extends BaseResponse {
//private String privateInterface;
@SerializedName(ApiConstants.IP_ADDRESS) @Param(description="the management IP address of the external Cisco Nexus 1000v Virtual Supervisor Module")
private String mgmtIpAddress;
private String vsmmgmtIpAddress;
public void setId(long vsmDeviceId) {
this.id.setValue(vsmDeviceId);
@ -58,6 +58,6 @@ public class CiscoNexusVSMResponse extends BaseResponse {
}
public void setMgmtIpAddress(String ipAddress) {
this.mgmtIpAddress = ipAddress;
this.vsmmgmtIpAddress = ipAddress;
}
}

View File

@ -12,25 +12,10 @@
package com.cloud.network.resource;
import java.util.Map;
import javax.naming.ConfigurationException;
import com.cloud.agent.IAgentControl;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.PingCommand;
import com.cloud.agent.api.StartupCommand;
import com.cloud.agent.api.StartupExternalLoadBalancerCommand;
import com.cloud.api.ApiConstants;
import com.cloud.host.Host;
import com.cloud.host.Host.Type;
import com.cloud.resource.ServerResource;
import com.cloud.serializer.GsonHelper;
import com.cloud.utils.NumbersUtil;
import com.google.gson.Gson;
import com.cloud.utils.cisco.n1kv.vsm.NetconfHelper;
import com.cloud.utils.ssh.*;
import com.cloud.utils.cisco.n1kv.vsm.CiscoNexusVSMService;
import com.cloud.utils.exception.CloudRuntimeException;
import org.apache.log4j.Logger;

View File

@ -40,7 +40,7 @@ import com.cloud.user.UserContext;
import com.cloud.utils.exception.CloudRuntimeException;
@Implementation(responseObject=CiscoNexusVSMResponse.class, description="Adds a Cisco Nexus 1000v Virtual Switch Manager device")
public class AddCiscoNexusVSMCmd extends BaseAsyncCmd {
public class AddCiscoNexusVSMCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(AddCiscoNexusVSMCmd.class.getName());
private static final String s_name = "addciscon1kvvsmresponse";
@ -50,12 +50,12 @@ public class AddCiscoNexusVSMCmd extends BaseAsyncCmd {
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@IdentityMapper(entityTableName="virtual_supervisor_module")
@IdentityMapper(entityTableName="cluster")
@Parameter(name=ApiConstants.ID, type=CommandType.LONG, required = true, description="Id of the CloudStack cluster in which the Cisco Nexus 1000v VSM appliance.")
private long id;
@Parameter(name=ApiConstants.IP_ADDRESS, type=CommandType.STRING, required = true, description="IP Address of the Cisco Nexus 1000v VSM appliance.")
private String ipaddr;
@Parameter(name=ApiConstants.CLUSTER_ID, type=CommandType.LONG, required = true, description="Id of the CloudStack cluster in which the Cisco Nexus 1000v VSM appliance.")
private long clusterId;
private String ipaddress;
@Parameter(name=ApiConstants.USERNAME, type=CommandType.STRING, required = true, description="username to reach the Cisco Nexus 1000v VSM device")
private String username;
@ -63,7 +63,13 @@ public class AddCiscoNexusVSMCmd extends BaseAsyncCmd {
@Parameter(name=ApiConstants.PASSWORD, type=CommandType.STRING, required = true, description="password to reach the Cisco Nexus 1000v VSM device")
private String password;
@Parameter(name=ApiConstants.NAME, type=CommandType.STRING, required = false, description="name of Cisco Nexus 1000v VSM device")
@Parameter(name=ApiConstants.VCENTER_IP_ADDRESS, type=CommandType.STRING, required = true, description="IP Address of the VMWare vCenter the VSM connects to")
private String vcenteripaddr;
@Parameter(name=ApiConstants.VCENTER_DC_NAME, type=CommandType.STRING, required = true, description="Name of the DataCenter the VSM monitors")
private String vcenterdcName;
@Parameter(name=ApiConstants.CISCO_NEXUS_VSM_NAME, type=CommandType.STRING, required = false, description="Name of the VSM")
private String vsmName;
/////////////////////////////////////////////////////
@ -71,7 +77,7 @@ public class AddCiscoNexusVSMCmd extends BaseAsyncCmd {
/////////////////////////////////////////////////////
public String getIpAddr() {
return ipaddr;
return ipaddress;
}
public String getUsername() {
@ -82,12 +88,20 @@ public class AddCiscoNexusVSMCmd extends BaseAsyncCmd {
return password;
}
public String getVSMName() {
return vsmName;
public String getvCenterIpaddr() {
return vcenteripaddr;
}
public String getvCenterDcName() {
return vcenterdcName;
}
public long getClusterId() {
return clusterId;
return id;
}
public String getvsmName() {
return vsmName;
}
/////////////////////////////////////////////////////
@ -116,15 +130,15 @@ public class AddCiscoNexusVSMCmd extends BaseAsyncCmd {
}
}
@Override
public String getEventDescription() {
return "Adding a Cisco Nexus VSM device";
}
//@Override
//public String getEventDescription() {
// return "Adding a Cisco Nexus VSM device";
//}
@Override
public String getEventType() {
return EventTypes.EVENT_EXTERNAL_SWITCH_MGMT_DEVICE_ADD;
}
//@Override
//public String getEventType() {
// return EventTypes.EVENT_EXTERNAL_SWITCH_MGMT_DEVICE_ADD;
//}
@Override
public String getCommandName() {

View File

@ -40,7 +40,7 @@ import com.cloud.user.UserContext;
import com.cloud.utils.exception.CloudRuntimeException;
@Implementation(responseObject=SuccessResponse.class, description=" delete a Cisco Nexus VSM device")
public class DeleteCiscoNexusVSMCmd extends BaseAsyncCmd {
public class DeleteCiscoNexusVSMCmd extends BaseCmd {
public static final Logger s_logger = Logger.getLogger(DeleteCiscoNexusVSMCmd.class.getName());
private static final String s_name = "deletecisconexusvsmresponse";

View File

@ -156,14 +156,19 @@ public abstract class CiscoNexusVSMDeviceManagerImpl extends AdapterBase {
@DB
//public CiscoNexusVSMDeviceVO addCiscoNexusVSM(long clusterId, String ipaddress, String username, String password, ServerResource resource, String vsmName) {
public CiscoNexusVSMDeviceVO addCiscoNexusVSM(long clusterId, String ipaddress, String username, String password, String vsmName) {
public CiscoNexusVSMDeviceVO addCiscoNexusVSM(long clusterId, String ipaddress, String username, String password, String vCenterIpaddr, String vCenterDcName) {
// In this function, we associate this VSM with each host
// in the clusterId specified.
// First check if the cluster is of type vmware. If not,
// throw an exception. VSMs are tightly integrated with vmware clusters.
s_logger.info("in addCiscoNexuVSM, clusterId is --> " + clusterId + ", ipaddress is --> " + ipaddress + ", username --> " + username + ", pwd --> " + password + ", vcenterip --> " + vCenterIpaddr + ", vCenterdcName --> " + vCenterDcName);
ClusterVO cluster = _clusterDao.findById(clusterId);
if (cluster == null) {
throw new InvalidParameterValueException("Cluster with specified ID not found!");
}
if (cluster.getHypervisorType() != HypervisorType.VMware) {
InvalidParameterValueException ex = new InvalidParameterValueException("Cluster with specified id is not a VMWare hypervisor cluster");
throw ex;
@ -182,6 +187,8 @@ public abstract class CiscoNexusVSMDeviceManagerImpl extends AdapterBase {
// Next, check if this VSM is reachable. Use the XML-RPC VSM API Java bindings to talk to
// the VSM.
//NetconfHelper (String ip, String username, String password)
CiscoNexusVSM vsmObj = new CiscoNexusVSM(ipaddress, username, password);
if (!vsmObj.connectToVSM()) {
throw new CloudRuntimeException("Couldn't login to the specified VSM");
@ -197,11 +204,19 @@ public abstract class CiscoNexusVSMDeviceManagerImpl extends AdapterBase {
// advantage of our approach for now is that existing infrastructure using
// the existing VSM won't be affected if the new request to add the VSM
// assumed different information on the VSM (mgmt vlan, username, password etc).
CiscoNexusVSMDeviceVO VSMObj = _ciscoNexusVSMDeviceDao.getVSMbyIpaddress(ipaddress);
CiscoNexusVSMDeviceVO VSMObj;
try {
VSMObj = _ciscoNexusVSMDeviceDao.getVSMbyIpaddress(ipaddress);
} catch (Exception e) {
throw new CloudRuntimeException(e.getMessage());
}
//CiscoNexusVSMDeviceVO VSMObj = _ciscoNexusVSMDeviceDao.getVSMbyDomainId(1);
if (VSMObj == null) {
s_logger.info("no record found.. will create one");
// Create the VSM record. For now, we aren't using the vsmName field.
VSMObj = new CiscoNexusVSMDeviceVO(ipaddress, username, password);
VSMObj = new CiscoNexusVSMDeviceVO(ipaddress, username, password, vCenterIpaddr, vCenterDcName);
Transaction txn = Transaction.currentTxn();
try {
txn.start();
@ -239,6 +254,7 @@ public abstract class CiscoNexusVSMDeviceManagerImpl extends AdapterBase {
// entries in the database to contain this VSM information before the injection.
for (HostVO host : hosts) {
s_logger.info("inside for loop!");
// Create a host details VO object and write it out for this hostid.
long vsmId = _ciscoNexusVSMDeviceDao.getVSMbyIpaddress(ipaddress).getId();
Long hostid = new Long(vsmId);

View File

@ -61,8 +61,8 @@ public class CiscoNexusVSMDeviceVO {
@Column(name = "password")
private String vsmPassword;
@Column(name = "vmsmgmtipaddr")
private String vsmMgmtIPAddr;
@Column(name = "ipaddr")
private String ipaddr;
@Column(name = "vcenteripaddr")
private String vCenterIPAddr;
@ -94,27 +94,6 @@ public class CiscoNexusVSMDeviceVO {
@Column(name = "vsmDeviceState")
private VSMDeviceState vsmDeviceState;
// ********** The ones below could be removed...
// Id of the DataCenter (as seen in vCenter) that this VSM manages.
// We can probably remove this.
@Column(name = "vcenteredcid")
private long vCenterDCId;
// Name of the DVS that gets created on vCenter to represent this VSM.
// Can be queried and hence can be most probably removed.
@Column(name = "dvsname")
private String dvsName;
// Number of VEMs being currently managed by this VSM.
// Again, queriable/removable.
@Column(name = "num_of_vems")
private int numVEMS;
// ******** End of removable candidates.
// This tells us whether the VSM is currently enabled or disabled. We may
// need this if we would like to carry out any sort of maintenance on the
@ -158,8 +137,8 @@ public class CiscoNexusVSMDeviceVO {
return vsmPassword;
}
public String getMgmtIpAddr() {
return vsmMgmtIPAddr;
public String getipaddr() {
return ipaddr;
}
public String getvCenterIPAddr() {
@ -212,20 +191,20 @@ public class CiscoNexusVSMDeviceVO {
this.hostId = hostid;
}
public void getUserName(String username) {
public void setVsmUserName(String username) {
this.vsmUserName = username;
}
public void setvsmName(String vsmName) {
public void setVsmName(String vsmName) {
this.vsmName = vsmName;
}
public void setPassword(String password) {
public void setVsmPassword(String password) {
this.vsmPassword = password;
}
public void setMgmtIpAddr(String ipaddr) {
this.vsmMgmtIPAddr = ipaddr;
this.ipaddr = ipaddr;
}
public void setvCenterIPAddr(String ipaddr) {
@ -252,37 +231,39 @@ public class CiscoNexusVSMDeviceVO {
this.storageVlan = vlan;
}
public void setvsmDomainId(long id) {
public void setVsmDomainId(long id) {
this.vsmDomainId = id;
}
public void setvsmConfigMode(VSMConfigMode mode) {
public void setVsmConfigMode(VSMConfigMode mode) {
this.vsmConfigMode = mode;
}
public void setvsmConfigState(VSMConfigState state) {
public void setVsmConfigState(VSMConfigState state) {
this.vsmConfigState = state;
}
public void setvsmDeviceState(VSMDeviceState devState) {
public void setVsmDeviceState(VSMDeviceState devState) {
this.vsmDeviceState = devState;
}
// Constructor methods.
public CiscoNexusVSMDeviceVO(String vsmIpAddr, String username, String password) {
public CiscoNexusVSMDeviceVO(String vsmIpAddr, String username, String password, String vCenterIpaddr, String vCenterDcName) {
// Set all the VSM's properties here.
this.uuid = UUID.randomUUID().toString();
this.vsmMgmtIPAddr = vsmIpAddr;
this.vsmUserName = username;
this.vsmPassword = password;
this.setMgmtIpAddr(vsmIpAddr);
this.setVsmUserName(username);
this.setVsmPassword(password);
this.setvCenterIPAddr(vCenterIpaddr);
this.setvCenterDCName(vCenterDcName);
}
public CiscoNexusVSMDeviceVO(String vsmIpAddr, String username, String password, String vsmName) {
public CiscoNexusVSMDeviceVO(String vsmIpAddr, String username, String password, long dummy) {
// Set all the VSM's properties here.
this.uuid = UUID.randomUUID().toString();
this.vsmMgmtIPAddr = vsmIpAddr;
this.ipaddr = vsmIpAddr;
this.vsmUserName = username;
this.vsmPassword = password;
this.vsmName = vsmName;

View File

@ -15,6 +15,8 @@ package com.cloud.network.dao;
import java.util.List;
import javax.ejb.Local;
import org.apache.log4j.Logger;
import com.cloud.network.CiscoNexusVSMDeviceVO;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.GenericDaoBase;
@ -24,6 +26,7 @@ import com.cloud.utils.db.SearchCriteria.Op;
@Local(value=CiscoNexusVSMDeviceDao.class) @DB(txn=false)
public class CiscoNexusVSMDeviceDaoImpl extends GenericDaoBase<CiscoNexusVSMDeviceVO, Long> implements CiscoNexusVSMDeviceDao {
protected static final Logger s_logger = Logger.getLogger(CiscoNexusVSMDeviceDaoImpl.class);
final SearchBuilder<CiscoNexusVSMDeviceVO> mgmtVlanIdSearch;
final SearchBuilder<CiscoNexusVSMDeviceVO> domainIdSearch;
final SearchBuilder<CiscoNexusVSMDeviceVO> nameSearch;
@ -32,7 +35,7 @@ public class CiscoNexusVSMDeviceDaoImpl extends GenericDaoBase<CiscoNexusVSMDevi
// We will add more searchbuilder objects.
public CiscoNexusVSMDeviceDaoImpl() {
public CiscoNexusVSMDeviceDaoImpl() {
super();
mgmtVlanIdSearch = createSearchBuilder();
@ -55,7 +58,7 @@ public class CiscoNexusVSMDeviceDaoImpl extends GenericDaoBase<CiscoNexusVSMDevi
nameSearch.done();
ipaddrSearch = createSearchBuilder();
ipaddrSearch.and("vsmMgmtIPAddr", ipaddrSearch.entity().getvsmName(), Op.EQ);
ipaddrSearch.and("ipaddr", ipaddrSearch.entity().getipaddr(), Op.EQ);
ipaddrSearch.done();
// We may add more and conditions by specifying more fields, like say, accountId.
@ -75,7 +78,7 @@ public class CiscoNexusVSMDeviceDaoImpl extends GenericDaoBase<CiscoNexusVSMDevi
public CiscoNexusVSMDeviceVO getVSMbyIpaddress(String ipaddress) {
SearchCriteria<CiscoNexusVSMDeviceVO> sc = ipaddrSearch.create();
sc.setParameters("vsmMgmtIPAddr", ipaddress);
sc.setParameters("ipaddr", ipaddress);
return findOneBy(sc);
}

View File

@ -172,14 +172,15 @@ public class CiscoNexusVSMElement extends CiscoNexusVSMDeviceManagerImpl impleme
String vsmipaddress = cmd.getIpAddr();
String vsmusername = cmd.getUsername();
String vsmpassword = cmd.getPassword();
String vsmName = cmd.getVSMName();
String vCenterIpaddr = cmd.getvCenterIpaddr();
String vCenterDcName = cmd.getvCenterDcName();
long clusterId = cmd.getClusterId();
// Invoke the addCiscoNexusVSM() function defined in the upper layer (DeviceMgrImpl).
// The upper layer function will create a resource of type "host" to represent this VSM.
// It will add this VSM to the db.
//CiscoNexusVSMDeviceVO vsmDeviceVO = addCiscoNexusVSM(clusterId, vsmipaddress, vsmusername, vsmpassword, (ServerResource) new CiscoNexusVSMResource(), vsmName);
CiscoNexusVSMDeviceVO vsmDeviceVO = addCiscoNexusVSM(clusterId, vsmipaddress, vsmusername, vsmpassword, vsmName);
CiscoNexusVSMDeviceVO vsmDeviceVO = addCiscoNexusVSM(clusterId, vsmipaddress, vsmusername, vsmpassword, vCenterIpaddr, vCenterDcName);
return vsmDeviceVO;
}
@ -222,7 +223,7 @@ public class CiscoNexusVSMElement extends CiscoNexusVSMDeviceManagerImpl impleme
public CiscoNexusVSMResponse createCiscoNexusVSMResponse(CiscoNexusVSMDeviceVO vsmDeviceVO) {
CiscoNexusVSMResponse response = new CiscoNexusVSMResponse();
response.setId(vsmDeviceVO.getId());
response.setMgmtIpAddress(vsmDeviceVO.getMgmtIpAddr());
response.setMgmtIpAddress(vsmDeviceVO.getipaddr());
return response;
}

View File

@ -2095,7 +2095,7 @@ CREATE TABLE `cloud`.`virtual_supervisor_module` (
`vsm_name` varchar(255),
`username` varchar(255) NOT NULL,
`password` varchar(255) NOT NULL,
`vsmmgmtipaddr` varchar(80) NOT NULL,
`ipaddr` varchar(80) NOT NULL,
`vcenteripaddr` varchar(80) NOT NULL,
`vcenterdcname` varchar(255) NOT NULL,
`management_vlan` int(32),