Skip to content

Commit 5b15d18

Browse files
Pearl1594nvazquez
authored andcommitted
Add support to add and remove ACL rules when CIDR list is passed when creating LB rules (#53)
* Add support to add and remove ACL rules when CIDR list is passed when creating LB rules * add deny all rule * delete the deny rule as well
1 parent d555cc8 commit 5b15d18

File tree

8 files changed

+193
-13
lines changed

8 files changed

+193
-13
lines changed

api/src/main/java/com/cloud/network/netris/NetrisNetworkRule.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,17 @@ public enum NetrisRuleAction {
2929
private SDNProviderNetworkRule baseRule;
3030
private NetrisRuleAction aclAction;
3131
private List<NetrisLbBackend> lbBackends;
32+
private String lbRuleName;
33+
private String lbCidrList;
3234
private String reason;
3335

3436
public NetrisNetworkRule(Builder builder) {
3537
this.baseRule = builder.baseRule;
3638
this.aclAction = builder.aclAction;
3739
this.lbBackends = builder.lbBackends;
3840
this.reason = builder.reason;
41+
this.lbCidrList = builder.lbCidrList;
42+
this.lbRuleName = builder.lbRuleName;
3943
}
4044

4145
public NetrisRuleAction getAclAction() {
@@ -50,6 +54,10 @@ public String getReason() {
5054
return reason;
5155
}
5256

57+
public String getLbCidrList() {return lbCidrList; }
58+
59+
public String getLbRuleName() { return lbRuleName; }
60+
5361
public SDNProviderNetworkRule getBaseRule() {
5462
return baseRule;
5563
}
@@ -60,6 +68,8 @@ public static class Builder {
6068
private NetrisRuleAction aclAction;
6169
private List<NetrisLbBackend> lbBackends;
6270
private String reason;
71+
private String lbCidrList;
72+
private String lbRuleName;
6373

6474
public Builder baseRule(SDNProviderNetworkRule baseRule) {
6575
this.baseRule = baseRule;
@@ -81,6 +91,16 @@ public Builder reason(String reason) {
8191
return this;
8292
}
8393

94+
public Builder lbCidrList(String lbCidrList) {
95+
this.lbCidrList = lbCidrList;
96+
return this;
97+
}
98+
99+
public Builder lbRuleName(String lbRuleName) {
100+
this.lbRuleName = lbRuleName;
101+
return this;
102+
}
103+
84104
public NetrisNetworkRule build() {
85105
return new NetrisNetworkRule(this);
86106
}

plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/CreateOrUpdateNetrisLoadBalancerRuleCommand.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ public class CreateOrUpdateNetrisLoadBalancerRuleCommand extends NetrisCommand {
2828
List<NetrisLbBackend> lbBackends;
2929
private String publicIp;
3030
private final Long lbId;
31+
private String cidrList;
32+
private String ruleName;
3133

3234
public CreateOrUpdateNetrisLoadBalancerRuleCommand(long zoneId, Long accountId, Long domainId, String name, Long id, boolean isVpc,
3335
List<NetrisLbBackend> lbBackends, long lbId, String publicIp, String publicPort,
@@ -69,4 +71,20 @@ public Long getLbId() {
6971
public String getPublicIp() {
7072
return publicIp;
7173
}
74+
75+
public String getCidrList() {
76+
return cidrList;
77+
}
78+
79+
public void setCidrList(String cidrList) {
80+
this.cidrList = cidrList;
81+
}
82+
83+
public String getRuleName() {
84+
return ruleName;
85+
}
86+
87+
public void setRuleName(String ruleName) {
88+
this.ruleName = ruleName;
89+
}
7290
}

plugins/network-elements/netris/src/main/java/org/apache/cloudstack/agent/api/DeleteNetrisLoadBalancerRuleCommand.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
public class DeleteNetrisLoadBalancerRuleCommand extends NetrisCommand {
2020
private Long lbId;
21+
private String ruleName;
22+
private String cidrList;
2123

2224
public DeleteNetrisLoadBalancerRuleCommand(long zoneId, Long accountId, Long domainId, String name, Long id, boolean isVpc, Long lbId) {
2325
super(zoneId, accountId, domainId, name, id, isVpc);
@@ -31,4 +33,20 @@ public Long getLbId() {
3133
public void setLbId(Long lbId) {
3234
this.lbId = lbId;
3335
}
36+
37+
public String getRuleName() {
38+
return ruleName;
39+
}
40+
41+
public void setRuleName(String ruleName) {
42+
this.ruleName = ruleName;
43+
}
44+
45+
public String getCidrList() {
46+
return cidrList;
47+
}
48+
49+
public void setCidrList(String cidrList) {
50+
this.cidrList = cidrList;
51+
}
3452
}

plugins/network-elements/netris/src/main/java/org/apache/cloudstack/resource/NetrisResource.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -319,15 +319,15 @@ private Answer executeRequest(DeleteNetrisNatRuleCommand cmd) {
319319
}
320320

321321
private Answer executeRequest(CreateNetrisACLCommand cmd) {
322-
boolean result = netrisApiClient.addAclRule(cmd);
322+
boolean result = netrisApiClient.addAclRule(cmd, false);
323323
if (!result) {
324324
return new NetrisAnswer(cmd, false, String.format("Creation of Netris ACL rule: %s failed", cmd.getNetrisAclName()));
325325
}
326326
return new NetrisAnswer(cmd, true, "OK");
327327
}
328328

329329
private Answer executeRequest(DeleteNetrisACLCommand cmd) {
330-
boolean result = netrisApiClient.deleteAclRule(cmd);
330+
boolean result = netrisApiClient.deleteAclRule(cmd, false);
331331
if (!result) {
332332
return new NetrisAnswer(cmd, false, String.format("Failed to delete Netris ACLs: %s", String.join("'", cmd.getAclRuleNames())));
333333
}

plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisApiClient.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,8 @@ public interface NetrisApiClient {
8181
boolean createOrUpdateDNATRule(CreateOrUpdateNetrisNatCommand cmd);
8282
boolean createStaticNatRule(CreateOrUpdateNetrisNatCommand cmd);
8383
boolean deleteNatRule(DeleteNetrisNatRuleCommand cmd);
84-
boolean addAclRule(CreateNetrisACLCommand cmd);
85-
boolean deleteAclRule(DeleteNetrisACLCommand cmd);
84+
boolean addAclRule(CreateNetrisACLCommand cmd, boolean forLb);
85+
boolean deleteAclRule(DeleteNetrisACLCommand cmd, boolean forLb);
8686
boolean addOrUpdateStaticRoute(AddOrUpdateNetrisStaticRouteCommand cmd);
8787
boolean deleteStaticRoute(DeleteNetrisStaticRouteCommand cmd);
8888
boolean releaseNatIp(ReleaseNatIpCommand cmd);

plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisApiClientImpl.java

Lines changed: 122 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package org.apache.cloudstack.service;
1818

1919
import com.cloud.network.netris.NetrisLbBackend;
20+
import com.cloud.network.netris.NetrisNetworkRule;
2021
import com.cloud.utils.Pair;
2122
import com.cloud.utils.exception.CloudRuntimeException;
2223
import com.cloud.utils.net.NetUtils;
@@ -131,6 +132,7 @@
131132
import java.util.List;
132133
import java.util.Locale;
133134
import java.util.Objects;
135+
import java.util.concurrent.atomic.AtomicInteger;
134136
import java.util.stream.Collectors;
135137

136138
public 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);

plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisElement.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,8 @@ public boolean applyLBRules(Network network, List<LoadBalancingRule> rules) thro
764764
NetrisNetworkRule networkRule = new NetrisNetworkRule.Builder()
765765
.baseRule(baseNetworkRule)
766766
.lbBackends(lbBackends)
767+
.lbCidrList(loadBalancingRule.getCidrList())
768+
.lbRuleName(loadBalancingRule.getName())
767769
.build();
768770
if (Arrays.asList(FirewallRule.State.Add, FirewallRule.State.Active).contains(loadBalancingRule.getState())) {
769771
result &= netrisService.createOrUpdateLbRule(networkRule);

plugins/network-elements/netris/src/main/java/org/apache/cloudstack/service/NetrisServiceImpl.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ public boolean addFirewallRules(Network network, List<NetrisNetworkRule> firewal
405405
return answer.getResult();
406406
}
407407

408-
private String getPrefix(String prefix) {
408+
public static String getPrefix(String prefix) {
409409
if ("ANY".equals(prefix)) {
410410
return NetUtils.ALL_IP4_CIDRS;
411411
}
@@ -464,6 +464,10 @@ public boolean createOrUpdateLbRule(NetrisNetworkRule rule) {
464464
baseRule.getDomainId(), baseRule.getNetworkResourceName(), baseRule.getNetworkResourceId(), baseRule.isVpcResource(),
465465
rule.getLbBackends(), baseRule.getRuleId(), baseRule.getPublicIp(), baseRule.getPublicPort(),
466466
baseRule.getPrivatePort(), baseRule.getAlgorithm(), baseRule.getProtocol());
467+
if (Objects.nonNull(rule.getLbCidrList())) {
468+
cmd.setCidrList(rule.getLbCidrList());
469+
}
470+
cmd.setRuleName(rule.getLbRuleName());
467471
NetrisAnswer answer = sendNetrisCommand(cmd, baseRule.getZoneId());
468472
return answer.getResult();
469473
}
@@ -474,6 +478,10 @@ public boolean deleteLbRule(NetrisNetworkRule rule) {
474478
DeleteNetrisLoadBalancerRuleCommand cmd = new DeleteNetrisLoadBalancerRuleCommand(baseRule.getZoneId(), baseRule.getAccountId(),
475479
baseRule.getDomainId(), baseRule.getNetworkResourceName(), baseRule.getNetworkResourceId(), baseRule.isVpcResource(),
476480
baseRule.getRuleId());
481+
if (Objects.nonNull(rule.getLbCidrList())) {
482+
cmd.setCidrList(rule.getLbCidrList());
483+
}
484+
cmd.setRuleName(rule.getLbRuleName());
477485
NetrisAnswer answer = sendNetrisCommand(cmd, baseRule.getZoneId());
478486
return answer.getResult();
479487
}

0 commit comments

Comments
 (0)