blob: e0976acf6ede3929ca8133f53e0e20387d13ba32 [file] [log] [blame]
// 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;
}
}