From c65199cd8cd7c68c0c8da163b1656292fabd3301 Mon Sep 17 00:00:00 2001 From: Sateesh Chodapuneedi Date: Tue, 15 May 2012 21:53:36 +0530 Subject: [PATCH] CS-9919 Support for Nexus Swiches (Cisco Vswitches) Added VSM credentials to AddClusterCmd(optonal params only). Cleanup. Conflicts: api/src/com/cloud/api/commands/AddClusterCmd.java --- api/src/com/cloud/api/ApiConstants.java | 3 + .../com/cloud/api/commands/AddClusterCmd.java | 215 ++++++++++-------- .../vmware/resource/VmwareResource.java | 19 +- .../hypervisor/vmware/VmwareManagerImpl.java | 48 ++-- .../cloud/resource/ResourceManagerImpl.java | 54 ++++- .../vmware/mo/HypervisorHostHelper.java | 2 +- 6 files changed, 215 insertions(+), 126 deletions(-) diff --git a/api/src/com/cloud/api/ApiConstants.java b/api/src/com/cloud/api/ApiConstants.java index 0dc1b364ad8..300c5c15add 100755 --- a/api/src/com/cloud/api/ApiConstants.java +++ b/api/src/com/cloud/api/ApiConstants.java @@ -343,6 +343,9 @@ public class ApiConstants { 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 static final String VSM_USERNAME = "vsmusername"; + public static final String VSM_PASSWORD = "vsmpassword"; + public static final String VSM_IPADDRESS = "vsmipaddress"; public enum HostDetails { all, capacity, events, stats, min; diff --git a/api/src/com/cloud/api/commands/AddClusterCmd.java b/api/src/com/cloud/api/commands/AddClusterCmd.java index c718b195f96..28b38abedad 100755 --- a/api/src/com/cloud/api/commands/AddClusterCmd.java +++ b/api/src/com/cloud/api/commands/AddClusterCmd.java @@ -10,7 +10,8 @@ // limitations under the License. // // Automatically generated by addcopyright.py at 04/03/2012 -package com.cloud.api.commands; + +package com.cloud.api.commands; import java.util.ArrayList; import java.util.List; @@ -28,18 +29,18 @@ import com.cloud.api.response.ListResponse; import com.cloud.exception.DiscoveryException; import com.cloud.org.Cluster; import com.cloud.user.Account; - -@Implementation(description="Adds a new cluster", responseObject=ClusterResponse.class) -public class AddClusterCmd extends BaseCmd { - public static final Logger s_logger = Logger.getLogger(AddClusterCmd.class.getName()); - - private static final String s_name = "addclusterresponse"; - - @Parameter(name=ApiConstants.CLUSTER_NAME, type=CommandType.STRING, required=true, description="the cluster name") - private String clusterName; - - @Parameter(name=ApiConstants.PASSWORD, type=CommandType.STRING, required=false, description="the password for the host") - private String password; + +@Implementation(description="Adds a new cluster", responseObject=ClusterResponse.class) +public class AddClusterCmd extends BaseCmd { + public static final Logger s_logger = Logger.getLogger(AddClusterCmd.class.getName()); + + private static final String s_name = "addclusterresponse"; + + @Parameter(name=ApiConstants.CLUSTER_NAME, type=CommandType.STRING, required=true, description="the cluster name") + private String clusterName; + + @Parameter(name=ApiConstants.PASSWORD, type=CommandType.STRING, required=false, description="the password for the host") + private String password; @IdentityMapper(entityTableName="host_pod_ref") @Parameter(name=ApiConstants.POD_ID, type=CommandType.LONG, required=true, description="the Pod ID for the host") @@ -52,94 +53,116 @@ public class AddClusterCmd extends BaseCmd { private String username; @IdentityMapper(entityTableName="data_center") - @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.LONG, required=true, description="the Zone ID for the cluster") - private Long zoneId; - - @Parameter(name=ApiConstants.HYPERVISOR, type=CommandType.STRING, required=true, description="hypervisor type of the cluster: XenServer,KVM,VMware,Hyperv,BareMetal,Simulator") - private String hypervisor; - - @Parameter(name=ApiConstants.CLUSTER_TYPE, type=CommandType.STRING, required=true, description="type of the cluster: CloudManaged, ExternalManaged") - private String clusterType; - - @Parameter(name=ApiConstants.ALLOCATION_STATE, type=CommandType.STRING, description="Allocation state of this cluster for allocation of new resources") + + @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.LONG, required=true, description="the Zone ID for the cluster") + private Long zoneId; + + @Parameter(name=ApiConstants.HYPERVISOR, type=CommandType.STRING, required=true, description="hypervisor type of the cluster: XenServer,KVM,VMware,Hyperv,BareMetal,Simulator") + private String hypervisor; + + @Parameter(name=ApiConstants.CLUSTER_TYPE, type=CommandType.STRING, required=true, description="type of the cluster: CloudManaged, ExternalManaged") + private String clusterType; + + @Parameter(name=ApiConstants.ALLOCATION_STATE, type=CommandType.STRING, description="Allocation state of this cluster for allocation of new resources") private String allocationState; - public String getClusterName() { - return clusterName; + @Parameter(name = ApiConstants.VSM_USERNAME, type = CommandType.STRING, required = false, description = "the username for the VSM associated with this cluster") + private String vsmusername; + + @Parameter(name = ApiConstants.VSM_PASSWORD, type = CommandType.STRING, required = false, description = "the password for the VSM associated with this cluster") + private String vsmpassword; + + @Parameter(name = ApiConstants.VSM_IPADDRESS, type = CommandType.STRING, required = false, description = "the ipaddress of the VSM associated with this cluster") + private String vsmipaddress; + + public String getVSMIpaddress() { + return vsmipaddress; } - public String getPassword() { - return password; + public String getVSMPassword() { + return vsmpassword; } - public Long getPodId() { - return podId; - } - - public String getUrl() { - return url; - } - - public String getUsername() { - return username; - } - - public Long getZoneId() { - return zoneId; - } - - public String getHypervisor() { - return hypervisor; - } - - @Override - public String getCommandName() { - return s_name; - } - - public String getClusterType() { - return clusterType; - } - - public void setClusterType(String type) { - this.clusterType = type; - } - - @Override - public long getEntityOwnerId() { - return Account.ACCOUNT_ID_SYSTEM; - } - - public String getAllocationState() { - return allocationState; - } - - public void setAllocationState(String allocationState) { - this.allocationState = allocationState; - } - - @Override - public void execute(){ - try { - List result = _resourceService.discoverCluster(this); - ListResponse response = new ListResponse(); - List clusterResponses = new ArrayList(); - if (result != null) { - for (Cluster cluster : result) { - ClusterResponse clusterResponse = _responseGenerator.createClusterResponse(cluster, false); - clusterResponses.add(clusterResponse); - } - } else { - throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to add cluster"); - } - - response.setResponses(clusterResponses); - response.setResponseName(getCommandName()); - - this.setResponseObject(response); - } catch (DiscoveryException ex) { - s_logger.warn("Exception: ", ex); - throw new ServerApiException(BaseCmd.INTERNAL_ERROR, ex.getMessage()); - } + public String getVSMUsername() { + return vsmusername; } + + public String getClusterName() { + return clusterName; + } + + public String getPassword() { + return password; + } + + public Long getPodId() { + return podId; + } + + public String getUrl() { + return url; + } + + public String getUsername() { + return username; + } + + public Long getZoneId() { + return zoneId; + } + + public String getHypervisor() { + return hypervisor; + } + + @Override + public String getCommandName() { + return s_name; + } + + public String getClusterType() { + return clusterType; + } + + public void setClusterType(String type) { + this.clusterType = type; + } + + @Override + public long getEntityOwnerId() { + return Account.ACCOUNT_ID_SYSTEM; + } + + public String getAllocationState() { + return allocationState; + } + + public void setAllocationState(String allocationState) { + this.allocationState = allocationState; + } + + @Override + public void execute(){ + try { + List result = _resourceService.discoverCluster(this); + ListResponse response = new ListResponse(); + List clusterResponses = new ArrayList(); + if (result != null) { + for (Cluster cluster : result) { + ClusterResponse clusterResponse = _responseGenerator.createClusterResponse(cluster, false); + clusterResponses.add(clusterResponse); + } + } else { + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to add cluster"); + } + + response.setResponses(clusterResponses); + response.setResponseName(getCommandName()); + + this.setResponseObject(response); + } catch (DiscoveryException ex) { + s_logger.warn("Exception: ", ex); + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, ex.getMessage()); + } + } } diff --git a/core/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/core/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 07bbeb0a272..5a4d1ac3666 100755 --- a/core/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/core/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -1474,7 +1474,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } } - String switchUuid; + String dvSwitchUuid; ManagedObjectReference dcMor = hyperHost.getHyperHostDatacenter(); DatacenterMO dataCenterMo = new DatacenterMO(context, dcMor); @@ -1487,10 +1487,10 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa Pair networkInfo = prepareNetworkFromNicInfo(vmMo.getRunningHost(), nicTo); ManagedObjectReference dvsMor = dataCenterMo.getDvSwitchMor(networkInfo.first()); - switchUuid = dataCenterMo.getDvSwitchUuid(dvsMor); - s_logger.info("Preparing NIC device on dvSwitch : " + switchUuid); + dvSwitchUuid = dataCenterMo.getDvSwitchUuid(dvsMor); + s_logger.info("Preparing NIC device on dvSwitch : " + dvSwitchUuid); - nic = VmwareHelper.prepareNicDevice(vmMo, networkInfo.first(), nicDeviceType, networkInfo.second(), nicTo.getMac(), i, i + 1, true, true); + nic = VmwareHelper.prepareDvNicDevice(vmMo, networkInfo.first(), nicDeviceType, networkInfo.second(), dvSwitchUuid, nicTo.getMac(), i, i + 1, true, true); deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec(); deviceConfigSpecArray[i].setDevice(nic); deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.add); @@ -4034,7 +4034,16 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa _hostName = hostMo.getHyperHostName(); _privateNetworkVSwitchName = mgr.getPrivateVSwitchName(Long.parseLong(_dcId), HypervisorType.VMware); _publicNetworkVSwitchName = mgr.getPublicVSwitchName(Long.parseLong(_dcId), HypervisorType.VMware); - _guestNetworkVSwitchName = mgr.getGuestVSwitchName(Long.parseLong(_dcId), HypervisorType.VMware); + _guestNetworkVSwitchName = mgr.getGuestVSwitchName(Long.parseLong(_dcId), HypervisorType.VMware); + Map vsmCredentials; + if (mgr.getNexusVSwitchGlobalParameter()) { + vsmCredentials = mgr.getNexusVSMCredentials(_guid); + if (vsmCredentials != null) { + s_logger.info("Stocking credentials while configuring resource."); + context.registerStockObject("vsmcredentials", vsmCredentials); + } + } + } catch (Exception e) { s_logger.error("Unexpected Exception ", e); } diff --git a/server/src/com/cloud/hypervisor/vmware/VmwareManagerImpl.java b/server/src/com/cloud/hypervisor/vmware/VmwareManagerImpl.java index 24113bc4e27..ac90fb8ba7a 100755 --- a/server/src/com/cloud/hypervisor/vmware/VmwareManagerImpl.java +++ b/server/src/com/cloud/hypervisor/vmware/VmwareManagerImpl.java @@ -745,7 +745,7 @@ public class VmwareManagerImpl implements VmwareManager, VmwareStorageMount, Lis mountPoint = mount(uri.getHost() + ":" + uri.getPath(), _mountParent); if(mountPoint == null) { s_logger.error("Unable to create mount point for " + storageUrl); - throw new CloudRuntimeException("Unable to create mount point for " + storageUrl); + return "/mnt/sec"; // throw new CloudRuntimeException("Unable to create mount point for " + storageUrl); } _storageMounts.put(storageUrl, mountPoint); @@ -874,24 +874,19 @@ public class VmwareManagerImpl implements VmwareManager, VmwareStorageMount, Lis @DB public Map getNexusVSMCredentials(String hostGuid) { - CiscoNexusVSMDeviceVO nexusVSM = null; - ClusterVSMMapVO vsmMapVO = null; + s_logger.info("Reading credentials from DB."); HostVO host = _hostDao.findByGuid(hostGuid); - if (host != null) - vsmMapVO = _vsmMapDao.findByClusterId(host.getClusterId()); - if (vsmMapVO != null) - nexusVSM = _nexusDao.findById(vsmMapVO.getVsmId()); - Map nexusVSMCredentials = new HashMap(); - if (nexusVSM != null) { - nexusVSMCredentials.put("vsmip", nexusVSM.getipaddr()); - nexusVSMCredentials.put("vsmusername", nexusVSM.getUserName()); - nexusVSMCredentials.put("vsmpassword", nexusVSM.getPassword()); - } else { - nexusVSMCredentials.put("vsmip", "10.102.125.32"); - nexusVSMCredentials.put("vsmusername", "admin"); - nexusVSMCredentials.put("vsmpassword", "vCenter!9"); + Map vsmCredentials = null; + long clusterId; + if (host != null) { + clusterId = host.getClusterId(); + s_logger.info("cluster is : " + clusterId); + vsmCredentials = getNexusVSMCredentialsByClusterId(clusterId); } - return nexusVSMCredentials; + else { + s_logger.info("Found invalid host object for hostGuid : " + hostGuid); + } + return vsmCredentials; } @Override @DB @@ -1023,17 +1018,24 @@ public class VmwareManagerImpl implements VmwareManager, VmwareStorageMount, Lis ClusterVSMMapVO vsmMapVO = null; vsmMapVO = _vsmMapDao.findByClusterId(clusterId); - if (vsmMapVO != null) - nexusVSM = _nexusDao.findById(vsmMapVO.getVsmId()); + long vsmId = 0; + if (vsmMapVO != null) { + vsmId = vsmMapVO.getVsmId(); + s_logger.info("vsmId is " + vsmId); + nexusVSM = _nexusDao.findById(vsmId); + s_logger.info("Fetching nexus vsm credentials from database."); + } + else { + s_logger.info("Found empty vsmMapVO."); + return null; + } + Map nexusVSMCredentials = new HashMap(); if (nexusVSM != null) { nexusVSMCredentials.put("vsmip", nexusVSM.getipaddr()); nexusVSMCredentials.put("vsmusername", nexusVSM.getUserName()); nexusVSMCredentials.put("vsmpassword", nexusVSM.getPassword()); - } else { - nexusVSMCredentials.put("vsmip", "10.102.125.32"); - nexusVSMCredentials.put("vsmusername", "admin"); - nexusVSMCredentials.put("vsmpassword", "vCenter!9"); + s_logger.info(nexusVSMCredentials.toString()); } return nexusVSMCredentials; } diff --git a/server/src/com/cloud/resource/ResourceManagerImpl.java b/server/src/com/cloud/resource/ResourceManagerImpl.java index d715cd918a9..99008b06dcb 100755 --- a/server/src/com/cloud/resource/ResourceManagerImpl.java +++ b/server/src/com/cloud/resource/ResourceManagerImpl.java @@ -65,11 +65,13 @@ import com.cloud.configuration.ConfigurationManager; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.dc.ClusterDetailsDao; import com.cloud.dc.ClusterVO; +import com.cloud.dc.ClusterVSMMapVO; import com.cloud.dc.DataCenterIpAddressVO; import com.cloud.dc.DataCenterVO; import com.cloud.dc.HostPodVO; import com.cloud.dc.PodCluster; import com.cloud.dc.dao.ClusterDao; +import com.cloud.dc.dao.ClusterVSMMapDao; import com.cloud.dc.dao.DataCenterDao; import com.cloud.dc.dao.DataCenterIpAddressDao; import com.cloud.dc.dao.HostPodDao; @@ -92,12 +94,14 @@ import com.cloud.host.dao.HostTagsDao; import com.cloud.hypervisor.Hypervisor; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.hypervisor.kvm.resource.KvmDummyResourceBase; +import com.cloud.network.CiscoNexusVSMDeviceVO; import com.cloud.network.IPAddressVO; +import com.cloud.network.dao.CiscoNexusVSMDeviceDao; import com.cloud.network.dao.IPAddressDao; import com.cloud.org.Cluster; import com.cloud.org.Grouping; -import com.cloud.org.Managed; import com.cloud.org.Grouping.AllocationState; +import com.cloud.org.Managed; import com.cloud.service.ServiceOfferingVO; import com.cloud.storage.GuestOSCategoryVO; import com.cloud.storage.StorageManager; @@ -123,6 +127,7 @@ import com.cloud.user.UserContext; import com.cloud.utils.Pair; import com.cloud.utils.StringUtils; import com.cloud.utils.UriUtils; +import com.cloud.utils.cisco.n1kv.vsm.NetconfHelper; import com.cloud.utils.component.Adapters; import com.cloud.utils.component.Inject; import com.cloud.utils.component.Manager; @@ -167,6 +172,10 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma @Inject protected ClusterDao _clusterDao; @Inject + protected ClusterVSMMapDao _clusterVSMDao; + @Inject + protected CiscoNexusVSMDeviceDao _vsmDao; + @Inject protected CapacityDao _capacityDao; @Inject protected HostDao _hostDao; @@ -311,6 +320,7 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma } + @DB @Override public List discoverCluster(AddClusterCmd cmd) throws IllegalArgumentException, DiscoveryException { long dcId = cmd.getZoneId(); @@ -421,6 +431,47 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma clusterId = cluster.getId(); result.add(cluster); + String vsmIp = cmd.getVSMIpaddress(); + String vsmUser = cmd.getVSMUsername(); + String vsmPassword = cmd.getVSMPassword(); + + 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); + throw new CloudRuntimeException(msg); + } + // persist credentials in 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 VSM details to database. Exception: " + e.getMessage()); + throw new CloudRuntimeException(e.getMessage()); + } + + 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 VSM with cluster: " + clusterName + ". Exception: " + e.getMessage()); + throw new CloudRuntimeException(e.getMessage()); + } + } + if (clusterType == Cluster.ClusterType.CloudManaged) { return result; } @@ -432,6 +483,7 @@ public class ResourceManagerImpl implements ResourceManager, ResourceService, Ma details.put("password", password); _clusterDetailsDao.persist(cluster.getId(), details); + boolean success = false; try { try { 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 176f0764241..b79636ff698 100755 --- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java +++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/HypervisorHostHelper.java @@ -128,7 +128,7 @@ public class HypervisorHostHelper { } public static Map getValidatedVsmCredentials(VmwareContext context) throws Exception { - Map vsmCredentials = context.getStockObject("vsmcredentials"); + Map vsmCredentials = context.getStockObject("vsmcredentials"); String msg; if(vsmCredentials == null || vsmCredentials.size() != 3) { msg = "Failed to retrieve required credentials of Nexus VSM from database.";