fix bug CLOUDSTACK-2341 remove network from VM is not removing PF/LB/static nat rules for the VM

This commit is contained in:
Mice Xia 2013-05-09 11:03:43 +08:00
parent 3c59747635
commit 6ef615e40d
5 changed files with 92 additions and 13 deletions

View File

@ -24,6 +24,7 @@ import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.IpAddress;
import com.cloud.user.Account;
import com.cloud.uservm.UserVm;
import com.cloud.vm.Nic;
import com.cloud.vm.VirtualMachine;
/**
@ -87,4 +88,6 @@ public interface RulesManager extends RulesService {
*/
boolean applyStaticNatForNetwork(long networkId, boolean continueOnError, Account caller, boolean forRevoke);
List<FirewallRuleVO> listAssociatedRulesForGuestNic(Nic nic);
}

View File

@ -50,8 +50,11 @@ import com.cloud.network.dao.FirewallRulesCidrsDao;
import com.cloud.network.dao.FirewallRulesDao;
import com.cloud.network.dao.IPAddressDao;
import com.cloud.network.dao.IPAddressVO;
import com.cloud.network.dao.LoadBalancerVMMapDao;
import com.cloud.network.dao.LoadBalancerVMMapVO;
import com.cloud.network.rules.FirewallRule.FirewallRuleType;
import com.cloud.network.rules.FirewallRule.Purpose;
import com.cloud.network.rules.FirewallRule.TrafficType;
import com.cloud.network.rules.dao.PortForwardingRulesDao;
import com.cloud.network.vpc.VpcManager;
import com.cloud.offering.NetworkOffering;
@ -77,6 +80,7 @@ import com.cloud.utils.db.SearchCriteria.Op;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.net.Ip;
import com.cloud.utils.net.NetUtils;
import com.cloud.vm.Nic;
import com.cloud.vm.NicSecondaryIp;
import com.cloud.vm.UserVmVO;
@ -132,6 +136,8 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
VpcManager _vpcMgr;
@Inject
NicSecondaryIpDao _nicSecondaryDao;
@Inject
LoadBalancerVMMapDao _loadBalancerVMMapDao;
@Override
public void checkIpAndUserVm(IpAddress ipAddress, UserVm userVm, Account caller) {
@ -1467,4 +1473,36 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
protected void removePFRule(PortForwardingRuleVO rule) {
_portForwardingDao.remove(rule.getId());
}
@Override
public List<FirewallRuleVO> listAssociatedRulesForGuestNic(Nic nic){
List<FirewallRuleVO> result = new ArrayList<FirewallRuleVO>();
// add PF rules
result.addAll(_portForwardingDao.listByDestIpAddr(nic.getIp4Address()));
// add static NAT rules
List<FirewallRuleVO> staticNatRules = _firewallDao.listStaticNatByVmId(nic.getInstanceId());
for(FirewallRuleVO rule : staticNatRules){
if(rule.getNetworkId() == nic.getNetworkId())
result.add(rule);
}
List<? extends IpAddress> staticNatIps = _ipAddressDao.listStaticNatPublicIps(nic.getNetworkId());
for(IpAddress ip : staticNatIps){
if(ip.getVmIp() != null && ip.getVmIp().equals(nic.getIp4Address())){
VMInstanceVO vm = _vmInstanceDao.findById(nic.getInstanceId());
// generate a static Nat rule on the fly because staticNATrule does not persist into db anymore
// FIX ME
FirewallRuleVO staticNatRule = new FirewallRuleVO(null, ip.getId(), 0, 65535, NetUtils.ALL_PROTO.toString(),
nic.getNetworkId(), vm.getAccountId(), vm.getDomainId(), Purpose.StaticNat, null, null, null, null, null);
result.add(staticNatRule);
}
}
// add LB rules
List<LoadBalancerVMMapVO> lbMapList = _loadBalancerVMMapDao.listByInstanceId(nic.getInstanceId());
for(LoadBalancerVMMapVO lb : lbMapList){
FirewallRuleVO lbRule = _firewallDao.findById(lb.getLoadBalancerId());
if(lbRule.getNetworkId() == nic.getNetworkId())
result.add(lbRule);
}
return result;
}
}

View File

