diff --git a/api/src/com/cloud/api/commands/CreateFirewallRuleCmd.java b/api/src/com/cloud/api/commands/CreateFirewallRuleCmd.java index 9a31e6a7bbe..b13228b37c9 100644 --- a/api/src/com/cloud/api/commands/CreateFirewallRuleCmd.java +++ b/api/src/com/cloud/api/commands/CreateFirewallRuleCmd.java @@ -72,11 +72,6 @@ public class CreateFirewallRuleCmd extends BaseAsyncCreateCmd implements Firewal @Parameter(name = ApiConstants.TYPE, type = CommandType.STRING, description = "type of firewallrule: system/user") private String type; - @IdentityMapper(entityTableName="networks") - @Parameter(name=ApiConstants.NETWORK_ID, type=CommandType.LONG, - description="The network of the vm the Firewall rule will be created for") - private Long networkId; - // /////////////////////////////////////////////////// // ///////////////// Accessors /////////////////////// // /////////////////////////////////////////////////// @@ -197,9 +192,8 @@ public class CreateFirewallRuleCmd extends BaseAsyncCreateCmd implements Firewal if (ip.getAssociatedWithNetworkId() != null) { ntwkId = ip.getAssociatedWithNetworkId(); - } else { - ntwkId = networkId; } + if (ntwkId == null) { throw new InvalidParameterValueException("Unable to create firewall rule for the ipAddress id=" + ipAddressId + " as ip is not associated with any network and no networkId is passed in"); diff --git a/api/src/com/cloud/api/commands/CreateLoadBalancerRuleCmd.java b/api/src/com/cloud/api/commands/CreateLoadBalancerRuleCmd.java index b4aed0b68c3..fc6cf8b4ac3 100644 --- a/api/src/com/cloud/api/commands/CreateLoadBalancerRuleCmd.java +++ b/api/src/com/cloud/api/commands/CreateLoadBalancerRuleCmd.java @@ -87,7 +87,8 @@ public class CreateLoadBalancerRuleCmd extends BaseAsyncCreateCmd /*implements private List cidrlist; @IdentityMapper(entityTableName="networks") - @Parameter(name=ApiConstants.NETWORK_ID, type=CommandType.LONG, description="The guest network this rule will be created for") + @Parameter(name=ApiConstants.NETWORK_ID, type=CommandType.LONG, description="The guest network this " + + "rule will be created for. Required when public Ip address is not associated with any Guest network yet (VPC case)") private Long networkId; ///////////////////////////////////////////////////// diff --git a/api/src/com/cloud/api/commands/CreatePortForwardingRuleCmd.java b/api/src/com/cloud/api/commands/CreatePortForwardingRuleCmd.java index 61f67af8f7e..2553d7eada3 100644 --- a/api/src/com/cloud/api/commands/CreatePortForwardingRuleCmd.java +++ b/api/src/com/cloud/api/commands/CreatePortForwardingRuleCmd.java @@ -79,7 +79,8 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P @IdentityMapper(entityTableName="networks") @Parameter(name=ApiConstants.NETWORK_ID, type=CommandType.LONG, - description="The network of the vm the Port Forwarding rule will be created for") + description="The network of the vm the Port Forwarding rule will be created for. " + + "Required when public Ip address is not associated with any Guest network yet (VPC case)") private Long networkId; // /////////////////////////////////////////////////// diff --git a/api/src/com/cloud/api/commands/CreateRemoteAccessVpnCmd.java b/api/src/com/cloud/api/commands/CreateRemoteAccessVpnCmd.java index b783adf781a..7964166b009 100644 --- a/api/src/com/cloud/api/commands/CreateRemoteAccessVpnCmd.java +++ b/api/src/com/cloud/api/commands/CreateRemoteAccessVpnCmd.java @@ -58,11 +58,6 @@ public class CreateRemoteAccessVpnCmd extends BaseAsyncCreateCmd { @Parameter(name = ApiConstants.OPEN_FIREWALL, type = CommandType.BOOLEAN, description = "if true, firewall rule for source/end pubic port is automatically created; if false - firewall rule has to be created explicitely. Has value true by default") private Boolean openFirewall; - @IdentityMapper(entityTableName="networks") - @Parameter(name=ApiConstants.NETWORK_ID, type=CommandType.LONG, - description="The network of the ip the VPN be created for") - private Long networkId; - ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -136,9 +131,8 @@ public class CreateRemoteAccessVpnCmd extends BaseAsyncCreateCmd { if (ip.getAssociatedWithNetworkId() != null) { ntwkId = ip.getAssociatedWithNetworkId(); - } else { - ntwkId = networkId; } + if (ntwkId == null) { throw new InvalidParameterValueException("Unable to create remote access vpn for the ipAddress id=" + getPublicIpId() + " as ip is not associated with any network and no networkId is passed in"); diff --git a/api/src/com/cloud/api/commands/EnableStaticNatCmd.java b/api/src/com/cloud/api/commands/EnableStaticNatCmd.java index 8c0c9ac5a65..a8cd131f1c2 100644 --- a/api/src/com/cloud/api/commands/EnableStaticNatCmd.java +++ b/api/src/com/cloud/api/commands/EnableStaticNatCmd.java @@ -50,7 +50,8 @@ public class EnableStaticNatCmd extends BaseCmd{ @IdentityMapper(entityTableName="networks") @Parameter(name=ApiConstants.NETWORK_ID, type=CommandType.LONG, - description="The network of the vm the static nat will be enabled for.") + description="The network of the vm the static nat will be enabled for." + + " Required when public Ip address is not associated with any Guest network yet (VPC case)") private Long networkId; ///////////////////////////////////////////////////// diff --git a/api/src/com/cloud/network/firewall/NetworkACLService.java b/api/src/com/cloud/network/firewall/NetworkACLService.java index d556844da2c..3cdb0583aae 100644 --- a/api/src/com/cloud/network/firewall/NetworkACLService.java +++ b/api/src/com/cloud/network/firewall/NetworkACLService.java @@ -44,6 +44,4 @@ public interface NetworkACLService { */ List listNetworkACLs(ListNetworkACLsCmd cmd); - List listNetworkACLs(long guestNtwkId); - } diff --git a/api/src/com/cloud/network/vpc/Vpc.java b/api/src/com/cloud/network/vpc/Vpc.java index 5e15bab1732..5efd2e859c8 100644 --- a/api/src/com/cloud/network/vpc/Vpc.java +++ b/api/src/com/cloud/network/vpc/Vpc.java @@ -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(); diff --git a/server/src/com/cloud/configuration/Config.java b/server/src/com/cloud/configuration/Config.java index dea61399a17..37da9d8561e 100755 --- a/server/src/com/cloud/configuration/Config.java +++ b/server/src/com/cloud/configuration/Config.java @@ -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; diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 2b810cfcd70..8e84d6422d6 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -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 ipsToRelease = _ipAddressDao.listByAssociatedNetwork(networkId, null); for (IPAddressVO ipToRelease : ipsToRelease) { if (ipToRelease.getVpcId() != null) { diff --git a/server/src/com/cloud/network/firewall/FirewallManagerImpl.java b/server/src/com/cloud/network/firewall/FirewallManagerImpl.java index a364dbc48d0..1c1c882bb73 100644 --- a/server/src/com/cloud/network/firewall/FirewallManagerImpl.java +++ b/server/src/com/cloud/network/firewall/FirewallManagerImpl.java @@ -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); } diff --git a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java index f00a4ccb671..a777d9ad787 100755 --- a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java +++ b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java @@ -47,7 +47,6 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.NetworkRuleConflictException; import com.cloud.exception.PermissionDeniedException; import com.cloud.exception.ResourceUnavailableException; -import com.cloud.network.dao.NetworkServiceMapDao; import com.cloud.network.ExternalLoadBalancerUsageManager; import com.cloud.network.IPAddressVO; import com.cloud.network.IpAddress; @@ -67,7 +66,7 @@ import com.cloud.network.dao.LBStickinessPolicyDao; import com.cloud.network.dao.LoadBalancerDao; import com.cloud.network.dao.LoadBalancerVMMapDao; import com.cloud.network.dao.NetworkDao; -import com.cloud.network.element.NetworkElement; +import com.cloud.network.dao.NetworkServiceMapDao; import com.cloud.network.lb.LoadBalancingRule.LbDestination; import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy; import com.cloud.network.rules.FirewallManager; @@ -99,7 +98,6 @@ import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; -import com.cloud.utils.AnnotationHelper; import com.cloud.vm.Nic; import com.cloud.vm.UserVmVO; import com.cloud.vm.VirtualMachine.State; @@ -708,19 +706,17 @@ public class LoadBalancingRulesManagerImpl 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()); } - - _networkMgr.checkIpForService(ipAddressVo, Service.Lb); } LoadBalancer result = _elbMgr.handleCreateLoadBalancerRule(lb, lbOwner, lb.getNetworkId()); @@ -728,15 +724,22 @@ public class LoadBalancingRulesManagerImpl 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"); } result = createLoadBalancer(lb, openFirewall); } catch (Exception ex) { diff --git a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java index cc87960ff89..cc473aba819 100644 --- a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java @@ -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 networkACLs = _networkACLService.listNetworkACLs(guestNetworkId); + List 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()) { diff --git a/server/src/com/cloud/network/vpc/Dao/StaticRouteDao.java b/server/src/com/cloud/network/vpc/Dao/StaticRouteDao.java index d5a7d35cd2c..a9515e8baab 100644 --- a/server/src/com/cloud/network/vpc/Dao/StaticRouteDao.java +++ b/server/src/com/cloud/network/vpc/Dao/StaticRouteDao.java @@ -27,7 +27,7 @@ public interface StaticRouteDao extends GenericDao{ List listByGatewayIdAndNotRevoked(long gatewayId); - List listByVpcId(long vpcId); + List listByVpcId(long vpcId); long countRoutesByGateway(long gatewayId); diff --git a/server/src/com/cloud/network/vpc/Dao/StaticRouteDaoImpl.java b/server/src/com/cloud/network/vpc/Dao/StaticRouteDaoImpl.java index d88b89f04f0..d4b195b00e8 100644 --- a/server/src/com/cloud/network/vpc/Dao/StaticRouteDaoImpl.java +++ b/server/src/com/cloud/network/vpc/Dao/StaticRouteDaoImpl.java @@ -80,7 +80,7 @@ public class StaticRouteDaoImpl extends GenericDaoBase impl } @Override - public List listByVpcId(long vpcId) { + public List listByVpcId(long vpcId) { SearchCriteria sc = AllFieldsSearch.create(); sc.setParameters("vpcId", vpcId); return listBy(sc); diff --git a/server/src/com/cloud/network/vpc/Dao/VpcDao.java b/server/src/com/cloud/network/vpc/Dao/VpcDao.java index 75fd56e88b7..ac8b0d4ad51 100644 --- a/server/src/com/cloud/network/vpc/Dao/VpcDao.java +++ b/server/src/com/cloud/network/vpc/Dao/VpcDao.java @@ -32,5 +32,7 @@ public interface VpcDao extends GenericDao{ Vpc getActiveVpcById(long vpcId); List listByAccountId(long accountId); + + List listInactiveVpcs(); } diff --git a/server/src/com/cloud/network/vpc/Dao/VpcDaoImpl.java b/server/src/com/cloud/network/vpc/Dao/VpcDaoImpl.java index 6d6b03c220b..e0ea5d920f3 100644 --- a/server/src/com/cloud/network/vpc/Dao/VpcDaoImpl.java +++ b/server/src/com/cloud/network/vpc/Dao/VpcDaoImpl.java @@ -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 implements VpcDao{ public Vpc getActiveVpcById(long vpcId) { SearchCriteria 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 implements VpcDao{ sc.setParameters("accountId", accountId); return listBy(sc, null); } + + @Override + public List listInactiveVpcs() { + SearchCriteria sc = AllFieldsSearch.create(); + sc.setParameters("state", Vpc.State.Inactive); + return listBy(sc, null); + } } diff --git a/server/src/com/cloud/network/vpc/NetworkACLManager.java b/server/src/com/cloud/network/vpc/NetworkACLManager.java new file mode 100644 index 00000000000..01f54f01b2f --- /dev/null +++ b/server/src/com/cloud/network/vpc/NetworkACLManager.java @@ -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 listNetworkACLs(long guestNtwkId); + +} diff --git a/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java b/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java index be30e8cc1a9..e546565d746 100644 --- a/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java +++ b/server/src/com/cloud/network/vpc/NetworkACLManagerImpl.java @@ -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 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 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; + } + } diff --git a/server/src/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/com/cloud/network/vpc/VpcManagerImpl.java index 1bad9dccf27..b4323a75669 100644 --- a/server/src/com/cloud/network/vpc/VpcManagerImpl.java +++ b/server/src/com/cloud/network/vpc/VpcManagerImpl.java @@ -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 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 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 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 routes = _staticRouteDao.listByVpcId(vpcId); - return applyStaticRoutes(routes, caller); + return applyStaticRoutes(routes, caller, true); } - protected boolean applyStaticRoutes(List routes, Account caller) throws ResourceUnavailableException { + protected boolean applyStaticRoutes(List routes, Account caller, boolean updateRoutesInDB) throws ResourceUnavailableException { boolean success = true; List staticRouteProfiles = new ArrayList(routes.size()); Map gatewayMap = new HashMap(); @@ -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 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 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); + } + } } } diff --git a/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java b/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java index 39dbea96463..9290044e324 100755 --- a/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java +++ b/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java @@ -120,18 +120,6 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag } IPAddressVO ipAddress = _ipAddressDao.findById(publicIpId); - - //associate ip address to network (if needed) - if (ipAddress.getAssociatedWithNetworkId() == null) { - s_logger.debug("The ip is not associated with the network id="+ networkId + " so assigning"); - try { - ipAddress = _networkMgr.associateIPToGuestNetwork(publicIpId, networkId); - } catch (Exception ex) { - s_logger.warn("Failed to associate ip id=" + publicIpId + " to network id=" + networkId + " as " + - "a part of remote access vpn creation"); - return null; - } - } _networkMgr.checkIpForService(ipAddress, Service.Vpn); RemoteAccessVpnVO vpnVO = _remoteAccessVpnDao.findByPublicIpAddress(publicIpId); diff --git a/server/src/com/cloud/projects/ProjectManagerImpl.java b/server/src/com/cloud/projects/ProjectManagerImpl.java index 01fdeda84a9..9b06e49a58f 100755 --- a/server/src/com/cloud/projects/ProjectManagerImpl.java +++ b/server/src/com/cloud/projects/ProjectManagerImpl.java @@ -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; diff --git a/server/src/com/cloud/user/AccountManagerImpl.java b/server/src/com/cloud/user/AccountManagerImpl.java index fc26dd8e0d7..9e091164797 100755 --- a/server/src/com/cloud/user/AccountManagerImpl.java +++ b/server/src/com/cloud/user/AccountManagerImpl.java @@ -233,7 +233,7 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag Map 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()) { diff --git a/ui/scripts/cloudStack.js b/ui/scripts/cloudStack.js index c528a154dfd..809faa56971 100644 --- a/ui/scripts/cloudStack.js +++ b/ui/scripts/cloudStack.js @@ -62,14 +62,31 @@ dataType: 'json', cache: false, error: function(data) { - cloudStack.dialog.notice({ message: parseXMLHttpResponse(data) }); + var clickAction = false; + if (isValidJsonString(data.responseText)) { + var json = JSON.parse(data.responseText); + if (json != null) { + var property; + for(property in json) {} + var errorObj = json[property]; + if(errorObj.errorcode == 401 && errorObj.errortext == "unable to verify user credentials and/or request signature") { + clickAction = function() { + $('#user-options a').eq(0).trigger('click'); + }; + } + } + } + cloudStack.dialog.notice({ message: parseXMLHttpResponse(data), clickAction: clickAction }); }, - beforeSend: function(XMLHttpRequest) { + beforeSend: function(XMLHttpRequest) { if (g_mySession == $.cookie("JSESSIONID")) { return true; } else { - cloudStack.dialog.notice({ message: _l('label.session.expired') }); + var clickAction = function() { + $('#user-options a').eq(0).trigger('click'); + }; + cloudStack.dialog.notice({ message: _l('label.session.expired'), clickAction: clickAction }); return false; } }