This is an automated email from the ASF dual-hosted git repository. pearl11594 pushed a commit to branch nsx-cks-support in repository https://gitbox.apache.org/repos/asf/cloudstack.git
commit b0257dfaba441a4fa77a99665c7deaf7374160b2 Author: Pearl Dsilva <[email protected]> AuthorDate: Tue Nov 14 22:24:44 2023 -0500 Add Firewall rules --- .../apache/cloudstack/resource/NsxNetworkRule.java | 85 +++++++++++++++++++--- .../apache/cloudstack/resource/NsxResource.java | 4 +- .../apache/cloudstack/service/NsxApiClient.java | 67 +++++++++++------ .../org/apache/cloudstack/service/NsxElement.java | 30 +++++++- .../cloudstack/service/NsxApiClientTest.java | 4 +- 5 files changed, 153 insertions(+), 37 deletions(-) diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/resource/NsxNetworkRule.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/resource/NsxNetworkRule.java index a562b1bd3ea..b115aa802a8 100644 --- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/resource/NsxNetworkRule.java +++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/resource/NsxNetworkRule.java @@ -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 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 setCidrList(List<String> cidrList) { - this.cidrList = cidrList; + 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; } } diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/resource/NsxResource.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/resource/NsxResource.java index ba747eeb495..1754387fdf0 100644 --- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/resource/NsxResource.java +++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/resource/NsxResource.java @@ -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); diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxApiClient.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxApiClient.java index 4e916a7f4f1..918a633df9b 100644 --- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxApiClient.java +++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxApiClient.java @@ -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); diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxElement.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxElement.java index 9bdd03f452e..41e5a40de0c 100644 --- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxElement.java +++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxElement.java @@ -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); + } } diff --git a/plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/service/NsxApiClientTest.java b/plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/service/NsxApiClientTest.java index 2408b6f1e43..1865a008151 100644 --- a/plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/service/NsxApiClientTest.java +++ b/plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/service/NsxApiClientTest.java @@ -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);
