| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| package com.cloud.network; |
| |
| import java.util.List; |
| |
| import javax.inject.Inject; |
| |
| import org.apache.log4j.Logger; |
| |
| import com.cloud.agent.api.StartupCommand; |
| import com.cloud.dc.ClusterDetailsDao; |
| 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.exception.InvalidParameterValueException; |
| import com.cloud.exception.ResourceInUseException; |
| import com.cloud.host.Host; |
| import com.cloud.host.HostVO; |
| import com.cloud.host.dao.HostDetailsDao; |
| import com.cloud.hypervisor.Hypervisor.HypervisorType; |
| import com.cloud.hypervisor.vmware.manager.VmwareManager; |
| import com.cloud.network.dao.CiscoNexusVSMDeviceDao; |
| import com.cloud.network.dao.PortProfileDao; |
| import com.cloud.resource.ResourceManager; |
| import com.cloud.utils.cisco.n1kv.vsm.NetconfHelper; |
| import com.cloud.utils.component.AdapterBase; |
| import com.cloud.utils.db.DB; |
| import com.cloud.utils.db.Transaction; |
| import com.cloud.utils.db.TransactionCallbackNoReturn; |
| import com.cloud.utils.db.TransactionStatus; |
| import com.cloud.utils.exception.CloudRuntimeException; |
| |
| public abstract class CiscoNexusVSMDeviceManagerImpl extends AdapterBase { |
| |
| @Inject |
| CiscoNexusVSMDeviceDao _ciscoNexusVSMDeviceDao; |
| @Inject |
| ClusterDao _clusterDao; |
| @Inject |
| ClusterVSMMapDao _clusterVSMDao; |
| @Inject |
| ResourceManager _resourceMgr; |
| @Inject |
| VmwareManager _vmwareMgr; |
| @Inject |
| ClusterDetailsDao _clusterDetailsDao; |
| @Inject |
| HostDetailsDao _hostDetailDao; |
| @Inject |
| PortProfileDao _ppDao; |
| |
| private static final org.apache.log4j.Logger s_logger = Logger.getLogger(ExternalLoadBalancerDeviceManagerImpl.class); |
| |
| @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 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. |
| |
| 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; |
| } |
| |
| // Next, check if the cluster already has a VSM associated with it. |
| // If so, throw an exception disallowing this operation. The user must first |
| // delete the current VSM and then only attempt to add the new one. |
| |
| if (_clusterVSMDao.findByClusterId(clusterId) != null) { |
| // We can't have two VSMs for the same cluster. Throw exception. |
| throw new InvalidParameterValueException("Cluster with specified id already has a VSM tied to it. Please remove that first and retry the operation."); |
| } |
| |
| // TODO: Confirm whether we should be checking for VSM reachability here. |
| |
| // 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) |
| |
| NetconfHelper netconfClient; |
| try { |
| netconfClient = new NetconfHelper(ipaddress, username, password); |
| } catch (CloudRuntimeException e) { |
| String msg = "Failed to connect to Nexus VSM " + ipaddress + " with credentials of user " + username; |
| s_logger.error(msg); |
| throw new CloudRuntimeException(msg); |
| } |
| |
| // Disconnect from the VSM. A VSM has a default of 8 maximum parallel connections that it allows. |
| netconfClient.disconnect(); |
| |
| // Now, go ahead and associate the cluster with this VSM. |
| // First, check if VSM already exists in the table "virtual_supervisor_module". |
| // If it's not there already, create it. |
| // If it's there already, return success. |
| |
| // TODO - Right now, we only check if the ipaddress matches for both requests. |
| // We must really check whether every field of the VSM matches. Anyway, the |
| // 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; |
| try { |
| VSMObj = _ciscoNexusVSMDeviceDao.getVSMbyIpaddress(ipaddress); |
| } catch (Exception e) { |
| throw new CloudRuntimeException(e.getMessage()); |
| } |
| |
| if (VSMObj == null) { |
| // Create the VSM record. For now, we aren't using the vsmName field. |
| VSMObj = new CiscoNexusVSMDeviceVO(ipaddress, username, password); |
| _ciscoNexusVSMDeviceDao.persist(VSMObj); |
| } |
| |
| // At this stage, we have a VSM record for sure. Connect the VSM to the cluster Id. |
| long vsmId = _ciscoNexusVSMDeviceDao.getVSMbyIpaddress(ipaddress).getId(); |
| ClusterVSMMapVO connectorObj = new ClusterVSMMapVO(clusterId, vsmId); |
| _clusterVSMDao.persist(connectorObj); |
| |
| // Now, get a list of all the ESXi servers in this cluster. |
| // This is effectively a select * from host where cluster_id=clusterId; |
| // All ESXi servers are stored in the host table, and their resource |
| // type is vmwareresource. |
| |
| //List<HostVO> hosts = _resourceMgr.listAllHostsInCluster(clusterId); |
| |
| //TODO: Activate the code below if we make the Nexus VSM a separate resource. |
| // Iterate through each of the hosts in this list. Each host has a host id. |
| // Given this host id, we can reconfigure the in-memory resource representing |
| // the host via the agent manager. Thus we inject VSM related information |
| // into each host's resource. Also, we first configure each resource's |
| // entries in the database to contain this VSM information before the injection. |
| |
| //for (HostVO host : hosts) { |
| // Create a host details VO object and write it out for this hostid. |
| //Long hostid = new Long(vsmId); |
| //DetailVO vsmDetail = new DetailVO(host.getId(), "vsmId", hostid.toString()); |
| //Transaction tx = Transaction.currentTxn(); |
| //try { |
| //tx.start(); |
| //_hostDetailDao.persist(vsmDetail); |
| //tx.commit(); |
| //} catch (Exception e) { |
| //tx.rollback(); |
| //throw new CloudRuntimeException(e.getMessage()); |
| //} |
| //} |
| // Reconfigure the resource. |
| //Map hostDetails = new HashMap<String, String>(); |
| //hostDetails.put(ApiConstants.ID, vsmId); |
| //hostDetails.put(ApiConstants.IP_ADDRESS, ipaddress); |
| //hostDetails.put(ApiConstants.USERNAME, username); |
| //hostDetails.put(ApiConstants.PASSWORD, password); |
| //_agentMrg.send(host.getId(), ) |
| |
| return VSMObj; |
| |
| } |
| |
| @DB |
| public boolean deleteCiscoNexusVSM(final long vsmId) throws ResourceInUseException { |
| CiscoNexusVSMDeviceVO cisconexusvsm = _ciscoNexusVSMDeviceDao.findById(vsmId); |
| if (cisconexusvsm == null) { |
| // This entry is already not present. Return success. |
| return true; |
| } |
| |
| // First, check whether this VSM is part of any non-empty cluster. |
| // Search ClusterVSMMap's table for a list of clusters using this vsmId. |
| |
| List<ClusterVSMMapVO> clusterList = _clusterVSMDao.listByVSMId(vsmId); |
| |
| if (clusterList != null) { |
| for (ClusterVSMMapVO record : clusterList) { |
| // If this cluster id has any hosts in it, fail this operation. |
| Long clusterId = record.getClusterId(); |
| List<HostVO> hosts = _resourceMgr.listAllHostsInCluster(clusterId); |
| if (hosts != null && hosts.size() > 0) { |
| for (Host host : hosts) { |
| if (host.getType() == Host.Type.Routing) { |
| s_logger.info("Non-empty cluster with id" + clusterId + "still has a host that uses this VSM. Please empty the cluster first"); |
| throw new ResourceInUseException("Non-empty cluster with id" + clusterId + |
| "still has a host that uses this VSM. Please empty the cluster first"); |
| } |
| } |
| } |
| } |
| } |
| |
| // Iterate through the cluster list again, this time, delete the VSM. |
| Transaction.execute(new TransactionCallbackNoReturn() { |
| @Override |
| public void doInTransactionWithoutResult(TransactionStatus status) { |
| // Remove the VSM entry in CiscoNexusVSMDeviceVO's table. |
| _ciscoNexusVSMDeviceDao.remove(vsmId); |
| // Remove the current record as well from ClusterVSMMapVO's table. |
| _clusterVSMDao.removeByVsmId(vsmId); |
| } |
| }); |
| |
| return true; |
| } |
| |
| @DB |
| public CiscoNexusVSMDeviceVO enableCiscoNexusVSM(long vsmId) { |
| CiscoNexusVSMDeviceVO cisconexusvsm = _ciscoNexusVSMDeviceDao.findById(vsmId); |
| if (cisconexusvsm == null) { |
| throw new InvalidParameterValueException("Invalid vsm Id specified"); |
| } |
| // Else, check if this db record shows that this VSM is enabled or not. |
| if (cisconexusvsm.getvsmDeviceState() == CiscoNexusVSMDeviceVO.VSMDeviceState.Disabled) { |
| // it's currently disabled. So change it to enabled and write it out to the db. |
| cisconexusvsm.setVsmDeviceState(CiscoNexusVSMDeviceVO.VSMDeviceState.Enabled); |
| _ciscoNexusVSMDeviceDao.persist(cisconexusvsm); |
| } |
| |
| return cisconexusvsm; |
| } |
| |
| @DB |
| public CiscoNexusVSMDeviceVO disableCiscoNexusVSM(long vsmId) { |
| CiscoNexusVSMDeviceVO cisconexusvsm = _ciscoNexusVSMDeviceDao.findById(vsmId); |
| if (cisconexusvsm == null) { |
| throw new InvalidParameterValueException("Invalid vsm Id specified"); |
| } |
| // Else, check if this db record shows that this VSM is enabled or not. |
| if (cisconexusvsm.getvsmDeviceState() == CiscoNexusVSMDeviceVO.VSMDeviceState.Enabled) { |
| // it's currently disabled. So change it to enabled and write it out to the db. |
| cisconexusvsm.setVsmDeviceState(CiscoNexusVSMDeviceVO.VSMDeviceState.Disabled); |
| _ciscoNexusVSMDeviceDao.persist(cisconexusvsm); |
| } |
| |
| return cisconexusvsm; |
| } |
| |
| @DB |
| public CiscoNexusVSMDeviceVO getCiscoVSMbyVSMId(long vsmId) { |
| return _ciscoNexusVSMDeviceDao.findById(vsmId); |
| } |
| |
| @DB |
| public CiscoNexusVSMDeviceVO getCiscoVSMbyClusId(long clusterId) { |
| ClusterVSMMapVO mapVO = _clusterVSMDao.findByClusterId(clusterId); |
| if (mapVO == null) { |
| s_logger.info("Couldn't find a VSM associated with the specified cluster Id"); |
| return null; |
| } |
| // Else, pull out the VSM associated with the VSM id in mapVO. |
| CiscoNexusVSMDeviceVO result = _ciscoNexusVSMDeviceDao.findById(mapVO.getVsmId()); |
| return result; |
| } |
| |
| public HostVO createHostVOForConnectedAgent(HostVO host, StartupCommand[] cmd) { |
| // TODO Auto-generated method stub |
| return null; |
| } |
| } |