mirror of https://github.com/apache/cloudstack.git
Add Firewall rules
This commit is contained in:
parent
96de7e3fcc
commit
b0257dfaba
|
|
@ -16,6 +16,8 @@
|
|||
// under the License.
|
||||
package org.apache.cloudstack.resource;
|
||||
|
||||
import com.cloud.network.Network;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class NsxNetworkRule {
|
||||
|
|
@ -35,8 +37,13 @@ public class NsxNetworkRule {
|
|||
private String algorithm;
|
||||
private List<NsxLoadBalancerMember> memberList;
|
||||
private String aclAction;
|
||||
private List<String> cidrList;
|
||||
private List<String> sourceCidrList;
|
||||
private List<String> destinationCidrList;
|
||||
private Integer icmpCode;
|
||||
|
||||
private Integer icmpType;
|
||||
private String trafficType;
|
||||
private Network.Service service;
|
||||
|
||||
public long getDomainId() {
|
||||
return domainId;
|
||||
|
|
@ -166,12 +173,44 @@ public class NsxNetworkRule {
|
|||
this.aclAction = aclAction;
|
||||
}
|
||||
|
||||
public List<String> getCidrList() {
|
||||
return cidrList;
|
||||
public Network.Service getService() {
|
||||
return service;
|
||||
}
|
||||
|
||||
public void setCidrList(List<String> cidrList) {
|
||||
this.cidrList = cidrList;
|
||||
public void setService(Network.Service service) {
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
public Integer getIcmpCode() {
|
||||
return icmpCode;
|
||||
}
|
||||
|
||||
public void setIcmpCode(Integer icmpCode) {
|
||||
this.icmpCode = icmpCode;
|
||||
}
|
||||
|
||||
public Integer getIcmpType() {
|
||||
return icmpType;
|
||||
}
|
||||
|
||||
public void setIcmpType(Integer icmpType) {
|
||||
this.icmpType = icmpType;
|
||||
}
|
||||
|
||||
public List<String> getSourceCidrList() {
|
||||
return sourceCidrList;
|
||||
}
|
||||
|
||||
public void setSourceCidrList(List<String> sourceCidrList) {
|
||||
this.sourceCidrList = sourceCidrList;
|
||||
}
|
||||
|
||||
public List<String> getDestinationCidrList() {
|
||||
return destinationCidrList;
|
||||
}
|
||||
|
||||
public void setDestinationCidrList(List<String> destinationCidrList) {
|
||||
this.destinationCidrList = destinationCidrList;
|
||||
}
|
||||
|
||||
public String getTrafficType() {
|
||||
|
|
@ -200,8 +239,12 @@ public class NsxNetworkRule {
|
|||
private String algorithm;
|
||||
private List<NsxLoadBalancerMember> memberList;
|
||||
private String aclAction;
|
||||
private List<String> cidrList;
|
||||
private List<String> sourceCidrList;
|
||||
private List<String> destinationidrList;
|
||||
private String trafficType;
|
||||
private Integer icmpType;
|
||||
private Integer icmpCode;
|
||||
private Network.Service service;
|
||||
|
||||
public Builder() {
|
||||
}
|
||||
|
|
@ -287,8 +330,23 @@ public class NsxNetworkRule {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Builder setCidrList(List<String> cidrList) {
|
||||
this.cidrList = cidrList;
|
||||
public Builder setIcmpType(Integer icmpType) {
|
||||
this.icmpType = icmpType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setIcmpCode(Integer icmpCode) {
|
||||
this.icmpCode = icmpCode;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setSourceCidrList(List<String> sourceCidrList) {
|
||||
this.sourceCidrList = sourceCidrList;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setDestinationCidrList(List<String> destinationCidrList) {
|
||||
this.destinationidrList = destinationCidrList;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
@ -297,6 +355,11 @@ public class NsxNetworkRule {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Builder setService(Network.Service service) {
|
||||
this.service = service;
|
||||
return this;
|
||||
}
|
||||
|
||||
public NsxNetworkRule build() {
|
||||
NsxNetworkRule rule = new NsxNetworkRule();
|
||||
rule.setDomainId(this.domainId);
|
||||
|
|
@ -315,8 +378,12 @@ public class NsxNetworkRule {
|
|||
rule.setAlgorithm(this.algorithm);
|
||||
rule.setMemberList(this.memberList);
|
||||
rule.setAclAction(this.aclAction);
|
||||
rule.setCidrList(this.cidrList);
|
||||
rule.setIcmpType(this.icmpType);
|
||||
rule.setIcmpCode(this.icmpCode);
|
||||
rule.setSourceCidrList(this.sourceCidrList);
|
||||
rule.setDestinationCidrList(this.destinationidrList);
|
||||
rule.setTrafficType(this.trafficType);
|
||||
rule.setService(service);
|
||||
return rule;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -398,8 +398,8 @@ public class NsxResource implements ServerResource {
|
|||
cmd.getNetworkResourceId(), cmd.isResourceVpc());
|
||||
try {
|
||||
String privatePort = cmd.getPrivatePort();
|
||||
String service = privatePort.contains("-") ? nsxApiClient.createNsxInfraService(ruleName, privatePort, cmd.getProtocol()) :
|
||||
nsxApiClient.getNsxInfraServices(ruleName, privatePort, cmd.getProtocol());
|
||||
String service = privatePort.contains("-") ? nsxApiClient.getServicePath(ruleName, privatePort, cmd.getProtocol(), null, null) :
|
||||
nsxApiClient.getNsxInfraServices(ruleName, privatePort, cmd.getProtocol(), null, null);
|
||||
|
||||
nsxApiClient.createPortForwardingRule(ruleName, tier1GatewayName, cmd.getNetworkResourceName(), cmd.getPublicIp(),
|
||||
cmd.getVmIp(), cmd.getPublicPort(), service);
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ import com.vmware.nsx_policy.model.ApiError;
|
|||
import com.vmware.nsx_policy.model.DhcpRelayConfig;
|
||||
import com.vmware.nsx_policy.model.EnforcementPointListResult;
|
||||
import com.vmware.nsx_policy.model.Group;
|
||||
import com.vmware.nsx_policy.model.ICMPTypeServiceEntry;
|
||||
import com.vmware.nsx_policy.model.L4PortSetServiceEntry;
|
||||
import com.vmware.nsx_policy.model.LBAppProfileListResult;
|
||||
import com.vmware.nsx_policy.model.LBPool;
|
||||
|
|
@ -650,7 +651,7 @@ public class NsxApiClient {
|
|||
}
|
||||
}
|
||||
|
||||
public String getNsxInfraServices(String ruleName, String port, String protocol) {
|
||||
public String getNsxInfraServices(String ruleName, String port, String protocol, Integer icmpType, Integer icmpCode) {
|
||||
try {
|
||||
Services service = (Services) nsxService.apply(Services.class);
|
||||
|
||||
|
|
@ -675,7 +676,7 @@ public class NsxApiClient {
|
|||
}
|
||||
|
||||
// Else, create a service entry
|
||||
return createNsxInfraService(ruleName, port, protocol);
|
||||
return getServicePath(ruleName, port, protocol, icmpType, icmpCode);
|
||||
} catch (Error error) {
|
||||
ApiError ae = error.getData()._convertTo(ApiError.class);
|
||||
String msg = String.format("Failed to list NSX infra service, due to: %s", ae.getErrorMessage());
|
||||
|
|
@ -684,28 +685,35 @@ public class NsxApiClient {
|
|||
}
|
||||
}
|
||||
|
||||
public String createNsxInfraService(String ruleName, String port, String protocol) {
|
||||
public void createNsxInfraService(Services service, String serviceName, String ruleName, String port, String protocol,
|
||||
Integer icmpCode, Integer icmpType) {
|
||||
try {
|
||||
List<Structure> serviceEntries = new ArrayList<>();
|
||||
protocol = protocol.equals("ICMP") ? "ICMP4" : protocol;
|
||||
String serviceEntryName = getServiceEntryName(ruleName, port, protocol);
|
||||
String serviceName = getServiceName(ruleName, port, protocol);
|
||||
Services service = (Services) nsxService.apply(Services.class);
|
||||
if (protocol.equals("ICMP4")) {
|
||||
serviceEntries.add(new ICMPTypeServiceEntry.Builder()
|
||||
.setDisplayName(serviceEntryName)
|
||||
.setDisplayName(serviceEntryName)
|
||||
.setIcmpCode(Long.valueOf(icmpCode))
|
||||
.setIcmpType(Long.valueOf(icmpType))
|
||||
.setProtocol(protocol)
|
||||
.build()
|
||||
);
|
||||
} else {
|
||||
serviceEntries.add( new L4PortSetServiceEntry.Builder()
|
||||
.setId(serviceEntryName)
|
||||
.setDisplayName(serviceEntryName)
|
||||
.setDestinationPorts(List.of(port))
|
||||
.setL4Protocol(protocol)
|
||||
.build());
|
||||
}
|
||||
com.vmware.nsx_policy.model.Service infraService = new com.vmware.nsx_policy.model.Service.Builder()
|
||||
.setServiceEntries(List.of(
|
||||
new L4PortSetServiceEntry.Builder()
|
||||
.setId(serviceEntryName)
|
||||
.setDisplayName(serviceEntryName)
|
||||
.setDestinationPorts(List.of(port))
|
||||
.setL4Protocol(protocol)
|
||||
.build()
|
||||
))
|
||||
.setServiceEntries(serviceEntries)
|
||||
.setId(serviceName)
|
||||
.setDisplayName(serviceName)
|
||||
.build();
|
||||
service.patch(serviceName, infraService);
|
||||
|
||||
com.vmware.nsx_policy.model.Service svc = service.get(serviceName);
|
||||
return svc.getServiceEntries().get(0)._getDataValue().getField("parent_path").toString();
|
||||
|
||||
} catch (Error error) {
|
||||
ApiError ae = error.getData()._convertTo(ApiError.class);
|
||||
String msg = String.format("Failed to create NSX infra service, due to: %s", ae.getErrorMessage());
|
||||
|
|
@ -714,6 +722,18 @@ public class NsxApiClient {
|
|||
}
|
||||
}
|
||||
|
||||
private com.vmware.nsx_policy.model.Service getInfraService(String ruleName, String port, String protocol, Integer icmpType, Integer icmpCode) {
|
||||
Services service = (Services) nsxService.apply(Services.class);
|
||||
String serviceName = getServiceName(ruleName, port, protocol);
|
||||
createNsxInfraService(service, serviceName, ruleName, port, protocol, icmpType, icmpCode);
|
||||
return service.get(serviceName);
|
||||
}
|
||||
|
||||
public String getServicePath(String ruleName, String port, String protocol, Integer icmpType, Integer icmpCode) { //com.vmware.nsx_policy.model.Service svc) {
|
||||
com.vmware.nsx_policy.model.Service svc = getInfraService(ruleName, port, protocol, icmpType, icmpCode);
|
||||
return svc.getServiceEntries().get(0)._getDataValue().getField("parent_path").toString();
|
||||
}
|
||||
|
||||
private String getServiceById(String ruleName) {
|
||||
try {
|
||||
Services service = (Services) nsxService.apply(Services.class);
|
||||
|
|
@ -797,9 +817,13 @@ public class NsxApiClient {
|
|||
.setResourceType("SecurityPolicy")
|
||||
.setSourceGroups(getGroupsForTraffic(rule, segmentName, true))
|
||||
.setDestinationGroups(getGroupsForTraffic(rule, segmentName, false))
|
||||
.setServices(List.of("ANY"))
|
||||
.setServices(Objects.nonNull(rule.getPrivatePort()) ? List.of(getServicePath(ruleId, rule.getPrivatePort(),
|
||||
rule.getProtocol(), rule.getIcmpType(), rule.getIcmpCode())) : List.of("ANY"))
|
||||
.setScope(List.of("ANY"))
|
||||
.build();
|
||||
if (Objects.nonNull(rule.getPrivatePort())) {
|
||||
|
||||
}
|
||||
rules.add(ruleToAdd);
|
||||
}
|
||||
return rules;
|
||||
|
|
@ -808,13 +832,14 @@ public class NsxApiClient {
|
|||
protected List<String> getGroupsForTraffic(NsxNetworkRule rule,
|
||||
String segmentName, boolean source) {
|
||||
List<String> segmentGroup = List.of(String.format("%s/%s", GROUPS_PATH_PREFIX, segmentName));
|
||||
List<String> ruleCidrList = rule.getCidrList();
|
||||
List<String> sourceCidrList = rule.getSourceCidrList();
|
||||
List<String> destCidrList = rule.getDestinationCidrList();
|
||||
|
||||
String trafficType = rule.getTrafficType();
|
||||
if (trafficType.equalsIgnoreCase("ingress")) {
|
||||
return source ? ruleCidrList : segmentGroup;
|
||||
return source ? sourceCidrList : (rule.getService() == Network.Service.NetworkACL ? segmentGroup : destCidrList);
|
||||
} else if (trafficType.equalsIgnoreCase("egress")) {
|
||||
return source ? segmentGroup : ruleCidrList;
|
||||
return source ? segmentGroup : (rule.getService() == Network.Service.NetworkACL ? sourceCidrList : destCidrList);
|
||||
}
|
||||
String err = String.format("Unsupported traffic type %s", trafficType);
|
||||
LOGGER.error(err);
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ import com.cloud.network.dao.PhysicalNetworkDao;
|
|||
import com.cloud.network.dao.PhysicalNetworkVO;
|
||||
import com.cloud.network.element.DhcpServiceProvider;
|
||||
import com.cloud.network.element.DnsServiceProvider;
|
||||
import com.cloud.network.element.FirewallServiceProvider;
|
||||
import com.cloud.network.element.IpDeployer;
|
||||
import com.cloud.network.element.LoadBalancingServiceProvider;
|
||||
import com.cloud.network.element.NetworkACLServiceProvider;
|
||||
|
|
@ -109,7 +110,7 @@ import java.util.function.LongFunction;
|
|||
@Component
|
||||
public class NsxElement extends AdapterBase implements DhcpServiceProvider, DnsServiceProvider, VpcProvider,
|
||||
StaticNatServiceProvider, IpDeployer, PortForwardingServiceProvider, NetworkACLServiceProvider,
|
||||
LoadBalancingServiceProvider, ResourceStateAdapter, Listener {
|
||||
LoadBalancingServiceProvider, FirewallServiceProvider, ResourceStateAdapter, Listener {
|
||||
|
||||
|
||||
@Inject
|
||||
|
|
@ -578,7 +579,7 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, Dns
|
|||
String.valueOf(rule.getDestinationPortStart()).concat("-").concat(String.valueOf(rule.getDestinationPortEnd()));
|
||||
}
|
||||
|
||||
private static String getPrivatePortRange(PortForwardingRule rule) {
|
||||
private static String getPrivatePortRange(FirewallRule rule) {
|
||||
return Objects.equals(rule.getSourcePortStart(), rule.getSourcePortEnd()) ?
|
||||
String.valueOf(rule.getSourcePortStart()) :
|
||||
String.valueOf(rule.getSourcePortStart()).concat("-").concat(String.valueOf(rule.getSourcePortEnd()));
|
||||
|
|
@ -665,9 +666,10 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, Dns
|
|||
for (NetworkACLItem rule : rules) {
|
||||
NsxNetworkRule networkRule = new NsxNetworkRule.Builder()
|
||||
.setRuleId(rule.getId())
|
||||
.setCidrList(transformCidrListValues(rule.getSourceCidrList()))
|
||||
.setSourceCidrList(transformCidrListValues(rule.getSourceCidrList()))
|
||||
.setAclAction(rule.getAction().toString())
|
||||
.setTrafficType(rule.getTrafficType().toString())
|
||||
.setService(Network.Service.NetworkACL)
|
||||
.build();
|
||||
nsxNetworkRules.add(networkRule);
|
||||
}
|
||||
|
|
@ -688,4 +690,26 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, Dns
|
|||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyFWRules(Network network, List<? extends FirewallRule> rules) throws ResourceUnavailableException {
|
||||
if (!canHandle(network, Network.Service.Firewall)) {
|
||||
return false;
|
||||
}
|
||||
List<NsxNetworkRule> nsxNetworkRules = new ArrayList<>();
|
||||
for (FirewallRule rule : rules) {
|
||||
NsxNetworkRule networkRule = new NsxNetworkRule.Builder()
|
||||
.setRuleId(rule.getId())
|
||||
.setSourceCidrList(transformCidrListValues(rule.getSourceCidrList()))
|
||||
.setDestinationCidrList(transformCidrListValues(rule.getDestinationCidrList()))
|
||||
.setIcmpCode(rule.getIcmpCode())
|
||||
.setIcmpType(rule.getIcmpType())
|
||||
.setPrivatePort(getPrivatePortRange(rule))
|
||||
.setTrafficType(rule.getTrafficType().toString())
|
||||
.setService(Network.Service.Firewall)
|
||||
.build();
|
||||
nsxNetworkRules.add(networkRule);
|
||||
}
|
||||
return nsxService.addFirewallRules(network, nsxNetworkRules);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ public class NsxApiClientTest {
|
|||
@Test
|
||||
public void testGetGroupsForTrafficIngress() {
|
||||
NsxNetworkRule rule = Mockito.mock(NsxNetworkRule.class);
|
||||
Mockito.when(rule.getCidrList()).thenReturn(List.of("ANY"));
|
||||
Mockito.when(rule.getSourceCidrList()).thenReturn(List.of("ANY"));
|
||||
Mockito.when(rule.getTrafficType()).thenReturn("Ingress");
|
||||
String segmentName = "segment";
|
||||
List<String> sourceGroups = client.getGroupsForTraffic(rule, segmentName, true);
|
||||
|
|
@ -82,7 +82,7 @@ public class NsxApiClientTest {
|
|||
@Test
|
||||
public void testGetGroupsForTrafficEgress() {
|
||||
NsxNetworkRule rule = Mockito.mock(NsxNetworkRule.class);
|
||||
Mockito.when(rule.getCidrList()).thenReturn(List.of("ANY"));
|
||||
Mockito.when(rule.getSourceCidrList()).thenReturn(List.of("ANY"));
|
||||
Mockito.when(rule.getTrafficType()).thenReturn("Egress");
|
||||
String segmentName = "segment";
|
||||
List<String> sourceGroups = client.getGroupsForTraffic(rule, segmentName, true);
|
||||
|
|
|
|||
Loading…
Reference in New Issue