mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
[NSX] Add ACL types support (#8224)
* NSX: Create segment group on segment creation * Add unit tests * Remove group for segment before removing segment * Create Distributed Firewall rules * Remove distributed firewall policy on segment deletion * Fix policy rule ID and add more unit tests * Fix DROP action rules and transform tests * Add new ACL rules * Fixes * associate security policies with groups and not to DFW and add deletion of rules * Fix name convention --------- Co-authored-by: Pearl Dsilva <pearl1594@gmail.com>
This commit is contained in:
parent
053521077c
commit
8a87eaaec9
@ -1735,8 +1735,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
|
||||
}
|
||||
|
||||
//apply network ACLs
|
||||
// TODO: remove check for NSX
|
||||
if (!offering.isForNsx() && !_networkACLMgr.applyACLToNetwork(networkId)) {
|
||||
if (!_networkACLMgr.applyACLToNetwork(networkId)) {
|
||||
s_logger.warn("Failed to reapply network ACLs as a part of of network id=" + networkId + " restart");
|
||||
success = false;
|
||||
}
|
||||
|
||||
@ -0,0 +1,49 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.agent.api;
|
||||
|
||||
import org.apache.cloudstack.resource.NsxNetworkRule;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class CreateNsxDistributedFirewallRulesCommand extends NsxCommand {
|
||||
|
||||
private Long vpcId;
|
||||
private long networkId;
|
||||
private List<NsxNetworkRule> rules;
|
||||
|
||||
public CreateNsxDistributedFirewallRulesCommand(long domainId, long accountId, long zoneId,
|
||||
Long vpcId, long networkId,
|
||||
List<NsxNetworkRule> rules) {
|
||||
super(domainId, accountId, zoneId);
|
||||
this.vpcId = vpcId;
|
||||
this.networkId = networkId;
|
||||
this.rules = rules;
|
||||
}
|
||||
|
||||
public Long getVpcId() {
|
||||
return vpcId;
|
||||
}
|
||||
|
||||
public long getNetworkId() {
|
||||
return networkId;
|
||||
}
|
||||
|
||||
public List<NsxNetworkRule> getRules() {
|
||||
return rules;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.agent.api;
|
||||
|
||||
import org.apache.cloudstack.resource.NsxNetworkRule;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class DeletedNsxDistributedFirewallRulesCommand extends CreateNsxDistributedFirewallRulesCommand {
|
||||
public DeletedNsxDistributedFirewallRulesCommand(long domainId, long accountId, long zoneId, Long vpcId, long networkId, List<NsxNetworkRule> rules) {
|
||||
super(domainId, accountId, zoneId, vpcId, networkId, rules);
|
||||
}
|
||||
}
|
||||
@ -16,9 +16,16 @@
|
||||
// under the License.
|
||||
package org.apache.cloudstack.resource;
|
||||
|
||||
import com.cloud.network.Network;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class NsxNetworkRule {
|
||||
|
||||
public enum NsxRuleAction {
|
||||
ALLOW, DROP
|
||||
}
|
||||
|
||||
private long domainId;
|
||||
private long accountId;
|
||||
private long zoneId;
|
||||
@ -34,6 +41,36 @@ public class NsxNetworkRule {
|
||||
private String protocol;
|
||||
private String algorithm;
|
||||
private List<NsxLoadBalancerMember> memberList;
|
||||
private NsxRuleAction aclAction;
|
||||
private List<String> cidrList;
|
||||
private String trafficType;
|
||||
private Integer icmpCode;
|
||||
private Integer icmpType;
|
||||
private Network.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 Network.Service getService() {
|
||||
return service;
|
||||
}
|
||||
|
||||
public void setService(Network.Service service) {
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
public long getDomainId() {
|
||||
return domainId;
|
||||
@ -155,6 +192,30 @@ public class NsxNetworkRule {
|
||||
this.memberList = memberList;
|
||||
}
|
||||
|
||||
public NsxRuleAction getAclAction() {
|
||||
return aclAction;
|
||||
}
|
||||
|
||||
public void setAclAction(NsxRuleAction aclAction) {
|
||||
this.aclAction = aclAction;
|
||||
}
|
||||
|
||||
public List<String> getCidrList() {
|
||||
return cidrList;
|
||||
}
|
||||
|
||||
public void setCidrList(List<String> cidrList) {
|
||||
this.cidrList = cidrList;
|
||||
}
|
||||
|
||||
public String getTrafficType() {
|
||||
return trafficType;
|
||||
}
|
||||
|
||||
public void setTrafficType(String trafficType) {
|
||||
this.trafficType = trafficType;
|
||||
}
|
||||
|
||||
public static final class Builder {
|
||||
private long domainId;
|
||||
private long accountId;
|
||||
@ -172,6 +233,12 @@ public class NsxNetworkRule {
|
||||
private String protocol;
|
||||
private String algorithm;
|
||||
private List<NsxLoadBalancerMember> memberList;
|
||||
private NsxRuleAction aclAction;
|
||||
private List<String> cidrList;
|
||||
private String trafficType;
|
||||
private Integer icmpType;
|
||||
private Integer icmpCode;
|
||||
private Network.Service service;
|
||||
|
||||
public Builder() {
|
||||
}
|
||||
@ -252,6 +319,36 @@ public class NsxNetworkRule {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setAclAction(NsxRuleAction aclAction) {
|
||||
this.aclAction = aclAction;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setCidrList(List<String> cidrList) {
|
||||
this.cidrList = cidrList;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setTrafficType(String trafficType) {
|
||||
this.trafficType = trafficType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setIcmpType(Integer icmpType) {
|
||||
this.icmpType = icmpType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setIcmpCode(Integer icmpCode) {
|
||||
this.icmpCode = icmpCode;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setService(Network.Service service) {
|
||||
this.service = service;
|
||||
return this;
|
||||
}
|
||||
|
||||
public NsxNetworkRule build() {
|
||||
NsxNetworkRule rule = new NsxNetworkRule();
|
||||
rule.setDomainId(this.domainId);
|
||||
@ -269,6 +366,12 @@ public class NsxNetworkRule {
|
||||
rule.setRuleId(this.ruleId);
|
||||
rule.setAlgorithm(this.algorithm);
|
||||
rule.setMemberList(this.memberList);
|
||||
rule.setAclAction(this.aclAction);
|
||||
rule.setCidrList(this.cidrList);
|
||||
rule.setTrafficType(this.trafficType);
|
||||
rule.setIcmpType(this.icmpType);
|
||||
rule.setIcmpCode(this.icmpCode);
|
||||
rule.setService(this.service);
|
||||
return rule;
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,6 +36,7 @@ import com.vmware.nsx_policy.model.SiteListResult;
|
||||
import org.apache.cloudstack.NsxAnswer;
|
||||
import org.apache.cloudstack.StartupNsxCommand;
|
||||
import org.apache.cloudstack.agent.api.CreateNsxDhcpRelayConfigCommand;
|
||||
import org.apache.cloudstack.agent.api.CreateNsxDistributedFirewallRulesCommand;
|
||||
import org.apache.cloudstack.agent.api.CreateNsxLoadBalancerRuleCommand;
|
||||
import org.apache.cloudstack.agent.api.CreateNsxPortForwardRuleCommand;
|
||||
import org.apache.cloudstack.agent.api.CreateNsxSegmentCommand;
|
||||
@ -46,6 +47,7 @@ import org.apache.cloudstack.agent.api.DeleteNsxLoadBalancerRuleCommand;
|
||||
import org.apache.cloudstack.agent.api.DeleteNsxSegmentCommand;
|
||||
import org.apache.cloudstack.agent.api.DeleteNsxNatRuleCommand;
|
||||
import org.apache.cloudstack.agent.api.DeleteNsxTier1GatewayCommand;
|
||||
import org.apache.cloudstack.agent.api.DeletedNsxDistributedFirewallRulesCommand;
|
||||
import org.apache.cloudstack.service.NsxApiClient;
|
||||
import org.apache.cloudstack.utils.NsxControllerUtils;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
@ -123,6 +125,10 @@ public class NsxResource implements ServerResource {
|
||||
return executeRequest((CreateNsxLoadBalancerRuleCommand) cmd);
|
||||
} else if (cmd instanceof DeleteNsxLoadBalancerRuleCommand) {
|
||||
return executeRequest((DeleteNsxLoadBalancerRuleCommand) cmd);
|
||||
} else if (cmd instanceof DeletedNsxDistributedFirewallRulesCommand) {
|
||||
return executeRequest((DeletedNsxDistributedFirewallRulesCommand) cmd);
|
||||
} else if (cmd instanceof CreateNsxDistributedFirewallRulesCommand) {
|
||||
return executeRequest((CreateNsxDistributedFirewallRulesCommand) cmd);
|
||||
} else {
|
||||
return Answer.createUnsupportedCommandAnswer(cmd);
|
||||
}
|
||||
@ -353,6 +359,7 @@ public class NsxResource implements ServerResource {
|
||||
String tier1GatewayName = NsxControllerUtils.getTier1GatewayName(cmd.getDomainId(), cmd.getAccountId(),
|
||||
cmd.getZoneId(), networkResourceId, isResourceVpc);
|
||||
nsxApiClient.createSegment(segmentName, tier1GatewayName, gatewayAddress, enforcementPointPath, transportZones);
|
||||
nsxApiClient.createGroupForSegment(segmentName);
|
||||
} catch (Exception e) {
|
||||
LOGGER.error(String.format("Failed to create network: %s", cmd.getNetworkName()));
|
||||
return new NsxAnswer(cmd, new CloudRuntimeException(e.getMessage()));
|
||||
@ -394,8 +401,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);
|
||||
@ -454,6 +461,32 @@ public class NsxResource implements ServerResource {
|
||||
return new NsxAnswer(cmd, true, null);
|
||||
}
|
||||
|
||||
private NsxAnswer executeRequest(CreateNsxDistributedFirewallRulesCommand cmd) {
|
||||
String segmentName = NsxControllerUtils.getNsxSegmentId(cmd.getDomainId(), cmd.getAccountId(),
|
||||
cmd.getZoneId(), cmd.getVpcId(), cmd.getNetworkId());
|
||||
List<NsxNetworkRule> rules = cmd.getRules();
|
||||
try {
|
||||
nsxApiClient.createSegmentDistributedFirewall(segmentName, rules);
|
||||
} catch (Exception e) {
|
||||
LOGGER.error(String.format("Failed to create NSX distributed firewall %s: %s", segmentName, e.getMessage()), e);
|
||||
return new NsxAnswer(cmd, new CloudRuntimeException(e.getMessage()));
|
||||
}
|
||||
return new NsxAnswer(cmd, true, null);
|
||||
}
|
||||
|
||||
private NsxAnswer executeRequest(DeletedNsxDistributedFirewallRulesCommand cmd) {
|
||||
String segmentName = NsxControllerUtils.getNsxSegmentId(cmd.getDomainId(), cmd.getAccountId(),
|
||||
cmd.getZoneId(), cmd.getVpcId(), cmd.getNetworkId());
|
||||
List<NsxNetworkRule> rules = cmd.getRules();
|
||||
try {
|
||||
nsxApiClient.deleteDistributedFirewallRules(segmentName, rules);
|
||||
} catch (Exception e) {
|
||||
LOGGER.error(String.format("Failed to create NSX distributed firewall %s: %s", segmentName, e.getMessage()), e);
|
||||
return new NsxAnswer(cmd, new CloudRuntimeException(e.getMessage()));
|
||||
}
|
||||
return new NsxAnswer(cmd, true, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean start() {
|
||||
return true;
|
||||
|
||||
@ -29,12 +29,18 @@ import com.vmware.nsx_policy.infra.Segments;
|
||||
import com.vmware.nsx_policy.infra.Services;
|
||||
import com.vmware.nsx_policy.infra.Sites;
|
||||
import com.vmware.nsx_policy.infra.Tier1s;
|
||||
import com.vmware.nsx_policy.infra.domains.Groups;
|
||||
import com.vmware.nsx_policy.infra.domains.SecurityPolicies;
|
||||
import com.vmware.nsx_policy.infra.domains.security_policies.Rules;
|
||||
import com.vmware.nsx_policy.infra.sites.EnforcementPoints;
|
||||
import com.vmware.nsx_policy.infra.tier_0s.LocaleServices;
|
||||
import com.vmware.nsx_policy.infra.tier_1s.nat.NatRules;
|
||||
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.GroupListResult;
|
||||
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;
|
||||
@ -44,8 +50,11 @@ import com.vmware.nsx_policy.model.LBService;
|
||||
import com.vmware.nsx_policy.model.LBVirtualServer;
|
||||
import com.vmware.nsx_policy.model.LBVirtualServerListResult;
|
||||
import com.vmware.nsx_policy.model.LocaleServicesListResult;
|
||||
import com.vmware.nsx_policy.model.PathExpression;
|
||||
import com.vmware.nsx_policy.model.PolicyNatRule;
|
||||
import com.vmware.nsx_policy.model.PolicyNatRuleListResult;
|
||||
import com.vmware.nsx_policy.model.Rule;
|
||||
import com.vmware.nsx_policy.model.SecurityPolicy;
|
||||
import com.vmware.nsx_policy.model.Segment;
|
||||
import com.vmware.nsx_policy.model.SegmentSubnet;
|
||||
import com.vmware.nsx_policy.model.ServiceListResult;
|
||||
@ -64,6 +73,7 @@ import com.vmware.vapi.internal.protocol.client.rest.authn.BasicAuthenticationAp
|
||||
import com.vmware.vapi.protocol.HttpConfiguration;
|
||||
import com.vmware.vapi.std.errors.Error;
|
||||
import org.apache.cloudstack.resource.NsxLoadBalancerMember;
|
||||
import org.apache.cloudstack.resource.NsxNetworkRule;
|
||||
import org.apache.cloudstack.utils.NsxControllerUtils;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
@ -86,7 +96,7 @@ import static org.apache.cloudstack.utils.NsxControllerUtils.getLoadBalancerAlgo
|
||||
|
||||
public class NsxApiClient {
|
||||
|
||||
private final Function<Class<? extends Service>, Service> nsxService;
|
||||
protected Function<Class<? extends Service>, Service> nsxService;
|
||||
|
||||
public static final int RESPONSE_TIMEOUT_SECONDS = 60;
|
||||
private static final Logger LOGGER = Logger.getLogger(NsxApiClient.class);
|
||||
@ -97,6 +107,9 @@ public class NsxApiClient {
|
||||
private static final String SEGMENT_RESOURCE_TYPE = "Segment";
|
||||
private static final String TIER_0_GATEWAY_PATH_PREFIX = "/infra/tier-0s/";
|
||||
private static final String TIER_1_GATEWAY_PATH_PREFIX = "/infra/tier-1s/";
|
||||
protected static final String SEGMENTS_PATH = "/infra/segments";
|
||||
protected static final String DEFAULT_DOMAIN = "default";
|
||||
protected static final String GROUPS_PATH_PREFIX = "/infra/domains/default/groups";
|
||||
|
||||
private enum PoolAllocation { ROUTING, LB_SMALL, LB_MEDIUM, LB_LARGE, LB_XLARGE }
|
||||
|
||||
@ -137,6 +150,9 @@ public class NsxApiClient {
|
||||
TIER1_LB_VIP, TIER1_LB_SNAT, TIER1_DNS_FORWARDER_IP, TIER1_IPSEC_LOCAL_ENDPOINT
|
||||
}
|
||||
|
||||
protected NsxApiClient() {
|
||||
}
|
||||
|
||||
public NsxApiClient(String hostname, String port, String username, char[] password) {
|
||||
String controllerUrl = String.format("https://%s:%s", hostname, port);
|
||||
HttpConfiguration.SslConfiguration.Builder sslConfigBuilder = new HttpConfiguration.SslConfiguration.Builder();
|
||||
@ -376,6 +392,8 @@ public class NsxApiClient {
|
||||
public void deleteSegment(long zoneId, long domainId, long accountId, Long vpcId, long networkId, String segmentName) {
|
||||
try {
|
||||
Segments segmentService = (Segments) nsxService.apply(Segments.class);
|
||||
removeSegmentDistributedFirewallRules(segmentName);
|
||||
removeGroupForSegment(segmentName);
|
||||
LOGGER.debug(String.format("Removing the segment with ID %s", segmentName));
|
||||
segmentService.delete(segmentName);
|
||||
DhcpRelayConfigs dhcpRelayConfig = (DhcpRelayConfigs) nsxService.apply(DhcpRelayConfigs.class);
|
||||
@ -422,7 +440,7 @@ public class NsxApiClient {
|
||||
// delete NAT rule
|
||||
natService.delete(tier1GatewayName, NatId.USER.name(), ruleName);
|
||||
if (service == Network.Service.PortForwarding) {
|
||||
String svcName = getServiceName(ruleName, privatePort, protocol);
|
||||
String svcName = getServiceName(ruleName, privatePort, protocol, null, null);
|
||||
// Delete service
|
||||
Services services = (Services) nsxService.apply(Services.class);
|
||||
services.delete(svcName);
|
||||
@ -635,7 +653,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);
|
||||
|
||||
@ -660,7 +678,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());
|
||||
@ -669,28 +687,47 @@ public class NsxApiClient {
|
||||
}
|
||||
}
|
||||
|
||||
public String createNsxInfraService(String ruleName, String port, String protocol) {
|
||||
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, icmpType, icmpCode);
|
||||
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 = getInfraService(ruleName, port, protocol, icmpType, icmpCode);
|
||||
return svc.getServiceEntries().get(0)._getDataValue().getField("parent_path").toString();
|
||||
}
|
||||
|
||||
public void createNsxInfraService(Services service, String serviceName, String ruleName, String port, String protocol,
|
||||
Integer icmpType, Integer icmpCode) {
|
||||
try {
|
||||
List<Structure> serviceEntries = new ArrayList<>();
|
||||
protocol = "ICMP".equalsIgnoreCase(protocol) ? "ICMPv4" : protocol;
|
||||
String serviceEntryName = getServiceEntryName(ruleName, port, protocol);
|
||||
String serviceName = getServiceName(ruleName, port, protocol);
|
||||
Services service = (Services) nsxService.apply(Services.class);
|
||||
if (protocol.equals("ICMPv4")) {
|
||||
serviceEntries.add(new ICMPTypeServiceEntry.Builder()
|
||||
.setId(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());
|
||||
@ -711,4 +748,152 @@ public class NsxApiClient {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Group for the Segment on the Inventory, with the same name as the segment and being the segment the only member of the group
|
||||
*/
|
||||
public void createGroupForSegment(String segmentName) {
|
||||
LOGGER.info(String.format("Creating Group for Segment %s", segmentName));
|
||||
|
||||
PathExpression pathExpression = new PathExpression();
|
||||
List<String> paths = List.of(String.format("%s/%s", SEGMENTS_PATH, segmentName));
|
||||
pathExpression.setPaths(paths);
|
||||
|
||||
Groups service = (Groups) nsxService.apply(Groups.class);
|
||||
Group group = new Group.Builder()
|
||||
.setId(segmentName)
|
||||
.setDisplayName(segmentName)
|
||||
.setExpression(List.of(pathExpression))
|
||||
.build();
|
||||
service.patch(DEFAULT_DOMAIN, segmentName, group);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove Segment Group from the Inventory
|
||||
*/
|
||||
private void removeGroupForSegment(String segmentName) {
|
||||
LOGGER.info(String.format("Removing Group for Segment %s", segmentName));
|
||||
Groups service = (Groups) nsxService.apply(Groups.class);
|
||||
service.delete(DEFAULT_DOMAIN, segmentName, true, false);
|
||||
}
|
||||
|
||||
private void removeSegmentDistributedFirewallRules(String segmentName) {
|
||||
try {
|
||||
SecurityPolicies services = (SecurityPolicies) nsxService.apply(SecurityPolicies.class);
|
||||
services.delete(DEFAULT_DOMAIN, segmentName);
|
||||
} catch (Error error) {
|
||||
ApiError ae = error.getData()._convertTo(ApiError.class);
|
||||
String msg = String.format("Failed to remove NSX distributed firewall policy for segment %s, due to: %s", segmentName, ae.getErrorMessage());
|
||||
LOGGER.error(msg);
|
||||
throw new CloudRuntimeException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
public void createSegmentDistributedFirewall(String segmentName, List<NsxNetworkRule> nsxRules) {
|
||||
try {
|
||||
String groupPath = getGroupPath(segmentName);
|
||||
if (Objects.isNull(groupPath)) {
|
||||
throw new CloudRuntimeException(String.format("Failed to find group for segment %s", segmentName));
|
||||
}
|
||||
SecurityPolicies services = (SecurityPolicies) nsxService.apply(SecurityPolicies.class);
|
||||
List<Rule> rules = getRulesForDistributedFirewall(segmentName, nsxRules);
|
||||
SecurityPolicy policy = new SecurityPolicy.Builder()
|
||||
.setDisplayName(segmentName)
|
||||
.setId(segmentName)
|
||||
.setCategory("Application")
|
||||
.setRules(rules)
|
||||
.setScope(List.of(groupPath))
|
||||
.build();
|
||||
services.patch(DEFAULT_DOMAIN, segmentName, policy);
|
||||
} catch (Error error) {
|
||||
ApiError ae = error.getData()._convertTo(ApiError.class);
|
||||
String msg = String.format("Failed to create NSX distributed firewall policy for segment %s, due to: %s", segmentName, ae.getErrorMessage());
|
||||
LOGGER.error(msg);
|
||||
throw new CloudRuntimeException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteDistributedFirewallRules(String segmentName, List<NsxNetworkRule> nsxRules) {
|
||||
for(NsxNetworkRule rule : nsxRules) {
|
||||
String ruleId = NsxControllerUtils.getNsxDistributedFirewallPolicyRuleId(segmentName, rule.getRuleId());
|
||||
String svcName = getServiceName(ruleId, rule.getPrivatePort(), rule.getProtocol(), rule.getIcmpType(), rule.getIcmpCode());
|
||||
// delete rules
|
||||
Rules rules = (Rules) nsxService.apply(Rules.class);
|
||||
rules.delete(DEFAULT_DOMAIN, segmentName, ruleId);
|
||||
// delete service - if any
|
||||
Services services = (Services) nsxService.apply(Services.class);
|
||||
services.delete(svcName);
|
||||
}
|
||||
}
|
||||
|
||||
private List<Rule> getRulesForDistributedFirewall(String segmentName, List<NsxNetworkRule> nsxRules) {
|
||||
List<Rule> rules = new ArrayList<>();
|
||||
String groupPath = getGroupPath(segmentName);
|
||||
if (Objects.isNull(groupPath)) {
|
||||
throw new CloudRuntimeException(String.format("Failed to find group for segment %s", segmentName));
|
||||
}
|
||||
for (NsxNetworkRule rule : nsxRules) {
|
||||
String ruleId = NsxControllerUtils.getNsxDistributedFirewallPolicyRuleId(segmentName, rule.getRuleId());
|
||||
Rule ruleToAdd = new Rule.Builder()
|
||||
.setAction(rule.getAclAction().toString())
|
||||
.setId(ruleId)
|
||||
.setDisplayName(ruleId)
|
||||
.setResourceType("SecurityPolicy")
|
||||
.setSourceGroups(getGroupsForTraffic(rule, segmentName, true))
|
||||
.setDestinationGroups(getGroupsForTraffic(rule, segmentName, false))
|
||||
.setServices(getServicesListForDistributedFirewallRule(rule, segmentName))
|
||||
.setScope(List.of(groupPath))
|
||||
.build();
|
||||
rules.add(ruleToAdd);
|
||||
}
|
||||
return rules;
|
||||
}
|
||||
|
||||
private List<String> getServicesListForDistributedFirewallRule(NsxNetworkRule rule, String segmentName) {
|
||||
List<String> services = List.of("ANY");
|
||||
if (!rule.getProtocol().equalsIgnoreCase("all")) {
|
||||
String ruleName = String.format("%s-R%s", segmentName, rule.getRuleId());
|
||||
String serviceName = getNsxInfraServices(ruleName, rule.getPrivatePort(), rule.getProtocol(),
|
||||
rule.getIcmpType(), rule.getIcmpCode());
|
||||
services = List.of(serviceName);
|
||||
}
|
||||
return services;
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
String trafficType = rule.getTrafficType();
|
||||
if (trafficType.equalsIgnoreCase("ingress")) {
|
||||
return source ? ruleCidrList : segmentGroup;
|
||||
} else if (trafficType.equalsIgnoreCase("egress")) {
|
||||
return source ? segmentGroup : ruleCidrList;
|
||||
}
|
||||
String err = String.format("Unsupported traffic type %s", trafficType);
|
||||
LOGGER.error(err);
|
||||
throw new CloudRuntimeException(err);
|
||||
}
|
||||
|
||||
private List<Group> listNsxGroups() {
|
||||
try {
|
||||
Groups groups = (Groups) nsxService.apply(Groups.class);
|
||||
GroupListResult result = groups.list(DEFAULT_DOMAIN, null, false, null, null, null, null, null);
|
||||
return result.getResults();
|
||||
} catch (Error error) {
|
||||
ApiError ae = error.getData()._convertTo(ApiError.class);
|
||||
String msg = String.format("Failed to list NSX groups, due to: %s", ae.getErrorMessage());
|
||||
LOGGER.error(msg);
|
||||
throw new CloudRuntimeException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
private String getGroupPath(String segmentName) {
|
||||
List<Group> groups = listNsxGroups();
|
||||
Optional<Group> matchingGroup = groups.stream().filter(group -> group.getDisplayName().equals(segmentName)).findFirst();
|
||||
return matchingGroup.map(Group::getPath).orElse(null);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -56,6 +56,7 @@ import com.cloud.network.element.DhcpServiceProvider;
|
||||
import com.cloud.network.element.DnsServiceProvider;
|
||||
import com.cloud.network.element.IpDeployer;
|
||||
import com.cloud.network.element.LoadBalancingServiceProvider;
|
||||
import com.cloud.network.element.NetworkACLServiceProvider;
|
||||
import com.cloud.network.element.PortForwardingServiceProvider;
|
||||
import com.cloud.network.element.StaticNatServiceProvider;
|
||||
import com.cloud.network.element.VpcProvider;
|
||||
@ -107,7 +108,7 @@ import java.util.function.LongFunction;
|
||||
|
||||
@Component
|
||||
public class NsxElement extends AdapterBase implements DhcpServiceProvider, DnsServiceProvider, VpcProvider,
|
||||
StaticNatServiceProvider, IpDeployer, PortForwardingServiceProvider,
|
||||
StaticNatServiceProvider, IpDeployer, PortForwardingServiceProvider, NetworkACLServiceProvider,
|
||||
LoadBalancingServiceProvider, ResourceStateAdapter, Listener {
|
||||
|
||||
|
||||
@ -159,6 +160,15 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, Dns
|
||||
capabilities.put(Network.Service.Lb, null);
|
||||
capabilities.put(Network.Service.PortForwarding, null);
|
||||
capabilities.put(Network.Service.NetworkACL, null);
|
||||
|
||||
Map<Network.Capability, String> firewallCapabilities = new HashMap<>();
|
||||
firewallCapabilities.put(Network.Capability.SupportedProtocols, "tcp,udp,icmp");
|
||||
firewallCapabilities.put(Network.Capability.SupportedEgressProtocols, "tcp,udp,icmp,all");
|
||||
firewallCapabilities.put(Network.Capability.MultipleIps, "true");
|
||||
firewallCapabilities.put(Network.Capability.TrafficStatistics, "per public ip");
|
||||
firewallCapabilities.put(Network.Capability.SupportedTrafficDirection, "ingress, egress");
|
||||
capabilities.put(Network.Service.Firewall, firewallCapabilities);
|
||||
|
||||
Map<Network.Capability, String> sourceNatCapabilities = new HashMap<>();
|
||||
sourceNatCapabilities.put(Network.Capability.RedundantRouter, "true");
|
||||
sourceNatCapabilities.put(Network.Capability.SupportedSourceNatTypes, "peraccount");
|
||||
@ -574,6 +584,12 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, Dns
|
||||
String.valueOf(rule.getSourcePortStart()).concat("-").concat(String.valueOf(rule.getSourcePortEnd()));
|
||||
}
|
||||
|
||||
private static String getPrivatePortRangeForACLRule(NetworkACLItem rule) {
|
||||
return Objects.equals(rule.getSourcePortStart(), rule.getSourcePortEnd()) ?
|
||||
String.valueOf(rule.getSourcePortStart()) :
|
||||
String.valueOf(rule.getSourcePortStart()).concat("-").concat(String.valueOf(rule.getSourcePortEnd()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyLBRules(Network network, List<LoadBalancingRule> rules) throws ResourceUnavailableException {
|
||||
for (LoadBalancingRule loadBalancingRule : rules) {
|
||||
@ -645,4 +661,70 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, Dns
|
||||
}
|
||||
return lbMembers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyNetworkACLs(Network network, List<? extends NetworkACLItem> rules) throws ResourceUnavailableException {
|
||||
if (!canHandle(network, Network.Service.NetworkACL)) {
|
||||
return false;
|
||||
}
|
||||
List<NsxNetworkRule> nsxAddNetworkRules = new ArrayList<>();
|
||||
List<NsxNetworkRule> nsxDelNetworkRules = new ArrayList<>();
|
||||
for (NetworkACLItem rule : rules) {
|
||||
String privatePort = getPrivatePortRangeForACLRule(rule);
|
||||
|
||||
NsxNetworkRule networkRule = new NsxNetworkRule.Builder()
|
||||
.setRuleId(rule.getId())
|
||||
.setCidrList(transformCidrListValues(rule.getSourceCidrList()))
|
||||
.setAclAction(transformActionValue(rule.getAction()))
|
||||
.setTrafficType(rule.getTrafficType().toString())
|
||||
.setProtocol(rule.getProtocol().toUpperCase())
|
||||
.setPublicPort(String.valueOf(rule.getSourcePortStart()))
|
||||
.setPrivatePort(privatePort)
|
||||
.setIcmpCode(rule.getIcmpCode())
|
||||
.setIcmpType(rule.getIcmpType())
|
||||
.setService(Network.Service.NetworkACL)
|
||||
.build();
|
||||
if (NetworkACLItem.State.Add == rule.getState()) {
|
||||
nsxAddNetworkRules.add(networkRule);
|
||||
} else if (NetworkACLItem.State.Revoke == rule.getState()) {
|
||||
nsxDelNetworkRules.add(networkRule);
|
||||
}
|
||||
}
|
||||
boolean success = true;
|
||||
if (!nsxDelNetworkRules.isEmpty()) {
|
||||
success = nsxService.deleteFirewallRules(network, nsxDelNetworkRules);
|
||||
if (!success) {
|
||||
LOGGER.warn("Not all firewall rules were successfully deleted");
|
||||
}
|
||||
}
|
||||
return success && nsxService.addFirewallRules(network, nsxAddNetworkRules);
|
||||
}
|
||||
|
||||
protected NsxNetworkRule.NsxRuleAction transformActionValue(NetworkACLItem.Action action) {
|
||||
if (action == NetworkACLItem.Action.Allow) {
|
||||
return NsxNetworkRule.NsxRuleAction.ALLOW;
|
||||
} else if (action == NetworkACLItem.Action.Deny) {
|
||||
return NsxNetworkRule.NsxRuleAction.DROP;
|
||||
}
|
||||
String err = String.format("Unsupported action %s", action.toString());
|
||||
LOGGER.error(err);
|
||||
throw new CloudRuntimeException(err);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace 0.0.0.0/0 to ANY on each occurrence
|
||||
*/
|
||||
protected List<String> transformCidrListValues(List<String> sourceCidrList) {
|
||||
List<String> list = new ArrayList<>();
|
||||
if (org.apache.commons.collections.CollectionUtils.isNotEmpty(sourceCidrList)) {
|
||||
for (String cidr : sourceCidrList) {
|
||||
if (cidr.equals("0.0.0.0/0")) {
|
||||
list.add("ANY");
|
||||
} else {
|
||||
list.add(cidr);
|
||||
}
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,6 +26,7 @@ import com.cloud.network.vpc.VpcVO;
|
||||
import com.cloud.network.vpc.dao.VpcDao;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import org.apache.cloudstack.NsxAnswer;
|
||||
import org.apache.cloudstack.agent.api.CreateNsxDistributedFirewallRulesCommand;
|
||||
import org.apache.cloudstack.agent.api.CreateNsxLoadBalancerRuleCommand;
|
||||
import org.apache.cloudstack.agent.api.CreateNsxPortForwardRuleCommand;
|
||||
import org.apache.cloudstack.agent.api.CreateNsxStaticNatCommand;
|
||||
@ -35,12 +36,14 @@ import org.apache.cloudstack.agent.api.DeleteNsxLoadBalancerRuleCommand;
|
||||
import org.apache.cloudstack.agent.api.DeleteNsxSegmentCommand;
|
||||
import org.apache.cloudstack.agent.api.DeleteNsxNatRuleCommand;
|
||||
import org.apache.cloudstack.agent.api.DeleteNsxTier1GatewayCommand;
|
||||
import org.apache.cloudstack.agent.api.DeletedNsxDistributedFirewallRulesCommand;
|
||||
import org.apache.cloudstack.resource.NsxNetworkRule;
|
||||
import org.apache.cloudstack.utils.NsxControllerUtils;
|
||||
import org.apache.cloudstack.utils.NsxHelper;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class NsxServiceImpl implements NsxService {
|
||||
@ -172,4 +175,18 @@ public class NsxServiceImpl implements NsxService {
|
||||
NsxAnswer result = nsxControllerUtils.sendNsxCommand(command, netRule.getZoneId());
|
||||
return result.getResult();
|
||||
}
|
||||
|
||||
public boolean addFirewallRules(Network network, List<NsxNetworkRule> netRules) {
|
||||
CreateNsxDistributedFirewallRulesCommand command = new CreateNsxDistributedFirewallRulesCommand(network.getDomainId(),
|
||||
network.getAccountId(), network.getDataCenterId(), network.getVpcId(), network.getId(), netRules);
|
||||
NsxAnswer result = nsxControllerUtils.sendNsxCommand(command, network.getDataCenterId());
|
||||
return result.getResult();
|
||||
}
|
||||
|
||||
public boolean deleteFirewallRules(Network network, List<NsxNetworkRule> netRules) {
|
||||
DeletedNsxDistributedFirewallRulesCommand command = new DeletedNsxDistributedFirewallRulesCommand(network.getDomainId(),
|
||||
network.getAccountId(), network.getDataCenterId(), network.getVpcId(), network.getId(), netRules);
|
||||
NsxAnswer result = nsxControllerUtils.sendNsxCommand(command, network.getDataCenterId());
|
||||
return result.getResult();
|
||||
}
|
||||
}
|
||||
|
||||
@ -45,6 +45,10 @@ public class NsxControllerUtils {
|
||||
return String.format("D%s-A%s-Z%s-%s%s-NAT", domainId, accountId, dataCenterId, resourcePrefix, resourceId);
|
||||
}
|
||||
|
||||
public static String getNsxDistributedFirewallPolicyRuleId(String segmentName, long ruleId) {
|
||||
return String.format("%s-R%s", segmentName, ruleId);
|
||||
}
|
||||
|
||||
public NsxAnswer sendNsxCommand(NsxCommand cmd, long zoneId) throws IllegalArgumentException {
|
||||
|
||||
NsxProviderVO nsxProviderVO = nsxProviderDao.findByZoneId(zoneId);
|
||||
@ -97,8 +101,10 @@ public class NsxControllerUtils {
|
||||
return getTier1GatewayName(domainId, accountId, zoneId, networkResourceId, isVpcResource) + suffix + ruleId;
|
||||
}
|
||||
|
||||
public static String getServiceName(String ruleName, String port, String protocol) {
|
||||
return ruleName + "-SVC-" + port + "-" +protocol;
|
||||
public static String getServiceName(String ruleName, String port, String protocol, Integer icmpType, Integer icmpCode) {
|
||||
return protocol.equalsIgnoreCase("icmp") ?
|
||||
String.format("%s-SVC-%s-%s-%s", ruleName, icmpType, icmpCode, protocol) :
|
||||
String.format("%s-SVC-%s-%s", ruleName, port, protocol);
|
||||
}
|
||||
|
||||
public static String getServiceEntryName(String ruleName, String port, String protocol) {
|
||||
|
||||
@ -0,0 +1,93 @@
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.service;
|
||||
|
||||
import com.vmware.nsx_policy.infra.domains.Groups;
|
||||
import com.vmware.nsx_policy.model.Group;
|
||||
import com.vmware.nsx_policy.model.PathExpression;
|
||||
import com.vmware.vapi.bindings.Service;
|
||||
import org.apache.cloudstack.resource.NsxNetworkRule;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockedConstruction;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class NsxApiClientTest {
|
||||
|
||||
@Mock
|
||||
private Function<Class<? extends Service>, Service> nsxService;
|
||||
@Mock
|
||||
private Groups groupService;
|
||||
|
||||
private NsxApiClient client = new NsxApiClient();
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
client.nsxService = nsxService;
|
||||
Mockito.when(nsxService.apply(Groups.class)).thenReturn(groupService);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateGroupForSegment() {
|
||||
final Group[] groups = new Group[1];
|
||||
final PathExpression[] pathExpressions = new PathExpression[1];
|
||||
try (MockedConstruction<Group> ignored = Mockito.mockConstruction(Group.class, (mock, context) -> {
|
||||
groups[0] = mock;
|
||||
}); MockedConstruction<PathExpression> ignoredExp = Mockito.mockConstruction(PathExpression.class, (mock, context) -> {
|
||||
pathExpressions[0] = mock;
|
||||
})
|
||||
) {
|
||||
String segmentName = "segment1";
|
||||
client.createGroupForSegment(segmentName);
|
||||
Mockito.verify(groupService).patch(Mockito.eq(NsxApiClient.DEFAULT_DOMAIN), Mockito.eq(segmentName), Mockito.eq(groups[0]));
|
||||
String segmentPath = String.format("%s/%s", NsxApiClient.SEGMENTS_PATH, segmentName);
|
||||
Mockito.verify(groups[0]).setExpression(Mockito.eq(List.of(pathExpressions[0])));
|
||||
Mockito.verify(pathExpressions[0]).setPaths(List.of(segmentPath));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetGroupsForTrafficIngress() {
|
||||
NsxNetworkRule rule = Mockito.mock(NsxNetworkRule.class);
|
||||
Mockito.when(rule.getCidrList()).thenReturn(List.of("ANY"));
|
||||
Mockito.when(rule.getTrafficType()).thenReturn("Ingress");
|
||||
String segmentName = "segment";
|
||||
List<String> sourceGroups = client.getGroupsForTraffic(rule, segmentName, true);
|
||||
List<String> destinationGroups = client.getGroupsForTraffic(rule, segmentName, false);
|
||||
Assert.assertEquals(List.of("ANY"), sourceGroups);
|
||||
Assert.assertEquals(List.of(String.format("%s/%s", NsxApiClient.GROUPS_PATH_PREFIX, segmentName)), destinationGroups);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetGroupsForTrafficEgress() {
|
||||
NsxNetworkRule rule = Mockito.mock(NsxNetworkRule.class);
|
||||
Mockito.when(rule.getCidrList()).thenReturn(List.of("ANY"));
|
||||
Mockito.when(rule.getTrafficType()).thenReturn("Egress");
|
||||
String segmentName = "segment";
|
||||
List<String> sourceGroups = client.getGroupsForTraffic(rule, segmentName, true);
|
||||
List<String> destinationGroups = client.getGroupsForTraffic(rule, segmentName, false);
|
||||
Assert.assertEquals(List.of(String.format("%s/%s", NsxApiClient.GROUPS_PATH_PREFIX, segmentName)), sourceGroups);
|
||||
Assert.assertEquals(List.of("ANY"), destinationGroups);
|
||||
}
|
||||
}
|
||||
@ -28,12 +28,15 @@ import com.cloud.network.Networks;
|
||||
import com.cloud.network.dao.NetworkDao;
|
||||
import com.cloud.network.dao.PhysicalNetworkDao;
|
||||
import com.cloud.network.dao.PhysicalNetworkVO;
|
||||
import com.cloud.network.vpc.NetworkACLItem;
|
||||
import com.cloud.network.vpc.Vpc;
|
||||
import com.cloud.network.vpc.dao.VpcOfferingServiceMapDao;
|
||||
import com.cloud.resource.ResourceManager;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountManager;
|
||||
import com.cloud.vm.ReservationContext;
|
||||
import org.apache.cloudstack.resource.NsxNetworkRule;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@ -129,6 +132,24 @@ public class NsxElementTest {
|
||||
assertTrue(nsxElement.shutdownVpc(vpc, reservationContext));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransformActionValue() {
|
||||
NsxNetworkRule.NsxRuleAction action = nsxElement.transformActionValue(NetworkACLItem.Action.Deny);
|
||||
Assert.assertEquals(NsxNetworkRule.NsxRuleAction.DROP, action);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransformCidrListValuesEmptyList() {
|
||||
List<String> values = nsxElement.transformCidrListValues(null);
|
||||
Assert.assertNotNull(values);
|
||||
Assert.assertTrue(values.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransformCidrListValuesList() {
|
||||
List<String> values = nsxElement.transformCidrListValues(List.of("0.0.0.0/0"));
|
||||
Assert.assertEquals(1, values.size());
|
||||
Assert.assertEquals("ANY", values.get(0));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1251,6 +1251,11 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio
|
||||
serviceProviderMap.put(Service.StaticNat, Provider.Nsx);
|
||||
serviceProviderMap.put(Service.PortForwarding, Provider.Nsx);
|
||||
serviceProviderMap.put(Service.Lb, Provider.Nsx);
|
||||
if (forVpc) {
|
||||
serviceProviderMap.put(Service.NetworkACL, Provider.Nsx);
|
||||
} else {
|
||||
serviceProviderMap.put(Service.Firewall, Provider.Nsx);
|
||||
}
|
||||
}
|
||||
return serviceProviderMap;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user