You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by sa...@apache.org on 2013/05/05 04:49:01 UTC
[09/11] git commit: updated refs/heads/vmware-datamodel to 3201dbf
CLOUDSTACK-1963 New mapping model for CloudStack zone and Vmware datacenter
Plugin, API & DB changes
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/7a8003e1
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/7a8003e1
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/7a8003e1
Branch: refs/heads/vmware-datamodel
Commit: 7a8003e1dad3c39396da46761154d6830e899583
Parents: 63f3ccd
Author: Sateesh Chodapuneedi <sa...@apache.org>
Authored: Fri May 3 22:38:57 2013 +0530
Committer: Sateesh Chodapuneedi <sa...@apache.org>
Committed: Sat May 4 23:23:50 2013 +0530
----------------------------------------------------------------------
client/tomcatconf/nonossComponentContext.xml.in | 2 +
.../cloud/hypervisor/vmware/VmwareDatacenter.java | 23 ++
.../hypervisor/vmware/VmwareDatacenterService.java | 15 +
.../hypervisor/vmware/VmwareDatacenterVO.java | 155 ++++++++
.../hypervisor/vmware/VmwareDatacenterZoneMap.java | 13 +
.../vmware/VmwareDatacenterZoneMapVO.java | 77 ++++
.../hypervisor/vmware/VmwareServerDiscoverer.java | 80 ++++-
.../hypervisor/vmware/dao/VmwareDatacenterDao.java | 48 +++
.../vmware/dao/VmwareDatacenterDaoImpl.java | 87 +++++
.../vmware/dao/VmwareDatacenterZoneMapDao.java | 18 +
.../vmware/dao/VmwareDatacenterZoneMapDaoImpl.java | 61 +++
.../vmware/manager/VmwareManagerImpl.java | 302 ++++++++++++++-
.../api/command/admin/zone/AddVmwareDcCmd.java | 103 +++++
.../api/command/admin/zone/RemoveVmwareDcCmd.java | 80 ++++
.../api/response/VmwareDatacenterResponse.java | 34 ++
setup/db/db/schema-410to420.sql | 18 +
.../hypervisor/vmware/mo/CustomFieldConstants.java | 1 +
.../cloud/hypervisor/vmware/mo/DatacenterMO.java | 5 +
18 files changed, 1118 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7a8003e1/client/tomcatconf/nonossComponentContext.xml.in
----------------------------------------------------------------------
diff --git a/client/tomcatconf/nonossComponentContext.xml.in b/client/tomcatconf/nonossComponentContext.xml.in
index ff52457..6d97b9c 100644
--- a/client/tomcatconf/nonossComponentContext.xml.in
+++ b/client/tomcatconf/nonossComponentContext.xml.in
@@ -77,6 +77,8 @@
</bean>
<bean id="VmwareManager" class="com.cloud.hypervisor.vmware.manager.VmwareManagerImpl"/>
<bean id="vmwareContextFactory" class="com.cloud.hypervisor.vmware.resource.VmwareContextFactory" />
+ <bean id="VmwareDatacenterDaoImpl" class="com.cloud.hypervisor.vmware.dao.VmwareDatacenterDaoImpl" />
+ <bean id="VmwareDatacenterZoneMapDaoImpl" class="com.cloud.hypervisor.vmware.dao.VmwareDatacenterZoneMapDaoImpl" />
<!--
Nicira support components
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7a8003e1/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareDatacenter.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareDatacenter.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareDatacenter.java
new file mode 100644
index 0000000..246b477
--- /dev/null
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareDatacenter.java
@@ -0,0 +1,23 @@
+package com.cloud.hypervisor.vmware;
+
+import org.apache.cloudstack.api.Identity;
+import org.apache.cloudstack.api.InternalIdentity;
+
+import com.vmware.vim25.ManagedObjectReference;
+
+public interface VmwareDatacenter extends Identity, InternalIdentity {
+
+ String getVmwareDatacenterName();
+
+ ManagedObjectReference getVmwareDatacenterMor();
+
+ String getGuid();
+
+ String getVcenterHost();
+
+ long getId();
+
+ String getPassword();
+
+ String getUser();
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7a8003e1/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..f04b2b5
--- /dev/null
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareDatacenterService.java
@@ -0,0 +1,15 @@
+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, Exception;
+
+ public boolean removeVmwareDatacenter(RemoveVmwareDcCmd cmd) throws IllegalArgumentException, ResourceInUseException, Exception;
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7a8003e1/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareDatacenterVO.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareDatacenterVO.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareDatacenterVO.java
new file mode 100644
index 0000000..aaeccc2
--- /dev/null
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareDatacenterVO.java
@@ -0,0 +1,155 @@
+package com.cloud.hypervisor.vmware;
+
+import java.util.UUID;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.db.Encrypt;
+import com.vmware.vim25.ManagedObjectReference;
+
+/**
+ * VmwareDatacenterVO contains information of Vmware Datacenter associated with a CloudStack zone.
+ */
+
+@Entity
+@Table(name="vmware_data_center")
+public class VmwareDatacenterVO implements VmwareDatacenter {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "id")
+ private long id;
+
+ @Column(name = "guid")
+ private String guid;
+
+ @Column(name = "name")
+ private String name;
+
+ @Column(name = "vcenter_host")
+ private String vCenterHost;
+
+ @Column(name = "uuid")
+ private String uuid;
+
+ @Column(name = "username")
+ private String user;
+
+ @Encrypt
+ @Column(name = "password")
+ private String password;
+
+ @Override
+ public String getUuid() {
+ return uuid;
+ }
+
+ @Override
+ public long getId() {
+ return id;
+ }
+
+ @Override
+ public String getVmwareDatacenterName() {
+ return name;
+ }
+
+ @Override
+ public String getGuid() {
+ return guid;
+ }
+
+ @Override
+ public String getUser() {
+ return user;
+ }
+
+ @Override
+ public String getPassword() {
+ return password;
+ }
+
+ @Override
+ public ManagedObjectReference getVmwareDatacenterMor() {
+ String morString = guid.split("@")[0];
+ ManagedObjectReference mor = new ManagedObjectReference();
+
+ mor.setType(morString.split(":")[0]);
+ mor.setValue(morString.split(":")[1]);
+
+ return mor;
+ }
+
+ @Override
+ public String getVcenterHost() {
+ return vCenterHost;
+ }
+
+ public void setUuid(String uuid) {
+ this.uuid = uuid;
+ }
+
+ public void setGuid(String guid) {
+ this.guid = guid;
+ }
+
+ public void setVmwareDatacenterName(String name) {
+ this.name = name;
+ }
+
+ public void setVcenterHost(String vCenterHost) {
+ this.vCenterHost = vCenterHost;
+ }
+
+ public void setUser(String user) {
+ this.user = user; ;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ @Override
+ public String toString() {
+ return new StringBuilder("VmwareDatacenter[").append(guid).append("]").toString();
+ }
+
+ @Override
+ public int hashCode() {
+ return NumbersUtil.hash(id);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof VmwareDatacenterVO) {
+ return ((VmwareDatacenterVO)obj).getId() == this.getId();
+ } else {
+ return false;
+ }
+ }
+
+ public VmwareDatacenterVO(String guid, String name, String vCenterHost, String user, String password) {
+ this.uuid = UUID.randomUUID().toString();
+ this.name = name;
+ this.guid = guid;
+ this.vCenterHost = vCenterHost;
+ this.user = user;
+ this.password = password;
+ }
+
+ public VmwareDatacenterVO(long id, String guid, String name, String vCenterHost, String user, String password) {
+ this(guid, name, vCenterHost, user, password);
+ this.id = id;
+ }
+
+ public VmwareDatacenterVO() {
+ this.uuid = UUID.randomUUID().toString();
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7a8003e1/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareDatacenterZoneMap.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareDatacenterZoneMap.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareDatacenterZoneMap.java
new file mode 100644
index 0000000..840c633
--- /dev/null
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareDatacenterZoneMap.java
@@ -0,0 +1,13 @@
+package com.cloud.hypervisor.vmware;
+
+import org.apache.cloudstack.api.InternalIdentity;
+
+import com.cloud.org.Grouping;
+
+public interface VmwareDatacenterZoneMap extends Grouping, InternalIdentity {
+ public long getId();
+
+ public long getZoneId();
+
+ public long getVmwareDcId();
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7a8003e1/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareDatacenterZoneMapVO.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareDatacenterZoneMapVO.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareDatacenterZoneMapVO.java
new file mode 100644
index 0000000..e20386d
--- /dev/null
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/VmwareDatacenterZoneMapVO.java
@@ -0,0 +1,77 @@
+//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 javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+
+//NOTE: This particular table is totally internal to the CS MS.
+//Do not ever include a uuid/guid field in this table. We just
+//need it map zone ids with VMware datacenter Ids.
+
+@Entity
+@Table(name="vmware_data_center_zone_map")
+public class VmwareDatacenterZoneMapVO implements VmwareDatacenterZoneMap {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name="id")
+ private long id;
+
+ @Column(name="zone_id")
+ private long zoneId;
+
+ @Column(name="vmware_data_center_id")
+ private long vmwareDcId;
+
+ public VmwareDatacenterZoneMapVO(long zoneId, long vmwareDcId) {
+ this.zoneId = zoneId;
+ this.vmwareDcId = vmwareDcId;
+ }
+
+ public VmwareDatacenterZoneMapVO() {
+ // Do nothing.
+ }
+
+ @Override
+ public long getId() {
+ return id;
+ }
+
+ @Override
+ public long getZoneId() {
+ return zoneId;
+ }
+
+ @Override
+ public long getVmwareDcId() {
+ return vmwareDcId;
+ }
+
+ public void setZoneId(long zoneId) {
+ this.zoneId = zoneId;
+ }
+
+ public void setVsmId(long vmwareDcId) {
+ this.vmwareDcId = vmwareDcId;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7a8003e1/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/7a8003e1/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/dao/VmwareDatacenterDao.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/dao/VmwareDatacenterDao.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/dao/VmwareDatacenterDao.java
new file mode 100644
index 0000000..e339604
--- /dev/null
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/dao/VmwareDatacenterDao.java
@@ -0,0 +1,48 @@
+package com.cloud.hypervisor.vmware.dao;
+
+import java.util.List;
+
+import com.cloud.hypervisor.vmware.VmwareDatacenterVO;
+import com.cloud.utils.db.GenericDao;
+
+public interface VmwareDatacenterDao extends GenericDao<VmwareDatacenterVO, Long> {
+
+ /**
+ * Return a VMware Datacenter given guid
+ * @param guid of VMware datacenter
+ * @return VmwareDatacenterVO for the VMware datacenter having the specified guid.
+ */
+ VmwareDatacenterVO getVmwareDatacenterByGuid(String guid);
+
+ /**
+ * Return a VMware Datacenter given name and vCenter host.
+ * For legacy zones multiple records will be present in the table.
+ * @param name of VMware datacenter
+ * @param vCenter host
+ * @return VmwareDatacenterVO for the VMware datacenter with given name and
+ * belonging to specified vCenter host.
+ */
+ List<VmwareDatacenterVO> getVmwareDatacenterByNameAndVcenter(String name, String vCenterHost);
+
+ /**
+ * Return a list of VMware Datacenter given name.
+ * @param name of Vmware datacenter
+ * @return list of VmwareDatacenterVO for VMware datacenters having the specified name.
+ */
+ List<VmwareDatacenterVO> listVmwareDatacenterByName(String name);
+
+ /**
+ * Return a list of VMware Datacenters belonging to specified vCenter
+ * @param vCenter Host
+ * @return list of VmwareDatacenterVO for all VMware datacenters belonging to
+ * specified vCenter
+ */
+ List<VmwareDatacenterVO> listVmwareDatacenterByVcenter(String vCenterHost);
+
+ /**
+ * Lists all associated VMware datacenter on the management server.
+ * @return list of VmwareDatacenterVO for all associated VMware datacenters
+ */
+ List<VmwareDatacenterVO> listAllVmwareDatacenters();
+
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7a8003e1/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/dao/VmwareDatacenterDaoImpl.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/dao/VmwareDatacenterDaoImpl.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/dao/VmwareDatacenterDaoImpl.java
new file mode 100644
index 0000000..b8fa715
--- /dev/null
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/dao/VmwareDatacenterDaoImpl.java
@@ -0,0 +1,87 @@
+package com.cloud.hypervisor.vmware.dao;
+
+import java.util.List;
+
+import javax.ejb.Local;
+
+import org.apache.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import com.cloud.hypervisor.vmware.VmwareDatacenterVO;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria.Op;
+
+@Component
+@Local(value=VmwareDatacenterDao.class) @DB(txn=false)
+public class VmwareDatacenterDaoImpl extends GenericDaoBase<VmwareDatacenterVO, Long> implements VmwareDatacenterDao {
+ protected static final Logger s_logger = Logger.getLogger(VmwareDatacenterDaoImpl.class);
+
+ final SearchBuilder<VmwareDatacenterVO> nameSearch;
+ final SearchBuilder<VmwareDatacenterVO> guidSearch;
+ final SearchBuilder<VmwareDatacenterVO> vcSearch;
+ final SearchBuilder<VmwareDatacenterVO> nameVcSearch;
+ final SearchBuilder<VmwareDatacenterVO> fullTableSearch;
+
+ public VmwareDatacenterDaoImpl() {
+ super();
+
+ nameSearch = createSearchBuilder();
+ nameSearch.and("name", nameSearch.entity().getVmwareDatacenterName(), Op.EQ);
+ nameSearch.done();
+
+ nameVcSearch = createSearchBuilder();
+ nameVcSearch.and("name", nameVcSearch.entity().getVmwareDatacenterName(), Op.EQ);
+ nameVcSearch.and("vCenterHost", nameVcSearch.entity().getVcenterHost(), Op.EQ);
+ nameVcSearch.done();
+
+ vcSearch = createSearchBuilder();
+ vcSearch.and("vCenterHost", vcSearch.entity().getVcenterHost(), Op.EQ);
+ vcSearch.done();
+
+ guidSearch = createSearchBuilder();
+ guidSearch.and("guid", guidSearch.entity().getGuid(), Op.EQ);
+ guidSearch.done();
+
+ fullTableSearch = createSearchBuilder();
+ fullTableSearch.done();
+ }
+
+ @Override
+ public VmwareDatacenterVO getVmwareDatacenterByGuid(String guid) {
+ SearchCriteria<VmwareDatacenterVO> sc = guidSearch.create();
+ sc.setParameters("guid", guid);
+ return findOneBy(sc);
+ }
+
+ @Override
+ public List<VmwareDatacenterVO> getVmwareDatacenterByNameAndVcenter(String name, String vCenterHost) {
+ SearchCriteria<VmwareDatacenterVO> sc = guidSearch.create();
+ sc.setParameters("name", name);
+ sc.setParameters("vCenterHost", vCenterHost);
+ return search(sc, null);
+ }
+
+ @Override
+ public List<VmwareDatacenterVO> listVmwareDatacenterByName(String name) {
+ SearchCriteria<VmwareDatacenterVO> sc = guidSearch.create();
+ sc.setParameters("name", name);
+ return search(sc, null);
+ }
+
+ @Override
+ public List<VmwareDatacenterVO> listVmwareDatacenterByVcenter(String vCenterHost) {
+ SearchCriteria<VmwareDatacenterVO> sc = vcSearch.create();
+ sc.setParameters("vCenterHost", vCenterHost);
+ return search(sc, null);
+ }
+
+ @Override
+ public List<VmwareDatacenterVO> listAllVmwareDatacenters() {
+ SearchCriteria<VmwareDatacenterVO> sc = fullTableSearch.create();
+ return search(sc, null);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7a8003e1/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/dao/VmwareDatacenterZoneMapDao.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/dao/VmwareDatacenterZoneMapDao.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/dao/VmwareDatacenterZoneMapDao.java
new file mode 100644
index 0000000..dff9bb0
--- /dev/null
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/dao/VmwareDatacenterZoneMapDao.java
@@ -0,0 +1,18 @@
+package com.cloud.hypervisor.vmware.dao;
+
+import com.cloud.hypervisor.vmware.VmwareDatacenterZoneMapVO;
+import com.cloud.utils.db.GenericDao;
+
+public interface VmwareDatacenterZoneMapDao extends GenericDao<VmwareDatacenterZoneMapVO, Long> {
+ /**
+ * @param id of zone
+ * @return map object of VMware datacenter & zone
+ */
+ VmwareDatacenterZoneMapVO findByZoneId(long zoneId);
+
+ /**
+ * @param id of VMware datacenter
+ * @return map object of VMware datacenter & zone
+ */
+ VmwareDatacenterZoneMapVO findByVmwareDcId(long vmwareDcId);
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7a8003e1/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/dao/VmwareDatacenterZoneMapDaoImpl.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/dao/VmwareDatacenterZoneMapDaoImpl.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/dao/VmwareDatacenterZoneMapDaoImpl.java
new file mode 100644
index 0000000..1c13269
--- /dev/null
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/dao/VmwareDatacenterZoneMapDaoImpl.java
@@ -0,0 +1,61 @@
+//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.dao;
+
+import javax.ejb.Local;
+
+import org.springframework.stereotype.Component;
+
+import com.cloud.hypervisor.vmware.VmwareDatacenterZoneMapVO;
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria.Op;
+
+@Component
+@Local(value=VmwareDatacenterZoneMapDao.class)
+public class VmwareDatacenterZoneMapDaoImpl extends GenericDaoBase<VmwareDatacenterZoneMapVO, Long>
+ implements VmwareDatacenterZoneMapDao {
+
+ protected final SearchBuilder<VmwareDatacenterZoneMapVO> zoneSearch;
+ protected final SearchBuilder<VmwareDatacenterZoneMapVO> vmwareDcSearch;
+
+ public VmwareDatacenterZoneMapDaoImpl() {
+ zoneSearch = createSearchBuilder();
+ zoneSearch.and("zoneId", zoneSearch.entity().getZoneId(), Op.EQ);
+ zoneSearch.done();
+
+ vmwareDcSearch = createSearchBuilder();
+ vmwareDcSearch.and("vmwareDcId", vmwareDcSearch.entity().getVmwareDcId(), Op.EQ);
+ vmwareDcSearch.done();
+ }
+
+ @Override
+ public VmwareDatacenterZoneMapVO findByZoneId(long zoneId) {
+ SearchCriteria<VmwareDatacenterZoneMapVO> sc = zoneSearch.create();
+ sc.setParameters("zoneId", zoneId);
+ return findOneBy(sc);
+ }
+
+ @Override
+ public VmwareDatacenterZoneMapVO findByVmwareDcId(long vmwareDcId) {
+ SearchCriteria<VmwareDatacenterZoneMapVO> sc = vmwareDcSearch.create();
+ sc.setParameters("vmwareDcId", vmwareDcId);
+ return findOneBy(sc);
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7a8003e1/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..3b94537 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,279 @@ 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 Exception {
+ 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");
+
+ // Check if the zone exists in the system
+ // If no, throw invalid param value exception
+ DataCenterVO zone = _dcDao.findById(zoneId);
+ if (zone == null) {
+ InvalidParameterValueException ex = new InvalidParameterValueException(
+ "Can't find zone by the id specified");
+ ex.addProxyObject(zone, zoneId, "dcId");
+ throw ex;
+ }
+
+ 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.");
+ }
+
+ // Check if zone has resources? - For now look for clusters
+ // If yes, throw resource in use execption
+ List<ClusterVO> clusters = _clusterDao.listByZoneId(zoneId);
+ if (clusters != null) {
+ try {
+ if (clusters.size() > 0) {
+ throw new ResourceInUseException("Zone has one or more clusters."
+ + " Can't add VMware datacenter to zone which already has clusters.");
+ }}catch(Throwable t) {
+ s_logger.error(t);
+ }
+ }
+
+ // 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
+ dcMor = dcMo.getMor();
+ guid = dcMor.getType() + ":" + dcMor.getValue() + "@" + 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 Exception {
+ 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");
+ ex.addProxyObject(zone, zoneId, "dcId");
+ throw ex;
+ }
+
+ // Check if zone has resources? - For now look for clusters
+ List<ClusterVO> clusters = _clusterDao.listByZoneId(zoneId);
+ if(clusters != null && clusters.size() != 0) {
+ 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/7a8003e1/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..3d9101b
--- /dev/null
+++ b/plugins/hypervisors/vmware/src/org/apache/cloudstack/api/command/admin/zone/AddVmwareDcCmd.java
@@ -0,0 +1,103 @@
+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;
+
+@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 (Exception e) {
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7a8003e1/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..cf54698
--- /dev/null
+++ b/plugins/hypervisors/vmware/src/org/apache/cloudstack/api/command/admin/zone/RemoveVmwareDcCmd.java
@@ -0,0 +1,80 @@
+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;
+
+@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 (Exception e) {
+ }
+ }
+
+ @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/7a8003e1/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..151d037
--- /dev/null
+++ b/plugins/hypervisors/vmware/src/org/apache/cloudstack/api/response/VmwareDatacenterResponse.java
@@ -0,0 +1,34 @@
+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;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7a8003e1/setup/db/db/schema-410to420.sql
----------------------------------------------------------------------
diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql
index 99b476d..5f90a55a 100644
--- a/setup/db/db/schema-410to420.sql
+++ b/setup/db/db/schema-410to420.sql
@@ -915,6 +915,24 @@ CREATE TABLE `cloud`.`network_asa1000v_map` (
CONSTRAINT `fk_network_asa1000v_map__asa1000v_id` FOREIGN KEY (`asa1000v_id`) REFERENCES `external_cisco_asa1000v_devices`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+CREATE TABLE `cloud`.`vmware_data_center` (
+ `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
+ `uuid` varchar(255) UNIQUE,
+ `name` varchar(255) NOT NULL COMMENT 'Name of VMware datacenter',
+ `guid` varchar(255) NOT NULL UNIQUE COMMENT 'id of VMware datacenter',
+ `vcenter_host` varchar(255) NOT NULL COMMENT 'vCenter host containing this VMware datacenter',
+ `username` varchar(255) NOT NULL COMMENT 'Name of vCenter host user',
+ `password` varchar(255) NOT NULL COMMENT 'Password of vCenter host user',
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+CREATE TABLE `cloud`.`vmware_data_center_zone_map` (
+ `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
+ `zone_id` bigint unsigned NOT NULL UNIQUE COMMENT 'id of CloudStack zone',
+ `vmware_data_center_id` bigint unsigned NOT NULL UNIQUE COMMENT 'id of VMware datacenter',
+ PRIMARY KEY (`id`),
+ CONSTRAINT `fk_vmware_data_center_zone_map__vmware_data_center_id` FOREIGN KEY (`vmware_data_center_id`) REFERENCES `vmware_data_center`(`id`) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `cloud`.`network_offerings` ADD COLUMN `eip_associate_public_ip` int(1) unsigned NOT NULL DEFAULT 0 COMMENT 'true if public IP is associated with user VM creation by default when EIP service is enabled.' AFTER `elastic_ip_service`;
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7a8003e1/vmware-base/src/com/cloud/hypervisor/vmware/mo/CustomFieldConstants.java
----------------------------------------------------------------------
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/CustomFieldConstants.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/CustomFieldConstants.java
index 4cd5f9b..11bc157 100644
--- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/CustomFieldConstants.java
+++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/CustomFieldConstants.java
@@ -21,4 +21,5 @@ public interface CustomFieldConstants {
public final static String CLOUD_GC = "cloud.gc";
public final static String CLOUD_GC_DVP = "cloud.gc.dvp";
public final static String CLOUD_NIC_MASK = "cloud.nic.mask";
+ public final static String CLOUD_ZONE = "cloud.zone";
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/7a8003e1/vmware-base/src/com/cloud/hypervisor/vmware/mo/DatacenterMO.java
----------------------------------------------------------------------
diff --git a/vmware-base/src/com/cloud/hypervisor/vmware/mo/DatacenterMO.java b/vmware-base/src/com/cloud/hypervisor/vmware/mo/DatacenterMO.java
index 0a3e20b..cabb60a 100755
--- a/vmware-base/src/com/cloud/hypervisor/vmware/mo/DatacenterMO.java
+++ b/vmware-base/src/com/cloud/hypervisor/vmware/mo/DatacenterMO.java
@@ -488,4 +488,9 @@ public class DatacenterMO extends BaseMO {
dvSwitchMor = _context.getVimClient().getDecendentMoRef(networkFolderMor, "VmwareDistributedVirtualSwitch", dvSwitchName);
return dvSwitchMor;
}
+
+ public boolean ensureCustomFieldDef(String fieldName) throws Exception {
+ CustomFieldsManagerMO cfmMo = new CustomFieldsManagerMO(_context, _context.getServiceContent().getCustomFieldsManager());
+ return cfmMo.ensureCustomFieldDef("Datacenter", fieldName) > 0;
+ }
}