cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sate...@apache.org
Subject [47/50] [abbrv] git commit: updated refs/heads/vmware-datamodel to f1a5d70
Date Thu, 23 May 2013 07:25:52 GMT
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>


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/03d6a043
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/03d6a043
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/03d6a043

Branch: refs/heads/vmware-datamodel
Commit: 03d6a043e42622ec7f713fd73bafaa17d60bac55
Parents: e838059
Author: Sateesh Chodapuneedi <sateesh@apache.org>
Authored: Thu May 23 12:34:19 2013 +0530
Committer: Sateesh Chodapuneedi <sateesh@apache.org>
Committed: Thu May 23 12:53:21 2013 +0530

----------------------------------------------------------------------
 .../hypervisor/vmware/VmwareDatacenterService.java |   32 ++
 .../hypervisor/vmware/VmwareServerDiscoverer.java  |   80 ++++-
 .../vmware/manager/VmwareManagerImpl.java          |  282 ++++++++++++++-
 .../api/command/admin/zone/AddVmwareDcCmd.java     |  122 +++++++
 .../api/command/admin/zone/RemoveVmwareDcCmd.java  |   99 +++++
 .../api/response/VmwareDatacenterResponse.java     |   51 +++
 6 files changed, 662 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/03d6a043/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareDatacenterService.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareDatacenterService.java
b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareDatacenterService.java
new file mode 100644
index 0000000..5e80e18
--- /dev/null
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareDatacenterService.java
@@ -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;
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/03d6a043/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java
b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java
index 2f82b53..aec44b3 100755
--- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareServerDiscoverer.java
@@ -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 {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/03d6a043/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
index 9f260f1..3718762 100755
--- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareManagerImpl.java
@@ -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;
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/03d6a043/plugins/hypervisors/vmware/src/org/apache/cloudstack/api/command/admin/zone/AddVmwareDcCmd.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/org/apache/cloudstack/api/command/admin/zone/AddVmwareDcCmd.java
b/plugins/hypervisors/vmware/src/org/apache/cloudstack/api/command/admin/zone/AddVmwareDcCmd.java
new file mode 100644
index 0000000..7168c7f
--- /dev/null
+++ b/plugins/hypervisors/vmware/src/org/apache/cloudstack/api/command/admin/zone/AddVmwareDcCmd.java
@@ -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());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/03d6a043/plugins/hypervisors/vmware/src/org/apache/cloudstack/api/command/admin/zone/RemoveVmwareDcCmd.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/org/apache/cloudstack/api/command/admin/zone/RemoveVmwareDcCmd.java
b/plugins/hypervisors/vmware/src/org/apache/cloudstack/api/command/admin/zone/RemoveVmwareDcCmd.java
new file mode 100644
index 0000000..a74c91b
--- /dev/null
+++ b/plugins/hypervisors/vmware/src/org/apache/cloudstack/api/command/admin/zone/RemoveVmwareDcCmd.java
@@ -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;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/03d6a043/plugins/hypervisors/vmware/src/org/apache/cloudstack/api/response/VmwareDatacenterResponse.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/org/apache/cloudstack/api/response/VmwareDatacenterResponse.java
b/plugins/hypervisors/vmware/src/org/apache/cloudstack/api/response/VmwareDatacenterResponse.java
new file mode 100644
index 0000000..420320b
--- /dev/null
+++ b/plugins/hypervisors/vmware/src/org/apache/cloudstack/api/response/VmwareDatacenterResponse.java
@@ -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;
+    }
+}


Mime
View raw message