Removed network_id reference from domain_router table as now VirtualRouter can be associated with multiple networks (VPC case). Code modifications were done accordingly to the places where this field was used.

Router->Networks (one to many) are held in router_network_ref table now
This commit is contained in:
Alena Prokharchyk 2012-05-18 17:23:05 -07:00
parent 8cb1149766
commit 998cf66e6c
15 changed files with 634 additions and 429 deletions

View File

@ -287,5 +287,5 @@ public interface Network extends ControlledEntity {
/**
* @return
*/
long getVpcId();
Long getVpcId();
}

View File

@ -213,7 +213,7 @@ public class NetworkProfile implements Network {
}
@Override
public long getVpcId() {
public Long getVpcId() {
return vpcId;
}

View File

@ -40,7 +40,7 @@ public interface VirtualMachineProfile<T extends VirtualMachine> {
public static final Param VmPassword = new Param("VmPassword");
public static final Param ControlNic = new Param("ControlNic");
public static final Param ReProgramNetwork = new Param("RestartNetwork");
public static final Param ReProgramGuestNetworks = new Param("RestartNetwork");
public static final Param PxeSeverType = new Param("PxeSeverType");
public static final Param HaTag = new Param("HaTag");

View File

@ -45,9 +45,6 @@ public class DomainRouterVO extends VMInstanceVO implements VirtualRouter {
@Column(name="guest_ip_address")
private String guestIpAddress;
@Column(name="network_id")
long networkId;
@Column(name="is_redundant_router")
boolean isRedundantRouter;
@ -83,15 +80,14 @@ public class DomainRouterVO extends VMInstanceVO implements VirtualRouter {
long guestOSId,
long domainId,
long accountId,
long networkId,
boolean isRedundantRouter,
int priority,
boolean isPriorityBumpUp,
RedundantState redundantState,
boolean haEnabled, boolean stopPending) {
boolean haEnabled,
boolean stopPending) {
super(id, serviceOfferingId, name, name, Type.DomainRouter, templateId, hypervisorType, guestOSId, domainId, accountId, haEnabled);
this.elementId = elementId;
this.networkId = networkId;
this.isRedundantRouter = isRedundantRouter;
this.priority = priority;
this.redundantState = redundantState;
@ -108,16 +104,15 @@ public class DomainRouterVO extends VMInstanceVO implements VirtualRouter {
long guestOSId,
long domainId,
long accountId,
long networkId,
boolean isRedundantRouter,
int priority,
boolean isPriorityBumpUp,
RedundantState redundantState,
boolean haEnabled,
boolean stopPending, VirtualMachine.Type vmType) {
boolean stopPending,
VirtualMachine.Type vmType) {
super(id, serviceOfferingId, name, name, vmType, templateId, hypervisorType, guestOSId, domainId, accountId, haEnabled);
this.elementId = elementId;
this.networkId = networkId;
this.isRedundantRouter = isRedundantRouter;
this.priority = priority;
this.redundantState = redundantState;
@ -141,10 +136,6 @@ public class DomainRouterVO extends VMInstanceVO implements VirtualRouter {
this.publicNetmask = publicNetmask;
}
public long getNetworkId() {
return networkId;
}
public void setGuestIpAddress(String routerIpAddress) {
this.guestIpAddress = routerIpAddress;
}

View File

@ -70,6 +70,7 @@ import com.cloud.maint.UpgradeManagerImpl;
import com.cloud.maint.dao.AgentUpgradeDaoImpl;
import com.cloud.network.ExternalLoadBalancerUsageManagerImpl;
import com.cloud.network.NetworkManagerImpl;
import com.cloud.network.RouterNetworkDaoImpl;
import com.cloud.network.StorageNetworkManagerImpl;
import com.cloud.network.dao.CiscoNexusVSMDeviceDaoImpl;
import com.cloud.network.dao.ExternalFirewallDeviceDaoImpl;

View File

@ -77,7 +77,7 @@ public class NetworkVO implements Network, Identity {
long networkOfferingId;
@Column(name="vpc_id")
long vpcId;
Long vpcId;
@Column(name="physical_network_id")
Long physicalNetworkId;
@ -478,7 +478,7 @@ public class NetworkVO implements Network, Identity {
}
@Override
public long getVpcId() {
public Long getVpcId() {
return vpcId;
}
}

View File

@ -0,0 +1,43 @@
// Copyright 2012 Citrix Systems, Inc. Licensed under the
// Apache License, Version 2.0 (the "License"); you may not use this
// file except in compliance with the License. Citrix Systems, Inc.
// reserves all rights not expressly granted by 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.
//
// Automatically generated by addcopyright.py at 04/03/2012
package com.cloud.network;
import java.util.List;
import com.cloud.utils.db.GenericDao;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.GenericSearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.SearchCriteria.Op;
/**
* @author Alena Prokharchyk
*/
public class RouterNetworkDaoImpl extends GenericDaoBase<RouterNetworkVO, Long> implements GenericDao<RouterNetworkVO, Long>{
protected final GenericSearchBuilder<RouterNetworkVO, Long> RouterNetworksSearch;
public RouterNetworkDaoImpl() {
super();
RouterNetworksSearch = createSearchBuilder(Long.class);
RouterNetworksSearch.selectField(RouterNetworksSearch.entity().getNetworkId());
RouterNetworksSearch.and("routerId", RouterNetworksSearch.entity().getRouterId(), Op.EQ);
RouterNetworksSearch.done();
}
public List<Long> getRouterNetworks(long routerId) {
SearchCriteria<Long> sc = RouterNetworksSearch.create();
sc.setParameters("routerId", routerId);
return customSearch(sc, null);
}
}

View File

@ -0,0 +1,68 @@
// Copyright 2012 Citrix Systems, Inc. Licensed under the
// Apache License, Version 2.0 (the "License"); you may not use this
// file except in compliance with the License. Citrix Systems, Inc.
// reserves all rights not expressly granted by 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.
//
// Automatically generated by addcopyright.py at 04/03/2012
package com.cloud.network;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import com.cloud.network.Network.GuestType;
/**
* @author Alena Prokharchyk
*/
@Entity
@Table(name="router_network_ref")
public class RouterNetworkVO{
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
long id;
@Column(name="router_id")
long routerId;
@Column(name="network_id")
long networkId;
@Column(name="guest_type")
@Enumerated(value=EnumType.STRING)
Network.GuestType guestType;
protected RouterNetworkVO() {
}
public RouterNetworkVO(long routerId, long networkId, GuestType guestType) {
this.networkId = networkId;
this.routerId = routerId;
this.guestType = guestType;
}
public long getRouterId() {
return routerId;
}
public long getNetworkId() {
return networkId;
}
public Network.GuestType getGuestType() {
return guestType;
}
}

View File

@ -155,7 +155,7 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl
}
Map<VirtualMachineProfile.Param, Object> params = new HashMap<VirtualMachineProfile.Param, Object>(1);
params.put(VirtualMachineProfile.Param.ReProgramNetwork, true);
params.put(VirtualMachineProfile.Param.ReProgramGuestNetworks, true);
_routerMgr.deployVirtualRouter(network, dest, _accountMgr.getAccount(network.getAccountId()), params, offering.getRedundantRouter());

View File

@ -224,7 +224,7 @@ public class ElasticLoadBalancerManagerImpl implements
Pod pod = podId == null?null:_podDao.findById(podId);
Map<VirtualMachineProfile.Param, Object> params = new HashMap<VirtualMachineProfile.Param, Object>(
1);
params.put(VirtualMachineProfile.Param.ReProgramNetwork, true);
params.put(VirtualMachineProfile.Param.ReProgramGuestNetworks, true);
Account owner = _accountService.getActiveAccountByName("system", new Long(1));
DeployDestination dest = new DeployDestination(dc, pod, null, null);
s_logger.debug("About to deploy ELB vm ");
@ -513,7 +513,7 @@ public class ElasticLoadBalancerManagerImpl implements
}
elbVm = new DomainRouterVO(id, _elasticLbVmOffering.getId(), vrProvider.getId(), VirtualMachineName.getSystemVmName(id, _instance, _elbVmNamePrefix), template.getId(), template.getHypervisorType(),
template.getGuestOSId(), owner.getDomainId(), owner.getId(), guestNetwork.getId(), false, 0, false, RedundantState.UNKNOWN, _elasticLbVmOffering.getOfferHA(), false, VirtualMachine.Type.ElasticLoadBalancerVm);
template.getGuestOSId(), owner.getDomainId(), owner.getId(), false, 0, false, RedundantState.UNKNOWN, _elasticLbVmOffering.getOfferHA(), false, VirtualMachine.Type.ElasticLoadBalancerVm);
elbVm.setRole(Role.LB);
elbVm = _itMgr.allocate(elbVm, template, _elasticLbVmOffering, networks, plan, null, owner);
//TODO: create usage stats
@ -801,7 +801,17 @@ public class ElasticLoadBalancerManagerImpl implements
@Override
public boolean finalizeVirtualMachineProfile(VirtualMachineProfile<DomainRouterVO> profile, DeployDestination dest, ReservationContext context) {
DomainRouterVO elbVm = profile.getVirtualMachine();
NetworkVO network = _networkDao.findById(elbVm.getNetworkId());
List<NicProfile> elbNics = profile.getNics();
Long guestNtwkId = null;
for (NicProfile routerNic : elbNics) {
if (routerNic.getTrafficType() == TrafficType.Guest) {
guestNtwkId = routerNic.getNetworkId();
break;
}
}
NetworkVO guestNetwork = _networkDao.findById(guestNtwkId);
DataCenter dc = dest.getDataCenter();
@ -847,7 +857,7 @@ public class ElasticLoadBalancerManagerImpl implements
controlNic = nic;
}
}
String domain = network.getNetworkDomain();
String domain = guestNetwork.getNetworkDomain();
if (domain != null) {
buf.append(" domain=" + domain);
}

View File

@ -477,41 +477,47 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
final Transaction txn = Transaction.currentTxn();
try {
txn.start();
final UserStatisticsVO userStats = _userStatsDao.lock(router.getAccountId(), router.getDataCenterIdToDeployIn(), router.getNetworkId(), null, router.getId(), router.getType().toString());
if (userStats != null) {
final RebootAnswer sa = (RebootAnswer) answer;
final Long received = sa.getBytesReceived();
long netBytes = 0;
if (received != null) {
if (received.longValue() >= userStats.getCurrentBytesReceived()) {
netBytes = received.longValue();
//FIXME!!! - UserStats command should grab bytesSent/Received for all guest interfaces of the VR
List<Long> routerGuestNtwkIds = _routerDao.getRouterNetworks(router.getId());
for (Long guestNtwkId : routerGuestNtwkIds) {
final UserStatisticsVO userStats = _userStatsDao.lock(router.getAccountId(), router.getDataCenterIdToDeployIn(),
guestNtwkId, null, router.getId(), router.getType().toString());
if (userStats != null) {
final RebootAnswer sa = (RebootAnswer) answer;
final Long received = sa.getBytesReceived();
long netBytes = 0;
if (received != null) {
if (received.longValue() >= userStats.getCurrentBytesReceived()) {
netBytes = received.longValue();
} else {
netBytes = userStats.getCurrentBytesReceived() + received;
}
} else {
netBytes = userStats.getCurrentBytesReceived() + received;
netBytes = userStats.getCurrentBytesReceived();
}
} else {
netBytes = userStats.getCurrentBytesReceived();
}
userStats.setCurrentBytesReceived(0);
userStats.setNetBytesReceived(userStats.getNetBytesReceived() + netBytes);
userStats.setCurrentBytesReceived(0);
userStats.setNetBytesReceived(userStats.getNetBytesReceived() + netBytes);
final Long sent = sa.getBytesSent();
final Long sent = sa.getBytesSent();
if (sent != null) {
if (sent.longValue() >= userStats.getCurrentBytesSent()) {
netBytes = sent.longValue();
if (sent != null) {
if (sent.longValue() >= userStats.getCurrentBytesSent()) {
netBytes = sent.longValue();
} else {
netBytes = userStats.getCurrentBytesSent() + sent;
}
} else {
netBytes = userStats.getCurrentBytesSent() + sent;
netBytes = userStats.getCurrentBytesSent();
}
userStats.setNetBytesSent(userStats.getNetBytesSent() + netBytes);
userStats.setCurrentBytesSent(0);
_userStatsDao.update(userStats.getId(), userStats);
s_logger.debug("Successfully updated user statistics as a part of domR " + router + " reboot/stop");
} else {
netBytes = userStats.getCurrentBytesSent();
s_logger.warn("User stats were not created for account " + router.getAccountId() + " and dc " + router.getDataCenterIdToDeployIn());
}
userStats.setNetBytesSent(userStats.getNetBytesSent() + netBytes);
userStats.setCurrentBytesSent(0);
_userStatsDao.update(userStats.getId(), userStats);
s_logger.debug("Successfully updated user statistics as a part of domR " + router + " reboot/stop");
} else {
s_logger.warn("User stats were not created for account " + router.getAccountId() + " and dc " + router.getDataCenterIdToDeployIn());
}
txn.commit();
} catch (final Exception e) {
txn.rollback();
@ -749,64 +755,71 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
for (DomainRouterVO router : routers) {
String privateIP = router.getPrivateIpAddress();
if (privateIP != null) {
final NetworkUsageCommand usageCmd = new NetworkUsageCommand(privateIP, router.getHostName());
UserStatisticsVO previousStats = _statsDao.findBy(router.getAccountId(), router.getDataCenterIdToDeployIn(), router.getNetworkId(), null, router.getId(), router.getType().toString());
NetworkUsageAnswer answer = null;
try {
answer = (NetworkUsageAnswer) _agentMgr.easySend(router.getHostId(), usageCmd);
} catch (Exception e) {
s_logger.warn("Error while collecting network stats from router: "+router.getInstanceName()+" from host: "+router.getHostId(), e);
continue;
}
if (answer != null) {
if (!answer.getResult()) {
s_logger.warn("Error while collecting network stats from router: "+router.getInstanceName()+" from host: "+router.getHostId() + "; details: " + answer.getDetails());
if (privateIP != null) {
List<Long> routerGuestNtwkIds = _routerDao.getRouterNetworks(router.getId());
for (Long guestNtwkId : routerGuestNtwkIds) {
final NetworkUsageCommand usageCmd = new NetworkUsageCommand(privateIP, router.getHostName());
UserStatisticsVO previousStats = _statsDao.findBy(router.getAccountId(),
router.getDataCenterIdToDeployIn(), guestNtwkId, null, router.getId(), router.getType().toString());
NetworkUsageAnswer answer = null;
try {
answer = (NetworkUsageAnswer) _agentMgr.easySend(router.getHostId(), usageCmd);
} catch (Exception e) {
s_logger.warn("Error while collecting network stats from router: "+router.getInstanceName()+" from host: "+router.getHostId(), e);
continue;
}
Transaction txn = Transaction.open(Transaction.CLOUD_DB);
try {
if ((answer.getBytesReceived() == 0) && (answer.getBytesSent() == 0)) {
s_logger.debug("Recieved and Sent bytes are both 0. Not updating user_statistics");
continue;
}
txn.start();
UserStatisticsVO stats = _statsDao.lock(router.getAccountId(), router.getDataCenterIdToDeployIn(), router.getNetworkId(), null, router.getId(), router.getType().toString());
if (stats == null) {
s_logger.warn("unable to find stats for account: " + router.getAccountId());
continue;
}
if(previousStats != null
&& ((previousStats.getCurrentBytesReceived() != stats.getCurrentBytesReceived()) || (previousStats.getCurrentBytesSent() != stats.getCurrentBytesSent()))){
s_logger.debug("Router stats changed from the time NetworkUsageCommand was sent. Ignoring current answer. Router: "+answer.getRouterName()+" Rcvd: " + answer.getBytesReceived()+ "Sent: " +answer.getBytesSent());
if (answer != null) {
if (!answer.getResult()) {
s_logger.warn("Error while collecting network stats from router: "+router.getInstanceName()+" from host: "+router.getHostId() + "; details: " + answer.getDetails());
continue;
}
Transaction txn = Transaction.open(Transaction.CLOUD_DB);
try {
if ((answer.getBytesReceived() == 0) && (answer.getBytesSent() == 0)) {
s_logger.debug("Recieved and Sent bytes are both 0. Not updating user_statistics");
continue;
}
txn.start();
UserStatisticsVO stats = _statsDao.lock(router.getAccountId(),
router.getDataCenterIdToDeployIn(), guestNtwkId, null, router.getId(), router.getType().toString());
if (stats == null) {
s_logger.warn("unable to find stats for account: " + router.getAccountId());
continue;
}
if (stats.getCurrentBytesReceived() > answer.getBytesReceived()) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Received # of bytes that's less than the last one. Assuming something went wrong and persisting it. Router: "+answer.getRouterName()+" Reported: " + answer.getBytesReceived()
+ " Stored: " + stats.getCurrentBytesReceived());
if(previousStats != null
&& ((previousStats.getCurrentBytesReceived() != stats.getCurrentBytesReceived()) || (previousStats.getCurrentBytesSent() != stats.getCurrentBytesSent()))){
s_logger.debug("Router stats changed from the time NetworkUsageCommand was sent. Ignoring current answer. Router: "+answer.getRouterName()+" Rcvd: " + answer.getBytesReceived()+ "Sent: " +answer.getBytesSent());
continue;
}
stats.setNetBytesReceived(stats.getNetBytesReceived() + stats.getCurrentBytesReceived());
}
stats.setCurrentBytesReceived(answer.getBytesReceived());
if (stats.getCurrentBytesSent() > answer.getBytesSent()) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Received # of bytes that's less than the last one. Assuming something went wrong and persisting it. Router: "+answer.getRouterName()+" Reported: " + answer.getBytesSent()
+ " Stored: " + stats.getCurrentBytesSent());
if (stats.getCurrentBytesReceived() > answer.getBytesReceived()) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Received # of bytes that's less than the last one. Assuming something went wrong and persisting it. Router: "+answer.getRouterName()+" Reported: " + answer.getBytesReceived()
+ " Stored: " + stats.getCurrentBytesReceived());
}
stats.setNetBytesReceived(stats.getNetBytesReceived() + stats.getCurrentBytesReceived());
}
stats.setNetBytesSent(stats.getNetBytesSent() + stats.getCurrentBytesSent());
stats.setCurrentBytesReceived(answer.getBytesReceived());
if (stats.getCurrentBytesSent() > answer.getBytesSent()) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Received # of bytes that's less than the last one. Assuming something went wrong and persisting it. Router: "+answer.getRouterName()+" Reported: " + answer.getBytesSent()
+ " Stored: " + stats.getCurrentBytesSent());
}
stats.setNetBytesSent(stats.getNetBytesSent() + stats.getCurrentBytesSent());
}
stats.setCurrentBytesSent(answer.getBytesSent());
_statsDao.update(stats.getId(), stats);
txn.commit();
} catch (Exception e) {
txn.rollback();
s_logger.warn("Unable to update user statistics for account: " + router.getAccountId() + " Rx: " + answer.getBytesReceived() + "; Tx: " + answer.getBytesSent());
} finally {
txn.close();
}
stats.setCurrentBytesSent(answer.getBytesSent());
_statsDao.update(stats.getId(), stats);
txn.commit();
} catch (Exception e) {
txn.rollback();
s_logger.warn("Unable to update user statistics for account: " + router.getAccountId() + " Rx: " + answer.getBytesReceived() + "; Tx: " + answer.getBytesSent());
} finally {
txn.close();
}
}
}
@ -993,36 +1006,40 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
if (!router.getIsRedundantRouter()) {
continue;
}
long networkId = router.getNetworkId();
if (checkedNetwork.contains(networkId)) {
continue;
}
checkedNetwork.add(networkId);
List<DomainRouterVO> checkingRouters = _routerDao.listByNetworkAndRole(networkId, Role.VIRTUAL_ROUTER);
if (checkingRouters.size() != 2) {
continue;
}
DomainRouterVO masterRouter = null;
DomainRouterVO backupRouter = null;
for (DomainRouterVO r : checkingRouters) {
if (r.getRedundantState() == RedundantState.MASTER) {
if (masterRouter == null) {
masterRouter = r;
} else {
//Duplicate master! We give up, until the admin fix duplicate MASTER issue
break;
}
} else if (r.getRedundantState() == RedundantState.BACKUP) {
if (backupRouter == null) {
backupRouter = r;
} else {
break;
List<Long> routerGuestNtwkIds = _routerDao.getRouterNetworks(router.getId());
for (Long routerGuestNtwkId : routerGuestNtwkIds) {
if (checkedNetwork.contains(routerGuestNtwkId)) {
continue;
}
checkedNetwork.add(routerGuestNtwkId);
List<DomainRouterVO> checkingRouters = _routerDao.listByNetworkAndRole(routerGuestNtwkId, Role.VIRTUAL_ROUTER);
if (checkingRouters.size() != 2) {
continue;
}
DomainRouterVO masterRouter = null;
DomainRouterVO backupRouter = null;
for (DomainRouterVO r : checkingRouters) {
if (r.getRedundantState() == RedundantState.MASTER) {
if (masterRouter == null) {
masterRouter = r;
} else {
//Duplicate master! We give up, until the admin fix duplicate MASTER issue
break;
}
} else if (r.getRedundantState() == RedundantState.BACKUP) {
if (backupRouter == null) {
backupRouter = r;
} else {
break;
}
}
}
}
if (masterRouter != null && backupRouter != null) {
if (getRealPriority(masterRouter) - DEFAULT_DELTA + 1 != getRealPriority(backupRouter) || backupRouter.getIsPriorityBumpUp()) {
recoverRedundantNetwork(masterRouter, backupRouter);
if (masterRouter != null && backupRouter != null) {
if (getRealPriority(masterRouter) - DEFAULT_DELTA + 1 != getRealPriority(backupRouter) || backupRouter.getIsPriorityBumpUp()) {
recoverRedundantNetwork(masterRouter, backupRouter);
}
}
}
}
@ -1031,17 +1048,21 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
private void checkDuplicateMaster(List <DomainRouterVO> routers) {
Map<Long, DomainRouterVO> networkRouterMaps = new HashMap<Long, DomainRouterVO>();
for (DomainRouterVO router : routers) {
if (router.getRedundantState() == RedundantState.MASTER) {
if (networkRouterMaps.containsKey(router.getNetworkId())) {
DomainRouterVO dupRouter = networkRouterMaps.get(router.getNetworkId());
String title = "More than one redundant virtual router is in MASTER state! Router " + router.getHostName() + " and router " + dupRouter.getHostName();
String context = "Virtual router (name: " + router.getHostName() + ", id: " + router.getId() + " and router (name: "
+ dupRouter.getHostName() + ", id: " + router.getId() + ") are both in MASTER state! If the problem persist, restart both of routers. ";
List<Long> routerGuestNtwkIds = _routerDao.getRouterNetworks(router.getId());
_alertMgr.sendAlert(AlertManager.ALERT_TYPE_DOMAIN_ROUTER, router.getDataCenterIdToDeployIn(), router.getPodIdToDeployIn(), title, context);
_alertMgr.sendAlert(AlertManager.ALERT_TYPE_DOMAIN_ROUTER, dupRouter.getDataCenterIdToDeployIn(), dupRouter.getPodIdToDeployIn(), title, context);
} else {
networkRouterMaps.put(router.getNetworkId(), router);
for (Long routerGuestNtwkId : routerGuestNtwkIds) {
if (router.getRedundantState() == RedundantState.MASTER) {
if (networkRouterMaps.containsKey(routerGuestNtwkId)) {
DomainRouterVO dupRouter = networkRouterMaps.get(routerGuestNtwkId);
String title = "More than one redundant virtual router is in MASTER state! Router " + router.getHostName() + " and router " + dupRouter.getHostName();
String context = "Virtual router (name: " + router.getHostName() + ", id: " + router.getId() + " and router (name: "
+ dupRouter.getHostName() + ", id: " + router.getId() + ") are both in MASTER state! If the problem persist, restart both of routers. ";
_alertMgr.sendAlert(AlertManager.ALERT_TYPE_DOMAIN_ROUTER, router.getDataCenterIdToDeployIn(), router.getPodIdToDeployIn(), title, context);
_alertMgr.sendAlert(AlertManager.ALERT_TYPE_DOMAIN_ROUTER, dupRouter.getDataCenterIdToDeployIn(), dupRouter.getPodIdToDeployIn(), title, context);
} else {
networkRouterMaps.put(routerGuestNtwkId, router);
}
}
}
}
@ -1050,7 +1071,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
@Override
public void run() {
try {
final List<DomainRouterVO> routers = _routerDao.listVirtualByHostId(null);
final List<DomainRouterVO> routers = _routerDao.listIsolatedByHostId(null);
s_logger.debug("Found " + routers.size() + " routers. ");
updateRoutersRedundantState(routers);
@ -1321,7 +1342,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
}
router = new DomainRouterVO(id, routerOffering.getId(), vrProvider.getId(), VirtualMachineName.getRouterName(id, _instance), template.getId(), template.getHypervisorType(),
template.getGuestOSId(), owner.getDomainId(), owner.getId(), guestNetwork.getId(), isRedundant, 0, false, RedundantState.UNKNOWN, offerHA, false);
template.getGuestOSId(), owner.getDomainId(), owner.getId(), isRedundant, 0, false, RedundantState.UNKNOWN, offerHA, false);
router.setRole(Role.VIRTUAL_ROUTER);
router = _itMgr.allocate(router, template, routerOffering, networks, plan, null, owner);
} catch (InsufficientCapacityException ex) {
@ -1477,68 +1498,25 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
}
@Override
public boolean finalizeVirtualMachineProfile(VirtualMachineProfile<DomainRouterVO> profile, DeployDestination dest, ReservationContext context) {
public boolean finalizeVirtualMachineProfile(VirtualMachineProfile<DomainRouterVO> profile, DeployDestination dest,
ReservationContext context) {
DataCenterVO dc = _dcDao.findById(dest.getDataCenter().getId());
//1) Set router details
DomainRouterVO router = profile.getVirtualMachine();
Map<String, String> details = _vmDetailsDao.findDetails(router.getId());
router.setDetails(details);
NetworkVO network = _networkDao.findById(router.getNetworkId());
String type = null;
String dhcpRange = null;
String rpFilter = " ";
DataCenter dc = dest.getDataCenter();
DataCenterVO dcVO = _dcDao.findById(dc.getId());
_dcDao.loadDetails(dcVO);
if (dc.getNetworkType() == NetworkType.Advanced) {
String cidr = network.getCidr();
if (cidr != null) {
dhcpRange = NetUtils.getDhcpRange(cidr);
}
}
String rpValue = _configDao.getValue(Config.NetworkRouterRpFilter.key());
if (rpValue != null && rpValue.equalsIgnoreCase("true")) {
_disable_rp_filter = true;
}else
{
_disable_rp_filter = false;
}
boolean publicNetwork = false;
if (_networkMgr.isProviderSupportServiceInNetwork(network.getId(), Service.SourceNat, Provider.VirtualRouter)) {
publicNetwork = true;
}
if (!publicNetwork) {
type = "dhcpsrvr";
} else {
type = "router";
if (_disable_rp_filter) {
rpFilter=" disable_rp_filter=true";
}
}
//2) Prepare boot loader elements related with Public/Control networks
StringBuilder buf = profile.getBootArgsBuilder();
buf.append(" template=domP type=" + type+rpFilter);
buf.append(" template=domP");
buf.append(" name=").append(profile.getHostName());
if (Boolean.valueOf(_configDao.getValue("system.vm.random.password"))) {
buf.append(" vmpassword=").append(_configDao.getValue("system.vm.password"));
}
boolean isRedundant = router.getIsRedundantRouter();
if (isRedundant) {
buf.append(" redundant_router=1");
List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER);
try {
int priority = getUpdatedPriority(network, routers, router);
router.setPriority(priority);
} catch (InsufficientVirtualNetworkCapcityException e) {
s_logger.error("Failed to get update priority!", e);
throw new CloudRuntimeException("Failed to get update priority!");
}
}
NicProfile controlNic = null;
String defaultDns1 = null;
String defaultDns2 = null;
@ -1547,23 +1525,17 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
int deviceId = nic.getDeviceId();
buf.append(" eth").append(deviceId).append("ip=").append(nic.getIp4Address());
buf.append(" eth").append(deviceId).append("mask=").append(nic.getNetmask());
if (nic.isDefaultNic()) {
buf.append(" gateway=").append(nic.getGateway());
defaultDns1 = nic.getDns1();
defaultDns2 = nic.getDns2();
if (dc.getNetworkType() == NetworkType.Basic) {
long cidrSize = NetUtils.getCidrSize(nic.getNetmask());
String cidr = NetUtils.getCidrSubNet(nic.getGateway(), cidrSize);
if (cidr != null) {
dhcpRange = NetUtils.getIpRangeStartIpFromCidr(cidr, cidrSize);
}
}
}
if (nic.getTrafficType() == TrafficType.Management) {
buf.append(" localgw=").append(dest.getPod().getGateway());
} else if (nic.getTrafficType() == TrafficType.Control) {
controlNic = nic;
// DOMR control command is sent over management server in VMware
if (dest.getHost().getHypervisorType() == HypervisorType.VMware) {
if (s_logger.isInfoEnabled()) {
@ -1589,46 +1561,124 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
buf.append(" sshonguest=true");
}
}
} else if (nic.getTrafficType() == TrafficType.Guest) {
//build bootloader parameter for the guest
createGuestBootLoadArgs(profile, nic, defaultDns1, defaultDns2);
}
}
controlNic = nic;
} else if (nic.getTrafficType() == TrafficType.Guest && isRedundant) {
Network net = _networkMgr.getNetwork(nic.getNetworkId());
buf.append(" guestgw=").append(net.getGateway());
String brd = NetUtils.long2Ip(NetUtils.ip2Long(nic.getIp4Address()) | ~NetUtils.ip2Long(nic.getNetmask()));
buf.append(" guestbrd=").append(brd);
buf.append(" guestcidrsize=").append(NetUtils.getCidrSize(nic.getNetmask()));
buf.append(" router_pr=").append(router.getPriority());
if (controlNic == null) {
throw new CloudRuntimeException("Didn't start a control port");
}
String domain_suffix = dc.getDetail(ZoneConfig.DnsSearchOrder.getName());
if (domain_suffix != null) {
buf.append(" dnssearchorder=").append(domain_suffix);
}
if (profile.getHypervisorType() == HypervisorType.VMware) {
buf.append(" extra_pubnics=" + _routerExtraPublicNics);
}
if (s_logger.isDebugEnabled()) {
s_logger.debug("Boot Args for " + profile + ": " + buf.toString());
}
return true;
}
protected void createGuestBootLoadArgs(VirtualMachineProfile<DomainRouterVO> profile, NicProfile nic,
String defaultDns1, String defaultDns2) {
long guestNetworkId = nic.getNetworkId();
NetworkVO guestNetwork = _networkDao.findById(guestNetworkId);
DomainRouterVO router = profile.getVirtualMachine();
String type = null;
String dhcpRange = null;
String rpFilter = " ";
DataCenterVO dc = _dcDao.findById(guestNetwork.getDataCenterId());
if (dc.getNetworkType() == NetworkType.Advanced) {
String cidr = guestNetwork.getCidr();
if (cidr != null) {
dhcpRange = NetUtils.getDhcpRange(cidr);
}
}
String rpValue = _configDao.getValue(Config.NetworkRouterRpFilter.key());
if (rpValue != null && rpValue.equalsIgnoreCase("true")) {
_disable_rp_filter = true;
}else {
_disable_rp_filter = false;
}
boolean publicNetwork = false;
if (_networkMgr.isProviderSupportServiceInNetwork(guestNetwork.getId(), Service.SourceNat, Provider.VirtualRouter)) {
publicNetwork = true;
}
if (!publicNetwork) {
type = "dhcpsrvr";
} else {
type = "router";
if (_disable_rp_filter) {
rpFilter=" disable_rp_filter=true";
}
}
StringBuilder buf = profile.getBootArgsBuilder();
buf.append(" type=" + type + rpFilter);
boolean isRedundant = router.getIsRedundantRouter();
if (isRedundant) {
buf.append(" redundant_router=1");
List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(guestNetwork.getId(), Role.VIRTUAL_ROUTER);
try {
int priority = getUpdatedPriority(guestNetwork, routers, router);
router.setPriority(priority);
} catch (InsufficientVirtualNetworkCapcityException e) {
s_logger.error("Failed to get update priority!", e);
throw new CloudRuntimeException("Failed to get update priority!");
}
}
if (nic.isDefaultNic() && dc.getNetworkType() == NetworkType.Basic) {
long cidrSize = NetUtils.getCidrSize(nic.getNetmask());
String cidr = NetUtils.getCidrSubNet(nic.getGateway(), cidrSize);
if (cidr != null) {
dhcpRange = NetUtils.getIpRangeStartIpFromCidr(cidr, cidrSize);
}
}
if (dhcpRange != null) {
buf.append(" dhcprange=" + dhcpRange);
}
String domain = network.getNetworkDomain();
if (isRedundant) {
Network net = _networkMgr.getNetwork(nic.getNetworkId());
buf.append(" guestgw=").append(net.getGateway());
String brd = NetUtils.long2Ip(NetUtils.ip2Long(nic.getIp4Address()) | ~NetUtils.ip2Long(nic.getNetmask()));
buf.append(" guestbrd=").append(brd);
buf.append(" guestcidrsize=").append(NetUtils.getCidrSize(nic.getNetmask()));
buf.append(" router_pr=").append(router.getPriority());
}
String domain = guestNetwork.getNetworkDomain();
if (domain != null) {
buf.append(" domain=" + domain);
}
String domain_suffix = dcVO.getDetail(ZoneConfig.DnsSearchOrder.getName());
if (domain_suffix != null) {
buf.append(" dnssearchorder=").append(domain_suffix);
boolean dnsProvided = false;
boolean dhcpProvided = false;
if (nic.getTrafficType() == TrafficType.Guest) {
//FiXME - for multiple guest network case this should be set individually
dnsProvided = _networkMgr.isProviderSupportServiceInNetwork(nic.getNetworkId(), Service.Dns, Provider.VirtualRouter);
dhcpProvided = _networkMgr.isProviderSupportServiceInNetwork(nic.getNetworkId(), Service.Dhcp, Provider.VirtualRouter);
}
// if (!network.isDefault() && network.getGuestType() == Network.GuestType.Shared) {
// buf.append(" defaultroute=false");
//
// String virtualNetworkElementNicIP = _networkMgr.getIpOfNetworkElementInVirtualNetwork(network.getAccountId(), network.getDataCenterId());
// if (network.getGuestType() != Network.GuestType.Shared && virtualNetworkElementNicIP != null) {
// defaultDns1 = virtualNetworkElementNicIP;
// } else {
// s_logger.debug("No Virtual network found for account id=" + network.getAccountId() + " so setting dns to the dns of the network id=" + network.getId());
// }
// } else {
// buf.append(" defaultroute=true");
// }
boolean dnsProvided = _networkMgr.isProviderSupportServiceInNetwork(network.getId(), Service.Dns, Provider.VirtualRouter);
boolean dhcpProvided = _networkMgr.isProviderSupportServiceInNetwork(network.getId(), Service.Dhcp, Provider.VirtualRouter);
/* If virtual router didn't provide DNS service but provide DHCP service, we need to override the DHCP response to return DNS server rather than
/* If virtual router didn't provide DNS service but provide DHCP service, we need to override the DHCP response
* to return DNS server rather than
* virtual router itself. */
if (dnsProvided || dhcpProvided) {
buf.append(" dns1=").append(defaultDns1);
@ -1647,20 +1697,6 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
buf.append(" useextdns=true");
}
}
if(profile.getHypervisorType() == HypervisorType.VMware) {
buf.append(" extra_pubnics=" + _routerExtraPublicNics);
}
if (s_logger.isDebugEnabled()) {
s_logger.debug("Boot Args for " + profile + ": " + buf.toString());
}
if (controlNic == null) {
throw new CloudRuntimeException("Didn't start a control port");
}
return true;
}
@Override
@ -1726,9 +1762,9 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
cmds.addCommand("networkUsage", new NetworkUsageCommand(controlNic.getIp4Address(), router.getHostName(), "create"));
// restart network if restartNetwork = false is not specified in profile parameters
boolean reprogramNetwork = true;
if (profile.getParameter(Param.ReProgramNetwork) != null && (Boolean) profile.getParameter(Param.ReProgramNetwork) == false) {
reprogramNetwork = false;
boolean reprogramGuestNtwks = true;
if (profile.getParameter(Param.ReProgramGuestNetworks) != null && (Boolean) profile.getParameter(Param.ReProgramGuestNetworks) == false) {
reprogramGuestNtwks = false;
}
VirtualRouterProvider vrProvider = _vrProviderDao.findById(router.getElementId());
@ -1740,136 +1776,139 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
throw new CloudRuntimeException("Cannot find related provider of virtual router provider: " + vrProvider.getType().toString());
}
if (reprogramNetwork) {
s_logger.debug("Resending ipAssoc, port forwarding, load balancing rules as a part of Virtual router start");
long networkId = router.getNetworkId();
long ownerId = router.getAccountId();
long zoneId = router.getDataCenterIdToDeployIn();
List<Long> routerGuestNtwkIds = _routerDao.getRouterNetworks(router.getId());
for (Long guestNetworkId : routerGuestNtwkIds) {
if (reprogramGuestNtwks) {
s_logger.debug("Resending ipAssoc, port forwarding, load balancing rules as a part of Virtual router start");
long ownerId = router.getAccountId();
long zoneId = router.getDataCenterIdToDeployIn();
final List<IPAddressVO> userIps = _networkMgr.listPublicIpAddressesInVirtualNetwork(ownerId, zoneId, null, networkId);
List<PublicIp> allPublicIps = new ArrayList<PublicIp>();
if (userIps != null && !userIps.isEmpty()) {
for (IPAddressVO userIp : userIps) {
PublicIp publicIp = new PublicIp(userIp, _vlanDao.findById(userIp.getVlanId()), NetUtils.createSequenceBasedMacAddress(userIp.getMacAddress()));
allPublicIps.add(publicIp);
}
}
//Get public Ips that should be handled by router
Network network = _networkDao.findById(networkId);
Map<PublicIp, Set<Service>> ipToServices = _networkMgr.getIpToServices(allPublicIps, false, false);
Map<Provider, ArrayList<PublicIp>> providerToIpList = _networkMgr.getProviderToIpList(network, ipToServices);
// Only cover virtual router for now, if ELB use it this need to be modified
ArrayList<PublicIp> publicIps = providerToIpList.get(Provider.VirtualRouter);
s_logger.debug("Found " + publicIps.size() + " ip(s) to apply as a part of domR " + router + " start.");
if (!publicIps.isEmpty()) {
List<RemoteAccessVpn> vpns = new ArrayList<RemoteAccessVpn>();
List<PortForwardingRule> pfRules = new ArrayList<PortForwardingRule>();
List<FirewallRule> staticNatFirewallRules = new ArrayList<FirewallRule>();
List<StaticNat> staticNats = new ArrayList<StaticNat>();
List<FirewallRule> firewallRules = new ArrayList<FirewallRule>();
// Re-apply public ip addresses - should come before PF/LB/VPN
if (_networkMgr.isProviderSupportServiceInNetwork(router.getNetworkId(), Service.Firewall, provider)) {
createAssociateIPCommands(router, publicIps, cmds, 0);
final List<IPAddressVO> userIps = _networkMgr.listPublicIpAddressesInVirtualNetwork(ownerId, zoneId, null, guestNetworkId);
List<PublicIp> allPublicIps = new ArrayList<PublicIp>();
if (userIps != null && !userIps.isEmpty()) {
for (IPAddressVO userIp : userIps) {
PublicIp publicIp = new PublicIp(userIp, _vlanDao.findById(userIp.getVlanId()), NetUtils.createSequenceBasedMacAddress(userIp.getMacAddress()));
allPublicIps.add(publicIp);
}
}
//Get information about all the rules (StaticNats and StaticNatRules; PFVPN to reapply on domR start)
for (PublicIp ip : publicIps) {
if (_networkMgr.isProviderSupportServiceInNetwork(router.getNetworkId(), Service.PortForwarding, provider)) {
pfRules.addAll(_pfRulesDao.listForApplication(ip.getId()));
}
if (_networkMgr.isProviderSupportServiceInNetwork(router.getNetworkId(), Service.StaticNat, provider)) {
staticNatFirewallRules.addAll(_rulesDao.listByIpAndPurpose(ip.getId(), Purpose.StaticNat));
}
if (_networkMgr.isProviderSupportServiceInNetwork(router.getNetworkId(), Service.Firewall, provider)) {
firewallRules.addAll(_rulesDao.listByIpAndPurpose(ip.getId(), Purpose.Firewall));
//Get public Ips that should be handled by router
Network network = _networkDao.findById(guestNetworkId);
Map<PublicIp, Set<Service>> ipToServices = _networkMgr.getIpToServices(allPublicIps, false, false);
Map<Provider, ArrayList<PublicIp>> providerToIpList = _networkMgr.getProviderToIpList(network, ipToServices);
// Only cover virtual router for now, if ELB use it this need to be modified
ArrayList<PublicIp> publicIps = providerToIpList.get(Provider.VirtualRouter);
s_logger.debug("Found " + publicIps.size() + " ip(s) to apply as a part of domR " + router + " start.");
if (!publicIps.isEmpty()) {
List<RemoteAccessVpn> vpns = new ArrayList<RemoteAccessVpn>();
List<PortForwardingRule> pfRules = new ArrayList<PortForwardingRule>();
List<FirewallRule> staticNatFirewallRules = new ArrayList<FirewallRule>();
List<StaticNat> staticNats = new ArrayList<StaticNat>();
List<FirewallRule> firewallRules = new ArrayList<FirewallRule>();
// Re-apply public ip addresses - should come before PF/LB/VPN
if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.Firewall, provider)) {
createAssociateIPCommands(router, publicIps, cmds, 0);
}
if (_networkMgr.isProviderSupportServiceInNetwork(router.getNetworkId(), Service.Vpn, provider)) {
RemoteAccessVpn vpn = _vpnDao.findById(ip.getId());
if (vpn != null) {
vpns.add(vpn);
//Get information about all the rules (StaticNats and StaticNatRules; PFVPN to reapply on domR start)
for (PublicIp ip : publicIps) {
if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.PortForwarding, provider)) {
pfRules.addAll(_pfRulesDao.listForApplication(ip.getId()));
}
if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.StaticNat, provider)) {
staticNatFirewallRules.addAll(_rulesDao.listByIpAndPurpose(ip.getId(), Purpose.StaticNat));
}
if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.Firewall, provider)) {
firewallRules.addAll(_rulesDao.listByIpAndPurpose(ip.getId(), Purpose.Firewall));
}
if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.Vpn, provider)) {
RemoteAccessVpn vpn = _vpnDao.findById(ip.getId());
if (vpn != null) {
vpns.add(vpn);
}
}
if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.StaticNat, provider)) {
if (ip.isOneToOneNat()) {
String dstIp = _networkMgr.getIpInNetwork(ip.getAssociatedWithVmId(), guestNetworkId);
StaticNatImpl staticNat = new StaticNatImpl(ip.getAccountId(), ip.getDomainId(), guestNetworkId, ip.getId(), dstIp, false);
staticNats.add(staticNat);
}
}
}
if (_networkMgr.isProviderSupportServiceInNetwork(router.getNetworkId(), Service.StaticNat, provider)) {
if (ip.isOneToOneNat()) {
String dstIp = _networkMgr.getIpInNetwork(ip.getAssociatedWithVmId(), networkId);
StaticNatImpl staticNat = new StaticNatImpl(ip.getAccountId(), ip.getDomainId(), networkId, ip.getId(), dstIp, false);
staticNats.add(staticNat);
//Re-apply static nats
s_logger.debug("Found " + staticNats.size() + " static nat(s) to apply as a part of domR " + router + " start.");
if (!staticNats.isEmpty()) {
createApplyStaticNatCommands(staticNats, router, cmds);
}
//Re-apply firewall rules
s_logger.debug("Found " + staticNats.size() + " firewall rule(s) to apply as a part of domR " + router + " start.");
if (!firewallRules.isEmpty()) {
createFirewallRulesCommands(firewallRules, router, cmds);
}
// Re-apply port forwarding rules
s_logger.debug("Found " + pfRules.size() + " port forwarding rule(s) to apply as a part of domR " + router + " start.");
if (!pfRules.isEmpty()) {
createApplyPortForwardingRulesCommands(pfRules, router, cmds);
}
// Re-apply static nat rules
s_logger.debug("Found " + staticNatFirewallRules.size() + " static nat rule(s) to apply as a part of domR " + router + " start.");
if (!staticNatFirewallRules.isEmpty()) {
List<StaticNatRule> staticNatRules = new ArrayList<StaticNatRule>();
for (FirewallRule rule : staticNatFirewallRules) {
staticNatRules.add(_rulesMgr.buildStaticNatRule(rule, false));
}
createApplyStaticNatRulesCommands(staticNatRules, router, cmds);
}
// Re-apply vpn rules
s_logger.debug("Found " + vpns.size() + " vpn(s) to apply as a part of domR " + router + " start.");
if (!vpns.isEmpty()) {
for (RemoteAccessVpn vpn : vpns) {
createApplyVpnCommands(vpn, router, cmds);
}
}
}
//Re-apply static nats
s_logger.debug("Found " + staticNats.size() + " static nat(s) to apply as a part of domR " + router + " start.");
if (!staticNats.isEmpty()) {
createApplyStaticNatCommands(staticNats, router, cmds);
}
//Re-apply firewall rules
s_logger.debug("Found " + staticNats.size() + " firewall rule(s) to apply as a part of domR " + router + " start.");
if (!firewallRules.isEmpty()) {
createFirewallRulesCommands(firewallRules, router, cmds);
}
// Re-apply port forwarding rules
s_logger.debug("Found " + pfRules.size() + " port forwarding rule(s) to apply as a part of domR " + router + " start.");
if (!pfRules.isEmpty()) {
createApplyPortForwardingRulesCommands(pfRules, router, cmds);
}
// Re-apply static nat rules
s_logger.debug("Found " + staticNatFirewallRules.size() + " static nat rule(s) to apply as a part of domR " + router + " start.");
if (!staticNatFirewallRules.isEmpty()) {
List<StaticNatRule> staticNatRules = new ArrayList<StaticNatRule>();
for (FirewallRule rule : staticNatFirewallRules) {
staticNatRules.add(_rulesMgr.buildStaticNatRule(rule, false));
List<LoadBalancerVO> lbs = _loadBalancerDao.listByNetworkId(guestNetworkId);
List<LoadBalancingRule> lbRules = new ArrayList<LoadBalancingRule>();
if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.Lb, provider)) {
// Re-apply load balancing rules
for (LoadBalancerVO lb : lbs) {
List<LbDestination> dstList = _lbMgr.getExistingDestinations(lb.getId());
List<LbStickinessPolicy> policyList = _lbMgr.getStickinessPolicies(lb.getId());
LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, policyList);
lbRules.add(loadBalancing);
}
}
createApplyStaticNatRulesCommands(staticNatRules, router, cmds);
}
// Re-apply vpn rules
s_logger.debug("Found " + vpns.size() + " vpn(s) to apply as a part of domR " + router + " start.");
if (!vpns.isEmpty()) {
for (RemoteAccessVpn vpn : vpns) {
createApplyVpnCommands(vpn, router, cmds);
s_logger.debug("Found " + lbRules.size() + " load balancing rule(s) to apply as a part of domR " + router + " start.");
if (!lbRules.isEmpty()) {
createApplyLoadBalancingRulesCommands(lbRules, router, cmds);
}
}
List<LoadBalancerVO> lbs = _loadBalancerDao.listByNetworkId(networkId);
List<LoadBalancingRule> lbRules = new ArrayList<LoadBalancingRule>();
if (_networkMgr.isProviderSupportServiceInNetwork(router.getNetworkId(), Service.Lb, provider)) {
// Re-apply load balancing rules
for (LoadBalancerVO lb : lbs) {
List<LbDestination> dstList = _lbMgr.getExistingDestinations(lb.getId());
List<LbStickinessPolicy> policyList = _lbMgr.getStickinessPolicies(lb.getId());
LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, policyList);
lbRules.add(loadBalancing);
}
}
s_logger.debug("Found " + lbRules.size() + " load balancing rule(s) to apply as a part of domR " + router + " start.");
if (!lbRules.isEmpty()) {
createApplyLoadBalancingRulesCommands(lbRules, router, cmds);
}
}
}
if (_networkMgr.isProviderSupportServiceInNetwork(router.getNetworkId(), Service.Dhcp, provider)) {
// Resend dhcp
s_logger.debug("Reapplying dhcp entries as a part of domR " + router + " start...");
createDhcpEntryCommandsForVMs(router, cmds);
}
if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.Dhcp, provider)) {
// Resend dhcp
s_logger.debug("Reapplying dhcp entries as a part of domR " + router + " start...");
createDhcpEntryCommandsForVMs(router, cmds, guestNetworkId);
}
if (_networkMgr.isProviderSupportServiceInNetwork(router.getNetworkId(), Service.UserData, provider)) {
// Resend user data
s_logger.debug("Reapplying vm data (userData and metaData) entries as a part of domR " + router + " start...");
createVmDataCommandForVMs(router, cmds);
if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.UserData, provider)) {
// Resend user data
s_logger.debug("Reapplying vm data (userData and metaData) entries as a part of domR " + router + " start...");
createVmDataCommandForVMs(router, cmds, guestNetworkId);
}
}
return true;
@ -1878,6 +1917,17 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
@Override
public boolean finalizeStart(VirtualMachineProfile<DomainRouterVO> profile, long hostId, Commands cmds, ReservationContext context) {
DomainRouterVO router = profile.getVirtualMachine();
//Get guest nic info
List<NicProfile> routerNics = profile.getNics();
Network guestNetwork = null;
for (NicProfile routerNic : routerNics) {
if (routerNic.getTrafficType() == TrafficType.Guest) {
guestNetwork = _networkMgr.getNetwork(routerNic.getNetworkId());
break;
}
}
boolean result = true;
Answer answer = cmds.getAnswer("checkSsh");
@ -1902,7 +1952,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
} else {
router.setTemplateVersion(versionAnswer.getTemplateVersion());
router.setScriptsVersion(versionAnswer.getScriptsVersion());
router = _routerDao.persist(router);
router = _routerDao.persist(router, guestNetwork);
}
} else {
result = false;
@ -2115,15 +2165,6 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
@Override
public DomainRouterVO persist(DomainRouterVO router) {
DomainRouterVO virtualRouter = _routerDao.persist(router);
// Creating stats entry for router
UserStatisticsVO stats = _userStatsDao.findBy(virtualRouter.getAccountId(), virtualRouter.getDataCenterIdToDeployIn(), router.getNetworkId(), null, router.getId(), router.getType().toString());
if (stats == null) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Creating user statistics for the account: " + virtualRouter.getAccountId() + " Router Id: " + router.getId());
}
stats = new UserStatisticsVO(virtualRouter.getAccountId(), virtualRouter.getDataCenterIdToDeployIn(), null, router.getId(), router.getType().toString(), router.getNetworkId());
_userStatsDao.persist(stats);
}
return virtualRouter;
}
@ -2239,9 +2280,9 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
UserVO user = _userDao.findById(UserContext.current().getCallerUserId());
Map<Param, Object> params = new HashMap<Param, Object>();
if (reprogramNetwork) {
params.put(Param.ReProgramNetwork, true);
params.put(Param.ReProgramGuestNetworks, true);
} else {
params.put(Param.ReProgramNetwork, false);
params.put(Param.ReProgramGuestNetworks, false);
}
VirtualRouter virtualRouter = startVirtualRouter(router, user, caller, params);
if(virtualRouter == null){
@ -2462,9 +2503,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
}
private void createVmDataCommandForVMs(DomainRouterVO router, Commands cmds) {
long networkId = router.getNetworkId();
List<UserVmVO> vms = _userVmDao.listByNetworkIdAndStates(networkId, State.Running, State.Migrating, State.Stopping);
private void createVmDataCommandForVMs(DomainRouterVO router, Commands cmds, long guestNetworkId) {
List<UserVmVO> vms = _userVmDao.listByNetworkIdAndStates(guestNetworkId, State.Running, State.Migrating, State.Stopping);
DataCenterVO dc = _dcDao.findById(router.getDataCenterIdToDeployIn());
for (UserVmVO vm : vms) {
boolean createVmData = true;
@ -2473,7 +2513,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
}
if (createVmData) {
NicVO nic = _nicDao.findByInstanceIdAndNetworkId(networkId, vm.getId());
NicVO nic = _nicDao.findByInstanceIdAndNetworkId(guestNetworkId, vm.getId());
if (nic != null) {
s_logger.debug("Creating user data entry for vm " + vm + " on domR " + router);
createVmDataCommand(router, vm, nic, null, cmds);
@ -2505,9 +2545,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
cmds.addCommand("dhcp", dhcpCommand);
}
private void createDhcpEntryCommandsForVMs(DomainRouterVO router, Commands cmds) {
long networkId = router.getNetworkId();
List<UserVmVO> vms = _userVmDao.listByNetworkIdAndStates(networkId, State.Running, State.Migrating, State.Stopping);
private void createDhcpEntryCommandsForVMs(DomainRouterVO router, Commands cmds, long guestNetworkId) {
List<UserVmVO> vms = _userVmDao.listByNetworkIdAndStates(guestNetworkId, State.Running, State.Migrating, State.Stopping);
DataCenterVO dc = _dcDao.findById(router.getDataCenterIdToDeployIn());
for (UserVmVO vm : vms) {
boolean createDhcp = true;
@ -2515,7 +2554,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
createDhcp = false;
}
if (createDhcp) {
NicVO nic = _nicDao.findByInstanceIdAndNetworkId(networkId, vm.getId());
NicVO nic = _nicDao.findByInstanceIdAndNetworkId(guestNetworkId, vm.getId());
if (nic != null) {
s_logger.debug("Creating dhcp entry for vm " + vm + " on domR " + router + ".");
createDhcpEntryCommand(router, vm, nic, cmds);
@ -2861,7 +2900,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
public void processConnect(HostVO host, StartupCommand cmd, boolean forRebalance) throws ConnectionException {
UserContext context = UserContext.current();
context.setAccountId(1);
List<DomainRouterVO> routers = _routerDao.listVirtualByHostId(host.getId());
List<DomainRouterVO> routers = _routerDao.listIsolatedByHostId(host.getId());
for (DomainRouterVO router : routers) {
if (router.isStopPending()) {
State state = router.getState();

View File

@ -64,16 +64,7 @@ public interface DomainRouterDao extends GenericDao<DomainRouterVO, Long> {
* @param hostId id of the host. null if to get all.
* @return list of DomainRouterVO
*/
public List<DomainRouterVO> listVirtualByHostId(Long hostId);
/**
* list virtual machine routers by host id. exclude destroyed, stopped, expunging VM,
* pass in null to get all
* virtual machine routers.
* @param hostId id of the host. null if to get all.
* @return list of DomainRouterVO
*/
public List<DomainRouterVO> listVirtualUpByHostId(Long hostId);
public List<DomainRouterVO> listIsolatedByHostId(Long hostId);
/**
* Find the list of domain routers for a domain
@ -101,4 +92,17 @@ public interface DomainRouterDao extends GenericDao<DomainRouterVO, Long> {
List<DomainRouterVO> listByNetworkAndRole(long networkId, Role role);
List<DomainRouterVO> listByElementId(long elementId);
/**
* Persists the domain router instance + creates the reference to the guest network (if not null)
* @param guestNetwork TODO
* @return
*/
DomainRouterVO persist(DomainRouterVO router, Network guestNetwork);
/**
* @param routerId
* @return
*/
List<Long> getRouterNetworks(long routerId);
}

View File

@ -16,15 +16,16 @@ import java.util.List;
import javax.ejb.Local;
import org.apache.log4j.Logger;
import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDaoImpl;
import com.cloud.network.Network;
import com.cloud.network.NetworkVO;
import com.cloud.network.dao.NetworkDaoImpl;
import com.cloud.network.RouterNetworkDaoImpl;
import com.cloud.network.RouterNetworkVO;
import com.cloud.network.router.VirtualRouter.Role;
import com.cloud.user.UserStatisticsVO;
import com.cloud.user.dao.UserStatisticsDaoImpl;
import com.cloud.utils.component.ComponentLocator;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.JoinBuilder.JoinType;
import com.cloud.utils.db.SearchBuilder;
@ -37,15 +38,16 @@ import com.cloud.vm.VirtualMachine.State;
@Local(value = { DomainRouterDao.class })
public class DomainRouterDaoImpl extends GenericDaoBase<DomainRouterVO, Long> implements DomainRouterDao {
private static final Logger s_logger = Logger.getLogger(DomainRouterDaoImpl.class);
protected final SearchBuilder<DomainRouterVO> AllFieldsSearch;
protected final SearchBuilder<DomainRouterVO> IdNetworkIdStatesSearch;
protected final SearchBuilder<DomainRouterVO> HostUpSearch;
protected final SearchBuilder<DomainRouterVO> StateNetworkTypeSearch;
protected final SearchBuilder<DomainRouterVO> OutsidePodSearch;
NetworkDaoImpl _networksDao = ComponentLocator.inject(NetworkDaoImpl.class);
HostDaoImpl _hostsDao = ComponentLocator.inject(HostDaoImpl.class);
RouterNetworkDaoImpl _routerNetworkDao = ComponentLocator.inject(RouterNetworkDaoImpl.class);
UserStatisticsDaoImpl _userStatsDao = ComponentLocator.inject(UserStatisticsDaoImpl.class);
protected DomainRouterDaoImpl() {
AllFieldsSearch = createSearchBuilder();
@ -56,37 +58,49 @@ public class DomainRouterDaoImpl extends GenericDaoBase<DomainRouterVO, Long> im
AllFieldsSearch.and("host", AllFieldsSearch.entity().getHostId(), Op.EQ);
AllFieldsSearch.and("lastHost", AllFieldsSearch.entity().getLastHostId(), Op.EQ);
AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), Op.EQ);
AllFieldsSearch.and("network", AllFieldsSearch.entity().getNetworkId(), Op.EQ);
SearchBuilder<RouterNetworkVO> joinRouterNetwork = _routerNetworkDao.createSearchBuilder();
joinRouterNetwork.and("networkId", joinRouterNetwork.entity().getNetworkId(), Op.EQ);
AllFieldsSearch.join("networkRouter", joinRouterNetwork, joinRouterNetwork.entity().getRouterId(), AllFieldsSearch.entity().getId(), JoinType.INNER);
AllFieldsSearch.and("podId", AllFieldsSearch.entity().getPodIdToDeployIn(), Op.EQ);
AllFieldsSearch.and("elementId", AllFieldsSearch.entity().getElementId(), Op.EQ);
AllFieldsSearch.done();
IdNetworkIdStatesSearch = createSearchBuilder();
IdNetworkIdStatesSearch.and("id", IdNetworkIdStatesSearch.entity().getId(), Op.EQ);
IdNetworkIdStatesSearch.and("network", IdNetworkIdStatesSearch.entity().getNetworkId(), Op.EQ);
SearchBuilder<RouterNetworkVO> joinRouterNetwork1 = _routerNetworkDao.createSearchBuilder();
joinRouterNetwork1.and("networkId", joinRouterNetwork1.entity().getNetworkId(), Op.EQ);
IdNetworkIdStatesSearch.join("networkRouter", joinRouterNetwork1, joinRouterNetwork1.entity().getRouterId(), IdNetworkIdStatesSearch.entity().getId(), JoinType.INNER);
IdNetworkIdStatesSearch.and("states", IdNetworkIdStatesSearch.entity().getState(), Op.IN);
IdNetworkIdStatesSearch.done();
HostUpSearch = createSearchBuilder();
HostUpSearch.and("host", HostUpSearch.entity().getHostId(), Op.EQ);
HostUpSearch.and("states", HostUpSearch.entity().getState(), Op.NIN);
SearchBuilder<NetworkVO> joinNetwork = _networksDao.createSearchBuilder();
joinNetwork.and("type", joinNetwork.entity().getGuestType(), Op.EQ);
HostUpSearch.join("network", joinNetwork, joinNetwork.entity().getId(), HostUpSearch.entity().getNetworkId(), JoinType.INNER);
SearchBuilder<RouterNetworkVO> joinRouterNetwork3 = _routerNetworkDao.createSearchBuilder();
joinRouterNetwork3.and("networkId", joinRouterNetwork3.entity().getNetworkId(), Op.EQ);
joinRouterNetwork3.and("type", joinRouterNetwork3.entity().getGuestType(), Op.EQ);
HostUpSearch.join("networkRouter", joinRouterNetwork3, joinRouterNetwork3.entity().getRouterId(), HostUpSearch.entity().getId(), JoinType.INNER);
HostUpSearch.done();
StateNetworkTypeSearch = createSearchBuilder();
StateNetworkTypeSearch.and("state", StateNetworkTypeSearch.entity().getState(), Op.EQ);
SearchBuilder<NetworkVO> joinStateNetwork = _networksDao.createSearchBuilder();
joinStateNetwork.and("type", joinStateNetwork.entity().getGuestType(), Op.EQ);
StateNetworkTypeSearch.join("network", joinStateNetwork, joinStateNetwork.entity().getId(), StateNetworkTypeSearch.entity().getNetworkId(), JoinType.INNER);
SearchBuilder<RouterNetworkVO> joinRouterNetwork4 = _routerNetworkDao.createSearchBuilder();
joinRouterNetwork4.and("networkId", joinRouterNetwork4.entity().getNetworkId(), Op.EQ);
joinRouterNetwork4.and("type", joinRouterNetwork4.entity().getGuestType(), Op.EQ);
StateNetworkTypeSearch.join("networkRouter", joinRouterNetwork4, joinRouterNetwork4.entity().getRouterId(), StateNetworkTypeSearch.entity().getId(), JoinType.INNER);
SearchBuilder<HostVO> joinHost = _hostsDao.createSearchBuilder();
joinHost.and("mgmtServerId", joinHost.entity().getManagementServerId(), Op.EQ);
StateNetworkTypeSearch.join("host", joinHost, joinHost.entity().getId(), StateNetworkTypeSearch.entity().getHostId(), JoinType.INNER);
StateNetworkTypeSearch.join("host", joinHost, joinHost.entity().getId(),
StateNetworkTypeSearch.entity().getHostId(), JoinType.INNER);
StateNetworkTypeSearch.done();
OutsidePodSearch = createSearchBuilder();
OutsidePodSearch.and("network", OutsidePodSearch.entity().getNetworkId(), Op.EQ);
SearchBuilder<RouterNetworkVO> joinRouterNetwork2 = _routerNetworkDao.createSearchBuilder();
joinRouterNetwork2.and("networkId", joinRouterNetwork2.entity().getNetworkId(), Op.EQ);
OutsidePodSearch.join("networkRouter", joinRouterNetwork2, joinRouterNetwork2.entity().getRouterId(),
OutsidePodSearch.entity().getId(), JoinType.INNER);
OutsidePodSearch.and("podId", OutsidePodSearch.entity().getPodIdToDeployIn(), Op.NEQ);
OutsidePodSearch.and("state", OutsidePodSearch.entity().getState(), Op.EQ);
OutsidePodSearch.and("role", OutsidePodSearch.entity().getRole(), Op.EQ);
@ -150,23 +164,12 @@ public class DomainRouterDaoImpl extends GenericDaoBase<DomainRouterVO, Long> im
}
@Override
public List<DomainRouterVO> listVirtualByHostId(Long hostId) {
public List<DomainRouterVO> listIsolatedByHostId(Long hostId) {
SearchCriteria<DomainRouterVO> sc = HostUpSearch.create();
if (hostId != null) {
sc.setParameters("host", hostId);
}
sc.setJoinParameters("network", "type", Network.GuestType.Isolated);
return listBy(sc);
}
@Override
public List<DomainRouterVO> listVirtualUpByHostId(Long hostId) {
SearchCriteria<DomainRouterVO> sc = HostUpSearch.create();
if (hostId != null) {
sc.setParameters("host", hostId);
}
sc.setParameters("states", State.Destroyed, State.Stopped, State.Expunging);
sc.setJoinParameters("network", "type", Network.GuestType.Isolated);
sc.setJoinParameters("networkRouter", "type", Network.GuestType.Isolated);
return listBy(sc);
}
@ -180,7 +183,7 @@ public class DomainRouterDaoImpl extends GenericDaoBase<DomainRouterVO, Long> im
@Override
public List<DomainRouterVO> findByNetwork(long networkId) {
SearchCriteria<DomainRouterVO> sc = AllFieldsSearch.create();
sc.setParameters("network", networkId);
sc.setParameters("networkId", networkId);
return listBy(sc);
}
@ -195,7 +198,7 @@ public class DomainRouterDaoImpl extends GenericDaoBase<DomainRouterVO, Long> im
@Override
public List<DomainRouterVO> listActive(long networkId) {
SearchCriteria<DomainRouterVO> sc = IdNetworkIdStatesSearch.create();
sc.setParameters("network", networkId);
sc.setParameters("networkId", networkId);
sc.setParameters("states", State.Running, State.Migrating, State.Stopping, State.Starting);
return listBy(sc);
}
@ -204,7 +207,7 @@ public class DomainRouterDaoImpl extends GenericDaoBase<DomainRouterVO, Long> im
public List<DomainRouterVO> listByStateAndNetworkType(State state, Network.GuestType type, long mgmtSrvrId) {
SearchCriteria<DomainRouterVO> sc = StateNetworkTypeSearch.create();
sc.setParameters("state", state);
sc.setJoinParameters("network", "type", type);
sc.setJoinParameters("networkRouter", "type", type);
sc.setJoinParameters("host", "mgmtServerId", mgmtSrvrId);
return listBy(sc);
}
@ -212,7 +215,7 @@ public class DomainRouterDaoImpl extends GenericDaoBase<DomainRouterVO, Long> im
@Override
public List<DomainRouterVO> findByNetworkOutsideThePod(long networkId, long podId, State state, Role role) {
SearchCriteria<DomainRouterVO> sc = OutsidePodSearch.create();
sc.setParameters("network", networkId);
sc.setParameters("networkId", networkId);
sc.setParameters("podId", podId);
sc.setParameters("state", state);
sc.setParameters("role", role);
@ -222,7 +225,7 @@ public class DomainRouterDaoImpl extends GenericDaoBase<DomainRouterVO, Long> im
@Override
public List<DomainRouterVO> listByNetworkAndPodAndRole(long networkId, long podId, Role role) {
SearchCriteria<DomainRouterVO> sc = AllFieldsSearch.create();
sc.setParameters("network", networkId);
sc.setParameters("networkId", networkId);
sc.setParameters("podId", podId);
sc.setParameters("role", role);
return listBy(sc);
@ -231,7 +234,7 @@ public class DomainRouterDaoImpl extends GenericDaoBase<DomainRouterVO, Long> im
@Override
public List<DomainRouterVO> listByNetworkAndRole(long networkId, Role role) {
SearchCriteria<DomainRouterVO> sc = AllFieldsSearch.create();
sc.setParameters("network", networkId);
sc.setParameters("networkId", networkId);
sc.setParameters("role", role);
return listBy(sc);
}
@ -242,4 +245,39 @@ public class DomainRouterDaoImpl extends GenericDaoBase<DomainRouterVO, Long> im
sc.setParameters("elementId", elementId);
return listBy(sc);
}
@Override
@DB
public DomainRouterVO persist(DomainRouterVO router, Network guestNetwork) {
Transaction txn = Transaction.currentTxn();
txn.start();
// 1) create network
DomainRouterVO newRouter = super.persist(router);
// 2) add router to the network
addRouterToNetwork(router.getId(), guestNetwork);
// 3) create user stats entry
UserStatisticsVO stats = _userStatsDao.findBy(router.getAccountId(), router.getDataCenterIdToDeployIn(),
guestNetwork.getId(), null, router.getId(), router.getType().toString());
if (stats == null) {
stats = new UserStatisticsVO(router.getAccountId(), router.getDataCenterIdToDeployIn(), null, router.getId(),
router.getType().toString(), guestNetwork.getId());
_userStatsDao.persist(stats);
}
txn.commit();
return newRouter;
}
protected void addRouterToNetwork(long routerId, Network guestNetwork) {
RouterNetworkVO routerNtwkMap = new RouterNetworkVO(routerId, guestNetwork.getId(), guestNetwork.getGuestType());
_routerNetworkDao.persist(routerNtwkMap);
}
@Override
public List<Long> getRouterNetworks(long routerId) {
return _routerNetworkDao.getRouterNetworks(routerId);
}
}

View File

@ -2184,5 +2184,16 @@ CREATE TABLE `cloud`.`vpc_offering_service_map` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `cloud`.`router_network_ref` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
`router_id` bigint unsigned NOT NULL COMMENT 'router id',
`network_id` bigint unsigned NOT NULL COMMENT 'network id',
`guest_type` char(32) COMMENT 'type of guest network that can be shared or isolated',
PRIMARY KEY (`id`),
CONSTRAINT `fk_router_network_ref__router_id` FOREIGN KEY (`router_id`) REFERENCES `domain_router`(`id`) ON DELETE CASCADE,
CONSTRAINT `fk_router_network_ref__networks_id` FOREIGN KEY (`network_id`) REFERENCES `networks`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
SET foreign_key_checks = 1;

View File

@ -3,7 +3,7 @@
# the following two variables are used by the target "waf dist"
# if you change 'em here, you need to change it also in cloud.spec, add a %changelog entry there, and add an entry in debian/changelog
VERSION = '3.0.3.2012-05-18T01:05:37Z'
VERSION = '3.0.3.2012-05-19T00:20:25Z'
APPNAME = 'cloud'
import shutil,os