@ -831,6 +831,12 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use
if(network == null) {
throw new InvalidParameterValueException("unable to find a network with id " + networkId);
}
List<NicVO> allNics = _nicDao.listByVmId(vmInstance.getId());
for(NicVO nic : allNics){
if(nic.getNetworkId() == network.getId())
throw new CloudRuntimeException("A NIC already exists for VM:" + vmInstance.getInstanceName() + " in network: " + network.getUuid());
}
NicProfile profile = new NicProfile(null, null);
if(ipAddress != null) {
profile = new NicProfile(ipAddress, null);

View File

@ -24,7 +24,6 @@ import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -37,40 +36,56 @@ import javax.ejb.Local;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import com.cloud.capacity.CapacityManager;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import com.cloud.dc.*;
import com.cloud.agent.api.*;
import org.apache.log4j.Logger;
import com.cloud.agent.AgentManager;
import com.cloud.agent.AgentManager.OnError;
import com.cloud.agent.Listener;
import com.cloud.agent.api.AgentControlAnswer;
import com.cloud.agent.api.AgentControlCommand;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.CheckVirtualMachineAnswer;
import com.cloud.agent.api.CheckVirtualMachineCommand;
import com.cloud.agent.api.ClusterSyncAnswer;
import com.cloud.agent.api.ClusterSyncCommand;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.MigrateAnswer;
import com.cloud.agent.api.MigrateCommand;
import com.cloud.agent.api.PingRoutingCommand;
import com.cloud.agent.api.PrepareForMigrationAnswer;
import com.cloud.agent.api.PrepareForMigrationCommand;
import com.cloud.agent.api.RebootAnswer;
import com.cloud.agent.api.RebootCommand;
import com.cloud.agent.api.ScaleVmCommand;
import com.cloud.agent.api.StartAnswer;
import com.cloud.agent.api.StartCommand;
import com.cloud.agent.api.StartupCommand;
import com.cloud.agent.api.StartupRoutingCommand;
import com.cloud.agent.api.StartupRoutingCommand.VmState;
import com.cloud.agent.api.StopAnswer;
import com.cloud.agent.api.StopCommand;
import com.cloud.agent.api.to.NicTO;
import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.agent.api.to.StorageFilerTO;
import com.cloud.agent.api.to.VolumeTO;
import com.cloud.agent.manager.Commands;
import com.cloud.agent.manager.allocator.HostAllocator;
import com.cloud.alert.AlertManager;
import com.cloud.capacity.CapacityManager;
import com.cloud.cluster.ClusterManager;
import com.cloud.configuration.Config;
import com.cloud.configuration.ConfigurationManager;
import com.cloud.configuration.Resource.ResourceType;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.dc.dao.ClusterDao;
import com.cloud.dc.ClusterDetailsDao;
import com.cloud.dc.ClusterDetailsVO;
import com.cloud.dc.DataCenter;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.HostPodVO;
import com.cloud.consoleproxy.ConsoleProxyManager;
import com.cloud.dc.dao.ClusterDao;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.dc.dao.HostPodDao;
import com.cloud.deploy.DataCenterDeployment;
@ -109,6 +124,7 @@ import com.cloud.network.NetworkManager;
import com.cloud.network.NetworkModel;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkVO;
import com.cloud.network.rules.RulesManager;
import com.cloud.offering.ServiceOffering;
import com.cloud.org.Cluster;
import com.cloud.resource.ResourceManager;
@ -126,9 +142,9 @@ import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.DiskOfferingDao;
import com.cloud.storage.dao.GuestOSCategoryDao;
import com.cloud.storage.dao.GuestOSDao;
import com.cloud.storage.dao.StoragePoolHostDao;
import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.storage.dao.VolumeDao;
import com.cloud.storage.dao.StoragePoolHostDao;
import com.cloud.storage.snapshot.SnapshotManager;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
@ -154,12 +170,12 @@ import com.cloud.vm.VirtualMachine.Event;
import com.cloud.vm.VirtualMachine.State;
import com.cloud.vm.dao.NicDao;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.UserVmDetailsDao;
import com.cloud.vm.dao.VMInstanceDao;
import com.cloud.vm.snapshot.VMSnapshot;
import com.cloud.vm.snapshot.VMSnapshotManager;
import com.cloud.vm.snapshot.VMSnapshotVO;
import com.cloud.vm.snapshot.dao.VMSnapshotDao;
import com.cloud.vm.dao.UserVmDetailsDao;
@Local(value = VirtualMachineManager.class)
public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMachineManager, Listener {
@ -235,6 +251,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
protected VolumeDataFactory volFactory;
@Inject
protected ResourceLimitService _resourceLimitMgr;
@Inject
protected RulesManager rulesMgr;
protected List<DeploymentPlanner> _planners;
public List<DeploymentPlanner> getPlanners() {
@ -2845,6 +2863,12 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
s_logger.warn("Failed to remove nic from " + vm + " in " + network + ", nic is default.");
throw new CloudRuntimeException("Failed to remove nic from " + vm + " in " + network + ", nic is default.");
}
// if specified nic is associated with PF/LB/Static NAT
if(rulesMgr.listAssociatedRulesForGuestNic(nic).size() > 0){
throw new CloudRuntimeException("Failed to remove nic from " + vm + " in " + network
+ ", nic has associated Port forwarding or Load balancer or Static NAT rules.");
}
NicProfile nicProfile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(),
_networkModel.getNetworkRate(network.getId(), vm.getId()),

View File

@ -28,6 +28,7 @@ import com.cloud.exception.InsufficientAddressCapacityException;
import com.cloud.exception.NetworkRuleConflictException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.rules.FirewallRule;
import com.cloud.network.rules.FirewallRuleVO;
import com.cloud.network.rules.PortForwardingRule;
import com.cloud.network.rules.PortForwardingRuleVO;
import com.cloud.network.rules.RulesManager;
@ -40,6 +41,7 @@ import com.cloud.utils.Pair;
import com.cloud.utils.component.Manager;
import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.net.Ip;
import com.cloud.vm.Nic;
import com.cloud.vm.VirtualMachine;
@Local(value = {RulesManager.class, RulesService.class})
@ -310,4 +312,10 @@ public class MockRulesManagerImpl extends ManagerBase implements RulesManager, R
return null;
}
@Override
public List<FirewallRuleVO> listAssociatedRulesForGuestNic(Nic nic) {
// TODO Auto-generated method stub
return null;
}
}