VPC: implemented vpc cleanup thread that cleans up Inactive VPCs (that were failed to delete)

This commit is contained in:
Alena Prokharchyk 2012-06-27 14:38:21 -07:00
parent 164ea701a6
commit bc9b23dfcd
16 changed files with 275 additions and 75 deletions

View File

@ -44,6 +44,4 @@ public interface NetworkACLService {
*/
List<? extends NetworkACL> listNetworkACLs(ListNetworkACLsCmd cmd);
List<? extends NetworkACL> listNetworkACLs(long guestNtwkId);
}

View File

@ -22,7 +22,7 @@ import com.cloud.network.Network;
public interface Vpc extends ControlledEntity{
public enum State {
Enabled,
Disabled
Inactive
}
public static final String _supportedProviders = Network.Provider.VPCVirtualRouter.getName();

View File

@ -337,7 +337,8 @@ public enum Config {
CustomDiskOfferingMaxSize("Advanced", ManagementServer.class, Long.class, "custom.diskoffering.size.max", "1024", "Maximum size in GB for custom disk offering", null),
ConsoleProxyServiceOffering("Advanced", ManagementServer.class, Long.class, "consoleproxy.service.offering", null, "Service offering used by console proxy; if NULL - system offering will be used", null),
SecondaryStorageServiceOffering("Advanced", ManagementServer.class, Long.class, "secstorage.service.offering", null, "Service offering used by secondary storage; if NULL - system offering will be used", null),
HaTag("Advanced", ManagementServer.class, String.class, "ha.tag", null, "HA tag defining that the host marked with this tag can be used for HA purposes only", null);
HaTag("Advanced", ManagementServer.class, String.class, "ha.tag", null, "HA tag defining that the host marked with this tag can be used for HA purposes only", null),
VpcCleanupInterval("Advanced", ManagementServer.class, Integer.class, "vpc.cleanup.interval", "3600", "The interval (in seconds) between cleanup for Inactive VPCs", null);
private final String _category;

View File

@ -1263,6 +1263,9 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
ip.setVpcId(vpcId);
ip.setSourceNat(isSourceNat);
_ipAddressDao.update(ipId, ip);
//mark ip as allocated
markPublicIpAsAllocated(ip);
txn.commit();
s_logger.debug("Successfully assigned ip " + ipToAssoc + " to vpc " + vpc);
@ -2590,7 +2593,9 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
if (vpcId != null) {
Vpc vpc = _vpcMgr.getActiveVpc(vpcId);
if (vpc == null) {
throw new InvalidParameterValueException("Unable to find enabled vpc by id " + vpcId);
InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find Enabled VPC ");
ex.addProxyObject("vpc", vpcId, "VPC");
throw ex;
}
_accountMgr.checkAccess(caller, null, false, vpc);
}
@ -5895,7 +5900,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
boolean success = true;
Network network = getNetwork(networkId);
// remove all PF/Static Nat rules for the network
//remove all PF/Static Nat rules for the network
try {
if (_rulesMgr.revokeAllPFStaticNatRulesForNetwork(networkId, callerUserId, caller)) {
s_logger.debug("Successfully cleaned up portForwarding/staticNat rules for network id=" + networkId);
@ -5909,7 +5914,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
s_logger.warn("Failed to release portForwarding/StaticNat rules as a part of network id=" + networkId + " cleanup due to resourceUnavailable ", ex);
}
// remove all LB rules for the network
//remove all LB rules for the network
if (_lbMgr.removeAllLoadBalanacersForNetwork(networkId, caller, callerUserId)) {
s_logger.debug("Successfully cleaned up load balancing rules for network id=" + networkId);
} else {
@ -5918,7 +5923,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
s_logger.warn("Failed to cleanup LB rules as a part of network id=" + networkId + " cleanup");
}
// revoke all firewall rules for the network
//revoke all firewall rules for the network
try {
if (_firewallMgr.revokeAllFirewallRulesForNetwork(networkId, callerUserId, caller)) {
s_logger.debug("Successfully cleaned up firewallRules rules for network id=" + networkId);
@ -5932,7 +5937,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
s_logger.warn("Failed to cleanup Firewall rules as a part of network id=" + networkId + " cleanup due to resourceUnavailable ", ex);
}
// release all ip addresses
//release all ip addresses
List<IPAddressVO> ipsToRelease = _ipAddressDao.listByAssociatedNetwork(networkId, null);
for (IPAddressVO ipToRelease : ipsToRelease) {
if (ipToRelease.getVpcId() != null) {

View File

@ -606,7 +606,7 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma
for (FirewallRuleVO rule : fwRules) {
// Mark all Firewall rules as Revoke, but don't revoke them yet - we have to revoke all rules for ip, no
// need to send them one by one
// need to send them one by one
revokeFirewallRule(rule.getId(), false, caller, Account.ACCOUNT_ID_SYSTEM);
}

View File

@ -706,16 +706,16 @@ public class LoadBalancingRulesManagerImpl<Type> implements LoadBalancingRulesMa
}
Long ipAddrId = lb.getSourceIpAddressId();
IPAddressVO ipAddressVo = null;
IPAddressVO ipAddressVO = null;
if (ipAddrId != null) {
ipAddressVo = _ipAddressDao.findById(ipAddrId);
ipAddressVO = _ipAddressDao.findById(ipAddrId);
// Validate ip address
if (ipAddressVo == null) {
if (ipAddressVO == null) {
throw new InvalidParameterValueException("Unable to create load balance rule; ip id=" + ipAddrId + "" +
" doesn't exist in the system");
} else if (ipAddressVo.isOneToOneNat()) {
throw new NetworkRuleConflictException("Can't do load balance on ip address: " + ipAddressVo.getAddress());
} else if (ipAddressVO.isOneToOneNat()) {
throw new NetworkRuleConflictException("Can't do load balance on ip address: " + ipAddressVO.getAddress());
}
}
@ -724,18 +724,23 @@ public class LoadBalancingRulesManagerImpl<Type> implements LoadBalancingRulesMa
IpAddress ip = null;
Network guestNetwork = _networkMgr.getNetwork(lb.getNetworkId());
NetworkOffering off = _configMgr.getNetworkOffering(guestNetwork.getNetworkOfferingId());
if (off.getElasticLb() && ipAddressVo == null) {
if (off.getElasticLb() && ipAddressVO == null) {
ip = _networkMgr.assignSystemIp(lb.getNetworkId(), lbOwner, true, false);
lb.setSourceIpAddressId(ip.getId());
}
try {
if (ip.getAssociatedWithNetworkId() == null) {
s_logger.debug("The ip is not associated with the network id="+ lb.getNetworkId() + " so assigning");
ip = _networkMgr.associateIPToGuestNetwork(ipAddrId, lb.getNetworkId());
if (ipAddressVO != null) {
if (ipAddressVO.getAssociatedWithNetworkId() == null) {
s_logger.debug("The ip is not associated with the network id="+ lb.getNetworkId() + " so assigning");
ipAddressVO = _networkMgr.associateIPToGuestNetwork(ipAddrId, lb.getNetworkId());
}
_networkMgr.checkIpForService(ipAddressVO, Service.Lb);
}
if (lb.getSourceIpAddressId() == null) {
throw new CloudRuntimeException("No ip address is defined to assign the LB to");
}
ipAddressVo = _ipAddressDao.findById(ipAddrId);
_networkMgr.checkIpForService(ipAddressVo, Service.Lb);
result = createLoadBalancer(lb, openFirewall);
} catch (Exception ex) {
s_logger.warn("Failed to create load balancer due to ", ex);

View File

@ -70,8 +70,8 @@ import com.cloud.network.VirtualRouterProvider.VirtualRouterProviderType;
import com.cloud.network.VpcVirtualNetworkApplianceService;
import com.cloud.network.addr.PublicIp;
import com.cloud.network.dao.PhysicalNetworkDao;
import com.cloud.network.firewall.NetworkACLService;
import com.cloud.network.rules.NetworkACL;
import com.cloud.network.vpc.NetworkACLManager;
import com.cloud.network.vpc.PrivateGateway;
import com.cloud.network.vpc.StaticRoute;
import com.cloud.network.vpc.StaticRouteProfile;
@ -104,15 +104,15 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian
private static final Logger s_logger = Logger.getLogger(VpcVirtualNetworkApplianceManagerImpl.class);
@Inject
VpcDao _vpcDao = null;
VpcDao _vpcDao;
@Inject
VpcOfferingDao _vpcOffDao = null;
VpcOfferingDao _vpcOffDao;
@Inject
PhysicalNetworkDao _pNtwkDao = null;
PhysicalNetworkDao _pNtwkDao;
@Inject
NetworkService _ntwkService = null;
NetworkService _ntwkService;
@Inject
NetworkACLService _networkACLService = null;
NetworkACLManager _networkACLMgr;
@Inject
VMInstanceDao _vmDao;
@Inject
@ -854,7 +854,7 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian
super.finalizeNetworkRulesForNetwork(cmds, router, provider, guestNetworkId);
if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.Firewall, Provider.VPCVirtualRouter)) {
List<? extends NetworkACL> networkACLs = _networkACLService.listNetworkACLs(guestNetworkId);
List<? extends NetworkACL> networkACLs = _networkACLMgr.listNetworkACLs(guestNetworkId);
s_logger.debug("Found " + networkACLs.size() + " network ACLs to apply as a part of VPC VR " + router
+ " start for guest network id=" + guestNetworkId);
if (!networkACLs.isEmpty()) {

View File

@ -27,7 +27,7 @@ public interface StaticRouteDao extends GenericDao<StaticRouteVO, Long>{
List<? extends StaticRoute> listByGatewayIdAndNotRevoked(long gatewayId);
List<? extends StaticRoute> listByVpcId(long vpcId);
List<StaticRouteVO> listByVpcId(long vpcId);
long countRoutesByGateway(long gatewayId);

View File

@ -80,7 +80,7 @@ public class StaticRouteDaoImpl extends GenericDaoBase<StaticRouteVO, Long> impl
}
@Override
public List<? extends StaticRoute> listByVpcId(long vpcId) {
public List<StaticRouteVO> listByVpcId(long vpcId) {
SearchCriteria<StaticRouteVO> sc = AllFieldsSearch.create();
sc.setParameters("vpcId", vpcId);
return listBy(sc);

View File

@ -32,5 +32,7 @@ public interface VpcDao extends GenericDao<VpcVO, Long>{
Vpc getActiveVpcById(long vpcId);
List<? extends Vpc> listByAccountId(long accountId);
List<VpcVO> listInactiveVpcs();
}

View File

@ -16,7 +16,6 @@ import java.util.List;
import javax.ejb.Local;
import com.cloud.domain.Domain.State;
import com.cloud.network.vpc.Vpc;
import com.cloud.network.vpc.VpcVO;
import com.cloud.utils.db.DB;
@ -66,7 +65,7 @@ public class VpcDaoImpl extends GenericDaoBase<VpcVO, Long> implements VpcDao{
public Vpc getActiveVpcById(long vpcId) {
SearchCriteria<VpcVO> sc = AllFieldsSearch.create();
sc.setParameters("id", vpcId);
sc.setParameters("state", State.Active);
sc.setParameters("state", Vpc.State.Enabled);
return findOneBy(sc);
}
@ -76,5 +75,12 @@ public class VpcDaoImpl extends GenericDaoBase<VpcVO, Long> implements VpcDao{
sc.setParameters("accountId", accountId);
return listBy(sc, null);
}
@Override
public List<VpcVO> listInactiveVpcs() {
SearchCriteria<VpcVO> sc = AllFieldsSearch.create();
sc.setParameters("state", Vpc.State.Inactive);
return listBy(sc, null);
}
}

View File

@ -0,0 +1,38 @@
// Copyright 2012 Citrix Systems, Inc. Licensed under the
// Apache License, Version 2.0 (the "License"); you may not use this
// file except in compliance with the License. Citrix Systems, Inc.
// reserves all rights not expressly granted by 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.
//
// Automatically generated by addcopyright.py at 04/03/2012
package com.cloud.network.vpc;
import java.util.List;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.firewall.NetworkACLService;
import com.cloud.network.rules.NetworkACL;
import com.cloud.user.Account;
/**
* @author Alena Prokharchyk
*/
public interface NetworkACLManager extends NetworkACLService{
/**
* @param networkId
* @param userId
* @param caller
* @return
* @throws ResourceUnavailableException
*/
boolean revokeAllNetworkACLsForNetwork(long networkId, long userId, Account caller) throws ResourceUnavailableException;
List<? extends NetworkACL> listNetworkACLs(long guestNtwkId);
}

View File

@ -63,8 +63,8 @@ import com.cloud.utils.net.NetUtils;
* @author Alena Prokharchyk
*/
@Local(value = { NetworkACLService.class})
public class NetworkACLManagerImpl implements Manager,NetworkACLService{
@Local(value = { NetworkACLService.class, NetworkACLManager.class})
public class NetworkACLManagerImpl implements Manager,NetworkACLManager{
String _name;
private static final Logger s_logger = Logger.getLogger(NetworkACLManagerImpl.class);
@ -289,7 +289,7 @@ public class NetworkACLManagerImpl implements Manager,NetworkACLService{
if (rule == null || rule.getPurpose() != Purpose.NetworkACL) {
throw new InvalidParameterValueException("Unable to find " + ruleId + " having purpose " + Purpose.NetworkACL);
}
_accountMgr.checkAccess(caller, null, true, rule);
_firewallMgr.revokeRule(rule, caller, userId, false);
@ -298,7 +298,7 @@ public class NetworkACLManagerImpl implements Manager,NetworkACLService{
if (apply) {
List<FirewallRuleVO> rules = _firewallDao.listByNetworkAndPurpose(rule.getNetworkId(), Purpose.NetworkACL);
return _firewallMgr.applyFirewallRules(rules, false, caller);
success = _firewallMgr.applyFirewallRules(rules, false, caller);
} else {
success = true;
}
@ -367,4 +367,30 @@ public class NetworkACLManagerImpl implements Manager,NetworkACLService{
return _firewallDao.listByNetworkAndPurpose(guestNtwkId, Purpose.NetworkACL);
}
@Override
public boolean revokeAllNetworkACLsForNetwork(long networkId, long userId, Account caller) throws ResourceUnavailableException {
List<FirewallRuleVO> ACLs = _firewallDao.listByNetworkAndPurposeAndNotRevoked(networkId, Purpose.NetworkACL);
if (s_logger.isDebugEnabled()) {
s_logger.debug("Releasing " + ACLs.size() + " Network ACLs for network id=" + networkId);
}
for (FirewallRuleVO ACL : ACLs) {
// Mark all Firewall rules as Revoke, but don't revoke them yet - we have to revoke all rules for ip, no
// need to send them one by one
revokeNetworkACL(ACL.getId(), false, caller, Account.ACCOUNT_ID_SYSTEM);
}
// now send everything to the backend
boolean success = _firewallMgr.applyFirewallRules(ACLs, false, caller);
if (s_logger.isDebugEnabled()) {
s_logger.debug("Successfully released Network ACLs for network id=" + networkId + " and # of rules now = " + ACLs.size());
}
// Now we check again in case more rules have been inserted.
ACLs.addAll(_firewallDao.listByNetworkAndPurposeAndNotRevoked(networkId, Purpose.Firewall));
return success && ACLs.size() == 0;
}
}

View File

@ -18,6 +18,9 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.ejb.Local;
import javax.naming.ConfigurationException;
@ -26,6 +29,7 @@ import org.apache.log4j.Logger;
import com.cloud.api.commands.ListPrivateGatewaysCmd;
import com.cloud.api.commands.ListStaticRoutesCmd;
import com.cloud.configuration.Config;
import com.cloud.configuration.ConfigurationManager;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.dc.DataCenter;
@ -67,11 +71,15 @@ import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.User;
import com.cloud.user.UserContext;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.Ternary;
import com.cloud.utils.component.ComponentLocator;
import com.cloud.utils.component.Inject;
import com.cloud.utils.component.Manager;
import com.cloud.utils.concurrency.NamedThreadFactory;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.Filter;
import com.cloud.utils.db.GlobalLock;
import com.cloud.utils.db.JoinBuilder;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
@ -84,6 +92,7 @@ import com.cloud.vm.ReservationContext;
import com.cloud.vm.ReservationContextImpl;
import com.cloud.vm.dao.DomainRouterDao;
/**
* @author Alena Prokharchyk
*/
@ -118,9 +127,12 @@ public class VpcManagerImpl implements VpcManager, Manager{
@Inject
StaticRouteDao _staticRouteDao;
private final ScheduledExecutorService _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("VpcChecker"));
private VpcProvider vpcElement = null;
String _name;
int _cleanupInterval;
@Override
@DB
@ -146,11 +158,18 @@ public class VpcManagerImpl implements VpcManager, Manager{
txn.commit();
ComponentLocator locator = ComponentLocator.getCurrentLocator();
ConfigurationDao configDao = locator.getDao(ConfigurationDao.class);
Map<String, String> configs = configDao.getConfiguration(params);
String value = configs.get(Config.VpcCleanupInterval.key());
_cleanupInterval = NumbersUtil.parseInt(value, 60 * 60); // 1 hour
return true;
}
@Override
public boolean start() {
_executor.scheduleAtFixedRate(new VpcCleanupTask(), _cleanupInterval, _cleanupInterval, TimeUnit.SECONDS);
return true;
}
@ -256,7 +275,7 @@ public class VpcManagerImpl implements VpcManager, Manager{
@Override
public Vpc getActiveVpc(long vpcId) {
return _vpcDao.findById(vpcId);
return _vpcDao.getActiveVpcById(vpcId);
}
@Override
@ -528,9 +547,9 @@ public class VpcManagerImpl implements VpcManager, Manager{
}
//mark VPC as disabled
s_logger.debug("Updating VPC " + vpc + " with state " + Vpc.State.Disabled + " as a part of vpc delete");
s_logger.debug("Updating VPC " + vpc + " with state " + Vpc.State.Inactive + " as a part of vpc delete");
VpcVO vpcVO = _vpcDao.findById(vpc.getId());
vpcVO.setState(Vpc.State.Disabled);
vpcVO.setState(Vpc.State.Inactive);
_vpcDao.update(vpc.getId(), vpcVO);
//shutdown VPC
@ -545,7 +564,9 @@ public class VpcManagerImpl implements VpcManager, Manager{
return false;
}
//update the instance with removed flag only when the cleanup is executed successfully
if (_vpcDao.remove(vpc.getId())) {
s_logger.debug("Vpc " + vpc + " is removed succesfully");
return true;
} else {
return false;
@ -712,7 +733,9 @@ public class VpcManagerImpl implements VpcManager, Manager{
//check if vpc exists
Vpc vpc = getActiveVpc(vpcId);
if (vpc == null) {
throw new InvalidParameterValueException("Unable to find Enabled vpc by id " + vpcId);
InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find Enabled VPC by id specified");
ex.addProxyObject("vpc", vpcId, "VPC");
throw ex;
}
//permission check
@ -871,10 +894,12 @@ public class VpcManagerImpl implements VpcManager, Manager{
return _vpcDao.listByAccountId(accountId);
}
public boolean cleanupVpcResources(long vpcId, Account caller, long callerUserId) {
public boolean cleanupVpcResources(long vpcId, Account caller, long callerUserId)
throws ResourceUnavailableException, ConcurrentOperationException {
s_logger.debug("Cleaning up resources for vpc id=" + vpcId);
boolean success = true;
// release all ip addresses
//1) release all ip addresses
List<IPAddressVO> ipsToRelease = _ipAddressDao.listByAssociatedVpc(vpcId, null);
s_logger.debug("Releasing ips for vpc id=" + vpcId + " as a part of vpc cleanup");
for (IPAddressVO ipToRelease : ipsToRelease) {
@ -882,6 +907,31 @@ public class VpcManagerImpl implements VpcManager, Manager{
if (!success) {
s_logger.warn("Failed to cleanup ip " + ipToRelease + " as a part of vpc id=" + vpcId + " cleanup");
}
}
if (success) {
s_logger.debug("Released ip addresses for vpc id=" + vpcId + " as a part of cleanup vpc process");
} else {
s_logger.warn("Failed to release ip addresses for vpc id=" + vpcId + " as a part of cleanup vpc process");
//although it failed, proceed to the next cleanup step as it doesn't depend on the public ip release
}
//2) Delete all static route rules
if (!revokeStaticRoutesForVpc(vpcId, caller)) {
s_logger.warn("Failed to revoke static routes for vpc " + vpcId + " as a part of cleanup vpc process");
return false;
}
//3) Delete private gateway
PrivateGateway gateway = getVpcPrivateGateway(vpcId);
if (gateway != null) {
s_logger.debug("Deleting private gateway " + gateway + " as a part of vpc " + vpcId + " resources cleanup");
if (!deleteVpcPrivateGateway(gateway.getId())) {
success = false;
s_logger.debug("Failed to delete private gateway " + gateway + " as a part of vpc " + vpcId + " resources cleanup");
} else {
s_logger.debug("Deleted private gateway " + gateway + " as a part of vpc " + vpcId + " resources cleanup");
}
}
return success;
@ -895,9 +945,11 @@ public class VpcManagerImpl implements VpcManager, Manager{
Account caller = UserContext.current().getCaller();
// Verify input parameters
VpcVO vpc = _vpcDao.findById(vpcId);
Vpc vpc = getActiveVpc(vpcId);
if (vpc == null) {
throw new InvalidParameterValueException("Unable to find vpc offering " + vpcId);
InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find Enabled VPC by id specified");
ex.addProxyObject("vpc", vpcId, "VPC");
throw ex;
}
_accountMgr.checkAccess(caller, null, false, vpc);
@ -905,7 +957,7 @@ public class VpcManagerImpl implements VpcManager, Manager{
s_logger.debug("Restarting VPC " + vpc);
boolean restartRequired = false;
try {
s_logger.debug("Shuttign down VPC " + vpc + " as a part of VPC restart process");
s_logger.debug("Shutting down VPC " + vpc + " as a part of VPC restart process");
if (!shutdownVpc(vpcId)) {
s_logger.warn("Failed to shutdown vpc as a part of VPC " + vpc + " restart process");
restartRequired = true;
@ -922,8 +974,9 @@ public class VpcManagerImpl implements VpcManager, Manager{
return true;
} finally {
s_logger.debug("Updating VPC " + vpc + " with restartRequired=" + restartRequired);
vpc.setRestartRequired(restartRequired);
_vpcDao.update(vpc.getId(), vpc);
VpcVO vo = _vpcDao.findById(vpcId);
vo.setRestartRequired(restartRequired);
_vpcDao.update(vpc.getId(), vo);
}
}
@ -957,9 +1010,11 @@ public class VpcManagerImpl implements VpcManager, Manager{
ConcurrentOperationException, InsufficientCapacityException {
//Validate parameters
Vpc vpc = getVpc(vpcId);
Vpc vpc = getActiveVpc(vpcId);
if (vpc == null) {
throw new InvalidParameterValueException("Unable to find VPC by id given");
InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find Enabled VPC by id specified");
ex.addProxyObject("vpc", vpcId, "VPC");
throw ex;
}
//allow only one private gateway per vpc
@ -1017,8 +1072,15 @@ public class VpcManagerImpl implements VpcManager, Manager{
if (gatewayVO == null || gatewayVO.getType() != VpcGateway.Type.Private) {
throw new InvalidParameterValueException("Can't find private gateway by id specified");
}
//don't allow to remove gateway when there are static routes associated with it
long routeCount = _staticRouteDao.countRoutesByGateway(gatewayVO.getId());
if (routeCount > 0) {
throw new CloudRuntimeException("Can't delete private gateway " + gatewayVO + " as it has " + routeCount +
" static routes applied. Remove the routes first");
}
//1) delete the gateaway on the backend
//1) delete the gateway on the backend
PrivateGateway gateway = getVpcPrivateGateway(gatewayId);
if (getVpcElement().deletePrivateGateway(gateway)) {
s_logger.debug("Private gateway " + gateway + " was applied succesfully on the backend");
@ -1027,22 +1089,15 @@ public class VpcManagerImpl implements VpcManager, Manager{
return false;
}
//2) Delete private gateway
return deletePrivateGateway(gateway);
//2) Delete private gateway from the DB
return deletePrivateGatewayFromTheDB(gateway);
}
@DB
public boolean deletePrivateGateway(PrivateGateway gateway) {
protected boolean deletePrivateGatewayFromTheDB(PrivateGateway gateway) {
//check if there are ips allocted in the network
long networkId = gateway.getNetworkId();
//don't allow to remove gateway when there are static routes associated with it
long routeCount = _staticRouteDao.countRoutesByGateway(gateway.getId());
if (routeCount > 0) {
throw new CloudRuntimeException("Can't delete private gateway " + gateway + " as it has " + routeCount +
" static routes applied. Remove the routes first");
}
boolean deleteNetwork = true;
List<PrivateIpVO> privateIps = _privateIpDao.listByNetworkId(networkId);
if (privateIps.size() > 1 || !privateIps.get(0).getIpAddress().equalsIgnoreCase(gateway.getIp4Address())) {
@ -1122,10 +1177,10 @@ public class VpcManagerImpl implements VpcManager, Manager{
public boolean applyStaticRoutes(long vpcId) throws ResourceUnavailableException {
Account caller = UserContext.current().getCaller();
List<? extends StaticRoute> routes = _staticRouteDao.listByVpcId(vpcId);
return applyStaticRoutes(routes, caller);
return applyStaticRoutes(routes, caller, true);
}
protected boolean applyStaticRoutes(List<? extends StaticRoute> routes, Account caller) throws ResourceUnavailableException {
protected boolean applyStaticRoutes(List<? extends StaticRoute> routes, Account caller, boolean updateRoutesInDB) throws ResourceUnavailableException {
boolean success = true;
List<StaticRouteProfile> staticRouteProfiles = new ArrayList<StaticRouteProfile>(routes.size());
Map<Long, PrivateGateway> gatewayMap = new HashMap<Long, PrivateGateway>();
@ -1141,15 +1196,19 @@ public class VpcManagerImpl implements VpcManager, Manager{
s_logger.warn("Routes are not completely applied");
return false;
} else {
for (StaticRoute route : routes) {
if (route.getState() == StaticRoute.State.Revoke) {
_staticRouteDao.remove(route.getId());
} else if (route.getState() == StaticRoute.State.Add) {
StaticRouteVO ruleVO = _staticRouteDao.findById(route.getId());
ruleVO.setState(StaticRoute.State.Active);
_staticRouteDao.update(ruleVO.getId(), ruleVO);
if (updateRoutesInDB) {
for (StaticRoute route : routes) {
if (route.getState() == StaticRoute.State.Revoke) {
_staticRouteDao.remove(route.getId());
s_logger.debug("Removed route " + route + " from the DB");
} else if (route.getState() == StaticRoute.State.Add) {
StaticRouteVO ruleVO = _staticRouteDao.findById(route.getId());
ruleVO.setState(StaticRoute.State.Active);
_staticRouteDao.update(ruleVO.getId(), ruleVO);
s_logger.debug("Marked route " + route + " with state " + StaticRoute.State.Active);
}
}
}
}
}
return success;
@ -1185,10 +1244,28 @@ public class VpcManagerImpl implements VpcManager, Manager{
_accountMgr.checkAccess(caller, null, false, route);
revokeStaticRoute(route, caller);
markStaticRouteForRevoke(route, caller);
return applyStaticRoutes(route.getVpcId());
}
@DB
protected boolean revokeStaticRoutesForVpc(long vpcId, Account caller) throws ResourceUnavailableException {
//get all static routes for the vpc
List<StaticRouteVO> routes = _staticRouteDao.listByVpcId(vpcId);
s_logger.debug("Found " + routes.size() + " to revoke for the vpc " + vpcId);
if (!routes.isEmpty()) {
//mark all of them as revoke
Transaction txn = Transaction.currentTxn();
txn.start();
for (StaticRouteVO route : routes) {
markStaticRouteForRevoke(route, caller);
}
txn.commit();
return applyStaticRoutes(vpcId);
}
return true;
}
@Override
@ -1203,7 +1280,10 @@ public class VpcManagerImpl implements VpcManager, Manager{
throw new InvalidParameterValueException("Invalid gateway id is given");
}
Vpc vpc = getVpc(gateway.getVpcId());
Vpc vpc = getActiveVpc(gateway.getVpcId());
if (vpc == null) {
throw new InvalidParameterValueException("Can't add static route to VPC that is being deleted");
}
_accountMgr.checkAccess(caller, null, false, vpc);
if (!NetUtils.isValidCIDR(cidr)){
@ -1293,7 +1373,7 @@ public class VpcManagerImpl implements VpcManager, Manager{
}
}
protected void revokeStaticRoute(StaticRouteVO route, Account caller) {
protected void markStaticRouteForRevoke(StaticRouteVO route, Account caller) {
s_logger.debug("Revoking static route " + route);
if (caller != null) {
_accountMgr.checkAccess(caller, null, false, route);
@ -1307,7 +1387,47 @@ public class VpcManagerImpl implements VpcManager, Manager{
} else if (route.getState() == StaticRoute.State.Add || route.getState() == StaticRoute.State.Active) {
route.setState(StaticRoute.State.Revoke);
_staticRouteDao.update(route.getId(), route);
s_logger.debug("Marked static route " + route + " with state " + StaticRoute.State.Revoke);
}
}
protected class VpcCleanupTask implements Runnable {
@Override
public void run() {
try {
GlobalLock lock = GlobalLock.getInternLock("VpcCleanup");
if (lock == null) {
s_logger.debug("Couldn't get the global lock");
return;
}
if (!lock.lock(30)) {
s_logger.debug("Couldn't lock the db");
return;
}
Transaction txn = null;
try {
txn = Transaction.open(Transaction.CLOUD_DB);
// Cleanup inactive VPCs
List<VpcVO> inactiveVpcs = _vpcDao.listInactiveVpcs();
s_logger.info("Found " + inactiveVpcs.size() + " removed VPCs to cleanup");
for (VpcVO vpc : inactiveVpcs) {
s_logger.debug("Cleaning up " + vpc);
destroyVpc(vpc);
}
} catch (Exception e) {
s_logger.error("Exception ", e);
} finally {
if (txn != null) {
txn.close();
}
lock.unlock();
}
} catch (Exception e) {
s_logger.error("Exception ", e);
}
}
}
}

View File

@ -69,7 +69,6 @@ import com.cloud.utils.Ternary;
import com.cloud.utils.component.Inject;
import com.cloud.utils.component.Manager;
import com.cloud.utils.concurrency.NamedThreadFactory;
import com.cloud.utils.AnnotationHelper;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.Filter;
import com.cloud.utils.db.JoinBuilder;

View File

@ -233,7 +233,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag
Map<String, String> configs = configDao.getConfiguration(params);
String value = configs.get(Config.AccountCleanupInterval.key());
_cleanupInterval = NumbersUtil.parseInt(value, 60 * 60 * 24); // 1 hour.
_cleanupInterval = NumbersUtil.parseInt(value, 60 * 60 * 24); // 1 day.
_userAuthenticators = locator.getAdapters(UserAuthenticator.class);
if (_userAuthenticators == null || !_userAuthenticators.isSet()) {