| // 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.rules; | |
| import org.apache.cloudstack.network.topology.NetworkTopologyVisitor; | |
| import com.cloud.exception.ConcurrentOperationException; | |
| import com.cloud.exception.ResourceUnavailableException; | |
| import com.cloud.network.Network; | |
| import com.cloud.network.NetworkModel; | |
| import com.cloud.network.dao.NetworkDao; | |
| import com.cloud.network.router.NetworkHelper; | |
| import com.cloud.network.router.NicProfileHelper; | |
| import com.cloud.network.router.VirtualRouter; | |
| import com.cloud.network.vpc.NetworkACLManager; | |
| import com.cloud.network.vpc.PrivateGateway; | |
| import com.cloud.network.vpc.PrivateIpVO; | |
| import com.cloud.vm.NicProfile; | |
| import com.cloud.vm.VirtualMachineManager; | |
| public class PrivateGatewayRules extends RuleApplier { | |
| private final PrivateGateway _privateGateway; | |
| private boolean _isAddOperation; | |
| private NicProfile _nicProfile; | |
| public PrivateGatewayRules(final PrivateGateway privateGateway) { | |
| super(null); | |
| _privateGateway = privateGateway; | |
| } | |
| @Override | |
| public boolean accept(final NetworkTopologyVisitor visitor, final VirtualRouter router) throws ResourceUnavailableException { | |
| _router = router; | |
| boolean result = false; | |
| try { | |
| final NetworkModel networkModel = visitor.getVirtualNetworkApplianceFactory().getNetworkModel(); | |
| _network = networkModel.getNetwork(_privateGateway.getNetworkId()); | |
| final NicProfileHelper nicProfileHelper = visitor.getVirtualNetworkApplianceFactory().getNicProfileHelper(); | |
| final NicProfile requested = nicProfileHelper.createPrivateNicProfileForGateway(_privateGateway, _router); | |
| final NetworkHelper networkHelper = visitor.getVirtualNetworkApplianceFactory().getNetworkHelper(); | |
| if (!networkHelper.checkRouterVersion(_router)) { | |
| logger.warn("Router requires upgrade. Unable to send command to router: {}", _router); | |
| return false; | |
| } | |
| final VirtualMachineManager itMgr = visitor.getVirtualNetworkApplianceFactory().getItMgr(); | |
| _nicProfile = itMgr.addVmToNetwork(_router, _network, requested); | |
| // setup source nat | |
| if (_nicProfile != null) { | |
| _isAddOperation = true; | |
| result = visitor.visit(this); | |
| } | |
| } catch (final Exception ex) { | |
| logger.warn("Failed to create private gateway " + _privateGateway + " on router " + _router + " due to ", ex); | |
| } finally { | |
| if (!result) { | |
| logger.debug("Failed to setup gateway " + _privateGateway + " on router " + _router + " with the source nat. Will now remove the gateway."); | |
| _isAddOperation = false; | |
| final boolean isRemoved = destroyPrivateGateway(visitor); | |
| if (isRemoved) { | |
| logger.debug("Removed the gateway " + _privateGateway + " from router " + _router + " as a part of cleanup"); | |
| } else { | |
| logger.warn("Failed to remove the gateway " + _privateGateway + " from router " + _router + " as a part of cleanup"); | |
| } | |
| } | |
| } | |
| return result; | |
| } | |
| public boolean isAddOperation() { | |
| return _isAddOperation; | |
| } | |
| public NicProfile getNicProfile() { | |
| return _nicProfile; | |
| } | |
| public PrivateIpVO retrivePrivateIP(final NetworkTopologyVisitor visitor) { | |
| final PrivateIpVO ipVO = visitor.getVirtualNetworkApplianceFactory().getPrivateIpDao().findByIpAndSourceNetworkId(_nicProfile.getNetworkId(), _nicProfile.getIPv4Address()); | |
| return ipVO; | |
| } | |
| public Network retrievePrivateNetwork(final NetworkTopologyVisitor visitor) { | |
| // This network might be the same we have already as an instance in the | |
| // RuleApplier super class. | |
| // Just doing this here, but will double check is remove if it's not | |
| // needed. | |
| final NetworkDao networkDao = visitor.getVirtualNetworkApplianceFactory().getNetworkDao(); | |
| final Network network = networkDao.findById(_nicProfile.getNetworkId()); | |
| return network; | |
| } | |
| protected boolean destroyPrivateGateway(final NetworkTopologyVisitor visitor) throws ConcurrentOperationException, ResourceUnavailableException { | |
| final NetworkModel networkModel = visitor.getVirtualNetworkApplianceFactory().getNetworkModel(); | |
| if (!networkModel.isVmPartOfNetwork(_router.getId(), _privateGateway.getNetworkId())) { | |
| logger.debug("Router doesn't have nic for gateway " + _privateGateway + " so no need to removed it"); | |
| return true; | |
| } | |
| final Network privateNetwork = networkModel.getNetwork(_privateGateway.getNetworkId()); | |
| logger.debug("Releasing private ip for gateway " + _privateGateway + " from " + _router); | |
| _nicProfile = networkModel.getNicProfile(_router, privateNetwork.getId(), null); | |
| boolean result = visitor.visit(this); | |
| if (!result) { | |
| logger.warn("Failed to release private ip for gateway " + _privateGateway + " on router " + _router); | |
| return false; | |
| } | |
| // revoke network acl on the private gateway. | |
| final NetworkACLManager networkACLMgr = visitor.getVirtualNetworkApplianceFactory().getNetworkACLMgr(); | |
| if (!networkACLMgr.revokeACLItemsForPrivateGw(_privateGateway)) { | |
| logger.debug("Failed to delete network acl items on " + _privateGateway + " from router " + _router); | |
| return false; | |
| } | |
| logger.debug("Removing router " + _router + " from private network " + privateNetwork + " as a part of delete private gateway"); | |
| final VirtualMachineManager itMgr = visitor.getVirtualNetworkApplianceFactory().getItMgr(); | |
| result = result && itMgr.removeVmFromNetwork(_router, privateNetwork, null); | |
| logger.debug("Private gateawy " + _privateGateway + " is removed from router " + _router); | |
| return result; | |
| } | |
| } |