blob: beac489acdb3d32115cd2f7a1774db8db08002e5 [file] [log] [blame]
// 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 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;
@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;
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) {
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) {
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;
}
}