From 09763596d0399f32c5acbbed055572eaf4830d28 Mon Sep 17 00:00:00 2001 From: Antonio Fornie Date: Wed, 16 Jul 2014 12:11:47 -0500 Subject: [PATCH] Deployment more OO - Objects with data and behavior Conflicts: server/src/com/cloud/network/element/VirtualRouterElement.java server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java --- .../network/element/VirtualRouterElement.java | 18 +- .../element/VpcVirtualRouterElement.java | 38 +- .../network/router/NetworkGeneralHelper.java | 137 ++-- .../router/RouterDeploymentDefinition.java | 139 ---- .../router/RouterDeploymentManager.java | 681 ------------------ .../VirtualNetworkApplianceManager.java | 4 - .../VirtualNetworkApplianceManagerImpl.java | 12 +- ...VpcVirtualNetworkApplianceManagerImpl.java | 67 +- .../router/VpcVirtualNetworkHelperImpl.java | 81 +-- .../RouterDeploymentDefinition.java | 530 ++++++++++++++ .../RouterDeploymentDefinitionBuilder.java | 188 +++++ .../VpcRouterDeploymentDefinition.java | 241 +++++++ ...MockVpcVirtualNetworkApplianceManager.java | 11 - 13 files changed, 1112 insertions(+), 1035 deletions(-) delete mode 100644 server/src/com/cloud/network/router/RouterDeploymentDefinition.java delete mode 100644 server/src/com/cloud/network/router/RouterDeploymentManager.java create mode 100644 server/src/com/cloud/network/router/deployment/RouterDeploymentDefinition.java create mode 100644 server/src/com/cloud/network/router/deployment/RouterDeploymentDefinitionBuilder.java create mode 100644 server/src/com/cloud/network/router/deployment/VpcRouterDeploymentDefinition.java diff --git a/server/src/com/cloud/network/element/VirtualRouterElement.java b/server/src/com/cloud/network/element/VirtualRouterElement.java index 65f06b346cb..90e9a639fa5 100755 --- a/server/src/com/cloud/network/element/VirtualRouterElement.java +++ b/server/src/com/cloud/network/element/VirtualRouterElement.java @@ -72,10 +72,11 @@ import com.cloud.network.dao.VirtualRouterProviderDao; import com.cloud.network.lb.LoadBalancingRule; import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy; import com.cloud.network.lb.LoadBalancingRulesManager; -import com.cloud.network.router.RouterDeploymentDefinition; import com.cloud.network.router.VirtualRouter; import com.cloud.network.router.VirtualRouter.Role; import com.cloud.network.router.VpcVirtualNetworkApplianceManager; +import com.cloud.network.router.deployment.RouterDeploymentDefinition; +import com.cloud.network.router.deployment.RouterDeploymentDefinitionBuilder; import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.LbStickinessMethod; import com.cloud.network.rules.LbStickinessMethod.StickinessMethodType; @@ -156,6 +157,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl @Inject NetworkTopologyContext networkTopologyContext; + @Inject + private RouterDeploymentDefinitionBuilder routerDeploymentDefinitionBuilder; protected boolean canHandle(final Network network, final Service service) { Long physicalNetworkId = _networkMdl.getPhysicalNetworkId(network); @@ -197,10 +200,10 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl Map params = new HashMap(1); params.put(VirtualMachineProfile.Param.ReProgramGuestNetworks, true); - RouterDeploymentDefinition routerDeploymentDefinition = new RouterDeploymentDefinition(network, dest, _accountMgr.getAccount(network.getAccountId()), params, - offering.getRedundantRouter()); + RouterDeploymentDefinition routerDeploymentDefinition = routerDeploymentDefinitionBuilder.create().setGuestNetwork(network).setDeployDestination(dest) + .setAccountOwner(_accountMgr.getAccount(network.getAccountId())).setParams(params).setRedundant(offering.getRedundantRouter()).build(); - List routers = _routerMgr.deployVirtualRouter(routerDeploymentDefinition); + List routers = routerDeploymentDefinition.deployVirtualRouter(); int routerCounts = 1; if (offering.getRedundantRouter()) { @@ -232,9 +235,10 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl return false; } - RouterDeploymentDefinition routerDeploymentDefinition = new RouterDeploymentDefinition(network, dest, _accountMgr.getAccount(network.getAccountId()), vm.getParameters(), - offering.getRedundantRouter()); - List routers = _routerMgr.deployVirtualRouter(routerDeploymentDefinition); + RouterDeploymentDefinition routerDeploymentDefinition = routerDeploymentDefinitionBuilder.create().setGuestNetwork(network).setDeployDestination(dest) + .setAccountOwner(_accountMgr.getAccount(network.getAccountId())).setParams(vm.getParameters()).setRedundant(offering.getRedundantRouter()).build(); + + List routers = routerDeploymentDefinition.deployVirtualRouter(); if (routers == null || routers.size() == 0) { throw new ResourceUnavailableException("Can't find at least one running router!", DataCenter.class, network.getDataCenterId()); diff --git a/server/src/com/cloud/network/element/VpcVirtualRouterElement.java b/server/src/com/cloud/network/element/VpcVirtualRouterElement.java index 0cc083ba0d2..77346c859d7 100644 --- a/server/src/com/cloud/network/element/VpcVirtualRouterElement.java +++ b/server/src/com/cloud/network/element/VpcVirtualRouterElement.java @@ -47,10 +47,11 @@ import com.cloud.network.VpnUser; import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.NetworkDao; import com.cloud.network.dao.Site2SiteVpnGatewayDao; -import com.cloud.network.router.RouterDeploymentDefinition; import com.cloud.network.router.VirtualRouter; import com.cloud.network.router.VirtualRouter.Role; import com.cloud.network.router.VpcVirtualNetworkApplianceManager; +import com.cloud.network.router.deployment.RouterDeploymentDefinition; +import com.cloud.network.router.deployment.RouterDeploymentDefinitionBuilder; import com.cloud.network.vpc.NetworkACLItem; import com.cloud.network.vpc.NetworkACLItemDao; import com.cloud.network.vpc.NetworkACLItemVO; @@ -93,6 +94,9 @@ public class VpcVirtualRouterElement extends VirtualRouterElement implements Vpc @Inject EntityManager _entityMgr; + @Inject + private RouterDeploymentDefinitionBuilder routerDeploymentDefinitionBuilder; + private static final Map> capabilities = setCapabilities(); @Override @@ -133,8 +137,14 @@ public class VpcVirtualRouterElement extends VirtualRouterElement implements Vpc params.put(VirtualMachineProfile.Param.ReProgramGuestNetworks, true); RouterDeploymentDefinition routerDeploymentDefinition = - new RouterDeploymentDefinition(vpc, dest, _accountMgr.getAccount(vpc.getAccountId()), params, false); - _vpcRouterMgr.deployVirtualRouter(routerDeploymentDefinition); + this.routerDeploymentDefinitionBuilder.create() + .setVpc(vpc) + .setDeployDestination(dest) + .setAccountOwner(_accountMgr.getAccount(vpc.getAccountId())) + .setParams(params) + .build(); + + routerDeploymentDefinition.deployVirtualRouter(); return true; } @@ -172,8 +182,15 @@ public class VpcVirtualRouterElement extends VirtualRouterElement implements Vpc params.put(VirtualMachineProfile.Param.ReProgramGuestNetworks, true); RouterDeploymentDefinition routerDeploymentDefinition = - new RouterDeploymentDefinition(vpc, dest, _accountMgr.getAccount(vpc.getAccountId()), params, false); - List routers = _vpcRouterMgr.deployVirtualRouter(routerDeploymentDefinition); + this.routerDeploymentDefinitionBuilder.create() + .setVpc(vpc) + .setDeployDestination(dest) + .setAccountOwner(_accountMgr.getAccount(vpc.getAccountId())) + .setParams(params) + .build(); + + List routers = routerDeploymentDefinition.deployVirtualRouter(); + if ((routers == null) || (routers.size() == 0)) { throw new ResourceUnavailableException("Can't find at least one running router!", DataCenter.class, network.getDataCenterId()); } @@ -218,9 +235,16 @@ public class VpcVirtualRouterElement extends VirtualRouterElement implements Vpc if (vm.getType() == VirtualMachine.Type.User) { Map params = new HashMap(1); params.put(VirtualMachineProfile.Param.ReProgramGuestNetworks, true); + RouterDeploymentDefinition routerDeploymentDefinition = - new RouterDeploymentDefinition(vpc, dest, _accountMgr.getAccount(vpc.getAccountId()), params, false); - List routers = _vpcRouterMgr.deployVirtualRouter(routerDeploymentDefinition); + this.routerDeploymentDefinitionBuilder.create() + .setVpc(vpc) + .setDeployDestination(dest) + .setAccountOwner(_accountMgr.getAccount(vpc.getAccountId())) + .setParams(params) + .build(); + List routers = routerDeploymentDefinition.deployVirtualRouter(); + if ((routers == null) || (routers.size() == 0)) { throw new ResourceUnavailableException("Can't find at least one running router!", DataCenter.class, network.getDataCenterId()); } diff --git a/server/src/com/cloud/network/router/NetworkGeneralHelper.java b/server/src/com/cloud/network/router/NetworkGeneralHelper.java index c3e1caf9409..4b331f7fa45 100644 --- a/server/src/com/cloud/network/router/NetworkGeneralHelper.java +++ b/server/src/com/cloud/network/router/NetworkGeneralHelper.java @@ -68,6 +68,7 @@ import com.cloud.network.dao.NetworkVO; import com.cloud.network.dao.UserIpv6AddressDao; import com.cloud.network.router.VirtualRouter.RedundantState; import com.cloud.network.router.VirtualRouter.Role; +import com.cloud.network.router.deployment.RouterDeploymentDefinition; import com.cloud.network.vpn.Site2SiteVpnManager; import com.cloud.offering.NetworkOffering; import com.cloud.resource.ResourceManager; @@ -101,47 +102,48 @@ public class NetworkGeneralHelper { @Inject - NicDao _nicDao; + private NicDao nicDao; @Inject - NetworkDao _networkDao; + private NetworkDao networkDao; @Inject - DomainRouterDao _routerDao; + private DomainRouterDao routerDao; @Inject - AgentManager _agentMgr; + private AgentManager agentMgr; @Inject - NetworkModel _networkModel; + private NetworkModel networkModel; @Inject - VirtualMachineManager _itMgr; + private VirtualMachineManager itMgr; @Inject - AccountManager _accountMgr; + private AccountManager accountMgr; @Inject - Site2SiteVpnManager _s2sVpnMgr; + private Site2SiteVpnManager s2sVpnMgr; @Inject - HostDao _hostDao; + private HostDao hostDao; @Inject - VolumeDao _volumeDao; + private VolumeDao volumeDao; @Inject - ServiceOfferingDao _serviceOfferingDao; + private ServiceOfferingDao serviceOfferingDao; @Inject - VMTemplateDao _templateDao; + private VMTemplateDao templateDao; @Inject - ResourceManager _resourceMgr; + private ResourceManager resourceMgr; @Inject - ClusterDao _clusterDao; + private ClusterDao clusterDao; @Inject - IPAddressDao _ipAddressDao; + private IPAddressDao ipAddressDao; @Inject - IpAddressManager _ipAddrMgr; + private IpAddressManager ipAddrMgr; @Inject - UserIpv6AddressDao _ipv6Dao; + private UserIpv6AddressDao ipv6Dao; @Inject - NetworkOrchestrationService _networkMgr; + private NetworkOrchestrationService networkMgr; + public String getRouterControlIp(final long routerId) { String routerControlIpAddress = null; - final List nics = _nicDao.listByVmId(routerId); + final List nics = nicDao.listByVmId(routerId); for (final NicVO n : nics) { - final NetworkVO nc = _networkDao.findById(n.getNetworkId()); + final NetworkVO nc = networkDao.findById(n.getNetworkId()); if (nc != null && nc.getTrafficType() == TrafficType.Control) { routerControlIpAddress = n.getIp4Address(); // router will have only one control ip @@ -151,7 +153,7 @@ public class NetworkGeneralHelper { if (routerControlIpAddress == null) { s_logger.warn("Unable to find router's control ip in its attached NICs!. routerId: " + routerId); - final DomainRouterVO router = _routerDao.findById(routerId); + final DomainRouterVO router = routerDao.findById(routerId); return router.getPrivateIpAddress(); } @@ -159,7 +161,7 @@ public class NetworkGeneralHelper { } public String getRouterIpInNetwork(final long networkId, final long instanceId) { - return _nicDao.getIpAddress(networkId, instanceId); + return nicDao.getIpAddress(networkId, instanceId); } @@ -172,7 +174,7 @@ public class NetworkGeneralHelper { } Answer[] answers = null; try { - answers = _agentMgr.send(router.getHostId(), cmds); + answers = agentMgr.send(router.getHostId(), cmds); } catch (final OperationTimedoutException e) { s_logger.warn("Timed Out", e); throw new AgentUnavailableException("Unable to send commands to virtual router ", router.getHostId(), e); @@ -202,9 +204,9 @@ public class NetworkGeneralHelper { // @Override public NicTO getNicTO(final VirtualRouter router, final Long networkId, final String broadcastUri) { - NicProfile nicProfile = _networkModel.getNicProfile(router, networkId, broadcastUri); + NicProfile nicProfile = networkModel.getNicProfile(router, networkId, broadcastUri); - return _itMgr.toNicTO(nicProfile, router.getHypervisorType()); + return itMgr.toNicTO(nicProfile, router.getHypervisorType()); } // @Override @@ -214,15 +216,15 @@ public class NetworkGeneralHelper { s_logger.debug("Attempting to destroy router " + routerId); } - final DomainRouterVO router = _routerDao.findById(routerId); + final DomainRouterVO router = routerDao.findById(routerId); if (router == null) { return null; } - _accountMgr.checkAccess(caller, null, true, router); + accountMgr.checkAccess(caller, null, true, router); - _itMgr.expunge(router.getUuid()); - _routerDao.remove(router.getId()); + itMgr.expunge(router.getUuid()); + routerDao.remove(router.getId()); return router; } @@ -250,26 +252,26 @@ public class NetworkGeneralHelper { throws StorageUnavailableException, InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { s_logger.debug("Starting router " + router); try { - _itMgr.advanceStart(router.getUuid(), params, planToDeploy, null); + itMgr.advanceStart(router.getUuid(), params, planToDeploy, null); } catch (final OperationTimedoutException e) { throw new ResourceUnavailableException("Starting router " + router + " failed! " + e.toString(), DataCenter.class, router.getDataCenterId()); } if (router.isStopPending()) { s_logger.info("Clear the stop pending flag of router " + router.getHostName() + " after start router successfully!"); router.setStopPending(false); - router = _routerDao.persist(router); + router = routerDao.persist(router); } // We don't want the failure of VPN Connection affect the status of router, so we try to make connection // only after router start successfully final Long vpcId = router.getVpcId(); if (vpcId != null) { - _s2sVpnMgr.reconnectDisconnectedVpnByVpc(vpcId); + s2sVpnMgr.reconnectDisconnectedVpnByVpc(vpcId); } - return _routerDao.findById(router.getId()); + return routerDao.findById(router.getId()); } protected DomainRouterVO waitRouter(final DomainRouterVO router) { - DomainRouterVO vm = _routerDao.findById(router.getId()); + DomainRouterVO vm = routerDao.findById(router.getId()); if (s_logger.isDebugEnabled()) { s_logger.debug("Router " + router.getInstanceName() + " is not fully up yet, we will wait"); @@ -281,7 +283,7 @@ public class NetworkGeneralHelper { } // reload to get the latest state info - vm = _routerDao.findById(router.getId()); + vm = routerDao.findById(router.getId()); } if (vm.getState() == State.Running) { @@ -298,8 +300,9 @@ public class NetworkGeneralHelper { // @Override - public List startRouters(final RouterDeploymentDefinition routerDeploymentDefinition) throws StorageUnavailableException, - InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { + public List startRouters(final RouterDeploymentDefinition routerDeploymentDefinition) + throws StorageUnavailableException, InsufficientCapacityException, + ConcurrentOperationException, ResourceUnavailableException { List runningRouters = new ArrayList(); @@ -307,14 +310,14 @@ public class NetworkGeneralHelper { boolean skip = false; final State state = router.getState(); if (router.getHostId() != null && state != State.Running) { - final HostVO host = _hostDao.findById(router.getHostId()); + final HostVO host = hostDao.findById(router.getHostId()); if (host == null || host.getState() != Status.Up) { skip = true; } } if (!skip) { if (state != State.Running) { - router = startVirtualRouter(router, _accountMgr.getSystemUser(), _accountMgr.getSystemAccount(), + router = startVirtualRouter(router, accountMgr.getSystemUser(), accountMgr.getSystemAccount(), routerDeploymentDefinition.getParams()); } if (router != null) { @@ -350,14 +353,14 @@ public class NetworkGeneralHelper { DataCenterDeployment plan = new DataCenterDeployment(0, null, null, null, null, null); DomainRouterVO result = null; assert router.getIsRedundantRouter(); - final List networkIds = _routerDao.getRouterNetworks(router.getId()); + final List networkIds = routerDao.getRouterNetworks(router.getId()); //Not support VPC now if (networkIds.size() > 1) { throw new ResourceUnavailableException("Unable to support more than one guest network for redundant router now!", DataCenter.class, router.getDataCenterId()); } DomainRouterVO routerToBeAvoid = null; if (networkIds.size() != 0) { - final List routerList = _routerDao.findByNetwork(networkIds.get(0)); + final List routerList = routerDao.findByNetwork(networkIds.get(0)); for (final DomainRouterVO rrouter : routerList) { if (rrouter.getHostId() != null && rrouter.getIsRedundantRouter() && rrouter.getState() == State.Running) { if (routerToBeAvoid != null) { @@ -379,9 +382,9 @@ public class NetworkGeneralHelper { avoids[0] = new ExcludeList(); avoids[0].addPod(routerToBeAvoid.getPodIdToDeployIn()); avoids[1] = new ExcludeList(); - avoids[1].addCluster(_hostDao.findById(routerToBeAvoid.getHostId()).getClusterId()); + avoids[1].addCluster(hostDao.findById(routerToBeAvoid.getHostId()).getClusterId()); avoids[2] = new ExcludeList(); - final List volumes = _volumeDao.findByInstanceAndType(routerToBeAvoid.getId(), Volume.Type.ROOT); + final List volumes = volumeDao.findByInstanceAndType(routerToBeAvoid.getId(), Volume.Type.ROOT); if (volumes != null && volumes.size() != 0) { avoids[2].addPool(volumes.get(0).getPoolId()); } @@ -417,7 +420,7 @@ public class NetworkGeneralHelper { InsufficientServerCapacityException, InsufficientCapacityException, StorageUnavailableException, ResourceUnavailableException { - final ServiceOfferingVO routerOffering = _serviceOfferingDao.findById(svcOffId); + final ServiceOfferingVO routerOffering = serviceOfferingDao.findById(svcOffId); final DeployDestination dest = routerDeploymentDefinition.getDest(); final Account owner = routerDeploymentDefinition.getOwner(); @@ -431,7 +434,7 @@ public class NetworkGeneralHelper { for (final Iterator iter = hypervisors.iterator(); iter.hasNext();) { final HypervisorType hType = iter.next(); try { - final long id = _routerDao.getNextInSequence(Long.class, "id"); + final long id = routerDao.getNextInSequence(Long.class, "id"); if (s_logger.isDebugEnabled()) { s_logger.debug("Allocating the VR i=" + id + " in datacenter " + dest.getDataCenter() + "with the hypervisor type " + hType); } @@ -456,7 +459,7 @@ public class NetworkGeneralHelper { default: break; } - final VMTemplateVO template = _templateDao.findRoutingTemplate(hType, templateName); + final VMTemplateVO template = templateDao.findRoutingTemplate(hType, templateName); if (template == null) { s_logger.debug(hType + " won't support system vm, skip it"); @@ -479,9 +482,9 @@ public class NetworkGeneralHelper { router.setDynamicallyScalable(template.isDynamicallyScalable()); router.setRole(Role.VIRTUAL_ROUTER); - router = _routerDao.persist(router); - _itMgr.allocate(router.getInstanceName(), template, routerOffering, networks, routerDeploymentDefinition.getPlan(), null); - router = _routerDao.findById(router.getId()); + router = routerDao.persist(router); + itMgr.allocate(router.getInstanceName(), template, routerOffering, networks, routerDeploymentDefinition.getPlan(), null); + router = routerDao.findById(router.getId()); } catch (final InsufficientCapacityException ex) { if (allocateRetry < 2 && iter.hasNext()) { s_logger.debug("Failed to allocate the VR with hypervisor type " + hType + ", retrying one more time"); @@ -495,13 +498,13 @@ public class NetworkGeneralHelper { if (startRouter) { try { - router = startVirtualRouter(router, _accountMgr.getSystemUser(), _accountMgr.getSystemAccount(), routerDeploymentDefinition.getParams()); + router = startVirtualRouter(router, accountMgr.getSystemUser(), accountMgr.getSystemAccount(), routerDeploymentDefinition.getParams()); break; } catch (final InsufficientCapacityException ex) { if (startRetry < 2 && iter.hasNext()) { s_logger.debug("Failed to start the VR " + router + " with hypervisor type " + hType + ", " + "destroying it and recreating one more time"); // destroy the router - destroyRouter(router.getId(), _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM), User.UID_SYSTEM); + destroyRouter(router.getId(), accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM), User.UID_SYSTEM); continue; } else { throw ex; @@ -530,12 +533,12 @@ public class NetworkGeneralHelper { hypervisors.add(dest.getCluster().getHypervisorType()); } } else { - final HypervisorType defaults = _resourceMgr.getDefaultHypervisor(dest.getDataCenter().getId()); + final HypervisorType defaults = resourceMgr.getDefaultHypervisor(dest.getDataCenter().getId()); if (defaults != HypervisorType.None) { hypervisors.add(defaults); } else { //if there is no default hypervisor, get it from the cluster - hypervisors = _resourceMgr.getSupportedHypervisorTypes(dest.getDataCenter().getId(), true, routerDeploymentDefinition.getPodId()); + hypervisors = resourceMgr.getSupportedHypervisorTypes(dest.getDataCenter().getId(), true, routerDeploymentDefinition.getPodId()); } } @@ -564,13 +567,13 @@ public class NetworkGeneralHelper { * Ovm won't support any system. So we have to choose a partner cluster in the same pod to start domain router for us */ protected HypervisorType getClusterToStartDomainRouterForOvm(final long podId) { - final List clusters = _clusterDao.listByPodId(podId); + final List clusters = clusterDao.listByPodId(podId); for (final ClusterVO cv : clusters) { if (cv.getHypervisorType() == HypervisorType.Ovm || cv.getHypervisorType() == HypervisorType.BareMetal) { continue; } - final List hosts = _resourceMgr.listAllHostsInCluster(cv.getId()); + final List hosts = resourceMgr.listAllHostsInCluster(cv.getId()); if (hosts == null || hosts.isEmpty()) { continue; } @@ -616,7 +619,7 @@ public class NetworkGeneralHelper { + guestNetwork); String defaultNetworkStartIp = null, defaultNetworkStartIpv6 = null; if (!setupPublicNetwork) { - final Nic placeholder = _networkModel + final Nic placeholder = networkModel .getPlaceholderNicForRouter(guestNetwork, routerDeploymentDefinition.getPodId()); if (guestNetwork.getCidr() != null) { @@ -628,10 +631,10 @@ public class NetworkGeneralHelper { + guestNetwork); defaultNetworkStartIp = placeholder.getIp4Address(); } else { - final String startIp = _networkModel + final String startIp = networkModel .getStartIpAddress(guestNetwork.getId()); if (startIp != null - && _ipAddressDao.findByIpAndSourceNetworkId( + && ipAddressDao.findByIpAndSourceNetworkId( guestNetwork.getId(), startIp) .getAllocatedTime() == null) { defaultNetworkStartIp = startIp; @@ -654,10 +657,10 @@ public class NetworkGeneralHelper { + guestNetwork); defaultNetworkStartIpv6 = placeholder.getIp6Address(); } else { - final String startIpv6 = _networkModel + final String startIpv6 = networkModel .getStartIpv6Address(guestNetwork.getId()); if (startIpv6 != null - && _ipv6Dao.findByNetworkIdAndIp( + && ipv6Dao.findByNetworkIdAndIp( guestNetwork.getId(), startIpv6) == null) { defaultNetworkStartIpv6 = startIpv6; } else if (s_logger.isDebugEnabled()) { @@ -675,7 +678,7 @@ public class NetworkGeneralHelper { defaultNetworkStartIpv6); if (setupPublicNetwork) { if (routerDeploymentDefinition.isRedundant()) { - gatewayNic.setIp4Address(_ipAddrMgr.acquireGuestIpAddress( + gatewayNic.setIp4Address(ipAddrMgr.acquireGuestIpAddress( guestNetwork, null)); } else { gatewayNic.setIp4Address(guestNetwork.getGateway()); @@ -698,10 +701,10 @@ public class NetworkGeneralHelper { // 2) Control network s_logger.debug("Adding nic for Virtual Router in Control network "); - List offerings = _networkModel + List offerings = networkModel .getSystemAccountNetworkOfferings(NetworkOffering.SystemControlNetwork); NetworkOffering controlOffering = offerings.get(0); - Network controlConfig = _networkMgr.setupNetwork(VirtualNwStatus.account, + Network controlConfig = networkMgr.setupNetwork(VirtualNwStatus.account, controlOffering, routerDeploymentDefinition.getPlan(), null, null, false).get(0); networks.put(controlConfig, new ArrayList()); // 3) Public network @@ -717,7 +720,7 @@ public class NetworkGeneralHelper { defaultNic.setNetmask(sourceNatIp.getNetmask()); defaultNic.setMacAddress(sourceNatIp.getMacAddress()); // get broadcast from public network - final Network pubNet = _networkDao.findById(sourceNatIp + final Network pubNet = networkDao.findById(sourceNatIp .getNetworkId()); if (pubNet.getBroadcastDomainType() == BroadcastDomainType.Vxlan) { defaultNic.setBroadcastType(BroadcastDomainType.Vxlan); @@ -735,16 +738,16 @@ public class NetworkGeneralHelper { if (hasGuestNetwork) { defaultNic.setDeviceId(2); } - final NetworkOffering publicOffering = _networkModel + final NetworkOffering publicOffering = networkModel .getSystemAccountNetworkOfferings( NetworkOffering.SystemPublicNetwork).get(0); - final List publicNetworks = _networkMgr + final List publicNetworks = networkMgr .setupNetwork(VirtualNwStatus.account, publicOffering, routerDeploymentDefinition.getPlan(), null, null, false); final String publicIp = defaultNic.getIp4Address(); // We want to use the identical MAC address for RvR on public // interface if possible - final NicVO peerNic = _nicDao.findByIp4AddressAndNetworkId( + final NicVO peerNic = nicDao.findByIp4AddressAndNetworkId( publicIp, publicNetworks.get(0).getId()); if (peerNic != null) { s_logger.info("Use same MAC as previous RvR, the MAC is " diff --git a/server/src/com/cloud/network/router/RouterDeploymentDefinition.java b/server/src/com/cloud/network/router/RouterDeploymentDefinition.java deleted file mode 100644 index 372f21479cf..00000000000 --- a/server/src/com/cloud/network/router/RouterDeploymentDefinition.java +++ /dev/null @@ -1,139 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. -package com.cloud.network.router; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import com.cloud.dc.DataCenter.NetworkType; -import com.cloud.dc.Pod; -import com.cloud.deploy.DataCenterDeployment; -import com.cloud.deploy.DeployDestination; -import com.cloud.deploy.DeploymentPlan; -import com.cloud.network.Network; -import com.cloud.network.vpc.Vpc; -import com.cloud.user.Account; -import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.vm.DomainRouterVO; -import com.cloud.vm.VirtualMachineProfile.Param; - -public class RouterDeploymentDefinition { - - protected Vpc vpc; - protected Network guestNetwork; - protected DeployDestination dest; - protected Account owner; - protected Map params; - protected boolean isRedundant; - protected DeploymentPlan plan; - protected List routers = new ArrayList<>(); - - public RouterDeploymentDefinition(final Vpc vpc, final DeployDestination dest, - final Account owner, final Map params, - final boolean isRedundant) { - - this.vpc = vpc; - this.dest = dest; - this.owner = owner; - this.params = params; - this.isRedundant = isRedundant; - } - - public RouterDeploymentDefinition(final Network guestNetwork, final DeployDestination dest, - final Account owner, final Map params, final boolean isRedundant) { - - this.guestNetwork = guestNetwork; - this.dest = dest; - this.owner = owner; - this.params = params; - this.isRedundant = isRedundant; - } - - public Vpc getVpc() { - return vpc; - } - public void setVpc(final Vpc vpc) { - this.vpc = vpc; - } - public Network getGuestNetwork() { - return guestNetwork; - } - public void setGuestNetwork(final Network guestNetwork) { - this.guestNetwork = guestNetwork; - } - public DeployDestination getDest() { - return dest; - } - public void setDest(final DeployDestination dest) { - this.dest = dest; - } - public Account getOwner() { - return owner; - } - public void setOwner(final Account owner) { - this.owner = owner; - } - public Map getParams() { - return params; - } - public void setParams(final Map params) { - this.params = params; - } - public boolean isRedundant() { - return isRedundant; - } - public void setRedundant(final boolean isRedundant) { - this.isRedundant = isRedundant; - } - public DeploymentPlan getPlan() { - return plan; - } - - public boolean isVpcRouter() { - return vpc != null; - } - public Pod getPod() { - return dest.getPod(); - } - public Long getPodId() { - return dest.getPod().getId(); - } - - public List getRouters() { - return routers; - } - public void setRouters(List routers) { - this.routers = routers; - } - - public boolean isBasic() { - return this.dest.getDataCenter().getNetworkType() == NetworkType.Basic; - } - - public void planDeployment() { - final long dcId = this.dest.getDataCenter().getId(); - Long podId = null; - if (this.isBasic()) { - if (this.dest.getPod() != null) { - throw new CloudRuntimeException("Pod id is expected in deployment destination"); - } - podId = this.dest.getPod().getId(); - } - this.plan = new DataCenterDeployment(dcId, podId, null, null, null, null); - } -} \ No newline at end of file diff --git a/server/src/com/cloud/network/router/RouterDeploymentManager.java b/server/src/com/cloud/network/router/RouterDeploymentManager.java deleted file mode 100644 index 2d3512ecbaa..00000000000 --- a/server/src/com/cloud/network/router/RouterDeploymentManager.java +++ /dev/null @@ -1,681 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you under the Apache License, Version 2.0 (the -// "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, -// software distributed under the License is distributed on an -// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the -// specific language governing permissions and limitations -// under the License. -package com.cloud.network.router; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.TreeSet; - -import javax.inject.Inject; - -import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; -import org.apache.log4j.Logger; - -import com.cloud.dc.HostPodVO; -import com.cloud.dc.dao.HostPodDao; -import com.cloud.dc.dao.VlanDao; -import com.cloud.deploy.DeployDestination; -import com.cloud.exception.ConcurrentOperationException; -import com.cloud.exception.InsufficientAddressCapacityException; -import com.cloud.exception.InsufficientCapacityException; -import com.cloud.exception.InsufficientServerCapacityException; -import com.cloud.exception.ResourceUnavailableException; -import com.cloud.exception.StorageUnavailableException; -import com.cloud.network.IpAddress; -import com.cloud.network.IpAddressManager; -import com.cloud.network.Network; -import com.cloud.network.Network.Provider; -import com.cloud.network.Network.Service; -import com.cloud.network.NetworkModel; -import com.cloud.network.Networks.BroadcastDomainType; -import com.cloud.network.Networks.IsolationType; -import com.cloud.network.Networks.TrafficType; -import com.cloud.network.PhysicalNetwork; -import com.cloud.network.PhysicalNetworkServiceProvider; -import com.cloud.network.VirtualRouterProvider; -import com.cloud.network.VirtualRouterProvider.Type; -import com.cloud.network.addr.PublicIp; -import com.cloud.network.dao.IPAddressDao; -import com.cloud.network.dao.IPAddressVO; -import com.cloud.network.dao.NetworkDao; -import com.cloud.network.dao.PhysicalNetworkDao; -import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; -import com.cloud.network.dao.UserIpv6AddressDao; -import com.cloud.network.dao.VirtualRouterProviderDao; -import com.cloud.network.router.VirtualRouter.Role; -import com.cloud.network.vpc.PrivateGateway; -import com.cloud.network.vpc.Vpc; -import com.cloud.network.vpc.VpcManager; -import com.cloud.network.vpc.dao.VpcDao; -import com.cloud.network.vpc.dao.VpcOfferingDao; -import com.cloud.offering.NetworkOffering; -import com.cloud.offerings.dao.NetworkOfferingDao; -import com.cloud.service.ServiceOfferingVO; -import com.cloud.user.Account; -import com.cloud.user.AccountManager; -import com.cloud.utils.Pair; -import com.cloud.utils.db.DB; -import com.cloud.utils.db.JoinBuilder; -import com.cloud.utils.db.SearchBuilder; -import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.utils.net.NetUtils; -import com.cloud.vm.DomainRouterVO; -import com.cloud.vm.Nic; -import com.cloud.vm.NicProfile; -import com.cloud.vm.NicVO; -import com.cloud.vm.VMInstanceVO; -import com.cloud.vm.VirtualMachine; -import com.cloud.vm.dao.DomainRouterDao; -import com.cloud.vm.dao.NicDao; -import com.cloud.vm.dao.VMInstanceDao; - -public class RouterDeploymentManager { - - private static final Logger logger = Logger.getLogger(RouterDeploymentManager.class); - - @Inject - private VpcDao vpcDao; - @Inject - private VpcOfferingDao vpcOffDao; - @Inject - private PhysicalNetworkDao pNtwkDao; - @Inject - private VpcManager vpcMgr; - @Inject - private PhysicalNetworkServiceProviderDao physicalProviderDao; - @Inject - private VlanDao vlanDao; - @Inject - private IPAddressDao ipAddressDao; - @Inject - private NetworkOrchestrationService networkMgr; - @Inject - private NetworkModel networkModel; - @Inject - private VirtualRouterProviderDao vrProviderDao; - @Inject - private NetworkDao _networkDao; - @Inject - private NetworkModel _networkModel; - @Inject - private DomainRouterDao _routerDao = null; - @Inject - private PhysicalNetworkServiceProviderDao _physicalProviderDao; - @Inject - private NetworkOfferingDao _networkOfferingDao = null; - @Inject - private VirtualRouterProviderDao _vrProviderDao; - @Inject - private IPAddressDao _ipAddressDao = null; - @Inject - private UserIpv6AddressDao _ipv6Dao; - @Inject - private VMInstanceDao _vmDao; - @Inject - private AccountManager _accountMgr; - @Inject - private HostPodDao _podDao = null; - @Inject - private IpAddressManager _ipAddrMgr; - @Inject - private NetworkOrchestrationService _networkMgr; - @Inject - private NicDao _nicDao; - - @Inject - private NetworkGeneralHelper nwHelper; - @Inject - private VpcVirtualNetworkHelperImpl vpcHelper; - - - protected ServiceOfferingVO offering; - - - - public void setOffering(ServiceOfferingVO offering) { - this.offering = offering; - } - - public Long getOfferingId() { - return offering == null ? null : offering.getId(); - } - - public List deployVirtualRouter(final RouterDeploymentDefinition routerDeploymentDefinition) - throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { - - if (routerDeploymentDefinition.getVpc() != null) { - return deployVirtualRouterInVpc(routerDeploymentDefinition); - } else { - return deployVirtualRouterInGuestNetwork(routerDeploymentDefinition); - } - } - - /////////////////////////////////////////////////////////////////////// - // Non-VPC behavior - /////////////////////////////////////////////////////////////////////// - protected List deployVirtualRouterInGuestNetwork(final RouterDeploymentDefinition routerDeploymentDefinition) - throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { - - findOrDeployVirtualRouterInGuestNetwork(routerDeploymentDefinition); - - return nwHelper.startRouters(routerDeploymentDefinition); - } - - - @DB - protected void findOrDeployVirtualRouterInGuestNetwork(final RouterDeploymentDefinition routerDeploymentDefinition) - throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { - - final Network guestNetwork = routerDeploymentDefinition.getGuestNetwork(); - final DeployDestination dest = routerDeploymentDefinition.getDest(); - - List routers = new ArrayList(); - final Network lock = _networkDao.acquireInLockTable(guestNetwork.getId(), NetworkOrchestrationService.NetworkLockTimeout.value()); - if (lock == null) { - throw new ConcurrentOperationException("Unable to lock network " + guestNetwork.getId()); - } - - if (logger.isDebugEnabled()) { - logger.debug("Lock is acquired for network id " + lock.getId() + " as a part of router startup in " + dest); - } - - try { - - 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; - - // 1) Get deployment plan and find out the list of routers - - // dest has pod=null, for Basic Zone findOrDeployVRs for all Pods - final List destinations = new ArrayList(); - - // for basic zone, if 'dest' has pod set to null then this is network restart scenario otherwise it is a vm deployment scenario - if (routerDeploymentDefinition.isBasic() && dest.getPod() == null) { - // Find all pods in the data center with running or starting user vms - final long dcId = dest.getDataCenter().getId(); - final List pods = listByDataCenterIdVMTypeAndStates(dcId, VirtualMachine.Type.User, VirtualMachine.State.Starting, VirtualMachine.State.Running); - - // Loop through all the pods skip those with running or starting VRs - for (final HostPodVO pod : pods) { - // Get list of VRs in starting or running state - final long podId = pod.getId(); - final List virtualRouters = _routerDao.listByPodIdAndStates(podId, VirtualMachine.State.Starting, VirtualMachine.State.Running); - - assert (virtualRouters.size() <= 1) : "Pod can have utmost one VR in Basic Zone, please check!"; - - // Add virtualRouters to the routers, this avoids the situation when - // all routers are skipped and VirtualRouterElement throws exception - routers.addAll(virtualRouters); - - // If List size is one, we already have a starting or running VR, skip deployment - if (virtualRouters.size() == 1) { - logger.debug("Skipping VR deployment: Found a running or starting VR in Pod " + pod.getName() + " id=" + podId); - continue; - } - // Add new DeployDestination for this pod - destinations.add(new DeployDestination(dest.getDataCenter(), pod, null, null)); - } - } else { - // Else, just add the supplied dest - destinations.add(dest); - } - - // Except for Basic Zone, the for loop will iterate only once - for (final DeployDestination destination : destinations) { - routerDeploymentDefinition.setDest(destination); - planDeploymentRouters(routerDeploymentDefinition); - routers = routerDeploymentDefinition.getRouters(); - - // 2) Figure out required routers count - int routerCount = 1; - if (routerDeploymentDefinition.isRedundant()) { - routerCount = 2; - //Check current redundant routers, if possible(all routers are stopped), reset the priority - if (routers.size() != 0) { - checkAndResetPriorityOfRedundantRouter(routers); - } - } - - // If old network is redundant but new is single router, then routers.size() = 2 but routerCount = 1 - if (routers.size() >= routerCount) { - return; - } - - if (routers.size() >= 5) { - logger.error("Too much redundant routers!"); - } - - // Check if providers are supported in the physical networks - final Type type = Type.VirtualRouter; - final Long physicalNetworkId = _networkModel.getPhysicalNetworkId(guestNetwork); - final PhysicalNetworkServiceProvider provider = _physicalProviderDao.findByServiceProvider(physicalNetworkId, type.toString()); - if (provider == null) { - throw new CloudRuntimeException("Cannot find service provider " + type.toString() + " in physical network " + physicalNetworkId); - } - final 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 (_networkModel.isNetworkSystem(guestNetwork) || guestNetwork.getGuestType() == Network.GuestType.Shared) { - routerDeploymentDefinition.setOwner(_accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM)); - } - - // Check if public network has to be set on VR - boolean publicNetwork = false; - if (_networkModel.isProviderSupportServiceInNetwork(guestNetwork.getId(), Service.SourceNat, Provider.VirtualRouter)) { - publicNetwork = true; - } - if (routerDeploymentDefinition.isRedundant() && !publicNetwork) { - logger.error("Didn't support redundant virtual router without public network!"); - routerDeploymentDefinition.setRouters(null); - return; - } - - Long offeringId = _networkOfferingDao.findById(guestNetwork.getNetworkOfferingId()).getServiceOfferingId(); - if (offeringId == null) { - offeringId = getOfferingId(); - } - - PublicIp sourceNatIp = null; - if (publicNetwork) { - sourceNatIp = _ipAddrMgr.assignSourceNatIpAddressToGuestNetwork( - routerDeploymentDefinition.getOwner(), guestNetwork); - } - - // 3) deploy virtual router(s) - final int count = routerCount - routers.size(); - for (int i = 0; i < count; i++) { - LinkedHashMap> networks = - createRouterNetworks(routerDeploymentDefinition, new Pair( - publicNetwork, sourceNatIp)); - //don't start the router as we are holding the network lock that needs to be released at the end of router allocation - DomainRouterVO router = nwHelper.deployRouter(routerDeploymentDefinition, vrProvider, offeringId, networks, false, null); - - if (router != null) { - _routerDao.addRouterToGuestNetwork(router, guestNetwork); - routers.add(router); - } - } - } - } finally { - if (lock != null) { - _networkDao.releaseFromLockTable(lock.getId()); - if (logger.isDebugEnabled()) { - logger.debug("Lock is released for network id " + lock.getId() + " as a part of router startup in " + dest); - } - } - } - } - - protected List listByDataCenterIdVMTypeAndStates(final long id, final VirtualMachine.Type type, final VirtualMachine.State... states) { - final SearchBuilder vmInstanceSearch = _vmDao.createSearchBuilder(); - vmInstanceSearch.and("type", vmInstanceSearch.entity().getType(), SearchCriteria.Op.EQ); - vmInstanceSearch.and("states", vmInstanceSearch.entity().getState(), SearchCriteria.Op.IN); - - final SearchBuilder podIdSearch = _podDao.createSearchBuilder(); - podIdSearch.and("dc", podIdSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); - podIdSearch.select(null, SearchCriteria.Func.DISTINCT, podIdSearch.entity().getId()); - podIdSearch.join("vmInstanceSearch", vmInstanceSearch, podIdSearch.entity().getId(), vmInstanceSearch.entity().getPodIdToDeployIn(), JoinBuilder.JoinType.INNER); - podIdSearch.done(); - - final SearchCriteria sc = podIdSearch.create(); - sc.setParameters("dc", id); - sc.setJoinParameters("vmInstanceSearch", "type", type); - sc.setJoinParameters("vmInstanceSearch", "states", (Object[])states); - return _podDao.search(sc, null); - } - - protected LinkedHashMap> createRouterNetworks(final RouterDeploymentDefinition routerDeploymentDefinition, - final Pair publicNetwork) throws ConcurrentOperationException, InsufficientAddressCapacityException { - - final Network guestNetwork = routerDeploymentDefinition.getGuestNetwork(); - boolean setupPublicNetwork = false; - if (publicNetwork != null) { - setupPublicNetwork = publicNetwork.first(); - } - - //Form networks - LinkedHashMap> networks = new LinkedHashMap>(3); - //1) Guest network - boolean hasGuestNetwork = false; - if (guestNetwork != null) { - logger.debug("Adding nic for Virtual Router in Guest network " + guestNetwork); - String defaultNetworkStartIp = null, defaultNetworkStartIpv6 = null; - if (!setupPublicNetwork) { - final Nic placeholder = _networkModel.getPlaceholderNicForRouter(guestNetwork, routerDeploymentDefinition.getPodId()); - if (guestNetwork.getCidr() != null) { - if (placeholder != null && placeholder.getIp4Address() != null) { - logger.debug("Requesting ipv4 address " + placeholder.getIp4Address() + " stored in placeholder nic for the network " + guestNetwork); - defaultNetworkStartIp = placeholder.getIp4Address(); - } else { - final String startIp = _networkModel.getStartIpAddress(guestNetwork.getId()); - if (startIp != null && _ipAddressDao.findByIpAndSourceNetworkId(guestNetwork.getId(), startIp).getAllocatedTime() == null) { - defaultNetworkStartIp = startIp; - } else if (logger.isDebugEnabled()) { - logger.debug("First ipv4 " + startIp + " in network id=" + guestNetwork.getId() + - " is already allocated, can't use it for domain router; will get random ip address from the range"); - } - } - } - - if (guestNetwork.getIp6Cidr() != null) { - if (placeholder != null && placeholder.getIp6Address() != null) { - logger.debug("Requesting ipv6 address " + placeholder.getIp6Address() + " stored in placeholder nic for the network " + guestNetwork); - defaultNetworkStartIpv6 = placeholder.getIp6Address(); - } else { - final String startIpv6 = _networkModel.getStartIpv6Address(guestNetwork.getId()); - if (startIpv6 != null && _ipv6Dao.findByNetworkIdAndIp(guestNetwork.getId(), startIpv6) == null) { - defaultNetworkStartIpv6 = startIpv6; - } else if (logger.isDebugEnabled()) { - logger.debug("First ipv6 " + startIpv6 + " in network id=" + guestNetwork.getId() + - " is already allocated, can't use it for domain router; will get random ipv6 address from the range"); - } - } - } - } - - final NicProfile gatewayNic = new NicProfile(defaultNetworkStartIp, defaultNetworkStartIpv6); - if (setupPublicNetwork) { - if (routerDeploymentDefinition.isRedundant()) { - gatewayNic.setIp4Address(_ipAddrMgr.acquireGuestIpAddress(guestNetwork, null)); - } else { - gatewayNic.setIp4Address(guestNetwork.getGateway()); - } - gatewayNic.setBroadcastUri(guestNetwork.getBroadcastUri()); - gatewayNic.setBroadcastType(guestNetwork.getBroadcastDomainType()); - gatewayNic.setIsolationUri(guestNetwork.getBroadcastUri()); - gatewayNic.setMode(guestNetwork.getMode()); - final String gatewayCidr = guestNetwork.getCidr(); - gatewayNic.setNetmask(NetUtils.getCidrNetmask(gatewayCidr)); - } else { - gatewayNic.setDefaultNic(true); - } - - networks.put(guestNetwork, new ArrayList(Arrays.asList(gatewayNic))); - hasGuestNetwork = true; - } - - //2) Control network - logger.debug("Adding nic for Virtual Router in Control network "); - List offerings = _networkModel.getSystemAccountNetworkOfferings(NetworkOffering.SystemControlNetwork); - NetworkOffering controlOffering = offerings.get(0); - Network controlConfig = _networkMgr.setupNetwork(VirtualNwStatus.account, controlOffering, routerDeploymentDefinition.getPlan(), - null, null, false).get(0); - networks.put(controlConfig, new ArrayList()); - //3) Public network - if (setupPublicNetwork) { - final PublicIp sourceNatIp = publicNetwork.second(); - 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 - final NicProfile defaultNic = new NicProfile(); - defaultNic.setDefaultNic(true); - defaultNic.setIp4Address(sourceNatIp.getAddress().addr()); - defaultNic.setGateway(sourceNatIp.getGateway()); - defaultNic.setNetmask(sourceNatIp.getNetmask()); - defaultNic.setMacAddress(sourceNatIp.getMacAddress()); - // get broadcast from public network - final Network pubNet = _networkDao.findById(sourceNatIp.getNetworkId()); - if (pubNet.getBroadcastDomainType() == BroadcastDomainType.Vxlan) { - defaultNic.setBroadcastType(BroadcastDomainType.Vxlan); - defaultNic.setBroadcastUri(BroadcastDomainType.Vxlan.toUri(sourceNatIp.getVlanTag())); - defaultNic.setIsolationUri(BroadcastDomainType.Vxlan.toUri(sourceNatIp.getVlanTag())); - } else { - defaultNic.setBroadcastType(BroadcastDomainType.Vlan); - defaultNic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(sourceNatIp.getVlanTag())); - defaultNic.setIsolationUri(IsolationType.Vlan.toUri(sourceNatIp.getVlanTag())); - } - if (hasGuestNetwork) { - defaultNic.setDeviceId(2); - } - final NetworkOffering publicOffering = _networkModel.getSystemAccountNetworkOfferings(NetworkOffering.SystemPublicNetwork).get(0); - final List publicNetworks = _networkMgr.setupNetwork(VirtualNwStatus.account, publicOffering, - routerDeploymentDefinition.getPlan(), null, null, false); - final String publicIp = defaultNic.getIp4Address(); - // We want to use the identical MAC address for RvR on public interface if possible - final NicVO peerNic = _nicDao.findByIp4AddressAndNetworkId(publicIp, publicNetworks.get(0).getId()); - if (peerNic != null) { - logger.info("Use same MAC as previous RvR, the MAC is " + peerNic.getMacAddress()); - defaultNic.setMacAddress(peerNic.getMacAddress()); - } - networks.put(publicNetworks.get(0), new ArrayList(Arrays.asList(defaultNic))); - } - - return networks; - } - - /** - * Originally a NON Vpc specific method - * - * @param isPodBased - * @param dest - * @param guestNetworkId - * @return - */ - protected void planDeploymentRouters(final RouterDeploymentDefinition routerDeploymentDefinition) { - List routers = null; - if (routerDeploymentDefinition.getVpc() != null) { - routers = vpcHelper.getVpcRouters(routerDeploymentDefinition.getVpc().getId()); - } else if (routerDeploymentDefinition.isBasic()) { - routers = _routerDao.listByNetworkAndPodAndRole(routerDeploymentDefinition.getGuestNetwork().getId(), - routerDeploymentDefinition.getPodId(), Role.VIRTUAL_ROUTER); - } else { - routers = _routerDao.listByNetworkAndRole(routerDeploymentDefinition.getGuestNetwork().getId(), - Role.VIRTUAL_ROUTER); - } - - routerDeploymentDefinition.setRouters(routers); - routerDeploymentDefinition.planDeployment(); - } - - private void checkAndResetPriorityOfRedundantRouter(final List routers) { - boolean allStopped = true; - for (final DomainRouterVO router : routers) { - if (!router.getIsRedundantRouter() || router.getState() != VirtualMachine.State.Stopped) { - allStopped = false; - break; - } - } - if (!allStopped) { - return; - } - - for (final DomainRouterVO router : routers) { - // getUpdatedPriority() would update the value later - router.setPriority(0); - router.setIsPriorityBumpUp(false); - _routerDao.update(router.getId(), router); - } - } - - /////////////////////////////////////////////////////////////////////// - // VPC Specific behavior - /////////////////////////////////////////////////////////////////////// - - protected List deployVirtualRouterInVpc(final RouterDeploymentDefinition routerDeploymentDefinition) - throws InsufficientCapacityException, - ConcurrentOperationException, ResourceUnavailableException { - - findOrDeployVirtualRouterInVpc(routerDeploymentDefinition); - - return nwHelper.startRouters(routerDeploymentDefinition); - } - - @DB - protected void findOrDeployVirtualRouterInVpc(final RouterDeploymentDefinition routerDeploymentDefinition) - throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { - - final Vpc vpc = routerDeploymentDefinition.getVpc(); - logger.debug("Deploying Virtual Router in VPC " + vpc); - - 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 - planDeploymentRouters(routerDeploymentDefinition); - - // The plan & router should have been injected into the routerDeplymentDefinition in the previous method - //DeploymentPlan plan = planAndRouters.first(); - // List routers = planAndRouters.second(); - - //2) Return routers if exist, otherwise... - if (routerDeploymentDefinition.getRouters().size() < 1) { - try { - - Long offeringId = vpcOffDao.findById(vpc.getVpcOfferingId()).getServiceOfferingId(); - if (offeringId == null) { - offeringId = offering.getId(); - } - //3) Deploy Virtual Router - List pNtwks = pNtwkDao.listByZone(vpc.getZoneId()); - - VirtualRouterProvider vpcVrProvider = null; - - for (PhysicalNetwork pNtwk : pNtwks) { - PhysicalNetworkServiceProvider provider = physicalProviderDao.findByServiceProvider(pNtwk.getId(), Type.VPCVirtualRouter.toString()); - if (provider == null) { - throw new CloudRuntimeException("Cannot find service provider " + Type.VPCVirtualRouter.toString() + " in physical network " + pNtwk.getId()); - } - vpcVrProvider = vrProviderDao.findByNspIdAndType(provider.getId(), Type.VPCVirtualRouter); - if (vpcVrProvider != null) { - break; - } - } - - PublicIp sourceNatIp = vpcMgr.assignSourceNatIpAddressToVpc(routerDeploymentDefinition.getOwner(), vpc); - - DomainRouterVO router = deployVpcRouter(routerDeploymentDefinition, vpcVrProvider, offeringId, sourceNatIp); - routerDeploymentDefinition.getRouters().add(router); - - } finally { - // TODO Should we do this after the pre or after the whole?? - if (vpcLock != null) { - vpcDao.releaseFromLockTable(vpc.getId()); - } - } - } - } - - protected DomainRouterVO deployVpcRouter(final RouterDeploymentDefinition routerDeploymentDefinition, final VirtualRouterProvider vrProvider, - final long svcOffId, final PublicIp sourceNatIp) throws ConcurrentOperationException, InsufficientAddressCapacityException, - InsufficientServerCapacityException, InsufficientCapacityException, StorageUnavailableException, ResourceUnavailableException { - - LinkedHashMap> networks = createVpcRouterNetworks(routerDeploymentDefinition, - new Pair(true, sourceNatIp), routerDeploymentDefinition.getVpc().getId()); - - DomainRouterVO router = - nwHelper.deployRouter(routerDeploymentDefinition, vrProvider, svcOffId, networks, true, vpcMgr.getSupportedVpcHypervisors()); - - return router; - } - - protected LinkedHashMap> createVpcRouterNetworks(final RouterDeploymentDefinition routerDeploymentDefinition, - final Pair sourceNatIp, final long vpcId) - throws ConcurrentOperationException, InsufficientAddressCapacityException { - - LinkedHashMap> networks = new LinkedHashMap>(4); - - TreeSet publicVlans = new TreeSet(); - publicVlans.add(sourceNatIp.second().getVlanTag()); - - //1) allocate nic for control and source nat public ip - networks = nwHelper.createRouterNetworks(routerDeploymentDefinition, null, sourceNatIp); - - - //2) allocate nic for private gateways if needed - List privateGateways = vpcMgr.getVpcPrivateGateways(vpcId); - if (privateGateways != null && !privateGateways.isEmpty()) { - for (PrivateGateway privateGateway : privateGateways) { - NicProfile privateNic = vpcHelper.createPrivateNicProfileForGateway(privateGateway); - Network privateNetwork = networkModel.getNetwork(privateGateway.getNetworkId()); - networks.put(privateNetwork, new ArrayList(Arrays.asList(privateNic))); - } - } - - //3) allocate nic for guest gateway if needed - List guestNetworks = vpcMgr.getVpcNetworks(vpcId); - for (Network guestNetwork : guestNetworks) { - if (networkModel.isPrivateGateway(guestNetwork.getId())) { - continue; - } - if (guestNetwork.getState() == Network.State.Implemented || guestNetwork.getState() == Network.State.Setup) { - NicProfile guestNic = createGuestNicProfileForVpcRouter(guestNetwork); - networks.put(guestNetwork, new ArrayList(Arrays.asList(guestNic))); - } - } - - //4) allocate nic for additional public network(s) - List ips = ipAddressDao.listByAssociatedVpc(vpcId, false); - List publicNics = new ArrayList(); - Network publicNetwork = null; - for (IPAddressVO ip : ips) { - PublicIp publicIp = PublicIp.createFromAddrAndVlan(ip, vlanDao.findById(ip.getVlanId())); - if ((ip.getState() == IpAddress.State.Allocated || ip.getState() == IpAddress.State.Allocating) && vpcMgr.isIpAllocatedToVpc(ip) && - !publicVlans.contains(publicIp.getVlanTag())) { - logger.debug("Allocating nic for router in vlan " + publicIp.getVlanTag()); - NicProfile publicNic = new NicProfile(); - publicNic.setDefaultNic(false); - publicNic.setIp4Address(publicIp.getAddress().addr()); - publicNic.setGateway(publicIp.getGateway()); - publicNic.setNetmask(publicIp.getNetmask()); - publicNic.setMacAddress(publicIp.getMacAddress()); - publicNic.setBroadcastType(BroadcastDomainType.Vlan); - publicNic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(publicIp.getVlanTag())); - publicNic.setIsolationUri(IsolationType.Vlan.toUri(publicIp.getVlanTag())); - NetworkOffering publicOffering = networkModel.getSystemAccountNetworkOfferings(NetworkOffering.SystemPublicNetwork).get(0); - if (publicNetwork == null) { - List publicNetworks = networkMgr.setupNetwork(VirtualNwStatus.account, - publicOffering, routerDeploymentDefinition.getPlan(), null, null, false); - publicNetwork = publicNetworks.get(0); - } - publicNics.add(publicNic); - publicVlans.add(publicIp.getVlanTag()); - } - } - if (publicNetwork != null) { - if (networks.get(publicNetwork) != null) { - List publicNicProfiles = (List)networks.get(publicNetwork); - publicNicProfiles.addAll(publicNics); - networks.put(publicNetwork, publicNicProfiles); - } else { - networks.put(publicNetwork, publicNics); - } - } - - return networks; - } - - protected NicProfile createGuestNicProfileForVpcRouter(final Network guestNetwork) { - NicProfile guestNic = new NicProfile(); - guestNic.setIp4Address(guestNetwork.getGateway()); - guestNic.setBroadcastUri(guestNetwork.getBroadcastUri()); - guestNic.setBroadcastType(guestNetwork.getBroadcastDomainType()); - guestNic.setIsolationUri(guestNetwork.getBroadcastUri()); - guestNic.setMode(guestNetwork.getMode()); - String gatewayCidr = guestNetwork.getCidr(); - guestNic.setNetmask(NetUtils.getCidrNetmask(gatewayCidr)); - - return guestNic; - } - -} diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java index f277e1aa8bb..2b9228844d9 100644 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java @@ -23,7 +23,6 @@ import org.apache.cloudstack.framework.config.ConfigKey; import com.cloud.deploy.DeployDestination; import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.ConcurrentOperationException; -import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.Network; import com.cloud.network.PublicIpAddress; @@ -97,9 +96,6 @@ public interface VirtualNetworkApplianceManager extends Manager, VirtualNetworkA boolean saveUserDataToRouter(Network network, NicProfile nic, VirtualMachineProfile profile, List routers) throws ResourceUnavailableException; - List deployVirtualRouter(RouterDeploymentDefinition routerDeploymentDefinition) - throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException; - boolean startRemoteAccessVpn(Network network, RemoteAccessVpn vpn, List routers) throws ResourceUnavailableException; boolean deleteRemoteAccessVpn(Network network, RemoteAccessVpn vpn, List routers) throws ResourceUnavailableException; diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index f3386f216b8..76cadd90877 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -192,6 +192,7 @@ import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy; import com.cloud.network.lb.LoadBalancingRulesManager; import com.cloud.network.router.VirtualRouter.RedundantState; import com.cloud.network.router.VirtualRouter.Role; +import com.cloud.network.router.deployment.RouterDeploymentDefinitionBuilder; import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.FirewallRule.Purpose; import com.cloud.network.rules.FirewallRuleVO; @@ -392,7 +393,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V @Inject protected NetworkGeneralHelper nwHelper; @Inject - protected RouterDeploymentManager routerDeploymentManager; + protected RouterDeploymentDefinitionBuilder routerDeploymentManagerBuilder; int _routerRamSize; int _routerCpuMHz; @@ -726,7 +727,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V useLocalStorage, true, null, true, VirtualMachine.Type.DomainRouter, true); offering.setUniqueName(ServiceOffering.routerDefaultOffUniqueName); offering = _serviceOfferingDao.persistSystemServiceOffering(offering); - routerDeploymentManager.setOffering(offering); + routerDeploymentManagerBuilder.setOffering(offering); // this can sometimes happen, if DB is manually or programmatically // manipulated @@ -1506,13 +1507,6 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V return priority; } - @Override - public List deployVirtualRouter(final RouterDeploymentDefinition routerDeploymentDefinition) throws InsufficientCapacityException, - ConcurrentOperationException, ResourceUnavailableException { - - return routerDeploymentManager.deployVirtualRouter(routerDeploymentDefinition); - } - @Override public boolean finalizeVirtualMachineProfile(final VirtualMachineProfile profile, final DeployDestination dest, final ReservationContext context) { diff --git a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java index 40c64cbdfe7..86d2a8afda0 100644 --- a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java @@ -61,7 +61,6 @@ import com.cloud.network.IpAddress; import com.cloud.network.Network; import com.cloud.network.Network.Provider; import com.cloud.network.Network.Service; -import com.cloud.network.NetworkService; import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.IsolationType; import com.cloud.network.Networks.TrafficType; @@ -72,14 +71,9 @@ import com.cloud.network.VirtualRouterProvider; import com.cloud.network.VpcVirtualNetworkApplianceService; import com.cloud.network.VpnUser; import com.cloud.network.addr.PublicIp; -import com.cloud.network.dao.FirewallRulesDao; -import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.IPAddressVO; -import com.cloud.network.dao.PhysicalNetworkDao; import com.cloud.network.dao.RemoteAccessVpnVO; import com.cloud.network.dao.Site2SiteCustomerGatewayVO; -import com.cloud.network.dao.Site2SiteVpnConnectionDao; -import com.cloud.network.dao.Site2SiteVpnGatewayDao; import com.cloud.network.dao.Site2SiteVpnGatewayVO; import com.cloud.network.vpc.NetworkACLItem; import com.cloud.network.vpc.NetworkACLItemDao; @@ -98,7 +92,6 @@ import com.cloud.network.vpc.dao.PrivateIpDao; import com.cloud.network.vpc.dao.StaticRouteDao; import com.cloud.network.vpc.dao.VpcDao; import com.cloud.network.vpc.dao.VpcGatewayDao; -import com.cloud.network.vpc.dao.VpcOfferingDao; import com.cloud.network.vpn.Site2SiteVpnManager; import com.cloud.user.Account; import com.cloud.user.UserStatisticsVO; @@ -121,50 +114,30 @@ import com.cloud.vm.dao.VMInstanceDao; @Local(value = {VpcVirtualNetworkApplianceManager.class, VpcVirtualNetworkApplianceService.class}) public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplianceManagerImpl implements VpcVirtualNetworkApplianceManager { private static final Logger s_logger = Logger.getLogger(VpcVirtualNetworkApplianceManagerImpl.class); - String _name; - @Inject - VpcDao _vpcDao; - @Inject - VpcOfferingDao _vpcOffDao; - @Inject - PhysicalNetworkDao _pNtwkDao; - @Inject - NetworkService _ntwkService; - @Inject - NetworkACLManager _networkACLMgr; - @Inject - VMInstanceDao _vmDao; - @Inject - StaticRouteDao _staticRouteDao; - @Inject - VpcManager _vpcMgr; - @Inject - PrivateIpDao _privateIpDao; - @Inject - IPAddressDao _ipAddrDao; - @Inject - Site2SiteVpnGatewayDao _vpnGatewayDao; - @Inject - Site2SiteVpnConnectionDao _vpnConnectionDao; - @Inject - FirewallRulesDao _firewallDao; - @Inject - Site2SiteVpnManager _s2sVpnMgr; - @Inject - VpcGatewayDao _vpcGatewayDao; - @Inject - NetworkACLItemDao _networkACLItemDao; - @Inject - EntityManager _entityMgr; @Inject - protected NetworkGeneralHelper nwHelper; + private VpcDao _vpcDao; + @Inject + private NetworkACLManager _networkACLMgr; + @Inject + private VMInstanceDao _vmDao; + @Inject + private StaticRouteDao _staticRouteDao; + @Inject + private VpcManager _vpcMgr; + @Inject + private PrivateIpDao _privateIpDao; + @Inject + private Site2SiteVpnManager _s2sVpnMgr; + @Inject + private VpcGatewayDao _vpcGatewayDao; + @Inject + private NetworkACLItemDao _networkACLItemDao; + @Inject + private EntityManager _entityMgr; @Inject - protected VpcVirtualNetworkHelperImpl vpcHelper; - - @Inject - protected RouterDeploymentManager routerDeploymentManager; + private VpcVirtualNetworkHelperImpl vpcHelper; @Override public boolean configure(final String name, final Map params) throws ConfigurationException { diff --git a/server/src/com/cloud/network/router/VpcVirtualNetworkHelperImpl.java b/server/src/com/cloud/network/router/VpcVirtualNetworkHelperImpl.java index 54563639d97..373ee9ff7a6 100644 --- a/server/src/com/cloud/network/router/VpcVirtualNetworkHelperImpl.java +++ b/server/src/com/cloud/network/router/VpcVirtualNetworkHelperImpl.java @@ -23,35 +23,17 @@ import java.util.List; import javax.ejb.Local; import javax.inject.Inject; -import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; import org.springframework.stereotype.Component; -import com.cloud.dc.dao.DataCenterDao; -import com.cloud.dc.dao.VlanDao; import com.cloud.network.Network; import com.cloud.network.NetworkModel; -import com.cloud.network.NetworkService; import com.cloud.network.Networks.AddressFormat; import com.cloud.network.Networks.BroadcastDomainType; -import com.cloud.network.dao.FirewallRulesDao; -import com.cloud.network.dao.IPAddressDao; -import com.cloud.network.dao.NetworkDao; -import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; -import com.cloud.network.dao.Site2SiteVpnConnectionDao; -import com.cloud.network.dao.Site2SiteVpnGatewayDao; -import com.cloud.network.dao.VirtualRouterProviderDao; -import com.cloud.network.vpc.NetworkACLItemDao; -import com.cloud.network.vpc.NetworkACLManager; import com.cloud.network.vpc.PrivateIpAddress; import com.cloud.network.vpc.PrivateIpVO; import com.cloud.network.vpc.VpcGateway; -import com.cloud.network.vpc.VpcManager; import com.cloud.network.vpc.dao.PrivateIpDao; -import com.cloud.network.vpc.dao.StaticRouteDao; -import com.cloud.network.vpc.dao.VpcGatewayDao; -import com.cloud.server.ConfigurationServer; import com.cloud.utils.db.DB; -import com.cloud.utils.db.EntityManager; import com.cloud.utils.net.NetUtils; import com.cloud.vm.DomainRouterVO; import com.cloud.vm.Nic; @@ -67,55 +49,15 @@ import com.cloud.vm.dao.VMInstanceDao; @Local(value = {VpcVirtualNetworkHelperImpl.class}) public class VpcVirtualNetworkHelperImpl { - String _name; @Inject - NetworkService _ntwkService; + private VMInstanceDao _vmDao; + private PrivateIpDao _privateIpDao; @Inject - NetworkACLManager _networkACLMgr; + private DomainRouterDao _routerDao; @Inject - VMInstanceDao _vmDao; + private NetworkModel _networkModel; @Inject - StaticRouteDao _staticRouteDao; - @Inject - VpcManager _vpcMgr; - @Inject - PrivateIpDao _privateIpDao; - @Inject - Site2SiteVpnGatewayDao _vpnGatewayDao; - @Inject - Site2SiteVpnConnectionDao _vpnConnectionDao; - @Inject - FirewallRulesDao _firewallDao; - @Inject - VpcGatewayDao _vpcGatewayDao; - @Inject - NetworkACLItemDao _networkACLItemDao; - @Inject - EntityManager _entityMgr; - @Inject - PhysicalNetworkServiceProviderDao _physicalProviderDao; - @Inject - DataCenterDao _dcDao; - @Inject - VlanDao _vlanDao; - @Inject - FirewallRulesDao _rulesDao; - @Inject - IPAddressDao _ipAddressDao; - @Inject - DomainRouterDao _routerDao; - @Inject - ConfigurationServer _configServer; - @Inject - NetworkOrchestrationService _networkMgr; - @Inject - NetworkModel _networkModel; - @Inject - NetworkDao _networkDao; - @Inject - NicDao _nicDao; - @Inject - VirtualRouterProviderDao _vrProviderDao; + private NicDao _nicDao; protected NetworkGeneralHelper nwHelper = new NetworkGeneralHelper(); @@ -163,4 +105,17 @@ public class VpcVirtualNetworkHelperImpl { return privateNicProfile; } + public NicProfile createGuestNicProfileForVpcRouter(final Network guestNetwork) { + NicProfile guestNic = new NicProfile(); + guestNic.setIp4Address(guestNetwork.getGateway()); + guestNic.setBroadcastUri(guestNetwork.getBroadcastUri()); + guestNic.setBroadcastType(guestNetwork.getBroadcastDomainType()); + guestNic.setIsolationUri(guestNetwork.getBroadcastUri()); + guestNic.setMode(guestNetwork.getMode()); + String gatewayCidr = guestNetwork.getCidr(); + guestNic.setNetmask(NetUtils.getCidrNetmask(gatewayCidr)); + + return guestNic; + } + } diff --git a/server/src/com/cloud/network/router/deployment/RouterDeploymentDefinition.java b/server/src/com/cloud/network/router/deployment/RouterDeploymentDefinition.java new file mode 100644 index 00000000000..5d740a4c5a9 --- /dev/null +++ b/server/src/com/cloud/network/router/deployment/RouterDeploymentDefinition.java @@ -0,0 +1,530 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.network.router.deployment; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import javax.inject.Inject; + +import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; +import org.apache.log4j.Logger; + +import com.cloud.dc.DataCenter.NetworkType; +import com.cloud.dc.HostPodVO; +import com.cloud.dc.Pod; +import com.cloud.dc.dao.HostPodDao; +import com.cloud.deploy.DataCenterDeployment; +import com.cloud.deploy.DeployDestination; +import com.cloud.deploy.DeploymentPlan; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientAddressCapacityException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.IpAddressManager; +import com.cloud.network.Network; +import com.cloud.network.Network.Provider; +import com.cloud.network.Network.Service; +import com.cloud.network.NetworkModel; +import com.cloud.network.Networks.BroadcastDomainType; +import com.cloud.network.Networks.IsolationType; +import com.cloud.network.Networks.TrafficType; +import com.cloud.network.PhysicalNetworkServiceProvider; +import com.cloud.network.VirtualRouterProvider; +import com.cloud.network.VirtualRouterProvider.Type; +import com.cloud.network.addr.PublicIp; +import com.cloud.network.dao.IPAddressDao; +import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; +import com.cloud.network.dao.UserIpv6AddressDao; +import com.cloud.network.dao.VirtualRouterProviderDao; +import com.cloud.network.router.NetworkGeneralHelper; +import com.cloud.network.router.VirtualNwStatus; +import com.cloud.network.router.VirtualRouter.Role; +import com.cloud.network.router.VpcVirtualNetworkHelperImpl; +import com.cloud.network.vpc.Vpc; +import com.cloud.offering.NetworkOffering; +import com.cloud.offerings.dao.NetworkOfferingDao; +import com.cloud.service.ServiceOfferingVO; +import com.cloud.user.Account; +import com.cloud.user.AccountManager; +import com.cloud.utils.Pair; +import com.cloud.utils.db.DB; +import com.cloud.utils.db.JoinBuilder; +import com.cloud.utils.db.SearchBuilder; +import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.net.NetUtils; +import com.cloud.vm.DomainRouterVO; +import com.cloud.vm.Nic; +import com.cloud.vm.NicProfile; +import com.cloud.vm.NicVO; +import com.cloud.vm.VMInstanceVO; +import com.cloud.vm.VirtualMachine; +import com.cloud.vm.VirtualMachineProfile.Param; +import com.cloud.vm.dao.DomainRouterDao; +import com.cloud.vm.dao.NicDao; +import com.cloud.vm.dao.VMInstanceDao; + +public class RouterDeploymentDefinition { + private static final Logger logger = Logger.getLogger(RouterDeploymentDefinition.class); + + protected NetworkDao networkDao; + protected DomainRouterDao routerDao; + protected PhysicalNetworkServiceProviderDao physicalProviderDao; + protected NetworkModel networkModel; + protected VirtualRouterProviderDao vrProviderDao; + protected NetworkOfferingDao networkOfferingDao; + protected IpAddressManager ipAddrMgr; + protected VMInstanceDao vmDao; + protected HostPodDao podDao; + protected AccountManager accountMgr; + protected NetworkOrchestrationService networkMgr; + protected NicDao nicDao; + protected UserIpv6AddressDao ipv6Dao; + protected IPAddressDao ipAddressDao; + + + @Inject + protected NetworkGeneralHelper nwHelper; + @Inject + protected VpcVirtualNetworkHelperImpl vpcHelper; + + + protected Network guestNetwork; + protected DeployDestination dest; + protected Account owner; + protected Map params; + protected boolean isRedundant; + protected DeploymentPlan plan; + protected List routers = new ArrayList<>(); + protected ServiceOfferingVO offering; + + + + + protected RouterDeploymentDefinition(final Network guestNetwork, final DeployDestination dest, + final Account owner, final Map params, final boolean isRedundant) { + + this.guestNetwork = guestNetwork; + this.dest = dest; + this.owner = owner; + this.params = params; + this.isRedundant = isRedundant; + } + + public void setOffering(ServiceOfferingVO offering) { + this.offering = offering; + } + public Vpc getVpc() { + return null; + } + public Network getGuestNetwork() { + return guestNetwork; + } + public void setGuestNetwork(final Network guestNetwork) { + this.guestNetwork = guestNetwork; + } + public DeployDestination getDest() { + return dest; + } + public void setDest(final DeployDestination dest) { + this.dest = dest; + } + public Account getOwner() { + return owner; + } + public void setOwner(final Account owner) { + this.owner = owner; + } + public Map getParams() { + return params; + } + public void setParams(final Map params) { + this.params = params; + } + public boolean isRedundant() { + return isRedundant; + } + public void setRedundant(final boolean isRedundant) { + this.isRedundant = isRedundant; + } + public DeploymentPlan getPlan() { + return plan; + } + + public boolean isVpcRouter() { + return false; + } + public Pod getPod() { + return dest.getPod(); + } + public Long getPodId() { + return dest.getPod().getId(); + } + + public List getRouters() { + return routers; + } + public void setRouters(List routers) { + this.routers = routers; + } + + public boolean isBasic() { + return this.dest.getDataCenter().getNetworkType() == NetworkType.Basic; + } + + public Long getOfferingId() { + return offering == null ? null : offering.getId(); + } + + public void generateDeploymentPlan() { + final long dcId = this.dest.getDataCenter().getId(); + Long podId = null; + if (this.isBasic()) { + if (this.dest.getPod() == null) { + throw new CloudRuntimeException("Pod id is expected in deployment destination"); + } + podId = this.dest.getPod().getId(); + } + this.plan = new DataCenterDeployment(dcId, podId, null, null, null, null); + } + + + public List deployVirtualRouter() + throws InsufficientCapacityException, + ConcurrentOperationException, ResourceUnavailableException { + + findOrDeployVirtualRouter(); + + return nwHelper.startRouters(this); + } + + @DB + protected void findOrDeployVirtualRouter() + throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { + + final Network lock = networkDao.acquireInLockTable(guestNetwork.getId(), NetworkOrchestrationService.NetworkLockTimeout.value()); + if (lock == null) { + throw new ConcurrentOperationException("Unable to lock network " + guestNetwork.getId()); + } + + if (logger.isDebugEnabled()) { + logger.debug("Lock is acquired for network id " + lock.getId() + " as a part of router startup in " + dest); + } + + try { + + 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; + + // 1) Get deployment plan and find out the list of routers + + // dest has pod=null, for Basic Zone findOrDeployVRs for all Pods + final List destinations = new ArrayList(); + + // for basic zone, if 'dest' has pod set to null then this is network restart scenario otherwise it is a vm deployment scenario + if (this.isBasic() && dest.getPod() == null) { + // Find all pods in the data center with running or starting user vms + final long dcId = dest.getDataCenter().getId(); + final List pods = listByDataCenterIdVMTypeAndStates(dcId, VirtualMachine.Type.User, VirtualMachine.State.Starting, VirtualMachine.State.Running); + + // Loop through all the pods skip those with running or starting VRs + for (final HostPodVO pod : pods) { + // Get list of VRs in starting or running state + final long podId = pod.getId(); + final List virtualRouters = routerDao.listByPodIdAndStates(podId, VirtualMachine.State.Starting, VirtualMachine.State.Running); + + assert (virtualRouters.size() <= 1) : "Pod can have utmost one VR in Basic Zone, please check!"; + + // Add virtualRouters to the routers, this avoids the situation when + // all routers are skipped and VirtualRouterElement throws exception + this.routers.addAll(virtualRouters); + + // If List size is one, we already have a starting or running VR, skip deployment + if (virtualRouters.size() == 1) { + logger.debug("Skipping VR deployment: Found a running or starting VR in Pod " + pod.getName() + " id=" + podId); + continue; + } + // Add new DeployDestination for this pod + destinations.add(new DeployDestination(dest.getDataCenter(), pod, null, null)); + } + } else { + // Else, just add the supplied dest + destinations.add(dest); + } + + // Except for Basic Zone, the for loop will iterate only once + for (final DeployDestination destination : destinations) { + this.dest = destination; + planDeploymentRouters(); + this.generateDeploymentPlan(); + + // 2) Figure out required routers count + int routerCount = 1; + if (this.isRedundant) { + routerCount = 2; + //Check current redundant routers, if possible(all routers are stopped), reset the priority + if (this.routers.size() != 0) { + checkAndResetPriorityOfRedundantRouter(this.routers); + } + } + + // If old network is redundant but new is single router, then routers.size() = 2 but routerCount = 1 + if (this.routers.size() >= routerCount) { + return; + } + + if (this.routers.size() >= 5) { + logger.error("Too much redundant routers!"); + } + + // Check if providers are supported in the physical networks + final Type type = Type.VirtualRouter; + final Long physicalNetworkId = networkModel.getPhysicalNetworkId(guestNetwork); + final PhysicalNetworkServiceProvider provider = physicalProviderDao.findByServiceProvider(physicalNetworkId, type.toString()); + if (provider == null) { + throw new CloudRuntimeException("Cannot find service provider " + type.toString() + " in physical network " + physicalNetworkId); + } + final 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 (networkModel.isNetworkSystem(guestNetwork) || guestNetwork.getGuestType() == Network.GuestType.Shared) { + this.owner = accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM); + } + + // Check if public network has to be set on VR + boolean publicNetwork = false; + if (networkModel.isProviderSupportServiceInNetwork(guestNetwork.getId(), Service.SourceNat, Provider.VirtualRouter)) { + publicNetwork = true; + } + if (this.isRedundant && !publicNetwork) { + logger.error("Didn't support redundant virtual router without public network!"); + this.routers = null; + return; + } + + Long offeringId = networkOfferingDao.findById(guestNetwork.getNetworkOfferingId()).getServiceOfferingId(); + if (offeringId == null) { + offeringId = getOfferingId(); + } + + PublicIp sourceNatIp = null; + if (publicNetwork) { + sourceNatIp = ipAddrMgr.assignSourceNatIpAddressToGuestNetwork( + this.owner, guestNetwork); + } + + // 3) deploy virtual router(s) + final int count = routerCount - this.routers.size(); + for (int i = 0; i < count; i++) { + LinkedHashMap> networks = + createRouterNetworks(new Pair( + publicNetwork, sourceNatIp)); + //don't start the router as we are holding the network lock that needs to be released at the end of router allocation + DomainRouterVO router = nwHelper.deployRouter(this, vrProvider, offeringId, networks, false, null); + + if (router != null) { + routerDao.addRouterToGuestNetwork(router, guestNetwork); + this.routers.add(router); + } + } + } + } finally { + if (lock != null) { + networkDao.releaseFromLockTable(lock.getId()); + if (logger.isDebugEnabled()) { + logger.debug("Lock is released for network id " + lock.getId() + " as a part of router startup in " + dest); + } + } + } + } + + + protected List listByDataCenterIdVMTypeAndStates(final long id, final VirtualMachine.Type type, final VirtualMachine.State... states) { + final SearchBuilder vmInstanceSearch = vmDao.createSearchBuilder(); + vmInstanceSearch.and("type", vmInstanceSearch.entity().getType(), SearchCriteria.Op.EQ); + vmInstanceSearch.and("states", vmInstanceSearch.entity().getState(), SearchCriteria.Op.IN); + + final SearchBuilder podIdSearch = podDao.createSearchBuilder(); + podIdSearch.and("dc", podIdSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ); + podIdSearch.select(null, SearchCriteria.Func.DISTINCT, podIdSearch.entity().getId()); + podIdSearch.join("vmInstanceSearch", vmInstanceSearch, podIdSearch.entity().getId(), vmInstanceSearch.entity().getPodIdToDeployIn(), JoinBuilder.JoinType.INNER); + podIdSearch.done(); + + final SearchCriteria sc = podIdSearch.create(); + sc.setParameters("dc", id); + sc.setJoinParameters("vmInstanceSearch", "type", type); + sc.setJoinParameters("vmInstanceSearch", "states", (Object[])states); + return podDao.search(sc, null); + } + + protected void planDeploymentRouters() { + if (this.isBasic()) { + this.routers = routerDao.listByNetworkAndPodAndRole(this.guestNetwork.getId(), + this.getPodId(), Role.VIRTUAL_ROUTER); + } else { + this.routers = routerDao.listByNetworkAndRole(this.guestNetwork.getId(), + Role.VIRTUAL_ROUTER); + } + } + + private void checkAndResetPriorityOfRedundantRouter(final List routers) { + boolean allStopped = true; + for (final DomainRouterVO router : routers) { + if (!router.getIsRedundantRouter() || router.getState() != VirtualMachine.State.Stopped) { + allStopped = false; + break; + } + } + if (!allStopped) { + return; + } + + for (final DomainRouterVO router : routers) { + // getUpdatedPriority() would update the value later + router.setPriority(0); + router.setIsPriorityBumpUp(false); + routerDao.update(router.getId(), router); + } + } + protected LinkedHashMap> createRouterNetworks( + final Pair publicNetwork) + throws ConcurrentOperationException, InsufficientAddressCapacityException { + + final Network guestNetwork = this.guestNetwork; + boolean setupPublicNetwork = false; + if (publicNetwork != null) { + setupPublicNetwork = publicNetwork.first(); + } + + //Form networks + LinkedHashMap> networks = new LinkedHashMap>(3); + //1) Guest network + boolean hasGuestNetwork = false; + if (guestNetwork != null) { + logger.debug("Adding nic for Virtual Router in Guest network " + guestNetwork); + String defaultNetworkStartIp = null, defaultNetworkStartIpv6 = null; + if (!setupPublicNetwork) { + final Nic placeholder = networkModel.getPlaceholderNicForRouter(guestNetwork, this.getPodId()); + if (guestNetwork.getCidr() != null) { + if (placeholder != null && placeholder.getIp4Address() != null) { + logger.debug("Requesting ipv4 address " + placeholder.getIp4Address() + " stored in placeholder nic for the network " + guestNetwork); + defaultNetworkStartIp = placeholder.getIp4Address(); + } else { + final String startIp = networkModel.getStartIpAddress(guestNetwork.getId()); + if (startIp != null && ipAddressDao.findByIpAndSourceNetworkId(guestNetwork.getId(), startIp).getAllocatedTime() == null) { + defaultNetworkStartIp = startIp; + } else if (logger.isDebugEnabled()) { + logger.debug("First ipv4 " + startIp + " in network id=" + guestNetwork.getId() + + " is already allocated, can't use it for domain router; will get random ip address from the range"); + } + } + } + + if (guestNetwork.getIp6Cidr() != null) { + if (placeholder != null && placeholder.getIp6Address() != null) { + logger.debug("Requesting ipv6 address " + placeholder.getIp6Address() + " stored in placeholder nic for the network " + guestNetwork); + defaultNetworkStartIpv6 = placeholder.getIp6Address(); + } else { + final String startIpv6 = networkModel.getStartIpv6Address(guestNetwork.getId()); + if (startIpv6 != null && ipv6Dao.findByNetworkIdAndIp(guestNetwork.getId(), startIpv6) == null) { + defaultNetworkStartIpv6 = startIpv6; + } else if (logger.isDebugEnabled()) { + logger.debug("First ipv6 " + startIpv6 + " in network id=" + guestNetwork.getId() + + " is already allocated, can't use it for domain router; will get random ipv6 address from the range"); + } + } + } + } + + final NicProfile gatewayNic = new NicProfile(defaultNetworkStartIp, defaultNetworkStartIpv6); + if (setupPublicNetwork) { + if (this.isRedundant) { + gatewayNic.setIp4Address(ipAddrMgr.acquireGuestIpAddress(guestNetwork, null)); + } else { + gatewayNic.setIp4Address(guestNetwork.getGateway()); + } + gatewayNic.setBroadcastUri(guestNetwork.getBroadcastUri()); + gatewayNic.setBroadcastType(guestNetwork.getBroadcastDomainType()); + gatewayNic.setIsolationUri(guestNetwork.getBroadcastUri()); + gatewayNic.setMode(guestNetwork.getMode()); + final String gatewayCidr = guestNetwork.getCidr(); + gatewayNic.setNetmask(NetUtils.getCidrNetmask(gatewayCidr)); + } else { + gatewayNic.setDefaultNic(true); + } + + networks.put(guestNetwork, new ArrayList(Arrays.asList(gatewayNic))); + hasGuestNetwork = true; + } + + //2) Control network + logger.debug("Adding nic for Virtual Router in Control network "); + List offerings = networkModel.getSystemAccountNetworkOfferings(NetworkOffering.SystemControlNetwork); + NetworkOffering controlOffering = offerings.get(0); + Network controlConfig = networkMgr.setupNetwork(VirtualNwStatus.account, controlOffering, this.plan, + null, null, false).get(0); + networks.put(controlConfig, new ArrayList()); + //3) Public network + if (setupPublicNetwork) { + final PublicIp sourceNatIp = publicNetwork.second(); + 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 + final NicProfile defaultNic = new NicProfile(); + defaultNic.setDefaultNic(true); + defaultNic.setIp4Address(sourceNatIp.getAddress().addr()); + defaultNic.setGateway(sourceNatIp.getGateway()); + defaultNic.setNetmask(sourceNatIp.getNetmask()); + defaultNic.setMacAddress(sourceNatIp.getMacAddress()); + // get broadcast from public network + final Network pubNet = networkDao.findById(sourceNatIp.getNetworkId()); + if (pubNet.getBroadcastDomainType() == BroadcastDomainType.Vxlan) { + defaultNic.setBroadcastType(BroadcastDomainType.Vxlan); + defaultNic.setBroadcastUri(BroadcastDomainType.Vxlan.toUri(sourceNatIp.getVlanTag())); + defaultNic.setIsolationUri(BroadcastDomainType.Vxlan.toUri(sourceNatIp.getVlanTag())); + } else { + defaultNic.setBroadcastType(BroadcastDomainType.Vlan); + defaultNic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(sourceNatIp.getVlanTag())); + defaultNic.setIsolationUri(IsolationType.Vlan.toUri(sourceNatIp.getVlanTag())); + } + if (hasGuestNetwork) { + defaultNic.setDeviceId(2); + } + final NetworkOffering publicOffering = networkModel.getSystemAccountNetworkOfferings(NetworkOffering.SystemPublicNetwork).get(0); + final List publicNetworks = networkMgr.setupNetwork(VirtualNwStatus.account, publicOffering, + this.plan, null, null, false); + final String publicIp = defaultNic.getIp4Address(); + // We want to use the identical MAC address for RvR on public interface if possible + final NicVO peerNic = nicDao.findByIp4AddressAndNetworkId(publicIp, publicNetworks.get(0).getId()); + if (peerNic != null) { + logger.info("Use same MAC as previous RvR, the MAC is " + peerNic.getMacAddress()); + defaultNic.setMacAddress(peerNic.getMacAddress()); + } + networks.put(publicNetworks.get(0), new ArrayList(Arrays.asList(defaultNic))); + } + + return networks; + } + +} \ No newline at end of file diff --git a/server/src/com/cloud/network/router/deployment/RouterDeploymentDefinitionBuilder.java b/server/src/com/cloud/network/router/deployment/RouterDeploymentDefinitionBuilder.java new file mode 100644 index 00000000000..f06cb4c89fd --- /dev/null +++ b/server/src/com/cloud/network/router/deployment/RouterDeploymentDefinitionBuilder.java @@ -0,0 +1,188 @@ +package com.cloud.network.router.deployment; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import javax.inject.Inject; + +import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; + +import com.cloud.dc.dao.HostPodDao; +import com.cloud.dc.dao.VlanDao; +import com.cloud.deploy.DeployDestination; +import com.cloud.network.IpAddressManager; +import com.cloud.network.Network; +import com.cloud.network.NetworkModel; +import com.cloud.network.dao.IPAddressDao; +import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.PhysicalNetworkDao; +import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; +import com.cloud.network.dao.UserIpv6AddressDao; +import com.cloud.network.dao.VirtualRouterProviderDao; +import com.cloud.network.vpc.Vpc; +import com.cloud.network.vpc.VpcManager; +import com.cloud.network.vpc.dao.VpcDao; +import com.cloud.network.vpc.dao.VpcOfferingDao; +import com.cloud.offerings.dao.NetworkOfferingDao; +import com.cloud.service.ServiceOfferingVO; +import com.cloud.user.Account; +import com.cloud.user.AccountManager; +import com.cloud.vm.DomainRouterVO; +import com.cloud.vm.VirtualMachineProfile.Param; +import com.cloud.vm.dao.DomainRouterDao; +import com.cloud.vm.dao.NicDao; +import com.cloud.vm.dao.VMInstanceDao; + +public class RouterDeploymentDefinitionBuilder { + + @Inject + private NetworkDao networkDao; + @Inject + private DomainRouterDao routerDao = null; + @Inject + private PhysicalNetworkServiceProviderDao physicalProviderDao; + @Inject + private NetworkModel networkModel; + @Inject + private VirtualRouterProviderDao vrProviderDao; + @Inject + private NetworkOfferingDao networkOfferingDao; + @Inject + private IpAddressManager ipAddrMgr; + @Inject + private VMInstanceDao vmDao; + @Inject + private HostPodDao podDao; + @Inject + private AccountManager accountMgr; + @Inject + private NetworkOrchestrationService networkMgr; + @Inject + private NicDao nicDao; + @Inject + private UserIpv6AddressDao ipv6Dao; + @Inject + private IPAddressDao ipAddressDao; + @Inject + private VpcDao vpcDao; + @Inject + private VpcOfferingDao vpcOffDao; + @Inject + private PhysicalNetworkDao pNtwkDao; + @Inject + private VpcManager vpcMgr; + @Inject + private VlanDao vlanDao; + + protected ServiceOfferingVO offering; + + public void setOffering(ServiceOfferingVO offering) { + this.offering = offering; + } + + public IntermediateStateBuilder create() { + return new IntermediateStateBuilder(this); + } + + protected RouterDeploymentDefinition injectDependencies( + final RouterDeploymentDefinition routerDeploymentDefinition) { + + routerDeploymentDefinition.networkDao = this.networkDao; + routerDeploymentDefinition.routerDao = this.routerDao; + routerDeploymentDefinition.physicalProviderDao = this.physicalProviderDao; + routerDeploymentDefinition.networkModel = this.networkModel; + routerDeploymentDefinition.vrProviderDao = this.vrProviderDao; + routerDeploymentDefinition.networkOfferingDao = this.networkOfferingDao; + routerDeploymentDefinition.ipAddrMgr = this.ipAddrMgr; + routerDeploymentDefinition.vmDao = this.vmDao; + routerDeploymentDefinition.podDao = this.podDao; + routerDeploymentDefinition.accountMgr = this.accountMgr; + routerDeploymentDefinition.networkMgr = this.networkMgr; + routerDeploymentDefinition.nicDao = this.nicDao; + routerDeploymentDefinition.ipv6Dao = this.ipv6Dao; + routerDeploymentDefinition.ipAddressDao = this.ipAddressDao; + routerDeploymentDefinition.offering = this.offering; + + if (routerDeploymentDefinition instanceof VpcRouterDeploymentDefinition) { + this.injectVpcDependencies((VpcRouterDeploymentDefinition) routerDeploymentDefinition); + } + + return routerDeploymentDefinition; + } + + protected void injectVpcDependencies( + final VpcRouterDeploymentDefinition routerDeploymentDefinition) { + + routerDeploymentDefinition.vpcDao = this.vpcDao; + routerDeploymentDefinition.vpcOffDao = this.vpcOffDao; + routerDeploymentDefinition.pNtwkDao = this.pNtwkDao; + routerDeploymentDefinition.vpcMgr = this.vpcMgr; + routerDeploymentDefinition.vlanDao = this.vlanDao; + } + + + public class IntermediateStateBuilder { + + RouterDeploymentDefinitionBuilder builder; + + protected Vpc vpc; + protected Network guestNetwork; + protected DeployDestination dest; + protected Account owner; + protected Map params; + protected boolean isRedundant; + protected List routers = new ArrayList<>(); + + protected IntermediateStateBuilder(RouterDeploymentDefinitionBuilder builder) { + this.builder = builder; + } + + public IntermediateStateBuilder makeRedundant() { + this.isRedundant = true; + return this; + } + + public IntermediateStateBuilder setRedundant(boolean isRedundant) { + this.isRedundant = isRedundant; + return this; + } + + public IntermediateStateBuilder setVpc(final Vpc vpc) { + this.vpc = vpc; + return this; + } + + public IntermediateStateBuilder setGuestNetwork(final Network nw) { + this.guestNetwork = nw; + return this; + } + + public IntermediateStateBuilder setAccountOwner(final Account owner) { + this.owner = owner; + return this; + } + + public IntermediateStateBuilder setDeployDestination(final DeployDestination dest) { + this.dest = dest; + return this; + } + + public IntermediateStateBuilder setParams(final Map params) { + this.params = params; + return this; + } + + public RouterDeploymentDefinition build() { + RouterDeploymentDefinition routerDeploymentDefinition = null; + if (this.vpc != null) { + routerDeploymentDefinition = new VpcRouterDeploymentDefinition(vpc, dest, owner, params, isRedundant); + } else { + routerDeploymentDefinition = new RouterDeploymentDefinition(guestNetwork, dest, owner, params, isRedundant); + } + + return builder.injectDependencies(routerDeploymentDefinition); + } + } + +} diff --git a/server/src/com/cloud/network/router/deployment/VpcRouterDeploymentDefinition.java b/server/src/com/cloud/network/router/deployment/VpcRouterDeploymentDefinition.java new file mode 100644 index 00000000000..c3e63271a0b --- /dev/null +++ b/server/src/com/cloud/network/router/deployment/VpcRouterDeploymentDefinition.java @@ -0,0 +1,241 @@ +package com.cloud.network.router.deployment; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.TreeSet; + +import javax.inject.Inject; + +import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; +import org.apache.log4j.Logger; + +import com.cloud.dc.dao.VlanDao; +import com.cloud.deploy.DeployDestination; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientAddressCapacityException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InsufficientServerCapacityException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.exception.StorageUnavailableException; +import com.cloud.network.IpAddress; +import com.cloud.network.Network; +import com.cloud.network.NetworkModel; +import com.cloud.network.Networks.BroadcastDomainType; +import com.cloud.network.Networks.IsolationType; +import com.cloud.network.PhysicalNetwork; +import com.cloud.network.PhysicalNetworkServiceProvider; +import com.cloud.network.VirtualRouterProvider; +import com.cloud.network.VirtualRouterProvider.Type; +import com.cloud.network.addr.PublicIp; +import com.cloud.network.dao.IPAddressDao; +import com.cloud.network.dao.IPAddressVO; +import com.cloud.network.dao.PhysicalNetworkDao; +import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; +import com.cloud.network.dao.VirtualRouterProviderDao; +import com.cloud.network.router.VirtualNwStatus; +import com.cloud.network.vpc.PrivateGateway; +import com.cloud.network.vpc.Vpc; +import com.cloud.network.vpc.VpcManager; +import com.cloud.network.vpc.dao.VpcDao; +import com.cloud.network.vpc.dao.VpcOfferingDao; +import com.cloud.offering.NetworkOffering; +import com.cloud.user.Account; +import com.cloud.utils.Pair; +import com.cloud.utils.db.DB; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.vm.DomainRouterVO; +import com.cloud.vm.NicProfile; +import com.cloud.vm.VirtualMachineProfile.Param; + +public class VpcRouterDeploymentDefinition extends RouterDeploymentDefinition { + private static final Logger logger = Logger.getLogger(VpcRouterDeploymentDefinition.class); + + @Inject + protected VpcDao vpcDao; + @Inject + protected VpcOfferingDao vpcOffDao; + @Inject + protected PhysicalNetworkDao pNtwkDao; + @Inject + protected VpcManager vpcMgr; + @Inject + protected PhysicalNetworkServiceProviderDao physicalProviderDao; + @Inject + protected VlanDao vlanDao; + @Inject + protected IPAddressDao ipAddressDao; + @Inject + protected NetworkOrchestrationService networkMgr; + @Inject + protected NetworkModel networkModel; + @Inject + protected VirtualRouterProviderDao vrProviderDao; + + + protected Vpc vpc; + + + protected VpcRouterDeploymentDefinition(final Vpc vpc, final DeployDestination dest, final Account owner, + final Map params, final boolean isRedundant) { + + super(null, dest, owner, params, isRedundant); + + this.vpc = vpc; + } + + @Override + public boolean isVpcRouter() { + return true; + } + + @Override + @DB + protected void findOrDeployVirtualRouter() + throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { + + logger.debug("Deploying Virtual Router in VPC " + vpc); + + Vpc vpcLock = vpcDao.acquireInLockTable(vpc.getId()); + if (vpcLock == null) { + throw new ConcurrentOperationException("Unable to lock vpc " + vpc.getId()); + } + + //1) Find out the list of routers and generate deployment plan + planDeploymentRouters(); + this.generateDeploymentPlan(); + + //2) Return routers if exist, otherwise... + if (this.routers.size() < 1) { + try { + + Long offeringId = vpcOffDao.findById(vpc.getVpcOfferingId()).getServiceOfferingId(); + if (offeringId == null) { + offeringId = offering.getId(); + } + //3) Deploy Virtual Router + List pNtwks = pNtwkDao.listByZone(vpc.getZoneId()); + + VirtualRouterProvider vpcVrProvider = null; + + for (PhysicalNetwork pNtwk : pNtwks) { + PhysicalNetworkServiceProvider provider = physicalProviderDao.findByServiceProvider(pNtwk.getId(), Type.VPCVirtualRouter.toString()); + if (provider == null) { + throw new CloudRuntimeException("Cannot find service provider " + Type.VPCVirtualRouter.toString() + " in physical network " + pNtwk.getId()); + } + vpcVrProvider = vrProviderDao.findByNspIdAndType(provider.getId(), Type.VPCVirtualRouter); + if (vpcVrProvider != null) { + break; + } + } + + PublicIp sourceNatIp = vpcMgr.assignSourceNatIpAddressToVpc(this.owner, vpc); + + DomainRouterVO router = deployVpcRouter(vpcVrProvider, offeringId, sourceNatIp); + this.routers.add(router); + + } finally { + // TODO Should we do this after the pre or after the whole?? + if (vpcLock != null) { + vpcDao.releaseFromLockTable(vpc.getId()); + } + } + } + } + + + protected DomainRouterVO deployVpcRouter(final VirtualRouterProvider vrProvider, + final long svcOffId, final PublicIp sourceNatIp) throws ConcurrentOperationException, InsufficientAddressCapacityException, + InsufficientServerCapacityException, InsufficientCapacityException, StorageUnavailableException, ResourceUnavailableException { + + LinkedHashMap> networks = createVpcRouterNetworks( + new Pair(true, sourceNatIp), this.vpc.getId()); + + DomainRouterVO router = + nwHelper.deployRouter(this, vrProvider, svcOffId, networks, true, vpcMgr.getSupportedVpcHypervisors()); + + return router; + } + + protected LinkedHashMap> createVpcRouterNetworks( + final Pair sourceNatIp, final long vpcId) + throws ConcurrentOperationException, InsufficientAddressCapacityException { + + TreeSet publicVlans = new TreeSet(); + publicVlans.add(sourceNatIp.second().getVlanTag()); + + //1) allocate nic for control and source nat public ip + LinkedHashMap> networks = nwHelper.createRouterNetworks(this, null, sourceNatIp); + + + //2) allocate nic for private gateways if needed + List privateGateways = vpcMgr.getVpcPrivateGateways(vpcId); + if (privateGateways != null && !privateGateways.isEmpty()) { + for (PrivateGateway privateGateway : privateGateways) { + NicProfile privateNic = vpcHelper.createPrivateNicProfileForGateway(privateGateway); + Network privateNetwork = networkModel.getNetwork(privateGateway.getNetworkId()); + networks.put(privateNetwork, new ArrayList(Arrays.asList(privateNic))); + } + } + + //3) allocate nic for guest gateway if needed + List guestNetworks = vpcMgr.getVpcNetworks(vpcId); + for (Network guestNetwork : guestNetworks) { + if (networkModel.isPrivateGateway(guestNetwork.getId())) { + continue; + } + if (guestNetwork.getState() == Network.State.Implemented || guestNetwork.getState() == Network.State.Setup) { + NicProfile guestNic = vpcHelper.createGuestNicProfileForVpcRouter(guestNetwork); + networks.put(guestNetwork, new ArrayList(Arrays.asList(guestNic))); + } + } + + //4) allocate nic for additional public network(s) + List ips = ipAddressDao.listByAssociatedVpc(vpcId, false); + List publicNics = new ArrayList(); + Network publicNetwork = null; + for (IPAddressVO ip : ips) { + PublicIp publicIp = PublicIp.createFromAddrAndVlan(ip, vlanDao.findById(ip.getVlanId())); + if ((ip.getState() == IpAddress.State.Allocated || ip.getState() == IpAddress.State.Allocating) && vpcMgr.isIpAllocatedToVpc(ip) && + !publicVlans.contains(publicIp.getVlanTag())) { + logger.debug("Allocating nic for router in vlan " + publicIp.getVlanTag()); + NicProfile publicNic = new NicProfile(); + publicNic.setDefaultNic(false); + publicNic.setIp4Address(publicIp.getAddress().addr()); + publicNic.setGateway(publicIp.getGateway()); + publicNic.setNetmask(publicIp.getNetmask()); + publicNic.setMacAddress(publicIp.getMacAddress()); + publicNic.setBroadcastType(BroadcastDomainType.Vlan); + publicNic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(publicIp.getVlanTag())); + publicNic.setIsolationUri(IsolationType.Vlan.toUri(publicIp.getVlanTag())); + NetworkOffering publicOffering = networkModel.getSystemAccountNetworkOfferings(NetworkOffering.SystemPublicNetwork).get(0); + if (publicNetwork == null) { + List publicNetworks = networkMgr.setupNetwork(VirtualNwStatus.account, + publicOffering, this.plan, null, null, false); + publicNetwork = publicNetworks.get(0); + } + publicNics.add(publicNic); + publicVlans.add(publicIp.getVlanTag()); + } + } + if (publicNetwork != null) { + if (networks.get(publicNetwork) != null) { + List publicNicProfiles = (List)networks.get(publicNetwork); + publicNicProfiles.addAll(publicNics); + networks.put(publicNetwork, publicNicProfiles); + } else { + networks.put(publicNetwork, publicNics); + } + } + + return networks; + } + + @Override + protected void planDeploymentRouters() { + this.routers = vpcHelper.getVpcRouters(this.getVpc().getId()); + } + +} diff --git a/server/test/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java b/server/test/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java index 218b04560e7..fc98db6a4a1 100644 --- a/server/test/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java +++ b/server/test/com/cloud/vpc/MockVpcVirtualNetworkApplianceManager.java @@ -39,7 +39,6 @@ import com.cloud.network.Site2SiteVpnConnection; import com.cloud.network.VpcVirtualNetworkApplianceService; import com.cloud.network.VpnUser; import com.cloud.network.lb.LoadBalancingRule; -import com.cloud.network.router.RouterDeploymentDefinition; import com.cloud.network.router.VirtualRouter; import com.cloud.network.router.VpcVirtualNetworkApplianceManager; import com.cloud.network.rules.FirewallRule; @@ -93,16 +92,6 @@ public class MockVpcVirtualNetworkApplianceManager extends ManagerBase implement return false; } - /* (non-Javadoc) - * @see com.cloud.network.router.VirtualNetworkApplianceManager#deployVirtualRouterInGuestNetwork(com.cloud.network.Network, com.cloud.deploy.DeployDestination, com.cloud.user.Account, java.util.Map, boolean) - */ - @Override - public List deployVirtualRouter(final RouterDeploymentDefinition routerDeploymentDefinition) - throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException { - // TODO Auto-generated method stub - return null; - } - /* (non-Javadoc) * @see com.cloud.network.router.VirtualNetworkApplianceManager#startRemoteAccessVpn(com.cloud.network.Network, com.cloud.network.RemoteAccessVpn, java.util.List) */