From 9debd3a5df4f83d9c0bd03b5aeafbb295d64e689 Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Mon, 21 May 2012 14:29:34 -0700 Subject: [PATCH] 1) Added start logic to the VPC 2) VirtualRouterManagerImpl - refactored deployVirtualRouter method 3) Added vpcId to domain_router/user_ip_address tables and corresponding vo objects Conflicts: server/src/com/cloud/network/IPAddressVO.java --- .../com/cloud/api/commands/CreateVPCCmd.java | 18 +- api/src/com/cloud/network/IpAddress.java | 10 + .../cloud/network/element/NetworkElement.java | 16 +- .../element/UserDataServiceProvider.java | 1 - .../cloud/network/element/VpcProvider.java | 35 + .../cloud/network/router/VirtualRouter.java | 4 + .../com/cloud/network/vpc/VpcOffering.java | 5 + api/src/com/cloud/network/vpc/VpcService.java | 16 +- core/src/com/cloud/vm/DomainRouterVO.java | 8 + .../DefaultComponentLibrary.java | 3 +- server/src/com/cloud/network/IPAddressVO.java | 18 +- .../src/com/cloud/network/NetworkManager.java | 7 + .../com/cloud/network/NetworkManagerImpl.java | 6 +- .../network/element/VirtualRouterElement.java | 63 +- .../VirtualNetworkApplianceManager.java | 2 +- .../VirtualNetworkApplianceManagerImpl.java | 614 ++++++++++-------- .../VpcVirtualNetworkApplianceManager.java | 45 ++ ...VpcVirtualNetworkApplianceManagerImpl.java | 112 ++++ .../network/vpc/Dao/VpcOfferingDaoImpl.java | 2 +- .../com/cloud/network/vpc/VpcManagerImpl.java | 56 +- .../com/cloud/network/vpc/VpcOfferingVO.java | 16 +- .../src/com/cloud/vm/dao/DomainRouterDao.java | 6 + .../com/cloud/vm/dao/DomainRouterDaoImpl.java | 9 + setup/db/create-schema.sql | 11 +- wscript | 2 +- 25 files changed, 774 insertions(+), 311 deletions(-) create mode 100644 api/src/com/cloud/network/element/VpcProvider.java create mode 100644 server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManager.java create mode 100644 server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java diff --git a/api/src/com/cloud/api/commands/CreateVPCCmd.java b/api/src/com/cloud/api/commands/CreateVPCCmd.java index 59efff6cbcd..b8e2fe3bb6c 100644 --- a/api/src/com/cloud/api/commands/CreateVPCCmd.java +++ b/api/src/com/cloud/api/commands/CreateVPCCmd.java @@ -22,7 +22,10 @@ import com.cloud.api.Parameter; import com.cloud.api.ServerApiException; import com.cloud.api.response.VpcResponse; import com.cloud.event.EventTypes; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.ResourceAllocationException; +import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.vpc.Vpc; import com.cloud.user.UserContext; @@ -111,7 +114,20 @@ public class CreateVPCCmd extends BaseAsyncCreateCmd{ @Override public void execute() { //TODO - prepare vpc here (call start() method, it should start the VR, associate source nat ip address, etc) - Vpc vpc = _vpcService.getVpc(this.getEntityId()); + Vpc vpc = null; + try { + vpc = _vpcService.startVpc(this.getEntityId()); + } catch (ResourceUnavailableException ex) { + s_logger.warn("Exception: ", ex); + throw new ServerApiException(BaseCmd.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage()); + } catch (ConcurrentOperationException ex) { + s_logger.warn("Exception: ", ex); + throw new ServerApiException(BaseCmd.INTERNAL_ERROR, ex.getMessage()); + } catch (InsufficientCapacityException ex) { + s_logger.info(ex); + s_logger.trace(ex); + throw new ServerApiException(BaseCmd.INSUFFICIENT_CAPACITY_ERROR, ex.getMessage()); + } if (vpc != null) { VpcResponse response = _responseGenerator.createVpcResponse(vpc); response.setResponseName(getCommandName()); diff --git a/api/src/com/cloud/network/IpAddress.java b/api/src/com/cloud/network/IpAddress.java index 5885572ee38..f67a1fa3c46 100644 --- a/api/src/com/cloud/network/IpAddress.java +++ b/api/src/com/cloud/network/IpAddress.java @@ -80,4 +80,14 @@ public interface IpAddress extends ControlledEntity { boolean getSystem(); + /** + * @return + */ + Long getVpcId(); + + /** + * @param vpcId + */ + void setVpcId(Long vpcId); + } diff --git a/api/src/com/cloud/network/element/NetworkElement.java b/api/src/com/cloud/network/element/NetworkElement.java index c838fd3d919..3fdb094d9bb 100644 --- a/api/src/com/cloud/network/element/NetworkElement.java +++ b/api/src/com/cloud/network/element/NetworkElement.java @@ -56,7 +56,8 @@ public interface NetworkElement extends Adapter { * @return true if network configuration is now usable; false if not; null if not handled by this element. * @throws InsufficientNetworkCapacityException TODO */ - boolean implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException; + boolean implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) + throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException; /** * Prepare for a nic to be added into this network. @@ -70,7 +71,9 @@ public interface NetworkElement extends Adapter { * @throws ResourceUnavailableException * @throws InsufficientNetworkCapacityException */ - boolean prepare(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException; + boolean prepare(Network network, NicProfile nic, VirtualMachineProfile vm, + DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, + ResourceUnavailableException, InsufficientCapacityException; /** * A nic is released from this network. @@ -82,7 +85,8 @@ public interface NetworkElement extends Adapter { * @throws ConcurrentOperationException * @throws ResourceUnavailableException */ - boolean release(Network network, NicProfile nic, VirtualMachineProfile vm, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException; + boolean release(Network network, NicProfile nic, VirtualMachineProfile vm, + ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException; /** * The network is being shutdown. @@ -93,7 +97,8 @@ public interface NetworkElement extends Adapter { * @throws ConcurrentOperationException * @throws ResourceUnavailableException */ - boolean shutdown(Network network, ReservationContext context, boolean cleanup) throws ConcurrentOperationException, ResourceUnavailableException; + boolean shutdown(Network network, ReservationContext context, boolean cleanup) + throws ConcurrentOperationException, ResourceUnavailableException; /** * The network is being destroyed. @@ -118,7 +123,8 @@ public interface NetworkElement extends Adapter { * @throws ConcurrentOperationException * @throws ResourceUnavailableException */ - boolean shutdownProviderInstances(PhysicalNetworkServiceProvider provider, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException; + boolean shutdownProviderInstances(PhysicalNetworkServiceProvider provider, ReservationContext context) + throws ConcurrentOperationException, ResourceUnavailableException; /** * This should return true if out of multiple services provided by this element, only some can be enabled. If all the services MUST be provided, this should return false. diff --git a/api/src/com/cloud/network/element/UserDataServiceProvider.java b/api/src/com/cloud/network/element/UserDataServiceProvider.java index fe4c324142d..d848216d37f 100644 --- a/api/src/com/cloud/network/element/UserDataServiceProvider.java +++ b/api/src/com/cloud/network/element/UserDataServiceProvider.java @@ -21,7 +21,6 @@ import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.Network; -import com.cloud.uservm.UserVm; import com.cloud.vm.NicProfile; import com.cloud.vm.ReservationContext; import com.cloud.vm.VirtualMachine; diff --git a/api/src/com/cloud/network/element/VpcProvider.java b/api/src/com/cloud/network/element/VpcProvider.java new file mode 100644 index 00000000000..86f70ea53d9 --- /dev/null +++ b/api/src/com/cloud/network/element/VpcProvider.java @@ -0,0 +1,35 @@ +// 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.element; + +import com.cloud.deploy.DeployDestination; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InsufficientNetworkCapacityException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.vpc.Vpc; +import com.cloud.vm.ReservationContext; + +/** + * @author Alena Prokharchyk + */ +public interface VpcProvider extends NetworkElement{ + /** + * Start vpc element as specified + * @param vpc fully specified vpc configuration. + * @throws InsufficientNetworkCapacityException TODO + */ + boolean startVpc(Vpc vpc, DeployDestination dest, ReservationContext context) + throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException; + +} diff --git a/api/src/com/cloud/network/router/VirtualRouter.java b/api/src/com/cloud/network/router/VirtualRouter.java index 6be97e3d966..fc50efb4b2d 100755 --- a/api/src/com/cloud/network/router/VirtualRouter.java +++ b/api/src/com/cloud/network/router/VirtualRouter.java @@ -38,4 +38,8 @@ public interface VirtualRouter extends VirtualMachine { String getPublicIpAddress(); boolean isStopPending(); void setStopPending(boolean stopPending); + /** + * @return + */ + Long getVpcId(); } diff --git a/api/src/com/cloud/network/vpc/VpcOffering.java b/api/src/com/cloud/network/vpc/VpcOffering.java index 5531f55a998..167cdced8bb 100644 --- a/api/src/com/cloud/network/vpc/VpcOffering.java +++ b/api/src/com/cloud/network/vpc/VpcOffering.java @@ -38,4 +38,9 @@ public interface VpcOffering { boolean isDefault(); + /** + * @return + */ + Long getServiceOfferingId(); + } diff --git a/api/src/com/cloud/network/vpc/VpcService.java b/api/src/com/cloud/network/vpc/VpcService.java index faf2845006c..682c0c6feec 100644 --- a/api/src/com/cloud/network/vpc/VpcService.java +++ b/api/src/com/cloud/network/vpc/VpcService.java @@ -16,6 +16,9 @@ import java.util.List; import java.util.Map; import java.util.Set; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.Network; import com.cloud.network.Network.Provider; import com.cloud.network.Network.Service; @@ -30,9 +33,7 @@ public interface VpcService { public VpcOffering createVpcOffering(String name, String displayText, List supportedServices); public Vpc getVpc(long vpcId); - - public Vpc createVpc(long zoneId, String name, String cidr, long ownerId); - + public List getVpcNetworks(long vpcId); Map> getVpcOffSvcProvidersMap(long vpcOffId); @@ -102,4 +103,13 @@ public interface VpcService { List supportedServicesStr, String cidr, Long vpcOffId, String state, String accountName, Long domainId, String keyword, Long startIndex, Long pageSizeVal, Long zoneId, Boolean isRecursive, Boolean listAll); + /** + * @param vpcId + * @return + * @throws InsufficientCapacityException + * @throws ResourceUnavailableException + * @throws ConcurrentOperationException + */ + Vpc startVpc(long vpcId) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException; + } diff --git a/core/src/com/cloud/vm/DomainRouterVO.java b/core/src/com/cloud/vm/DomainRouterVO.java index dcf41485904..43d851dcd76 100755 --- a/core/src/com/cloud/vm/DomainRouterVO.java +++ b/core/src/com/cloud/vm/DomainRouterVO.java @@ -71,6 +71,9 @@ public class DomainRouterVO extends VMInstanceVO implements VirtualRouter { @Column(name="scripts_version") private String scriptsVersion; + @Column(name="vpc_id") + private Long vpcId; + public DomainRouterVO(long id, long serviceOfferingId, long elementId, @@ -240,4 +243,9 @@ public class DomainRouterVO extends VMInstanceVO implements VirtualRouter { public void setScriptsVersion(String scriptsVersion) { this.scriptsVersion = scriptsVersion; } + + @Override + public Long getVpcId() { + return vpcId; + } } diff --git a/server/src/com/cloud/configuration/DefaultComponentLibrary.java b/server/src/com/cloud/configuration/DefaultComponentLibrary.java index 4cf6d6eb0c0..e2ae66c651f 100755 --- a/server/src/com/cloud/configuration/DefaultComponentLibrary.java +++ b/server/src/com/cloud/configuration/DefaultComponentLibrary.java @@ -70,7 +70,6 @@ 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; @@ -114,6 +113,7 @@ import com.cloud.network.ovs.OvsTunnelManagerImpl; import com.cloud.network.ovs.dao.OvsTunnelInterfaceDaoImpl; import com.cloud.network.ovs.dao.OvsTunnelNetworkDaoImpl; import com.cloud.network.router.VirtualNetworkApplianceManagerImpl; +import com.cloud.network.router.VpcVirtualNetworkApplianceManagerImpl; import com.cloud.network.rules.RulesManagerImpl; import com.cloud.network.rules.dao.PortForwardingRulesDaoImpl; import com.cloud.network.security.SecurityGroupManagerImpl2; @@ -394,6 +394,7 @@ public class DefaultComponentLibrary extends ComponentLibraryBase implements Com addManager("ExternalLoadBalancerUsageManager", ExternalLoadBalancerUsageManagerImpl.class); addManager("HA Manager", HighAvailabilityManagerImpl.class); addManager("VPC Manager", VpcManagerImpl.class); + addManager("VpcVirtualRouterManager", VpcVirtualNetworkApplianceManagerImpl.class); } @Override diff --git a/server/src/com/cloud/network/IPAddressVO.java b/server/src/com/cloud/network/IPAddressVO.java index fb05d2bc612..b28efec3b06 100644 --- a/server/src/com/cloud/network/IPAddressVO.java +++ b/server/src/com/cloud/network/IPAddressVO.java @@ -28,7 +28,6 @@ import javax.persistence.TemporalType; import javax.persistence.Transient; import com.cloud.api.Identity; -import com.cloud.network.IpAddress; import com.cloud.utils.net.Ip; /** @@ -101,7 +100,10 @@ public class IPAddressVO implements IpAddress, Identity { @Transient @Column(name="domain_id") private Long domainId = null; - + + @Column(name="vpc_id") + private Long vpcId; + protected IPAddressVO() { this.uuid = UUID.randomUUID().toString(); } @@ -272,4 +274,14 @@ public class IPAddressVO implements IpAddress, Identity { public void setSystem(boolean isSystem) { this.system = isSystem; } -} + + @Override + public Long getVpcId() { + return vpcId; + } + + @Override + public void setVpcId(Long vpcId) { + this.vpcId = vpcId; + } +} diff --git a/server/src/com/cloud/network/NetworkManager.java b/server/src/com/cloud/network/NetworkManager.java index 2577440d298..bdd07175b5b 100755 --- a/server/src/com/cloud/network/NetworkManager.java +++ b/server/src/com/cloud/network/NetworkManager.java @@ -36,6 +36,7 @@ import com.cloud.network.Network.Provider; import com.cloud.network.Network.Service; import com.cloud.network.Networks.TrafficType; import com.cloud.network.addr.PublicIp; +import com.cloud.network.element.NetworkElement; import com.cloud.network.element.RemoteAccessVPNServiceProvider; import com.cloud.network.element.UserDataServiceProvider; import com.cloud.network.guru.NetworkGuru; @@ -307,4 +308,10 @@ public interface NetworkManager extends NetworkService { String getDefaultPublicTrafficLabel(long dcId, HypervisorType vmware); String getDefaultGuestTrafficLabel(long dcId, HypervisorType vmware); + + /** + * @param providerName + * @return + */ + NetworkElement getElementImplementingProvider(String providerName); } diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 7eae799203e..2150d7e32db 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -327,6 +327,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag private static HashMap> s_serviceToImplementedProvidersMap = new HashMap>(); private static HashMap s_providerToNetworkElementMap = new HashMap(); + @Override public NetworkElement getElementImplementingProvider(String providerName) { String elementName = s_providerToNetworkElementMap.get(providerName); NetworkElement element = _networkElements.get(elementName); @@ -1782,12 +1783,13 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag private void implementNetworkElementsAndResources(DeployDestination dest, ReservationContext context, NetworkVO network, NetworkOfferingVO offering) throws ConcurrentOperationException, InsufficientAddressCapacityException, ResourceUnavailableException, InsufficientCapacityException { // If this is a 1) guest virtual network 2) network has sourceNat service 3) network offering does not support a -// Shared source NAT rule, + // Shared source NAT rule, // associate a source NAT IP (if one isn't already associated with the network) boolean sharedSourceNat = offering.getSharedSourceNat(); - if (network.getGuestType() == Network.GuestType.Isolated && areServicesSupportedInNetwork(network.getId(), Service.SourceNat) && !sharedSourceNat) { + if (network.getGuestType() == Network.GuestType.Isolated && areServicesSupportedInNetwork(network.getId(), Service.SourceNat) + && !sharedSourceNat) { List ips = _ipAddressDao.listByAssociatedNetwork(network.getId(), true); if (ips.isEmpty()) { diff --git a/server/src/com/cloud/network/element/VirtualRouterElement.java b/server/src/com/cloud/network/element/VirtualRouterElement.java index 7defe1016ed..76db8516a59 100755 --- a/server/src/com/cloud/network/element/VirtualRouterElement.java +++ b/server/src/com/cloud/network/element/VirtualRouterElement.java @@ -55,12 +55,14 @@ import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy; import com.cloud.network.lb.LoadBalancingRulesManager; import com.cloud.network.router.VirtualNetworkApplianceManager; import com.cloud.network.router.VirtualRouter.Role; +import com.cloud.network.router.VpcVirtualNetworkApplianceManager; import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.LbStickinessMethod; import com.cloud.network.rules.LbStickinessMethod.StickinessMethodType; import com.cloud.network.rules.PortForwardingRule; import com.cloud.network.rules.RulesManager; import com.cloud.network.rules.StaticNat; +import com.cloud.network.vpc.Vpc; import com.cloud.offering.NetworkOffering; import com.cloud.offerings.NetworkOfferingVO; import com.cloud.offerings.dao.NetworkOfferingDao; @@ -85,8 +87,9 @@ import com.cloud.vm.dao.UserVmDao; import com.google.gson.Gson; @Local(value = NetworkElement.class) -public class VirtualRouterElement extends AdapterBase implements VirtualRouterElementService, DhcpServiceProvider, UserDataServiceProvider, SourceNatServiceProvider, StaticNatServiceProvider, FirewallServiceProvider, - LoadBalancingServiceProvider, PortForwardingServiceProvider, RemoteAccessVPNServiceProvider, IpDeployer { +public class VirtualRouterElement extends AdapterBase implements VirtualRouterElementService, DhcpServiceProvider, + UserDataServiceProvider, SourceNatServiceProvider, StaticNatServiceProvider, FirewallServiceProvider, + LoadBalancingServiceProvider, PortForwardingServiceProvider, RemoteAccessVPNServiceProvider, IpDeployer, VpcProvider { private static final Logger s_logger = Logger.getLogger(VirtualRouterElement.class); private static final Map> capabilities = setCapabilities(); @@ -121,6 +124,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl ConfigurationDao _configDao; @Inject VirtualRouterProviderDao _vrProviderDao; + @Inject + VpcVirtualNetworkApplianceManager _vpcRouterMgr; protected boolean canHandle(Network network, Service service) { Long physicalNetworkId = _networkMgr.getPhysicalNetworkId(network); @@ -139,7 +144,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl } } else { if (!_networkMgr.isProviderSupportServiceInNetwork(network.getId(), service, getProvider())) { - s_logger.trace("Element " + getProvider().getName() + " doesn't support service " + service.getName() + " in the network " + network); + s_logger.trace("Element " + getProvider().getName() + " doesn't support service " + service.getName() + + " in the network " + network); return false; } } @@ -148,8 +154,10 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl } @Override - public boolean implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws ResourceUnavailableException, ConcurrentOperationException, + public boolean implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) + throws ResourceUnavailableException, ConcurrentOperationException, InsufficientCapacityException { + if (offering.isSystemOnly()) { return false; } @@ -157,13 +165,16 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl Map params = new HashMap(1); params.put(VirtualMachineProfile.Param.ReProgramGuestNetworks, true); - _routerMgr.deployVirtualRouter(network, dest, _accountMgr.getAccount(network.getAccountId()), params, offering.getRedundantRouter()); + _routerMgr.deployVirtualRouterInGuestNetwork(network, dest, _accountMgr.getAccount(network.getAccountId()), params, + offering.getRedundantRouter()); return true; } @Override - public boolean prepare(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, + public boolean prepare(Network network, NicProfile nic, VirtualMachineProfile vm, + DeployDestination dest, ReservationContext context) + throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { if (vm.getType() != VirtualMachine.Type.User || vm.getHypervisorType() == HypervisorType.BareMetal) { return false; @@ -183,7 +194,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl @SuppressWarnings("unchecked") VirtualMachineProfile uservm = (VirtualMachineProfile) vm; - List routers = _routerMgr.deployVirtualRouter(network, dest, _accountMgr.getAccount(network.getAccountId()), uservm.getParameters(), offering.getRedundantRouter()); + List routers = _routerMgr.deployVirtualRouterInGuestNetwork(network, dest, _accountMgr.getAccount(network.getAccountId()), + uservm.getParameters(), offering.getRedundantRouter()); if ((routers == null) || (routers.size() == 0)) { throw new ResourceUnavailableException("Can't find at least one running router!", DataCenter.class, network.getDataCenterId()); } @@ -195,7 +207,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl if (canHandle(config, Service.Firewall)) { List routers = _routerDao.listByNetworkAndRole(config.getId(), Role.VIRTUAL_ROUTER); if (routers == null || routers.isEmpty()) { - s_logger.debug("Virtual router elemnt doesn't need to apply firewall rules on the backend; virtual router doesn't exist in the network " + config.getId()); + s_logger.debug("Virtual router elemnt doesn't need to apply firewall rules on the backend; virtual " + + "router doesn't exist in the network " + config.getId()); return true; } @@ -265,10 +278,12 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl expire = value; } if ((expire != null) && !containsOnlyNumbers(expire, timeEndChar)) { - throw new InvalidParameterValueException("Failed LB in validation rule id: " + rule.getId() + " Cause: expire is not in timeformat: " + expire); + throw new InvalidParameterValueException("Failed LB in validation rule id: " + rule.getId() + + " Cause: expire is not in timeformat: " + expire); } if ((tablesize != null) && !containsOnlyNumbers(tablesize, "kmg")) { - throw new InvalidParameterValueException("Failed LB in validation rule id: " + rule.getId() + " Cause: tablesize is not in size format: " + tablesize); + throw new InvalidParameterValueException("Failed LB in validation rule id: " + rule.getId() + + " Cause: tablesize is not in size format: " + tablesize); } } else if (StickinessMethodType.AppCookieBased.getName().equalsIgnoreCase(stickinessPolicy.getMethodName())) { @@ -294,7 +309,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl } if ((length != null) && (!containsOnlyNumbers(length, null))) { - throw new InvalidParameterValueException("Failed LB in validation rule id: " + rule.getId() + " Cause: length is not a number: " + length); + throw new InvalidParameterValueException("Failed LB in validation rule id: " + rule.getId() + + " Cause: length is not a number: " + length); } if ((holdTime != null) && (!containsOnlyNumbers(holdTime, timeEndChar) && !containsOnlyNumbers(holdTime, null))) { throw new InvalidParameterValueException("Failed LB in validation rule id: " + rule.getId() + " Cause: holdtime is not in timeformat: " + holdTime); @@ -321,7 +337,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl if (canHandle(network, Service.Lb)) { List routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); if (routers == null || routers.isEmpty()) { - s_logger.debug("Virtual router elemnt doesn't need to apply firewall rules on the backend; virtual router doesn't exist in the network " + network.getId()); + s_logger.debug("Virtual router elemnt doesn't need to apply firewall rules on the backend; virtual " + + "router doesn't exist in the network " + network.getId()); return true; } @@ -372,7 +389,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl if (canHandle(network, Service.Vpn)) { List routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); if (routers == null || routers.isEmpty()) { - s_logger.debug("Virtual router elemnt doesn't need stop vpn on the backend; virtual router doesn't exist in the network " + network.getId()); + s_logger.debug("Virtual router elemnt doesn't need stop vpn on the backend; virtual router doesn't " + + "exist in the network " + network.getId()); return true; } return _routerMgr.deleteRemoteAccessVpn(network, vpn, routers); @@ -394,7 +412,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl if (canHandle) { List routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); if (routers == null || routers.isEmpty()) { - s_logger.debug("Virtual router elemnt doesn't need to associate ip addresses on the backend; virtual router doesn't exist in the network " + network.getId()); + s_logger.debug("Virtual router elemnt doesn't need to associate ip addresses on the backend; virtual " + + "router doesn't exist in the network " + network.getId()); return true; } @@ -724,7 +743,7 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl } // for Basic zone, add all Running routers - we have to send Dhcp/vmData/password info to them when -// network.dns.basiczone.updates is set to "all" + // network.dns.basiczone.updates is set to "all" Long podId = dest.getPod().getId(); if (isPodBased && _routerMgr.getDnsBasicZoneUpdate().equalsIgnoreCase("all")) { List allRunningRoutersOutsideThePod = _routerDao.findByNetworkOutsideThePod(network.getId(), podId, State.Running, Role.VIRTUAL_ROUTER); @@ -772,7 +791,7 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl } // for Basic zone, add all Running routers - we have to send Dhcp/vmData/password info to them when -// network.dns.basiczone.updates is set to "all" + // network.dns.basiczone.updates is set to "all" Long podId = dest.getPod().getId(); if (isPodBased && _routerMgr.getDnsBasicZoneUpdate().equalsIgnoreCase("all")) { List allRunningRoutersOutsideThePod = _routerDao.findByNetworkOutsideThePod(network.getId(), podId, State.Running, Role.VIRTUAL_ROUTER); @@ -823,4 +842,16 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl public IpDeployer getIpDeployer(Network network) { return this; } + + @Override + public boolean startVpc(Vpc vpc, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, + ResourceUnavailableException, InsufficientCapacityException { + + Map params = new HashMap(1); + params.put(VirtualMachineProfile.Param.ReProgramGuestNetworks, true); + + _vpcRouterMgr.deployVirtualRouterInVpc(vpc, dest, _accountMgr.getAccount(vpc.getAccountId()), params); + + return true; + } } diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java index 5c40161ee32..f6d83c3f865 100644 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java @@ -59,7 +59,7 @@ public interface VirtualNetworkApplianceManager extends Manager, VirtualNetworkA boolean savePasswordToRouter(Network network, NicProfile nic, VirtualMachineProfile profile, List routers) throws ResourceUnavailableException; - List deployVirtualRouter(Network guestNetwork, DeployDestination dest, Account owner, + List deployVirtualRouterInGuestNetwork(Network guestNetwork, DeployDestination dest, Account owner, Map params, boolean isRedundant) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException; diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index bf7f8385f79..f8f87d8752d 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -98,6 +98,7 @@ import com.cloud.event.EventTypes; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.ConnectionException; +import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.InsufficientServerCapacityException; import com.cloud.exception.InsufficientVirtualNetworkCapcityException; @@ -310,7 +311,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian int _routerStatsInterval = 300; int _routerCheckInterval = 30; - private ServiceOfferingVO _offering; + protected ServiceOfferingVO _offering; private String _dnsBasicZoneUpdates = "all"; private boolean _disable_rp_filter = false; @@ -403,7 +404,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian // Check that the service offering being upgraded to has the same storage pool preference as the VM's current service // offering if (currentServiceOffering.getUseLocalStorage() != newServiceOffering.getUseLocalStorage()) { - throw new InvalidParameterValueException("Can't upgrade, due to new local storage status : " + newServiceOffering.getUseLocalStorage() + " is different from " + throw new InvalidParameterValueException("Can't upgrade, due to new local storage status : " + + newServiceOffering.getUseLocalStorage() + " is different from " + "curruent local storage status: " + currentServiceOffering.getUseLocalStorage()); } @@ -526,7 +528,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } @Override @ActionEvent(eventType = EventTypes.EVENT_ROUTER_REBOOT, eventDescription = "rebooting router Vm", async = true) - public VirtualRouter rebootRouter(long routerId, boolean reprogramNetwork) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { + public VirtualRouter rebootRouter(long routerId, boolean reprogramNetwork) throws ConcurrentOperationException, + ResourceUnavailableException, InsufficientCapacityException { Account caller = UserContext.current().getCaller(); // verify parameters @@ -540,7 +543,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian // Can reboot domain router only in Running state if (router == null || router.getState() != State.Running) { s_logger.warn("Unable to reboot, virtual router is not in the right state " + router.getState()); - throw new ResourceUnavailableException("Unable to reboot domR, it is not in right state " + router.getState(), DataCenter.class, router.getDataCenterIdToDeployIn()); + throw new ResourceUnavailableException("Unable to reboot domR, it is not in right state " + router.getState(), + DataCenter.class, router.getDataCenterIdToDeployIn()); } UserVO user = _userDao.findById(UserContext.current().getCallerUserId()); @@ -603,7 +607,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian _itMgr.registerGuru(VirtualMachine.Type.DomainRouter, this); boolean useLocalStorage = Boolean.parseBoolean(configs.get(Config.SystemVMUseLocalStorage.key())); - _offering = new ServiceOfferingVO("System Offering For Software Router", 1, _routerRamSize, _routerCpuMHz, null, null, true, null, useLocalStorage, true, null, true, VirtualMachine.Type.DomainRouter, true); + _offering = new ServiceOfferingVO("System Offering For Software Router", 1, _routerRamSize, _routerCpuMHz, null, + null, true, null, useLocalStorage, true, null, true, VirtualMachine.Type.DomainRouter, true); _offering.setUniqueName(ServiceOffering.routerDefaultOffUniqueName); _offering = _serviceOfferingDao.persistSystemServiceOffering(_offering); @@ -671,7 +676,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian endDate = cal.getTime().getTime(); } - _networkStatsUpdateExecutor.scheduleAtFixedRate(new NetworkStatsUpdateTask(), (endDate - System.currentTimeMillis()), (_usageAggregationRange * 60 * 1000), TimeUnit.MILLISECONDS); + _networkStatsUpdateExecutor.scheduleAtFixedRate(new NetworkStatsUpdateTask(), (endDate - System.currentTimeMillis()), + (_usageAggregationRange * 60 * 1000), TimeUnit.MILLISECONDS); if (_routerCheckInterval > 0) { _checkExecutor.scheduleAtFixedRate(new CheckRouterTask(), _routerCheckInterval, _routerCheckInterval, TimeUnit.SECONDS); @@ -699,7 +705,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian return VirtualMachineName.getRouterId(vmName); } - private VmDataCommand generateVmDataCommand(VirtualRouter router, String vmPrivateIpAddress, String userData, String serviceOffering, String zoneName, String guestIpAddress, String vmName, + private VmDataCommand generateVmDataCommand(VirtualRouter router, String vmPrivateIpAddress, String userData, + String serviceOffering, String zoneName, String guestIpAddress, String vmName, String vmInstanceName, long vmId, String publicKey) { VmDataCommand cmd = new VmDataCommand(vmPrivateIpAddress, vmName); @@ -791,14 +798,19 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } 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()); + && ((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; } 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() + 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()); @@ -806,7 +818,9 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian 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() + 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()); @@ -816,7 +830,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian 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()); + s_logger.warn("Unable to update user statistics for account: " + router.getAccountId() + + " Rx: " + answer.getBytesReceived() + "; Tx: " + answer.getBytesSent()); } finally { txn.close(); } @@ -1139,7 +1154,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian for (HostVO h : hosts) { if (h.getStatus() == Status.Up) { - s_logger.debug("Pick up host that has hypervisor type " + h.getHypervisorType() + " in cluster " + cv.getId() + " to start domain router for OVM"); + s_logger.debug("Pick up host that has hypervisor type " + h.getHypervisorType() + " in cluster " + + cv.getId() + " to start domain router for OVM"); return h.getHypervisorType(); } } @@ -1147,21 +1163,44 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian String errMsg = "Cannot find an available cluster in Pod " + podId - + " to start domain router for Ovm. \n Ovm won't support any system vm including domain router, please make sure you have a cluster with hypervisor type of any of xenserver/KVM/Vmware in the same pod with Ovm cluster. And there is at least one host in UP status in that cluster."; + + " to start domain router for Ovm. \n Ovm won't support any system vm including domain router, " + + "please make sure you have a cluster with hypervisor type of any of xenserver/KVM/Vmware in the same pod" + + " with Ovm cluster. And there is at least one host in UP status in that cluster."; throw new CloudRuntimeException(errMsg); } @DB - protected List findOrDeployVirtualRouters(Network guestNetwork, DeployDestination dest, Account owner, boolean isRedundant, Map params) throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { + protected List findOrDeployVirtualRouterInGuestNetwork(Network guestNetwork, DeployDestination dest, Account owner, + boolean isRedundant, Map params) throws ConcurrentOperationException, + InsufficientCapacityException, ResourceUnavailableException { + + assert guestNetwork.getState() == Network.State.Implemented || guestNetwork.getState() == Network.State.Setup || + guestNetwork.getState() == Network.State.Implementing : "Network is not yet fully implemented: " + + guestNetwork; + assert guestNetwork.getTrafficType() == TrafficType.Guest; Network network = _networkDao.acquireInLockTable(guestNetwork.getId()); if (network == null) { throw new ConcurrentOperationException("Unable to lock network " + guestNetwork.getId()); } + + //Check if providers are supported in the physical networks + VirtualRouterProviderType type = VirtualRouterProviderType.VirtualRouter; + Long physicalNetworkId = _networkMgr.getPhysicalNetworkId(network); + PhysicalNetworkServiceProvider provider = _physicalProviderDao.findByServiceProvider(physicalNetworkId, type.toString()); + if (provider == null) { + throw new CloudRuntimeException("Cannot find service provider " + type.toString() + " in physical network " + physicalNetworkId); + } + VirtualRouterProvider vrProvider = _vrProviderDao.findByNspIdAndType(provider.getId(), type); + if (vrProvider == null) { + throw new CloudRuntimeException("Cannot find virtual router provider " + type.toString()+ " as service provider " + provider.getId()); + } + + if (_networkMgr.isNetworkSystem(guestNetwork) || guestNetwork.getGuestType() == Network.GuestType.Shared) { + owner = _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM); + } - long dcId = dest.getDataCenter().getId(); - DataCenterDeployment plan = new DataCenterDeployment(dcId); - boolean isPodBased = (dest.getDataCenter().getNetworkType() == NetworkType.Basic || _networkMgr.areServicesSupportedInNetwork(guestNetwork.getId(), Service.SecurityGroup)) && guestNetwork.getTrafficType() == TrafficType.Guest; + //Check if public network has to be sest on VR boolean publicNetwork = false; if (_networkMgr.isProviderSupportServiceInNetwork(guestNetwork.getId(), Service.SourceNat, Provider.VirtualRouter)) { publicNetwork = true; @@ -1170,211 +1209,50 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian s_logger.error("Didn't support redundant virtual router without public network!"); return null; } - List routers; - Long podId = null; - if (isPodBased) { - Pod pod = dest.getPod(); - if (pod != null) { - podId = pod.getId(); + + + //1) Get deployment plan and find out the list of routers + boolean isPodBased = (dest.getDataCenter().getNetworkType() == NetworkType.Basic || + _networkMgr.areServicesSupportedInNetwork(guestNetwork.getId(), Service.SecurityGroup)) + && guestNetwork.getTrafficType() == TrafficType.Guest; + Pair> planAndRouters = getDeploymentPlanAndRouters(isPodBased, dest, guestNetwork.getId()); + DeploymentPlan plan = planAndRouters.first(); + List routers = planAndRouters.second(); + + //2) Figure out required routers count + int routerCount = 1; + if (isRedundant) { + routerCount = 2; + } + + /* If it is the single router network, then keep it untouched */ + for (DomainRouterVO router : routers) { + if (!router.getIsRedundantRouter()) { + routerCount = 1; } } + + /* If old network is redundant but new is single router, then routers.size() = 2 but routerCount = 1 */ + if (routers.size() >= routerCount || (isPodBased)) { + return routers; + } + + if (routers.size() >= 5) { + s_logger.error("Too much redundant routers!"); + } - if (publicNetwork) { - routers = _routerDao.listByNetworkAndRole(guestNetwork.getId(), Role.VIRTUAL_ROUTER); - } else { - if (isPodBased && podId != null) { - routers = _routerDao.listByNetworkAndPodAndRole(guestNetwork.getId(), podId, Role.VIRTUAL_ROUTER); - plan = new DataCenterDeployment(dcId, podId, null, null, null, null); - } else { - routers = _routerDao.listByNetworkAndRole(guestNetwork.getId(), Role.VIRTUAL_ROUTER); - plan = new DataCenterDeployment(dcId); - } + Long offeringId = _networkOfferingDao.findById(guestNetwork.getNetworkOfferingId()).getServiceOfferingId(); + if (offeringId == null) { + offeringId = _offering.getId(); } - + + //3) Deploy Virtual Router(s) try { - int routerCount = 1; - if (isRedundant) { - routerCount = 2; - } - - /* If it is the single router network, then keep it untouched */ - for (DomainRouterVO router : routers) { - if (!router.getIsRedundantRouter()) { - routerCount = 1; - } - } - - /* If old network is redundant but new is single router, then routers.size() = 2 but routerCount = 1 */ - if (routers.size() >= routerCount || (isPodBased && podId == null)) { - return routers; - } - - if (routers.size() >= 5) { - s_logger.error("Too much redundant routers!"); - } - - NicProfile defaultNic = new NicProfile(); - //if source nat service is supported by the network, get the source nat ip address - if (publicNetwork) { - PublicIp sourceNatIp = _networkMgr.assignSourceNatIpAddress(owner, guestNetwork, _accountMgr.getSystemUser().getId()); - defaultNic.setDefaultNic(true); - defaultNic.setIp4Address(sourceNatIp.getAddress().addr()); - defaultNic.setGateway(sourceNatIp.getGateway()); - defaultNic.setNetmask(sourceNatIp.getNetmask()); - defaultNic.setMacAddress(sourceNatIp.getMacAddress()); - defaultNic.setBroadcastType(BroadcastDomainType.Vlan); - defaultNic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(sourceNatIp.getVlanTag())); - defaultNic.setIsolationUri(IsolationType.Vlan.toUri(sourceNatIp.getVlanTag())); - defaultNic.setDeviceId(2); - } - int count = routerCount - routers.size(); - for (int i = 0; i < count; i++) { - long id = _routerDao.getNextInSequence(Long.class, "id"); - if (s_logger.isDebugEnabled()) { - s_logger.debug("Creating the router " + id); - } - - DomainRouterVO router = null; - - List offerings = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemControlNetwork); - NetworkOfferingVO controlOffering = offerings.get(0); - NetworkVO controlConfig = _networkMgr.setupNetwork(_systemAcct, controlOffering, plan, null, null, false).get(0); - - List> networks = new ArrayList>(3); - if (publicNetwork) { - NetworkOfferingVO publicOffering = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemPublicNetwork).get(0); - List publicNetworks = _networkMgr.setupNetwork(_systemAcct, publicOffering, plan, null, null, false); - networks.add(new Pair(publicNetworks.get(0), defaultNic)); - } - - String defaultNetworkStartIp = null; - if (guestNetwork.getCidr() != null && !publicNetwork) { - String startIp = _networkMgr.getStartIpAddress(guestNetwork.getId()); - if (startIp != null && _ipAddressDao.findByIpAndSourceNetworkId(guestNetwork.getId(), startIp).getAllocatedTime() == null) { - defaultNetworkStartIp = startIp; - } else if (s_logger.isDebugEnabled()){ - s_logger.debug("First ip " + startIp + " in network id=" + guestNetwork.getId() + " is already allocated, can't use it for domain router; will get random ip address from the range"); - } - } - - NicProfile gatewayNic = new NicProfile(defaultNetworkStartIp); - if (publicNetwork) { - if (isRedundant) { - gatewayNic.setIp4Address(_networkMgr.acquireGuestIpAddress(guestNetwork, null)); - } else { - gatewayNic.setIp4Address(guestNetwork.getGateway()); - } - gatewayNic.setBroadcastUri(guestNetwork.getBroadcastUri()); - gatewayNic.setBroadcastType(guestNetwork.getBroadcastDomainType()); - gatewayNic.setIsolationUri(guestNetwork.getBroadcastUri()); - gatewayNic.setMode(guestNetwork.getMode()); - String gatewayCidr = guestNetwork.getCidr(); - gatewayNic.setNetmask(NetUtils.getCidrNetmask(gatewayCidr)); - } else { - gatewayNic.setDefaultNic(true); - } - - networks.add(new Pair((NetworkVO) guestNetwork, gatewayNic)); - networks.add(new Pair(controlConfig, null)); - - Long offering_id = _networkOfferingDao.findById(guestNetwork.getNetworkOfferingId()).getServiceOfferingId(); - if (offering_id == null) { - offering_id = _offering.getId(); - } - VirtualRouterProviderType type = VirtualRouterProviderType.VirtualRouter; - Long physicalNetworkId = _networkMgr.getPhysicalNetworkId(network); - PhysicalNetworkServiceProvider provider = _physicalProviderDao.findByServiceProvider(physicalNetworkId, type.toString()); - if (provider == null) { - throw new CloudRuntimeException("Cannot find service provider " + type.toString() + " in physical network " + physicalNetworkId); - } - VirtualRouterProvider vrProvider = _vrProviderDao.findByNspIdAndType(provider.getId(), type); - if (vrProvider == null) { - throw new CloudRuntimeException("Cannot find virtual router provider " + type.toString()+ " as service provider " + provider.getId()); - } - ServiceOfferingVO routerOffering = _serviceOfferingDao.findById(offering_id); - - //Router is the network element, we don't know the hypervisor type yet. - //Try to allocate the domR twice using diff hypervisors, and when failed both times, throw the exception up - List supportedHypervisors = new ArrayList(); - HypervisorType defaults = _resourceMgr.getDefaultHypervisor(dest.getDataCenter().getId()); - if (defaults != HypervisorType.None) { - supportedHypervisors.add(defaults); - } - - if (dest.getCluster() != null) { - if (dest.getCluster().getHypervisorType() == HypervisorType.Ovm) { - supportedHypervisors.add(getClusterToStartDomainRouterForOvm(dest.getCluster().getPodId())); - } else { - supportedHypervisors.add(dest.getCluster().getHypervisorType()); - } - } else { - supportedHypervisors = _resourceMgr.getSupportedHypervisorTypes(dest.getDataCenter().getId(), true, podId); - } - - if (supportedHypervisors.isEmpty()) { - if (podId != null) { - throw new InsufficientServerCapacityException("Unable to create virtual router, there are no clusters in the pod ", Pod.class, podId); - } - throw new InsufficientServerCapacityException("Unable to create virtual router, there are no clusters in the zone ", DataCenter.class, dest.getDataCenter().getId()); - } - - int allocateRetry = 0; - int startRetry = 0; - - - for (Iterator iter = supportedHypervisors.iterator();iter.hasNext();) { - HypervisorType hType = iter.next(); - try { - s_logger.debug("Allocating the domR with the hypervisor type " + hType); - VMTemplateVO template = _templateDao.findRoutingTemplate(hType); - - if (template == null) { - s_logger.debug(hType + " won't support system vm, skip it"); - continue; - } - - boolean offerHA = routerOffering.getOfferHA(); - /* We don't provide HA to redundant router VMs, admin should own it all, and redundant router themselves are HA */ - if (isRedundant) { - offerHA = false; - } - - router = new DomainRouterVO(id, routerOffering.getId(), vrProvider.getId(), VirtualMachineName.getRouterName(id, _instance), template.getId(), template.getHypervisorType(), - 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) { - if (allocateRetry < 2 && iter.hasNext()) { - s_logger.debug("Failed to allocate the domR with hypervisor type " + hType + ", retrying one more time"); - continue; - } else { - throw ex; - } - } finally { - allocateRetry++; - } - - try { - router = startVirtualRouter(router, _accountMgr.getSystemUser(), _accountMgr.getSystemAccount(), params); - break; - } catch (InsufficientCapacityException ex) { - if (startRetry < 2 && iter.hasNext()) { - s_logger.debug("Failed to start the domR " + router + " with hypervisor type " + hType + ", destroying it and recreating one more time"); - //destroy the router - destroyRouter(router.getId()); - continue; - } else { - throw ex; - } - } finally { - startRetry++; - } - } - + DomainRouterVO router = deployRouter(owner, dest, plan, params, publicNetwork, guestNetwork, isRedundant, + vrProvider, offeringId); routers.add(router); - } } finally { if (network != null) { @@ -1384,7 +1262,202 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian return routers; } - private DomainRouterVO startVirtualRouter(DomainRouterVO router, User user, Account caller, Map params) throws StorageUnavailableException, InsufficientCapacityException, + protected DomainRouterVO deployRouter(Account owner, DeployDestination dest, DeploymentPlan plan, Map params, + boolean setupPublicNetwork, Network guestNetwork, boolean isRedundant, + VirtualRouterProvider vrProvider, long svcOffId) throws ConcurrentOperationException, + InsufficientAddressCapacityException, InsufficientServerCapacityException, InsufficientCapacityException, + StorageUnavailableException, ResourceUnavailableException { + + long id = _routerDao.getNextInSequence(Long.class, "id"); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Creating the router " + id + " in datacenter " + dest.getDataCenter()); + } + + //1) Create router networks + List> networks = createRouterNetworks(owner, setupPublicNetwork, guestNetwork, + isRedundant, plan); + + + ServiceOfferingVO routerOffering = _serviceOfferingDao.findById(svcOffId); + + //2) Router is the network element, we don't know the hypervisor type yet. + //Try to allocate the domR twice using diff hypervisors, and when failed both times, throw the exception up + List supportedHypervisors = new ArrayList(); + HypervisorType defaults = _resourceMgr.getDefaultHypervisor(dest.getDataCenter().getId()); + if (defaults != HypervisorType.None) { + supportedHypervisors.add(defaults); + } + + if (dest.getCluster() != null) { + if (dest.getCluster().getHypervisorType() == HypervisorType.Ovm) { + supportedHypervisors.add(getClusterToStartDomainRouterForOvm(dest.getCluster().getPodId())); + } else { + supportedHypervisors.add(dest.getCluster().getHypervisorType()); + } + } else { + supportedHypervisors = _resourceMgr.getSupportedHypervisorTypes(dest.getDataCenter().getId(), true, + plan.getPodId()); + } + + if (supportedHypervisors.isEmpty()) { + if (plan.getPodId() != null) { + throw new InsufficientServerCapacityException("Unable to create virtual router, " + + "there are no clusters in the pod ", Pod.class, plan.getPodId()); + } + throw new InsufficientServerCapacityException("Unable to create virtual router, " + + "there are no clusters in the zone ", DataCenter.class, dest.getDataCenter().getId()); + } + + int allocateRetry = 0; + int startRetry = 0; + DomainRouterVO router = null; + for (Iterator iter = supportedHypervisors.iterator();iter.hasNext();) { + HypervisorType hType = iter.next(); + try { + s_logger.debug("Allocating the domR with the hypervisor type " + hType); + VMTemplateVO template = _templateDao.findRoutingTemplate(hType); + + if (template == null) { + s_logger.debug(hType + " won't support system vm, skip it"); + continue; + } + + boolean offerHA = routerOffering.getOfferHA(); + /* We don't provide HA to redundant router VMs, admin should own it all, and redundant router themselves are HA */ + if (isRedundant) { + offerHA = false; + } + + router = new DomainRouterVO(id, routerOffering.getId(), vrProvider.getId(), + VirtualMachineName.getRouterName(id, _instance), template.getId(), template.getHypervisorType(), + 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) { + if (allocateRetry < 2 && iter.hasNext()) { + s_logger.debug("Failed to allocate the domR with hypervisor type " + hType + ", retrying one more time"); + continue; + } else { + throw ex; + } + } finally { + allocateRetry++; + } + + try { + router = startVirtualRouter(router, _accountMgr.getSystemUser(), _accountMgr.getSystemAccount(), params); + break; + } catch (InsufficientCapacityException ex) { + if (startRetry < 2 && iter.hasNext()) { + s_logger.debug("Failed to start the domR " + router + " with hypervisor type " + hType + ", destroying it and recreating one more time"); + //destroy the router + destroyRouter(router.getId()); + continue; + } else { + throw ex; + } + } finally { + startRetry++; + } + } + return router; + } + + protected List> createRouterNetworks(Account owner, boolean setupPublicNetwork, + Network guestNetwork, boolean isRedundant, DeploymentPlan plan) throws ConcurrentOperationException, + InsufficientAddressCapacityException { + //Form networks + //1) Public network + List> networks = new ArrayList>(3); + if (setupPublicNetwork) { + s_logger.debug("Adding nic for Virtual Router in Public network "); + //if source nat service is supported by the network, get the source nat ip address + PublicIp sourceNatIp = _networkMgr.assignSourceNatIpAddress(owner, guestNetwork, _accountMgr.getSystemUser().getId()); + NicProfile defaultNic = new NicProfile(); + defaultNic.setDefaultNic(true); + defaultNic.setIp4Address(sourceNatIp.getAddress().addr()); + defaultNic.setGateway(sourceNatIp.getGateway()); + defaultNic.setNetmask(sourceNatIp.getNetmask()); + defaultNic.setMacAddress(sourceNatIp.getMacAddress()); + defaultNic.setBroadcastType(BroadcastDomainType.Vlan); + defaultNic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(sourceNatIp.getVlanTag())); + defaultNic.setIsolationUri(IsolationType.Vlan.toUri(sourceNatIp.getVlanTag())); + defaultNic.setDeviceId(2); + NetworkOfferingVO publicOffering = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemPublicNetwork).get(0); + List publicNetworks = _networkMgr.setupNetwork(_systemAcct, publicOffering, plan, null, null, false); + networks.add(new Pair(publicNetworks.get(0), defaultNic)); + } + + //2) Control network + List offerings = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemControlNetwork); + NetworkOfferingVO controlOffering = offerings.get(0); + NetworkVO controlConfig = _networkMgr.setupNetwork(_systemAcct, controlOffering, plan, null, null, false).get(0); + s_logger.debug("Adding nic for Virtual Router in Control network "); + networks.add(new Pair(controlConfig, null)); + + //3) Guest network + if (guestNetwork != null) { + String defaultNetworkStartIp = null; + s_logger.debug("Adding nic for Virtual Router in Guest network " + guestNetwork); + if (guestNetwork.getCidr() != null && !setupPublicNetwork) { + String startIp = _networkMgr.getStartIpAddress(guestNetwork.getId()); + if (startIp != null && _ipAddressDao.findByIpAndSourceNetworkId(guestNetwork.getId(), startIp).getAllocatedTime() == null) { + defaultNetworkStartIp = startIp; + } else if (s_logger.isDebugEnabled()){ + s_logger.debug("First ip " + startIp + " in network id=" + guestNetwork.getId() + + " is already allocated, can't use it for domain router; will get random ip address from the range"); + } + } + + NicProfile gatewayNic = new NicProfile(defaultNetworkStartIp); + if (setupPublicNetwork) { + if (isRedundant) { + gatewayNic.setIp4Address(_networkMgr.acquireGuestIpAddress(guestNetwork, null)); + } else { + gatewayNic.setIp4Address(guestNetwork.getGateway()); + } + gatewayNic.setBroadcastUri(guestNetwork.getBroadcastUri()); + gatewayNic.setBroadcastType(guestNetwork.getBroadcastDomainType()); + gatewayNic.setIsolationUri(guestNetwork.getBroadcastUri()); + gatewayNic.setMode(guestNetwork.getMode()); + String gatewayCidr = guestNetwork.getCidr(); + gatewayNic.setNetmask(NetUtils.getCidrNetmask(gatewayCidr)); + } else { + gatewayNic.setDefaultNic(true); + } + networks.add(new Pair((NetworkVO) guestNetwork, gatewayNic)); + } + + return networks; + } + + + protected Pair> getDeploymentPlanAndRouters(boolean isPodBased, + DeployDestination dest, long guestNetworkId) { + long dcId = dest.getDataCenter().getId(); + List routers = null; + DeploymentPlan plan = new DataCenterDeployment(dcId); + if (isPodBased) { + Pod pod = dest.getPod(); + Long podId = null; + if (pod != null) { + podId = pod.getId(); + } else { + throw new CloudRuntimeException("Pod id is expected in deployment destination"); + } + routers = _routerDao.listByNetworkAndPodAndRole(guestNetworkId, podId, Role.VIRTUAL_ROUTER); + plan = new DataCenterDeployment(dcId, podId, null, null, null, null); + } else { + routers = _routerDao.listByNetworkAndRole(guestNetworkId, Role.VIRTUAL_ROUTER); + } + + return new Pair>(plan, routers); + } + + + private DomainRouterVO startVirtualRouter(DomainRouterVO router, User user, Account caller, Map params) + throws StorageUnavailableException, InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { if (router.getRole() != Role.VIRTUAL_ROUTER || !router.getIsRedundantRouter()) { @@ -1451,25 +1524,17 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } @Override - public List deployVirtualRouter(Network guestNetwork, DeployDestination dest, Account owner, + public List deployVirtualRouterInGuestNetwork(Network guestNetwork, DeployDestination dest, Account owner, Map params, boolean isRedundant) throws InsufficientCapacityException, - ConcurrentOperationException, ResourceUnavailableException { - if (_networkMgr.isNetworkSystem(guestNetwork) || guestNetwork.getGuestType() == Network.GuestType.Shared) { - owner = _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM); - } + ConcurrentOperationException, ResourceUnavailableException { - if(dest != null){ - if (s_logger.isDebugEnabled()) { - s_logger.debug("Starting a router for " + guestNetwork + " in datacenter:" + dest.getDataCenter()); - } - } + List routers = findOrDeployVirtualRouterInGuestNetwork(guestNetwork, dest, owner, isRedundant, params); - assert guestNetwork.getState() == Network.State.Implemented || guestNetwork.getState() == Network.State.Setup || - guestNetwork.getState() == Network.State.Implementing : "Network is not yet fully implemented: " - + guestNetwork; - assert guestNetwork.getTrafficType() == TrafficType.Guest; + return startRouters(params, routers); + } - List routers = findOrDeployVirtualRouters(guestNetwork, dest, owner, isRedundant, params); + protected List startRouters(Map params, List routers) throws StorageUnavailableException, InsufficientCapacityException, ConcurrentOperationException, + ResourceUnavailableException { List runningRouters = null; if (routers != null) { @@ -1976,16 +2041,19 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian @Override - public boolean startRemoteAccessVpn(Network network, RemoteAccessVpn vpn, List routers) throws ResourceUnavailableException { + public boolean startRemoteAccessVpn(Network network, RemoteAccessVpn vpn, List routers) + throws ResourceUnavailableException { if (routers == null || routers.isEmpty()) { s_logger.warn("Failed to start remote access VPN: no router found for account and zone"); - throw new ResourceUnavailableException("Failed to start remote access VPN: no router found for account and zone", DataCenter.class, network.getDataCenterId()); + throw new ResourceUnavailableException("Failed to start remote access VPN: no router found for account and zone", + DataCenter.class, network.getDataCenterId()); } for (VirtualRouter router : routers) { if (router.getState() != State.Running) { s_logger.warn("Failed to start remote access VPN: router not in right state " + router.getState()); - throw new ResourceUnavailableException("Failed to start remote access VPN: router not in right state " + router.getState(), DataCenter.class, network.getDataCenterId()); + throw new ResourceUnavailableException("Failed to start remote access VPN: router not in right state " + + router.getState(), DataCenter.class, network.getDataCenterId()); } Commands cmds = new Commands(OnError.Stop); @@ -1999,16 +2067,20 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } Answer answer = cmds.getAnswer("users"); if (!answer.getResult()) { - s_logger.error("Unable to start vpn: unable add users to vpn in zone " + router.getDataCenterIdToDeployIn() + " for account " + vpn.getAccountId() + " on domR: " + router.getInstanceName() + s_logger.error("Unable to start vpn: unable add users to vpn in zone " + router.getDataCenterIdToDeployIn() + + " for account " + vpn.getAccountId() + " on domR: " + router.getInstanceName() + " due to " + answer.getDetails()); - throw new ResourceUnavailableException("Unable to start vpn: Unable to add users to vpn in zone " + router.getDataCenterIdToDeployIn() + " for account " + vpn.getAccountId() + " on domR: " + throw new ResourceUnavailableException("Unable to start vpn: Unable to add users to vpn in zone " + + router.getDataCenterIdToDeployIn() + " for account " + vpn.getAccountId() + " on domR: " + router.getInstanceName() + " due to " + answer.getDetails(), DataCenter.class, router.getDataCenterIdToDeployIn()); } answer = cmds.getAnswer("startVpn"); if (!answer.getResult()) { - s_logger.error("Unable to start vpn in zone " + router.getDataCenterIdToDeployIn() + " for account " + vpn.getAccountId() + " on domR: " + router.getInstanceName() + " due to " + s_logger.error("Unable to start vpn in zone " + router.getDataCenterIdToDeployIn() + " for account " + + vpn.getAccountId() + " on domR: " + router.getInstanceName() + " due to " + answer.getDetails()); - throw new ResourceUnavailableException("Unable to start vpn in zone " + router.getDataCenterIdToDeployIn() + " for account " + vpn.getAccountId() + " on domR: " + router.getInstanceName() + throw new ResourceUnavailableException("Unable to start vpn in zone " + router.getDataCenterIdToDeployIn() + + " for account " + vpn.getAccountId() + " on domR: " + router.getInstanceName() + " due to " + answer.getDetails(), DataCenter.class, router.getDataCenterIdToDeployIn()); } @@ -2018,7 +2090,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian @Override - public boolean deleteRemoteAccessVpn(Network network, RemoteAccessVpn vpn, List routers) throws ResourceUnavailableException { + public boolean deleteRemoteAccessVpn(Network network, RemoteAccessVpn vpn, List routers) + throws ResourceUnavailableException { if (routers == null || routers.isEmpty()) { s_logger.warn("Failed to delete remote access VPN: no router found for account and zone"); throw new ResourceUnavailableException("Failed to delete remote access VPN", DataCenter.class, network.getDataCenterId()); @@ -2030,7 +2103,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian Commands cmds = new Commands(OnError.Continue); IpAddress ip = _networkMgr.getIp(vpn.getServerAddressId()); - RemoteAccessVpnCfgCommand removeVpnCmd = new RemoteAccessVpnCfgCommand(false, ip.getAddress().addr(), vpn.getLocalIp(), vpn.getIpRange(), vpn.getIpsecPresharedKey()); + RemoteAccessVpnCfgCommand removeVpnCmd = new RemoteAccessVpnCfgCommand(false, ip.getAddress().addr(), + vpn.getLocalIp(), vpn.getIpRange(), vpn.getIpsecPresharedKey()); removeVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); removeVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, router.getGuestIpAddress()); removeVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); @@ -2046,7 +2120,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian continue; } else { s_logger.warn("Failed to delete remote access VPN: domR " + router + " is not in right state " + router.getState()); - throw new ResourceUnavailableException("Failed to delete remote access VPN: domR is not in right state " + router.getState(), DataCenter.class, network.getDataCenterId()); + throw new ResourceUnavailableException("Failed to delete remote access VPN: domR is not in right state " + + router.getState(), DataCenter.class, network.getDataCenterId()); } } @@ -2054,7 +2129,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } - private DomainRouterVO start(DomainRouterVO router, User user, Account caller, Map params, DeploymentPlan planToDeploy) throws StorageUnavailableException, InsufficientCapacityException, + private DomainRouterVO start(DomainRouterVO router, User user, Account caller, Map params, DeploymentPlan planToDeploy) + throws StorageUnavailableException, InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { s_logger.debug("Starting router " + router); if (_itMgr.start(router, params, user, caller, planToDeploy) != null) { @@ -2089,7 +2165,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian boolean podLevelException = false; //for user vm in Basic zone we should try to re-deploy vm in a diff pod if it fails to deploy in original pod; so throwing exception with Pod scope - if (isZoneBasic && podId != null && updatedProfile.getVirtualMachine().getType() == VirtualMachine.Type.User && network.getTrafficType() == TrafficType.Guest && network.getGuestType() == Network.GuestType.Shared) { + if (isZoneBasic && podId != null && updatedProfile.getVirtualMachine().getType() == VirtualMachine.Type.User + && network.getTrafficType() == TrafficType.Guest && network.getGuestType() == Network.GuestType.Shared) { podLevelException = true; } @@ -2142,7 +2219,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian boolean podLevelException = false; //for user vm in Basic zone we should try to re-deploy vm in a diff pod if it fails to deploy in original pod; so throwing exception with Pod scope - if (isZoneBasic && podId != null && updatedProfile.getVirtualMachine().getType() == VirtualMachine.Type.User && network.getTrafficType() == TrafficType.Guest && network.getGuestType() == Network.GuestType.Shared) { + if (isZoneBasic && podId != null && updatedProfile.getVirtualMachine().getType() == VirtualMachine.Type.User + && network.getTrafficType() == TrafficType.Guest && network.getGuestType() == Network.GuestType.Shared) { podLevelException = true; } @@ -2173,7 +2251,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian public String[] applyVpnUsers(Network network, List users, List routers) throws ResourceUnavailableException { if (routers == null || routers.isEmpty()) { s_logger.warn("Failed to add/remove VPN users: no router found for account and zone"); - throw new ResourceUnavailableException("Unable to assign ip addresses, domR doesn't exist for network " + network.getId(), DataCenter.class, network.getDataCenterId()); + throw new ResourceUnavailableException("Unable to assign ip addresses, domR doesn't exist for network " + + network.getId(), DataCenter.class, network.getDataCenterId()); } boolean agentResults = true; @@ -2181,7 +2260,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian for (DomainRouterVO router : routers) { if (router.getState() != State.Running) { s_logger.warn("Failed to add/remove VPN users: router not in running state"); - throw new ResourceUnavailableException("Unable to assign ip addresses, domR is not in right state " + router.getState(), DataCenter.class, network.getDataCenterId()); + throw new ResourceUnavailableException("Unable to assign ip addresses, domR is not in right state " + + router.getState(), DataCenter.class, network.getDataCenterId()); } Commands cmds = new Commands(OnError.Continue); @@ -2245,7 +2325,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } @Override - public VirtualRouter startRouter(long routerId, boolean reprogramNetwork) throws ResourceUnavailableException, InsufficientCapacityException, ConcurrentOperationException { + public VirtualRouter startRouter(long routerId, boolean reprogramNetwork) throws ResourceUnavailableException, + InsufficientCapacityException, ConcurrentOperationException { Account caller = UserContext.current().getCaller(); User callerUser = _accountMgr.getActiveUser(UserContext.current().getCallerUserId()); @@ -2344,7 +2425,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian String vmGuestAddress = null; - IpAddressTO ip = new IpAddressTO(ipAddr.getAccountId(), ipAddr.getAddress().addr(), add, firstIP, sourceNat, vlanId, vlanGateway, vlanNetmask, vifMacAddress, vmGuestAddress, networkRate, ipAddr.isOneToOneNat()); + IpAddressTO ip = new IpAddressTO(ipAddr.getAccountId(), ipAddr.getAddress().addr(), add, firstIP, + sourceNat, vlanId, vlanGateway, vlanNetmask, vifMacAddress, vmGuestAddress, networkRate, ipAddr.isOneToOneNat()); ip.setTrafficType(network.getTrafficType()); ip.setNetworkName(_networkMgr.getNetworkTag(router.getHypervisorType(), network)); @@ -2465,7 +2547,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian IpAddress ip = _networkMgr.getIp(vpn.getServerAddressId()); - RemoteAccessVpnCfgCommand startVpnCmd = new RemoteAccessVpnCfgCommand(true, ip.getAddress().addr(), vpn.getLocalIp(), vpn.getIpRange(), vpn.getIpsecPresharedKey()); + RemoteAccessVpnCfgCommand startVpnCmd = new RemoteAccessVpnCfgCommand(true, ip.getAddress().addr(), + vpn.getLocalIp(), vpn.getIpRange(), vpn.getIpsecPresharedKey()); startVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId())); startVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, router.getGuestIpAddress()); startVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); @@ -2550,7 +2633,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian DataCenterVO dc = _dcDao.findById(router.getDataCenterIdToDeployIn()); for (UserVmVO vm : vms) { boolean createDhcp = true; - if (dc.getNetworkType() == NetworkType.Basic && router.getPodIdToDeployIn().longValue() != vm.getPodIdToDeployIn().longValue() && _dnsBasicZoneUpdates.equalsIgnoreCase("pod")) { + if (dc.getNetworkType() == NetworkType.Basic && router.getPodIdToDeployIn().longValue() != vm.getPodIdToDeployIn().longValue() + && _dnsBasicZoneUpdates.equalsIgnoreCase("pod")) { createDhcp = false; } if (createDhcp) { @@ -2603,10 +2687,12 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian return; } if (!connectedRouters.get(0).getIsRedundantRouter()) { - throw new ResourceUnavailableException("Who is calling this with non-redundant router or non-domain router?", DataCenter.class, connectedRouters.get(0).getDataCenterIdToDeployIn()); + throw new ResourceUnavailableException("Who is calling this with non-redundant router or non-domain router?", + DataCenter.class, connectedRouters.get(0).getDataCenterIdToDeployIn()); } if (!disconnectedRouters.get(0).getIsRedundantRouter()) { - throw new ResourceUnavailableException("Who is calling this with non-redundant router or non-domain router?", DataCenter.class, disconnectedRouters.get(0).getDataCenterIdToDeployIn()); + throw new ResourceUnavailableException("Who is calling this with non-redundant router or non-domain router?", + DataCenter.class, disconnectedRouters.get(0).getDataCenterIdToDeployIn()); } DomainRouterVO connectedRouter = (DomainRouterVO)connectedRouters.get(0); @@ -2756,7 +2842,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian boolean execute(Network network, VirtualRouter router) throws ResourceUnavailableException; } - private boolean applyRules(Network network, List routers, String typeString, boolean isPodLevelException, Long podId, boolean failWhenDisconnect, RuleApplier applier) throws ResourceUnavailableException { + private boolean applyRules(Network network, List routers, String typeString, + boolean isPodLevelException, Long podId, boolean failWhenDisconnect, RuleApplier applier) throws ResourceUnavailableException { if (routers == null || routers.isEmpty()) { s_logger.warn("Unable to apply " + typeString + ", virtual router doesn't exist in the network " + network.getId()); throw new ResourceUnavailableException("Unable to apply " + typeString , DataCenter.class, network.getDataCenterId()); @@ -2778,10 +2865,12 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian if (router.isStopPending()) { if (_hostDao.findById(router.getHostId()).getStatus() == Status.Up) { - throw new ResourceUnavailableException("Unable to process due to the stop pending router " + router.getInstanceName() + " haven't been stopped after it's host coming back!", + throw new ResourceUnavailableException("Unable to process due to the stop pending router " + + router.getInstanceName() + " haven't been stopped after it's host coming back!", DataCenter.class, router.getDataCenterIdToDeployIn()); } - s_logger.debug("Router " + router.getInstanceName() + " is stop pending, so not sending apply " + typeString + " commands to the backend"); + s_logger.debug("Router " + router.getInstanceName() + " is stop pending, so not sending apply " + + typeString + " commands to the backend"); continue; } try { @@ -2797,17 +2886,21 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian if (isZoneBasic && isPodLevelException) { throw new ResourceUnavailableException("Unable to apply " + typeString + " on router ", Pod.class, podId); } - throw new ResourceUnavailableException("Unable to apply " + typeString + " on router ", DataCenter.class, router.getDataCenterIdToDeployIn()); + throw new ResourceUnavailableException("Unable to apply " + typeString + " on router ", DataCenter.class, + router.getDataCenterIdToDeployIn()); } } else if (router.getState() == State.Stopped || router.getState() == State.Stopping) { - s_logger.debug("Router " + router.getInstanceName() + " is in " + router.getState() + ", so not sending apply " + typeString + " commands to the backend"); + s_logger.debug("Router " + router.getInstanceName() + " is in " + router.getState() + + ", so not sending apply " + typeString + " commands to the backend"); } else { s_logger.warn("Unable to apply " + typeString +", virtual router is not in the right state " + router.getState()); if (isZoneBasic && isPodLevelException) { - throw new ResourceUnavailableException("Unable to apply " + typeString + ", virtual router is not in the right state", Pod.class, podId); + throw new ResourceUnavailableException("Unable to apply " + typeString + + ", virtual router is not in the right state", Pod.class, podId); } - throw new ResourceUnavailableException("Unable to apply " + typeString + ", virtual router is not in the right state", DataCenter.class, router.getDataCenterIdToDeployIn()); + throw new ResourceUnavailableException("Unable to apply " + typeString + + ", virtual router is not in the right state", DataCenter.class, router.getDataCenterIdToDeployIn()); } } @@ -2862,7 +2955,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian rulesTO = new ArrayList(); for (StaticNat rule : rules) { IpAddress sourceIp = _networkMgr.getIp(rule.getSourceIpAddressId()); - StaticNatRuleTO ruleTO = new StaticNatRuleTO(0, sourceIp.getAddress().addr(), null, null, rule.getDestIpAddress(), null, null, null, rule.isForRevoke(), false); + StaticNatRuleTO ruleTO = new StaticNatRuleTO(0, sourceIp.getAddress().addr(), null, + null, rule.getDestIpAddress(), null, null, null, rule.isForRevoke(), false); rulesTO.add(ruleTO); } } diff --git a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManager.java b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManager.java new file mode 100644 index 00000000000..13df4f3f6ff --- /dev/null +++ b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManager.java @@ -0,0 +1,45 @@ +// 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.router; + +import java.util.List; +import java.util.Map; + +import com.cloud.deploy.DeployDestination; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.vpc.Vpc; +import com.cloud.user.Account; +import com.cloud.vm.DomainRouterVO; +import com.cloud.vm.VirtualMachineProfile.Param; + +/** + * @author Alena Prokharchyk + */ +public interface VpcVirtualNetworkApplianceManager extends VirtualNetworkApplianceManager{ + + /** + * @param vpc + * @param dest + * @param owner + * @param params + * @return + * @throws InsufficientCapacityException + * @throws ConcurrentOperationException + * @throws ResourceUnavailableException + */ + List deployVirtualRouterInVpc(Vpc vpc, DeployDestination dest, Account owner, Map params) throws InsufficientCapacityException, ConcurrentOperationException, + ResourceUnavailableException; + +} diff --git a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java new file mode 100644 index 00000000000..e2287a58f35 --- /dev/null +++ b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java @@ -0,0 +1,112 @@ +// 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.router; + +import java.util.List; +import java.util.Map; + +import javax.ejb.Local; + +import org.apache.log4j.Logger; + +import com.cloud.deploy.DataCenterDeployment; +import com.cloud.deploy.DeployDestination; +import com.cloud.deploy.DeploymentPlan; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.VirtualRouterProvider; +import com.cloud.network.VirtualRouterProvider.VirtualRouterProviderType; +import com.cloud.network.vpc.Vpc; +import com.cloud.network.vpc.Dao.VpcDao; +import com.cloud.network.vpc.Dao.VpcOfferingDao; +import com.cloud.user.Account; +import com.cloud.utils.Pair; +import com.cloud.utils.component.Inject; +import com.cloud.utils.db.DB; +import com.cloud.vm.DomainRouterVO; +import com.cloud.vm.VirtualMachineProfile.Param; + +/** + * @author Alena Prokharchyk + */ + +@Local(value = { VpcVirtualNetworkApplianceManager.class}) +public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplianceManagerImpl implements VpcVirtualNetworkApplianceManager{ + private static final Logger s_logger = Logger.getLogger(VpcVirtualNetworkApplianceManagerImpl.class); + + @Inject + VpcDao _vpcDao = null; + @Inject + VpcOfferingDao _vpcOffDao = null; + + @Override + public List deployVirtualRouterInVpc(Vpc vpc, DeployDestination dest, Account owner, + Map params) throws InsufficientCapacityException, + ConcurrentOperationException, ResourceUnavailableException { + + List routers = findOrDeployVirtualRouterInVpc(vpc, dest, owner, params); + + return startRouters(params, routers); + } + + @DB + protected List findOrDeployVirtualRouterInVpc(Vpc vpc, DeployDestination dest, Account owner, + Map params) throws ConcurrentOperationException, + InsufficientCapacityException, ResourceUnavailableException { + + Vpc vpcLock = _vpcDao.acquireInLockTable(vpc.getId()); + if (vpcLock == null) { + throw new ConcurrentOperationException("Unable to lock vpc " + vpc.getId()); + } + + //1) Get deployment plan and find out the list of routers + Pair> planAndRouters = getDeploymentPlanAndRouters(vpc.getId(), dest); + DeploymentPlan plan = planAndRouters.first(); + List routers = planAndRouters.second(); + + //2) Return routers if exist + if (routers.size() >= 1) { + return routers; + } + + Long offeringId = _vpcOffDao.findById(vpc.getVpcOfferingId()).getServiceOfferingId(); + if (offeringId == null) { + offeringId = _offering.getId(); + } + + //3) Deploy Virtual Router + try { + //FIXME - remove hardcoded provider type when decide if we want cross physical networks vpcs + VirtualRouterProvider vrProvider = _vrProviderDao.findByNspIdAndType(1, VirtualRouterProviderType.VirtualRouter); + DomainRouterVO router = deployRouter(owner, dest, plan, params, true, null, false, + vrProvider, offeringId); + routers.add(router); + + } finally { + if (vpcLock != null) { + _vpcDao.releaseFromLockTable(vpc.getId()); + } + } + return routers; + } + + protected Pair> getDeploymentPlanAndRouters(long vpcId,DeployDestination dest) { + long dcId = dest.getDataCenter().getId(); + + DeploymentPlan plan = new DataCenterDeployment(dcId); + List routers = _routerDao.listRoutersByVpcId(vpcId); + + return new Pair>(plan, routers); + } +} diff --git a/server/src/com/cloud/network/vpc/Dao/VpcOfferingDaoImpl.java b/server/src/com/cloud/network/vpc/Dao/VpcOfferingDaoImpl.java index 0a152344c69..b5e6c6ede8a 100644 --- a/server/src/com/cloud/network/vpc/Dao/VpcOfferingDaoImpl.java +++ b/server/src/com/cloud/network/vpc/Dao/VpcOfferingDaoImpl.java @@ -40,6 +40,7 @@ public class VpcOfferingDaoImpl extends GenericDaoBase impl AllFieldsSearch.and("name", AllFieldsSearch.entity().getName(), Op.EQ); AllFieldsSearch.and("uName", AllFieldsSearch.entity().getUniqueName(), Op.EQ); AllFieldsSearch.and("displayText", AllFieldsSearch.entity().getDisplayText(), Op.EQ); + AllFieldsSearch.and("svcOffId", AllFieldsSearch.entity().getServiceOfferingId(), Op.EQ); AllFieldsSearch.done(); } @@ -62,7 +63,6 @@ public class VpcOfferingDaoImpl extends GenericDaoBase impl public VpcOfferingVO findByUniqueName(String uniqueName) { SearchCriteria sc = AllFieldsSearch.create(); sc.setParameters("uName", uniqueName); - return findOneBy(sc); } } diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java index 108b4871531..7fb6bc646ce 100644 --- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java +++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java @@ -27,15 +27,22 @@ import org.apache.log4j.Logger; import com.cloud.configuration.ConfigurationManager; import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.dc.DataCenter; +import com.cloud.deploy.DeployDestination; import com.cloud.event.ActionEvent; import com.cloud.event.EventTypes; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.PermissionDeniedException; +import com.cloud.exception.ResourceUnavailableException; import com.cloud.exception.UnsupportedServiceException; import com.cloud.network.Network; import com.cloud.network.Network.Provider; import com.cloud.network.Network.Service; +import com.cloud.network.NetworkManager; import com.cloud.network.dao.NetworkDao; +import com.cloud.network.element.NetworkElement; +import com.cloud.network.element.VpcProvider; import com.cloud.network.vpc.VpcOffering.State; import com.cloud.network.vpc.Dao.VpcDao; import com.cloud.network.vpc.Dao.VpcOfferingDao; @@ -44,6 +51,7 @@ import com.cloud.org.Grouping; import com.cloud.projects.Project.ListProjectResourcesCriteria; import com.cloud.user.Account; import com.cloud.user.AccountManager; +import com.cloud.user.User; import com.cloud.user.UserContext; import com.cloud.utils.Ternary; import com.cloud.utils.component.Inject; @@ -53,7 +61,10 @@ import com.cloud.utils.db.Filter; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; +import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; +import com.cloud.vm.ReservationContext; +import com.cloud.vm.ReservationContextImpl; /** * @author Alena Prokharchyk @@ -76,6 +87,8 @@ public class VpcManagerImpl implements VpcManager, Manager{ AccountManager _accountMgr; @Inject NetworkDao _ntwkDao; + @Inject + NetworkManager _ntwkMgr; String _name; @@ -100,7 +113,7 @@ public class VpcManagerImpl implements VpcManager, Manager{ createVpcOffering(VpcOffering.defaultVPCOfferingName, VpcOffering.defaultVPCOfferingName, svcProviderMap, true, State.Enabled); } - + txn.commit(); return true; @@ -121,12 +134,6 @@ public class VpcManagerImpl implements VpcManager, Manager{ return _name; } - @Override - public Vpc createVpc(long zoneId, String name, String cidr, long ownerId) { - // TODO Auto-generated method stub - return null; - } - @Override public List getVpcNetworks(long vpcId) { // TODO Auto-generated method stub @@ -185,7 +192,7 @@ public class VpcManagerImpl implements VpcManager, Manager{ Transaction txn = Transaction.currentTxn(); txn.start(); // create vpc offering object - VpcOfferingVO offering = new VpcOfferingVO(name, displayText, isDefault); + VpcOfferingVO offering = new VpcOfferingVO(name, displayText, isDefault, null); if (state != null) { offering.setState(state); @@ -399,7 +406,7 @@ public class VpcManagerImpl implements VpcManager, Manager{ Account owner = _accountMgr.getAccount(vpcOwnerId); //Verify that caller can perform actions in behalf of vpc owner - _accountMgr.checkAccess(caller, null, true, owner); + _accountMgr.checkAccess(caller, null, false, owner); // Validate vpc offering VpcOfferingVO vpcOff = _vpcOffDao.findById(vpcOffId); @@ -605,4 +612,35 @@ public class VpcManagerImpl implements VpcManager, Manager{ services.add(Network.Service.Vpn); return services; } + + @Override + public Vpc startVpc(long vpcId) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { + UserContext ctx = UserContext.current(); + Account caller = ctx.getCaller(); + User callerUser = _accountMgr.getActiveUser(ctx.getCallerUserId()); + + //check if vpc exists + Vpc vpc = getVpc(vpcId); + if (vpc == null) { + throw new InvalidParameterValueException("Unable to find vpc by id " + vpcId); + } + + //permission check + _accountMgr.checkAccess(caller, null, false, vpc); + + DataCenter dc = _configMgr.getZone(vpc.getZoneId()); + + DeployDestination dest = new DeployDestination(dc, null, null, null); + ReservationContext context = new ReservationContextImpl(null, null, callerUser, _accountMgr.getAccount(vpc.getAccountId())); + + //deploy provider + if (((VpcProvider)_ntwkMgr.getElementImplementingProvider(Provider.VirtualRouter.getName())).startVpc(vpc, dest, context)) { + s_logger.debug("Vpc " + vpc + " has started succesfully"); + return getVpc(vpc.getId()); + } else { + throw new CloudRuntimeException("Failed to start vpc " + vpc); + //FIXME - add cleanup logic here + } + + } } diff --git a/server/src/com/cloud/network/vpc/VpcOfferingVO.java b/server/src/com/cloud/network/vpc/VpcOfferingVO.java index 86b698e6b05..2b96f2047dc 100644 --- a/server/src/com/cloud/network/vpc/VpcOfferingVO.java +++ b/server/src/com/cloud/network/vpc/VpcOfferingVO.java @@ -64,20 +64,24 @@ public class VpcOfferingVO implements VpcOffering{ @Column(name = GenericDao.CREATED_COLUMN) Date created; + @Column(name = "service_offering_id") + Long serviceOfferingId; + public VpcOfferingVO() { this.uuid = UUID.randomUUID().toString(); } - public VpcOfferingVO(String name, String displayText) { + public VpcOfferingVO(String name, String displayText, Long serviceOfferingId) { this.name = name; this.displayText = displayText; this.uniqueName = name; + this.serviceOfferingId = serviceOfferingId; this.uuid = UUID.randomUUID().toString(); this.state = State.Disabled; } - public VpcOfferingVO(String name, String displayText, boolean isDefault) { - this(name, displayText); + public VpcOfferingVO(String name, String displayText, boolean isDefault, Long serviceOfferingId) { + this(name, displayText, serviceOfferingId); this.isDefault = isDefault; } @@ -136,8 +140,12 @@ public class VpcOfferingVO implements VpcOffering{ this.displayText = displayText; } - public void setState(State state) { this.state = state; } + + @Override + public Long getServiceOfferingId() { + return serviceOfferingId; + } } diff --git a/server/src/com/cloud/vm/dao/DomainRouterDao.java b/server/src/com/cloud/vm/dao/DomainRouterDao.java index 2afc5af5279..350ea1d0206 100755 --- a/server/src/com/cloud/vm/dao/DomainRouterDao.java +++ b/server/src/com/cloud/vm/dao/DomainRouterDao.java @@ -105,4 +105,10 @@ public interface DomainRouterDao extends GenericDao { * @return */ List getRouterNetworks(long routerId); + + /** + * @param vpcId + * @return + */ + List listRoutersByVpcId(long vpcId); } diff --git a/server/src/com/cloud/vm/dao/DomainRouterDaoImpl.java b/server/src/com/cloud/vm/dao/DomainRouterDaoImpl.java index eb670cb3af1..23ecea990f1 100755 --- a/server/src/com/cloud/vm/dao/DomainRouterDaoImpl.java +++ b/server/src/com/cloud/vm/dao/DomainRouterDaoImpl.java @@ -63,6 +63,7 @@ public class DomainRouterDaoImpl extends GenericDaoBase im 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.and("vpcId", AllFieldsSearch.entity().getVpcId(), Op.EQ); AllFieldsSearch.done(); IdNetworkIdStatesSearch = createSearchBuilder(); @@ -280,4 +281,12 @@ public class DomainRouterDaoImpl extends GenericDaoBase im return _routerNetworkDao.getRouterNetworks(routerId); } + @Override + public List listRoutersByVpcId(long vpcId) { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("vpcId", vpcId); + sc.setParameters("role", Role.VIRTUAL_ROUTER); + return listBy(sc); + } + } diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index 56d3e6155e2..b077b31d165 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -920,6 +920,7 @@ CREATE TABLE `cloud`.`user_ip_address` ( `network_id` bigint unsigned COMMENT 'network this public ip address is associated with', `physical_network_id` bigint unsigned NOT NULL COMMENT 'physical network id that this configuration is based on', `is_system` int(1) unsigned NOT NULL default '0', + `vpc_id` bigint unsigned COMMENT 'vpc the ip address is associated with', PRIMARY KEY (`id`), UNIQUE (`public_ip_address`, `source_network_id`), CONSTRAINT `fk_user_ip_address__source_network_id` FOREIGN KEY (`source_network_id`) REFERENCES `networks`(`id`), @@ -930,6 +931,7 @@ CREATE TABLE `cloud`.`user_ip_address` ( CONSTRAINT `fk_user_ip_address__data_center_id` FOREIGN KEY (`data_center_id`) REFERENCES `data_center`(`id`) ON DELETE CASCADE, CONSTRAINT `uc_user_ip_address__uuid` UNIQUE (`uuid`), CONSTRAINT `fk_user_ip_address__physical_network_id` FOREIGN KEY (`physical_network_id`) REFERENCES `physical_network`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_user_ip_address__vpc_id` FOREIGN KEY (`vpc_id`) REFERENCES `vpc`(`id`) ON DELETE CASCADE, INDEX `i_user_ip_address__allocated`(`allocated`), INDEX `i_user_ip_address__source_nat`(`source_nat`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; @@ -1079,9 +1081,11 @@ CREATE TABLE `cloud`.`domain_router` ( `role` varchar(64) NOT NULL COMMENT 'type of role played by this router', `template_version` varchar(100) COMMENT 'template version', `scripts_version` varchar(100) COMMENT 'scripts version', + `vpc_id` bigint unsigned COMMENT 'correlated virtual router vpc ID', PRIMARY KEY (`id`), CONSTRAINT `fk_domain_router__id` FOREIGN KEY `fk_domain_router__id` (`id`) REFERENCES `vm_instance`(`id`) ON DELETE CASCADE, - CONSTRAINT `fk_domain_router__element_id` FOREIGN KEY `fk_domain_router__element_id`(`element_id`) REFERENCES `virtual_router_providers`(`id`) + CONSTRAINT `fk_domain_router__element_id` FOREIGN KEY `fk_domain_router__element_id`(`element_id`) REFERENCES `virtual_router_providers`(`id`), + CONSTRAINT `fk_domain_router__vpc_id` FOREIGN KEY `fk_domain_router__vpc_id`(`vpc_id`) REFERENCES `vpc`(`id`) ) ENGINE = InnoDB DEFAULT CHARSET=utf8 COMMENT = 'information about the domR instance'; CREATE TABLE `cloud`.`upload` ( @@ -2166,11 +2170,12 @@ CREATE TABLE `cloud`.`vpc_offerings` ( `default` int(1) unsigned NOT NULL DEFAULT 0 COMMENT '1 if vpc offering is default', `removed` datetime COMMENT 'date removed if not null', `created` datetime NOT NULL COMMENT 'date created', + `service_offering_id` bigint unsigned COMMENT 'service offering id that virtual router is tied to', PRIMARY KEY (`id`), - INDEX `i_vpc__removed`(`removed`) + INDEX `i_vpc__removed`(`removed`), + CONSTRAINT `fk_vpc_offerings__service_offering_id` FOREIGN KEY `fk_vpc_offerings__service_offering_id` (`service_offering_id`) REFERENCES `service_offering`(`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; - CREATE TABLE `cloud`.`vpc_offering_service_map` ( `id` bigint unsigned NOT NULL auto_increment, `vpc_offering_id` bigint unsigned NOT NULL COMMENT 'vpc_offering_id', diff --git a/wscript b/wscript index 9cd8d62d193..83041135c0a 100644 --- a/wscript +++ b/wscript @@ -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-19T01:23:44Z' +VERSION = '3.0.3.2012-05-21T20:55:19Z' APPNAME = 'cloud' import shutil,os