// 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 org.apache.log4j.Logger; 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 static final Logger s_logger = Logger.getLogger(PrivateGatewayRules.class); 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)) { s_logger.warn("Router requires upgrade. Unable to send command to router: " + _router.getId()); return false; } final VirtualMachineManager itMgr = visitor.getVirtualNetworkApplianceFactory().getItMgr(); _nicProfile = itMgr.addVmToNetwork(_router, _network, requested); // setup source nat if (_nicProfile != null) { _isAddOperation = true; // result = setupVpcPrivateNetwork(router, true, guestNic); result = visitor.visit(this); } } catch (final Exception ex) { s_logger.warn("Failed to create private gateway " + _privateGateway + " on router " + _router + " due to ", ex); } finally { if (!result) { s_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) { s_logger.debug("Removed the gateway " + _privateGateway + " from router " + _router + " as a part of cleanup"); } else { s_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())) { s_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()); s_logger.debug("Releasing private ip for gateway " + _privateGateway + " from " + _router); _nicProfile = networkModel.getNicProfile(_router, privateNetwork.getId(), null); boolean result = visitor.visit(this); if (!result) { s_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)) { s_logger.debug("Failed to delete network acl items on " + _privateGateway + " from router " + _router); return false; } s_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); s_logger.debug("Private gateawy " + _privateGateway + " is removed from router " + _router); return result; } }