Merging changes from zonesfeature branch for Bug 8026 - discern proper cluster/pod/zone for added host (and refactor AgentManagerImpl)

- CreateZone API creates a zoneToken, inserts in DB and returns it in the
response

- UpdateZone API takes in 'details' map that is loaded to data_center_details
This commit is contained in:
prachi 2011-04-28 23:08:58 -07:00
parent 11ef6bbbe2
commit 86b386e8c0
17 changed files with 165 additions and 27 deletions

View File

@ -43,6 +43,7 @@ public class StartupCommand extends Command {
String storageNetmaskDeux;
String agentTag;
String resourceName;
String gatewayIpAddress;
public StartupCommand(Host.Type type) {
this.type = type;
@ -59,6 +60,11 @@ public class StartupCommand extends Command {
this.type = type;
}
public StartupCommand(Long id, Host.Type type, String name, String dataCenter, String pod, String guid, String version, String gatewayIpAddress) {
this(id, type, name, dataCenter, pod, guid, version);
this.gatewayIpAddress = gatewayIpAddress;
}
public Host.Type getHostType() {
return type;
}
@ -265,7 +271,13 @@ public class StartupCommand extends Command {
return resourceName;
}
public String getGatewayIpAddress() {
return gatewayIpAddress;
}
public void setGatewayIpAddress(String gatewayIpAddress) {
this.gatewayIpAddress = gatewayIpAddress;
}
@Override
public boolean executeInSequence() {

View File

@ -226,4 +226,5 @@ public class ApiConstants {
public static final String CHECKSUM="checksum";
public static final String NETWORK_DEVICE_TYPE = "networkdevicetype";
public static final String NETWORK_DEVICE_PARAMETER_LIST = "networkdeviceparameterlist";
public static final String ZONE_TOKEN = "zonetoken";
}

View File

@ -18,6 +18,8 @@
package com.cloud.api.commands;
import java.util.Map;
import org.apache.log4j.Logger;
import com.cloud.api.ApiConstants;
@ -68,7 +70,11 @@ public class UpdateZoneCmd extends BaseCmd {
private Boolean isPublic;
@Parameter(name=ApiConstants.ALLOCATION_STATE, type=CommandType.STRING, description="Allocation state of this cluster for allocation of new resources")
private String allocationState;
private String allocationState;
@Parameter(name=ApiConstants.DETAILS, type=CommandType.MAP, description="the details for the Zone")
private Map details;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
@ -112,6 +118,10 @@ public class UpdateZoneCmd extends BaseCmd {
public String getAllocationState() {
return allocationState;
}
public Map getDetails() {
return details;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////

View File

@ -69,7 +69,10 @@ public class ZoneResponse extends BaseResponse {
private boolean securityGroupsEnabled;
@SerializedName("allocationstate") @Param(description="the allocation state of the cluster")
private String allocationState;
private String allocationState;
@SerializedName(ApiConstants.ZONE_TOKEN) @Param(description="Zone Token")
private String zoneToken;
public Long getId() {
return id;
@ -197,5 +200,13 @@ public class ZoneResponse extends BaseResponse {
public void setAllocationState(String allocationState) {
this.allocationState = allocationState;
}
}
public String getZoneToken() {
return zoneToken;
}
public void setZoneToken(String zoneToken) {
this.zoneToken = zoneToken;
}
}

View File

@ -57,5 +57,6 @@ public interface DataCenter extends Grouping {
Map<String, String> getDetails();
void setDetails(Map<String, String> details);
AllocationState getAllocationState();
String getZoneToken();
}

View File

@ -767,6 +767,7 @@ public class ApiResponseHelper implements ResponseGenerator {
zoneResponse.setDomainId(dataCenter.getDomainId());
zoneResponse.setType(dataCenter.getNetworkType().toString());
zoneResponse.setAllocationState(dataCenter.getAllocationState().toString());
zoneResponse.setZoneToken(dataCenter.getZoneToken());
zoneResponse.setObjectName("zone");
return zoneResponse;
}

View File

@ -94,10 +94,10 @@ public interface ConfigurationManager extends ConfigurationService, Manager {
* @param startIp
* @param endIp
* @param allocationState
* @param skipGatewayOverlapCheck (true if it is ok to not validate that gateway IP address overlap with Start/End IP of the POD)
* @return Pod
*/
HostPodVO createPod(long userId, String podName, long zoneId, String gateway, String cidr, String startIp, String endIp, String allocationState);
HostPodVO createPod(long userId, String podName, long zoneId, String gateway, String cidr, String startIp, String endIp, String allocationState, boolean skipGatewayOverlapCheck);
/**
* Creates a new zone

View File

@ -21,11 +21,14 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import javax.ejb.Local;
import javax.naming.ConfigurationException;
@ -506,7 +509,7 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
}
}
private void checkPodAttributes(long podId, String podName, long zoneId, String gateway, String cidr, String startIp, String endIp, String allocationStateStr, boolean checkForDuplicates) {
private void checkPodAttributes(long podId, String podName, long zoneId, String gateway, String cidr, String startIp, String endIp, String allocationStateStr, boolean checkForDuplicates, boolean skipGatewayOverlapCheck) {
if (checkForDuplicates) {
// Check if the pod already exists
if (validPod(podName, zoneId)) {
@ -540,8 +543,10 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
}
// Don't allow gateway to overlap with start/endIp
if (NetUtils.ipRangesOverlap(startIp, endIp, gateway, gateway)) {
throw new InvalidParameterValueException("The gateway shouldn't overlap start/end ip addresses");
if(!skipGatewayOverlapCheck){
if (NetUtils.ipRangesOverlap(startIp, endIp, gateway, gateway)) {
throw new InvalidParameterValueException("The gateway shouldn't overlap start/end ip addresses");
}
}
String checkPodCIDRs = _configDao.getValue("check.pod.cidrs");
@ -717,7 +722,7 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
// Verify pod's attributes
String cidr = NetUtils.ipAndNetMaskToCidr(gateway, netmask);
boolean checkForDuplicates = !oldPodName.equals(name);
checkPodAttributes(id, name, pod.getDataCenterId(), gateway, cidr, startIp, endIp, allocationStateStr, checkForDuplicates);
checkPodAttributes(id, name, pod.getDataCenterId(), gateway, cidr, startIp, endIp, allocationStateStr, checkForDuplicates, false);
Transaction txn = Transaction.currentTxn();
try {
@ -789,12 +794,12 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
if (allocationState == null) {
allocationState = Grouping.AllocationState.Enabled.toString();
}
return createPod(userId.longValue(), name, zoneId, gateway, cidr, startIp, endIp, allocationState);
return createPod(userId.longValue(), name, zoneId, gateway, cidr, startIp, endIp, allocationState, false);
}
@Override
@DB
public HostPodVO createPod(long userId, String podName, long zoneId, String gateway, String cidr, String startIp, String endIp, String allocationStateStr) {
public HostPodVO createPod(long userId, String podName, long zoneId, String gateway, String cidr, String startIp, String endIp, String allocationStateStr, boolean skipGatewayOverlapCheck) {
// Check if the zone is valid
if (!validZone(zoneId)) {
@ -819,7 +824,7 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
}
// Validate new pod settings
checkPodAttributes(-1, podName, zoneId, gateway, cidr, startIp, endIp, allocationStateStr, true);
checkPodAttributes(-1, podName, zoneId, gateway, cidr, startIp, endIp, allocationStateStr, true, skipGatewayOverlapCheck);
// Create the new pod in the database
String ipRange;
@ -1083,6 +1088,26 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
int stopVnetRange = 0;
Boolean isPublic = cmd.isPublic();
String allocationStateStr = cmd.getAllocationState();
Map detailsMap = cmd.getDetails();
Map<String, String> newDetails = new HashMap<String, String>();
if (detailsMap != null) {
Collection zoneDetailsCollection = detailsMap.values();
Iterator iter = zoneDetailsCollection.iterator();
while (iter.hasNext()) {
HashMap detail = (HashMap)iter.next();
String key = (String)detail.get("key");
String value = (String)detail.get("value");
if ((key == null) || (value == null)) {
throw new InvalidParameterValueException("Invalid Zone Detail specified, fields 'key' and 'value' cannot be null, please specify details in the form: details[0].key=XXX&details[0].value=YYY");
}
//validate the zone detail keys are known keys
/*if(!ZoneConfig.doesKeyExist(key)){
throw new InvalidParameterValueException("Invalid Zone Detail parameter: "+ key);
}*/
newDetails.put(key, value);
}
}
if (userId == null) {
userId = Long.valueOf(User.UID_SYSTEM);
@ -1205,6 +1230,14 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
zone.setDomainId(null);
zone.setDomain(null);
}
Map<String, String> updatedDetails = new HashMap<String, String>();
_zoneDao.loadDetails(zone);
if(zone.getDetails() != null){
updatedDetails.putAll(zone.getDetails());
}
updatedDetails.putAll(newDetails);
zone.setDetails(updatedDetails);
if (allocationStateStr != null && !allocationStateStr.isEmpty()) {
Grouping.AllocationState allocationState = Grouping.AllocationState.valueOf(allocationStateStr);
@ -1259,12 +1292,14 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
}
checkZoneParameters(zoneName, dns1, dns2, internalDns1, internalDns2, true, domainId, allocationStateStr);
byte[] bytes = (zoneName + System.currentTimeMillis()).getBytes();
String zoneToken = UUID.nameUUIDFromBytes(bytes).toString();
Transaction txn = Transaction.currentTxn();
try {
txn.start();
// Create the new zone in the database
DataCenterVO zone = new DataCenterVO(zoneName, null, dns1, dns2, internalDns1, internalDns2, vnetRange, guestCidr, domain, domainId, zoneType, isSecurityGroupEnabled);
DataCenterVO zone = new DataCenterVO(zoneName, null, dns1, dns2, internalDns1, internalDns2, vnetRange, guestCidr, domain, domainId, zoneType, isSecurityGroupEnabled, zoneToken);
if (allocationStateStr != null && !allocationStateStr.isEmpty()) {
Grouping.AllocationState allocationState = Grouping.AllocationState.valueOf(allocationStateStr);
zone.setAllocationState(allocationState);

View File

@ -55,6 +55,7 @@ import com.cloud.dc.dao.AccountVlanMapDaoImpl;
import com.cloud.dc.dao.ClusterDaoImpl;
import com.cloud.dc.dao.DataCenterDaoImpl;
import com.cloud.dc.dao.DataCenterIpAddressDaoImpl;
import com.cloud.dc.dao.DcDetailsDaoImpl;
import com.cloud.dc.dao.HostPodDaoImpl;
import com.cloud.dc.dao.PodVlanMapDaoImpl;
import com.cloud.dc.dao.VlanDaoImpl;
@ -269,6 +270,7 @@ public class DefaultComponentLibrary extends ComponentLibraryBase implements Com
addDao("HostTagsDao", HostTagsDaoImpl.class);
addDao("NetworkDomainDao", NetworkDomainDaoImpl.class);
addDao("KeystoreDao", KeystoreDaoImpl.class);
addDao("DcDetailsDao", DcDetailsDaoImpl.class);
}
@Override

View File

@ -109,6 +109,9 @@ public class DataCenterVO implements DataCenter {
@TableGenerator(name="mac_address_sq", table="data_center", pkColumnName="id", valueColumnName="mac_address", allocationSize=1)
private long macAddress = 1;
@Column(name="zone_token")
private String zoneToken;
// This is a delayed load value. If the value is null,
// then this field has not been loaded yet.
// Call the dao to load it.
@ -164,13 +167,13 @@ public class DataCenterVO implements DataCenter {
this.firewallProvider = firewallProvider;
}
public DataCenterVO(long id, String name, String description, String dns1, String dns2, String dns3, String dns4, String vnet, String guestCidr, String domain, Long domainId, NetworkType zoneType) {
this(name, description, dns1, dns2, dns3, dns4, vnet, guestCidr, domain, domainId, zoneType, false);
public DataCenterVO(long id, String name, String description, String dns1, String dns2, String dns3, String dns4, String vnet, String guestCidr, String domain, Long domainId, NetworkType zoneType, String zoneToken) {
this(name, description, dns1, dns2, dns3, dns4, vnet, guestCidr, domain, domainId, zoneType, false, zoneToken);
this.id = id;
this.allocationState = Grouping.AllocationState.Enabled;
}
public DataCenterVO(String name, String description, String dns1, String dns2, String dns3, String dns4, String vnet, String guestCidr, String domain, Long domainId, NetworkType zoneType, boolean securityGroupEnabled) {
public DataCenterVO(String name, String description, String dns1, String dns2, String dns3, String dns4, String vnet, String guestCidr, String domain, Long domainId, NetworkType zoneType, boolean securityGroupEnabled, String zoneToken) {
this.name = name;
this.description = description;
this.dns1 = dns1;
@ -198,6 +201,8 @@ public class DataCenterVO implements DataCenter {
dnsProvider = Provider.DhcpServer.getName();
userDataProvider = Provider.DhcpServer.getName();
}
this.zoneToken = zoneToken;
}
@ -383,5 +388,14 @@ public class DataCenterVO implements DataCenter {
}
DataCenterVO that = (DataCenterVO)obj;
return this.id == that.id;
}
}
@Override
public String getZoneToken() {
return zoneToken;
}
public void setZoneToken(String zoneToken) {
this.zoneToken = zoneToken;
}
}

View File

@ -73,4 +73,5 @@ public interface DataCenterDao extends GenericDao<DataCenterVO, Long> {
List<DataCenterVO> listDisabledZones();
List<DataCenterVO> listEnabledZones();
DataCenterVO findByToken(String zoneToken);
}

View File

@ -37,10 +37,12 @@ import com.cloud.org.Grouping;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.Pair;
import com.cloud.utils.component.ComponentLocator;
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.SequenceFetcher;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.net.NetUtils;
/**
@ -60,7 +62,8 @@ public class DataCenterDaoImpl extends GenericDaoBase<DataCenterVO, Long> implem
protected SearchBuilder<DataCenterVO> ChildZonesSearch;
protected SearchBuilder<DataCenterVO> securityGroupSearch;
protected SearchBuilder<DataCenterVO> DisabledZonesSearch;
protected SearchBuilder<DataCenterVO> TokenSearch;
protected final DataCenterIpAddressDaoImpl _ipAllocDao = ComponentLocator.inject(DataCenterIpAddressDaoImpl.class);
protected final DataCenterLinkLocalIpAddressDaoImpl _LinkLocalIpAllocDao = ComponentLocator.inject(DataCenterLinkLocalIpAddressDaoImpl.class);
protected final DataCenterVnetDaoImpl _vnetAllocDao = ComponentLocator.inject(DataCenterVnetDaoImpl.class);
@ -79,6 +82,13 @@ public class DataCenterDaoImpl extends GenericDaoBase<DataCenterVO, Long> implem
return findOneBy(sc);
}
@Override
public DataCenterVO findByToken(String zoneToken){
SearchCriteria<DataCenterVO> sc = TokenSearch.create();
sc.setParameters("zoneToken", zoneToken);
return findOneBy(sc);
}
@Override
public List<DataCenterVO> findZonesByDomainId(Long domainId){
SearchCriteria<DataCenterVO> sc = ListZonesByDomainIdSearch.create();
@ -273,10 +283,27 @@ public class DataCenterDaoImpl extends GenericDaoBase<DataCenterVO, Long> implem
DisabledZonesSearch.and("allocationState", DisabledZonesSearch.entity().getAllocationState(), SearchCriteria.Op.EQ);
DisabledZonesSearch.done();
TokenSearch = createSearchBuilder();
TokenSearch.and("zoneToken", TokenSearch.entity().getZoneToken(), SearchCriteria.Op.EQ);
TokenSearch.done();
_tgMacAddress = _tgs.get("macAddress");
assert _tgMacAddress != null : "Couldn't get mac address table generator";
}
@Override @DB
public boolean update(Long zoneId, DataCenterVO zone) {
Transaction txn = Transaction.currentTxn();
txn.start();
boolean persisted = super.update(zoneId, zone);
if (!persisted) {
return persisted;
}
saveDetails(zone);
txn.commit();
return persisted;
}
@Override
public void loadDetails(DataCenterVO zone) {
Map<String, String> details =_detailsDao.findDetails(zone.getId());

View File

@ -23,11 +23,11 @@ import com.cloud.dc.DcDetailVO;
import com.cloud.utils.db.GenericDao;
public interface DcDetailsDao extends GenericDao<DcDetailVO, Long> {
Map<String, String> findDetails(long hostId);
Map<String, String> findDetails(long dcId);
void persist(long hostId, Map<String, String> details);
void persist(long dcId, Map<String, String> details);
DcDetailVO findDetail(long hostId, String name);
DcDetailVO findDetail(long dcId, String name);
void deleteDetails(long hostId);
void deleteDetails(long dcId);
}

View File

@ -162,5 +162,6 @@ public interface HostDao extends GenericDao<HostVO, Long> {
void loadHostTags(HostVO host);
List<HostVO> listByHostTag(Host.Type type, Long clusterId, Long podId, long dcId, String hostTag);
long countRoutingHostsByDataCenter(long dcId);
}

View File

@ -49,6 +49,7 @@ import com.cloud.utils.db.GenericSearchBuilder;
import com.cloud.utils.db.JoinBuilder;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.SearchCriteria.Func;
import com.cloud.utils.db.SearchCriteria.Op;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.db.UpdateBuilder;
@ -87,6 +88,7 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
protected final SearchBuilder<HostVO> AvailHypevisorInZone;
protected final GenericSearchBuilder<HostVO, Long> HostsInStatusSearch;
protected final GenericSearchBuilder<HostVO, Long> CountRoutingByDc;
protected final Attribute _statusAttr;
protected final Attribute _msIdAttr;
@ -233,6 +235,13 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
HostsInStatusSearch.and("type", HostsInStatusSearch.entity().getType(), Op.EQ);
HostsInStatusSearch.and("statuses", HostsInStatusSearch.entity().getStatus(), Op.IN);
HostsInStatusSearch.done();
CountRoutingByDc = createSearchBuilder(Long.class);
CountRoutingByDc.select(null, Func.COUNT, null);
CountRoutingByDc.and("dc", CountRoutingByDc.entity().getDataCenterId(), SearchCriteria.Op.EQ);
CountRoutingByDc.and("type", CountRoutingByDc.entity().getType(), SearchCriteria.Op.EQ);
CountRoutingByDc.and("status", CountRoutingByDc.entity().getStatus(), SearchCriteria.Op.EQ);
CountRoutingByDc.done();
_statusAttr = _allAttributes.get("status");
_msIdAttr = _allAttributes.get("managementServerId");
@ -746,7 +755,16 @@ public class HostDaoImpl extends GenericDaoBase<HostVO, Long> implements HostDao
sc.setParameters("statuses", (Object[])statuses);
return customSearch(sc, null);
}
}
@Override
public long countRoutingHostsByDataCenter(long dcId){
SearchCriteria<Long> sc = CountRoutingByDc.create();
sc.setParameters("dc", dcId);
sc.setParameters("type", Host.Type.Routing);
sc.setParameters("status", Status.Up.toString());
return customSearch(sc, null).get(0);
}
}

View File

@ -475,10 +475,12 @@ CREATE TABLE `cloud`.`data_center` (
`userdata_provider` char(64) DEFAULT 'VirtualRouter',
`is_security_group_enabled` tinyint NOT NULL DEFAULT 0 COMMENT '1: enabled, 0: not',
`allocation_state` varchar(32) NOT NULL DEFAULT 'Enabled' COMMENT 'Is this data center enabled for allocation for new resources',
`zone_token` varchar(255),
PRIMARY KEY (`id`),
CONSTRAINT `fk_data_center__domain_id` FOREIGN KEY (`domain_id`) REFERENCES `domain`(`id`),
INDEX `i_data_center__domain_id`(`domain_id`),
INDEX `i_data_center__allocation_state`(`allocation_state`)
INDEX `i_data_center__allocation_state`(`allocation_state`),
INDEX `i_data_center__zone_token`(`zone_token`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `cloud`.`op_dc_ip_address_alloc` (

View File

@ -41,3 +41,5 @@ ALTER TABLE `cloud`.`security_group` DROP COLUMN `account_name`;
ALTER TABLE `cloud`.`security_ingress_rule` DROP COLUMN `allowed_security_group`;
ALTER TABLE `cloud`.`security_ingress_rule` DROP COLUMN `allowed_sec_grp_acct`;
ALTER TABLE `cloud`.`data_center` ADD COLUMN `zone_token` varchar(255);
ALTER TABLE `cloud`.`data_center` ADD INDEX `i_data_center__zone_token`(`zone_token`);