| // 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.Map; |
| import java.util.Set; |
| import java.util.TreeSet; |
| |
| import javax.annotation.PostConstruct; |
| import javax.inject.Inject; |
| |
| import org.apache.commons.lang3.StringUtils; |
| import org.apache.log4j.Logger; |
| import org.apache.cloudstack.network.router.deployment.RouterDeploymentDefinition; |
| |
| import com.cloud.dc.dao.VlanDao; |
| import com.cloud.exception.ConcurrentOperationException; |
| import com.cloud.exception.InsufficientAddressCapacityException; |
| import com.cloud.exception.InsufficientCapacityException; |
| import com.cloud.hypervisor.Hypervisor.HypervisorType; |
| import com.cloud.network.IpAddress; |
| import com.cloud.network.Network; |
| import com.cloud.network.Networks.BroadcastDomainType; |
| import com.cloud.network.Networks.IsolationType; |
| import com.cloud.network.addr.PublicIp; |
| import com.cloud.network.dao.IPAddressVO; |
| import com.cloud.network.vpc.PrivateGateway; |
| import com.cloud.network.vpc.VpcManager; |
| import com.cloud.offering.NetworkOffering; |
| import com.cloud.service.ServiceOfferingVO; |
| import com.cloud.storage.VMTemplateVO; |
| import com.cloud.vm.NicProfile; |
| |
| |
| public class VpcNetworkHelperImpl extends NetworkHelperImpl { |
| |
| private static final Logger s_logger = Logger.getLogger(VpcNetworkHelperImpl.class); |
| |
| @Inject |
| private VlanDao _vlanDao; |
| @Inject |
| protected VpcManager vpcMgr; |
| @Inject |
| protected NicProfileHelper nicProfileHelper; |
| |
| protected String noHypervisorsErrMsgDetails; |
| |
| @PostConstruct |
| protected void setupNoHypervisorsErrMsgDetails() { |
| noHypervisorsErrMsgDetails = StringUtils.join(vpcMgr.getSupportedVpcHypervisors(), ','); |
| noHypervisorsErrMsgDetails += " are the only supported Hypervisors"; |
| } |
| |
| @Override |
| protected String getNoHypervisorsErrMsgDetails() { |
| return noHypervisorsErrMsgDetails; |
| } |
| |
| @Override |
| protected void filterSupportedHypervisors(final List<HypervisorType> hypervisors) { |
| hypervisors.retainAll(vpcMgr.getSupportedVpcHypervisors()); |
| } |
| |
| @Override |
| public void reallocateRouterNetworks(final RouterDeploymentDefinition vpcRouterDeploymentDefinition, final VirtualRouter router, final VMTemplateVO template, final HypervisorType hType) |
| throws ConcurrentOperationException, InsufficientCapacityException { |
| |
| final TreeSet<String> publicVlans = new TreeSet<String>(); |
| if (vpcRouterDeploymentDefinition.isPublicNetwork()) { |
| publicVlans.add(vpcRouterDeploymentDefinition.getSourceNatIP() |
| .getVlanTag()); |
| } |
| |
| //1) allocate nic for control and source nat public ip |
| final LinkedHashMap<Network, List<? extends NicProfile>> networks = configureDefaultNics(vpcRouterDeploymentDefinition); |
| |
| final Long vpcId = vpcRouterDeploymentDefinition.getVpc().getId(); |
| //2) allocate nic for private gateways if needed |
| final List<PrivateGateway> privateGateways = vpcMgr.getVpcPrivateGateways(vpcId); |
| if (privateGateways != null && !privateGateways.isEmpty()) { |
| for (final PrivateGateway privateGateway : privateGateways) { |
| final NicProfile privateNic = nicProfileHelper.createPrivateNicProfileForGateway(privateGateway, router); |
| final Network privateNetwork = _networkModel.getNetwork(privateGateway.getNetworkId()); |
| networks.put(privateNetwork, new ArrayList<NicProfile>(Arrays.asList(privateNic))); |
| } |
| } |
| |
| //3) allocate nic for guest gateway if needed |
| final List<? extends Network> guestNetworks = vpcMgr.getVpcNetworks(vpcId); |
| for (final Network guestNetwork : guestNetworks) { |
| if (_networkModel.isPrivateGateway(guestNetwork.getId())) { |
| continue; |
| } |
| if (guestNetwork.getState() == Network.State.Implemented || guestNetwork.getState() == Network.State.Setup) { |
| final NicProfile guestNic = nicProfileHelper.createGuestNicProfileForVpcRouter(vpcRouterDeploymentDefinition, guestNetwork); |
| networks.put(guestNetwork, new ArrayList<NicProfile>(Arrays.asList(guestNic))); |
| } |
| } |
| |
| //4) allocate nic for additional public network(s) |
| final List<IPAddressVO> ips = _ipAddressDao.listByAssociatedVpc(vpcId, false); |
| final List<NicProfile> publicNics = new ArrayList<NicProfile>(); |
| Network publicNetwork = null; |
| final Map<Network.Service, Set<Network.Provider>> vpcOffSvcProvidersMap = vpcMgr.getVpcOffSvcProvidersMap(vpcRouterDeploymentDefinition.getVpc().getVpcOfferingId()); |
| |
| boolean vpcIsStaticNatProvider = vpcOffSvcProvidersMap.get(Network.Service.StaticNat) != null && |
| vpcOffSvcProvidersMap.get(Network.Service.StaticNat).contains(Network.Provider.VPCVirtualRouter); |
| |
| final ServiceOfferingVO routerOffering = _serviceOfferingDao.findById(vpcRouterDeploymentDefinition.getServiceOfferingId()); |
| |
| for (final IPAddressVO ip : ips) { |
| if (vpcIsStaticNatProvider || !ip.isOneToOneNat()) { |
| final 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())) { |
| s_logger.debug("Allocating nic for router in vlan " + publicIp.getVlanTag()); |
| final NicProfile publicNic = new NicProfile(); |
| publicNic.setDefaultNic(false); |
| publicNic.setIPv4Address(publicIp.getAddress() |
| .addr()); |
| publicNic.setIPv4Gateway(publicIp.getGateway()); |
| publicNic.setIPv4Netmask(publicIp.getNetmask()); |
| publicNic.setMacAddress(publicIp.getMacAddress()); |
| publicNic.setBroadcastType(BroadcastDomainType.Vlan); |
| publicNic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(publicIp.getVlanTag())); |
| publicNic.setIsolationUri(IsolationType.Vlan.toUri(publicIp.getVlanTag())); |
| final NetworkOffering publicOffering = _networkModel.getSystemAccountNetworkOfferings(NetworkOffering.SystemPublicNetwork) |
| .get(0); |
| if (publicNetwork == null) { |
| final List<? extends Network> publicNetworks = _networkMgr.setupNetwork(s_systemAccount, publicOffering, vpcRouterDeploymentDefinition.getPlan(), null, null, false); |
| publicNetwork = publicNetworks.get(0); |
| } |
| publicNics.add(publicNic); |
| publicVlans.add(publicIp.getVlanTag()); |
| } |
| } |
| } |
| if (publicNetwork != null) { |
| if (networks.get(publicNetwork) != null) { |
| @SuppressWarnings("unchecked") |
| final List<NicProfile> publicNicProfiles = (List<NicProfile>)networks.get(publicNetwork); |
| publicNicProfiles.addAll(publicNics); |
| networks.put(publicNetwork, publicNicProfiles); |
| } else { |
| networks.put(publicNetwork, publicNics); |
| } |
| } |
| |
| _itMgr.allocate(router.getInstanceName(), template, routerOffering, networks, vpcRouterDeploymentDefinition.getPlan(), hType); |
| } |
| |
| @Override |
| public LinkedHashMap<Network, List<? extends NicProfile>> configureDefaultNics(final RouterDeploymentDefinition routerDeploymentDefinition) throws ConcurrentOperationException, InsufficientAddressCapacityException { |
| |
| final LinkedHashMap<Network, List<? extends NicProfile>> networks = new LinkedHashMap<Network, List<? extends NicProfile>>(3); |
| |
| // 1) Control network |
| final LinkedHashMap<Network, List<? extends NicProfile>> controlNic = configureControlNic(routerDeploymentDefinition); |
| networks.putAll(controlNic); |
| |
| // 2) Public network |
| final LinkedHashMap<Network, List<? extends NicProfile>> publicNic = configurePublicNic(routerDeploymentDefinition, false); |
| networks.putAll(publicNic); |
| |
| // 3) Guest Network |
| final LinkedHashMap<Network, List<? extends NicProfile>> guestNic = configureGuestNic(routerDeploymentDefinition); |
| networks.putAll(guestNic); |
| |
| return networks; |
| } |
| } |