// 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 org.cloud.network.router.deployment; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.apache.log4j.Logger; import com.cloud.dc.dao.VlanDao; import com.cloud.deploy.DataCenterDeployment; import com.cloud.deploy.DeployDestination; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.Network; import com.cloud.network.PhysicalNetwork; import com.cloud.network.PhysicalNetworkServiceProvider; import com.cloud.network.VirtualRouterProvider.Type; import com.cloud.network.dao.PhysicalNetworkDao; 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.user.Account; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.DomainRouterVO; import com.cloud.vm.VirtualMachineProfile.Param; public class VpcRouterDeploymentDefinition extends RouterDeploymentDefinition { private static final Logger logger = Logger.getLogger(VpcRouterDeploymentDefinition.class); protected VpcDao vpcDao; protected VpcOfferingDao vpcOffDao; protected PhysicalNetworkDao pNtwkDao; protected VpcManager vpcMgr; protected VlanDao vlanDao; protected Vpc vpc; protected VpcRouterDeploymentDefinition(final Network guestNetwork, final Vpc vpc, final DeployDestination dest, final Account owner, final Map<Param, Object> params) { super(guestNetwork, dest, owner, params); this.vpc = vpc; } @Override public Vpc getVpc() { return vpc; } @Override public boolean isVpcRouter() { return true; } @Override public boolean isPublicNetwork() { return true; } @Override protected void lock() { final Vpc vpcLock = vpcDao.acquireInLockTable(vpc.getId()); if (vpcLock == null) { throw new ConcurrentOperationException("Unable to lock vpc " + vpc.getId()); } tableLockId = vpcLock.getId(); } @Override protected void unlock() { if (tableLockId != null) { vpcDao.releaseFromLockTable(tableLockId); if (logger.isDebugEnabled()) { logger.debug("Lock is released for vpc id " + tableLockId + " as a part of router startup in " + dest); } } } @Override protected void checkPreconditions() { // No preconditions for Vpc } @Override protected List<DeployDestination> findDestinations() { final List<DeployDestination> destinations = new ArrayList<>(); destinations.add(dest); return destinations; } /** * @see RouterDeploymentDefinition#prepareDeployment() * * @return if the deployment can proceed */ @Override protected boolean prepareDeployment() { return true; } @Override protected void findSourceNatIP() throws InsufficientAddressCapacityException, ConcurrentOperationException { sourceNatIp = vpcMgr.assignSourceNatIpAddressToVpc(owner, vpc); } @Override protected void findOrDeployVirtualRouter() throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { final Vpc vpc = getVpc(); if (vpc != null) { // This call will associate any existing router to the "routers" attribute. // It's needed in order to continue with the VMs deployment. planDeploymentRouters(); if (routers.size() == MAX_NUMBER_OF_ROUTERS) { // If we have 2 routers already deployed, do nothing and return. return; } } super.findOrDeployVirtualRouter(); } @Override protected void findVirtualProvider() { final List<? extends PhysicalNetwork> pNtwks = pNtwkDao.listByZone(vpc.getZoneId()); for (final PhysicalNetwork pNtwk : pNtwks) { final 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()); } vrProvider = vrProviderDao.findByNspIdAndType(provider.getId(), Type.VPCVirtualRouter); if (vrProvider != null) { break; } } } @Override protected void findServiceOfferingId() { serviceOfferingId = vpcOffDao.findById(vpc.getVpcOfferingId()).getServiceOfferingId(); if (serviceOfferingId == null) { findDefaultServiceOfferingId(); } } @Override protected void deployAllVirtualRouters() throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { // Implement Redundant Vpc final int routersToDeploy = getNumberOfRoutersToDeploy(); for(int i = 0; i < routersToDeploy; i++) { // Don't start the router as we are holding the network lock that needs to be released at the end of router allocation final DomainRouterVO router = nwHelper.deployRouter(this, false); if (router != null) { routers.add(router); } } } @Override protected void planDeploymentRouters() { routers = routerDao.listByVpcId(vpc.getId()); } @Override public void generateDeploymentPlan() { plan = new DataCenterDeployment(dest.getDataCenter().getId()); } @Override public boolean isRedundant() { return vpc.isRedundant(); } }