Skip to content

Commit 5c9e02d

Browse files
RodrigoDLopezLopezwinterhazel
authored andcommitted
enable to create VPC portfowarding rules with source cidr (apache#7081)
Co-authored-by: Lopez <[email protected]> Co-authored-by: Fabricio Duarte <[email protected]>
1 parent ce77e48 commit 5c9e02d

File tree

25 files changed

+399
-102
lines changed

25 files changed

+399
-102
lines changed

api/src/main/java/com/cloud/agent/api/to/PortForwardingRuleTO.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
import com.cloud.network.rules.FirewallRule;
2020
import com.cloud.network.rules.PortForwardingRule;
2121
import com.cloud.utils.net.NetUtils;
22+
import org.apache.commons.lang3.StringUtils;
23+
24+
import java.util.List;
2225

2326
/**
2427
* PortForwardingRuleTO specifies one port forwarding rule.
@@ -29,6 +32,8 @@ public class PortForwardingRuleTO extends FirewallRuleTO {
2932
String dstIp;
3033
int[] dstPortRange;
3134

35+
List<String> sourceCidrList;
36+
3237
protected PortForwardingRuleTO() {
3338
super();
3439
}
@@ -37,6 +42,7 @@ public PortForwardingRuleTO(PortForwardingRule rule, String srcVlanTag, String s
3742
super(rule, srcVlanTag, srcIp);
3843
this.dstIp = rule.getDestinationIpAddress().addr();
3944
this.dstPortRange = new int[] {rule.getDestinationPortStart(), rule.getDestinationPortEnd()};
45+
this.sourceCidrList = rule.getSourceCidrList();
4046
}
4147

4248
public PortForwardingRuleTO(long id, String srcIp, int srcPortStart, int srcPortEnd, String dstIp, int dstPortStart, int dstPortEnd, String protocol,
@@ -58,4 +64,11 @@ public String getStringDstPortRange() {
5864
return NetUtils.portRangeToString(dstPortRange);
5965
}
6066

67+
public String getSourceCidrListAsString() {
68+
if (sourceCidrList != null) {
69+
return StringUtils.join(sourceCidrList, ",");
70+
}
71+
return null;
72+
}
73+
6174
}

api/src/main/java/com/cloud/network/rules/RulesService.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import com.cloud.user.Account;
2727
import com.cloud.utils.Pair;
2828
import com.cloud.utils.net.Ip;
29+
import org.apache.cloudstack.api.command.user.firewall.UpdatePortForwardingRuleCmd;
2930

3031
public interface RulesService {
3132
Pair<List<? extends FirewallRule>, Integer> searchStaticNatRules(Long ipId, Long id, Long vmId, Long start, Long size, String accountName, Long domainId,
@@ -81,6 +82,8 @@ Pair<List<? extends FirewallRule>, Integer> searchStaticNatRules(Long ipId, Long
8182

8283
boolean disableStaticNat(long ipId) throws ResourceUnavailableException, NetworkRuleConflictException, InsufficientAddressCapacityException;
8384

84-
PortForwardingRule updatePortForwardingRule(long id, Integer privatePort, Integer privateEndPort, Long virtualMachineId, Ip vmGuestIp, String customId, Boolean forDisplay);
85+
PortForwardingRule updatePortForwardingRule(UpdatePortForwardingRuleCmd cmd);
86+
87+
void validatePortForwardingSourceCidrList(List<String> sourceCidrList);
8588

8689
}

api/src/main/java/org/apache/cloudstack/api/ApiConstants.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,8 @@ public class ApiConstants {
458458
public static final String SNAPSHOT_POLICY_ID = "snapshotpolicyid";
459459
public static final String SNAPSHOT_TYPE = "snapshottype";
460460
public static final String SNAPSHOT_QUIESCEVM = "quiescevm";
461+
public static final String SUPPORTS_STORAGE_SNAPSHOT = "supportsstoragesnapshot";
462+
public static final String SOURCE_CIDR_LIST = "sourcecidrlist";
461463
public static final String SOURCE_ZONE_ID = "sourcezoneid";
462464
public static final String SSL_VERIFICATION = "sslverification";
463465
public static final String START_ASN = "startasn";

api/src/main/java/org/apache/cloudstack/api/command/user/firewall/CreatePortForwardingRuleCmd.java

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,12 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P
105105
description = "the ID of the virtual machine for the port forwarding rule")
106106
private Long virtualMachineId;
107107

108-
@Parameter(name = ApiConstants.CIDR_LIST, type = CommandType.LIST, collectionType = CommandType.STRING, description = "the cidr list to forward traffic from. Multiple entries must be separated by a single comma character (,). This parameter is deprecated. Do not use.")
109-
private List<String> cidrlist;
108+
@Parameter(name = ApiConstants.CIDR_LIST,
109+
type = CommandType.LIST,
110+
collectionType = CommandType.STRING,
111+
description = " the source CIDR list to allow traffic from; all other CIDRs will be blocked. " +
112+
"Multiple entries must be separated by a single comma character (,). This param will be used only for VPC tiers. By default, all CIDRs are allowed.")
113+
private List<String> sourceCidrList;
110114

111115
@Parameter(name = ApiConstants.OPEN_FIREWALL, type = CommandType.BOOLEAN, description = "if true, firewall rule for source/end public port is automatically created; "
112116
+ "if false - firewall rule has to be created explicitly. If not specified 1) defaulted to false when PF"
@@ -155,11 +159,7 @@ public long getVirtualMachineId() {
155159

156160
@Override
157161
public List<String> getSourceCidrList() {
158-
if (cidrlist != null) {
159-
throw new InvalidParameterValueException("Parameter cidrList is deprecated; if you need to open firewall "
160-
+ "rule for the specific cidr, please refer to createFirewallRule command");
161-
}
162-
return null;
162+
return sourceCidrList;
163163
}
164164

165165
public Boolean getOpenFirewall() {
@@ -332,19 +332,15 @@ public int getDestinationPortEnd() {
332332

333333
@Override
334334
public void create() {
335-
// cidr list parameter is deprecated
336-
if (cidrlist != null) {
337-
throw new InvalidParameterValueException(
338-
"Parameter cidrList is deprecated; if you need to open firewall rule for the specific cidr, please refer to createFirewallRule command");
339-
}
340-
341335
Ip privateIp = getVmSecondaryIp();
342336
if (privateIp != null) {
343337
if (!NetUtils.isValidIp4(privateIp.toString())) {
344338
throw new InvalidParameterValueException("Invalid vm ip address");
345339
}
346340
}
347341

342+
_rulesService.validatePortForwardingSourceCidrList(sourceCidrList);
343+
348344
try {
349345
PortForwardingRule result = _rulesService.createPortForwardingRule(this, virtualMachineId, privateIp, getOpenFirewall(), isDisplay());
350346
setEntityId(result.getId());

api/src/main/java/org/apache/cloudstack/api/command/user/firewall/UpdatePortForwardingRuleCmd.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
import com.cloud.user.Account;
3333
import com.cloud.utils.net.Ip;
3434

35+
import java.util.List;
36+
3537
@APICommand(name = "updatePortForwardingRule",
3638
responseObject = FirewallRuleResponse.class,
3739
description = "Updates a port forwarding rule. Only the private port and the virtual machine can be updated.", entityType = {PortForwardingRule.class},
@@ -63,6 +65,13 @@ public class UpdatePortForwardingRuleCmd extends BaseAsyncCustomIdCmd {
6365
@Parameter(name = ApiConstants.FOR_DISPLAY, type = CommandType.BOOLEAN, description = "an optional field, whether to the display the rule to the end user or not", since = "4.4", authorized = {RoleType.Admin})
6466
private Boolean display;
6567

68+
@Parameter(name = ApiConstants.CIDR_LIST,
69+
type = CommandType.LIST,
70+
collectionType = CommandType.STRING,
71+
description = " the source CIDR list to allow traffic from; all other CIDRs will be blocked. " +
72+
"Multiple entries must be separated by a single comma character (,). This param will be used only for VPC tiers. By default, all CIDRs are allowed.")
73+
private List<String> sourceCidrList;
74+
6675
/////////////////////////////////////////////////////
6776
/////////////////// Accessors ///////////////////////
6877
/////////////////////////////////////////////////////
@@ -94,6 +103,10 @@ public Boolean getDisplay() {
94103
return display;
95104
}
96105

106+
public List<String> getSourceCidrList() {
107+
return sourceCidrList;
108+
}
109+
97110
/////////////////////////////////////////////////////
98111
/////////////// API Implementation///////////////////
99112
/////////////////////////////////////////////////////
@@ -130,7 +143,7 @@ public void checkUuid() {
130143

131144
@Override
132145
public void execute() {
133-
PortForwardingRule rule = _rulesService.updatePortForwardingRule(getId(), getPrivatePort(), getPrivateEndPort(), getVirtualMachineId(), getVmGuestIp(), getCustomId(), getDisplay());
146+
PortForwardingRule rule = _rulesService.updatePortForwardingRule(this);
134147
FirewallRuleResponse fwResponse = new FirewallRuleResponse();
135148
if (rule != null) {
136149
fwResponse = _responseGenerator.createPortForwardingRuleResponse(rule);

api/src/main/java/org/apache/cloudstack/api/command/user/loadbalancer/CreateLoadBalancerRuleCmd.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ public class CreateLoadBalancerRuleCmd extends BaseAsyncCreateCmd /*implements L
104104
@Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, entityType = DomainResponse.class, description = "the domain ID associated with the load balancer")
105105
private Long domainId;
106106

107-
@Parameter(name = ApiConstants.CIDR_LIST, type = CommandType.LIST, collectionType = CommandType.STRING, since = "4.18.0.0", description = "the CIDR list to allow traffic, "
107+
@Parameter(name = ApiConstants.CIDR_LIST, type = CommandType.LIST, collectionType = CommandType.STRING, since = "4.18.0.0", description = "the source CIDR list to allow traffic from; "
108108
+ "all other CIDRs will be blocked. Multiple entries must be separated by a single comma character (,). By default, all CIDRs are allowed.")
109109
private List<String> cidrlist;
110110

core/src/main/java/com/cloud/agent/resource/virtualnetwork/facade/SetPortForwardingRulesConfigItem.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public List<ConfigItem> generateConfig(final NetworkElementCommand cmd) {
4141

4242
for (final PortForwardingRuleTO rule : command.getRules()) {
4343
final ForwardingRule fwdRule = new ForwardingRule(rule.revoked(), rule.getProtocol().toLowerCase(), rule.getSrcIp(), rule.getStringSrcPortRange(), rule.getDstIp(),
44-
rule.getStringDstPortRange());
44+
rule.getStringDstPortRange(), rule.getSourceCidrListAsString());
4545
rules.add(fwdRule);
4646
}
4747

core/src/main/java/com/cloud/agent/resource/virtualnetwork/model/ForwardingRule.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,21 @@ public class ForwardingRule {
2626
private String sourcePortRange;
2727
private String destinationIpAddress;
2828
private String destinationPortRange;
29+
private String sourceCidrList;
2930

3031
public ForwardingRule() {
3132
// Empty constructor for (de)serialization
3233
}
3334

34-
public ForwardingRule(boolean revoke, String protocol, String sourceIpAddress, String sourcePortRange, String destinationIpAddress, String destinationPortRange) {
35+
public ForwardingRule(boolean revoke, String protocol, String sourceIpAddress, String sourcePortRange, String destinationIpAddress, String destinationPortRange,
36+
String sourceCidrList) {
3537
this.revoke = revoke;
3638
this.protocol = protocol;
3739
this.sourceIpAddress = sourceIpAddress;
3840
this.sourcePortRange = sourcePortRange;
3941
this.destinationIpAddress = destinationIpAddress;
4042
this.destinationPortRange = destinationPortRange;
43+
this.sourceCidrList = sourceCidrList;
4144
}
4245

4346
public boolean isRevoke() {
@@ -88,4 +91,8 @@ public void setDestinationPortRange(String destinationPortRange) {
8891
this.destinationPortRange = destinationPortRange;
8992
}
9093

94+
public String getSourceCidrList() {
95+
return sourceCidrList;
96+
}
97+
9198
}

engine/schema/src/main/java/com/cloud/network/dao/FirewallRulesCidrsDao.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,6 @@ public interface FirewallRulesCidrsDao extends GenericDao<FirewallRulesCidrsVO,
2929

3030
@DB
3131
List<FirewallRulesCidrsVO> listByFirewallRuleId(long firewallRuleId);
32+
33+
void updateSourceCidrsForRule(Long firewallRuleId, List<String> sourceCidrList);
3234
}

engine/schema/src/main/java/com/cloud/network/dao/FirewallRulesCidrsDaoImpl.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.util.List;
2121

2222

23+
import org.apache.commons.collections4.CollectionUtils;
2324
import org.springframework.stereotype.Component;
2425

2526
import com.cloud.utils.db.DB;
@@ -63,9 +64,27 @@ public List<FirewallRulesCidrsVO> listByFirewallRuleId(long firewallRuleId) {
6364
return results;
6465
}
6566

67+
@Override
68+
public void updateSourceCidrsForRule(Long firewallRuleId, List<String> sourceCidrList) {
69+
TransactionLegacy txn = TransactionLegacy.currentTxn();
70+
txn.start();
71+
72+
SearchCriteria<FirewallRulesCidrsVO> sc = CidrsSearch.create();
73+
sc.setParameters("firewallRuleId", firewallRuleId);
74+
remove(sc);
75+
76+
persist(firewallRuleId, sourceCidrList);
77+
78+
txn.commit();
79+
}
80+
6681
@Override
6782
@DB
6883
public void persist(long firewallRuleId, List<String> sourceCidrs) {
84+
if (CollectionUtils.isEmpty(sourceCidrs)) {
85+
return;
86+
}
87+
6988
TransactionLegacy txn = TransactionLegacy.currentTxn();
7089

7190
txn.start();

engine/schema/src/main/java/com/cloud/network/dao/FirewallRulesDaoImpl.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -251,9 +251,6 @@ public FirewallRuleVO persist(FirewallRuleVO firewallRule) {
251251
}
252252

253253
public void saveSourceCidrs(FirewallRuleVO firewallRule, List<String> cidrList) {
254-
if (cidrList == null) {
255-
return;
256-
}
257254
_firewallRulesCidrsDao.persist(firewallRule.getId(), cidrList);
258255
}
259256

engine/schema/src/main/java/com/cloud/network/rules/PortForwardingRuleVO.java

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import javax.persistence.Enumerated;
2626
import javax.persistence.PrimaryKeyJoinColumn;
2727
import javax.persistence.Table;
28+
import javax.persistence.Transient;
2829

2930
import com.cloud.utils.net.Ip;
3031

@@ -47,21 +48,20 @@ public class PortForwardingRuleVO extends FirewallRuleVO implements PortForwardi
4748
@Column(name = "instance_id")
4849
private long virtualMachineId;
4950

51+
@Transient
52+
List<String> sourceCidrs;
53+
5054
public PortForwardingRuleVO() {
5155
}
5256

5357
public PortForwardingRuleVO(String xId, long srcIpId, int srcPortStart, int srcPortEnd, Ip dstIp, int dstPortStart, int dstPortEnd, String protocol, long networkId,
54-
long accountId, long domainId, long instanceId) {
55-
super(xId, srcIpId, srcPortStart, srcPortEnd, protocol, networkId, accountId, domainId, Purpose.PortForwarding, null, null, null, null, null);
58+
long accountId, long domainId, long instanceId, List<String> sourceCidrs) {
59+
super(xId, srcIpId, srcPortStart, srcPortEnd, protocol, networkId, accountId, domainId, Purpose.PortForwarding, sourceCidrs, null, null, null, null);
5660
this.destinationIpAddress = dstIp;
5761
this.virtualMachineId = instanceId;
5862
this.destinationPortStart = dstPortStart;
5963
this.destinationPortEnd = dstPortEnd;
60-
}
61-
62-
public PortForwardingRuleVO(String xId, long srcIpId, int srcPort, Ip dstIp, int dstPort, String protocol, List<String> sourceCidrs, long networkId, long accountId,
63-
long domainId, long instanceId) {
64-
this(xId, srcIpId, srcPort, srcPort, dstIp, dstPort, dstPort, protocol.toLowerCase(), networkId, accountId, domainId, instanceId);
64+
this.sourceCidrs = sourceCidrs;
6565
}
6666

6767
@Override
@@ -106,4 +106,13 @@ public Long getRelated() {
106106
return null;
107107
}
108108

109+
public void setSourceCidrList(List<String> sourceCidrs) {
110+
this.sourceCidrs = sourceCidrs;
111+
}
112+
113+
@Override
114+
public List<String> getSourceCidrList() {
115+
return sourceCidrs;
116+
}
117+
109118
}

engine/schema/src/main/java/com/cloud/network/rules/dao/PortForwardingRulesDaoImpl.java

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@
3131
import com.cloud.utils.db.SearchBuilder;
3232
import com.cloud.utils.db.SearchCriteria;
3333
import com.cloud.utils.db.SearchCriteria.Op;
34+
import com.cloud.utils.db.Transaction;
35+
import com.cloud.utils.db.TransactionCallback;
36+
import com.cloud.utils.db.TransactionLegacy;
3437

3538
@Component
3639
public class PortForwardingRulesDaoImpl extends GenericDaoBase<PortForwardingRuleVO, Long> implements PortForwardingRulesDao {
@@ -42,7 +45,7 @@ public class PortForwardingRulesDaoImpl extends GenericDaoBase<PortForwardingRul
4245
protected final SearchBuilder<PortForwardingRuleVO> ActiveRulesSearchByAccount;
4346

4447
@Inject
45-
protected FirewallRulesCidrsDao _portForwardingRulesCidrsDao;
48+
protected FirewallRulesCidrsDao portForwardingRulesCidrsDao;
4649

4750
protected PortForwardingRulesDaoImpl() {
4851
super();
@@ -183,4 +186,43 @@ public int expungeByVmList(List<Long> vmIds, Long batchSize) {
183186
sc.setParameters("vmIds", vmIds.toArray());
184187
return batchExpunge(sc, batchSize);
185188
}
186-
}
189+
190+
public PortForwardingRuleVO persist(PortForwardingRuleVO portForwardingRule) {
191+
return Transaction.execute((TransactionCallback<PortForwardingRuleVO>) transactionStatus -> {
192+
PortForwardingRuleVO dbPfRule = super.persist(portForwardingRule);
193+
194+
portForwardingRulesCidrsDao.persist(portForwardingRule.getId(), portForwardingRule.getSourceCidrList());
195+
List<String> cidrList = portForwardingRulesCidrsDao.getSourceCidrs(portForwardingRule.getId());
196+
portForwardingRule.setSourceCidrList(cidrList);
197+
198+
return dbPfRule;
199+
});
200+
201+
}
202+
203+
@Override
204+
public boolean update(Long id, PortForwardingRuleVO entity) {
205+
TransactionLegacy txn = TransactionLegacy.currentTxn();
206+
txn.start();
207+
208+
boolean success = super.update(id, entity);
209+
if (!success) {
210+
return false;
211+
}
212+
213+
portForwardingRulesCidrsDao.updateSourceCidrsForRule(entity.getId(), entity.getSourceCidrList());
214+
txn.commit();
215+
216+
return true;
217+
}
218+
219+
@Override
220+
public PortForwardingRuleVO findById(Long id) {
221+
PortForwardingRuleVO rule = super.findById(id);
222+
223+
List<String> sourceCidrList = portForwardingRulesCidrsDao.getSourceCidrs(id);
224+
rule.setSourceCidrList(sourceCidrList);
225+
226+
return rule;
227+
}
228+
}

plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/actionworkers/KubernetesClusterResourceModifierActionWorker.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ protected void provisionPublicIpPortForwardingRule(IpAddress publicIp, Network n
461461
sourcePort, sourcePort,
462462
vmIp,
463463
destPort, destPort,
464-
"tcp", networkId, accountId, domainId, vmId);
464+
"tcp", networkId, accountId, domainId, vmId, null);
465465
newRule.setDisplay(true);
466466
newRule.setState(FirewallRule.State.Add);
467467
newRule = portForwardingRulesDao.persist(newRule);

0 commit comments

Comments
 (0)