3030import javax .ejb .Local ;
3131import javax .inject .Inject ;
3232
33+ import com .cloud .vm .dao .NicSecondaryIpDao ;
3334import org .apache .cloudstack .api .ApiConstants ;
3435import org .apache .cloudstack .api .command .user .loadbalancer .CreateLBHealthCheckPolicyCmd ;
3536import org .apache .cloudstack .api .command .user .loadbalancer .CreateLBStickinessPolicyCmd ;
@@ -258,6 +259,9 @@ public class LoadBalancingRulesManagerImpl<Type> extends ManagerBase implements
258259 @ Inject
259260 LoadBalancerCertMapDao _lbCertMapDao ;
260261
262+ @ Inject
263+ NicSecondaryIpDao _nicSecondaryIpDao ;
264+
261265 // Will return a string. For LB Stickiness this will be a json, for
262266 // autoscale this will be "," separated values
263267 @ Override
@@ -923,7 +927,7 @@ private boolean isRollBackAllowedForProvider(LoadBalancerVO loadBalancer) {
923927 @ Override
924928 @ DB
925929 @ ActionEvent (eventType = EventTypes .EVENT_ASSIGN_TO_LOAD_BALANCER_RULE , eventDescription = "assigning to load balancer" , async = true )
926- public boolean assignToLoadBalancer (long loadBalancerId , List <Long > instanceIds ) {
930+ public boolean assignToLoadBalancer (long loadBalancerId , List <Long > instanceIds , Map < Long , List < String >> vmIdIpMap ) {
927931 CallContext ctx = CallContext .current ();
928932 Account caller = ctx .getCallingAccount ();
929933
@@ -932,22 +936,68 @@ public boolean assignToLoadBalancer(long loadBalancerId, List<Long> instanceIds)
932936 throw new InvalidParameterValueException ("Failed to assign to load balancer " + loadBalancerId + ", the load balancer was not found." );
933937 }
934938
939+
940+ if (instanceIds == null && vmIdIpMap == null ) {
941+ throw new InvalidParameterValueException ("Both instanceids and vmidipmap can't be null" );
942+ }
943+
944+ // instanceIds and vmIdipmap is passed
945+ if (instanceIds != null && vmIdIpMap != null ) {
946+ for (long instanceId : instanceIds ) {
947+ if (!vmIdIpMap .containsKey (instanceId )) {
948+ vmIdIpMap .put (instanceId , null );
949+ }
950+ }
951+ }
952+
953+ //only instanceids list passed
954+ if (instanceIds != null && vmIdIpMap == null ){
955+ vmIdIpMap = new HashMap <Long , List <String >>();
956+ for (long instanceId : instanceIds ){
957+ vmIdIpMap .put (instanceId , null );
958+ }
959+ }
960+
935961 List <LoadBalancerVMMapVO > mappedInstances = _lb2VmMapDao .listByLoadBalancerId (loadBalancerId , false );
936962 Set <Long > mappedInstanceIds = new HashSet <Long >();
937963 for (LoadBalancerVMMapVO mappedInstance : mappedInstances ) {
938964 mappedInstanceIds .add (Long .valueOf (mappedInstance .getInstanceId ()));
939965 }
940966
941- final List <UserVm > vmsToAdd = new ArrayList <UserVm >();
967+ Map <Long , List <String >> existingVmIdIps = new HashMap <Long , List <String >>();
968+ // now get the ips of vm and add it to map
969+ for (LoadBalancerVMMapVO mappedInstance : mappedInstances ) {
942970
943- if (instanceIds == null || instanceIds .isEmpty ()) {
944- s_logger .warn ("List of vms to assign to the lb, is empty" );
945- return false ;
971+ List <String > ipsList = null ;
972+ if (existingVmIdIps .containsKey (mappedInstance .getInstanceId ())) {
973+ ipsList = existingVmIdIps .get (mappedInstance .getInstanceId ());
974+ } else {
975+ ipsList = new ArrayList <String >();
976+ }
977+ ipsList .add (mappedInstance .getInstanceIp ());
978+ existingVmIdIps .put (mappedInstance .getInstanceId (), ipsList );
946979 }
947980
948- for (Long instanceId : instanceIds ) {
949- if (mappedInstanceIds .contains (instanceId )) {
950- throw new InvalidParameterValueException ("VM " + instanceId + " is already mapped to load balancer." );
981+
982+
983+
984+ final List <UserVm > vmsToAdd = new ArrayList <UserVm >();
985+
986+ // check for conflict
987+ Set <Long > passedInstanceIds = vmIdIpMap .keySet ();
988+ for (Long instanceId : passedInstanceIds ) {
989+ if (existingVmIdIps .containsKey (instanceId )) {
990+ // now check for ip address
991+ List <String > mappedIps = existingVmIdIps .get (instanceId );
992+ List <String > newIps = vmIdIpMap .get (instanceId );
993+
994+ if (newIps != null ) {
995+ for (String newIp : newIps ) {
996+ if (mappedIps .contains (newIp )) {
997+ throw new InvalidParameterValueException ("VM " + instanceId + " with " + newIp +" is already mapped to load balancer." );
998+ }
999+ }
1000+ }
9511001 }
9521002
9531003 UserVm vm = _vmDao .findById (instanceId );
@@ -985,18 +1035,43 @@ public boolean assignToLoadBalancer(long loadBalancerId, List<Long> instanceIds)
9851035 throw ex ;
9861036 }
9871037
1038+ String priIp = nicInSameNetwork .getIp4Address ();
1039+ List <String > vmIpsList = vmIdIpMap .get (instanceId );
1040+ String vmLbIp = null ;
1041+
1042+ if (vmIpsList == null ) {
1043+ vmIpsList = new ArrayList <String >();
1044+ vmIpsList .add (priIp );
1045+ vmIdIpMap .put (instanceId , vmIpsList );
1046+ } else {
1047+ //check if the ips belongs to nic secondary ip
1048+ for (String ip : vmIpsList ) {
1049+ if (_nicSecondaryIpDao .findByIp4AddressAndNicId (ip ,nicInSameNetwork .getId ()) == null ) {
1050+ throw new InvalidParameterValueException ("VM ip specified " + ip + " is not belongs to nic in network " + nicInSameNetwork .getNetworkId ());
1051+ }
1052+ }
1053+ }
1054+
1055+
9881056 if (s_logger .isDebugEnabled ()) {
9891057 s_logger .debug ("Adding " + vm + " to the load balancer pool" );
9901058 }
9911059 vmsToAdd .add (vm );
9921060 }
9931061
1062+ final Set <Long > vmIds = vmIdIpMap .keySet ();
1063+ final Map <Long , List <String >> newMap = vmIdIpMap ;
1064+
9941065 Transaction .execute (new TransactionCallbackNoReturn () {
9951066 @ Override
9961067 public void doInTransactionWithoutResult (TransactionStatus status ) {
997- for (UserVm vm : vmsToAdd ) {
998- LoadBalancerVMMapVO map = new LoadBalancerVMMapVO (loadBalancer .getId (), vm .getId (), false );
1068+
1069+ for (Long vmId : vmIds ) {
1070+ final List <String > lbVmIps = newMap .get (vmId );
1071+ for (String vmIp : lbVmIps ) {
1072+ LoadBalancerVMMapVO map = new LoadBalancerVMMapVO (loadBalancer .getId (), vmId , vmIp , false );
9991073 map = _lb2VmMapDao .persist (map );
1074+ }
10001075 }
10011076 }
10021077 });
@@ -1020,8 +1095,8 @@ public void doInTransactionWithoutResult(TransactionStatus status) {
10201095 Transaction .execute (new TransactionCallbackNoReturn () {
10211096 @ Override
10221097 public void doInTransactionWithoutResult (TransactionStatus status ) {
1023- for (UserVm vm : vmsToAdd ) {
1024- vmInstanceIds .add (vm . getId () );
1098+ for (Long vmId : vmIds ) {
1099+ vmInstanceIds .add (vmId );
10251100 }
10261101 }
10271102 });
@@ -1875,7 +1950,7 @@ public List<LbDestination> getExistingDestinations(long lbId) {
18751950 for (LoadBalancerVMMapVO lbVmMap : lbVmMaps ) {
18761951 UserVm vm = _vmDao .findById (lbVmMap .getInstanceId ());
18771952 Nic nic = _nicDao .findByInstanceIdAndNetworkIdIncludingRemoved (lb .getNetworkId (), vm .getId ());
1878- dstIp = nic .getIp4Address ();
1953+ dstIp = lbVmMap . getInstanceIp () == null ? nic .getIp4Address (): lbVmMap . getInstanceIp ();
18791954 LbDestination lbDst = new LbDestination (lb .getDefaultPortStart (), lb .getDefaultPortEnd (), dstIp , lbVmMap .isRevoke ());
18801955 dstList .add (lbDst );
18811956 }
0 commit comments