Skip to content

Commit f76b58f

Browse files
authored
Add support to edit ACL rules (apache#74)
* Add support to edit ACL rules * add support to update acl rules * remove test file
1 parent bce51af commit f76b58f

File tree

7 files changed

+234
-55
lines changed

7 files changed

+234
-55
lines changed
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
package org.apache.cloudstack.agent.api;
18+
19+
import org.apache.cloudstack.resource.NetrisPortGroup;
20+
21+
public class CreateOrUpdateNetrisACLCommand extends NetrisCommand {
22+
private String vpcName;
23+
private Long vpcId;
24+
private String action;
25+
private String destPrefix;
26+
private String sourcePrefix;
27+
private Integer destPortStart;
28+
private Integer destPortEnd;
29+
private Integer icmpType;
30+
private String protocol;
31+
private NetrisPortGroup portGroup;
32+
private String netrisAclName;
33+
private String reason;
34+
35+
36+
public CreateOrUpdateNetrisACLCommand(long zoneId, Long accountId, Long domainId, String name, Long id, String vpcName, Long vpcId, boolean isVpc, String action,
37+
String sourcePrefix, String destPrefix, Integer destPortStart, Integer destPortEnd, String protocol) {
38+
super(zoneId, accountId, domainId, name, id, isVpc);
39+
this.vpcName = vpcName;
40+
this.vpcId = vpcId;
41+
this.action = action;
42+
this.sourcePrefix = sourcePrefix;
43+
this.destPrefix = destPrefix;
44+
this.destPortStart = destPortStart;
45+
this.destPortEnd = destPortEnd;
46+
this.protocol = protocol;
47+
}
48+
49+
public String getVpcName() {
50+
return vpcName;
51+
}
52+
53+
public void setVpcName(String vpcName) {
54+
this.vpcName = vpcName;
55+
}
56+
57+
public Long getVpcId() {
58+
return vpcId;
59+
}
60+
61+
public void setVpcId(Long vpcId) {
62+
this.vpcId = vpcId;
63+
}
64+
65+
public String getAction() {
66+
return action;
67+
}
68+
69+
public String getDestPrefix() {
70+
return destPrefix;
71+
}
72+
73+
public String getSourcePrefix() {
74+
return sourcePrefix;
75+
}
76+
77+
public Integer getDestPortStart() {
78+
return destPortStart;
79+
}
80+
81+
public Integer getDestPortEnd() {
82+
return destPortEnd;
83+
}
84+
85+
public String getProtocol() {
86+
return protocol;
87+
}
88+
89+
public NetrisPortGroup getPortGroup() {
90+
return portGroup;
91+
}
92+
93+
public void setPortGroup(NetrisPortGroup portGroup) {
94+
this.portGroup = portGroup;
95+
}
96+
97+
public Integer getIcmpType() {
98+
return icmpType;
99+
}
100+
101+
public void setIcmpType(Integer icmpType) {
102+
this.icmpType = icmpType;
103+
}
104+
105+
public String getNetrisAclName() {
106+
return netrisAclName;
107+
}
108+
109+
public void setNetrisAclName(String netrisAclName) {
110+
this.netrisAclName = netrisAclName;
111+
}
112+
113+
public String getReason() {
114+
return reason;
115+
}
116+
117+
public void setReason(String reason) {
118+
this.reason = reason;
119+
}
120+
}

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
import com.cloud.network.vpc.StaticRoute;
3030
import com.cloud.resource.ServerResource;
3131
import com.cloud.utils.exception.CloudRuntimeException;
32-
import org.apache.cloudstack.agent.api.CreateNetrisACLCommand;
32+
import org.apache.cloudstack.agent.api.CreateOrUpdateNetrisACLCommand;
3333
import org.apache.cloudstack.agent.api.AddOrUpdateNetrisStaticRouteCommand;
3434
import org.apache.cloudstack.agent.api.CreateNetrisVnetCommand;
3535
import org.apache.cloudstack.agent.api.CreateNetrisVpcCommand;
@@ -120,8 +120,8 @@ public Answer executeRequest(Command cmd) {
120120
return executeRequest((DeleteNetrisNatRuleCommand) cmd);
121121
} else if (cmd instanceof CreateOrUpdateNetrisNatCommand) {
122122
return executeRequest((CreateOrUpdateNetrisNatCommand) cmd);
123-
} else if (cmd instanceof CreateNetrisACLCommand) {
124-
return executeRequest((CreateNetrisACLCommand) cmd);
123+
} else if (cmd instanceof CreateOrUpdateNetrisACLCommand) {
124+
return executeRequest((CreateOrUpdateNetrisACLCommand) cmd);
125125
} else if (cmd instanceof DeleteNetrisACLCommand) {
126126
return executeRequest((DeleteNetrisACLCommand) cmd);
127127
} else if (cmd instanceof ListNetrisStaticRoutesCommand) {
@@ -360,8 +360,8 @@ private Answer executeRequest(DeleteNetrisNatRuleCommand cmd) {
360360
return new NetrisAnswer(cmd, true, "OK");
361361
}
362362

363-
private Answer executeRequest(CreateNetrisACLCommand cmd) {
364-
boolean result = netrisApiClient.addAclRule(cmd, false);
363+
private Answer executeRequest(CreateOrUpdateNetrisACLCommand cmd) {
364+
boolean result = netrisApiClient.addOrUpdateAclRule(cmd, false);
365365
if (!result) {
366366
return new NetrisAnswer(cmd, false, String.format("Creation of Netris ACL rule: %s failed", cmd.getNetrisAclName()));
367367
}

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
@@ -21,7 +21,7 @@
2121
import io.netris.model.GetSiteBody;
2222
import io.netris.model.VPCListing;
2323
import io.netris.model.response.TenantResponse;
24-
import org.apache.cloudstack.agent.api.CreateNetrisACLCommand;
24+
import org.apache.cloudstack.agent.api.CreateOrUpdateNetrisACLCommand;
2525
import org.apache.cloudstack.agent.api.AddOrUpdateNetrisStaticRouteCommand;
2626
import org.apache.cloudstack.agent.api.CreateNetrisVnetCommand;
2727
import org.apache.cloudstack.agent.api.CreateNetrisVpcCommand;
@@ -89,7 +89,7 @@ public interface NetrisApiClient {
8989
boolean createOrUpdateDNATRule(CreateOrUpdateNetrisNatCommand cmd);
9090
boolean createStaticNatRule(CreateOrUpdateNetrisNatCommand cmd);
9191
boolean deleteNatRule(DeleteNetrisNatRuleCommand cmd);
92-
boolean addAclRule(CreateNetrisACLCommand cmd, boolean forLb);
92+
boolean addOrUpdateAclRule(CreateOrUpdateNetrisACLCommand cmd, boolean forLb);
9393
boolean deleteAclRule(DeleteNetrisACLCommand cmd, boolean forLb);
9494
boolean addOrUpdateStaticRoute(AddOrUpdateNetrisStaticRouteCommand cmd);
9595
boolean deleteStaticRoute(DeleteNetrisStaticRouteCommand cmd);

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

Lines changed: 99 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,15 @@
4343
import io.netris.model.AclAddItem;
4444
import io.netris.model.AclBodyVpc;
4545
import io.netris.model.AclDeleteItem;
46+
import io.netris.model.AclEditItem;
4647
import io.netris.model.AclGetBody;
4748
import io.netris.model.AclResponseGetOk;
4849
import io.netris.model.AllocationBody;
4950
import io.netris.model.AllocationBodyVpc;
5051
import io.netris.model.FilterBySites;
5152
import io.netris.model.FilterByVpc;
5253
import io.netris.model.GetSiteBody;
54+
5355
import io.netris.model.InlineResponse20015;
5456
import io.netris.model.InlineResponse20016;
5557
import io.netris.model.InlineResponse2003;
@@ -112,7 +114,7 @@
112114
import io.netris.model.response.L4LbEditResponse;
113115
import io.netris.model.response.TenantResponse;
114116
import io.netris.model.response.TenantsResponse;
115-
import org.apache.cloudstack.agent.api.CreateNetrisACLCommand;
117+
import org.apache.cloudstack.agent.api.CreateOrUpdateNetrisACLCommand;
116118
import org.apache.cloudstack.agent.api.AddOrUpdateNetrisStaticRouteCommand;
117119
import org.apache.cloudstack.agent.api.CreateOrUpdateNetrisLoadBalancerRuleCommand;
118120
import org.apache.cloudstack.agent.api.CreateOrUpdateNetrisNatCommand;
@@ -386,42 +388,10 @@ public boolean deleteNatRule(DeleteNetrisNatRuleCommand cmd) {
386388
}
387389

388390
@Override
389-
public boolean addAclRule(CreateNetrisACLCommand cmd, boolean forLb) {
391+
public boolean addOrUpdateAclRule(CreateOrUpdateNetrisACLCommand cmd, boolean forLb) {
390392
String aclName = cmd.getNetrisAclName();
391393
try {
392394
AclApi aclApi = apiClient.getApiStubForMethod(AclApi.class);
393-
AclAddItem aclAddItem = new AclAddItem();
394-
aclAddItem.setAction(cmd.getAction());
395-
aclAddItem.setComment(String.format("ACL rule: %s. %s", cmd.getNetrisAclName(), cmd.getReason()));
396-
aclAddItem.setName(aclName);
397-
String protocol = cmd.getProtocol();
398-
if ("TCP".equals(protocol)) {
399-
aclAddItem.setEstablished(new BigDecimal(1));
400-
} else {
401-
aclAddItem.setReverse("yes");
402-
}
403-
if (!Arrays.asList(PROTOCOL_LIST).contains(protocol)) {
404-
aclAddItem.setProto("ip");
405-
aclAddItem.setSrcPortTo(cmd.getIcmpType());
406-
// TODO: set proto number: where should the protocol number be set - API sets the protocol number to Src-from & to and Dest-from & to fields
407-
} else if ("ICMP".equals(protocol)) {
408-
aclAddItem.setProto("icmp");
409-
if (cmd.getIcmpType() != -1) {
410-
aclAddItem.setIcmpType(cmd.getIcmpType());
411-
}
412-
} else {
413-
aclAddItem.setProto(protocol.toLowerCase(Locale.ROOT));
414-
}
415-
416-
aclAddItem.setDstPortFrom(cmd.getDestPortStart());
417-
aclAddItem.setDstPortTo(cmd.getDestPortEnd());
418-
aclAddItem.setDstPrefix(cmd.getDestPrefix());
419-
aclAddItem.setSrcPrefix(cmd.getSourcePrefix());
420-
aclAddItem.setSrcPortFrom(1);
421-
aclAddItem.setSrcPortTo(65535);
422-
if (NatPutBody.ProtocolEnum.ICMP.name().equalsIgnoreCase(protocol)) {
423-
aclAddItem.setIcmpType(cmd.getIcmpType());
424-
}
425395
VPCListing vpcResource;
426396
String netrisVpcName;
427397
if (forLb) {
@@ -436,20 +406,108 @@ public boolean addAclRule(CreateNetrisACLCommand cmd, boolean forLb) {
436406
}
437407
}
438408
AclBodyVpc vpc = new AclBodyVpc().id(vpcResource.getId());
439-
aclAddItem.setVpc(vpc);
440409
List<String> aclNames = List.of(aclName);
441410
Pair<Boolean, List<BigDecimal>> resultAndMatchingAclIds = getMatchingAclIds(aclNames, netrisVpcName);
442-
if (!resultAndMatchingAclIds.second().isEmpty()) {
443-
logger.debug("Netris ACL rule: {} already exists", aclName);
411+
List<BigDecimal> aclIdList = resultAndMatchingAclIds.second();
412+
if (!aclIdList.isEmpty()) {
413+
logger.debug("Netris ACL rule: {} already exists, updating it...", aclName);
414+
AclEditItem aclEditItem = getAclEditItem(cmd, aclName, aclIdList.get(0));
415+
aclEditItem.setVpc(vpc);
416+
try {
417+
aclApi.apiAclPut(aclEditItem);
418+
} catch (ApiException e) {
419+
if (e.getResponseBody().contains("This kind of acl already exists")) {
420+
logger.info("Netris ACL rule: {} already exists and doesn't need to be updated", aclName);
421+
return true;
422+
}
423+
throw new CloudRuntimeException("Error updating Netris ACL rule", e);
424+
}
444425
return true;
445426
}
427+
AclAddItem aclAddItem = getAclAddItem(cmd, aclName);
428+
aclAddItem.setVpc(vpc);
446429
aclApi.apiAclPost(aclAddItem);
447430
} catch (ApiException e) {
448431
logAndThrowException(String.format("Failed to create Netris ACL: %s", cmd.getNetrisAclName()), e);
449432
}
450433
return true;
451434
}
452435

436+
AclAddItem getAclAddItem(CreateOrUpdateNetrisACLCommand cmd, String aclName) throws ApiException {
437+
AclAddItem aclAddItem = new AclAddItem();
438+
aclAddItem.setAction(cmd.getAction());
439+
aclAddItem.setComment(String.format("ACL rule: %s. %s", cmd.getNetrisAclName(), cmd.getReason()));
440+
aclAddItem.setName(aclName);
441+
String protocol = cmd.getProtocol();
442+
if ("TCP".equals(protocol)) {
443+
aclAddItem.setEstablished(new BigDecimal(1));
444+
} else {
445+
aclAddItem.setReverse("yes");
446+
}
447+
if (!Arrays.asList(PROTOCOL_LIST).contains(protocol)) {
448+
aclAddItem.setProto("ip");
449+
aclAddItem.setSrcPortTo(cmd.getIcmpType());
450+
// TODO: set proto number: where should the protocol number be set - API sets the protocol number to Src-from & to and Dest-from & to fields
451+
} else if ("ICMP".equals(protocol)) {
452+
aclAddItem.setProto("icmp");
453+
if (cmd.getIcmpType() != -1) {
454+
aclAddItem.setIcmpType(cmd.getIcmpType());
455+
}
456+
} else {
457+
aclAddItem.setProto(protocol.toLowerCase(Locale.ROOT));
458+
}
459+
460+
aclAddItem.setDstPortFrom(cmd.getDestPortStart());
461+
aclAddItem.setDstPortTo(cmd.getDestPortEnd());
462+
aclAddItem.setDstPrefix(cmd.getDestPrefix());
463+
aclAddItem.setSrcPrefix(cmd.getSourcePrefix());
464+
aclAddItem.setSrcPortFrom(1);
465+
aclAddItem.setSrcPortTo(65535);
466+
if (NatPutBody.ProtocolEnum.ICMP.name().equalsIgnoreCase(protocol)) {
467+
aclAddItem.setIcmpType(cmd.getIcmpType());
468+
}
469+
470+
return aclAddItem;
471+
}
472+
473+
AclEditItem getAclEditItem(CreateOrUpdateNetrisACLCommand cmd, String aclName, BigDecimal aclId) throws ApiException {
474+
AclEditItem aclEditItem = new AclEditItem();
475+
aclEditItem.setId(aclId);
476+
aclEditItem.setAction(cmd.getAction());
477+
aclEditItem.setComment(String.format("ACL rule: %s. %s", cmd.getNetrisAclName(), cmd.getReason()));
478+
aclEditItem.setName(aclName);
479+
String protocol = cmd.getProtocol();
480+
if ("TCP".equals(protocol)) {
481+
aclEditItem.setEstablished(new BigDecimal(1));
482+
} else {
483+
aclEditItem.setReverse("yes");
484+
}
485+
if (!Arrays.asList(PROTOCOL_LIST).contains(protocol)) {
486+
aclEditItem.setProto("ip");
487+
aclEditItem.setSrcPortTo(cmd.getIcmpType());
488+
// TODO: set proto number: where should the protocol number be set - API sets the protocol number to Src-from & to and Dest-from & to fields
489+
} else if ("ICMP".equals(protocol)) {
490+
aclEditItem.setProto("icmp");
491+
if (cmd.getIcmpType() != -1) {
492+
aclEditItem.setIcmpType(cmd.getIcmpType());
493+
}
494+
} else {
495+
aclEditItem.setProto(protocol.toLowerCase(Locale.ROOT));
496+
}
497+
498+
aclEditItem.setDstPortFrom(cmd.getDestPortStart());
499+
aclEditItem.setDstPortTo(cmd.getDestPortEnd());
500+
aclEditItem.setDstPrefix(cmd.getDestPrefix());
501+
aclEditItem.setSrcPrefix(cmd.getSourcePrefix());
502+
aclEditItem.setSrcPortFrom(1);
503+
aclEditItem.setSrcPortTo(65535);
504+
if (NatPutBody.ProtocolEnum.ICMP.name().equalsIgnoreCase(protocol)) {
505+
aclEditItem.setIcmpType(cmd.getIcmpType());
506+
}
507+
508+
return aclEditItem;
509+
}
510+
453511
@Override
454512
public boolean deleteAclRule(DeleteNetrisACLCommand cmd, boolean forLb) {
455513
List<String> aclNames = cmd.getAclRuleNames();
@@ -768,12 +826,12 @@ public boolean createOrUpdateLbRule(CreateOrUpdateNetrisLoadBalancerRuleCommand
768826

769827
private void applyAclRulesForLb(CreateOrUpdateNetrisLoadBalancerRuleCommand cmd, String lbName) {
770828
// Add deny all rule first
771-
addAclRule(createNetrisACLRuleCommand(cmd, lbName, "ANY",
829+
addOrUpdateAclRule(createNetrisACLRuleCommand(cmd, lbName, "ANY",
772830
NetrisNetworkRule.NetrisRuleAction.DENY.name().toLowerCase(Locale.ROOT), 0), true);
773831
AtomicInteger cidrIndex = new AtomicInteger(1);
774832
for (String cidr : cmd.getCidrList().split(" ")) {
775833
try {
776-
addAclRule(createNetrisACLRuleCommand(cmd, lbName, cidr,
834+
addOrUpdateAclRule(createNetrisACLRuleCommand(cmd, lbName, cidr,
777835
NetrisNetworkRule.NetrisRuleAction.PERMIT.name().toLowerCase(Locale.ROOT),
778836
cidrIndex.getAndIncrement()), true);
779837
} catch (Exception e) {
@@ -782,7 +840,7 @@ private void applyAclRulesForLb(CreateOrUpdateNetrisLoadBalancerRuleCommand cmd,
782840
}
783841
}
784842

785-
private CreateNetrisACLCommand createNetrisACLRuleCommand(CreateOrUpdateNetrisLoadBalancerRuleCommand cmd, String netrisLbName, String cidr, String action, int index) {
843+
private CreateOrUpdateNetrisACLCommand createNetrisACLRuleCommand(CreateOrUpdateNetrisLoadBalancerRuleCommand cmd, String netrisLbName, String cidr, String action, int index) {
786844
Long zoneId = cmd.getZoneId();
787845
Long accountId = cmd.getAccountId();
788846
Long domainId = cmd.getDomainId();
@@ -801,7 +859,7 @@ private CreateNetrisACLCommand createNetrisACLRuleCommand(CreateOrUpdateNetrisLo
801859
String destinationPrefix = cmd.getPublicIp() + "/32";
802860
String srcPort = cmd.getPublicPort();
803861
String dstPort = cmd.getPublicPort();
804-
CreateNetrisACLCommand aclCommand = new CreateNetrisACLCommand(zoneId, accountId, domainId, networkName, networkId,
862+
CreateOrUpdateNetrisACLCommand aclCommand = new CreateOrUpdateNetrisACLCommand(zoneId, accountId, domainId, networkName, networkId,
805863
vpcName, vpcId, Objects.nonNull(vpcId), action, NetrisServiceImpl.getPrefix(cidr), NetrisServiceImpl.getPrefix(destinationPrefix),
806864
Integer.parseInt(srcPort), Integer.parseInt(dstPort), cmd.getProtocol());
807865
String aclName;

0 commit comments

Comments
 (0)