1717package org .apache .cloudstack .service ;
1818
1919import com .cloud .network .netris .NetrisLbBackend ;
20+ import com .cloud .network .netris .NetrisNetworkRule ;
2021import com .cloud .utils .Pair ;
2122import com .cloud .utils .exception .CloudRuntimeException ;
2223import com .cloud .utils .net .NetUtils ;
131132import java .util .List ;
132133import java .util .Locale ;
133134import java .util .Objects ;
135+ import java .util .concurrent .atomic .AtomicInteger ;
134136import java .util .stream .Collectors ;
135137
136138public class NetrisApiClientImpl implements NetrisApiClient {
@@ -330,7 +332,7 @@ public boolean deleteNatRule(DeleteNetrisNatRuleCommand cmd) {
330332 }
331333
332334 @ Override
333- public boolean addAclRule (CreateNetrisACLCommand cmd ) {
335+ public boolean addAclRule (CreateNetrisACLCommand cmd , boolean forLb ) {
334336 String aclName = cmd .getNetrisAclName ();
335337 try {
336338 AclApi aclApi = apiClient .getApiStubForMethod (AclApi .class );
@@ -366,10 +368,18 @@ public boolean addAclRule(CreateNetrisACLCommand cmd) {
366368 if (NatPutBody .ProtocolEnum .ICMP .name ().equalsIgnoreCase (protocol )) {
367369 aclAddItem .setIcmpType (cmd .getIcmpType ());
368370 }
369- String netrisVpcName = getNetrisVpcName (cmd , cmd .getVpcId (), cmd .getVpcName ());
370- VPCListing vpcResource = getNetrisVpcResource (netrisVpcName );
371- if (Objects .isNull (vpcResource )) {
372- return false ;
371+ VPCListing vpcResource ;
372+ String netrisVpcName ;
373+ if (forLb ) {
374+ vpcResource = getSystemVpc ();
375+ netrisVpcName = vpcResource .getName ();
376+
377+ } else {
378+ netrisVpcName = getNetrisVpcName (cmd , cmd .getVpcId (), cmd .getVpcName ());
379+ vpcResource = getNetrisVpcResource (netrisVpcName );
380+ if (Objects .isNull (vpcResource )) {
381+ return false ;
382+ }
373383 }
374384 AclBodyVpc vpc = new AclBodyVpc ().id (vpcResource .getId ());
375385 aclAddItem .setVpc (vpc );
@@ -387,13 +397,19 @@ public boolean addAclRule(CreateNetrisACLCommand cmd) {
387397 }
388398
389399 @ Override
390- public boolean deleteAclRule (DeleteNetrisACLCommand cmd ) {
400+ public boolean deleteAclRule (DeleteNetrisACLCommand cmd , boolean forLb ) {
391401 List <String > aclNames = cmd .getAclRuleNames ();
392402 try {
393403 AclApi aclApi = apiClient .getApiStubForMethod (AclApi .class );
394404
395- String suffix = getNetrisVpcNameSuffix (cmd .getVpcId (), cmd .getVpcName (), cmd .getId (), cmd .getName (), cmd .isVpc ());
396- String vpcName = NetrisResourceObjectUtils .retrieveNetrisResourceObjectName (cmd , NetrisResourceObjectUtils .NetrisObjectType .VPC , suffix );
405+ String vpcName ;
406+ if (!forLb ) {
407+ String suffix = getNetrisVpcNameSuffix (cmd .getVpcId (), cmd .getVpcName (), cmd .getId (), cmd .getName (), cmd .isVpc ());
408+ vpcName = NetrisResourceObjectUtils .retrieveNetrisResourceObjectName (cmd , NetrisResourceObjectUtils .NetrisObjectType .VPC , suffix );
409+ } else {
410+ VPCListing vpcResource = getSystemVpc ();
411+ vpcName = vpcResource .getName ();
412+ }
397413 Pair <Boolean , List <BigDecimal >> resultAndMatchingAclIds = getMatchingAclIds (aclNames , vpcName );
398414 Boolean result = resultAndMatchingAclIds .first ();
399415 List <BigDecimal > matchingAclIds = resultAndMatchingAclIds .second ();
@@ -661,12 +677,65 @@ public boolean createOrUpdateLbRule(CreateOrUpdateNetrisLoadBalancerRuleCommand
661677 if (ObjectUtils .allNull (editResponse , createResponse ) || Boolean .FALSE .equals (success )) {
662678 throw new CloudRuntimeException (String .format ("Failed to %s Netris LB rule" , updateRule ? "update" : "create" ));
663679 }
680+ if (Objects .nonNull (cmd .getCidrList ())) {
681+ applyAclRulesForLb (cmd , lbName );
682+ }
664683 } catch (ApiException e ) {
665684 logAndThrowException ("Failed to create Netris load balancer rule" , e );
666685 }
667686 return true ;
668687 }
669688
689+ private void applyAclRulesForLb (CreateOrUpdateNetrisLoadBalancerRuleCommand cmd , String lbName ) {
690+ // Add deny all rule first
691+ addAclRule (createNetrisACLRuleCommand (cmd , lbName , "ANY" ,
692+ NetrisNetworkRule .NetrisRuleAction .DENY .name ().toLowerCase (Locale .ROOT ), 0 ), true );
693+ AtomicInteger cidrIndex = new AtomicInteger (1 );
694+ for (String cidr : cmd .getCidrList ().split (" " )) {
695+ try {
696+ addAclRule (createNetrisACLRuleCommand (cmd , lbName , cidr ,
697+ NetrisNetworkRule .NetrisRuleAction .PERMIT .name ().toLowerCase (Locale .ROOT ),
698+ cidrIndex .getAndIncrement ()), true );
699+ } catch (Exception e ) {
700+ throw new CloudRuntimeException (String .format ("Failed to add Netris ACL rule for LB CIDR %s" , cidr ), e );
701+ }
702+ }
703+ }
704+
705+ private CreateNetrisACLCommand createNetrisACLRuleCommand (CreateOrUpdateNetrisLoadBalancerRuleCommand cmd , String netrisLbName , String cidr , String action , int index ) {
706+ Long zoneId = cmd .getZoneId ();
707+ Long accountId = cmd .getAccountId ();
708+ Long domainId = cmd .getDomainId ();
709+ String networkName = null ;
710+ Long networkId = null ;
711+ String vpcName = null ;
712+ Long vpcId = null ;
713+ boolean isVpc = cmd .isVpc ();
714+ if (isVpc ) {
715+ vpcId = cmd .getId ();
716+ vpcName = cmd .getName ();
717+ } else {
718+ networkName = cmd .getName ();
719+ networkId = cmd .getId ();
720+ }
721+ String destinationPrefix = cmd .getPublicIp () + "/32" ;
722+ String srcPort = cmd .getPublicPort ();
723+ String dstPort = cmd .getPublicPort ();
724+ CreateNetrisACLCommand aclCommand = new CreateNetrisACLCommand (zoneId , accountId , domainId , networkName , networkId ,
725+ vpcName , vpcId , Objects .nonNull (vpcId ), action , NetrisServiceImpl .getPrefix (cidr ), NetrisServiceImpl .getPrefix (destinationPrefix ),
726+ Integer .parseInt (srcPort ), Integer .parseInt (dstPort ), cmd .getProtocol ());
727+ String aclName ;
728+ if (isVpc ) {
729+ aclName = String .format ("V%s-LBACL%s-%s" , vpcId , index , cmd .getRuleName ());
730+ } else {
731+ aclName = String .format ("N%s-LBACL%s-%s" , networkId , index , cmd .getRuleName ());
732+ }
733+ String netrisAclName = NetrisResourceObjectUtils .retrieveNetrisResourceObjectName (cmd , NetrisResourceObjectUtils .NetrisObjectType .ACL , aclName );
734+ aclCommand .setNetrisAclName (netrisAclName );
735+ aclCommand .setReason (String .format ("ACL Rule for CIDR %s of LB %s " , aclName , netrisLbName ));
736+ return aclCommand ;
737+ }
738+
670739 private L4lbAddOrUpdateItem getL4LbRule (CreateOrUpdateNetrisLoadBalancerRuleCommand cmd , VPCListing vpcResource , String lbName ,
671740 String publicIp , List <NetrisLbBackend > lbBackends , boolean updateRule ) {
672741 L4lbAddOrUpdateItem l4lbAddItem = updateRule ? new L4LbEditItem () : new L4LbAddItem ();
@@ -729,6 +798,7 @@ public boolean deleteLbRule(DeleteNetrisLoadBalancerRuleCommand cmd) {
729798 networkId = cmd .getId ();
730799 }
731800 Long lbId = cmd .getLbId ();
801+ String cidrList = cmd .getCidrList ();
732802 try {
733803 String suffix = getNetrisVpcNameSuffix (vpcId , vpcName , networkId , networkName , isVpc );
734804 String netrisVpcName = NetrisResourceObjectUtils .retrieveNetrisResourceObjectName (cmd , NetrisResourceObjectUtils .NetrisObjectType .VPC , suffix );
@@ -748,12 +818,56 @@ public boolean deleteLbRule(DeleteNetrisLoadBalancerRuleCommand cmd) {
748818
749819 L4LoadBalancerApi lbApi = apiClient .getApiStubForMethod (L4LoadBalancerApi .class );
750820 lbApi .apiV2L4lbIdDelete (matchingLbId .get (0 ).intValue ());
821+ if (Objects .nonNull (cidrList )) {
822+ deleteAclRulesForLb (cmd );
823+ }
751824 } catch (ApiException e ) {
752825 logAndThrowException ("Failed to delete Netris load balancer rule" , e );
753826 }
754827 return true ;
755828 }
756829
830+ private void deleteAclRulesForLb (DeleteNetrisLoadBalancerRuleCommand cmd ) {
831+ // delete the deny rule
832+ deleteAclRule (deleteNetrisACLCommand (cmd , 0 ), true );
833+ AtomicInteger cidrIndex = new AtomicInteger (1 );
834+ for (String cidr : cmd .getCidrList ().split (" " )) {
835+ try {
836+ deleteAclRule (deleteNetrisACLCommand (cmd , cidrIndex .getAndIncrement ()), true );
837+ } catch (Exception e ) {
838+ throw new CloudRuntimeException (String .format ("Failed to delete Netris ACL rule for LB CIDR %s" , cidr ), e );
839+ }
840+ }
841+ }
842+
843+ private DeleteNetrisACLCommand deleteNetrisACLCommand (DeleteNetrisLoadBalancerRuleCommand cmd , int index ) {
844+ Long zoneId = cmd .getZoneId ();
845+ Long accountId = cmd .getAccountId ();
846+ Long domainId = cmd .getDomainId ();
847+ String networkName = null ;
848+ Long networkId = null ;
849+ String vpcName = null ;
850+ Long vpcId = null ;
851+ boolean isVpc = cmd .isVpc ();
852+ if (isVpc ) {
853+ vpcId = cmd .getId ();
854+ vpcName = cmd .getName ();
855+ } else {
856+ networkName = cmd .getName ();
857+ networkId = cmd .getId ();
858+ }
859+ DeleteNetrisACLCommand deleteAclCommand = new DeleteNetrisACLCommand (zoneId , accountId , domainId , networkName , networkId , isVpc , vpcId , vpcName );
860+ String aclName ;
861+ if (isVpc ) {
862+ aclName = String .format ("V%s-LBACL%s-%s" , vpcId , index , cmd .getRuleName ());
863+ } else {
864+ aclName = String .format ("N%s-LBACL%s-%s" , networkId , index , cmd .getRuleName ());
865+ }
866+ String netrisAclName = NetrisResourceObjectUtils .retrieveNetrisResourceObjectName (cmd , NetrisResourceObjectUtils .NetrisObjectType .ACL , aclName );
867+ deleteAclCommand .setAclRuleNames (Collections .singletonList (netrisAclName ));
868+ return deleteAclCommand ;
869+ }
870+
757871 private Pair <Boolean , List <BigDecimal >> getMatchingLbRule (String lbName , String vpcName ) {
758872 try {
759873 VPCListing vpcResource = getVpcByNameAndTenant (vpcName );
0 commit comments