| // 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.apache.cloudstack.network.topology; |
| |
| import java.util.List; |
| |
| import com.cloud.dc.DataCenter; |
| import com.cloud.deploy.DeployDestination; |
| import com.cloud.exception.ConcurrentOperationException; |
| import com.cloud.exception.ResourceUnavailableException; |
| import com.cloud.network.Network; |
| import com.cloud.network.PublicIpAddress; |
| import com.cloud.network.RemoteAccessVpn; |
| import com.cloud.network.VpnUser; |
| import com.cloud.network.router.VirtualRouter; |
| import com.cloud.network.rules.AdvancedVpnRules; |
| import com.cloud.network.rules.DhcpEntryRules; |
| import com.cloud.network.rules.DhcpPvlanRules; |
| import com.cloud.network.rules.NetworkAclsRules; |
| import com.cloud.network.rules.NicPlugInOutRules; |
| import com.cloud.network.rules.PrivateGatewayRules; |
| import com.cloud.network.rules.RuleApplier; |
| import com.cloud.network.rules.RuleApplierWrapper; |
| import com.cloud.network.rules.StaticRoutesRules; |
| import com.cloud.network.rules.UserdataPwdRules; |
| import com.cloud.network.rules.VpcIpAssociationRules; |
| import com.cloud.network.vpc.NetworkACLItem; |
| import com.cloud.network.vpc.PrivateGateway; |
| import com.cloud.network.vpc.StaticRouteProfile; |
| import com.cloud.vm.DomainRouterVO; |
| import com.cloud.vm.NicProfile; |
| import com.cloud.vm.VirtualMachine.State; |
| import com.cloud.vm.VirtualMachineProfile; |
| |
| import org.apache.log4j.Logger; |
| import org.springframework.beans.factory.annotation.Autowired; |
| import org.springframework.beans.factory.annotation.Qualifier; |
| import org.springframework.stereotype.Component; |
| |
| @Component |
| public class AdvancedNetworkTopology extends BasicNetworkTopology { |
| |
| private static final Logger s_logger = Logger.getLogger(AdvancedNetworkTopology.class); |
| |
| @Autowired |
| @Qualifier("advancedNetworkVisitor") |
| protected AdvancedNetworkVisitor _advancedVisitor; |
| |
| @Override |
| public BasicNetworkVisitor getVisitor() { |
| return _advancedVisitor; |
| } |
| |
| @Override |
| public String[] applyVpnUsers(final RemoteAccessVpn remoteAccessVpn, final List<? extends VpnUser> users, final VirtualRouter router) throws ResourceUnavailableException { |
| |
| s_logger.debug("APPLYING ADVANCED VPN USERS RULES"); |
| |
| final AdvancedVpnRules routesRules = new AdvancedVpnRules(remoteAccessVpn, users); |
| |
| final boolean agentResult = routesRules.accept(_advancedVisitor, router); |
| |
| final String[] result = new String[users.size()]; |
| for (int i = 0; i < result.length; i++) { |
| if (agentResult) { |
| result[i] = null; |
| } else { |
| result[i] = String.valueOf(agentResult); |
| } |
| } |
| |
| return result; |
| } |
| |
| @Override |
| public boolean applyStaticRoutes(final List<StaticRouteProfile> staticRoutes, final List<DomainRouterVO> routers) throws ResourceUnavailableException { |
| |
| s_logger.debug("APPLYING STATIC ROUTES RULES"); |
| |
| if (staticRoutes == null || staticRoutes.isEmpty()) { |
| s_logger.debug("No static routes to apply"); |
| return true; |
| } |
| |
| final StaticRoutesRules routesRules = new StaticRoutesRules(staticRoutes); |
| |
| boolean result = true; |
| for (final VirtualRouter router : routers) { |
| if (router.getState() == State.Running) { |
| |
| result = result && routesRules.accept(_advancedVisitor, router); |
| |
| } else if (router.getState() == State.Stopped || router.getState() == State.Stopping) { |
| s_logger.debug("Router " + router.getInstanceName() + " is in " + router.getState() + ", so not sending StaticRoute command to the backend"); |
| } else { |
| s_logger.warn("Unable to apply StaticRoute, virtual router is not in the right state " + router.getState()); |
| |
| throw new ResourceUnavailableException("Unable to apply StaticRoute on the backend," + " virtual router is not in the right state", DataCenter.class, |
| router.getDataCenterId()); |
| } |
| } |
| return result; |
| } |
| |
| @Override |
| public boolean setupDhcpForPvlan(final boolean isAddPvlan, final DomainRouterVO router, final Long hostId, final NicProfile nic) throws ResourceUnavailableException { |
| |
| s_logger.debug("SETUP DHCP PVLAN RULES"); |
| |
| if (!nic.getBroadCastUri().getScheme().equals("pvlan")) { |
| return false; |
| } |
| |
| final DhcpPvlanRules pvlanRules = new DhcpPvlanRules(isAddPvlan, nic); |
| |
| return pvlanRules.accept(_advancedVisitor, router); |
| } |
| |
| @Override |
| public boolean setupPrivateGateway(final PrivateGateway gateway, final VirtualRouter router) throws ConcurrentOperationException, ResourceUnavailableException { |
| s_logger.debug("SETUP PRIVATE GATEWAY RULES"); |
| |
| final PrivateGatewayRules routesRules = new PrivateGatewayRules(gateway); |
| |
| return routesRules.accept(_advancedVisitor, router); |
| } |
| |
| @Override |
| public boolean applyUserData(final Network network, final NicProfile nic, final VirtualMachineProfile profile, final DeployDestination dest, final DomainRouterVO router) |
| throws ResourceUnavailableException { |
| |
| s_logger.debug("APPLYING VPC USERDATA RULES"); |
| |
| final String typeString = "userdata and password entry"; |
| final boolean isPodLevelException = false; |
| final boolean failWhenDisconnect = false; |
| final Long podId = null; |
| |
| final UserdataPwdRules pwdRules = new UserdataPwdRules(network, nic, profile, dest); |
| |
| return applyRules(network, router, typeString, isPodLevelException, podId, failWhenDisconnect, new RuleApplierWrapper<RuleApplier>(pwdRules)); |
| } |
| |
| @Override |
| public boolean applyDhcpEntry(final Network network, final NicProfile nic, final VirtualMachineProfile profile, final DeployDestination dest, |
| final DomainRouterVO router) throws ResourceUnavailableException { |
| |
| s_logger.debug("APPLYING VPC DHCP ENTRY RULES"); |
| |
| final String typeString = "dhcp entry"; |
| final Long podId = null; |
| final boolean isPodLevelException = false; |
| final boolean failWhenDisconnect = false; |
| |
| final DhcpEntryRules dhcpRules = new DhcpEntryRules(network, nic, profile, dest); |
| |
| return applyRules(network, router, typeString, isPodLevelException, podId, failWhenDisconnect, new RuleApplierWrapper<RuleApplier>(dhcpRules)); |
| } |
| |
| @Override |
| public boolean removeDhcpEntry(Network network, NicProfile nic, VirtualMachineProfile profile, VirtualRouter virtualRouter) throws ResourceUnavailableException { |
| s_logger.debug("REMOVE VPC DHCP ENTRY RULES"); |
| |
| final String typeString = "dhcp entry"; |
| final Long podId = null; |
| final boolean isPodLevelException = false; |
| final boolean failWhenDisconnect = false; |
| |
| final DhcpEntryRules dhcpRules = new DhcpEntryRules(network, nic, profile, null); |
| dhcpRules.setRemove(true); |
| |
| return applyRules(network, virtualRouter, typeString, isPodLevelException, podId, failWhenDisconnect, new RuleApplierWrapper<RuleApplier>(dhcpRules)); |
| } |
| |
| @Override |
| public boolean associatePublicIP(final Network network, final List<? extends PublicIpAddress> ipAddresses, final VirtualRouter router) |
| throws ResourceUnavailableException { |
| |
| if (ipAddresses == null || ipAddresses.isEmpty()) { |
| s_logger.debug("No ip association rules to be applied for network " + network.getId()); |
| return true; |
| } |
| |
| if (network.getVpcId() == null) { |
| return super.associatePublicIP(network, ipAddresses, router); |
| } |
| |
| s_logger.debug("APPLYING VPC IP RULES"); |
| |
| final String typeString = "vpc ip association"; |
| final boolean isPodLevelException = false; |
| final boolean failWhenDisconnect = false; |
| final Long podId = null; |
| |
| final NicPlugInOutRules nicPlugInOutRules = new NicPlugInOutRules(network, ipAddresses); |
| nicPlugInOutRules.accept(_advancedVisitor, router); |
| |
| final VpcIpAssociationRules ipAssociationRules = new VpcIpAssociationRules(network, ipAddresses); |
| final boolean result = applyRules(network, router, typeString, isPodLevelException, podId, failWhenDisconnect, new RuleApplierWrapper<RuleApplier>(ipAssociationRules)); |
| |
| if (result) { |
| if (router.getState() == State.Stopped || router.getState() == State.Stopping) { |
| s_logger.debug("Router " + router.getInstanceName() + " is in " + router.getState() + ", so not sending NicPlugInOutRules command to the backend"); |
| } else { |
| _advancedVisitor.visit(nicPlugInOutRules); |
| } |
| } |
| |
| return result; |
| } |
| |
| @Override |
| public boolean applyNetworkACLs(final Network network, final List<? extends NetworkACLItem> rules, final VirtualRouter router, final boolean isPrivateGateway) |
| throws ResourceUnavailableException { |
| |
| if (rules == null || rules.isEmpty()) { |
| s_logger.debug("No network ACLs to be applied for network " + network.getId()); |
| return true; |
| } |
| |
| s_logger.debug("APPLYING NETWORK ACLs RULES"); |
| |
| final String typeString = "network acls"; |
| final boolean isPodLevelException = false; |
| final boolean failWhenDisconnect = false; |
| final Long podId = null; |
| |
| final NetworkAclsRules aclsRules = new NetworkAclsRules(network, rules, isPrivateGateway); |
| |
| final boolean result = applyRules(network, router, typeString, isPodLevelException, podId, failWhenDisconnect, new RuleApplierWrapper<RuleApplier>(aclsRules)); |
| return result; |
| } |
| } |