mirror of https://github.com/apache/cloudstack.git
CLOUDSTACK-1963 New mapping model for CloudStack zone and Vmware datacenter
Introduced 2 new API command classes AddVmwareDcCmd & RemoveVmwareDcCmd. The new APIs are addVmwareDc & removeVmwareDc, these APIs will associate a Vmware datacenter to a cloudstack zone & dis-associate a Vmware datacenter from a cloudstack zone. Constraint checks are added for infrastructure change operations in zone that encompass resources like clusters. Constraint checks are added in discoverer and manager classes. Added a service 'VmwareDatacenterService' to expose methods that will have API implementation for 2 APIs addVmwareDc & removeVmwareDc Signed-off-by: Sateesh Chodapuneedi <sateesh@apache.org>
This commit is contained in:
parent
47e355c1c2
commit
64419b1e4e
|
|
@ -0,0 +1,32 @@
|
|||
// 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.hypervisor.vmware;
|
||||
|
||||
import org.apache.cloudstack.api.command.admin.zone.AddVmwareDcCmd;
|
||||
import org.apache.cloudstack.api.command.admin.zone.RemoveVmwareDcCmd;
|
||||
|
||||
import com.cloud.exception.DiscoveryException;
|
||||
import com.cloud.exception.ResourceInUseException;
|
||||
import com.cloud.utils.component.PluggableService;
|
||||
|
||||
public interface VmwareDatacenterService extends PluggableService {
|
||||
|
||||
public VmwareDatacenterVO addVmwareDatacenter(AddVmwareDcCmd cmd) throws IllegalArgumentException, DiscoveryException, ResourceInUseException;
|
||||
|
||||
public boolean removeVmwareDatacenter(RemoveVmwareDcCmd cmd) throws IllegalArgumentException, ResourceInUseException;
|
||||
}
|
||||
|
|
@ -30,6 +30,7 @@ import javax.naming.ConfigurationException;
|
|||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.springframework.beans.NullValueInNestedPathException;
|
||||
|
||||
import com.cloud.agent.api.StartupCommand;
|
||||
import com.cloud.agent.api.StartupRoutingCommand;
|
||||
|
|
@ -51,6 +52,8 @@ import com.cloud.host.dao.HostDao;
|
|||
import com.cloud.hypervisor.Hypervisor;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao;
|
||||
import com.cloud.hypervisor.vmware.dao.VmwareDatacenterDao;
|
||||
import com.cloud.hypervisor.vmware.dao.VmwareDatacenterZoneMapDao;
|
||||
import com.cloud.hypervisor.vmware.manager.VmwareManager;
|
||||
import com.cloud.hypervisor.vmware.mo.ClusterMO;
|
||||
import com.cloud.hypervisor.vmware.mo.HostMO;
|
||||
|
|
@ -107,11 +110,16 @@ public class VmwareServerDiscoverer extends DiscovererBase implements
|
|||
@Inject
|
||||
CiscoNexusVSMDeviceDao _nexusDao;
|
||||
@Inject
|
||||
CiscoNexusVSMElementService _nexusElement;
|
||||
CiscoNexusVSMElement _nexusElement;
|
||||
@Inject
|
||||
NetworkModel _netmgr;
|
||||
@Inject
|
||||
HypervisorCapabilitiesDao _hvCapabilitiesDao;
|
||||
@Inject
|
||||
VmwareDatacenterZoneMapDao _vmwareDcZoneMapDao;
|
||||
@Inject
|
||||
VmwareDatacenterDao _vmwareDcDao;
|
||||
|
||||
protected Map<String, String> _urlParams;
|
||||
protected boolean useDVS = false;
|
||||
protected boolean nexusDVS = false;
|
||||
|
|
@ -140,6 +148,18 @@ public class VmwareServerDiscoverer extends DiscovererBase implements
|
|||
return null;
|
||||
}
|
||||
|
||||
Map<String, String> clusterDetails = _clusterDetailsDao.findDetails(clusterId);
|
||||
boolean legacyZone = false;
|
||||
//Check if NOT a legacy zone.
|
||||
if (!legacyZone) {
|
||||
String updatedInventoryPath = validateCluster(dcId, url, username, password);
|
||||
if (url.getPath() != updatedInventoryPath) {
|
||||
// If url from API doesn't specifiy DC then update url in database with DC assocaited with this zone.
|
||||
clusterDetails.put("url", url.getScheme() + "://" + url.getHost() + updatedInventoryPath);
|
||||
_clusterDetailsDao.persist(clusterId, clusterDetails);
|
||||
}
|
||||
}
|
||||
|
||||
List<HostVO> hosts = _resourceMgr.listAllHostsInCluster(clusterId);
|
||||
if (hosts != null && hosts.size() > 0) {
|
||||
int maxHostsPerCluster = _hvCapabilitiesDao.getMaxHostsPerCluster(hosts.get(0).getHypervisorType(), hosts.get(0).getHypervisorVersion());
|
||||
|
|
@ -164,7 +184,6 @@ public class VmwareServerDiscoverer extends DiscovererBase implements
|
|||
|
||||
VmwareTrafficLabel guestTrafficLabelObj = new VmwareTrafficLabel(TrafficType.Guest);
|
||||
VmwareTrafficLabel publicTrafficLabelObj = new VmwareTrafficLabel(TrafficType.Public);
|
||||
Map<String, String> clusterDetails = _clusterDetailsDao.findDetails(clusterId);
|
||||
DataCenterVO zone = _dcDao.findById(dcId);
|
||||
NetworkType zoneType = zone.getNetworkType();
|
||||
_readGlobalConfigParameters();
|
||||
|
|
@ -395,6 +414,63 @@ public class VmwareServerDiscoverer extends DiscovererBase implements
|
|||
}
|
||||
}
|
||||
|
||||
private String validateCluster(Long dcId, URI url, String username, String password) throws DiscoveryException {
|
||||
String msg;
|
||||
long vmwareDcId;
|
||||
VmwareDatacenterVO vmwareDc;
|
||||
String vmwareDcNameFromDb;
|
||||
String vmwareDcNameFromApi;
|
||||
String vCenterHost;
|
||||
String updatedInventoryPath = url.getPath();
|
||||
String clusterName = null;
|
||||
|
||||
// Check if zone is associated with DC
|
||||
VmwareDatacenterZoneMapVO vmwareDcZone = _vmwareDcZoneMapDao.findByZoneId(dcId);
|
||||
if (vmwareDcZone == null) {
|
||||
msg = "Zone " + dcId + " is not associated with any VMware DC yet. "
|
||||
+ "Please add VMware DC to this zone first and then try to add clusters.";
|
||||
s_logger.error(msg);
|
||||
throw new DiscoveryException(msg);
|
||||
}
|
||||
|
||||
// Retrieve DC added to this zone from database
|
||||
vmwareDcId = vmwareDcZone.getVmwareDcId();
|
||||
vmwareDc = _vmwareDcDao.findById(vmwareDcId);
|
||||
vmwareDcNameFromApi = vmwareDcNameFromDb = vmwareDc.getVmwareDatacenterName();
|
||||
vCenterHost = vmwareDc.getVcenterHost();
|
||||
String inventoryPath = url.getPath();
|
||||
|
||||
assert (inventoryPath != null);
|
||||
|
||||
String[] pathTokens = inventoryPath.split("/");
|
||||
if (pathTokens.length == 2) {
|
||||
// DC name is not present in url.
|
||||
// Using DC name read from database.
|
||||
clusterName = pathTokens[1];
|
||||
updatedInventoryPath = "/" + vmwareDcNameFromDb + "/" + clusterName;
|
||||
} else if (pathTokens.length == 3) {
|
||||
vmwareDcNameFromApi = pathTokens[1];
|
||||
clusterName = pathTokens[2];
|
||||
}
|
||||
|
||||
if (!vCenterHost.equalsIgnoreCase(url.getHost())) {
|
||||
msg = "This cluster " + clusterName + " belongs to vCenter " + url.getHost()
|
||||
+ " .But this zone is associated with VMware DC from vCenter " + vCenterHost
|
||||
+ ". Make sure the cluster being added belongs to vCenter " + vCenterHost
|
||||
+ " and DC " + vmwareDcNameFromDb;
|
||||
s_logger.error(msg);
|
||||
throw new DiscoveryException(msg);
|
||||
} else if (!vmwareDcNameFromDb.equalsIgnoreCase(vmwareDcNameFromApi)) {
|
||||
msg = "This cluster " + clusterName + " belongs to VMware DC " + vmwareDcNameFromApi
|
||||
+ " .But this zone is associated with VMware DC " + vmwareDcNameFromDb
|
||||
+ ". Make sure the cluster being added belongs to DC " + vmwareDcNameFromDb
|
||||
+ " in vCenter " + vCenterHost;
|
||||
s_logger.error(msg);
|
||||
throw new DiscoveryException(msg);
|
||||
}
|
||||
return updatedInventoryPath;
|
||||
}
|
||||
|
||||
private boolean validateDiscoveredHosts(VmwareContext context,
|
||||
ManagedObjectReference morCluster,
|
||||
List<ManagedObjectReference> morHosts) throws Exception {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import java.io.IOException;
|
|||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
|
@ -35,6 +36,8 @@ import javax.ejb.Local;
|
|||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import org.apache.cloudstack.api.command.admin.zone.AddVmwareDcCmd;
|
||||
import org.apache.cloudstack.api.command.admin.zone.RemoveVmwareDcCmd;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
|
|
@ -51,15 +54,28 @@ 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.DataCenterVO;
|
||||
import com.cloud.dc.dao.ClusterDao;
|
||||
import com.cloud.dc.dao.ClusterVSMMapDao;
|
||||
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.Status;
|
||||
import com.cloud.host.dao.HostDao;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao;
|
||||
import com.cloud.hypervisor.vmware.VmwareCleanupMaid;
|
||||
import com.cloud.hypervisor.vmware.VmwareDatacenterService;
|
||||
import com.cloud.hypervisor.vmware.VmwareDatacenterVO;
|
||||
import com.cloud.hypervisor.vmware.VmwareDatacenterZoneMapVO;
|
||||
import com.cloud.hypervisor.vmware.dao.VmwareDatacenterDao;
|
||||
import com.cloud.hypervisor.vmware.dao.VmwareDatacenterZoneMapDao;
|
||||
import com.cloud.hypervisor.vmware.mo.CustomFieldConstants;
|
||||
import com.cloud.hypervisor.vmware.mo.CustomFieldsManagerMO;
|
||||
import com.cloud.hypervisor.vmware.mo.DatacenterMO;
|
||||
import com.cloud.hypervisor.vmware.mo.DiskControllerType;
|
||||
import com.cloud.hypervisor.vmware.mo.HostFirewallSystemMO;
|
||||
import com.cloud.hypervisor.vmware.mo.HostMO;
|
||||
|
|
@ -68,8 +84,10 @@ import com.cloud.hypervisor.vmware.mo.TaskMO;
|
|||
import com.cloud.hypervisor.vmware.mo.VirtualEthernetCardType;
|
||||
import com.cloud.hypervisor.vmware.mo.VmwareHostType;
|
||||
import com.cloud.utils.ssh.SshHelper;
|
||||
import com.cloud.hypervisor.vmware.resource.VmwareContextFactory;
|
||||
import com.cloud.hypervisor.vmware.util.VmwareClient;
|
||||
import com.cloud.hypervisor.vmware.util.VmwareContext;
|
||||
import com.cloud.hypervisor.vmware.util.VmwareHelper;
|
||||
import com.cloud.network.CiscoNexusVSMDeviceVO;
|
||||
import com.cloud.network.NetworkModel;
|
||||
import com.cloud.network.dao.CiscoNexusVSMDeviceDao;
|
||||
|
|
@ -83,11 +101,13 @@ import com.cloud.storage.secondary.SecondaryStorageVmManager;
|
|||
import com.cloud.utils.FileUtil;
|
||||
import com.cloud.utils.NumbersUtil;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.UriUtils;
|
||||
import com.cloud.utils.component.Manager;
|
||||
import com.cloud.utils.component.ManagerBase;
|
||||
import com.cloud.utils.concurrency.NamedThreadFactory;
|
||||
import com.cloud.utils.db.DB;
|
||||
import com.cloud.utils.db.GlobalLock;
|
||||
import com.cloud.utils.db.Transaction;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.script.Script;
|
||||
import com.cloud.utils.ssh.SshHelper;
|
||||
|
|
@ -98,8 +118,8 @@ import com.vmware.vim25.HostConnectSpec;
|
|||
import com.vmware.vim25.ManagedObjectReference;
|
||||
|
||||
|
||||
@Local(value = {VmwareManager.class})
|
||||
public class VmwareManagerImpl extends ManagerBase implements VmwareManager, VmwareStorageMount, Listener {
|
||||
@Local(value = {VmwareManager.class, VmwareDatacenterService.class})
|
||||
public class VmwareManagerImpl extends ManagerBase implements VmwareManager, VmwareStorageMount, Listener, VmwareDatacenterService {
|
||||
private static final Logger s_logger = Logger.getLogger(VmwareManagerImpl.class);
|
||||
|
||||
private static final int STARTUP_DELAY = 60000; // 60 seconds
|
||||
|
|
@ -124,6 +144,9 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||
@Inject ConfigurationDao _configDao;
|
||||
@Inject ConfigurationServer _configServer;
|
||||
@Inject HypervisorCapabilitiesDao _hvCapabilitiesDao;
|
||||
@Inject DataCenterDao _dcDao;
|
||||
@Inject VmwareDatacenterDao _vmwareDcDao;
|
||||
@Inject VmwareDatacenterZoneMapDao _vmwareDcZoneMapDao;
|
||||
|
||||
String _mountParent;
|
||||
StorageLayer _storage;
|
||||
|
|
@ -865,4 +888,259 @@ public class VmwareManagerImpl extends ManagerBase implements VmwareManager, Vmw
|
|||
public String getRootDiskController() {
|
||||
return _rootDiskController;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Class<?>> getCommands() {
|
||||
List<Class<?>> cmdList = new ArrayList<Class<?>>();
|
||||
cmdList.add(AddVmwareDcCmd.class);
|
||||
cmdList.add(RemoveVmwareDcCmd.class);
|
||||
return cmdList;
|
||||
}
|
||||
|
||||
@Override
|
||||
@DB
|
||||
public VmwareDatacenterVO addVmwareDatacenter(AddVmwareDcCmd cmd) throws ResourceInUseException {
|
||||
VmwareDatacenterVO vmwareDc = null;
|
||||
Long zoneId = cmd.getZoneId();
|
||||
String url = cmd.getUrl();
|
||||
String userName = cmd.getUsername();
|
||||
String password = cmd.getPassword();
|
||||
String vmwareDcName = cmd.getName();
|
||||
|
||||
// Zone validation
|
||||
validateZone(zoneId, "add VMware datacenter to zone");
|
||||
|
||||
VmwareDatacenterZoneMapVO vmwareDcZoneMap = _vmwareDcZoneMapDao.findByZoneId(zoneId);
|
||||
// Check if zone is associated with VMware DC
|
||||
if (vmwareDcZoneMap != null) {
|
||||
throw new CloudRuntimeException("Zone " + zoneId + " is already associated with a VMware datacenter.");
|
||||
}
|
||||
|
||||
// Validate url and get uri
|
||||
URI uri = getUri(url);
|
||||
|
||||
// Validate username and password and DC name
|
||||
if (userName == null) {
|
||||
throw new InvalidParameterValueException("Invalid parameter username.");
|
||||
}
|
||||
|
||||
if (password == null) {
|
||||
throw new InvalidParameterValueException("Invalid parameter password.");
|
||||
}
|
||||
|
||||
if (vmwareDcName == null) {
|
||||
throw new InvalidParameterValueException("Invalid parameter name. Please provide valid VMware datacenter name.");
|
||||
}
|
||||
|
||||
// Check if DC is already part of zone
|
||||
// In that case vmware_data_center table should have the DC
|
||||
String vCenterHost = uri.getHost();
|
||||
List<VmwareDatacenterVO> vmwareDcs = _vmwareDcDao.getVmwareDatacenterByNameAndVcenter(vmwareDcName, vCenterHost);
|
||||
if (vmwareDcs != null && vmwareDcs.size() != 0) {
|
||||
throw new ResourceInUseException("This DC is already part of other CloudStack zone(s). Cannot add this DC to more zones.");
|
||||
}
|
||||
|
||||
VmwareContext context = null;
|
||||
DatacenterMO dcMo = null;
|
||||
String dcCustomFieldValue;
|
||||
boolean addDcCustomFieldDef = false;
|
||||
boolean dcInUse = false;
|
||||
String guid;
|
||||
ManagedObjectReference dcMor;
|
||||
try {
|
||||
context = VmwareContextFactory.create(vCenterHost, userName, password);
|
||||
|
||||
// Check if DC exists on vCenter
|
||||
try {
|
||||
dcMo = new DatacenterMO(context, vmwareDcName);
|
||||
} catch(Throwable t) {
|
||||
String msg = "Unable to find DC " + vmwareDcName + " in vCenter " + vCenterHost;
|
||||
s_logger.error(msg);
|
||||
throw new DiscoveryException(msg);
|
||||
}
|
||||
assert (dcMo != null);
|
||||
|
||||
// Check if DC is already associated with another cloudstack deployment
|
||||
// Get custom field property cloud.zone over this DC
|
||||
guid = vmwareDcName + "@" + vCenterHost;
|
||||
|
||||
dcCustomFieldValue = dcMo.getCustomFieldValue(CustomFieldConstants.CLOUD_ZONE);
|
||||
if (dcCustomFieldValue == null) {
|
||||
addDcCustomFieldDef = true;
|
||||
}
|
||||
dcInUse = Boolean.parseBoolean(dcCustomFieldValue);
|
||||
if (dcInUse) {
|
||||
throw new ResourceInUseException("This DC is being managed by other CloudStack deployment. Cannot add this DC to zone.");
|
||||
}
|
||||
|
||||
// Add DC to database into vmware_data_center table
|
||||
vmwareDc = new VmwareDatacenterVO(guid, vmwareDcName, vCenterHost, userName, password);
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
try {
|
||||
txn.start();
|
||||
vmwareDc = _vmwareDcDao.persist(vmwareDc);
|
||||
txn.commit();
|
||||
} catch (Exception e) {
|
||||
txn.rollback();
|
||||
s_logger.error("Failed to persist VMware datacenter details to database. Exception: " + e.getMessage());
|
||||
throw new CloudRuntimeException(e.getMessage());
|
||||
}
|
||||
|
||||
// Map zone with vmware datacenter
|
||||
vmwareDcZoneMap = new VmwareDatacenterZoneMapVO(zoneId, vmwareDc.getId());
|
||||
|
||||
txn = Transaction.currentTxn();
|
||||
try {
|
||||
txn.start();
|
||||
vmwareDcZoneMap = _vmwareDcZoneMapDao.persist(vmwareDcZoneMap);
|
||||
txn.commit();
|
||||
} catch (Exception e) {
|
||||
txn.rollback();
|
||||
s_logger.error("Failed to associate VMware datacenter with zone " + zoneId + ". Exception: " + e.getMessage());
|
||||
// Removing VMware datacenter from vmware_data_center table because association with zone failed.
|
||||
_vmwareDcDao.remove(vmwareDcZoneMap.getId());
|
||||
throw new CloudRuntimeException(e.getMessage());
|
||||
}
|
||||
|
||||
// Set custom field for this DC
|
||||
if (addDcCustomFieldDef) {
|
||||
dcMo.ensureCustomFieldDef(CustomFieldConstants.CLOUD_ZONE);
|
||||
}
|
||||
dcMo.setCustomFieldValue(CustomFieldConstants.CLOUD_ZONE, "true");
|
||||
|
||||
} catch (Exception e) {
|
||||
String msg = "VMware DC discovery failed due to : " + VmwareHelper.getExceptionMessage(e);
|
||||
s_logger.error(msg);
|
||||
throw new CloudRuntimeException(msg);
|
||||
} finally {
|
||||
if (context != null)
|
||||
context.close();
|
||||
context = null;
|
||||
}
|
||||
return vmwareDc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeVmwareDatacenter(RemoveVmwareDcCmd cmd) throws ResourceInUseException {
|
||||
Long zoneId = cmd.getZoneId();
|
||||
// Validate zone
|
||||
validateZone(zoneId, "remove VMware datacenter from zone");
|
||||
|
||||
// Get DC associated with this zone
|
||||
VmwareDatacenterZoneMapVO vmwareDcZoneMap;
|
||||
VmwareDatacenterVO vmwareDatacenter;
|
||||
String vmwareDcName;
|
||||
long vmwareDcId;
|
||||
String vCenterHost;
|
||||
String userName;
|
||||
String password;
|
||||
DatacenterMO dcMo = null;
|
||||
Transaction txn;
|
||||
|
||||
vmwareDcZoneMap = _vmwareDcZoneMapDao.findByZoneId(zoneId);
|
||||
// Check if zone is associated with VMware DC
|
||||
if (vmwareDcZoneMap == null) {
|
||||
throw new CloudRuntimeException("Zone " + zoneId + " is not associated with any VMware datacenter.");
|
||||
}
|
||||
|
||||
vmwareDcId = vmwareDcZoneMap.getVmwareDcId();
|
||||
vmwareDatacenter = _vmwareDcDao.findById(vmwareDcId);
|
||||
vmwareDcName = vmwareDatacenter.getVmwareDatacenterName();
|
||||
vCenterHost = vmwareDatacenter.getVcenterHost();
|
||||
userName = vmwareDatacenter.getUser();
|
||||
password = vmwareDatacenter.getPassword();
|
||||
txn = Transaction.currentTxn();
|
||||
try {
|
||||
txn.start();
|
||||
// Remove the VMware datacenter entry in table vmware_data_center
|
||||
_vmwareDcDao.remove(vmwareDcId);
|
||||
// Remove the map entry in table vmware_data_center_zone_map
|
||||
_vmwareDcZoneMapDao.remove(vmwareDcZoneMap.getId());
|
||||
txn.commit();
|
||||
} catch (Exception e) {
|
||||
s_logger.info("Caught exception when trying to delete VMware datacenter record.." + e.getMessage());
|
||||
throw new CloudRuntimeException("Failed to delete VMware datacenter ");
|
||||
}
|
||||
|
||||
// Construct context
|
||||
VmwareContext context = null;
|
||||
try {
|
||||
context = VmwareContextFactory.create(vCenterHost, userName, password);
|
||||
|
||||
// Check if DC exists on vCenter
|
||||
try {
|
||||
dcMo = new DatacenterMO(context, vmwareDcName);
|
||||
} catch(Throwable t) {
|
||||
String msg = "able to find DC " + vmwareDcName + " in vCenter " + vCenterHost;
|
||||
s_logger.error(msg);
|
||||
throw new DiscoveryException(msg);
|
||||
}
|
||||
|
||||
assert (dcMo != null);
|
||||
|
||||
// Reset custom field property cloud.zone over this DC
|
||||
dcMo.setCustomFieldValue(CustomFieldConstants.CLOUD_ZONE, "false");
|
||||
s_logger.info("Sucessfully reset custom field property cloud.zone over DC " + vmwareDcName);
|
||||
} catch (Exception e) {
|
||||
String msg = "Unable to reset custom field property cloud.zone over DC " + vmwareDcName
|
||||
+ " due to : " + VmwareHelper.getExceptionMessage(e);
|
||||
s_logger.error(msg);
|
||||
throw new CloudRuntimeException(msg);
|
||||
} finally {
|
||||
if (context != null)
|
||||
context.close();
|
||||
context = null;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void validateZone(Long zoneId, String errStr) throws ResourceInUseException {
|
||||
// Check if zone with specified id exists
|
||||
DataCenterVO zone = _dcDao.findById(zoneId);
|
||||
if (zone == null) {
|
||||
InvalidParameterValueException ex = new InvalidParameterValueException(
|
||||
"Can't find zone by the id specified");
|
||||
throw ex;
|
||||
}
|
||||
|
||||
// Check if zone has resources? - For now look for clusters
|
||||
List<ClusterVO> clusters = _clusterDao.listByZoneId(zoneId);
|
||||
if (clusters != null && clusters.size() > 0) {
|
||||
// Look for VMware hypervisor.
|
||||
for (ClusterVO cluster : clusters) {
|
||||
if (cluster.getHypervisorType().equals(HypervisorType.VMware)) {
|
||||
throw new ResourceInUseException("Zone has one or more clusters."
|
||||
+ " Can't " + errStr + " which already has clusters.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private URI getUri(String url) throws InvalidParameterValueException {
|
||||
if (url == null) {
|
||||
throw new InvalidParameterValueException("Invalid url.");
|
||||
}
|
||||
|
||||
URI uri = null;
|
||||
try {
|
||||
uri = new URI(UriUtils.encodeURIComponent(url));
|
||||
if (uri.getScheme() == null) {
|
||||
throw new InvalidParameterValueException(
|
||||
"uri.scheme is null " + url
|
||||
+ ", add http:// as a prefix");
|
||||
} else if (uri.getScheme().equalsIgnoreCase("http")) {
|
||||
if (uri.getHost() == null
|
||||
|| uri.getHost().equalsIgnoreCase("")
|
||||
|| uri.getPath() == null
|
||||
|| uri.getPath().equalsIgnoreCase("")) {
|
||||
throw new InvalidParameterValueException(
|
||||
"Your host and/or path is wrong. Make sure it's of the format http://hostname/path");
|
||||
}
|
||||
}
|
||||
} catch (URISyntaxException e) {
|
||||
throw new InvalidParameterValueException(url
|
||||
+ " is not a valid uri");
|
||||
}
|
||||
return uri;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,122 @@
|
|||
// 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 org.apache.cloudstack.api.command.admin.zone;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.VmwareDatacenterResponse;
|
||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.exception.DiscoveryException;
|
||||
import com.cloud.exception.ResourceInUseException;
|
||||
import com.cloud.hypervisor.vmware.VmwareDatacenterService;
|
||||
import com.cloud.hypervisor.vmware.VmwareDatacenterVO;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
@APICommand(name = "addVmwareDc", description="Adds a VMware datacenter to specified zone", responseObject=VmwareDatacenterResponse.class)
|
||||
public class AddVmwareDcCmd extends BaseCmd {
|
||||
|
||||
@Inject public VmwareDatacenterService _vmwareDatacenterService;
|
||||
|
||||
public static final Logger s_logger = Logger.getLogger(AddVmwareDcCmd.class.getName());
|
||||
|
||||
private static final String s_name = "addvmwaredcresponse";
|
||||
|
||||
@Parameter(name=ApiConstants.NAME, type=CommandType.STRING, required=true, description="Name of VMware datacenter to be added to specified zone.")
|
||||
private String name;
|
||||
|
||||
@Parameter(name=ApiConstants.URL, type=CommandType.STRING, required=false, description="The URL of vCenter.")
|
||||
private String url;
|
||||
|
||||
@Parameter(name=ApiConstants.USERNAME, type=CommandType.STRING, required=false, description="The Username required to connect to resource.")
|
||||
private String username;
|
||||
|
||||
@Parameter(name=ApiConstants.PASSWORD, type=CommandType.STRING, required=false, description="The password for specified username.")
|
||||
private String password;
|
||||
|
||||
@Parameter(name=ApiConstants.ZONE_ID, type=CommandType.UUID, entityType=ZoneResponse.class, required=true, description="The Zone ID.")
|
||||
private Long zoneId;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public Long getZoneId() {
|
||||
return zoneId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return Account.ACCOUNT_ID_SYSTEM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
try {
|
||||
VmwareDatacenterResponse response = new VmwareDatacenterResponse();
|
||||
VmwareDatacenterVO result = _vmwareDatacenterService.addVmwareDatacenter(this);
|
||||
if (result != null){
|
||||
response.setId(result.getUuid());
|
||||
response.setName(result.getVmwareDatacenterName());
|
||||
response.setResponseName(getCommandName());
|
||||
} else {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add VMware Datacenter to zone.");
|
||||
}
|
||||
this.setResponseObject(response);
|
||||
} catch (DiscoveryException ex) {
|
||||
s_logger.warn("Exception: ", ex);
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
|
||||
} catch (ResourceInUseException ex) {
|
||||
s_logger.warn("Exception: ", ex);
|
||||
ServerApiException e = new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
|
||||
for (String proxyObj : ex.getIdProxyList()) {
|
||||
e.addProxyObject(proxyObj);
|
||||
}
|
||||
throw e;
|
||||
} catch (IllegalArgumentException ex) {
|
||||
throw new IllegalArgumentException(ex.getMessage());
|
||||
} catch (CloudRuntimeException runtimeEx) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, runtimeEx.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
// 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 org.apache.cloudstack.api.command.admin.zone;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.BaseCmd.CommandType;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.cloudstack.api.response.ZoneResponse;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.DiscoveryException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.NetworkRuleConflictException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceInUseException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.hypervisor.vmware.VmwareDatacenterService;
|
||||
import com.cloud.network.element.CiscoNexusVSMElementService;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
@APICommand(name = "removeVmwareDc", responseObject=SuccessResponse.class, description="Remove a VMware datacenter from a zone.")
|
||||
public class RemoveVmwareDcCmd extends BaseCmd {
|
||||
|
||||
@Inject public VmwareDatacenterService _vmwareDatacenterService;
|
||||
|
||||
public static final Logger s_logger = Logger.getLogger(AddVmwareDcCmd.class.getName());
|
||||
|
||||
private static final String s_name = "removevmwaredcresponse";
|
||||
|
||||
@Parameter(name=ApiConstants.ZONE_ID, type=CommandType.UUID, entityType=ZoneResponse.class, required=true,
|
||||
description="The id of Zone from which VMware datacenter has to be removed.")
|
||||
|
||||
private Long zoneId;
|
||||
|
||||
public Long getZoneId() {
|
||||
return zoneId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
SuccessResponse response = new SuccessResponse();
|
||||
try {
|
||||
boolean result = _vmwareDatacenterService.removeVmwareDatacenter(this);
|
||||
if (result) {
|
||||
response.setResponseName(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
} else {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to remove VMware datacenter from zone");
|
||||
}
|
||||
} catch (ResourceInUseException ex) {
|
||||
s_logger.warn("The zone has one or more resources (like cluster), hence not able to remove VMware datacenter from zone."
|
||||
+ " Please remove all resource from zone, and retry. Exception: ", ex);
|
||||
ServerApiException e = new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
|
||||
for (String proxyObj : ex.getIdProxyList()) {
|
||||
e.addProxyObject(proxyObj);
|
||||
}
|
||||
throw e;
|
||||
} catch (IllegalArgumentException ex) {
|
||||
throw new IllegalArgumentException(ex.getMessage());
|
||||
} catch (CloudRuntimeException runtimeEx) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, runtimeEx.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return Account.ACCOUNT_ID_SYSTEM;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
// 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 org.apache.cloudstack.api.response;
|
||||
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseResponse;
|
||||
import org.apache.cloudstack.api.EntityReference;
|
||||
|
||||
import com.cloud.hypervisor.vmware.VmwareDatacenter;
|
||||
import com.cloud.serializer.Param;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
@EntityReference(value = VmwareDatacenter.class)
|
||||
public class VmwareDatacenterResponse extends BaseResponse {
|
||||
@SerializedName(ApiConstants.ID) @Param(description="The VMware Datacenter ID")
|
||||
private String id;
|
||||
|
||||
@SerializedName(ApiConstants.NAME) @Param(description="The VMware Datacenter name")
|
||||
private String name;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue