From 88d6ff213696f891c4f7f6882a283a8124f70a01 Mon Sep 17 00:00:00 2001 From: alena Date: Fri, 10 Dec 2010 11:53:15 -0800 Subject: [PATCH] bug 7467: release IP address works now. status 7467: resolved fixed Fixed all load balancer commands to work with the latest networking code --- .../routing/LoadBalancerConfigCommand.java | 9 +- .../commands/AssignToLoadBalancerRuleCmd.java | 22 +-- .../commands/CreateLoadBalancerRuleCmd.java | 7 - .../RemoveFromLoadBalancerRuleCmd.java | 32 +--- .../commands/UpdateLoadBalancerRuleCmd.java | 10 +- .../cloud/network/lb/LoadBalancingRule.java | 139 ++++++++++++++++++ .../network/lb/LoadBalancingRulesService.java | 2 +- .../com/cloud/network/rules/LoadBalancer.java | 11 +- client/tomcatconf/commands.properties.in | 2 +- .../cloud/network/LoadBalancerVMMapVO.java | 16 +- .../src/com/cloud/network/LoadBalancerVO.java | 18 ++- .../network/dao/LoadBalancerDaoImpl.java | 1 + .../network/dao/LoadBalancerVMMapDao.java | 4 +- .../network/dao/LoadBalancerVMMapDaoImpl.java | 18 ++- .../lb/LoadBalancingRulesManagerImpl.java | 139 ++++++++++++++++-- server/src/com/cloud/vm/dao/NicDao.java | 1 + server/src/com/cloud/vm/dao/NicDaoImpl.java | 8 + setup/db/create-schema.sql | 2 +- 18 files changed, 329 insertions(+), 112 deletions(-) create mode 100644 api/src/com/cloud/network/lb/LoadBalancingRule.java diff --git a/api/src/com/cloud/agent/api/routing/LoadBalancerConfigCommand.java b/api/src/com/cloud/agent/api/routing/LoadBalancerConfigCommand.java index b807bd46b79..8a8925ce1ef 100644 --- a/api/src/com/cloud/agent/api/routing/LoadBalancerConfigCommand.java +++ b/api/src/com/cloud/agent/api/routing/LoadBalancerConfigCommand.java @@ -19,8 +19,7 @@ package com.cloud.agent.api.routing; import java.util.List; -import com.cloud.network.rules.LoadBalancer; -import com.cloud.network.rules.LoadBalancer.Destination; +import com.cloud.network.lb.LoadBalancingRule.LbDestination; /** * LoadBalancerConfigCommand sends the load balancer configuration @@ -35,7 +34,7 @@ public class LoadBalancerConfigCommand extends RoutingCommand { boolean alreadyAdded; DestinationTO[] destinations; - public LoadBalancerConfigCommand(String srcIp, int srcPort, String protocol, String algorithm, boolean revoked, boolean alreadyAdded, List destinations) { + public LoadBalancerConfigCommand(String srcIp, int srcPort, String protocol, String algorithm, boolean revoked, boolean alreadyAdded, List destinations) { this.srcIp = srcIp; this.srcPort = srcPort; this.protocol = protocol; @@ -44,8 +43,8 @@ public class LoadBalancerConfigCommand extends RoutingCommand { this.alreadyAdded = alreadyAdded; this.destinations = new DestinationTO[destinations.size()]; int i = 0; - for (Destination destination : destinations) { - this.destinations[i++] = new DestinationTO(destination.getIpAddress(), destination.getDestinationPortStart(), destination.getRevoked(), destination.getAlreadyAdded()); + for (LbDestination destination : destinations) { + this.destinations[i++] = new DestinationTO(destination.getIpAddress(), destination.getDestinationPortStart(), destination.isRevoked(), false); } } diff --git a/api/src/com/cloud/api/commands/AssignToLoadBalancerRuleCmd.java b/api/src/com/cloud/api/commands/AssignToLoadBalancerRuleCmd.java index 30c3e8fd748..c68eac39487 100644 --- a/api/src/com/cloud/api/commands/AssignToLoadBalancerRuleCmd.java +++ b/api/src/com/cloud/api/commands/AssignToLoadBalancerRuleCmd.java @@ -17,7 +17,6 @@ */ package com.cloud.api.commands; -import java.util.ArrayList; import java.util.List; import org.apache.log4j.Logger; @@ -30,9 +29,9 @@ import com.cloud.api.Parameter; import com.cloud.api.ServerApiException; import com.cloud.api.response.SuccessResponse; import com.cloud.event.EventTypes; -import com.cloud.exception.InvalidParameterValueException; import com.cloud.network.rules.LoadBalancer; import com.cloud.user.Account; +import com.cloud.utils.StringUtils; @Implementation(description="Assigns virtual machine or a list of virtual machines to a load balancer rule.", responseObject=SuccessResponse.class) public class AssignToLoadBalancerRuleCmd extends BaseAsyncCmd { @@ -46,9 +45,6 @@ public class AssignToLoadBalancerRuleCmd extends BaseAsyncCmd { @Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="the ID of the load balancer rule") private Long id; - - @Parameter(name=ApiConstants.VIRTUAL_MACHINE_ID, type=CommandType.LONG, required=false, description="the ID of the virtual machine that is being assigned to the load balancer rule") - private Long virtualMachineId; @Parameter(name=ApiConstants.VIRTUAL_MACHINE_IDS, type=CommandType.LIST, collectionType=CommandType.LONG, required=false, description="the list of IDs of the virtual machine that are being assigned to the load balancer rule(i.e. virtualMachineIds=1,2,3)") private List virtualMachineIds; @@ -61,10 +57,6 @@ public class AssignToLoadBalancerRuleCmd extends BaseAsyncCmd { return id; } - public Long getVirtualMachineId() { - return virtualMachineId; - } - public List getVirtualMachineIds() { return virtualMachineIds; } @@ -94,21 +86,11 @@ public class AssignToLoadBalancerRuleCmd extends BaseAsyncCmd { @Override public String getEventDescription() { - return "applying port forwarding service for vm with id: " + getVirtualMachineId(); + return "applying instances for load balancer: " + getLoadBalancerId() + " (ids: " + StringUtils.join(getVirtualMachineIds(), ",") + ")"; } @Override public void execute(){ - if (virtualMachineIds == null && virtualMachineId == null) { - throw new InvalidParameterValueException("Must specify virtual machine id"); - } - if (virtualMachineIds == null) { - virtualMachineIds = new ArrayList(); - } - - if (virtualMachineId != null) { - virtualMachineIds.add(virtualMachineId); - } boolean result = _lbService.assignToLoadBalancer(getLoadBalancerId(), virtualMachineIds); if (result) { SuccessResponse response = new SuccessResponse(getCommandName()); diff --git a/api/src/com/cloud/api/commands/CreateLoadBalancerRuleCmd.java b/api/src/com/cloud/api/commands/CreateLoadBalancerRuleCmd.java index fa3b6d9ce9b..3cfd62f8ca5 100644 --- a/api/src/com/cloud/api/commands/CreateLoadBalancerRuleCmd.java +++ b/api/src/com/cloud/api/commands/CreateLoadBalancerRuleCmd.java @@ -18,8 +18,6 @@ package com.cloud.api.commands; -import java.util.List; - import org.apache.log4j.Logger; import com.cloud.api.ApiConstants; @@ -185,10 +183,5 @@ public class CreateLoadBalancerRuleCmd extends BaseCmd implements LoadBalancer public int getDefaultPortEnd() { return Integer.parseInt(privatePort); } - - @Override - public List getDestinations() { - throw new UnsupportedOperationException("not supported"); - } } diff --git a/api/src/com/cloud/api/commands/RemoveFromLoadBalancerRuleCmd.java b/api/src/com/cloud/api/commands/RemoveFromLoadBalancerRuleCmd.java index c72b79cf197..07c9f51d070 100644 --- a/api/src/com/cloud/api/commands/RemoveFromLoadBalancerRuleCmd.java +++ b/api/src/com/cloud/api/commands/RemoveFromLoadBalancerRuleCmd.java @@ -17,7 +17,6 @@ */ package com.cloud.api.commands; -import java.util.ArrayList; import java.util.List; import org.apache.log4j.Logger; @@ -30,7 +29,6 @@ import com.cloud.api.Parameter; import com.cloud.api.ServerApiException; import com.cloud.api.response.SuccessResponse; import com.cloud.event.EventTypes; -import com.cloud.exception.InvalidParameterValueException; import com.cloud.network.rules.LoadBalancer; import com.cloud.user.Account; import com.cloud.utils.StringUtils; @@ -48,10 +46,7 @@ public class RemoveFromLoadBalancerRuleCmd extends BaseAsyncCmd { @Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="The ID of the load balancer rule") private Long id; - @Parameter(name=ApiConstants.VIRTUAL_MACHINE_ID, type=CommandType.LONG, description="the ID of the virtual machine that is being removed from the load balancer rule") - private Long virtualMachineId; - - @Parameter(name=ApiConstants.VIRTUAL_MACHINE_IDS, type=CommandType.LIST, collectionType=CommandType.LONG, description="the list of IDs of the virtual machines that are being removed from the load balancer rule (i.e. virtualMachineIds=1,2,3)") + @Parameter(name=ApiConstants.VIRTUAL_MACHINE_IDS, type=CommandType.LIST, required = true, collectionType=CommandType.LONG, description="the list of IDs of the virtual machines that are being removed from the load balancer rule (i.e. virtualMachineIds=1,2,3)") private List virtualMachineIds; ///////////////////////////////////////////////////// @@ -62,10 +57,6 @@ public class RemoveFromLoadBalancerRuleCmd extends BaseAsyncCmd { return id; } - public Long getVirtualMachineId() { - return virtualMachineId; - } - public List getVirtualMachineIds() { return virtualMachineIds; } @@ -95,28 +86,11 @@ public class RemoveFromLoadBalancerRuleCmd extends BaseAsyncCmd { @Override public String getEventDescription() { - List vmIds = getVirtualMachineIds(); - if ((vmIds == null) || vmIds.isEmpty()) { - vmIds = new ArrayList(); - vmIds.add(getVirtualMachineId()); - } - - return "removing instances from load balancer: " + getId() + " (ids: " + StringUtils.join(vmIds, ",") + ")"; + return "removing instances from load balancer: " + getId() + " (ids: " + StringUtils.join(getVirtualMachineIds(), ",") + ")"; } @Override - public void execute(){ - if (virtualMachineIds == null && virtualMachineId == null) { - throw new InvalidParameterValueException("Must specify virtual machine id"); - } - if (virtualMachineIds == null) { - virtualMachineIds = new ArrayList(); - } - - if (virtualMachineId != null) { - virtualMachineIds.add(virtualMachineId); - } - + public void execute(){ boolean result = _lbService.removeFromLoadBalancer(id, virtualMachineIds); if (result) { SuccessResponse response = new SuccessResponse(getCommandName()); diff --git a/api/src/com/cloud/api/commands/UpdateLoadBalancerRuleCmd.java b/api/src/com/cloud/api/commands/UpdateLoadBalancerRuleCmd.java index 87a4027bc2c..fe675bd5a1e 100644 --- a/api/src/com/cloud/api/commands/UpdateLoadBalancerRuleCmd.java +++ b/api/src/com/cloud/api/commands/UpdateLoadBalancerRuleCmd.java @@ -51,8 +51,8 @@ public class UpdateLoadBalancerRuleCmd extends BaseAsyncCmd { @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, description="the name of the load balancer rule") private String loadBalancerName; - @Parameter(name=ApiConstants.PRIVATE_PORT, type=CommandType.STRING, description="the private port of the private ip address/virtual machine where the network traffic will be load balanced to") - private String privatePort; +// @Parameter(name=ApiConstants.PRIVATE_PORT, type=CommandType.STRING, description="the private port of the private ip address/virtual machine where the network traffic will be load balanced to") +// private String privatePort; ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// @@ -74,9 +74,9 @@ public class UpdateLoadBalancerRuleCmd extends BaseAsyncCmd { return loadBalancerName; } - public String getPrivatePort() { - return privatePort; - } +// public String getPrivatePort() { +// return privatePort; +// } ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// diff --git a/api/src/com/cloud/network/lb/LoadBalancingRule.java b/api/src/com/cloud/network/lb/LoadBalancingRule.java new file mode 100644 index 00000000000..d7cb938c1b8 --- /dev/null +++ b/api/src/com/cloud/network/lb/LoadBalancingRule.java @@ -0,0 +1,139 @@ +package com.cloud.network.lb; + +import java.util.List; + +import com.cloud.network.rules.FirewallRule; +import com.cloud.network.rules.LoadBalancer; +import com.cloud.utils.net.Ip; + +public class LoadBalancingRule implements FirewallRule, LoadBalancer{ + private LoadBalancer lb; + private List destinations; + + public LoadBalancingRule(LoadBalancer lb, List destinations) { + this.lb = lb; + this.destinations = destinations; + } + + @Override + public long getId() { + return lb.getId(); + } + + @Override + public long getAccountId() { + return lb.getAccountId(); + } + + @Override + public long getDomainId() { + return lb.getDomainId(); + } + + @Override + public String getName() { + return lb.getName(); + } + + @Override + public String getDescription() { + return lb.getDescription(); + } + + public int getDefaultPortStart() { + return lb.getDefaultPortStart(); + } + + @Override + public int getDefaultPortEnd() { + return lb.getDefaultPortEnd(); + } + + @Override + public String getAlgorithm() { + return lb.getAlgorithm(); + } + + @Override + public String getXid() { + return lb.getXid(); + } + + @Override + public Ip getSourceIpAddress() { + return lb.getSourceIpAddress(); + } + + @Override + public int getSourcePortStart() { + return lb.getSourcePortStart(); + } + + @Override + public int getSourcePortEnd() { + return lb.getSourcePortEnd(); + } + + @Override + public String getProtocol() { + return null; + } + + @Override + public Purpose getPurpose() { + return Purpose.LoadBalancing; + } + + @Override + public State getState() { + return lb.getState(); + } + + @Override + public long getNetworkId() { + return lb.getNetworkId(); + } + + public LoadBalancer getLb() { + return lb; + } + + public List getDestinations() { + return destinations; + } + + public interface Destination { + String getIpAddress(); + int getDestinationPortStart(); + int getDestinationPortEnd(); + boolean isRevoked(); + } + + public static class LbDestination implements Destination { + private int portStart; + private int portEnd; + private String ip; + boolean revoked; + + public LbDestination(int portStart, int portEnd, String ip, boolean revoked) { + this.portStart = portStart; + this.portEnd = portEnd; + this.ip = ip; + this.revoked = revoked; + } + + public String getIpAddress() { + return ip; + } + public int getDestinationPortStart() { + return portStart; + } + public int getDestinationPortEnd() { + return portEnd; + } + + public boolean isRevoked() { + return revoked; + } + } +} diff --git a/api/src/com/cloud/network/lb/LoadBalancingRulesService.java b/api/src/com/cloud/network/lb/LoadBalancingRulesService.java index c8db7e5d69a..07863b7c6b2 100644 --- a/api/src/com/cloud/network/lb/LoadBalancingRulesService.java +++ b/api/src/com/cloud/network/lb/LoadBalancingRulesService.java @@ -46,7 +46,7 @@ public interface LoadBalancingRulesService { boolean removeFromLoadBalancer(long lbRuleId, List vmIds); - boolean applyLoadBalancerConfig(long id) throws ResourceUnavailableException; + boolean applyLoadBalancerConfig(long lbRuleId) throws ResourceUnavailableException; /** * List instances that have either been applied to a load balancer or are eligible to be assigned to a load balancer. * @param cmd diff --git a/api/src/com/cloud/network/rules/LoadBalancer.java b/api/src/com/cloud/network/rules/LoadBalancer.java index 72097deea65..0f2f27ead73 100644 --- a/api/src/com/cloud/network/rules/LoadBalancer.java +++ b/api/src/com/cloud/network/rules/LoadBalancer.java @@ -17,13 +17,13 @@ */ package com.cloud.network.rules; -import java.util.List; /** * Definition for a LoadBalancer */ public interface LoadBalancer extends FirewallRule { + String getName(); String getDescription(); @@ -34,13 +34,4 @@ public interface LoadBalancer extends FirewallRule { String getAlgorithm(); - List getDestinations(); - - public interface Destination { - String getIpAddress(); - int getDestinationPortStart(); - int getDestinationPortEnd(); - boolean getRevoked(); - boolean getAlreadyAdded(); - } } diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index 6d526e97c5d..9cfdb7de125 100755 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -115,11 +115,11 @@ listIpForwardingRules=com.cloud.api.commands.ListIpForwardingRulesCmd;15 #### load balancer commands createLoadBalancerRule=com.cloud.api.commands.CreateLoadBalancerRuleCmd;15 deleteLoadBalancerRule=com.cloud.api.commands.DeleteLoadBalancerRuleCmd;15 -updateLoadBalancerRule=com.cloud.api.commands.UpdateLoadBalancerRuleCmd;15 removeFromLoadBalancerRule=com.cloud.api.commands.RemoveFromLoadBalancerRuleCmd;15 assignToLoadBalancerRule=com.cloud.api.commands.AssignToLoadBalancerRuleCmd;15 listLoadBalancerRules=com.cloud.api.commands.ListLoadBalancerRulesCmd;15 listLoadBalancerRuleInstances=com.cloud.api.commands.ListLoadBalancerRuleInstancesCmd;15 +updateLoadBalancerRule=com.cloud.api.commands.UpdateLoadBalancerRuleCmd;15 #### router commands startRouter=com.cloud.api.commands.StartRouterCmd;3 diff --git a/server/src/com/cloud/network/LoadBalancerVMMapVO.java b/server/src/com/cloud/network/LoadBalancerVMMapVO.java index f8381a9bc8b..33e58eede20 100644 --- a/server/src/com/cloud/network/LoadBalancerVMMapVO.java +++ b/server/src/com/cloud/network/LoadBalancerVMMapVO.java @@ -39,8 +39,8 @@ public class LoadBalancerVMMapVO { @Column(name="instance_id") private long instanceId; - @Column(name="pending") - private boolean pending = false; + @Column(name="revoke") + private boolean revoke = false; public LoadBalancerVMMapVO() { } @@ -49,10 +49,10 @@ public class LoadBalancerVMMapVO { this.instanceId = instanceId; } - public LoadBalancerVMMapVO(long loadBalancerId, long instanceId, boolean pending) { + public LoadBalancerVMMapVO(long loadBalancerId, long instanceId, boolean revoke) { this.loadBalancerId = loadBalancerId; this.instanceId = instanceId; - this.pending = pending; + this.revoke = revoke; } public long getId() { @@ -67,11 +67,11 @@ public class LoadBalancerVMMapVO { return instanceId; } - public boolean isPending() { - return pending; + public boolean isRevoke() { + return revoke; } - public void setPending(boolean pending) { - this.pending = pending; + public void setRevoke(boolean revoke) { + this.revoke = revoke; } } diff --git a/server/src/com/cloud/network/LoadBalancerVO.java b/server/src/com/cloud/network/LoadBalancerVO.java index f3affe8c630..36930190b51 100644 --- a/server/src/com/cloud/network/LoadBalancerVO.java +++ b/server/src/com/cloud/network/LoadBalancerVO.java @@ -18,8 +18,6 @@ package com.cloud.network; -import java.util.List; - import javax.persistence.Column; import javax.persistence.DiscriminatorValue; import javax.persistence.Entity; @@ -89,9 +87,15 @@ public class LoadBalancerVO extends FirewallRuleVO implements LoadBalancer { return defaultPortEnd; } - @Override - public List getDestinations() { - // TODO Auto-generated method stub - return null; - } + public void setName(String name) { + this.name = name; + } + + public void setAlgorithm(String algorithm) { + this.algorithm = algorithm; + } + + public void setDescription(String description) { + this.description = description; + } } diff --git a/server/src/com/cloud/network/dao/LoadBalancerDaoImpl.java b/server/src/com/cloud/network/dao/LoadBalancerDaoImpl.java index f845d2c9c88..e080ed35677 100644 --- a/server/src/com/cloud/network/dao/LoadBalancerDaoImpl.java +++ b/server/src/com/cloud/network/dao/LoadBalancerDaoImpl.java @@ -27,6 +27,7 @@ import javax.ejb.Local; import org.apache.log4j.Logger; +import com.cloud.domain.DomainVO; import com.cloud.network.LoadBalancerVO; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.SearchBuilder; diff --git a/server/src/com/cloud/network/dao/LoadBalancerVMMapDao.java b/server/src/com/cloud/network/dao/LoadBalancerVMMapDao.java index 0f1ae1544f7..31f6f347209 100644 --- a/server/src/com/cloud/network/dao/LoadBalancerVMMapDao.java +++ b/server/src/com/cloud/network/dao/LoadBalancerVMMapDao.java @@ -28,5 +28,7 @@ public interface LoadBalancerVMMapDao extends GenericDao instanceIds, Boolean pending); List listByInstanceId(long instanceId); List listByLoadBalancerId(long loadBalancerId); - List listByLoadBalancerId(long loadBalancerId, boolean pending); + List listByLoadBalancerId(long loadBalancerId, boolean revoke); + LoadBalancerVMMapVO findByLoadBalancerIdAndVmId(long loadBalancerId, long instanceId); + } diff --git a/server/src/com/cloud/network/dao/LoadBalancerVMMapDaoImpl.java b/server/src/com/cloud/network/dao/LoadBalancerVMMapDaoImpl.java index ca9c6915dc4..a787aba6499 100644 --- a/server/src/com/cloud/network/dao/LoadBalancerVMMapDaoImpl.java +++ b/server/src/com/cloud/network/dao/LoadBalancerVMMapDaoImpl.java @@ -38,12 +38,12 @@ public class LoadBalancerVMMapDaoImpl extends GenericDaoBase instanceIds, Boolean pending) { + public void remove(long loadBalancerId, List instanceIds, Boolean revoke) { SearchCriteria sc = createSearchCriteria(); sc.addAnd("loadBalancerId", SearchCriteria.Op.EQ, loadBalancerId); sc.addAnd("instanceId", SearchCriteria.Op.IN, instanceIds.toArray()); - if (pending != null) { - sc.addAnd("pending", SearchCriteria.Op.EQ, pending); + if (revoke != null) { + sc.addAnd("revoke", SearchCriteria.Op.EQ, revoke); } expunge(sc); @@ -69,8 +69,18 @@ public class LoadBalancerVMMapDaoImpl extends GenericDaoBase listByLoadBalancerId(long loadBalancerId, boolean pending) { SearchCriteria sc = createSearchCriteria(); sc.addAnd("loadBalancerId", SearchCriteria.Op.EQ, loadBalancerId); - sc.addAnd("pending", SearchCriteria.Op.EQ, pending); + sc.addAnd("revoke", SearchCriteria.Op.EQ, pending); return listBy(sc); } + + @Override + public LoadBalancerVMMapVO findByLoadBalancerIdAndVmId(long loadBalancerId, long instanceId) { + SearchCriteria sc = createSearchCriteria(); + sc.addAnd("loadBalancerId", SearchCriteria.Op.EQ, loadBalancerId); + sc.addAnd("instanceId", SearchCriteria.Op.EQ, instanceId); + return findOneBy(sc); + } + + } diff --git a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java index ff02f4777a5..fa7fbe59585 100644 --- a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java +++ b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java @@ -33,7 +33,6 @@ import com.cloud.api.commands.ListLoadBalancerRuleInstancesCmd; import com.cloud.api.commands.ListLoadBalancerRulesCmd; import com.cloud.api.commands.UpdateLoadBalancerRuleCmd; import com.cloud.dc.dao.VlanDao; -import com.cloud.domain.DomainVO; import com.cloud.domain.dao.DomainDao; import com.cloud.event.EventTypes; import com.cloud.event.EventVO; @@ -50,7 +49,9 @@ import com.cloud.network.dao.FirewallRulesDao; import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.LoadBalancerDao; import com.cloud.network.dao.LoadBalancerVMMapDao; +import com.cloud.network.lb.LoadBalancingRule.LbDestination; import com.cloud.network.rules.FirewallRule; +import com.cloud.network.rules.FirewallRule.Purpose; import com.cloud.network.rules.FirewallRuleVO; import com.cloud.network.rules.LoadBalancer; import com.cloud.network.rules.RulesManager; @@ -73,6 +74,7 @@ import com.cloud.utils.net.NetUtils; import com.cloud.vm.Nic; import com.cloud.vm.State; import com.cloud.vm.UserVmVO; +import com.cloud.vm.dao.NicDao; import com.cloud.vm.dao.UserVmDao; @Local(value = { LoadBalancingRulesManager.class, LoadBalancingRulesService.class }) @@ -102,6 +104,7 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesManager, @Inject UserVmDao _vmDao; @Inject AccountDao _accountDao; @Inject DomainDao _domainDao; + @Inject NicDao _nicDao; @Override @DB public boolean assignToLoadBalancer(long loadBalancerId, List instanceIds) { @@ -161,12 +164,22 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesManager, Transaction txn = Transaction.currentTxn(); txn.start(); + for (UserVm vm : vmsToAdd) { - LoadBalancerVMMapVO map = new LoadBalancerVMMapVO(loadBalancer.getId(), vm.getId(), true); + LoadBalancerVMMapVO map = new LoadBalancerVMMapVO(loadBalancer.getId(), vm.getId(), false); map = _lb2VmMapDao.persist(map); } - txn.commit(); + + try { + loadBalancer.setState(FirewallRule.State.Add); + _lbDao.persist(loadBalancer); + applyLoadBalancerConfig(loadBalancerId); + } catch (ResourceUnavailableException e) { + s_logger.warn("Unable to apply the load balancer config because resource is unavaliable.", e); + return false; + } + return true; } @@ -181,8 +194,26 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesManager, } _accountMgr.checkAccess(caller.getAccount(), loadBalancer); - - _lb2VmMapDao.remove(loadBalancerId, instanceIds, null); + + try { + loadBalancer.setState(FirewallRule.State.Add); + _lbDao.persist(loadBalancer); + + for (long instanceId : instanceIds) { + LoadBalancerVMMapVO map = _lb2VmMapDao.findByLoadBalancerIdAndVmId(loadBalancerId, instanceId); + map.setRevoke(true); + _lb2VmMapDao.persist(map); + s_logger.debug("Set load balancer rule for revoke: rule id " + loadBalancerId + ", vmId " + instanceId); + } + + applyLoadBalancerConfig(loadBalancerId); + _lb2VmMapDao.remove(loadBalancerId, instanceIds, null); + s_logger.debug("Load balancer rule id " + loadBalancerId + " is removed for vms " + instanceIds); + } catch (ResourceUnavailableException e) { + s_logger.warn("Unable to apply the load balancer config because resource is unavaliable.", e); + return false; + } + return true; } @@ -198,6 +229,7 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesManager, _accountMgr.checkAccess(caller.getAccount(), lb); lb.setState(FirewallRule.State.Revoke); + _lbDao.persist(lb); if (apply) { try { @@ -207,6 +239,9 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesManager, return false; } } + + _rulesDao.remove(lb.getId()); + s_logger.debug("Load balancer with id " + lb.getId() + " is removed successfully"); return true; } @@ -265,7 +300,7 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesManager, if (!_rulesDao.setStateToAdd(newRule)) { throw new CloudRuntimeException("Unable to update the state to add for " + newRule); } - + s_logger.debug("Load balancer " + newRule.getId() + " for Ip address " + srcIp + ", public port " + srcPortStart + ", private port " + defPortStart+ " is added successfully."); success = true; return newRule; } catch (Exception e) { @@ -273,7 +308,6 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesManager, if (e instanceof NetworkRuleConflictException) { throw (NetworkRuleConflictException) e; } - throw new CloudRuntimeException("Unable to add rule for " + newRule.getSourceIpAddress(), e); } finally { long userId = caller.getUserId(); @@ -300,13 +334,61 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesManager, @Override public boolean applyLoadBalancerConfig(long lbRuleId) throws ResourceUnavailableException { - return false; + + List rules = new ArrayList(); + LoadBalancerVO lb = _lbDao.findById(lbRuleId); + List dstList = getExistingDestinations(lb.getId()); + + if (dstList != null && !dstList.isEmpty()) { + LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList); + rules.add(loadBalancing); + + if (!_networkMgr.applyRules(lb.getSourceIpAddress(), rules, false)) { + s_logger.debug("LB rules are not completely applied"); + return false; + } + + if (lb.getState() == FirewallRule.State.Revoke) { + _lbDao.remove(lb.getId()); + s_logger.debug("LB " + lb.getId() + " is successfully removed"); + } else if (lb.getState() == FirewallRule.State.Add) { + lb.setState(FirewallRule.State.Active); + s_logger.debug("LB rule " + lbRuleId + " state is set to Active"); + _lbDao.persist(lb); + } + } + return true; } @Override - public boolean removeAllLoadBalanacers(Ip ip) { - // TODO Auto-generated method stub - return false; + public boolean removeAllLoadBalanacers(Ip ip) { + List rules = _rulesDao.listByIpAndNotRevoked(ip); + for (FirewallRule rule : rules) { + if (rule.getPurpose() == Purpose.LoadBalancing) { + boolean result = deleteLoadBalancerRule(rule.getId(), true); + if (result == false) { + s_logger.warn("Unable to remove load balancer rule " + rule.getId()); + return false; + } + } + } + return true; + } + + private List getExistingDestinations(long lbId) { + List dstList = new ArrayList(); + List lbVmMaps = _lb2VmMapDao.listByLoadBalancerId(lbId); + LoadBalancerVO lb = _lbDao.findById(lbId); + + String dstIp = null; + for (LoadBalancerVMMapVO lbVmMap : lbVmMaps) { + UserVm vm = _vmDao.findById(lbVmMap.getInstanceId()); + Nic nic = _nicDao.findByInstanceIdAndNetworkId(lb.getNetworkId(), vm.getId()); + dstIp = nic.getIp4Address(); + LbDestination lbDst = new LbDestination(lb.getDefaultPortStart(), lb.getDefaultPortEnd(), dstIp, lbVmMap.isRevoke()); + dstList.add(lbDst); + } + return dstList; } @Override @@ -332,8 +414,39 @@ public class LoadBalancingRulesManagerImpl implements LoadBalancingRulesManager, @Override public LoadBalancer updateLoadBalancerRule(UpdateLoadBalancerRuleCmd cmd) { - // TODO Auto-generated method stub - return null; + Long lbRuleId = cmd.getId(); + String name = cmd.getLoadBalancerName(); + String description = cmd.getDescription(); + String algorithm = cmd.getAlgorithm(); + LoadBalancerVO lb = _lbDao.findById(lbRuleId); + + + if (name != null) { + lb.setName(name); + } + + if (description != null) { + lb.setDescription(description); + } + + if (algorithm != null) { + lb.setAlgorithm(algorithm); + } + + _lbDao.update(lbRuleId, lb); + + //If algorithm is changed, have to reapply the lb config + if (algorithm != null) { + try { + lb.setState(FirewallRule.State.Add); + _lbDao.persist(lb); + applyLoadBalancerConfig(lbRuleId); + } catch (ResourceUnavailableException e) { + s_logger.warn("Unable to apply the load balancer config because resource is unavaliable.", e); + } + } + + return lb; } // @Override @DB diff --git a/server/src/com/cloud/vm/dao/NicDao.java b/server/src/com/cloud/vm/dao/NicDao.java index 078d6a1c1d3..010ddcf3d25 100644 --- a/server/src/com/cloud/vm/dao/NicDao.java +++ b/server/src/com/cloud/vm/dao/NicDao.java @@ -16,4 +16,5 @@ public interface NicDao extends GenericDao { List listByNetworkId(long networkId); List listNetworksWithNoActiveNics(); + NicVO findByInstanceIdAndNetworkId(long networkId, long instanceId); } diff --git a/server/src/com/cloud/vm/dao/NicDaoImpl.java b/server/src/com/cloud/vm/dao/NicDaoImpl.java index fe8d2a1376a..94afc182c5d 100644 --- a/server/src/com/cloud/vm/dao/NicDaoImpl.java +++ b/server/src/com/cloud/vm/dao/NicDaoImpl.java @@ -7,6 +7,7 @@ import java.util.List; import javax.ejb.Local; +import com.cloud.domain.DomainVO; import com.cloud.utils.db.GenericDaoBase; import com.cloud.utils.db.GenericSearchBuilder; import com.cloud.utils.db.SearchBuilder; @@ -73,4 +74,11 @@ public class NicDaoImpl extends GenericDaoBase implements NicDao { return customSearch(sc, null); } + + public NicVO findByInstanceIdAndNetworkId(long networkId, long instanceId) { + SearchCriteria sc = createSearchCriteria(); + sc.addAnd("networkId", SearchCriteria.Op.EQ, networkId); + sc.addAnd("instanceId", SearchCriteria.Op.EQ, instanceId); + return findOneBy(sc); + } } diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index df1647a78c2..c45b7f8a9fc 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -482,7 +482,7 @@ CREATE TABLE `cloud`.`load_balancer_vm_map` ( `id` bigint unsigned NOT NULL auto_increment, `load_balancer_id` bigint unsigned NOT NULL, `instance_id` bigint unsigned NOT NULL, - `pending` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'whether the vm is being applied to the load balancer (pending=1) or has already been applied (pending=0)', + `revoke` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT '1 when vm is set for revoke from load balancer', PRIMARY KEY (`id`), UNIQUE KEY (`load_balancer_id`, `instance_id`), CONSTRAINT `fk_load_balancer_vm_map__load_balancer_id` FOREIGN KEY(`load_balancer_id`) REFERENCES `load_balancing_rules`(`id`) ON DELETE CASCADE,