@Override public boolean removeVmwareDatacenter(RemoveVmwareDcCmd cmd) throws ResourceInUseException { Long zoneId = cmd.getZoneId(); // Validate zone validateZone(zoneId); // Zone validation to check if the zone already has resources. // Association of VMware DC to zone is not allowed if zone already has resources added. validateZoneWithResources(zoneId, "remove VMware datacenter to 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 = "Unable 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; }
@Override @DB public VmwareDatacenterVO addVmwareDatacenter(AddVmwareDcCmd cmd) throws ResourceInUseException { VmwareDatacenterVO vmwareDc = null; Long zoneId = cmd.getZoneId(); String userName = cmd.getUsername(); String password = cmd.getPassword(); String vCenterHost = cmd.getVcenter(); String vmwareDcName = cmd.getName(); // Validate username, password, VMware DC name and vCenter if (userName == null) { throw new InvalidParameterValueException("Missing or invalid parameter username."); } if (password == null) { throw new InvalidParameterValueException("Missing or invalid parameter username."); } if (vmwareDcName == null) { throw new InvalidParameterValueException( "Missing or invalid parameter name. Please provide valid VMware datacenter name."); } if (vCenterHost == null) { throw new InvalidParameterValueException( "Missing or invalid parameter name. " + "Please provide valid VMware vCenter server's IP address or fully qualified domain name."); } if (zoneId == null) { throw new InvalidParameterValueException( "Missing or invalid parameter name. " + "Please provide valid zone id."); } // Zone validation validateZone(zoneId); VmwareDatacenterZoneMapVO vmwareDcZoneMap = _vmwareDcZoneMapDao.findByZoneId(zoneId); // Check if zone is associated with VMware DC if (vmwareDcZoneMap != null) { // Check if the associated VMware DC matches the one specified in API params // This check would yield success as the association exists between same entities (zone and // VMware DC) // This scenario would result in if the API addVmwareDc is called more than once with same // parameters. Long associatedVmwareDcId = vmwareDcZoneMap.getVmwareDcId(); VmwareDatacenterVO associatedVmwareDc = _vmwareDcDao.findById(associatedVmwareDcId); if (associatedVmwareDc.getVcenterHost().equalsIgnoreCase(vCenterHost) && associatedVmwareDc.getVmwareDatacenterName().equalsIgnoreCase(vmwareDcName)) { s_logger.info( "Ignoring API call addVmwareDc, because VMware DC " + vCenterHost + "/" + vmwareDcName + " is already associated with specified zone with id " + zoneId); return associatedVmwareDc; } else { throw new CloudRuntimeException( "Zone " + zoneId + " is already associated with a VMware datacenter. " + "Only 1 VMware DC can be associated with a zone."); } } // Zone validation to check if the zone already has resources. // Association of VMware DC to zone is not allowed if zone already has resources added. validateZoneWithResources(zoneId, "add VMware datacenter to zone"); // Check if DC is already part of zone // In that case vmware_data_center table should have the DC vmwareDc = _vmwareDcDao.getVmwareDatacenterByGuid(vmwareDcName + "@" + vCenterHost); if (vmwareDc != null) { 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 dcMo = new DatacenterMO(context, vmwareDcName); dcMor = dcMo.getMor(); if (dcMor == null) { String msg = "Unable to find VMware DC " + vmwareDcName + " in vCenter " + vCenterHost + ". "; s_logger.error(msg); throw new InvalidParameterValueException(msg); } // 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 (Throwable e) { String msg = "Failed to add VMware DC to zone "; if (e instanceof RemoteException) { msg = "Encountered remote exception at vCenter. " + VmwareHelper.getExceptionMessage(e); } else { msg += "due to : " + e.getMessage(); } throw new CloudRuntimeException(msg); } finally { if (context != null) { context.close(); } context = null; } return vmwareDc; }