From 7332e6dbda050e792e19d1268251bd4aff335c01 Mon Sep 17 00:00:00 2001 From: Nicolas Vazquez Date: Tue, 10 Oct 2023 12:05:19 -0300 Subject: [PATCH 1/5] [NSX] Fix DHCP relay config deletion was missing zone name (#8068) --- .../cloudstack/agent/api/DeleteNsxSegmentCommand.java | 4 ++-- .../java/org/apache/cloudstack/resource/NsxResource.java | 5 ++++- .../java/org/apache/cloudstack/service/NsxElement.java | 9 ++++++++- .../org/apache/cloudstack/service/NsxServiceImpl.java | 4 ++-- 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/DeleteNsxSegmentCommand.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/DeleteNsxSegmentCommand.java index a1b30582118..06f8e219f6e 100644 --- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/DeleteNsxSegmentCommand.java +++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/DeleteNsxSegmentCommand.java @@ -19,7 +19,7 @@ package org.apache.cloudstack.agent.api; import com.cloud.network.dao.NetworkVO; public class DeleteNsxSegmentCommand extends CreateNsxSegmentCommand { - public DeleteNsxSegmentCommand(String accountName, String vpcName, NetworkVO network) { - super(null, network.getDataCenterId(), accountName, network.getAccountId(), vpcName, network); + public DeleteNsxSegmentCommand(String zoneName, String accountName, String vpcName, NetworkVO network) { + super(zoneName, network.getDataCenterId(), accountName, network.getAccountId(), vpcName, network); } } 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 9724c7bc926..fce5a4fd4dd 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 @@ -417,9 +417,12 @@ public class NsxResource implements ServerResource { Thread.sleep(30*1000); String segmentName = getSegmentName(cmd.getAccountName(), cmd.getTierNetwork().getName(), cmd.getVpcName()); Segments segmentService = (Segments) nsxService.apply(Segments.class); + LOGGER.debug(String.format("Removing the segment with ID %s", segmentName)); segmentService.delete(segmentName); DhcpRelayConfigs dhcpRelayConfig = (DhcpRelayConfigs) nsxService.apply(DhcpRelayConfigs.class); - dhcpRelayConfig.delete(getDhcpRelayId(cmd.getZoneName(), cmd.getAccountName(), cmd.getVpcName(), cmd.getTierNetwork().getName())); + String dhcpRelayId = getDhcpRelayId(cmd.getZoneName(), cmd.getAccountName(), cmd.getVpcName(), cmd.getTierNetwork().getName()); + LOGGER.debug(String.format("Removing the DHCP relay config with ID %s", dhcpRelayId)); + dhcpRelayConfig.delete(dhcpRelayId); } catch (Exception e) { LOGGER.error(String.format("Failed to delete NSX segment: %s", getSegmentName(cmd.getAccountName(), cmd.getTierNetwork().getName(), cmd.getVpcName()))); return new NsxAnswer(cmd, new CloudRuntimeException(e.getMessage())); 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 1f97cbdfa41..19d068d3349 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 @@ -59,6 +59,7 @@ import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.utils.Pair; import com.cloud.utils.component.AdapterBase; +import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.NicProfile; import com.cloud.vm.ReservationContext; import com.cloud.vm.VirtualMachineProfile; @@ -195,7 +196,13 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, DnsS public boolean destroy(Network network, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException { Account account = accountMgr.getAccount(network.getAccountId()); NetworkVO networkVO = networkDao.findById(network.getId()); - return nsxService.deleteNetwork(account.getAccountName(), networkVO); + DataCenterVO zone = dataCenterDao.findById(network.getDataCenterId()); + if (Objects.isNull(zone)) { + String msg = String.format("Cannot fing zone with ID %s", network.getDataCenterId()); + LOGGER.error(msg); + throw new CloudRuntimeException(msg); + } + return nsxService.deleteNetwork(zone.getName(), account.getAccountName(), networkVO); } @Override diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxServiceImpl.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxServiceImpl.java index 2158d995208..7d6853ea9ec 100644 --- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxServiceImpl.java +++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxServiceImpl.java @@ -47,13 +47,13 @@ public class NsxServiceImpl implements NsxService { return result.getResult(); } - public boolean deleteNetwork(String accountName, NetworkVO network) { + public boolean deleteNetwork(String zoneName, String accountName, NetworkVO network) { String vpcName = null; if (Objects.nonNull(network.getVpcId())) { VpcVO vpc = vpcDao.findById(network.getVpcId()); vpcName = Objects.nonNull(vpc) ? vpc.getName() : null; } - DeleteNsxSegmentCommand deleteNsxSegmentCommand = new DeleteNsxSegmentCommand(accountName, vpcName, network); + DeleteNsxSegmentCommand deleteNsxSegmentCommand = new DeleteNsxSegmentCommand(zoneName, accountName, vpcName, network); NsxAnswer result = nsxControllerUtils.sendNsxCommand(deleteNsxSegmentCommand, network.getDataCenterId()); return result.getResult(); } From 3f8f9e294b56172515d842b3c0d981391563e31e Mon Sep 17 00:00:00 2001 From: Nicolas Vazquez Date: Thu, 12 Oct 2023 19:39:01 -0300 Subject: [PATCH 2/5] [NSX] Refactor API wrapper operations (#8059) * [NSX] Refactor API wrapper operations * Big refactor * Address review comment * change network cidr to cidr to prevent NPE * add domain and zone names to the various networks - vpc & tier --------- Co-authored-by: Pearl Dsilva --- .../cloud/vm/VirtualMachineManagerImpl.java | 8 +- .../api/CreateNsxDhcpRelayConfigCommand.java | 4 +- .../agent/api/CreateNsxSegmentCommand.java | 41 ++- .../api/CreateNsxTier1GatewayCommand.java | 8 +- .../agent/api/DeleteNsxSegmentCommand.java | 20 +- .../api/DeleteNsxTier1GatewayCommand.java | 13 +- .../cloudstack/agent/api/NsxCommand.java | 35 +-- .../cloudstack/resource/NsxResource.java | 264 +++------------- .../org/apache/cloudstack/service/NsxApi.java | 32 -- .../cloudstack/service/NsxApiClient.java | 293 ++++++++++++++++++ .../apache/cloudstack/service/NsxElement.java | 24 +- .../service/NsxGuestNetworkGuru.java | 28 +- .../cloudstack/service/NsxServiceImpl.java | 13 +- .../cloudstack/utils/NsxApiClientUtils.java | 103 ------ .../NsxControllerUtils.java | 24 +- .../apache/cloudstack/utils/NsxHelper.java | 41 +++ .../cloudstack/nsx/spring-nsx-context.xml | 2 +- .../cloud/hypervisor/HypervisorGuruBase.java | 19 +- 18 files changed, 542 insertions(+), 430 deletions(-) delete mode 100644 plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxApi.java create mode 100644 plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxApiClient.java delete mode 100644 plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/utils/NsxApiClientUtils.java rename plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/{service => utils}/NsxControllerUtils.java (65%) create mode 100644 plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/utils/NsxHelper.java diff --git a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java index 36ec427735d..f49a7b2d113 100755 --- a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java @@ -48,6 +48,8 @@ import javax.inject.Inject; import javax.naming.ConfigurationException; import javax.persistence.EntityExistsException; +import com.cloud.domain.Domain; +import com.cloud.domain.dao.DomainDao; import com.cloud.network.vpc.VpcVO; import com.cloud.network.vpc.dao.VpcDao; import com.cloud.user.dao.AccountDao; @@ -392,6 +394,8 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac private AccountDao accountDao; @Inject private VpcDao vpcDao; + @Inject + private DomainDao domainDao; VmWorkJobHandlerProxy _jobHandlerProxy = new VmWorkJobHandlerProxy(this); @@ -1478,7 +1482,9 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac for (UserVmJoinVO userVmJoinVO : userVmJoinVOs) { NetworkVO networkVO = _networkDao.findById(userVmJoinVO.getNetworkId()); Account acc = accountDao.findById(networkVO.getAccountId()); - String networkName = acc.getAccountName() + "-" ; + Domain domain = domainDao.findById(networkVO.getDomainId()); + DataCenter zone = _dcDao.findById(vm.getDataCenterId()); + String networkName = domain.getName() + "-" + acc.getAccountName() + "-" + zone.getName() + "-"; if (Objects.isNull(networkVO.getVpcId())) { networkName += networkVO.getName(); } else { diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/CreateNsxDhcpRelayConfigCommand.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/CreateNsxDhcpRelayConfigCommand.java index f8b9d1d6710..44c21885d2f 100644 --- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/CreateNsxDhcpRelayConfigCommand.java +++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/CreateNsxDhcpRelayConfigCommand.java @@ -24,9 +24,9 @@ public class CreateNsxDhcpRelayConfigCommand extends NsxCommand { private String networkName; private List addresses; - public CreateNsxDhcpRelayConfigCommand(String zoneName, Long zoneId, String accountName, Long accountId, + public CreateNsxDhcpRelayConfigCommand(String domainName, String accountName, String zoneName, String vpcName, String networkName, List addresses) { - super(zoneName, zoneId, accountName, accountId); + super(domainName, accountName, zoneName); this.vpcName = vpcName; this.networkName = networkName; this.addresses = addresses; diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/CreateNsxSegmentCommand.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/CreateNsxSegmentCommand.java index 0f39272a889..b9c8fba4ff8 100644 --- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/CreateNsxSegmentCommand.java +++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/CreateNsxSegmentCommand.java @@ -16,23 +16,38 @@ // under the License. package org.apache.cloudstack.agent.api; -import com.cloud.network.dao.NetworkVO; - import java.util.Objects; -public class CreateNsxSegmentCommand extends CreateNsxTier1GatewayCommand { - private NetworkVO tierNetwork; - public CreateNsxSegmentCommand(String zoneName, Long zoneId, String accountName, Long accountId, String vpcName, NetworkVO tierNetwork) { - super(zoneName, zoneId, accountName, accountId, vpcName); - this.tierNetwork = tierNetwork; +public class CreateNsxSegmentCommand extends NsxCommand { + + private String vpcName; + private String networkName; + private String networkGateway; + private String networkCidr; + + public CreateNsxSegmentCommand(String domainName, String accountName, String zoneName, + String vpcName, String networkName, String networkGateway, String networkCidr) { + super(domainName, accountName, zoneName); + this.vpcName = vpcName; + this.networkName = networkName; + this.networkGateway = networkGateway; + this.networkCidr = networkCidr; } - public NetworkVO getTierNetwork() { - return tierNetwork; + public String getVpcName() { + return vpcName; } - public void setTierNetwork(NetworkVO tierNetwork) { - this.tierNetwork = tierNetwork; + public String getNetworkName() { + return networkName; + } + + public String getNetworkGateway() { + return networkGateway; + } + + public String getNetworkCidr() { + return networkCidr; } @Override @@ -41,11 +56,11 @@ public class CreateNsxSegmentCommand extends CreateNsxTier1GatewayCommand { if (o == null || getClass() != o.getClass()) return false; if (!super.equals(o)) return false; CreateNsxSegmentCommand command = (CreateNsxSegmentCommand) o; - return Objects.equals(tierNetwork, command.tierNetwork); + return Objects.equals(networkName, command.networkName); } @Override public int hashCode() { - return Objects.hash(super.hashCode(), tierNetwork); + return Objects.hash(super.hashCode(), networkName); } } diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/CreateNsxTier1GatewayCommand.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/CreateNsxTier1GatewayCommand.java index 03e57362f17..385bfd17c21 100644 --- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/CreateNsxTier1GatewayCommand.java +++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/CreateNsxTier1GatewayCommand.java @@ -21,8 +21,8 @@ import java.util.Objects; public class CreateNsxTier1GatewayCommand extends NsxCommand { private String vpcName; - public CreateNsxTier1GatewayCommand(String zoneName, Long zoneId, String accountName, Long accountId, String vpcName) { - super(zoneName, zoneId, accountName, accountId); + public CreateNsxTier1GatewayCommand(String domainName, String accountName, String zoneName, String vpcName) { + super(domainName, accountName, zoneName); this.vpcName = vpcName; } @@ -30,10 +30,6 @@ public class CreateNsxTier1GatewayCommand extends NsxCommand { return vpcName; } - public void setVpcName(String vpcName) { - this.vpcName = vpcName; - } - @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/DeleteNsxSegmentCommand.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/DeleteNsxSegmentCommand.java index 06f8e219f6e..fa5fe8b2c05 100644 --- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/DeleteNsxSegmentCommand.java +++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/DeleteNsxSegmentCommand.java @@ -16,10 +16,22 @@ // under the License. package org.apache.cloudstack.agent.api; -import com.cloud.network.dao.NetworkVO; +public class DeleteNsxSegmentCommand extends NsxCommand { -public class DeleteNsxSegmentCommand extends CreateNsxSegmentCommand { - public DeleteNsxSegmentCommand(String zoneName, String accountName, String vpcName, NetworkVO network) { - super(zoneName, network.getDataCenterId(), accountName, network.getAccountId(), vpcName, network); + private String vpcName; + private String networkName; + + public DeleteNsxSegmentCommand(String domainName, String accountName, String zoneName, String vpcName, String networkName) { + super(domainName, accountName, zoneName); + this.vpcName = vpcName; + this.networkName = networkName; + } + + public String getVpcName() { + return vpcName; + } + + public String getNetworkName() { + return networkName; } } diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/DeleteNsxTier1GatewayCommand.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/DeleteNsxTier1GatewayCommand.java index 12a64b8ee04..d3890542313 100644 --- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/DeleteNsxTier1GatewayCommand.java +++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/DeleteNsxTier1GatewayCommand.java @@ -16,9 +16,16 @@ // under the License. package org.apache.cloudstack.agent.api; -public class DeleteNsxTier1GatewayCommand extends CreateNsxTier1GatewayCommand { +public class DeleteNsxTier1GatewayCommand extends NsxCommand { - public DeleteNsxTier1GatewayCommand(String zoneName, Long zoneId, String accountName, Long accountId, String vpcName) { - super(zoneName, zoneId, accountName, accountId, vpcName); + private String vpcName; + + public DeleteNsxTier1GatewayCommand(String domainName, String accountName, String zoneName, String vpcName) { + super(domainName, accountName, zoneName); + this.vpcName = vpcName; + } + + public String getVpcName() { + return vpcName; } } diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/NsxCommand.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/NsxCommand.java index 6ad4edfc680..539f8c06729 100644 --- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/NsxCommand.java +++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/NsxCommand.java @@ -22,48 +22,27 @@ import java.util.Objects; public class NsxCommand extends Command { private String zoneName; - private Long zoneId; private String accountName; - private Long accountId; + private String domainName; - public NsxCommand(String zoneName, Long zoneId, String accountName, Long accountId) { + public NsxCommand(String domainName, String accountName, String zoneName) { this.zoneName = zoneName; - this.zoneId = zoneId; this.accountName = accountName; - this.accountId = accountId; + this.domainName = domainName; } public String getZoneName() { return zoneName; } - public void setZoneName(String zoneName) { - this.zoneName = zoneName; - } - - public Long getZoneId() { - return zoneId; - } - - public void setZoneId(Long zoneId) { - this.zoneId = zoneId; - } - public String getAccountName() { return accountName; } - public void setAccountName(String accountName) { - this.accountName = accountName; + public String getDomainName() { + return domainName; } - public Long getAccountId() { - return accountId; - } - - public void setAccountId(Long accountId) { - this.accountId = accountId; - } @Override public boolean executeInSequence() { return false; @@ -75,11 +54,11 @@ public class NsxCommand extends Command { if (o == null || getClass() != o.getClass()) return false; if (!super.equals(o)) return false; NsxCommand that = (NsxCommand) o; - return Objects.equals(zoneName, that.zoneName) && Objects.equals(zoneId, that.zoneId) && Objects.equals(accountName, that.accountName) && Objects.equals(accountId, that.accountId); + return Objects.equals(zoneName, that.zoneName) && Objects.equals(accountName, that.accountName) && Objects.equals(domainName, that.domainName); } @Override public int hashCode() { - return Objects.hash(super.hashCode(), zoneName, zoneId, accountName, accountId); + return Objects.hash(super.hashCode(), zoneName, accountName, domainName); } } 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 fce5a4fd4dd..cece0aa0d08 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 @@ -16,7 +16,6 @@ // under the License. package org.apache.cloudstack.resource; -import com.amazonaws.util.CollectionUtils; import com.cloud.agent.IAgentControl; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; @@ -24,29 +23,15 @@ import com.cloud.agent.api.PingCommand; import com.cloud.agent.api.ReadyAnswer; import com.cloud.agent.api.ReadyCommand; import com.cloud.agent.api.StartupCommand; -import com.cloud.exception.InvalidParameterValueException; import com.cloud.host.Host; import com.cloud.resource.ServerResource; import com.cloud.utils.exception.CloudRuntimeException; import com.vmware.nsx.model.TransportZone; import com.vmware.nsx.model.TransportZoneListResult; -import com.vmware.nsx_policy.infra.DhcpRelayConfigs; -import com.vmware.nsx_policy.infra.Segments; -import com.vmware.nsx_policy.infra.Sites; -import com.vmware.nsx_policy.infra.Tier1s; -import com.vmware.nsx_policy.infra.sites.EnforcementPoints; -import com.vmware.nsx_policy.infra.tier_0s.LocaleServices; -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.LocaleServicesListResult; import com.vmware.nsx_policy.model.Segment; -import com.vmware.nsx_policy.model.SegmentSubnet; import com.vmware.nsx_policy.model.SiteListResult; -import com.vmware.nsx_policy.model.Tier1; -import com.vmware.vapi.bindings.Service; -import com.vmware.vapi.std.errors.Error; import org.apache.cloudstack.NsxAnswer; import org.apache.cloudstack.StartupNsxCommand; import org.apache.cloudstack.agent.api.CreateNsxDhcpRelayConfigCommand; @@ -54,36 +39,21 @@ import org.apache.cloudstack.agent.api.CreateNsxSegmentCommand; import org.apache.cloudstack.agent.api.CreateNsxTier1GatewayCommand; import org.apache.cloudstack.agent.api.DeleteNsxSegmentCommand; import org.apache.cloudstack.agent.api.DeleteNsxTier1GatewayCommand; -import org.apache.cloudstack.service.NsxApi; -import org.apache.cloudstack.utils.NsxApiClientUtils; +import org.apache.cloudstack.service.NsxApiClient; +import org.apache.cloudstack.utils.NsxControllerUtils; +import org.apache.commons.collections.CollectionUtils; import org.apache.log4j.Logger; import javax.naming.ConfigurationException; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.function.Function; import java.util.stream.Collectors; -import static java.util.Objects.isNull; -import static org.apache.cloudstack.utils.NsxApiClientUtils.RouteAdvertisementType.TIER1_CONNECTED; -import static org.apache.cloudstack.utils.NsxApiClientUtils.RouteAdvertisementType.TIER1_IPSEC_LOCAL_ENDPOINT; -import static org.apache.cloudstack.utils.NsxApiClientUtils.HAMode.ACTIVE_STANDBY; -import static org.apache.cloudstack.utils.NsxApiClientUtils.FailoverMode.PREEMPTIVE; -import static org.apache.cloudstack.utils.NsxApiClientUtils.PoolAllocation.ROUTING; -import static org.apache.cloudstack.utils.NsxApiClientUtils.TransportType.OVERLAY; -import static org.apache.cloudstack.utils.NsxApiClientUtils.createApiClient; - public class NsxResource implements ServerResource { private static final Logger LOGGER = Logger.getLogger(NsxResource.class); - private static final String TIER_0_GATEWAY_PATH_PREFIX = "/infra/tier-0s/"; - private static final String TIER_1_GATEWAY_PATH_PREFIX = "/infra/tier-1s/"; private static final String DHCP_RELAY_CONFIGS_PATH_PREFIX = "/infra/dhcp-relay-configs"; - private static final String Tier_1_LOCALE_SERVICE_ID = "default"; - private static final String TIER_1_RESOURCE_TYPE = "Tier1"; - private static final String SEGMENT_RESOURCE_TYPE = "Segment"; - private String name; protected String hostname; protected String username; @@ -95,7 +65,7 @@ public class NsxResource implements ServerResource { protected String transportZone; protected String zoneId; - protected NsxApi nsxApi; + protected NsxApiClient nsxApiClient; @Override public Host.Type getType() { @@ -236,56 +206,42 @@ public class NsxResource implements ServerResource { throw new ConfigurationException("Missing NSX transportZone"); } - nsxApi = new NsxApi(); - nsxApi.setApiClient(createApiClient(hostname, port, username, password.toCharArray())); + nsxApiClient = new NsxApiClient(hostname, port, username, password.toCharArray()); return true; } - private String getDhcpRelayConfig(String zoneName, String accountName, String vpcName, String networkName) { - return String.format("%s-%s-%s-%s-Relay", zoneName, accountName, vpcName, networkName); - } - private Answer executeRequest(CreateNsxDhcpRelayConfigCommand cmd) { String zoneName = cmd.getZoneName(); + String domainName = cmd.getDomainName(); String accountName = cmd.getAccountName(); String vpcName = cmd.getVpcName(); String networkName = cmd.getNetworkName(); List addresses = cmd.getAddresses(); - String dhcpRelayConfigName = getDhcpRelayConfig(zoneName, accountName, vpcName, networkName); + String dhcpRelayConfigName = NsxControllerUtils.getNsxDhcpRelayConfigId(zoneName, domainName, accountName, vpcName, networkName); String msg = String.format("Creating DHCP relay config with name %s on network %s of VPC %s", dhcpRelayConfigName, networkName, vpcName); LOGGER.debug(msg); try { - DhcpRelayConfigs service = (DhcpRelayConfigs) nsxService.apply(DhcpRelayConfigs.class); - DhcpRelayConfig config = new DhcpRelayConfig.Builder() - .setServerAddresses(addresses) - .setId(dhcpRelayConfigName) - .setDisplayName(dhcpRelayConfigName) - .build(); - service.patch(dhcpRelayConfigName, config); - } catch (Error error) { - ApiError ae = error.getData()._convertTo(ApiError.class); - msg = String.format("Error creating the DHCP relay config with name %s: %s", dhcpRelayConfigName, ae.getErrorMessage()); - LOGGER.error(msg); - return new NsxAnswer(cmd, new CloudRuntimeException(ae.getErrorMessage())); + nsxApiClient.createDhcpRelayConfig(dhcpRelayConfigName, addresses); + } catch (CloudRuntimeException e) { + msg = String.format("Error creating the DHCP relay config with name %s: %s", dhcpRelayConfigName, e.getMessage()); + LOGGER.error(msg, e); + return new NsxAnswer(cmd, e); } - String segmentName = String.format("%s-%s-%s", accountName, vpcName, networkName); + String segmentName = NsxControllerUtils.getNsxSegmentId(domainName, accountName, zoneName, vpcName, networkName); String dhcpConfigPath = String.format("%s/%s", DHCP_RELAY_CONFIGS_PATH_PREFIX, dhcpRelayConfigName); try { - LOGGER.debug(String.format("Adding the creating DHCP relay config %s to the segment %s", dhcpConfigPath, segmentName)); - Segments segmentService = (Segments) nsxService.apply(Segments.class); - Segment segment = segmentService.get(segmentName); + Segment segment = nsxApiClient.getSegmentById(segmentName); segment.setDhcpConfigPath(dhcpConfigPath); - segmentService.patch(segmentName, segment); - } catch (Error error) { - ApiError ae = error.getData()._convertTo(ApiError.class); - msg = String.format("Error adding the DHCP relay config with name %s to the segment %s: %s", dhcpRelayConfigName, segmentName, ae.getErrorMessage()); + nsxApiClient.updateSegment(segmentName, segment); + } catch (CloudRuntimeException e) { + msg = String.format("Error adding the DHCP relay config with name %s to the segment %s: %s", dhcpRelayConfigName, segmentName, e.getMessage()); LOGGER.error(msg); - return new NsxAnswer(cmd, new CloudRuntimeException(ae.getErrorMessage())); + return new NsxAnswer(cmd, e); } return new NsxAnswer(cmd, true, ""); @@ -295,63 +251,21 @@ public class NsxResource implements ServerResource { return new ReadyAnswer(cmd); } - private Function, Service> nsxService = svcClass -> nsxApi.getApiClient().createStub(svcClass); private Answer executeRequest(CreateNsxTier1GatewayCommand cmd) { - String name = getTier1GatewayName(cmd); - Tier1 tier1 = getTier1Gateway(name); - if (tier1 != null) { - throw new InvalidParameterValueException(String.format("VPC network with name %s exists in NSX zone: %s and account %s", name, cmd.getZoneName(), cmd.getAccountName())); - } - - - String tier0GatewayPath = TIER_0_GATEWAY_PATH_PREFIX + tier0Gateway; - - Tier1s tier1service = (Tier1s) nsxService.apply(Tier1s.class); - tier1 = new Tier1.Builder() - .setTier0Path(tier0GatewayPath) - .setResourceType(TIER_1_RESOURCE_TYPE) - .setPoolAllocation(ROUTING.name()) - .setHaMode(ACTIVE_STANDBY.name()) - .setFailoverMode(PREEMPTIVE.name()) - .setRouteAdvertisementTypes(List.of(TIER1_CONNECTED.name(), TIER1_IPSEC_LOCAL_ENDPOINT.name())) - .setId(name) - .setDisplayName(name) - .build(); + String name = NsxControllerUtils.getTier1GatewayName(cmd.getDomainName(), cmd.getAccountName(), cmd.getZoneName(), cmd.getVpcName()); try { - tier1service.patch(name, tier1); - createTier1LocaleServices(name, edgeCluster); - } catch (Error error) { - ApiError ae = error.getData()._convertTo(ApiError.class); - return new NsxAnswer(cmd, new CloudRuntimeException(ae.getErrorMessage())); - } - return new NsxAnswer(cmd, true, ""); - } - - /** - * To instantiate Tier-1 in Edge Cluster - * @return - */ - private boolean createTier1LocaleServices(String tier1Id, String edgeCluster) { - try { - List localeServices = getTier0LocalServices(tier0Gateway); - com.vmware.nsx_policy.infra.tier_1s.LocaleServices tier1LocalService = (com.vmware.nsx_policy.infra.tier_1s.LocaleServices) nsxService.apply(com.vmware.nsx_policy.infra.tier_1s.LocaleServices.class); - com.vmware.nsx_policy.model.LocaleServices localeService = new com.vmware.nsx_policy.model.LocaleServices.Builder() - .setEdgeClusterPath(localeServices.get(0).getEdgeClusterPath()).build(); - tier1LocalService.patch(tier1Id, Tier_1_LOCALE_SERVICE_ID, localeService); - return true; - } catch (Error error) { - throw new CloudRuntimeException(String.format("Failed to instantiate tier-1 gateway %s in edge cluster %s", tier1Id, edgeCluster)); + nsxApiClient.createTier1Gateway(name, tier0Gateway, edgeCluster); + return new NsxAnswer(cmd, true, ""); + } catch (CloudRuntimeException e) { + LOGGER.error(String.format("Cannot create tier 1 gateway %s: %s", name, e.getMessage())); + return new NsxAnswer(cmd, e); } } private Answer executeRequest(DeleteNsxTier1GatewayCommand cmd) { + String tier1Id = NsxControllerUtils.getTier1GatewayName(cmd.getDomainName(), cmd.getAccountName(), cmd.getZoneName(), cmd.getVpcName()); try { - String tier1Id = getTier1GatewayName(cmd); - com.vmware.nsx_policy.infra.tier_1s.LocaleServices localeService = (com.vmware.nsx_policy.infra.tier_1s.LocaleServices) - nsxService.apply(com.vmware.nsx_policy.infra.tier_1s.LocaleServices.class); - localeService.delete(tier1Id, Tier_1_LOCALE_SERVICE_ID); - Tier1s tier1service = (Tier1s) nsxService.apply(Tier1s.class); - tier1service.delete(tier1Id); + nsxApiClient.deleteTier1Gateway(tier1Id); } catch (Exception e) { return new NsxAnswer(cmd, new CloudRuntimeException(e.getMessage())); } @@ -360,143 +274,61 @@ public class NsxResource implements ServerResource { private Answer executeRequest(CreateNsxSegmentCommand cmd) { try { - SiteListResult sites = getSites(); - String errorMsg = null; - if (CollectionUtils.isNullOrEmpty(sites.getResults())) { - errorMsg = String.format("Failed to create network: %s as no sites are found in the linked NSX infrastructure", cmd.getTierNetwork().getName()); + SiteListResult sites = nsxApiClient.getSites(); + String errorMsg; + String networkName = cmd.getNetworkName(); + if (CollectionUtils.isEmpty(sites.getResults())) { + errorMsg = String.format("Failed to create network: %s as no sites are found in the linked NSX infrastructure", networkName); LOGGER.error(errorMsg); return new NsxAnswer(cmd, new CloudRuntimeException(errorMsg)); } String siteId = sites.getResults().get(0).getId(); - EnforcementPointListResult epList = getEnforcementPoints(siteId); - if (CollectionUtils.isNullOrEmpty(epList.getResults())) { - errorMsg = String.format("Failed to create network: %s as no enforcement points are found in the linked NSX infrastructure", cmd.getTierNetwork().getName()); + EnforcementPointListResult epList = nsxApiClient.getEnforcementPoints(siteId); + if (CollectionUtils.isEmpty(epList.getResults())) { + errorMsg = String.format("Failed to create network: %s as no enforcement points are found in the linked NSX infrastructure", networkName); LOGGER.error(errorMsg); return new NsxAnswer(cmd, new CloudRuntimeException(errorMsg)); } String enforcementPointPath = epList.getResults().get(0).getPath(); - TransportZoneListResult transportZoneListResult = getTransportZones(); - if (CollectionUtils.isNullOrEmpty(transportZoneListResult.getResults())) { - errorMsg = String.format("Failed to create network: %s as no transport zones were found in the linked NSX infrastructure", cmd.getTierNetwork().getName()); + TransportZoneListResult transportZoneListResult = nsxApiClient.getTransportZones(); + if (CollectionUtils.isEmpty(transportZoneListResult.getResults())) { + errorMsg = String.format("Failed to create network: %s as no transport zones were found in the linked NSX infrastructure", networkName); LOGGER.error(errorMsg); return new NsxAnswer(cmd, new CloudRuntimeException(errorMsg)); } List transportZones = transportZoneListResult.getResults().stream().filter(tz -> tz.getDisplayName().equals(transportZone)).collect(Collectors.toList()); - if (CollectionUtils.isNullOrEmpty(transportZones)) { - errorMsg = String.format("Failed to create network: %s as no transport zone of name %s was found in the linked NSX infrastructure", cmd.getTierNetwork().getName(), transportZone); + if (CollectionUtils.isEmpty(transportZones)) { + errorMsg = String.format("Failed to create network: %s as no transport zone of name %s was found in the linked NSX infrastructure", networkName, transportZone); LOGGER.error(errorMsg); return new NsxAnswer(cmd, new CloudRuntimeException(errorMsg)); } - String segmentName = getSegmentName(cmd.getAccountName(), cmd.getTierNetwork().getName(), cmd.getVpcName()); - Segments segmentService = (Segments) nsxService.apply(Segments.class); - SegmentSubnet subnet = new SegmentSubnet.Builder() - .setGatewayAddress(cmd.getTierNetwork().getGateway() + "/" + cmd.getTierNetwork().getCidr().split("/")[1]).build(); - Segment segment = new Segment.Builder() - .setResourceType(SEGMENT_RESOURCE_TYPE) - .setId(segmentName) - .setDisplayName(segmentName) - .setConnectivityPath(isNull(cmd.getVpcName()) ? TIER_0_GATEWAY_PATH_PREFIX + tier0Gateway - : TIER_1_GATEWAY_PATH_PREFIX + getTier1GatewayName(cmd)) - .setAdminState(NsxApiClientUtils.AdminState.UP.name()) - .setSubnets(List.of(subnet)) - .setTransportZonePath(enforcementPointPath + "/transport-zones/" + transportZones.get(0).getId()) - .build(); - segmentService.patch(segmentName, segment); + String segmentName = NsxControllerUtils.getNsxSegmentId(cmd.getDomainName(), cmd.getAccountName(), cmd.getZoneName(), cmd.getVpcName(), networkName); + String gatewayAddress = cmd.getNetworkGateway() + "/" + cmd.getNetworkCidr().split("/")[1]; + + nsxApiClient.createSegment(cmd.getZoneName(), cmd.getDomainName(), cmd.getAccountName(), cmd.getVpcName(), + segmentName, gatewayAddress, tier0Gateway, enforcementPointPath, transportZones); } catch (Exception e) { - LOGGER.error(String.format("Failed to create network: %s", cmd.getTierNetwork().getName())); + LOGGER.error(String.format("Failed to create network: %s", cmd.getNetworkName())); return new NsxAnswer(cmd, new CloudRuntimeException(e.getMessage())); } return new NsxAnswer(cmd, true, null); } private NsxAnswer executeRequest(DeleteNsxSegmentCommand cmd) { + String segmentName = NsxControllerUtils.getNsxSegmentId(cmd.getDomainName(), cmd.getAccountName(), cmd.getZoneName(), cmd.getVpcName(), cmd.getNetworkName()); try { Thread.sleep(30*1000); - String segmentName = getSegmentName(cmd.getAccountName(), cmd.getTierNetwork().getName(), cmd.getVpcName()); - Segments segmentService = (Segments) nsxService.apply(Segments.class); - LOGGER.debug(String.format("Removing the segment with ID %s", segmentName)); - segmentService.delete(segmentName); - DhcpRelayConfigs dhcpRelayConfig = (DhcpRelayConfigs) nsxService.apply(DhcpRelayConfigs.class); - String dhcpRelayId = getDhcpRelayId(cmd.getZoneName(), cmd.getAccountName(), cmd.getVpcName(), cmd.getTierNetwork().getName()); - LOGGER.debug(String.format("Removing the DHCP relay config with ID %s", dhcpRelayId)); - dhcpRelayConfig.delete(dhcpRelayId); + nsxApiClient.deleteSegment(cmd.getZoneName(), cmd.getDomainName(), cmd.getAccountName(), cmd.getVpcName(), cmd.getNetworkName(), segmentName); } catch (Exception e) { - LOGGER.error(String.format("Failed to delete NSX segment: %s", getSegmentName(cmd.getAccountName(), cmd.getTierNetwork().getName(), cmd.getVpcName()))); + LOGGER.error(String.format("Failed to delete NSX segment: %s", segmentName)); return new NsxAnswer(cmd, new CloudRuntimeException(e.getMessage())); } return new NsxAnswer(cmd, true, null); } - private List getTier0LocalServices(String tier0Gateway) { - try { - LocaleServices tier0LocaleServices = (LocaleServices) nsxService.apply(LocaleServices.class); - LocaleServicesListResult result = tier0LocaleServices.list(tier0Gateway, null, false, null, null, null, null); - return result.getResults(); - } catch (Exception e) { - throw new CloudRuntimeException(String.format("Failed to fetch locale services for tier gateway %s due to %s", tier0Gateway, e.getMessage())); - } - } - - private Tier1 getTier1Gateway(String tier1GatewayId) { - try { - Tier1s tier1service = (Tier1s) nsxService.apply(Tier1s.class); - return tier1service.get(tier1GatewayId); - } catch (Exception e) { - LOGGER.debug(String.format("NSX Tier-1 gateway with name: %s not found", tier1GatewayId)); - } - return null; - } - - private SiteListResult getSites() { - try { - Sites sites = (Sites) nsxService.apply(Sites.class); - return sites.list(null, false, null, null, null, null); - } catch (Exception e) { - throw new CloudRuntimeException(String.format("Failed to fetch service segment list due to %s", e.getMessage())); - } - } - - private EnforcementPointListResult getEnforcementPoints(String siteId) { - try { - EnforcementPoints enforcementPoints = (EnforcementPoints) nsxService.apply(EnforcementPoints.class); - return enforcementPoints.list(siteId, null, false, null, null, null, null); - } catch (Exception e) { - throw new CloudRuntimeException(String.format("Failed to fetch service segment list due to %s", e.getMessage())); - } - } - - private TransportZoneListResult getTransportZones() { - try { - com.vmware.nsx.TransportZones transportZones = (com.vmware.nsx.TransportZones) nsxService.apply(com.vmware.nsx.TransportZones.class); - return transportZones.list(null, null, true, null, true, null, null, null, OVERLAY.name(), null); - } catch (Exception e) { - throw new CloudRuntimeException(String.format("Failed to fetch service segment list due to %s", e.getMessage())); - } - } - - private String getTier1GatewayName(CreateNsxTier1GatewayCommand cmd) { - return cmd.getZoneName() + "-" + cmd.getAccountName() + "-" + cmd.getVpcName(); - } - - private String getSegmentName(String accountName, String tierNetworkName, String vpcName) { - String segmentName = accountName + "-"; - if (isNull(vpcName)) { - return segmentName + tierNetworkName; - } - return segmentName + vpcName + "-" + tierNetworkName; - } - - private String getDhcpRelayId(String zoneName, String accountName, String vpcName, String networkName) { - String suffix = "-Relay"; - if (isNull(vpcName)) { - return zoneName + "-" + accountName + "-" + networkName + suffix; - } - return String.format("%s-%s-%s-%s%s", zoneName, accountName, vpcName, networkName, suffix); - } - @Override public boolean start() { return true; diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxApi.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxApi.java deleted file mode 100644 index 1d6b3e8867d..00000000000 --- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxApi.java +++ /dev/null @@ -1,32 +0,0 @@ -// 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.vapi.client.ApiClient; - -public class NsxApi { - - ApiClient apiClient; - - public ApiClient getApiClient() { - return apiClient; - } - - public void setApiClient(ApiClient apiClient) { - this.apiClient = apiClient; - } -} 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 new file mode 100644 index 00000000000..348a0d0b62c --- /dev/null +++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxApiClient.java @@ -0,0 +1,293 @@ +// 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.cloud.exception.InvalidParameterValueException; +import com.cloud.utils.exception.CloudRuntimeException; +import com.vmware.nsx.model.TransportZone; +import com.vmware.nsx.model.TransportZoneListResult; +import com.vmware.nsx_policy.infra.DhcpRelayConfigs; +import com.vmware.nsx_policy.infra.Segments; +import com.vmware.nsx_policy.infra.Sites; +import com.vmware.nsx_policy.infra.Tier1s; +import com.vmware.nsx_policy.infra.sites.EnforcementPoints; +import com.vmware.nsx_policy.infra.tier_0s.LocaleServices; +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.LocaleServicesListResult; +import com.vmware.nsx_policy.model.Segment; +import com.vmware.nsx_policy.model.SegmentSubnet; +import com.vmware.nsx_policy.model.SiteListResult; +import com.vmware.nsx_policy.model.Tier1; +import com.vmware.vapi.bindings.Service; +import com.vmware.vapi.bindings.StubConfiguration; +import com.vmware.vapi.cis.authn.SecurityContextFactory; +import com.vmware.vapi.client.ApiClient; +import com.vmware.vapi.client.ApiClients; +import com.vmware.vapi.client.Configuration; +import com.vmware.vapi.core.ExecutionContext; +import com.vmware.vapi.internal.protocol.RestProtocol; +import com.vmware.vapi.internal.protocol.client.rest.authn.BasicAuthenticationAppender; +import com.vmware.vapi.protocol.HttpConfiguration; +import com.vmware.vapi.std.errors.Error; +import org.apache.cloudstack.utils.NsxControllerUtils; +import org.apache.log4j.Logger; + +import java.util.List; +import java.util.function.Function; + +import static java.util.Objects.isNull; + +public class NsxApiClient { + + private final Function, Service> nsxService; + + public static final int RESPONSE_TIMEOUT_SECONDS = 60; + private static final Logger LOGGER = Logger.getLogger(NsxApiClient.class); + + // Constants + private static final String TIER_1_RESOURCE_TYPE = "Tier1"; + private static final String Tier_1_LOCALE_SERVICE_ID = "default"; + 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/"; + + private enum PoolAllocation { ROUTING, LB_SMALL, LB_MEDIUM, LB_LARGE, LB_XLARGE } + + private enum TYPE { ROUTED, NATTED } + + private enum HAMode { ACTIVE_STANDBY, ACTIVE_ACTIVE } + + private enum FailoverMode { PREEMPTIVE, NON_PREEMPTIVE } + + private enum AdminState { UP, DOWN } + + private enum TransportType { OVERLAY, VLAN } + + public enum RouteAdvertisementType { TIER1_STATIC_ROUTES, TIER1_CONNECTED, TIER1_NAT, + TIER1_LB_VIP, TIER1_LB_SNAT, TIER1_DNS_FORWARDER_IP, TIER1_IPSEC_LOCAL_ENDPOINT + } + + 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(); + sslConfigBuilder + .disableCertificateValidation() + .disableHostnameVerification(); + HttpConfiguration.SslConfiguration sslConfig = sslConfigBuilder.getConfig(); + + HttpConfiguration httpConfig = new HttpConfiguration.Builder() + .setSoTimeout(RESPONSE_TIMEOUT_SECONDS * 1000) + .setSslConfiguration(sslConfig).getConfig(); + + StubConfiguration stubConfig = new StubConfiguration(); + ExecutionContext.SecurityContext securityContext = SecurityContextFactory + .createUserPassSecurityContext(username, password); + stubConfig.setSecurityContext(securityContext); + + Configuration.Builder configBuilder = new Configuration.Builder() + .register(Configuration.HTTP_CONFIG_CFG, httpConfig) + .register(Configuration.STUB_CONFIG_CFG, stubConfig) + .register(RestProtocol.REST_REQUEST_AUTHENTICATOR_CFG, new BasicAuthenticationAppender()); + Configuration config = configBuilder.build(); + ApiClient apiClient = ApiClients.newRestClient(controllerUrl, config); + nsxService = apiClient::createStub; + } + + public void createDhcpRelayConfig(String dhcpRelayConfigName, List addresses) { + try { + DhcpRelayConfigs service = (DhcpRelayConfigs) nsxService.apply(DhcpRelayConfigs.class); + DhcpRelayConfig config = new DhcpRelayConfig.Builder() + .setServerAddresses(addresses) + .setId(dhcpRelayConfigName) + .setDisplayName(dhcpRelayConfigName) + .build(); + service.patch(dhcpRelayConfigName, config); + } catch (Error error) { + ApiError ae = error.getData()._convertTo(ApiError.class); + String msg = String.format("Error creating the DHCP relay config with name %s: %s", dhcpRelayConfigName, ae.getErrorMessage()); + LOGGER.error(msg); + throw new CloudRuntimeException(ae.getErrorMessage()); + } + } + + public Segment getSegmentById(String segmentName) { + try { + Segments segmentService = (Segments) nsxService.apply(Segments.class); + return segmentService.get(segmentName); + } catch (Error error) { + ApiError ae = error.getData()._convertTo(ApiError.class); + String msg = String.format("Error obtaining the segment with name %s: %s", segmentName, ae.getErrorMessage()); + LOGGER.error(msg); + throw new CloudRuntimeException(ae.getErrorMessage()); + } + } + + public void updateSegment(String segmentName, Segment segment) { + try { + Segments segmentService = (Segments) nsxService.apply(Segments.class); + segmentService.patch(segmentName, segment); + } catch (Error error) { + ApiError ae = error.getData()._convertTo(ApiError.class); + String msg = String.format("Error updating the segment with name %s: %s", segmentName, ae.getErrorMessage()); + LOGGER.error(msg); + throw new CloudRuntimeException(ae.getErrorMessage()); + } + } + + private Tier1 getTier1Gateway(String tier1GatewayId) { + try { + Tier1s tier1service = (Tier1s) nsxService.apply(Tier1s.class); + return tier1service.get(tier1GatewayId); + } catch (Exception e) { + LOGGER.debug(String.format("NSX Tier-1 gateway with name: %s not found", tier1GatewayId)); + } + return null; + } + + private List getTier0LocalServices(String tier0Gateway) { + try { + LocaleServices tier0LocaleServices = (LocaleServices) nsxService.apply(LocaleServices.class); + LocaleServicesListResult result = tier0LocaleServices.list(tier0Gateway, null, false, null, null, null, null); + return result.getResults(); + } catch (Exception e) { + throw new CloudRuntimeException(String.format("Failed to fetch locale services for tier gateway %s due to %s", tier0Gateway, e.getMessage())); + } + } + + /** + * To instantiate Tier-1 in Edge Cluster + */ + private void createTier1LocaleServices(String tier1Id, String edgeCluster, String tier0Gateway) { + try { + List localeServices = getTier0LocalServices(tier0Gateway); + com.vmware.nsx_policy.infra.tier_1s.LocaleServices tier1LocalService = (com.vmware.nsx_policy.infra.tier_1s.LocaleServices) nsxService.apply(com.vmware.nsx_policy.infra.tier_1s.LocaleServices.class); + com.vmware.nsx_policy.model.LocaleServices localeService = new com.vmware.nsx_policy.model.LocaleServices.Builder() + .setEdgeClusterPath(localeServices.get(0).getEdgeClusterPath()).build(); + tier1LocalService.patch(tier1Id, Tier_1_LOCALE_SERVICE_ID, localeService); + } catch (Error error) { + throw new CloudRuntimeException(String.format("Failed to instantiate tier-1 gateway %s in edge cluster %s", tier1Id, edgeCluster)); + } + } + + public void createTier1Gateway(String name, String tier0Gateway, String edgeCluster) { + String tier0GatewayPath = TIER_0_GATEWAY_PATH_PREFIX + tier0Gateway; + Tier1 tier1 = getTier1Gateway(name); + if (tier1 != null) { + throw new InvalidParameterValueException(String.format("VPC network with name %s exists in NSX zone", name)); + } + + Tier1s tier1service = (Tier1s) nsxService.apply(Tier1s.class); + tier1 = new Tier1.Builder() + .setTier0Path(tier0GatewayPath) + .setResourceType(TIER_1_RESOURCE_TYPE) + .setPoolAllocation(PoolAllocation.ROUTING.name()) + .setHaMode(HAMode.ACTIVE_STANDBY.name()) + .setFailoverMode(FailoverMode.PREEMPTIVE.name()) + .setRouteAdvertisementTypes(List.of(RouteAdvertisementType.TIER1_CONNECTED.name(), RouteAdvertisementType.TIER1_IPSEC_LOCAL_ENDPOINT.name())) + .setId(name) + .setDisplayName(name) + .build(); + try { + tier1service.patch(name, tier1); + createTier1LocaleServices(name, edgeCluster, tier0Gateway); + } catch (Error error) { + ApiError ae = error.getData()._convertTo(ApiError.class); + String msg = String.format("Error creating tier 1 gateway %s: %s", name, ae.getErrorMessage()); + LOGGER.error(msg); + throw new CloudRuntimeException(msg); + } + } + + public void deleteTier1Gateway(String tier1Id) { + com.vmware.nsx_policy.infra.tier_1s.LocaleServices localeService = (com.vmware.nsx_policy.infra.tier_1s.LocaleServices) + nsxService.apply(com.vmware.nsx_policy.infra.tier_1s.LocaleServices.class); + localeService.delete(tier1Id, Tier_1_LOCALE_SERVICE_ID); + Tier1s tier1service = (Tier1s) nsxService.apply(Tier1s.class); + tier1service.delete(tier1Id); + } + + public SiteListResult getSites() { + try { + Sites sites = (Sites) nsxService.apply(Sites.class); + return sites.list(null, false, null, null, null, null); + } catch (Exception e) { + throw new CloudRuntimeException(String.format("Failed to fetch service segment list due to %s", e.getMessage())); + } + } + + public EnforcementPointListResult getEnforcementPoints(String siteId) { + try { + EnforcementPoints enforcementPoints = (EnforcementPoints) nsxService.apply(EnforcementPoints.class); + return enforcementPoints.list(siteId, null, false, null, null, null, null); + } catch (Exception e) { + throw new CloudRuntimeException(String.format("Failed to fetch service segment list due to %s", e.getMessage())); + } + } + + public TransportZoneListResult getTransportZones() { + try { + com.vmware.nsx.TransportZones transportZones = (com.vmware.nsx.TransportZones) nsxService.apply(com.vmware.nsx.TransportZones.class); + return transportZones.list(null, null, true, null, true, null, null, null, TransportType.OVERLAY.name(), null); + } catch (Exception e) { + throw new CloudRuntimeException(String.format("Failed to fetch service segment list due to %s", e.getMessage())); + } + } + + public void createSegment(String zoneName, String domainName, String accountName, String vpcName, String segmentName, String gatewayAddress, String tier0Gateway, String enforcementPointPath, List transportZones) { + try { + Segments segmentService = (Segments) nsxService.apply(Segments.class); + SegmentSubnet subnet = new SegmentSubnet.Builder() + .setGatewayAddress(gatewayAddress) + .build(); + Segment segment = new Segment.Builder() + .setResourceType(SEGMENT_RESOURCE_TYPE) + .setId(segmentName) + .setDisplayName(segmentName) + .setConnectivityPath(isNull(vpcName) ? TIER_0_GATEWAY_PATH_PREFIX + tier0Gateway + : TIER_1_GATEWAY_PATH_PREFIX + NsxControllerUtils.getTier1GatewayName(domainName, accountName, zoneName, vpcName)) + .setAdminState(AdminState.UP.name()) + .setSubnets(List.of(subnet)) + .setTransportZonePath(enforcementPointPath + "/transport-zones/" + transportZones.get(0).getId()) + .build(); + segmentService.patch(segmentName, segment); + } catch (Error error) { + ApiError ae = error.getData()._convertTo(ApiError.class); + String msg = String.format("Error creating segment %s: %s", segmentName, ae.getErrorMessage()); + LOGGER.error(msg); + throw new CloudRuntimeException(msg); + } + } + + public void deleteSegment(String zoneName, String domainName, String accountName, String vpcName, String networkName, String segmentName) { + try { + Segments segmentService = (Segments) nsxService.apply(Segments.class); + LOGGER.debug(String.format("Removing the segment with ID %s", segmentName)); + segmentService.delete(segmentName); + DhcpRelayConfigs dhcpRelayConfig = (DhcpRelayConfigs) nsxService.apply(DhcpRelayConfigs.class); + String dhcpRelayConfigId = NsxControllerUtils.getNsxDhcpRelayConfigId(zoneName, domainName, accountName, vpcName, networkName); + LOGGER.debug(String.format("Removing the DHCP relay config with ID %s", dhcpRelayConfigId)); + dhcpRelayConfig.delete(dhcpRelayConfigId); + } catch (Error error) { + ApiError ae = error.getData()._convertTo(ApiError.class); + String msg = String.format("Error deleting segment %s: %s", segmentName, ae.getErrorMessage()); + LOGGER.error(msg); + throw new CloudRuntimeException(msg); + } + } +} 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 19d068d3349..b0f38831c93 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 @@ -27,6 +27,8 @@ import com.cloud.agent.api.StartupCommand; import com.cloud.dc.DataCenterVO; import com.cloud.dc.dao.DataCenterDao; import com.cloud.deploy.DeployDestination; +import com.cloud.domain.DomainVO; +import com.cloud.domain.dao.DomainDao; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.ConnectionException; import com.cloud.exception.InsufficientCapacityException; @@ -97,6 +99,8 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, DnsS PhysicalNetworkDao physicalNetworkDao; @Inject NetworkModel networkModel; + @Inject + private DomainDao domainDao; private static final Logger LOGGER = Logger.getLogger(NsxElement.class); @@ -197,12 +201,13 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, DnsS Account account = accountMgr.getAccount(network.getAccountId()); NetworkVO networkVO = networkDao.findById(network.getId()); DataCenterVO zone = dataCenterDao.findById(network.getDataCenterId()); + DomainVO domain = domainDao.findById(account.getDomainId()); if (Objects.isNull(zone)) { String msg = String.format("Cannot fing zone with ID %s", network.getDataCenterId()); LOGGER.error(msg); throw new CloudRuntimeException(msg); } - return nsxService.deleteNetwork(zone.getName(), account.getAccountName(), networkVO); + return nsxService.deleteNetwork(zone.getName(), account.getAccountName(), domain.getName(), networkVO); } @Override @@ -261,6 +266,16 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, DnsS return null; } + private DomainVO getDomainFromAccount(Account account) { + DomainVO domain = domainDao.findById(account.getDomainId()); + if (Objects.isNull(domain)) { + String msg = String.format("Unable to find domain with id: %s", account.getDomainId()); + LOGGER.error(msg); + throw new CloudRuntimeException(msg); + } + return domain; + } + @Override public boolean implementVpc(Vpc vpc, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { DataCenterVO zone = zoneFunction.apply(vpc.getZoneId()); @@ -272,7 +287,8 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, DnsS throw new InvalidParameterValueException(String.format("Failed to find account with id %s", vpc.getAccountId())); } Account account = isNsxAndAccount.second(); - return nsxService.createVpcNetwork(vpc.getZoneId(), zone.getName(), account.getAccountId(), account.getName(), vpc.getName()); + DomainVO domain = getDomainFromAccount(account); + return nsxService.createVpcNetwork(vpc.getZoneId(), zone.getName(), account.getName(), domain.getName(), vpc.getName()); } @Override @@ -286,8 +302,8 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, DnsS throw new InvalidParameterValueException(String.format("Failed to find account with id %s", vpc.getAccountId())); } Account account = isNsxAndAccount.second(); - - return nsxService.deleteVpcNetwork(vpc.getZoneId(), zone.getName(), account.getAccountId(), account.getName(), vpc.getName()); + DomainVO domain = getDomainFromAccount(account); + return nsxService.deleteVpcNetwork(vpc.getZoneId(), zone.getName(), account.getName(), domain.getName(), vpc.getName()); } private Pair validateVpcConfigurationAndGetAccount(DataCenterVO zone, Vpc vpc) { diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxGuestNetworkGuru.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxGuestNetworkGuru.java index e4bfcf30aa4..29d335d3cde 100644 --- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxGuestNetworkGuru.java +++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxGuestNetworkGuru.java @@ -23,6 +23,8 @@ import com.cloud.dc.DataCenter; import com.cloud.dc.dao.DataCenterDao; import com.cloud.deploy.DeployDestination; import com.cloud.deploy.DeploymentPlan; +import com.cloud.domain.DomainVO; +import com.cloud.domain.dao.DomainDao; import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.InsufficientVirtualNetworkCapacityException; import com.cloud.exception.InvalidParameterValueException; @@ -48,6 +50,8 @@ import com.cloud.vm.VirtualMachineProfile; import org.apache.cloudstack.NsxAnswer; import org.apache.cloudstack.agent.api.CreateNsxDhcpRelayConfigCommand; import org.apache.cloudstack.agent.api.CreateNsxSegmentCommand; +import org.apache.cloudstack.utils.NsxControllerUtils; +import org.apache.cloudstack.utils.NsxHelper; import org.apache.log4j.Logger; import javax.inject.Inject; @@ -65,6 +69,8 @@ public class NsxGuestNetworkGuru extends GuestNetworkGuru implements NetworkMigr DataCenterDao zoneDao; @Inject AccountDao accountDao; + @Inject + private DomainDao domainDao; public NsxGuestNetworkGuru() { super(); @@ -211,12 +217,17 @@ public class NsxGuestNetworkGuru extends GuestNetworkGuru implements NetworkMigr throw new CloudRuntimeException(msg); } + DomainVO domain = domainDao.findById(account.getDomainId()); + if (Objects.isNull(domain)) { + String msg = String.format("Unable to find domain with id: %s", account.getDomainId()); + LOGGER.error(msg); + throw new CloudRuntimeException(msg); + } + // Create the DHCP relay config for the segment String iPv4Address = nicProfile.getIPv4Address(); List addresses = List.of(iPv4Address); - CreateNsxDhcpRelayConfigCommand command = new CreateNsxDhcpRelayConfigCommand(zone.getName(), zone.getId(), - account.getAccountName(), network.getAccountId(), - vpc.getName(), network.getName(), addresses); + CreateNsxDhcpRelayConfigCommand command = NsxHelper.createNsxDhcpRelayConfigCommand(domain, account, zone, vpc, network, addresses); NsxAnswer answer = nsxControllerUtils.sendNsxCommand(command, zone.getId()); if (!answer.getResult()) { String msg = String.format("Error creating DHCP relay config for network %s and nic %s: %s", network.getName(), nic.getName(), answer.getDetails()); @@ -265,7 +276,7 @@ public class NsxGuestNetworkGuru extends GuestNetworkGuru implements NetworkMigr } private void createNsxSegment(NetworkVO networkVO, DataCenter zone) { - String vpcName = null; + String vpcName = null; if (nonNull(networkVO.getVpcId())) { VpcVO vpc = _vpcDao.findById(networkVO.getVpcId()); if (isNull(vpc)) { @@ -277,8 +288,13 @@ public class NsxGuestNetworkGuru extends GuestNetworkGuru implements NetworkMigr if (isNull(account)) { throw new CloudRuntimeException(String.format("Unable to find account with id: %s", networkVO.getAccountId())); } - CreateNsxSegmentCommand command = new CreateNsxSegmentCommand(zone.getName(), zone.getId(), - account.getAccountName(), networkVO.getAccountId(), vpcName, networkVO); + DomainVO domain = domainDao.findById(account.getDomainId()); + if (Objects.isNull(domain)) { + String msg = String.format("Unable to find domain with id: %s", account.getDomainId()); + LOGGER.error(msg); + throw new CloudRuntimeException(msg); + } + CreateNsxSegmentCommand command = NsxHelper.createNsxSegmentCommand(domain, account, zone, vpcName, networkVO); NsxAnswer answer = nsxControllerUtils.sendNsxCommand(command, zone.getId()); if (!answer.getResult()) { throw new CloudRuntimeException("can not create NSX network"); diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxServiceImpl.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxServiceImpl.java index 7d6853ea9ec..45369f4cdbf 100644 --- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxServiceImpl.java +++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxServiceImpl.java @@ -23,6 +23,7 @@ import org.apache.cloudstack.NsxAnswer; import org.apache.cloudstack.agent.api.CreateNsxTier1GatewayCommand; import org.apache.cloudstack.agent.api.DeleteNsxSegmentCommand; import org.apache.cloudstack.agent.api.DeleteNsxTier1GatewayCommand; +import org.apache.cloudstack.utils.NsxControllerUtils; import javax.inject.Inject; import java.util.Objects; @@ -33,27 +34,27 @@ public class NsxServiceImpl implements NsxService { @Inject private VpcDao vpcDao; - public boolean createVpcNetwork(Long zoneId, String zoneName, Long accountId, String accountName, String vpcName) { + public boolean createVpcNetwork(Long zoneId, String zoneName, String accountName, String domainName, String vpcName) { CreateNsxTier1GatewayCommand createNsxTier1GatewayCommand = - new CreateNsxTier1GatewayCommand(zoneName, zoneId, accountName, accountId, vpcName); + new CreateNsxTier1GatewayCommand(domainName, accountName, zoneName, vpcName); NsxAnswer result = nsxControllerUtils.sendNsxCommand(createNsxTier1GatewayCommand, zoneId); return result.getResult(); } - public boolean deleteVpcNetwork(Long zoneId, String zoneName, Long accountId, String accountName, String vpcName) { + public boolean deleteVpcNetwork(Long zoneId, String zoneName, String accountName, String domainName, String vpcName) { DeleteNsxTier1GatewayCommand deleteNsxTier1GatewayCommand = - new DeleteNsxTier1GatewayCommand(zoneName, zoneId, accountName, accountId, vpcName); + new DeleteNsxTier1GatewayCommand(domainName, accountName, zoneName, vpcName); NsxAnswer result = nsxControllerUtils.sendNsxCommand(deleteNsxTier1GatewayCommand, zoneId); return result.getResult(); } - public boolean deleteNetwork(String zoneName, String accountName, NetworkVO network) { + public boolean deleteNetwork(String zoneName, String accountName, String domainName, NetworkVO network) { String vpcName = null; if (Objects.nonNull(network.getVpcId())) { VpcVO vpc = vpcDao.findById(network.getVpcId()); vpcName = Objects.nonNull(vpc) ? vpc.getName() : null; } - DeleteNsxSegmentCommand deleteNsxSegmentCommand = new DeleteNsxSegmentCommand(zoneName, accountName, vpcName, network); + DeleteNsxSegmentCommand deleteNsxSegmentCommand = new DeleteNsxSegmentCommand(domainName, accountName, zoneName, vpcName, network.getName()); NsxAnswer result = nsxControllerUtils.sendNsxCommand(deleteNsxSegmentCommand, network.getDataCenterId()); return result.getResult(); } diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/utils/NsxApiClientUtils.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/utils/NsxApiClientUtils.java deleted file mode 100644 index 26aad6ad635..00000000000 --- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/utils/NsxApiClientUtils.java +++ /dev/null @@ -1,103 +0,0 @@ -// 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.utils; - -import com.vmware.vapi.bindings.StubConfiguration; -import com.vmware.vapi.cis.authn.SecurityContextFactory; -import com.vmware.vapi.client.ApiClient; -import com.vmware.vapi.client.ApiClients; -import com.vmware.vapi.client.Configuration; -import com.vmware.vapi.core.ExecutionContext.SecurityContext; -import com.vmware.vapi.internal.protocol.RestProtocol; -import com.vmware.vapi.internal.protocol.client.rest.authn.BasicAuthenticationAppender; -import com.vmware.vapi.protocol.HttpConfiguration; -import org.apache.log4j.Logger; - -public class NsxApiClientUtils { - private static final Logger S_LOGGER = Logger.getLogger(NsxApiClientUtils.class); - public static ApiClient apiClient = null; - public static final int RESPONSE_TIMEOUT_SECONDS = 60; - - public enum PoolAllocation { - ROUTING, - LB_SMALL, - LB_MEDIUM, - LB_LARGE, - LB_XLARGE - } - - public enum TYPE { - ROUTED, - NATTED - } - - public enum HAMode { - ACTIVE_STANDBY, - ACTIVE_ACTIVE - } - - public enum FailoverMode { - PREEMPTIVE, - NON_PREEMPTIVE - } - - public enum AdminState { - UP, - DOWN - } - - public enum TransportType { - OVERLAY, - VLAN - } - - public enum RouteAdvertisementType { - TIER1_STATIC_ROUTES, - TIER1_CONNECTED, - TIER1_NAT, - TIER1_LB_VIP, - TIER1_LB_SNAT, - TIER1_DNS_FORWARDER_IP, - TIER1_IPSEC_LOCAL_ENDPOINT - } - public static ApiClient createApiClient(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(); - sslConfigBuilder - .disableCertificateValidation() - .disableHostnameVerification(); - HttpConfiguration.SslConfiguration sslConfig = sslConfigBuilder.getConfig(); - - HttpConfiguration httpConfig = new HttpConfiguration.Builder() - .setSoTimeout(RESPONSE_TIMEOUT_SECONDS * 1000) - .setSslConfiguration(sslConfig).getConfig(); - - StubConfiguration stubConfig = new StubConfiguration(); - SecurityContext securityContext = SecurityContextFactory - .createUserPassSecurityContext(username, password); - stubConfig.setSecurityContext(securityContext); - - Configuration.Builder configBuilder = new Configuration.Builder() - .register(Configuration.HTTP_CONFIG_CFG, httpConfig) - .register(Configuration.STUB_CONFIG_CFG, stubConfig) - .register(RestProtocol.REST_REQUEST_AUTHENTICATOR_CFG, new BasicAuthenticationAppender()); - Configuration config = configBuilder.build(); - apiClient = ApiClients.newRestClient(controllerUrl, config); - - return apiClient; - } -} diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxControllerUtils.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/utils/NsxControllerUtils.java similarity index 65% rename from plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxControllerUtils.java rename to plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/utils/NsxControllerUtils.java index 944d663c5df..27a07bac3f3 100644 --- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxControllerUtils.java +++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/utils/NsxControllerUtils.java @@ -14,7 +14,7 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package org.apache.cloudstack.service; +package org.apache.cloudstack.utils; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; @@ -28,6 +28,8 @@ import org.springframework.stereotype.Component; import javax.inject.Inject; +import static java.util.Objects.isNull; + @Component public class NsxControllerUtils { private static final Logger s_logger = Logger.getLogger(NsxControllerUtils.class); @@ -53,4 +55,24 @@ public class NsxControllerUtils { return (NsxAnswer) answer; } + + public static String getTier1GatewayName(String domainName, String accountName, String zoneName, String vpcName) { + return String.format("%s-%s-%s-%s", domainName, accountName, zoneName, vpcName); + } + + public static String getNsxSegmentId(String domainName, String accountName, String zoneName, String vpcName, String tierNetworkName) { + String segmentName = String.format("%s-%s-%s-", domainName, accountName, zoneName); + if (isNull(vpcName)) { + return segmentName + tierNetworkName; + } + return segmentName + vpcName + "-" + tierNetworkName; + } + + public static String getNsxDhcpRelayConfigId(String zoneName, String domainName, String accountName, String vpcName, String networkName) { + String suffix = "-Relay"; + if (isNull(vpcName)) { + return domainName + "-" + accountName + "-" + zoneName + "-" +networkName + suffix; + } + return String.format("%s-%s-%s-%s-%s%s", domainName, accountName, zoneName, vpcName, networkName, suffix); + } } diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/utils/NsxHelper.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/utils/NsxHelper.java new file mode 100644 index 00000000000..31329fa7ee4 --- /dev/null +++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/utils/NsxHelper.java @@ -0,0 +1,41 @@ +// 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.utils; + +import com.cloud.dc.DataCenter; +import com.cloud.domain.DomainVO; +import com.cloud.network.Network; +import com.cloud.network.dao.NetworkVO; +import com.cloud.network.vpc.VpcVO; +import com.cloud.user.Account; +import org.apache.cloudstack.agent.api.CreateNsxDhcpRelayConfigCommand; +import org.apache.cloudstack.agent.api.CreateNsxSegmentCommand; + +import java.util.List; + +public class NsxHelper { + + public static CreateNsxDhcpRelayConfigCommand createNsxDhcpRelayConfigCommand(DomainVO domain, Account account, DataCenter zone, VpcVO vpc, Network network, List addresses) { + return new CreateNsxDhcpRelayConfigCommand(domain.getName(), account.getAccountName(), zone.getName(), + vpc.getName(), network.getName(), addresses); + } + + public static CreateNsxSegmentCommand createNsxSegmentCommand(DomainVO domain, Account account, DataCenter zone, String vpcName, NetworkVO networkVO) { + return new CreateNsxSegmentCommand(domain.getName(), account.getAccountName(), zone.getName(), + vpcName, networkVO.getName(), networkVO.getGateway(), networkVO.getCidr()); + } +} diff --git a/plugins/network-elements/nsx/src/main/resources/META-INF/cloudstack/nsx/spring-nsx-context.xml b/plugins/network-elements/nsx/src/main/resources/META-INF/cloudstack/nsx/spring-nsx-context.xml index 4e45b5fab99..43e03657b7a 100644 --- a/plugins/network-elements/nsx/src/main/resources/META-INF/cloudstack/nsx/spring-nsx-context.xml +++ b/plugins/network-elements/nsx/src/main/resources/META-INF/cloudstack/nsx/spring-nsx-context.xml @@ -33,6 +33,6 @@ - + diff --git a/server/src/main/java/com/cloud/hypervisor/HypervisorGuruBase.java b/server/src/main/java/com/cloud/hypervisor/HypervisorGuruBase.java index fb3dea1129f..956ada691ae 100644 --- a/server/src/main/java/com/cloud/hypervisor/HypervisorGuruBase.java +++ b/server/src/main/java/com/cloud/hypervisor/HypervisorGuruBase.java @@ -23,6 +23,10 @@ import java.util.UUID; import javax.inject.Inject; +import com.cloud.dc.DataCenter; +import com.cloud.dc.dao.DataCenterDao; +import com.cloud.domain.Domain; +import com.cloud.domain.dao.DomainDao; import com.cloud.network.vpc.VpcVO; import com.cloud.network.vpc.dao.VpcDao; import com.cloud.user.Account; @@ -86,6 +90,10 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis @Inject protected AccountManager accountManager; @Inject + private DomainDao domainDao; + @Inject + private DataCenterDao dcDao; + @Inject private NetworkOfferingDetailsDao networkOfferingDetailsDao; @Inject protected @@ -160,11 +168,13 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis NetworkVO network = networkDao.findById(profile.getNetworkId()); to.setNetworkUuid(network.getUuid()); Account account = accountManager.getAccount(network.getAccountId()); + Domain domain = domainDao.findById(network.getDomainId()); + DataCenter zone = dcDao.findById(network.getDataCenterId()); VpcVO vpc = null; if (Objects.nonNull(network) && Objects.nonNull(network.getVpcId())) { vpc = vpcDao.findById(network.getVpcId()); } - to.setNetworkSegmentName(getNetworkName(account.getAccountName(), vpc, network.getName())); + to.setNetworkSegmentName(getNetworkName(zone.getName(), domain.getName(), account.getAccountName(), vpc, network.getName())); // Workaround to make sure the TO has the UUID we need for Nicira integration NicVO nicVO = nicDao.findById(profile.getId()); @@ -193,11 +203,12 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis return to; } - private String getNetworkName(String accountName, VpcVO vpc, String networkName) { + private String getNetworkName(String zoneName, String domainName, String accountName, VpcVO vpc, String networkName) { + String prefix = String.format("%s-%s-%s", domainName, accountName, zoneName); if (Objects.isNull(vpc)) { - return accountName + "-" + networkName; + return prefix + "-" + networkName; } - return accountName + "-" + vpc.getName() + "-" + networkName; + return prefix + "-" + vpc.getName() + "-" + networkName; } From 8337486fdc9330e555cbca950887d598645cbecb Mon Sep 17 00:00:00 2001 From: Pearl Dsilva Date: Thu, 12 Oct 2023 21:30:47 -0400 Subject: [PATCH 3/5] Nsx unit tests (#8090) * Add tests * add test for NsxGuestNetworkGuru * add unit tests for NsxResource * add unti tests for NsxElement * cleanup * [NSX] Refactor API wrapper operations * update tests * update tests - add nsxProviderServiceImpl test * add unit test - NsxServiceImpl * add license * Big refactor * Address review comment * change network cidr to cidr to prevent NPE * add domain and zone names to the various networks - vpc & tier * fix tests --------- Co-authored-by: nvazquez --- .../cloud/vm/VirtualMachineManagerImpl.java | 2 +- .../vm/VirtualMachineManagerImplTest.java | 59 +++++ .../cloudstack/agent/api/NsxCommand.java | 3 + .../cloudstack/resource/NsxResource.java | 1 - .../apache/cloudstack/service/NsxElement.java | 5 +- .../service/NsxGuestNetworkGuru.java | 17 +- .../service/NsxProviderServiceImpl.java | 3 - .../cloudstack/service/NsxServiceImpl.java | 4 +- .../cloudstack/resource/NsxResourceTest.java | 163 ++++++++++++++ .../cloudstack/service/NsxElementTest.java | 135 ++++++++++++ .../service/NsxGuestNetworkGuruTest.java | 206 ++++++++++++++++++ .../service/NsxProviderServiceImplTest.java | 158 ++++++++++++++ .../service/NsxServiceImplTest.java | 94 ++++++++ .../vmware/mo/HypervisorHostHelperTest.java | 44 ++++ 14 files changed, 869 insertions(+), 25 deletions(-) create mode 100644 plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/resource/NsxResourceTest.java create mode 100644 plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/service/NsxElementTest.java create mode 100644 plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/service/NsxGuestNetworkGuruTest.java create mode 100644 plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/service/NsxProviderServiceImplTest.java create mode 100644 plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/service/NsxServiceImplTest.java diff --git a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java index f49a7b2d113..2c203fbd324 100755 --- a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java @@ -1474,7 +1474,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac } } - private void setVmNetworkDetails(VMInstanceVO vm, VirtualMachineTO vmTO) { + public void setVmNetworkDetails(VMInstanceVO vm, VirtualMachineTO vmTO) { if (VirtualMachine.Type.User.equals(vm.getType())) { List userVmJoinVOs = userVmJoinDao.searchByIds(vm.getId()); Map networkToNetworkNameMap = new HashMap<>(); diff --git a/engine/orchestration/src/test/java/com/cloud/vm/VirtualMachineManagerImplTest.java b/engine/orchestration/src/test/java/com/cloud/vm/VirtualMachineManagerImplTest.java index 15a2f2c0ac1..4082aeb5844 100644 --- a/engine/orchestration/src/test/java/com/cloud/vm/VirtualMachineManagerImplTest.java +++ b/engine/orchestration/src/test/java/com/cloud/vm/VirtualMachineManagerImplTest.java @@ -35,6 +35,18 @@ import java.util.Map; import java.util.Random; import java.util.stream.Collectors; +import com.cloud.agent.api.to.VirtualMachineTO; +import com.cloud.api.query.vo.UserVmJoinVO; +import com.cloud.dc.DataCenterVO; +import com.cloud.dc.dao.DataCenterDao; +import com.cloud.domain.DomainVO; +import com.cloud.domain.dao.DomainDao; +import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.NetworkVO; +import com.cloud.network.vpc.VpcVO; +import com.cloud.network.vpc.dao.VpcDao; +import com.cloud.user.AccountVO; +import com.cloud.user.dao.AccountDao; import org.apache.cloudstack.engine.subsystem.api.storage.StoragePoolAllocator; import org.apache.cloudstack.framework.config.ConfigKey; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; @@ -155,6 +167,16 @@ public class VirtualMachineManagerImplTest { private UserVmDao userVmDaoMock; @Mock private UserVmVO userVmMock; + @Mock + private NetworkDao networkDao; + @Mock + private AccountDao accountDao; + @Mock + private DomainDao domainDao; + @Mock + private DataCenterDao dcDao; + @Mock + private VpcDao vpcDao; @Before public void setup() { @@ -895,4 +917,41 @@ public class VirtualMachineManagerImplTest { map.put(Mockito.mock(Volume.class), pool2); virtualMachineManagerImpl.checkAndAttemptMigrateVmAcrossCluster(vm, destinationClusterId, map); } + + @Test + public void checkIfVmNetworkDetailsReturnedIsCorrect() { + VMInstanceVO vm = new VMInstanceVO(1L, 1L, "VM1", "i-2-2-VM", + VirtualMachine.Type.User, 1L, HypervisorType.KVM, 1L, 1L, 1L, + 1L, false, false); + + VirtualMachineTO vmTO = new VirtualMachineTO() {}; + UserVmJoinVO userVm = new UserVmJoinVO(); + NetworkVO networkVO = new NetworkVO(); + AccountVO accountVO = new AccountVO(); + DomainVO domainVO = new DomainVO(); + domainVO.setName("testDomain"); + DataCenterVO dataCenterVO = mock(DataCenterVO.class); + VpcVO vpcVO = new VpcVO(); + + networkVO.setAccountId(1L); + networkVO.setName("testNet"); + networkVO.setVpcId(1L); + + accountVO.setAccountName("testAcc"); + + vpcVO.setName("VPC1"); + + + List userVms = List.of(userVm); + Mockito.when(userVmJoinDaoMock.searchByIds(anyLong())).thenReturn(userVms); + Mockito.when(networkDao.findById(anyLong())).thenReturn(networkVO); + Mockito.when(accountDao.findById(anyLong())).thenReturn(accountVO); + Mockito.when(domainDao.findById(anyLong())).thenReturn(domainVO); + Mockito.when(dcDao.findById(anyLong())).thenReturn(dataCenterVO); + Mockito.when(vpcDao.findById(anyLong())).thenReturn(vpcVO); + Mockito.when(dataCenterVO.getName()).thenReturn("testZone"); + virtualMachineManagerImpl.setVmNetworkDetails(vm, vmTO); + assertEquals(vmTO.getNetworkIdToNetworkNameMap().size(), 1); + assertEquals(vmTO.getNetworkIdToNetworkNameMap().get(0L), "testDomain-testAcc-testZone-VPC1-testNet"); + } } diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/NsxCommand.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/NsxCommand.java index 539f8c06729..2ee88fa3ec0 100644 --- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/NsxCommand.java +++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/NsxCommand.java @@ -25,6 +25,9 @@ public class NsxCommand extends Command { private String accountName; private String domainName; + public NsxCommand() { + } + public NsxCommand(String domainName, String accountName, String zoneName) { this.zoneName = zoneName; this.accountName = accountName; 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 cece0aa0d08..1c1765cb4af 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 @@ -71,7 +71,6 @@ public class NsxResource implements ServerResource { public Host.Type getType() { return Host.Type.Routing; } - @Override public StartupCommand[] initialize() { StartupNsxCommand sc = new StartupNsxCommand(); 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 b0f38831c93..5c5ba1ac35c 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 @@ -100,7 +100,7 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, DnsS @Inject NetworkModel networkModel; @Inject - private DomainDao domainDao; + DomainDao domainDao; private static final Logger LOGGER = Logger.getLogger(NsxElement.class); @@ -117,7 +117,6 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, DnsS dnsCapabilities.put(Network.Capability.AllowDnsSuffixModification, "true"); capabilities.put(Network.Service.Dns, dnsCapabilities); -// capabilities.put(Network.Service.Connectivity, null); capabilities.put(Network.Service.StaticNat, null); Map sourceNatCapabilities = new HashMap<>(); @@ -234,7 +233,7 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, DnsS public boolean configure(String name, Map params) throws ConfigurationException { agentManager.registerForHostEvents(this, true, true, true); resourceManager.registerResourceStateAdapter(this.getClass().getSimpleName(), this); - return false; + return true; } @Override diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxGuestNetworkGuru.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxGuestNetworkGuru.java index 29d335d3cde..e5b80fbe82c 100644 --- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxGuestNetworkGuru.java +++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxGuestNetworkGuru.java @@ -20,7 +20,6 @@ import static java.util.Objects.isNull; import static java.util.Objects.nonNull; import com.cloud.dc.DataCenter; -import com.cloud.dc.dao.DataCenterDao; import com.cloud.deploy.DeployDestination; import com.cloud.deploy.DeploymentPlan; import com.cloud.domain.DomainVO; @@ -66,11 +65,9 @@ public class NsxGuestNetworkGuru extends GuestNetworkGuru implements NetworkMigr @Inject NsxControllerUtils nsxControllerUtils; @Inject - DataCenterDao zoneDao; - @Inject AccountDao accountDao; @Inject - private DomainDao domainDao; + DomainDao domainDao; public NsxGuestNetworkGuru() { super(); @@ -138,7 +135,7 @@ public class NsxGuestNetworkGuru extends GuestNetworkGuru implements NetworkMigr implemented.setBroadcastUri(Networks.BroadcastDomainType.NSX.toUri("nsx")); try { long zoneId = network.getDataCenterId(); - DataCenter zone = zoneDao.findById(zoneId); + DataCenter zone = _dcDao.findById(zoneId); if (isNull(zone)) { throw new CloudRuntimeException(String.format("Failed to find zone with id: %s", zoneId)); } @@ -179,16 +176,6 @@ public class NsxGuestNetworkGuru extends GuestNetworkGuru implements NetworkMigr implemented.setName(network.getName()); } implemented.setBroadcastUri(Networks.BroadcastDomainType.NSX.toUri("nsx")); -// try { -// long zoneId = network.getDataCenterId(); -// DataCenter zone = zoneDao.findById(zoneId); -// if (isNull(zone)) { -// throw new CloudRuntimeException(String.format("Failed to find zone with id: %s", zoneId)); -// } -// createNsxSegment(implemented, zone); -// } catch (Exception ex) { -// throw new CloudRuntimeException("unable to create NSX network " + network.getUuid() + "due to: " + ex.getMessage()); -// } return implemented; } diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxProviderServiceImpl.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxProviderServiceImpl.java index 00069e49e45..78239b01cc2 100644 --- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxProviderServiceImpl.java +++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxProviderServiceImpl.java @@ -53,9 +53,6 @@ import java.util.Map; import java.util.Objects; import java.util.UUID; - - - public class NsxProviderServiceImpl implements NsxProviderService { @Inject diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxServiceImpl.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxServiceImpl.java index 45369f4cdbf..6552c335b98 100644 --- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxServiceImpl.java +++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxServiceImpl.java @@ -30,9 +30,9 @@ import java.util.Objects; public class NsxServiceImpl implements NsxService { @Inject - private NsxControllerUtils nsxControllerUtils; + NsxControllerUtils nsxControllerUtils; @Inject - private VpcDao vpcDao; + VpcDao vpcDao; public boolean createVpcNetwork(Long zoneId, String zoneName, String accountName, String domainName, String vpcName) { CreateNsxTier1GatewayCommand createNsxTier1GatewayCommand = diff --git a/plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/resource/NsxResourceTest.java b/plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/resource/NsxResourceTest.java new file mode 100644 index 00000000000..511b257ecaa --- /dev/null +++ b/plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/resource/NsxResourceTest.java @@ -0,0 +1,163 @@ +// 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.resource; + +import com.cloud.network.dao.NetworkVO; +import com.vmware.nsx.model.TransportZone; +import com.vmware.nsx.model.TransportZoneListResult; +import com.vmware.nsx_policy.model.EnforcementPoint; +import com.vmware.nsx_policy.model.EnforcementPointListResult; +import com.vmware.nsx_policy.model.Site; +import com.vmware.nsx_policy.model.SiteListResult; +import junit.framework.Assert; +import org.apache.cloudstack.NsxAnswer; +import org.apache.cloudstack.agent.api.CreateNsxSegmentCommand; +import org.apache.cloudstack.agent.api.CreateNsxTier1GatewayCommand; +import org.apache.cloudstack.agent.api.DeleteNsxSegmentCommand; +import org.apache.cloudstack.agent.api.DeleteNsxTier1GatewayCommand; +import org.apache.cloudstack.agent.api.NsxCommand; +import org.apache.cloudstack.service.NsxApiClient; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.junit.MockitoJUnitRunner; + +import javax.naming.ConfigurationException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertThrows; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class NsxResourceTest { + + @Mock + NsxApiClient nsxApi; + + NsxResource nsxResource; + AutoCloseable closeable; + @Mock + EnforcementPointListResult enforcementPointListResult; + @Mock + SiteListResult siteListResult; + @Mock + TransportZoneListResult transportZoneListResult; + + @Before + public void setup() { + closeable = MockitoAnnotations.openMocks(this); + nsxResource = new NsxResource(); + nsxResource.nsxApiClient = nsxApi; + nsxResource.transportZone = "Overlay"; + } + + @After + public void tearDown() throws Exception { + closeable.close(); + } + + @Test + public void testConfigure() throws ConfigurationException { + Map params = new HashMap<>(); + params.put("name", "nsxController"); + params.put("guid", "5944b356-644f-11ee-b8c2-f37bc1b564ff"); + params.put("zoneId", "1"); + params.put("hostname", "host1"); + params.put("username", "admin"); + params.put("password", "password"); + params.put("tier0Gateway", "Tier0-GW01"); + params.put("edgeCluster", "EdgeCluster"); + params.put("transportZone", "Overlay"); + params.put("port", "443"); + + Assert.assertTrue(nsxResource.configure("nsx", params)); + } + + @Test + public void testConfigure_MissingParameter() throws ConfigurationException { + Map params = new HashMap<>(); + + assertThrows(ConfigurationException.class, () -> nsxResource.configure("nsx", params)); + } + + @Test + public void testCreateNsxTier1Gateway() { + NsxCommand command = new CreateNsxTier1GatewayCommand("testDomain", "testAcc", + "ZoneNSX", "VPC01"); + + NsxAnswer answer = (NsxAnswer) nsxResource.executeRequest(command); + assertTrue(answer.getResult()); + } + + @Test + public void testDeleteTier1Gateway() { + NsxCommand command = new DeleteNsxTier1GatewayCommand("testDomain", "testAcc", + "ZoneNSX", "VPC01"); + + NsxAnswer answer = (NsxAnswer) nsxResource.executeRequest(command); + assertTrue(answer.getResult()); + } + + @Test + public void testCreateNsxSegment() { + NetworkVO tierNetwork = new NetworkVO(); + tierNetwork.setName("tier1"); + tierNetwork.setCidr("10.0.0.0/8"); + tierNetwork.setGateway("10.0.0.1"); + Site site = mock(Site.class); + List siteList = List.of(site); + EnforcementPoint enforcementPoint = mock(EnforcementPoint.class); + List enforcementPointList = List.of(enforcementPoint); + List transportZoneList = List.of(new TransportZone.Builder().setDisplayName("Overlay").build()); + + NsxCommand command = new CreateNsxSegmentCommand("testDomain", "testAcc", + "ZoneNSX", "VPC01", "Web", "10.10.10.1", "10.10.10.0/24"); + + when(nsxApi.getSites()).thenReturn(siteListResult); + when(siteListResult.getResults()).thenReturn(siteList); + when(siteList.get(0).getId()).thenReturn("site1"); + + when(nsxApi.getEnforcementPoints(anyString())).thenReturn(enforcementPointListResult); + when(enforcementPointListResult.getResults()).thenReturn(enforcementPointList); + when(enforcementPointList.get(0).getPath()).thenReturn("enforcementPointPath"); + + when(nsxApi.getTransportZones()).thenReturn(transportZoneListResult); + when(transportZoneListResult.getResults()).thenReturn(transportZoneList); + + NsxAnswer answer = (NsxAnswer) nsxResource.executeRequest(command); + assertTrue(answer.getResult()); + } + + @Test + public void testDeleteNsxSegment() { + NetworkVO tierNetwork = new NetworkVO(); + tierNetwork.setName("tier1"); + DeleteNsxSegmentCommand command = new DeleteNsxSegmentCommand("testDomain", "testAcc", "ZoneA", "VPC01", "Web"); + + NsxAnswer answer = (NsxAnswer) nsxResource.executeRequest(command); + assertTrue(answer.getResult()); + } +} diff --git a/plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/service/NsxElementTest.java b/plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/service/NsxElementTest.java new file mode 100644 index 00000000000..b43229a62a4 --- /dev/null +++ b/plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/service/NsxElementTest.java @@ -0,0 +1,135 @@ +// 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.cloud.dc.DataCenterVO; +import com.cloud.dc.dao.DataCenterDao; +import com.cloud.deploy.DeployDestination; +import com.cloud.domain.DomainVO; +import com.cloud.domain.dao.DomainDao; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.NetworkModel; +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.Vpc; +import com.cloud.resource.ResourceManager; +import com.cloud.user.Account; +import com.cloud.user.AccountManager; +import com.cloud.vm.ReservationContext; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import java.util.List; + +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class NsxElementTest { + + @Mock + DataCenterDao dataCenterDao; + @Mock + NsxServiceImpl nsxService; + @Mock + AccountManager accountManager; + @Mock + NetworkDao networkDao; + @Mock + ResourceManager resourceManager; + @Mock + PhysicalNetworkDao physicalNetworkDao; + @Mock + NetworkModel networkModel; + @Mock + Vpc vpc; + @Mock + DataCenterVO zone; + @Mock + DataCenterVO dataCenterVO; + @Mock + Account account; + @Mock + DomainVO domain; + + NsxElement nsxElement; + ReservationContext reservationContext; + DeployDestination deployDestination; + @Mock + DomainDao domainDao; + + @Before + public void setup() { + nsxElement = new NsxElement(); + + nsxElement.dataCenterDao = dataCenterDao; + nsxElement.nsxService = nsxService; + nsxElement.accountMgr = accountManager; + nsxElement.networkDao = networkDao; + nsxElement.resourceManager = resourceManager; + nsxElement.physicalNetworkDao = physicalNetworkDao; + nsxElement.domainDao = domainDao; + nsxElement.networkModel = networkModel; + reservationContext = mock(ReservationContext.class); + deployDestination = mock(DeployDestination.class); + + when(vpc.getZoneId()).thenReturn(1L); + when(vpc.getAccountId()).thenReturn(2L); + when(dataCenterVO.getId()).thenReturn(1L); + when(dataCenterVO.getName()).thenReturn("zoneNSX"); + when(account.getName()).thenReturn("testAcc"); + when(vpc.getName()).thenReturn("VPC01"); + when(accountManager.getAccount(2L)).thenReturn(account); + when(dataCenterDao.findById(anyLong())).thenReturn(dataCenterVO); + when(domainDao.findById(anyLong())).thenReturn(domain); + when(vpc.getZoneId()).thenReturn(1L); + when(domain.getName()).thenReturn("testDomain"); + when(vpc.getName()).thenReturn("testVPC"); + + PhysicalNetworkVO physicalNetworkVO = new PhysicalNetworkVO(); + physicalNetworkVO.setIsolationMethods(List.of("NSX")); + List physicalNetworkVOList = List.of(physicalNetworkVO); + + when(physicalNetworkDao.listByZoneAndTrafficType(1L, Networks.TrafficType.Guest)).thenReturn(physicalNetworkVOList); + } + + @Test + public void testImplementVpc() throws ResourceUnavailableException, InsufficientCapacityException { + when(nsxService.createVpcNetwork(anyLong(), anyString(), anyString(), anyString(), anyString())).thenReturn(true); + + assertTrue(nsxElement.implementVpc(vpc, deployDestination, reservationContext)); + } + + @Test + public void testShutdownVpc() { + when(nsxService.deleteVpcNetwork(anyLong(), anyString(), anyString(), anyString(), anyString())).thenReturn(true); + + assertTrue(nsxElement.shutdownVpc(vpc, reservationContext)); + } + + + +} diff --git a/plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/service/NsxGuestNetworkGuruTest.java b/plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/service/NsxGuestNetworkGuruTest.java new file mode 100644 index 00000000000..fca3406ac79 --- /dev/null +++ b/plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/service/NsxGuestNetworkGuruTest.java @@ -0,0 +1,206 @@ +// 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.cloud.dc.DataCenter; +import com.cloud.dc.DataCenterVO; +import com.cloud.dc.dao.DataCenterDao; +import com.cloud.deploy.DeployDestination; +import com.cloud.deploy.DeploymentPlan; +import com.cloud.domain.DomainVO; +import com.cloud.domain.dao.DomainDao; +import com.cloud.network.Network; +import com.cloud.network.NetworkModel; +import com.cloud.network.Networks; +import com.cloud.network.dao.PhysicalNetworkDao; +import com.cloud.network.dao.PhysicalNetworkVO; +import com.cloud.network.vpc.VpcVO; +import com.cloud.network.vpc.dao.VpcDao; +import com.cloud.offering.NetworkOffering; +import com.cloud.offerings.dao.NetworkOfferingServiceMapDao; +import com.cloud.user.Account; +import com.cloud.user.AccountVO; +import com.cloud.user.dao.AccountDao; +import com.cloud.vm.ReservationContext; +import org.apache.cloudstack.NsxAnswer; +import org.apache.cloudstack.agent.api.CreateNsxSegmentCommand; +import org.apache.cloudstack.agent.api.NsxCommand; +import org.apache.cloudstack.utils.NsxControllerUtils; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentMatchers; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.mockito.junit.MockitoJUnitRunner; +import org.springframework.test.util.ReflectionTestUtils; + +import java.util.List; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.when; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.lenient; + +@RunWith(MockitoJUnitRunner.class) +public class NsxGuestNetworkGuruTest { + + @Mock + PhysicalNetworkDao physicalNetworkDao; + @Mock + DataCenterDao dcDao; + @Mock + VpcDao vpcDao; + @Mock + NetworkOfferingServiceMapDao networkOfferingServiceMapDao; + @Mock + NsxControllerUtils nsxControllerUtils; + @Mock + DataCenterDao zoneDao; + @Mock + AccountDao accountDao; + @Mock + PhysicalNetworkVO physicalNetwork; + @Mock + DataCenterVO dataCenterVO; + @Mock + NetworkOffering offering; + @Mock + DeploymentPlan plan; + @Mock + Network network; + @Mock + Account account; + @Mock + VpcVO vpcVO; + @Mock + NetworkModel networkModel; + @Mock + DomainDao domainDao; + + NsxGuestNetworkGuru guru; + AutoCloseable closeable; + + @Before + public void setUp() { + closeable = MockitoAnnotations.openMocks(this); + guru = new NsxGuestNetworkGuru(); + ReflectionTestUtils.setField(guru, "_physicalNetworkDao", physicalNetworkDao); + ReflectionTestUtils.setField(guru, "_dcDao", dcDao); + ReflectionTestUtils.setField(guru, "_networkModel", networkModel); + ReflectionTestUtils.setField(guru, "_vpcDao", vpcDao); + + guru.networkOfferingServiceMapDao = networkOfferingServiceMapDao; + guru.nsxControllerUtils = nsxControllerUtils; + guru.accountDao = accountDao; + guru.domainDao = domainDao; + + Mockito.when(dataCenterVO.getNetworkType()).thenReturn(DataCenter.NetworkType.Advanced); + + when(physicalNetwork.getIsolationMethods()).thenReturn(List.of("NSX")); + + when(offering.getTrafficType()).thenReturn(Networks.TrafficType.Guest); + when(offering.getGuestType()).thenReturn(Network.GuestType.Isolated); + when(offering.getId()).thenReturn(1L); + + when(plan.getDataCenterId()).thenReturn(1L); + when(plan.getPhysicalNetworkId()).thenReturn(1L); + + when(vpcDao.findById(anyLong())).thenReturn(vpcVO); + + when(vpcVO.getName()).thenReturn("VPC01"); + + when(account.getAccountId()).thenReturn(1L); + when(accountDao.findById(anyLong())).thenReturn(mock(AccountVO.class)); + when(domainDao.findById(anyLong())).thenReturn(mock(DomainVO.class)); + + Mockito.when(networkOfferingServiceMapDao.isProviderForNetworkOffering(offering.getId(), Network.Provider.Nsx)).thenReturn( + true); + } + + @After + public void tearDown() throws Exception { + closeable.close(); + } + + @Test + public void testIsMyIsolationMethod() { + assertTrue(guru.isMyIsolationMethod(physicalNetwork)); + } + + @Test + public void testCanHandle() { + assertTrue(guru.canHandle(offering, dataCenterVO.getNetworkType(), physicalNetwork)); + } + + @Test + public void testNsxNetworkDesign() { + when(physicalNetworkDao.findById(ArgumentMatchers.anyLong())).thenReturn(physicalNetwork); + when(dcDao.findById(ArgumentMatchers.anyLong())).thenReturn(dataCenterVO); + when(nsxControllerUtils.sendNsxCommand(any(CreateNsxSegmentCommand.class), anyLong())).thenReturn( + new NsxAnswer(new NsxCommand(), true, "")); + + Network designedNetwork = guru.design(offering, plan, network, "", 1L, account); + verify(nsxControllerUtils, times(1)).sendNsxCommand(any(CreateNsxSegmentCommand.class), anyLong()); + assertNotNull(designedNetwork); + assertSame(Networks.BroadcastDomainType.NSX, designedNetwork.getBroadcastDomainType()); + assertSame(Network.State.Allocated, designedNetwork.getState()); + } + + @Test + public void testNsxNetworkImplementation() { + final DeployDestination deployDestination = mock(DeployDestination.class); + final ReservationContext reservationContext = mock(ReservationContext.class); + + when(network.getTrafficType()).thenReturn(Networks.TrafficType.Guest); + when(network.getMode()).thenReturn(Networks.Mode.Dhcp); + when(network.getGateway()).thenReturn("192.168.1.1"); + when(network.getCidr()).thenReturn("192.168.1.0/24"); + when(network.getBroadcastDomainType()).thenReturn(Networks.BroadcastDomainType.NSX); + when(network.getNetworkOfferingId()).thenReturn(1L); + lenient().when(network.getState()).thenReturn(Network.State.Implementing); + when(network.getDataCenterId()).thenReturn(2L); + when(network.getPhysicalNetworkId()).thenReturn(3L); + when(network.getVpcId()).thenReturn(4L); + when(offering.isRedundantRouter()).thenReturn(false); + lenient().when(offering.getGuestType()).thenReturn(Network.GuestType.Isolated); + + + final Network implemented = guru.implement(network, offering, deployDestination, reservationContext); + assertEquals(Networks.BroadcastDomainType.NSX.toUri("nsx"), implemented.getBroadcastUri()); + assertEquals("192.168.1.1", implemented.getGateway()); + assertEquals("192.168.1.0/24", implemented.getCidr()); + assertEquals(Networks.Mode.Dhcp, implemented.getMode()); + assertEquals(Networks.BroadcastDomainType.NSX, implemented.getBroadcastDomainType()); + assertEquals(1L, implemented.getNetworkOfferingId()); + assertEquals(Network.State.Implemented, implemented.getState()); + assertEquals(2L, implemented.getDataCenterId()); + assertEquals(3L, implemented.getPhysicalNetworkId().longValue()); + assertEquals(4L, implemented.getVpcId().longValue()); + assertFalse(implemented.isRedundant()); + } +} diff --git a/plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/service/NsxProviderServiceImplTest.java b/plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/service/NsxProviderServiceImplTest.java new file mode 100644 index 00000000000..97717ac1524 --- /dev/null +++ b/plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/service/NsxProviderServiceImplTest.java @@ -0,0 +1,158 @@ +// 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.cloud.dc.DataCenterVO; +import com.cloud.dc.dao.DataCenterDao; +import com.cloud.host.Host; +import com.cloud.host.dao.HostDetailsDao; +import com.cloud.network.NsxProvider; +import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.NetworkVO; +import com.cloud.network.dao.NsxProviderDao; +import com.cloud.network.dao.PhysicalNetworkDao; +import com.cloud.network.dao.PhysicalNetworkVO; +import com.cloud.network.element.NsxProviderVO; +import com.cloud.resource.ResourceManager; +import com.cloud.resource.ServerResource; +import com.cloud.utils.exception.CloudRuntimeException; +import org.apache.cloudstack.api.BaseResponse; +import org.apache.cloudstack.api.command.AddNsxControllerCmd; +import org.apache.cloudstack.api.response.NsxControllerResponse; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; + +import java.util.List; +import java.util.UUID; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.anyMap; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class NsxProviderServiceImplTest { + @Mock + NsxProviderDao nsxProviderDao; + @Mock + DataCenterDao dataCenterDao; + @Mock + PhysicalNetworkDao physicalNetworkDao; + @Mock + NetworkDao networkDao; + @Mock + ResourceManager resourceManager; + @Mock + HostDetailsDao hostDetailsDao; + + NsxProviderServiceImpl nsxProviderService; + + @Before + public void setup() { + nsxProviderService = new NsxProviderServiceImpl(); + nsxProviderService.resourceManager = resourceManager; + nsxProviderService.nsxProviderDao = nsxProviderDao; + nsxProviderService.hostDetailsDao = hostDetailsDao; + nsxProviderService.dataCenterDao = dataCenterDao; + nsxProviderService.networkDao = networkDao; + nsxProviderService.physicalNetworkDao = physicalNetworkDao; + } + + @Test + public void testAddProvider() { + AddNsxControllerCmd cmd = mock(AddNsxControllerCmd.class); + when(cmd.getZoneId()).thenReturn(1L); + when(cmd.getName()).thenReturn("NsxController"); + when(cmd.getHostname()).thenReturn("192.168.0.100"); + when(cmd.getPort()).thenReturn("443"); + when(cmd.getUsername()).thenReturn("admin"); + when(cmd.getPassword()).thenReturn("password"); + when(cmd.getEdgeCluster()).thenReturn("EdgeCluster"); + when(cmd.getTier0Gateway()).thenReturn("Tier0-GW01"); + when(cmd.getTransportZone()).thenReturn("Overlay"); + when(resourceManager.addHost(anyLong(), any(ServerResource.class), any(Host.Type.class), anyMap())).thenReturn(mock(Host.class)); + try { + NsxProvider provider = nsxProviderService.addProvider(cmd); + Assert.assertNotNull(provider); + } catch (CloudRuntimeException e) { + e.printStackTrace(); + fail("Failed to add NSX controller due to internal error."); + } + } + + @Test + public void testCreateNsxControllerResponse() { + NsxProvider nsxProvider = mock(NsxProvider.class); + DataCenterVO zone = mock(DataCenterVO.class); + String uuid = UUID.randomUUID().toString(); + when(dataCenterDao.findById(anyLong())).thenReturn(zone); + when(zone.getUuid()).thenReturn(UUID.randomUUID().toString()); + when(zone.getName()).thenReturn("ZoneNSX"); + when(nsxProvider.getProviderName()).thenReturn("NSXController"); + when(nsxProvider.getUuid()).thenReturn(uuid); + when(nsxProvider.getHostname()).thenReturn("hostname"); + when(nsxProvider.getPort()).thenReturn("443"); + when(nsxProvider.getTier0Gateway()).thenReturn("Tier0Gw"); + when(nsxProvider.getEdgeCluster()).thenReturn("EdgeCluster"); + when(nsxProvider.getTransportZone()).thenReturn("Overlay"); + + NsxControllerResponse response = nsxProviderService.createNsxControllerResponse(nsxProvider); + + assertEquals(response.getEdgeCluster(), "EdgeCluster"); + assertEquals(response.getTier0Gateway(), "Tier0Gw"); + assertEquals(response.getTransportZone(), "Overlay"); + assertEquals(response.getZoneName(), "ZoneNSX"); + } + + @Test + public void testListNsxControllers() { + NsxProviderVO nsxProviderVO = Mockito.mock(NsxProviderVO.class); + + when(nsxProviderVO.getZoneId()).thenReturn(1L); + when(dataCenterDao.findById(1L)).thenReturn(mock(DataCenterVO.class)); + when(nsxProviderDao.findByZoneId(anyLong())).thenReturn(nsxProviderVO); + + List baseResponseList = nsxProviderService.listNsxProviders(1L); + assertEquals(1, baseResponseList.size()); + } + + @Test + public void testDeleteNsxController() { + NsxProviderVO nsxProviderVO = Mockito.mock(NsxProviderVO.class); + PhysicalNetworkVO physicalNetworkVO = mock(PhysicalNetworkVO.class); + List physicalNetworkVOList = List.of(physicalNetworkVO); + NetworkVO networkVO = mock(NetworkVO.class); + List networkVOList = List.of(networkVO); + + when(nsxProviderVO.getZoneId()).thenReturn(1L); + when(physicalNetworkVO.getId()).thenReturn(2L); + when(physicalNetworkDao.listByZone(1L)).thenReturn(physicalNetworkVOList); + when(nsxProviderDao.findById(anyLong())).thenReturn(nsxProviderVO); + when(networkDao.listByPhysicalNetwork(anyLong())).thenReturn(networkVOList); + + assertTrue(nsxProviderService.deleteNsxController(1L)); + } +} diff --git a/plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/service/NsxServiceImplTest.java b/plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/service/NsxServiceImplTest.java new file mode 100644 index 00000000000..0a0836090d9 --- /dev/null +++ b/plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/service/NsxServiceImplTest.java @@ -0,0 +1,94 @@ +// 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.cloud.network.dao.NetworkVO; +import com.cloud.network.vpc.VpcVO; +import com.cloud.network.vpc.dao.VpcDao; +import org.apache.cloudstack.NsxAnswer; +import org.apache.cloudstack.agent.api.CreateNsxTier1GatewayCommand; +import org.apache.cloudstack.agent.api.DeleteNsxSegmentCommand; +import org.apache.cloudstack.agent.api.DeleteNsxTier1GatewayCommand; +import org.apache.cloudstack.utils.NsxControllerUtils; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.junit.MockitoJUnitRunner; + +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class NsxServiceImplTest { + @Mock + private NsxControllerUtils nsxControllerUtils; + @Mock + private VpcDao vpcDao; + NsxServiceImpl nsxService; + + AutoCloseable closeable; + + @Before + public void setup() { + closeable = MockitoAnnotations.openMocks(this); + nsxService = new NsxServiceImpl(); + nsxService.nsxControllerUtils = nsxControllerUtils; + nsxService.vpcDao = vpcDao; + } + + @After + public void teardown() throws Exception { + closeable.close(); + } + + @Test + public void testCreateVpcNetwork() { + NsxAnswer createNsxTier1GatewayAnswer = mock(NsxAnswer.class); + when(nsxControllerUtils.sendNsxCommand(any(CreateNsxTier1GatewayCommand.class), anyLong())).thenReturn(createNsxTier1GatewayAnswer); + when(createNsxTier1GatewayAnswer.getResult()).thenReturn(true); + + assertTrue(nsxService.createVpcNetwork(1L, "ZoneNSX", "testAcc", "testAcc", "VPC01")); + } + + @Test + public void testDeleteVpcNetwork() { + NsxAnswer deleteNsxTier1GatewayAnswer = mock(NsxAnswer.class); + when(nsxControllerUtils.sendNsxCommand(any(DeleteNsxTier1GatewayCommand.class), anyLong())).thenReturn(deleteNsxTier1GatewayAnswer); + when(deleteNsxTier1GatewayAnswer.getResult()).thenReturn(true); + + assertTrue(nsxService.deleteVpcNetwork(1L, "ZoneNSX", "testAcc", "testAcc", "VPC01")); + } + + @Test + public void testDelete() { + NetworkVO network = new NetworkVO(); + network.setVpcId(1L); + VpcVO vpc = mock(VpcVO.class); + when(vpcDao.findById(1L)).thenReturn(mock(VpcVO.class)); + NsxAnswer deleteNsxSegmentAnswer = mock(NsxAnswer.class); + when(nsxControllerUtils.sendNsxCommand(any(DeleteNsxSegmentCommand.class), anyLong())).thenReturn(deleteNsxSegmentAnswer); + when(deleteNsxSegmentAnswer.getResult()).thenReturn(true); + + assertTrue(nsxService.deleteNetwork("ZoneNSX", "testAcc", "testDomain", network)); + } +} diff --git a/vmware-base/src/test/java/com/cloud/hypervisor/vmware/mo/HypervisorHostHelperTest.java b/vmware-base/src/test/java/com/cloud/hypervisor/vmware/mo/HypervisorHostHelperTest.java index 1c888a05748..026c84b886d 100644 --- a/vmware-base/src/test/java/com/cloud/hypervisor/vmware/mo/HypervisorHostHelperTest.java +++ b/vmware-base/src/test/java/com/cloud/hypervisor/vmware/mo/HypervisorHostHelperTest.java @@ -21,14 +21,24 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.nullable; +import static org.mockito.ArgumentMatchers.anyList; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.when; import java.util.HashMap; +import java.util.List; import java.util.Map; +import com.cloud.hypervisor.vmware.util.VmwareClient; +import com.cloud.network.Networks; +import com.cloud.utils.Pair; +import com.vmware.vim25.DynamicProperty; +import com.vmware.vim25.ManagedObjectReference; +import com.vmware.vim25.ObjectContent; +import com.vmware.vim25.VimPortType; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; @@ -61,6 +71,10 @@ public class HypervisorHostHelperTest { @Mock VmwareContext context; @Mock + ManagedObjectReference mor; + @Mock + VmwareClient vmwareClient; + @Mock DVPortgroupConfigInfo currentDvPortgroupInfo; @Mock DVPortgroupConfigSpec dvPortgroupConfigSpec; @@ -78,6 +92,12 @@ public class HypervisorHostHelperTest { private ClusterConfigInfoEx clusterConfigInfo; @Mock private DatacenterConfigInfo datacenterConfigInfo; + @Mock + HostMO hostMO; + @Mock + VimPortType vimService; + @Mock + ObjectContent ocs; String vSwitchName; Integer networkRateMbps; @@ -90,6 +110,10 @@ public class HypervisorHostHelperTest { @Before public void setup() throws Exception { closeable = MockitoAnnotations.openMocks(this); + ObjectContent oc = new ObjectContent(); + when(hostMO.getContext()).thenReturn(context); + when(context.getService()).thenReturn(vimService); + when(context.getVimClient()).thenReturn(vmwareClient); when(context.getServiceContent()).thenReturn(serviceContent); when(serviceContent.getAbout()).thenReturn(aboutInfo); when(clusterMO.getClusterConfigInfo()).thenReturn(clusterConfigInfo); @@ -947,4 +971,24 @@ public class HypervisorHostHelperTest { HypervisorHostHelper.setVMHardwareVersion(vmSpec, clusterMO, datacenterMO); verify(vmSpec, never()).setVersion(any()); } + + @Test + public void testPrepareNetwork() throws Exception { + String networkName = "testAcc-VPC1-tier1"; + DynamicProperty property = new DynamicProperty(); + property.setVal(networkName); + + when(hostMO.getHyperHostDatacenter()).thenReturn(mor); + when(datacenterMO.getDvSwitchMor(any(String.class))).thenReturn(mor); + when(vmwareClient.getDecendentMoRef(nullable(ManagedObjectReference.class), any(String.class), any(String.class))).thenReturn(mor); + when(vimService.retrieveProperties(any(), anyList())).thenReturn(List.of(ocs)); + when(ocs.getPropSet()).thenReturn(List.of(property)); + when(ocs.getObj()).thenReturn(mor); + + Pair morNet = HypervisorHostHelper.prepareNetwork("NSX-VDS", "cloud.guest", hostMO, null, null, + 200, null, 900000, VirtualSwitchType.VMwareDistributedVirtualSwitch, 1, null, + false, Networks.BroadcastDomainType.NSX, null, + null, networkName); + assertEquals(morNet.second(), networkName); + } } From 69ded800e9961081c2ed8390b0de899f364869b6 Mon Sep 17 00:00:00 2001 From: Pearl Dsilva Date: Mon, 23 Oct 2023 11:31:30 -0400 Subject: [PATCH 4/5] modify NSX resource naming convention (#8095) * modify NSX resource naming convention * remove unused imports * add a setup phase between desgin and implementation of a network for intermediary steps * add method to all classes --- .../com/cloud/network/guru/NetworkGuru.java | 2 ++ .../cloud/vm/VirtualMachineManagerImpl.java | 18 +++++++++-- .../orchestration/NetworkOrchestrator.java | 1 + .../vm/VirtualMachineManagerImplTest.java | 16 ++++++---- .../contrail/management/ContrailGuru.java | 5 ++++ .../api/CreateNsxDhcpRelayConfigCommand.java | 19 ++++++++++-- .../agent/api/CreateNsxSegmentCommand.java | 19 ++++++++++-- .../api/CreateNsxTier1GatewayCommand.java | 10 +++++-- .../agent/api/DeleteNsxSegmentCommand.java | 18 +++++++++-- .../api/DeleteNsxTier1GatewayCommand.java | 10 +++++-- .../cloudstack/agent/api/NsxCommand.java | 30 +++++++++---------- .../cloudstack/resource/NsxResource.java | 27 +++++++++-------- .../cloudstack/service/NsxApiClient.java | 10 +++---- .../apache/cloudstack/service/NsxElement.java | 8 ++--- .../service/NsxGuestNetworkGuru.java | 10 +++++-- .../cloudstack/service/NsxServiceImpl.java | 13 ++++---- .../cloudstack/utils/NsxControllerUtils.java | 24 +++++++-------- .../apache/cloudstack/utils/NsxHelper.java | 8 ++--- .../cloudstack/resource/NsxResourceTest.java | 14 ++++----- .../cloudstack/service/NsxElementTest.java | 7 ++--- .../service/NsxGuestNetworkGuruTest.java | 21 +++++++++---- .../service/NsxServiceImplTest.java | 6 ++-- .../cloud/hypervisor/HypervisorGuruBase.java | 20 +++++++++---- .../network/guru/ControlNetworkGuru.java | 5 ++++ .../cloud/network/guru/DirectNetworkGuru.java | 5 ++++ .../cloud/network/guru/GuestNetworkGuru.java | 5 ++++ .../network/guru/PodBasedNetworkGuru.java | 5 ++++ .../network/guru/PrivateNetworkGuru.java | 5 ++++ .../cloud/network/guru/PublicNetworkGuru.java | 5 ++++ .../vmware/mo/HypervisorHostHelperTest.java | 2 +- 30 files changed, 241 insertions(+), 107 deletions(-) diff --git a/api/src/main/java/com/cloud/network/guru/NetworkGuru.java b/api/src/main/java/com/cloud/network/guru/NetworkGuru.java index a0e856daea5..cbadbb18a8f 100644 --- a/api/src/main/java/com/cloud/network/guru/NetworkGuru.java +++ b/api/src/main/java/com/cloud/network/guru/NetworkGuru.java @@ -96,6 +96,8 @@ public interface NetworkGuru extends Adapter { */ Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, String name, Long vpcId, Account owner); + void setup(Network network, long networkId); + /** * For guest networks that are in Allocated state after the design stage, * resources are allocated when the guest network is actually being used diff --git a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java index 2c203fbd324..5feb1099673 100755 --- a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java @@ -1484,12 +1484,24 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac Account acc = accountDao.findById(networkVO.getAccountId()); Domain domain = domainDao.findById(networkVO.getDomainId()); DataCenter zone = _dcDao.findById(vm.getDataCenterId()); - String networkName = domain.getName() + "-" + acc.getAccountName() + "-" + zone.getName() + "-"; + if (Objects.isNull(zone)) { + throw new CloudRuntimeException(String.format("Failed to find zone with ID: %s", vm.getDataCenterId())); + } + if (Objects.isNull(acc)) { + throw new CloudRuntimeException(String.format("Failed to find account with ID: %s", networkVO.getAccountId())); + } + if (Objects.isNull(domain)) { + throw new CloudRuntimeException(String.format("Failed to find domain with ID: %s", networkVO.getDomainId())); + } + String networkName = String.format("D%s-A%s-Z%s", domain.getId(), acc.getId(), zone.getId()); if (Objects.isNull(networkVO.getVpcId())) { - networkName += networkVO.getName(); + networkName += "-S"+networkVO.getId(); } else { VpcVO vpc = vpcDao.findById(networkVO.getVpcId()); - networkName += (vpc.getName() + "-" + networkVO.getName()); + if (Objects.isNull(vpc)) { + throw new CloudRuntimeException(String.format("Failed to find VPC with ID: %s", networkVO.getVpcId())); + } + networkName = String.format("%s-V%s-S%s", networkName, vpc.getId(), networkVO.getId()); } networkToNetworkNameMap.put(networkVO.getId(), networkName); } diff --git a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java index 3231930de44..70176ebb29f 100644 --- a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java +++ b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java @@ -812,6 +812,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra } } }); + guru.setup(network, relatedFile); } if (networks.size() < 1) { diff --git a/engine/orchestration/src/test/java/com/cloud/vm/VirtualMachineManagerImplTest.java b/engine/orchestration/src/test/java/com/cloud/vm/VirtualMachineManagerImplTest.java index 4082aeb5844..1e7cc124643 100644 --- a/engine/orchestration/src/test/java/com/cloud/vm/VirtualMachineManagerImplTest.java +++ b/engine/orchestration/src/test/java/com/cloud/vm/VirtualMachineManagerImplTest.java @@ -926,12 +926,12 @@ public class VirtualMachineManagerImplTest { VirtualMachineTO vmTO = new VirtualMachineTO() {}; UserVmJoinVO userVm = new UserVmJoinVO(); - NetworkVO networkVO = new NetworkVO(); - AccountVO accountVO = new AccountVO(); - DomainVO domainVO = new DomainVO(); + NetworkVO networkVO = mock(NetworkVO.class); + AccountVO accountVO = mock(AccountVO.class); + DomainVO domainVO = mock(DomainVO.class); domainVO.setName("testDomain"); DataCenterVO dataCenterVO = mock(DataCenterVO.class); - VpcVO vpcVO = new VpcVO(); + VpcVO vpcVO = mock(VpcVO.class); networkVO.setAccountId(1L); networkVO.setName("testNet"); @@ -949,9 +949,13 @@ public class VirtualMachineManagerImplTest { Mockito.when(domainDao.findById(anyLong())).thenReturn(domainVO); Mockito.when(dcDao.findById(anyLong())).thenReturn(dataCenterVO); Mockito.when(vpcDao.findById(anyLong())).thenReturn(vpcVO); - Mockito.when(dataCenterVO.getName()).thenReturn("testZone"); + Mockito.when(dataCenterVO.getId()).thenReturn(1L); + when(accountVO.getId()).thenReturn(2L); + Mockito.when(domainVO.getId()).thenReturn(3L); + Mockito.when(vpcVO.getId()).thenReturn(4L); + Mockito.when(networkVO.getId()).thenReturn(5L); virtualMachineManagerImpl.setVmNetworkDetails(vm, vmTO); assertEquals(vmTO.getNetworkIdToNetworkNameMap().size(), 1); - assertEquals(vmTO.getNetworkIdToNetworkNameMap().get(0L), "testDomain-testAcc-testZone-VPC1-testNet"); + assertEquals(vmTO.getNetworkIdToNetworkNameMap().get(5L), "D3-A2-Z1-V4-S5"); } } diff --git a/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailGuru.java b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailGuru.java index bae6e8664a8..9b7d835dce3 100644 --- a/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailGuru.java +++ b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailGuru.java @@ -138,6 +138,11 @@ public class ContrailGuru extends AdapterBase implements NetworkGuru { return network; } + @Override + public void setup(Network network, long networkId) { + // do nothing + } + @Override public Network implement(Network network, NetworkOffering offering, DeployDestination destination, ReservationContext context) throws InsufficientVirtualNetworkCapacityException { diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/CreateNsxDhcpRelayConfigCommand.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/CreateNsxDhcpRelayConfigCommand.java index 44c21885d2f..5b986628628 100644 --- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/CreateNsxDhcpRelayConfigCommand.java +++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/CreateNsxDhcpRelayConfigCommand.java @@ -20,22 +20,35 @@ import java.util.List; public class CreateNsxDhcpRelayConfigCommand extends NsxCommand { + private Long vpcId; private String vpcName; + private long networkId; private String networkName; private List addresses; - public CreateNsxDhcpRelayConfigCommand(String domainName, String accountName, String zoneName, - String vpcName, String networkName, List addresses) { - super(domainName, accountName, zoneName); + public CreateNsxDhcpRelayConfigCommand(long domainId, long accountId, long zoneId, + Long vpcId, String vpcName, long networkId, String networkName, + List addresses) { + super(domainId, accountId, zoneId); + this.vpcId = vpcId; this.vpcName = vpcName; + this.networkId = networkId; this.networkName = networkName; this.addresses = addresses; } + public Long getVpcId() { + return vpcId; + } + public String getVpcName() { return vpcName; } + public long getNetworkId() { + return networkId; + } + public String getNetworkName() { return networkName; } diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/CreateNsxSegmentCommand.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/CreateNsxSegmentCommand.java index b9c8fba4ff8..b4b86bd640a 100644 --- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/CreateNsxSegmentCommand.java +++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/CreateNsxSegmentCommand.java @@ -20,24 +20,37 @@ import java.util.Objects; public class CreateNsxSegmentCommand extends NsxCommand { + private Long vpcId; private String vpcName; + private long networkId; private String networkName; private String networkGateway; private String networkCidr; - public CreateNsxSegmentCommand(String domainName, String accountName, String zoneName, - String vpcName, String networkName, String networkGateway, String networkCidr) { - super(domainName, accountName, zoneName); + public CreateNsxSegmentCommand(long domainId, long accountId, long zoneId, + Long vpcId, String vpcName, long networkId, String networkName, + String networkGateway, String networkCidr) { + super(domainId, accountId, zoneId); + this.vpcId = vpcId; this.vpcName = vpcName; + this.networkId = networkId; this.networkName = networkName; this.networkGateway = networkGateway; this.networkCidr = networkCidr; } + public Long getVpcId() { + return vpcId; + } + public String getVpcName() { return vpcName; } + public long getNetworkId() { + return networkId; + } + public String getNetworkName() { return networkName; } diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/CreateNsxTier1GatewayCommand.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/CreateNsxTier1GatewayCommand.java index 385bfd17c21..02616585f98 100644 --- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/CreateNsxTier1GatewayCommand.java +++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/CreateNsxTier1GatewayCommand.java @@ -19,13 +19,19 @@ package org.apache.cloudstack.agent.api; import java.util.Objects; public class CreateNsxTier1GatewayCommand extends NsxCommand { + private long vpcId; private String vpcName; - public CreateNsxTier1GatewayCommand(String domainName, String accountName, String zoneName, String vpcName) { - super(domainName, accountName, zoneName); + public CreateNsxTier1GatewayCommand(long domainId, long accountId, long zoneId, long vpcId, String vpcName) { + super(domainId, accountId, zoneId); + this.vpcId = vpcId; this.vpcName = vpcName; } + public long getVpcId() { + return vpcId; + } + public String getVpcName() { return vpcName; } diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/DeleteNsxSegmentCommand.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/DeleteNsxSegmentCommand.java index fa5fe8b2c05..06af4d8c31d 100644 --- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/DeleteNsxSegmentCommand.java +++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/DeleteNsxSegmentCommand.java @@ -18,19 +18,33 @@ package org.apache.cloudstack.agent.api; public class DeleteNsxSegmentCommand extends NsxCommand { + private Long vpcId; private String vpcName; + + private long networkId; private String networkName; - public DeleteNsxSegmentCommand(String domainName, String accountName, String zoneName, String vpcName, String networkName) { - super(domainName, accountName, zoneName); + public DeleteNsxSegmentCommand(long domainId, long accountId, long zoneId, Long vpcId, + String vpcName, long networkId, String networkName) { + super(domainId, accountId, zoneId); + this.vpcId = vpcId; this.vpcName = vpcName; + this.networkId = networkId; this.networkName = networkName; } + public Long getVpcId() { + return vpcId; + } + public String getVpcName() { return vpcName; } + public long getNetworkId() { + return networkId; + } + public String getNetworkName() { return networkName; } diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/DeleteNsxTier1GatewayCommand.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/DeleteNsxTier1GatewayCommand.java index d3890542313..3b684f28487 100644 --- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/DeleteNsxTier1GatewayCommand.java +++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/DeleteNsxTier1GatewayCommand.java @@ -18,13 +18,19 @@ package org.apache.cloudstack.agent.api; public class DeleteNsxTier1GatewayCommand extends NsxCommand { + private Long vpcId; private String vpcName; - public DeleteNsxTier1GatewayCommand(String domainName, String accountName, String zoneName, String vpcName) { - super(domainName, accountName, zoneName); + public DeleteNsxTier1GatewayCommand(long domainId, long accountId, long zoneId, Long vpcId, String vpcName) { + super(domainId, accountId, zoneId); + this.vpcId = vpcId; this.vpcName = vpcName; } + public Long getVpcId() { + return vpcId; + } + public String getVpcName() { return vpcName; } diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/NsxCommand.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/NsxCommand.java index 2ee88fa3ec0..7c5e3a1d9fa 100644 --- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/NsxCommand.java +++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/NsxCommand.java @@ -21,29 +21,29 @@ import com.cloud.agent.api.Command; import java.util.Objects; public class NsxCommand extends Command { - private String zoneName; - private String accountName; - private String domainName; + private long zoneId; + private long accountId; + private long domainId; public NsxCommand() { } - public NsxCommand(String domainName, String accountName, String zoneName) { - this.zoneName = zoneName; - this.accountName = accountName; - this.domainName = domainName; + public NsxCommand(long domainId, long accountId, long zoneId) { + this.zoneId = zoneId; + this.accountId = accountId; + this.domainId = domainId; } - public String getZoneName() { - return zoneName; + public long getZoneId() { + return zoneId; } - public String getAccountName() { - return accountName; + public long getAccountId() { + return accountId; } - public String getDomainName() { - return domainName; + public long getDomainId() { + return domainId; } @Override @@ -57,11 +57,11 @@ public class NsxCommand extends Command { if (o == null || getClass() != o.getClass()) return false; if (!super.equals(o)) return false; NsxCommand that = (NsxCommand) o; - return Objects.equals(zoneName, that.zoneName) && Objects.equals(accountName, that.accountName) && Objects.equals(domainName, that.domainName); + return Objects.equals(zoneId, that.zoneId) && Objects.equals(accountId, that.accountId) && Objects.equals(domainId, that.domainId); } @Override public int hashCode() { - return Objects.hash(super.hashCode(), zoneName, accountName, domainName); + return Objects.hash(super.hashCode(), zoneId, accountId, domainId); } } 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 1c1765cb4af..ad5ea2b7067 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 @@ -210,14 +210,16 @@ public class NsxResource implements ServerResource { } private Answer executeRequest(CreateNsxDhcpRelayConfigCommand cmd) { - String zoneName = cmd.getZoneName(); - String domainName = cmd.getDomainName(); - String accountName = cmd.getAccountName(); + long zoneId = cmd.getZoneId(); + long domainId = cmd.getDomainId(); + long accountId = cmd.getAccountId(); + long vpcId = cmd.getVpcId(); + long networkId = cmd.getNetworkId(); String vpcName = cmd.getVpcName(); String networkName = cmd.getNetworkName(); List addresses = cmd.getAddresses(); - String dhcpRelayConfigName = NsxControllerUtils.getNsxDhcpRelayConfigId(zoneName, domainName, accountName, vpcName, networkName); + String dhcpRelayConfigName = NsxControllerUtils.getNsxDhcpRelayConfigId(zoneId, domainId, accountId, vpcId, networkId); String msg = String.format("Creating DHCP relay config with name %s on network %s of VPC %s", dhcpRelayConfigName, networkName, vpcName); @@ -231,7 +233,7 @@ public class NsxResource implements ServerResource { return new NsxAnswer(cmd, e); } - String segmentName = NsxControllerUtils.getNsxSegmentId(domainName, accountName, zoneName, vpcName, networkName); + String segmentName = NsxControllerUtils.getNsxSegmentId(domainId, accountId, zoneId, vpcId, networkId); String dhcpConfigPath = String.format("%s/%s", DHCP_RELAY_CONFIGS_PATH_PREFIX, dhcpRelayConfigName); try { Segment segment = nsxApiClient.getSegmentById(segmentName); @@ -251,18 +253,18 @@ public class NsxResource implements ServerResource { } private Answer executeRequest(CreateNsxTier1GatewayCommand cmd) { - String name = NsxControllerUtils.getTier1GatewayName(cmd.getDomainName(), cmd.getAccountName(), cmd.getZoneName(), cmd.getVpcName()); + String name = NsxControllerUtils.getTier1GatewayName(cmd.getDomainId(), cmd.getAccountId(), cmd.getZoneId(), cmd.getVpcId()); try { nsxApiClient.createTier1Gateway(name, tier0Gateway, edgeCluster); return new NsxAnswer(cmd, true, ""); } catch (CloudRuntimeException e) { - LOGGER.error(String.format("Cannot create tier 1 gateway %s: %s", name, e.getMessage())); + LOGGER.error(String.format("Cannot create tier 1 gateway %s (VPC: %s): %s", name, cmd.getVpcName(), e.getMessage())); return new NsxAnswer(cmd, e); } } private Answer executeRequest(DeleteNsxTier1GatewayCommand cmd) { - String tier1Id = NsxControllerUtils.getTier1GatewayName(cmd.getDomainName(), cmd.getAccountName(), cmd.getZoneName(), cmd.getVpcName()); + String tier1Id = NsxControllerUtils.getTier1GatewayName(cmd.getDomainId(), cmd.getAccountId(), cmd.getZoneId(), cmd.getVpcId()); try { nsxApiClient.deleteTier1Gateway(tier1Id); } catch (Exception e) { @@ -304,10 +306,10 @@ public class NsxResource implements ServerResource { return new NsxAnswer(cmd, new CloudRuntimeException(errorMsg)); } - String segmentName = NsxControllerUtils.getNsxSegmentId(cmd.getDomainName(), cmd.getAccountName(), cmd.getZoneName(), cmd.getVpcName(), networkName); + String segmentName = NsxControllerUtils.getNsxSegmentId(cmd.getDomainId(), cmd.getAccountId(), cmd.getZoneId(), cmd.getVpcId(), cmd.getNetworkId()); String gatewayAddress = cmd.getNetworkGateway() + "/" + cmd.getNetworkCidr().split("/")[1]; - nsxApiClient.createSegment(cmd.getZoneName(), cmd.getDomainName(), cmd.getAccountName(), cmd.getVpcName(), + nsxApiClient.createSegment(cmd.getZoneId(), cmd.getDomainId(), cmd.getAccountId(), cmd.getVpcId(), segmentName, gatewayAddress, tier0Gateway, enforcementPointPath, transportZones); } catch (Exception e) { LOGGER.error(String.format("Failed to create network: %s", cmd.getNetworkName())); @@ -317,10 +319,11 @@ public class NsxResource implements ServerResource { } private NsxAnswer executeRequest(DeleteNsxSegmentCommand cmd) { - String segmentName = NsxControllerUtils.getNsxSegmentId(cmd.getDomainName(), cmd.getAccountName(), cmd.getZoneName(), cmd.getVpcName(), cmd.getNetworkName()); + String segmentName = NsxControllerUtils.getNsxSegmentId(cmd.getDomainId(), cmd.getAccountId(), cmd.getZoneId(), + cmd.getVpcId(), cmd.getNetworkId()); try { Thread.sleep(30*1000); - nsxApiClient.deleteSegment(cmd.getZoneName(), cmd.getDomainName(), cmd.getAccountName(), cmd.getVpcName(), cmd.getNetworkName(), segmentName); + nsxApiClient.deleteSegment(cmd.getZoneId(), cmd.getDomainId(), cmd.getAccountId(), cmd.getVpcId(), cmd.getNetworkId(), segmentName); } catch (Exception e) { LOGGER.error(String.format("Failed to delete NSX segment: %s", segmentName)); return new NsxAnswer(cmd, new CloudRuntimeException(e.getMessage())); 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 348a0d0b62c..973650db09c 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 @@ -249,7 +249,7 @@ public class NsxApiClient { } } - public void createSegment(String zoneName, String domainName, String accountName, String vpcName, String segmentName, String gatewayAddress, String tier0Gateway, String enforcementPointPath, List transportZones) { + public void createSegment(long zoneId, long domainId, long accountId, Long vpcId, String segmentName, String gatewayAddress, String tier0Gateway, String enforcementPointPath, List transportZones) { try { Segments segmentService = (Segments) nsxService.apply(Segments.class); SegmentSubnet subnet = new SegmentSubnet.Builder() @@ -259,8 +259,8 @@ public class NsxApiClient { .setResourceType(SEGMENT_RESOURCE_TYPE) .setId(segmentName) .setDisplayName(segmentName) - .setConnectivityPath(isNull(vpcName) ? TIER_0_GATEWAY_PATH_PREFIX + tier0Gateway - : TIER_1_GATEWAY_PATH_PREFIX + NsxControllerUtils.getTier1GatewayName(domainName, accountName, zoneName, vpcName)) + .setConnectivityPath(isNull(vpcId) ? TIER_0_GATEWAY_PATH_PREFIX + tier0Gateway + : TIER_1_GATEWAY_PATH_PREFIX + NsxControllerUtils.getTier1GatewayName(domainId, accountId, zoneId, vpcId)) .setAdminState(AdminState.UP.name()) .setSubnets(List.of(subnet)) .setTransportZonePath(enforcementPointPath + "/transport-zones/" + transportZones.get(0).getId()) @@ -274,13 +274,13 @@ public class NsxApiClient { } } - public void deleteSegment(String zoneName, String domainName, String accountName, String vpcName, String networkName, String segmentName) { + public void deleteSegment(long zoneId, long domainId, long accountId, long vpcId, long networkId, String segmentName) { try { Segments segmentService = (Segments) nsxService.apply(Segments.class); LOGGER.debug(String.format("Removing the segment with ID %s", segmentName)); segmentService.delete(segmentName); DhcpRelayConfigs dhcpRelayConfig = (DhcpRelayConfigs) nsxService.apply(DhcpRelayConfigs.class); - String dhcpRelayConfigId = NsxControllerUtils.getNsxDhcpRelayConfigId(zoneName, domainName, accountName, vpcName, networkName); + String dhcpRelayConfigId = NsxControllerUtils.getNsxDhcpRelayConfigId(zoneId, domainId, accountId, vpcId, networkId); LOGGER.debug(String.format("Removing the DHCP relay config with ID %s", dhcpRelayConfigId)); dhcpRelayConfig.delete(dhcpRelayConfigId); } catch (Error error) { 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 5c5ba1ac35c..b01700cfe2c 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 @@ -202,11 +202,11 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, DnsS DataCenterVO zone = dataCenterDao.findById(network.getDataCenterId()); DomainVO domain = domainDao.findById(account.getDomainId()); if (Objects.isNull(zone)) { - String msg = String.format("Cannot fing zone with ID %s", network.getDataCenterId()); + String msg = String.format("Cannot find zone with ID %s", network.getDataCenterId()); LOGGER.error(msg); throw new CloudRuntimeException(msg); } - return nsxService.deleteNetwork(zone.getName(), account.getAccountName(), domain.getName(), networkVO); + return nsxService.deleteNetwork(zone.getId(), account.getId(), domain.getId(), networkVO); } @Override @@ -287,7 +287,7 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, DnsS } Account account = isNsxAndAccount.second(); DomainVO domain = getDomainFromAccount(account); - return nsxService.createVpcNetwork(vpc.getZoneId(), zone.getName(), account.getName(), domain.getName(), vpc.getName()); + return nsxService.createVpcNetwork(vpc.getZoneId(), account.getId(), domain.getId(), vpc.getId(), vpc.getName()); } @Override @@ -302,7 +302,7 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, DnsS } Account account = isNsxAndAccount.second(); DomainVO domain = getDomainFromAccount(account); - return nsxService.deleteVpcNetwork(vpc.getZoneId(), zone.getName(), account.getName(), domain.getName(), vpc.getName()); + return nsxService.deleteVpcNetwork(vpc.getZoneId(), account.getId(), domain.getId(), vpc.getId(), vpc.getName()); } private Pair validateVpcConfigurationAndGetAccount(DataCenterVO zone, Vpc vpc) { diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxGuestNetworkGuru.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxGuestNetworkGuru.java index e5b80fbe82c..70102ec8295 100644 --- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxGuestNetworkGuru.java +++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxGuestNetworkGuru.java @@ -133,17 +133,23 @@ public class NsxGuestNetworkGuru extends GuestNetworkGuru implements NetworkMigr implemented.setName(name); } implemented.setBroadcastUri(Networks.BroadcastDomainType.NSX.toUri("nsx")); + + return network; + } + + @Override + public void setup(Network network, long networkId) { try { + NetworkVO designedNetwork = _networkDao.findById(networkId); long zoneId = network.getDataCenterId(); DataCenter zone = _dcDao.findById(zoneId); if (isNull(zone)) { throw new CloudRuntimeException(String.format("Failed to find zone with id: %s", zoneId)); } - createNsxSegment(implemented, zone); + createNsxSegment(designedNetwork, zone); } catch (Exception ex) { throw new CloudRuntimeException("unable to create NSX network " + network.getUuid() + "due to: " + ex.getMessage()); } - return network; } @Override diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxServiceImpl.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxServiceImpl.java index 6552c335b98..999f28bde25 100644 --- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxServiceImpl.java +++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxServiceImpl.java @@ -34,27 +34,28 @@ public class NsxServiceImpl implements NsxService { @Inject VpcDao vpcDao; - public boolean createVpcNetwork(Long zoneId, String zoneName, String accountName, String domainName, String vpcName) { + public boolean createVpcNetwork(Long zoneId, long accountId, long domainId, long vpcId, String vpcName) { CreateNsxTier1GatewayCommand createNsxTier1GatewayCommand = - new CreateNsxTier1GatewayCommand(domainName, accountName, zoneName, vpcName); + new CreateNsxTier1GatewayCommand(domainId, accountId, zoneId, vpcId, vpcName); NsxAnswer result = nsxControllerUtils.sendNsxCommand(createNsxTier1GatewayCommand, zoneId); return result.getResult(); } - public boolean deleteVpcNetwork(Long zoneId, String zoneName, String accountName, String domainName, String vpcName) { + public boolean deleteVpcNetwork(Long zoneId, long accountId, long domainId, Long vpcId, String vpcName) { DeleteNsxTier1GatewayCommand deleteNsxTier1GatewayCommand = - new DeleteNsxTier1GatewayCommand(domainName, accountName, zoneName, vpcName); + new DeleteNsxTier1GatewayCommand(domainId, accountId, zoneId, vpcId, vpcName); NsxAnswer result = nsxControllerUtils.sendNsxCommand(deleteNsxTier1GatewayCommand, zoneId); return result.getResult(); } - public boolean deleteNetwork(String zoneName, String accountName, String domainName, NetworkVO network) { + public boolean deleteNetwork(long zoneId, long accountId, long domainId, NetworkVO network) { String vpcName = null; if (Objects.nonNull(network.getVpcId())) { VpcVO vpc = vpcDao.findById(network.getVpcId()); vpcName = Objects.nonNull(vpc) ? vpc.getName() : null; } - DeleteNsxSegmentCommand deleteNsxSegmentCommand = new DeleteNsxSegmentCommand(domainName, accountName, zoneName, vpcName, network.getName()); + DeleteNsxSegmentCommand deleteNsxSegmentCommand = new DeleteNsxSegmentCommand(domainId, accountId, zoneId, + network.getVpcId(), vpcName, network.getId(), network.getName()); NsxAnswer result = nsxControllerUtils.sendNsxCommand(deleteNsxSegmentCommand, network.getDataCenterId()); return result.getResult(); } diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/utils/NsxControllerUtils.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/utils/NsxControllerUtils.java index 27a07bac3f3..bef09bb0d55 100644 --- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/utils/NsxControllerUtils.java +++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/utils/NsxControllerUtils.java @@ -56,23 +56,23 @@ public class NsxControllerUtils { return (NsxAnswer) answer; } - public static String getTier1GatewayName(String domainName, String accountName, String zoneName, String vpcName) { - return String.format("%s-%s-%s-%s", domainName, accountName, zoneName, vpcName); + public static String getTier1GatewayName(long domainId, long accountId, long zoneId, long vpcId) { + return String.format("D%s-A%s-Z%s-V%s", domainId, accountId, zoneId, vpcId); } - public static String getNsxSegmentId(String domainName, String accountName, String zoneName, String vpcName, String tierNetworkName) { - String segmentName = String.format("%s-%s-%s-", domainName, accountName, zoneName); - if (isNull(vpcName)) { - return segmentName + tierNetworkName; + public static String getNsxSegmentId(long domainId, long accountId, long zoneId, Long vpcId, long networkId) { + String segmentName = String.format("D%s-A%s-Z%s", domainId, accountId, zoneId); + if (isNull(vpcId)) { + return String.format("%s-S%s", segmentName, networkId); } - return segmentName + vpcName + "-" + tierNetworkName; + return String.format("%s-V%s-S%s",segmentName, vpcId, networkId); } - public static String getNsxDhcpRelayConfigId(String zoneName, String domainName, String accountName, String vpcName, String networkName) { - String suffix = "-Relay"; - if (isNull(vpcName)) { - return domainName + "-" + accountName + "-" + zoneName + "-" +networkName + suffix; + public static String getNsxDhcpRelayConfigId(long zoneId, long domainId, long accountId, Long vpcId, long networkId) { + String suffix = "Relay"; + if (isNull(vpcId)) { + return String.format("D%s-A%s-Z%s-S%s-%s", domainId, accountId, zoneId, networkId, suffix); } - return String.format("%s-%s-%s-%s-%s%s", domainName, accountName, zoneName, vpcName, networkName, suffix); + return String.format("D%s-A%s-Z%s-V%s-S%s-%s", domainId, accountId, zoneId, vpcId, networkId, suffix); } } diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/utils/NsxHelper.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/utils/NsxHelper.java index 31329fa7ee4..ec1b74cf475 100644 --- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/utils/NsxHelper.java +++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/utils/NsxHelper.java @@ -30,12 +30,12 @@ import java.util.List; public class NsxHelper { public static CreateNsxDhcpRelayConfigCommand createNsxDhcpRelayConfigCommand(DomainVO domain, Account account, DataCenter zone, VpcVO vpc, Network network, List addresses) { - return new CreateNsxDhcpRelayConfigCommand(domain.getName(), account.getAccountName(), zone.getName(), - vpc.getName(), network.getName(), addresses); + return new CreateNsxDhcpRelayConfigCommand(domain.getId(), account.getId(), zone.getId(), + vpc.getId(), vpc.getName(), network.getId(), network.getName(), addresses); } public static CreateNsxSegmentCommand createNsxSegmentCommand(DomainVO domain, Account account, DataCenter zone, String vpcName, NetworkVO networkVO) { - return new CreateNsxSegmentCommand(domain.getName(), account.getAccountName(), zone.getName(), - vpcName, networkVO.getName(), networkVO.getGateway(), networkVO.getCidr()); + return new CreateNsxSegmentCommand(domain.getId(), account.getId(), zone.getId(), + networkVO.getVpcId(), vpcName, networkVO.getId(), networkVO.getName(), networkVO.getGateway(), networkVO.getCidr()); } } diff --git a/plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/resource/NsxResourceTest.java b/plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/resource/NsxResourceTest.java index 511b257ecaa..9e1a98c854d 100644 --- a/plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/resource/NsxResourceTest.java +++ b/plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/resource/NsxResourceTest.java @@ -105,8 +105,8 @@ public class NsxResourceTest { @Test public void testCreateNsxTier1Gateway() { - NsxCommand command = new CreateNsxTier1GatewayCommand("testDomain", "testAcc", - "ZoneNSX", "VPC01"); + NsxCommand command = new CreateNsxTier1GatewayCommand(1L, 2L, + 1L, 3L, "VPC01"); NsxAnswer answer = (NsxAnswer) nsxResource.executeRequest(command); assertTrue(answer.getResult()); @@ -114,8 +114,8 @@ public class NsxResourceTest { @Test public void testDeleteTier1Gateway() { - NsxCommand command = new DeleteNsxTier1GatewayCommand("testDomain", "testAcc", - "ZoneNSX", "VPC01"); + NsxCommand command = new DeleteNsxTier1GatewayCommand(1L, 1L, + 1L, 2L, "VPC01"); NsxAnswer answer = (NsxAnswer) nsxResource.executeRequest(command); assertTrue(answer.getResult()); @@ -133,8 +133,8 @@ public class NsxResourceTest { List enforcementPointList = List.of(enforcementPoint); List transportZoneList = List.of(new TransportZone.Builder().setDisplayName("Overlay").build()); - NsxCommand command = new CreateNsxSegmentCommand("testDomain", "testAcc", - "ZoneNSX", "VPC01", "Web", "10.10.10.1", "10.10.10.0/24"); + NsxCommand command = new CreateNsxSegmentCommand(1L, 1L, + 1L, 2L, "VPC01", 3L, "Web", "10.10.10.1", "10.10.10.0/24"); when(nsxApi.getSites()).thenReturn(siteListResult); when(siteListResult.getResults()).thenReturn(siteList); @@ -155,7 +155,7 @@ public class NsxResourceTest { public void testDeleteNsxSegment() { NetworkVO tierNetwork = new NetworkVO(); tierNetwork.setName("tier1"); - DeleteNsxSegmentCommand command = new DeleteNsxSegmentCommand("testDomain", "testAcc", "ZoneA", "VPC01", "Web"); + DeleteNsxSegmentCommand command = new DeleteNsxSegmentCommand(1L, 1L, 1L, 3L, "VPC01", 2L, "Web"); NsxAnswer answer = (NsxAnswer) nsxResource.executeRequest(command); assertTrue(answer.getResult()); diff --git a/plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/service/NsxElementTest.java b/plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/service/NsxElementTest.java index b43229a62a4..79367a105b4 100644 --- a/plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/service/NsxElementTest.java +++ b/plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/service/NsxElementTest.java @@ -99,14 +99,11 @@ public class NsxElementTest { when(vpc.getZoneId()).thenReturn(1L); when(vpc.getAccountId()).thenReturn(2L); when(dataCenterVO.getId()).thenReturn(1L); - when(dataCenterVO.getName()).thenReturn("zoneNSX"); - when(account.getName()).thenReturn("testAcc"); when(vpc.getName()).thenReturn("VPC01"); when(accountManager.getAccount(2L)).thenReturn(account); when(dataCenterDao.findById(anyLong())).thenReturn(dataCenterVO); when(domainDao.findById(anyLong())).thenReturn(domain); when(vpc.getZoneId()).thenReturn(1L); - when(domain.getName()).thenReturn("testDomain"); when(vpc.getName()).thenReturn("testVPC"); PhysicalNetworkVO physicalNetworkVO = new PhysicalNetworkVO(); @@ -118,14 +115,14 @@ public class NsxElementTest { @Test public void testImplementVpc() throws ResourceUnavailableException, InsufficientCapacityException { - when(nsxService.createVpcNetwork(anyLong(), anyString(), anyString(), anyString(), anyString())).thenReturn(true); + when(nsxService.createVpcNetwork(anyLong(), anyLong(), anyLong(), anyLong(), anyString())).thenReturn(true); assertTrue(nsxElement.implementVpc(vpc, deployDestination, reservationContext)); } @Test public void testShutdownVpc() { - when(nsxService.deleteVpcNetwork(anyLong(), anyString(), anyString(), anyString(), anyString())).thenReturn(true); + when(nsxService.deleteVpcNetwork(anyLong(), anyLong(), anyLong(), anyLong(), anyString())).thenReturn(true); assertTrue(nsxElement.shutdownVpc(vpc, reservationContext)); } diff --git a/plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/service/NsxGuestNetworkGuruTest.java b/plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/service/NsxGuestNetworkGuruTest.java index fca3406ac79..c70945aaa5e 100644 --- a/plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/service/NsxGuestNetworkGuruTest.java +++ b/plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/service/NsxGuestNetworkGuruTest.java @@ -26,6 +26,8 @@ import com.cloud.domain.dao.DomainDao; import com.cloud.network.Network; import com.cloud.network.NetworkModel; import com.cloud.network.Networks; +import com.cloud.network.dao.NetworkDao; +import com.cloud.network.dao.NetworkVO; import com.cloud.network.dao.PhysicalNetworkDao; import com.cloud.network.dao.PhysicalNetworkVO; import com.cloud.network.vpc.VpcVO; @@ -80,8 +82,6 @@ public class NsxGuestNetworkGuruTest { @Mock NsxControllerUtils nsxControllerUtils; @Mock - DataCenterDao zoneDao; - @Mock AccountDao accountDao; @Mock PhysicalNetworkVO physicalNetwork; @@ -101,6 +101,8 @@ public class NsxGuestNetworkGuruTest { NetworkModel networkModel; @Mock DomainDao domainDao; + @Mock + NetworkDao networkDao; NsxGuestNetworkGuru guru; AutoCloseable closeable; @@ -111,6 +113,7 @@ public class NsxGuestNetworkGuruTest { guru = new NsxGuestNetworkGuru(); ReflectionTestUtils.setField(guru, "_physicalNetworkDao", physicalNetworkDao); ReflectionTestUtils.setField(guru, "_dcDao", dcDao); + ReflectionTestUtils.setField(guru, "_networkDao", networkDao); ReflectionTestUtils.setField(guru, "_networkModel", networkModel); ReflectionTestUtils.setField(guru, "_vpcDao", vpcDao); @@ -161,16 +164,24 @@ public class NsxGuestNetworkGuruTest { public void testNsxNetworkDesign() { when(physicalNetworkDao.findById(ArgumentMatchers.anyLong())).thenReturn(physicalNetwork); when(dcDao.findById(ArgumentMatchers.anyLong())).thenReturn(dataCenterVO); - when(nsxControllerUtils.sendNsxCommand(any(CreateNsxSegmentCommand.class), anyLong())).thenReturn( - new NsxAnswer(new NsxCommand(), true, "")); Network designedNetwork = guru.design(offering, plan, network, "", 1L, account); - verify(nsxControllerUtils, times(1)).sendNsxCommand(any(CreateNsxSegmentCommand.class), anyLong()); assertNotNull(designedNetwork); assertSame(Networks.BroadcastDomainType.NSX, designedNetwork.getBroadcastDomainType()); assertSame(Network.State.Allocated, designedNetwork.getState()); } + @Test + public void testNsxNetworkSetup() { + when(dcDao.findById(ArgumentMatchers.anyLong())).thenReturn(dataCenterVO); + when(networkDao.findById(ArgumentMatchers.anyLong())).thenReturn(mock(NetworkVO.class)); + when(nsxControllerUtils.sendNsxCommand(any(CreateNsxSegmentCommand.class), anyLong())).thenReturn( + new NsxAnswer(new NsxCommand(), true, "")); + + guru.setup(network, 1L); + verify(nsxControllerUtils, times(1)).sendNsxCommand(any(CreateNsxSegmentCommand.class), anyLong()); + } + @Test public void testNsxNetworkImplementation() { final DeployDestination deployDestination = mock(DeployDestination.class); diff --git a/plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/service/NsxServiceImplTest.java b/plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/service/NsxServiceImplTest.java index 0a0836090d9..effca9d4a30 100644 --- a/plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/service/NsxServiceImplTest.java +++ b/plugins/network-elements/nsx/src/test/java/org/apache/cloudstack/service/NsxServiceImplTest.java @@ -67,7 +67,7 @@ public class NsxServiceImplTest { when(nsxControllerUtils.sendNsxCommand(any(CreateNsxTier1GatewayCommand.class), anyLong())).thenReturn(createNsxTier1GatewayAnswer); when(createNsxTier1GatewayAnswer.getResult()).thenReturn(true); - assertTrue(nsxService.createVpcNetwork(1L, "ZoneNSX", "testAcc", "testAcc", "VPC01")); + assertTrue(nsxService.createVpcNetwork(1L, 3L, 2L, 5L, "VPC01")); } @Test @@ -76,7 +76,7 @@ public class NsxServiceImplTest { when(nsxControllerUtils.sendNsxCommand(any(DeleteNsxTier1GatewayCommand.class), anyLong())).thenReturn(deleteNsxTier1GatewayAnswer); when(deleteNsxTier1GatewayAnswer.getResult()).thenReturn(true); - assertTrue(nsxService.deleteVpcNetwork(1L, "ZoneNSX", "testAcc", "testAcc", "VPC01")); + assertTrue(nsxService.deleteVpcNetwork(1L, 2L, 3L, 10L, "VPC01")); } @Test @@ -89,6 +89,6 @@ public class NsxServiceImplTest { when(nsxControllerUtils.sendNsxCommand(any(DeleteNsxSegmentCommand.class), anyLong())).thenReturn(deleteNsxSegmentAnswer); when(deleteNsxSegmentAnswer.getResult()).thenReturn(true); - assertTrue(nsxService.deleteNetwork("ZoneNSX", "testAcc", "testDomain", network)); + assertTrue(nsxService.deleteNetwork(1L, 3L, 5L, network)); } } diff --git a/server/src/main/java/com/cloud/hypervisor/HypervisorGuruBase.java b/server/src/main/java/com/cloud/hypervisor/HypervisorGuruBase.java index 956ada691ae..85c51b67191 100644 --- a/server/src/main/java/com/cloud/hypervisor/HypervisorGuruBase.java +++ b/server/src/main/java/com/cloud/hypervisor/HypervisorGuruBase.java @@ -31,6 +31,7 @@ import com.cloud.network.vpc.VpcVO; import com.cloud.network.vpc.dao.VpcDao; import com.cloud.user.Account; import com.cloud.user.AccountManager; +import com.cloud.utils.exception.CloudRuntimeException; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.backup.Backup; import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; @@ -170,11 +171,20 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis Account account = accountManager.getAccount(network.getAccountId()); Domain domain = domainDao.findById(network.getDomainId()); DataCenter zone = dcDao.findById(network.getDataCenterId()); + if (Objects.isNull(zone)) { + throw new CloudRuntimeException(String.format("Failed to find zone with ID: %s", network.getDataCenterId())); + } + if (Objects.isNull(account)) { + throw new CloudRuntimeException(String.format("Failed to find account with ID: %s", network.getAccountId())); + } + if (Objects.isNull(domain)) { + throw new CloudRuntimeException(String.format("Failed to find domain with ID: %s", network.getDomainId())); + } VpcVO vpc = null; if (Objects.nonNull(network) && Objects.nonNull(network.getVpcId())) { vpc = vpcDao.findById(network.getVpcId()); } - to.setNetworkSegmentName(getNetworkName(zone.getName(), domain.getName(), account.getAccountName(), vpc, network.getName())); + to.setNetworkSegmentName(getNetworkName(zone.getId(), domain.getId(), account.getId(), vpc, network.getId())); // Workaround to make sure the TO has the UUID we need for Nicira integration NicVO nicVO = nicDao.findById(profile.getId()); @@ -203,12 +213,12 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis return to; } - private String getNetworkName(String zoneName, String domainName, String accountName, VpcVO vpc, String networkName) { - String prefix = String.format("%s-%s-%s", domainName, accountName, zoneName); + private String getNetworkName(long zoneId, long domainId, long accountId, VpcVO vpc, long networkId) { + String prefix = String.format("D%s-A%s-Z%s", domainId, accountId, zoneId); if (Objects.isNull(vpc)) { - return prefix + "-" + networkName; + return prefix + "-S" + networkId; } - return prefix + "-" + vpc.getName() + "-" + networkName; + return prefix + "-V" + vpc.getId() + "-S" + networkId; } diff --git a/server/src/main/java/com/cloud/network/guru/ControlNetworkGuru.java b/server/src/main/java/com/cloud/network/guru/ControlNetworkGuru.java index 11f629a16d9..76d1ec46d61 100644 --- a/server/src/main/java/com/cloud/network/guru/ControlNetworkGuru.java +++ b/server/src/main/java/com/cloud/network/guru/ControlNetworkGuru.java @@ -104,6 +104,11 @@ public class ControlNetworkGuru extends PodBasedNetworkGuru implements NetworkGu return config; } + @Override + public void setup(Network network, long networkId) { + // do nothing + } + protected ControlNetworkGuru() { super(); } diff --git a/server/src/main/java/com/cloud/network/guru/DirectNetworkGuru.java b/server/src/main/java/com/cloud/network/guru/DirectNetworkGuru.java index b5a88685ba0..0f7f31e6701 100644 --- a/server/src/main/java/com/cloud/network/guru/DirectNetworkGuru.java +++ b/server/src/main/java/com/cloud/network/guru/DirectNetworkGuru.java @@ -251,6 +251,11 @@ public class DirectNetworkGuru extends AdapterBase implements NetworkGuru { return config; } + @Override + public void setup(Network network, long networkId) { + // do nothing + } + protected DirectNetworkGuru() { super(); _isolationMethods = new IsolationMethod[] { new IsolationMethod("VLAN"), new IsolationMethod("VXLAN") }; diff --git a/server/src/main/java/com/cloud/network/guru/GuestNetworkGuru.java b/server/src/main/java/com/cloud/network/guru/GuestNetworkGuru.java index 420d458af6b..ce5af76bd3e 100644 --- a/server/src/main/java/com/cloud/network/guru/GuestNetworkGuru.java +++ b/server/src/main/java/com/cloud/network/guru/GuestNetworkGuru.java @@ -148,6 +148,11 @@ public abstract class GuestNetworkGuru extends AdapterBase implements NetworkGur _isolationMethods = null; } + @Override + public void setup(Network network, long networkId) { + // do nothing + } + private void updateNicIpv6(Network network, NicProfile nic, VirtualMachineProfile vm, DataCenter dc, boolean isGateway) throws InsufficientAddressCapacityException { boolean isIpv6Supported = networkOfferingDao.isIpv6Supported(network.getNetworkOfferingId()); if (!isIpv6Supported || nic.getIPv6Address() != null || network.getIp6Cidr() == null || network.getIp6Gateway() == null) { diff --git a/server/src/main/java/com/cloud/network/guru/PodBasedNetworkGuru.java b/server/src/main/java/com/cloud/network/guru/PodBasedNetworkGuru.java index 168209b1e4b..42ae12aad85 100644 --- a/server/src/main/java/com/cloud/network/guru/PodBasedNetworkGuru.java +++ b/server/src/main/java/com/cloud/network/guru/PodBasedNetworkGuru.java @@ -89,6 +89,11 @@ public class PodBasedNetworkGuru extends AdapterBase implements NetworkGuru { return config; } + @Override + public void setup(Network network, long networkId) { + // do nothing + } + protected PodBasedNetworkGuru() { super(); } diff --git a/server/src/main/java/com/cloud/network/guru/PrivateNetworkGuru.java b/server/src/main/java/com/cloud/network/guru/PrivateNetworkGuru.java index 14f9ebe773c..d6da50ed5c6 100644 --- a/server/src/main/java/com/cloud/network/guru/PrivateNetworkGuru.java +++ b/server/src/main/java/com/cloud/network/guru/PrivateNetworkGuru.java @@ -137,6 +137,11 @@ public class PrivateNetworkGuru extends AdapterBase implements NetworkGuru { return network; } + @Override + public void setup(Network network, long networkId) { + // do nothing + } + @Override public void deallocate(Network network, NicProfile nic, VirtualMachineProfile vm) { if (s_logger.isDebugEnabled()) { diff --git a/server/src/main/java/com/cloud/network/guru/PublicNetworkGuru.java b/server/src/main/java/com/cloud/network/guru/PublicNetworkGuru.java index 1c9654a2b45..5e157999357 100644 --- a/server/src/main/java/com/cloud/network/guru/PublicNetworkGuru.java +++ b/server/src/main/java/com/cloud/network/guru/PublicNetworkGuru.java @@ -115,6 +115,11 @@ public class PublicNetworkGuru extends AdapterBase implements NetworkGuru { } } + @Override + public void setup(Network network, long networkId) { + // do nothing + } + protected PublicNetworkGuru() { super(); } diff --git a/vmware-base/src/test/java/com/cloud/hypervisor/vmware/mo/HypervisorHostHelperTest.java b/vmware-base/src/test/java/com/cloud/hypervisor/vmware/mo/HypervisorHostHelperTest.java index 026c84b886d..f129ef75b4c 100644 --- a/vmware-base/src/test/java/com/cloud/hypervisor/vmware/mo/HypervisorHostHelperTest.java +++ b/vmware-base/src/test/java/com/cloud/hypervisor/vmware/mo/HypervisorHostHelperTest.java @@ -974,7 +974,7 @@ public class HypervisorHostHelperTest { @Test public void testPrepareNetwork() throws Exception { - String networkName = "testAcc-VPC1-tier1"; + String networkName = "D1-A2-Z2-V8-S3"; DynamicProperty property = new DynamicProperty(); property.setVal(networkName); From be2b8edd20757c2cdc59cedef45bec76823edb49 Mon Sep 17 00:00:00 2001 From: Pearl Dsilva Date: Mon, 23 Oct 2023 11:50:13 -0400 Subject: [PATCH 5/5] NSX: Refactor Network & VPC offering (#8110) * [NSX] Refactor API wrapper operations * Network offering changes for NSX * fix services and provider combination * address comments: rename param * update nsx_mode parameter --------- Co-authored-by: nvazquez --- .../com/cloud/network/vpc/VpcOffering.java | 7 +- .../network/vpc/VpcProvisioningService.java | 3 +- .../com/cloud/offering/NetworkOffering.java | 10 +- .../apache/cloudstack/api/ApiConstants.java | 1 + .../network/CreateNetworkOfferingCmd.java | 76 ++++- .../admin/vpc/CreateVPCOfferingCmd.java | 74 ++++- .../api/response/NetworkOfferingResponse.java | 8 + .../api/response/VpcOfferingResponse.java | 18 +- .../admin/vpc/CreateVPCOfferingCmdTest.java | 6 +- .../configuration/ConfigurationManager.java | 2 +- .../orchestration/NetworkOrchestrator.java | 20 +- .../com/cloud/network/vpc/VpcOfferingVO.java | 22 ++ .../cloud/offerings/NetworkOfferingVO.java | 12 + .../META-INF/db/schema-41810to41900.sql | 49 +++- .../management/ContrailManagerImpl.java | 6 +- .../apache/cloudstack/service/NsxElement.java | 6 +- .../service/NsxGuestNetworkGuru.java | 1 + .../java/com/cloud/api/ApiResponseHelper.java | 1 + .../api/query/dao/VpcOfferingJoinDaoImpl.java | 2 + .../api/query/vo/NetworkOfferingJoinVO.java | 13 + .../cloud/api/query/vo/VpcOfferingJoinVO.java | 16 + .../ConfigurationManagerImpl.java | 29 +- .../com/cloud/network/vpc/VpcManagerImpl.java | 66 ++++- .../cloud/server/ConfigurationServerImpl.java | 31 +- .../vpc/MockConfigurationManagerImpl.java | 2 +- .../CreateNetworkOfferingTest.java | 20 +- ui/public/locales/en.json | 5 + ui/src/components/CheckBoxSelectPair.vue | 17 +- ui/src/components/view/DetailsTab.vue | 2 +- ui/src/config/section/offering.js | 4 +- ui/src/views/offering/AddNetworkOffering.vue | 158 ++++++++-- ui/src/views/offering/AddVpcOffering.vue | 274 ++++++++++++------ 32 files changed, 778 insertions(+), 183 deletions(-) diff --git a/api/src/main/java/com/cloud/network/vpc/VpcOffering.java b/api/src/main/java/com/cloud/network/vpc/VpcOffering.java index c64b9320245..3aab57d5d3d 100644 --- a/api/src/main/java/com/cloud/network/vpc/VpcOffering.java +++ b/api/src/main/java/com/cloud/network/vpc/VpcOffering.java @@ -29,7 +29,8 @@ public interface VpcOffering extends InternalIdentity, Identity { public static final String defaultVPCOfferingName = "Default VPC offering"; public static final String defaultVPCNSOfferingName = "Default VPC offering with Netscaler"; public static final String redundantVPCOfferingName = "Redundant VPC offering"; - public static final String DEFAULT_VPC_NSX_OFFERING_NAME = "VPC offering with NSX"; + public static final String DEFAULT_VPC_NAT_NSX_OFFERING_NAME = "VPC offering with NSX - NAT Mode"; + public static final String DEFAULT_VPC_ROUTE_NSX_OFFERING_NAME = "VPC offering with NSX - Route Mode"; /** * @@ -54,6 +55,10 @@ public interface VpcOffering extends InternalIdentity, Identity { */ boolean isDefault(); + boolean isForNsx(); + + String getNsxMode(); + /** * @return service offering id used by VPC virtual router */ diff --git a/api/src/main/java/com/cloud/network/vpc/VpcProvisioningService.java b/api/src/main/java/com/cloud/network/vpc/VpcProvisioningService.java index 5cccd6c5a82..1ce3cf8ab0e 100644 --- a/api/src/main/java/com/cloud/network/vpc/VpcProvisioningService.java +++ b/api/src/main/java/com/cloud/network/vpc/VpcProvisioningService.java @@ -36,7 +36,8 @@ public interface VpcProvisioningService { VpcOffering createVpcOffering(String name, String displayText, List supportedServices, Map> serviceProviders, Map serviceCapabilitystList, NetUtils.InternetProtocol internetProtocol, - Long serviceOfferingId, List domainIds, List zoneIds, VpcOffering.State state); + Long serviceOfferingId, Boolean forNsx, String mode, + List domainIds, List zoneIds, VpcOffering.State state); Pair,Integer> listVpcOfferings(ListVPCOfferingsCmd cmd); diff --git a/api/src/main/java/com/cloud/offering/NetworkOffering.java b/api/src/main/java/com/cloud/offering/NetworkOffering.java index afe2a255f5b..6a68ab1246a 100644 --- a/api/src/main/java/com/cloud/offering/NetworkOffering.java +++ b/api/src/main/java/com/cloud/offering/NetworkOffering.java @@ -43,6 +43,11 @@ public interface NetworkOffering extends InfrastructureEntity, InternalIdentity, InternalLbProvider, PublicLbProvider, servicepackageuuid, servicepackagedescription, PromiscuousMode, MacAddressChanges, ForgedTransmits, MacLearning, RelatedNetworkOffering, domainid, zoneid, pvlanType, internetProtocol } + public enum NsxMode { + NATTED, + ROUTED + } + public final static String SystemPublicNetwork = "System-Public-Network"; public final static String SystemControlNetwork = "System-Control-Network"; public final static String SystemManagementNetwork = "System-Management-Network"; @@ -52,7 +57,8 @@ public interface NetworkOffering extends InfrastructureEntity, InternalIdentity, public final static String DefaultSharedNetworkOfferingWithSGService = "DefaultSharedNetworkOfferingWithSGService"; public static final String DEFAULT_TUNGSTEN_SHARED_NETWORK_OFFERING_WITH_SGSERVICE = "DefaultTungstenSharedNetworkOfferingWithSGService"; - public static final String DEFAULT_NSX_OFFERING = "DefaultNSXNetworkOffering"; + public static final String DEFAULT_NAT_NSX_OFFERING = "DefaultNATNSXNetworkOffering"; + public static final String DEFAULT_ROUTER_NSX_OFFERING = "DefaultRouteNSXNetworkOffering"; public final static String QuickCloudNoServices = "QuickCloudNoServices"; public final static String DefaultIsolatedNetworkOfferingWithSourceNatService = "DefaultIsolatedNetworkOfferingWithSourceNatService"; public final static String OvsIsolatedNetworkOfferingWithSourceNatService = "OvsIsolatedNetworkOfferingWithSourceNatService"; @@ -93,6 +99,8 @@ public interface NetworkOffering extends InfrastructureEntity, InternalIdentity, boolean isForNsx(); + String getNsxMode(); + TrafficType getTrafficType(); boolean isSpecifyVlan(); diff --git a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java index 3329f42bfc9..7448f8c6e41 100644 --- a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java @@ -292,6 +292,7 @@ public class ApiConstants { public static final String MIGRATION_TYPE = "migrationtype"; public static final String MEMORY = "memory"; public static final String MODE = "mode"; + public static final String NSX_MODE = "nsxmode"; public static final String NAME = "name"; public static final String METHOD_NAME = "methodname"; public static final String NETWORK_DOMAIN = "networkdomain"; diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java index 8bf6fce881c..e12ab53c073 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java @@ -24,7 +24,10 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; +import com.cloud.network.Network; +import com.cloud.network.VirtualRouterProvider; import org.apache.cloudstack.api.response.DomainResponse; import org.apache.cloudstack.api.response.ZoneResponse; import org.apache.commons.collections.CollectionUtils; @@ -47,6 +50,15 @@ import com.cloud.offering.NetworkOffering; import com.cloud.offering.NetworkOffering.Availability; import com.cloud.user.Account; +import static com.cloud.network.Network.Service.Dhcp; +import static com.cloud.network.Network.Service.Dns; +import static com.cloud.network.Network.Service.Lb; +import static com.cloud.network.Network.Service.StaticNat; +import static com.cloud.network.Network.Service.SourceNat; +import static com.cloud.network.Network.Service.PortForwarding; +import static com.cloud.network.Network.Service.NetworkACL; +import static com.cloud.network.Network.Service.UserData; + @APICommand(name = "createNetworkOffering", description = "Creates a network offering.", responseObject = NetworkOfferingResponse.class, since = "3.0.0", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class CreateNetworkOfferingCmd extends BaseCmd { @@ -127,6 +139,18 @@ public class CreateNetworkOfferingCmd extends BaseCmd { description = "true if network offering is meant to be used for VPC, false otherwise.") private Boolean forVpc; + @Parameter(name = ApiConstants.FOR_NSX, + type = CommandType.BOOLEAN, + description = "true if network offering is meant to be used for NSX, false otherwise.", + since = "4.20.0") + private Boolean forNsx; + + @Parameter(name = ApiConstants.NSX_MODE, + type = CommandType.STRING, + description = "Indicates the mode with which the network will operate. Valid option: NATTED or ROUTED", + since = "4.20.0") + private String nsxMode; + @Parameter(name = ApiConstants.FOR_TUNGSTEN, type = CommandType.BOOLEAN, description = "true if network offering is meant to be used for Tungsten-Fabric, false otherwise.") @@ -211,7 +235,24 @@ public class CreateNetworkOfferingCmd extends BaseCmd { } public List getSupportedServices() { - return supportedServices == null ? new ArrayList() : supportedServices; + if (!forNsx) { + return supportedServices == null ? new ArrayList() : supportedServices; + } else { + List services = new ArrayList<>(List.of( + Dhcp.getName(), + Dns.getName(), + StaticNat.getName(), + SourceNat.getName(), + PortForwarding.getName(), + UserData.getName(), + Lb.getName() + )); + if (Boolean.TRUE.equals(forVpc)) { + services.add(NetworkACL.getName()); + return services; + } + return services; + } } public String getGuestIpType() { @@ -241,6 +282,14 @@ public class CreateNetworkOfferingCmd extends BaseCmd { return forVpc; } + public Boolean isForNsx() { + return forNsx; + } + + public String getNsxMode() { + return nsxMode; + } + public Boolean getForTungsten() { return forTungsten; } @@ -261,9 +310,8 @@ public class CreateNetworkOfferingCmd extends BaseCmd { } public Map> getServiceProviders() { - Map> serviceProviderMap = null; - if (serviceProviderList != null && !serviceProviderList.isEmpty()) { - serviceProviderMap = new HashMap>(); + Map> serviceProviderMap = new HashMap>(); + if (serviceProviderList != null && !serviceProviderList.isEmpty() && !isForNsx()) { Collection servicesCollection = serviceProviderList.values(); Iterator iter = servicesCollection.iterator(); while (iter.hasNext()) { @@ -279,11 +327,29 @@ public class CreateNetworkOfferingCmd extends BaseCmd { providerList.add(provider); serviceProviderMap.put(service, providerList); } + } else if (Boolean.TRUE.equals(forNsx)) { + getServiceProviderMapForNsx(serviceProviderMap); } - return serviceProviderMap; } + private void getServiceProviderMapForNsx(Map> serviceProviderMap) { + String routerProvider = Boolean.TRUE.equals(getForVpc()) ? VirtualRouterProvider.Type.VPCVirtualRouter.name() : + VirtualRouterProvider.Type.VirtualRouter.name(); + List unsupportedServices = List.of("Vpn", "SecurityGroup", "Connectivity", + "Gateway", "Firewall", "BaremetalPxeService"); + List routerSupported = List.of("Dhcp", "Dns", "UserData"); + List allServices = Service.listAllServices().stream().map(Service::getName).collect(Collectors.toList()); + for (String service : allServices) { + if (unsupportedServices.contains(service)) + continue; + if (routerSupported.contains(service)) + serviceProviderMap.put(service, List.of(routerProvider)); + else + serviceProviderMap.put(service, List.of(Network.Provider.Nsx.getName())); + } + } + public Map getServiceCapabilities(Service service) { Map capabilityMap = null; diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/CreateVPCOfferingCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/CreateVPCOfferingCmd.java index b69e7f4a828..c55a4571733 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/CreateVPCOfferingCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/vpc/CreateVPCOfferingCmd.java @@ -23,8 +23,13 @@ import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; +import java.util.stream.Collectors; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.network.Network; +import com.cloud.network.VirtualRouterProvider; import org.apache.cloudstack.api.response.DomainResponse; import org.apache.cloudstack.api.response.ZoneResponse; import org.apache.commons.collections.CollectionUtils; @@ -45,6 +50,15 @@ import com.cloud.exception.ResourceAllocationException; import com.cloud.network.vpc.VpcOffering; import com.cloud.user.Account; +import static com.cloud.network.Network.Service.Dhcp; +import static com.cloud.network.Network.Service.Dns; +import static com.cloud.network.Network.Service.Lb; +import static com.cloud.network.Network.Service.StaticNat; +import static com.cloud.network.Network.Service.SourceNat; +import static com.cloud.network.Network.Service.PortForwarding; +import static com.cloud.network.Network.Service.NetworkACL; +import static com.cloud.network.Network.Service.UserData; + @APICommand(name = "createVPCOffering", description = "Creates VPC offering", responseObject = VpcOfferingResponse.class, requestHasSensitiveInfo = false, responseHasSensitiveInfo = false) public class CreateVPCOfferingCmd extends BaseAsyncCreateCmd { @@ -62,7 +76,6 @@ public class CreateVPCOfferingCmd extends BaseAsyncCreateCmd { @Parameter(name = ApiConstants.SUPPORTED_SERVICES, type = CommandType.LIST, - required = true, collectionType = CommandType.STRING, description = "services supported by the vpc offering") private List supportedServices; @@ -101,6 +114,18 @@ public class CreateVPCOfferingCmd extends BaseAsyncCreateCmd { since = "4.13") private List zoneIds; + @Parameter(name = ApiConstants.FOR_NSX, + type = CommandType.BOOLEAN, + description = "true if network offering is meant to be used for NSX, false otherwise.", + since = "4.20.0") + private Boolean forNsx; + + @Parameter(name = ApiConstants.NSX_MODE, + type = CommandType.STRING, + description = "Indicates the mode with which the network will operate. Valid option: NATTED or ROUTED", + since = "4.20.0") + private String nsxMode; + @Parameter(name = ApiConstants.ENABLE, type = CommandType.BOOLEAN, description = "set to true if the offering is to be enabled during creation. Default is false", @@ -120,13 +145,35 @@ public class CreateVPCOfferingCmd extends BaseAsyncCreateCmd { } public List getSupportedServices() { + if (!forNsx && CollectionUtils.isEmpty(supportedServices)) { + throw new InvalidParameterValueException("Supported services needs to be provided"); + } + if (forNsx) { + return List.of( + Dhcp.getName(), + Dns.getName(), + Lb.getName(), + StaticNat.getName(), + SourceNat.getName(), + NetworkACL.getName(), + PortForwarding.getName(), + UserData.getName() + ); + } return supportedServices; } + public Boolean isForNsx() { + return !Objects.isNull(forNsx) && forNsx; + } + + public String getNsxMode() { + return nsxMode; + } + public Map> getServiceProviders() { - Map> serviceProviderMap = null; - if (serviceProviderList != null && !serviceProviderList.isEmpty()) { - serviceProviderMap = new HashMap>(); + Map> serviceProviderMap = new HashMap>();; + if (serviceProviderList != null && !serviceProviderList.isEmpty() && !isForNsx()) { Collection> servicesCollection = serviceProviderList.values(); Iterator> iter = servicesCollection.iterator(); while (iter.hasNext()) { @@ -134,7 +181,7 @@ public class CreateVPCOfferingCmd extends BaseAsyncCreateCmd { if (s_logger.isTraceEnabled()) { s_logger.trace("service provider entry specified: " + obj); } - HashMap services = (HashMap)obj; + HashMap services = (HashMap) obj; String service = services.get("service"); String provider = services.get("provider"); List providerList = null; @@ -146,11 +193,28 @@ public class CreateVPCOfferingCmd extends BaseAsyncCreateCmd { providerList.add(provider); serviceProviderMap.put(service, providerList); } + } else if (Boolean.TRUE.equals(forNsx)) { + getServiceProviderMapForNsx(serviceProviderMap); } return serviceProviderMap; } + private void getServiceProviderMapForNsx(Map> serviceProviderMap) { + List unsupportedServices = List.of("Vpn", "BaremetalPxeService", "SecurityGroup", "Connectivity", + "Gateway", "Firewall"); + List routerSupported = List.of("Dhcp", "Dns", "UserData"); + List allServices = Network.Service.listAllServices().stream().map(Network.Service::getName).collect(Collectors.toList()); + for (String service : allServices) { + if (unsupportedServices.contains(service)) + continue; + if (routerSupported.contains(service)) + serviceProviderMap.put(service, List.of(VirtualRouterProvider.Type.VPCVirtualRouter.name())); + else + serviceProviderMap.put(service, List.of(Network.Provider.Nsx.getName())); + } + } + public Map> getServiceCapabilityList() { return serviceCapabilityList; } diff --git a/api/src/main/java/org/apache/cloudstack/api/response/NetworkOfferingResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/NetworkOfferingResponse.java index 4685580e4b5..2594488c5be 100644 --- a/api/src/main/java/org/apache/cloudstack/api/response/NetworkOfferingResponse.java +++ b/api/src/main/java/org/apache/cloudstack/api/response/NetworkOfferingResponse.java @@ -107,6 +107,10 @@ public class NetworkOfferingResponse extends BaseResponseWithAnnotations { @Param(description = "true if network offering can be used by Tungsten-Fabric networks only") private Boolean forTungsten; + @SerializedName(ApiConstants.NSX_MODE) + @Param(description = "Mode in which the network will operate. This parameter is only relevant for NSX offerings") + private String nsxMode; + @SerializedName(ApiConstants.IS_PERSISTENT) @Param(description = "true if network offering supports persistent networks, false otherwise") private Boolean isPersistent; @@ -227,6 +231,10 @@ public class NetworkOfferingResponse extends BaseResponseWithAnnotations { this.forTungsten = forTungsten; } + public void setNsxMode(String nsxMode) { + this.nsxMode = nsxMode; + } + public void setIsPersistent(Boolean isPersistent) { this.isPersistent = isPersistent; } diff --git a/api/src/main/java/org/apache/cloudstack/api/response/VpcOfferingResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/VpcOfferingResponse.java index 6881969646b..ce00827f06d 100644 --- a/api/src/main/java/org/apache/cloudstack/api/response/VpcOfferingResponse.java +++ b/api/src/main/java/org/apache/cloudstack/api/response/VpcOfferingResponse.java @@ -63,9 +63,17 @@ public class VpcOfferingResponse extends BaseResponse { private Boolean supportsDistributedRouter; @SerializedName((ApiConstants.SUPPORTS_REGION_LEVEL_VPC)) - @Param(description = " indicated if the offering can support region level vpc", since = "4.4") + @Param(description = "indicated if the offering can support region level vpc", since = "4.4") private Boolean supportsRegionLevelVpc; + @SerializedName(ApiConstants.FOR_NSX) + @Param(description = "true if vpc offering can be used by NSX networks only") + private Boolean forNsx; + + @SerializedName(ApiConstants.NSX_MODE) + @Param(description = "Mode in which the network will operate. This parameter is only relevant for NSX offerings") + private String nsxMode; + @SerializedName(ApiConstants.DOMAIN_ID) @Param(description = "the domain ID(s) this disk offering belongs to. Ignore this information as it is not currently applicable.") private String domainId; @@ -138,6 +146,14 @@ public class VpcOfferingResponse extends BaseResponse { this.domain = domain; } + public void setForNsx(Boolean forNsx) { + this.forNsx = forNsx; + } + + public void setNsxMode(String nsxMode) { + this.nsxMode = nsxMode; + } + public String getZoneId() { return zoneId; } diff --git a/api/src/test/java/org/apache/cloudstack/api/command/admin/vpc/CreateVPCOfferingCmdTest.java b/api/src/test/java/org/apache/cloudstack/api/command/admin/vpc/CreateVPCOfferingCmdTest.java index 16b716d7d63..290a2850c9a 100644 --- a/api/src/test/java/org/apache/cloudstack/api/command/admin/vpc/CreateVPCOfferingCmdTest.java +++ b/api/src/test/java/org/apache/cloudstack/api/command/admin/vpc/CreateVPCOfferingCmdTest.java @@ -52,15 +52,15 @@ public class CreateVPCOfferingCmdTest { IllegalAccessException { CreateVPCOfferingCmd cmd = new CreateVPCOfferingCmd(); ApiCmdTestUtil.set(cmd, ApiConstants.SERVICE_PROVIDER_LIST, new HashMap>()); - Assert.assertNull(cmd.getServiceProviders()); + Assert.assertTrue(cmd.getServiceProviders().isEmpty()); } @Test - public void getDetailsNull() throws IllegalArgumentException, + public void getDetailsEmpty() throws IllegalArgumentException, IllegalAccessException { CreateVPCOfferingCmd cmd = new CreateVPCOfferingCmd(); ApiCmdTestUtil.set(cmd, ApiConstants.SERVICE_PROVIDER_LIST, null); - Assert.assertNull(cmd.getServiceProviders()); + Assert.assertTrue(cmd.getServiceProviders().isEmpty()); } @Test diff --git a/engine/components-api/src/main/java/com/cloud/configuration/ConfigurationManager.java b/engine/components-api/src/main/java/com/cloud/configuration/ConfigurationManager.java index 1146a33861d..b0fbd30691a 100644 --- a/engine/components-api/src/main/java/com/cloud/configuration/ConfigurationManager.java +++ b/engine/components-api/src/main/java/com/cloud/configuration/ConfigurationManager.java @@ -225,7 +225,7 @@ public interface ConfigurationManager { Integer networkRate, Map> serviceProviderMap, boolean isDefault, Network.GuestType type, boolean systemOnly, Long serviceOfferingId, boolean conserveMode, Map> serviceCapabilityMap, boolean specifyIpRanges, boolean isPersistent, Map details, boolean egressDefaultPolicy, Integer maxconn, boolean enableKeepAlive, Boolean forVpc, - Boolean forTungsten, Boolean forNsx, List domainIds, List zoneIds, boolean enableOffering, final NetUtils.InternetProtocol internetProtocol); + Boolean forTungsten, Boolean forNsx, String mode, List domainIds, List zoneIds, boolean enableOffering, final NetUtils.InternetProtocol internetProtocol); Vlan createVlanAndPublicIpRange(long zoneId, long networkId, long physicalNetworkId, boolean forVirtualNetwork, boolean forSystemVms, Long podId, String startIP, String endIP, String vlanGateway, String vlanNetmask, String vlanId, boolean bypassVlanOverlapCheck, Domain domain, Account vlanOwner, String startIPv6, String endIPv6, String vlanIp6Gateway, String vlanIp6Cidr) diff --git a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java index 70176ebb29f..efecfc3d3f2 100644 --- a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java +++ b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java @@ -540,27 +540,27 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra if (_networkOfferingDao.findByUniqueName(NetworkOffering.QuickCloudNoServices) == null) { offering = _configMgr.createNetworkOffering(NetworkOffering.QuickCloudNoServices, "Offering for QuickCloud with no services", TrafficType.Guest, null, true, Availability.Optional, null, new HashMap>(), true, Network.GuestType.Shared, false, null, true, null, true, - false, null, false, null, true, false, false, false, null, null, true, null); + false, null, false, null, true, false, false, false, null, null, null, true, null); } //#2 - SG enabled network offering if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedNetworkOfferingWithSGService) == null) { offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedNetworkOfferingWithSGService, "Offering for Shared Security group enabled networks", TrafficType.Guest, null, true, Availability.Optional, null, defaultSharedNetworkOfferingProviders, true, Network.GuestType.Shared, false, null, true, - null, true, false, null, false, null, true, false, false, false, null, null, true, null); + null, true, false, null, false, null, true, false, false, false, null, null, null, true, null); } //#3 - shared network offering with no SG service if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedNetworkOffering) == null) { offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedNetworkOffering, "Offering for Shared networks", TrafficType.Guest, null, true, Availability.Optional, null, defaultSharedNetworkOfferingProviders, true, Network.GuestType.Shared, false, null, true, null, true, false, null, false, - null, true, false, false, false, null, null, true, null); + null, true, false, false, false, null,null, null, true, null); } if (_networkOfferingDao.findByUniqueName(NetworkOffering.DEFAULT_TUNGSTEN_SHARED_NETWORK_OFFERING_WITH_SGSERVICE) == null) { offering = _configMgr.createNetworkOffering(NetworkOffering.DEFAULT_TUNGSTEN_SHARED_NETWORK_OFFERING_WITH_SGSERVICE, "Offering for Tungsten Shared Security group enabled networks", TrafficType.Guest, null, true, Availability.Optional, null, defaultTungstenSharedSGEnabledNetworkOfferingProviders, true, Network.GuestType.Shared, false, null, true, - null, true, false, null, false, null, true, false, true, false, null, null, true, null); + null, true, false, null, false, null, true, false, true, false, null, null,null, true, null); offering.setState(NetworkOffering.State.Enabled); _networkOfferingDao.update(offering.getId(), offering); } @@ -570,14 +570,14 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingWithSourceNatService, "Offering for Isolated networks with Source Nat service enabled", TrafficType.Guest, null, false, Availability.Required, null, defaultIsolatedSourceNatEnabledNetworkOfferingProviders, true, Network.GuestType.Isolated, false, null, true, null, false, false, null, false, null, - true, false, false, false, null, null, true, null); + true, false, false, false, null, null,null, true, null); } //#5 - default vpc offering with LB service if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworks) == null) { offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworks, "Offering for Isolated VPC networks with Source Nat service enabled", TrafficType.Guest, null, false, Availability.Optional, null, - defaultVPCOffProviders, true, Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, true, false, false, null, null, true, null); + defaultVPCOffProviders, true, Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, true, false, false, null, null, null,true, null); } //#6 - default vpc offering with no LB service @@ -586,14 +586,14 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra defaultVPCOffProviders.remove(Service.Lb); offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksNoLB, "Offering for Isolated VPC networks with Source Nat service enabled and LB service disabled", TrafficType.Guest, null, false, Availability.Optional, - null, defaultVPCOffProviders, true, Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, true, false, false, null, null, true, null); + null, defaultVPCOffProviders, true, Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, true, false, false, null, null, null,true, null); } //#7 - isolated offering with source nat disabled if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOffering) == null) { offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOffering, "Offering for Isolated networks with no Source Nat service", TrafficType.Guest, null, true, Availability.Optional, null, defaultIsolatedNetworkOfferingProviders, true, Network.GuestType.Isolated, false, null, - true, null, true, false, null, false, null, true, false, false, false, null, null, true, null); + true, null, true, false, null, false, null, true, false, false, false, null, null, null, true, null); } //#8 - network offering with internal lb service @@ -615,7 +615,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksWithInternalLB) == null) { offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksWithInternalLB, "Offering for Isolated VPC networks with Internal Lb support", TrafficType.Guest, null, false, Availability.Optional, null, internalLbOffProviders, - true, Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, true, false, false, null, null, true, null); + true, Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, true, false, false, null, null, null, true, null); offering.setInternalLb(true); offering.setPublicLb(false); _networkOfferingDao.update(offering.getId(), offering); @@ -646,7 +646,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra if (_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedEIPandELBNetworkOffering) == null) { offering = _configMgr.createNetworkOffering(NetworkOffering.DefaultSharedEIPandELBNetworkOffering, "Offering for Shared networks with Elastic IP and Elastic LB capabilities", TrafficType.Guest, null, true, Availability.Optional, null, - netscalerServiceProviders, true, Network.GuestType.Shared, false, null, true, serviceCapabilityMap, true, false, null, false, null, true, false, false, false, null, null, true, null); + netscalerServiceProviders, true, Network.GuestType.Shared, false, null, true, serviceCapabilityMap, true, false, null, false, null, true, false, false, false, null, null, null, true, null); offering.setDedicatedLB(false); _networkOfferingDao.update(offering.getId(), offering); } diff --git a/engine/schema/src/main/java/com/cloud/network/vpc/VpcOfferingVO.java b/engine/schema/src/main/java/com/cloud/network/vpc/VpcOfferingVO.java index aa26f16568a..350dda3f3b8 100644 --- a/engine/schema/src/main/java/com/cloud/network/vpc/VpcOfferingVO.java +++ b/engine/schema/src/main/java/com/cloud/network/vpc/VpcOfferingVO.java @@ -58,6 +58,12 @@ public class VpcOfferingVO implements VpcOffering { @Column(name = "default") boolean isDefault = false; + @Column(name = "for_nsx") + boolean forNsx = false; + + @Column(name = "nsx_mode") + String nsxMode; + @Column(name = GenericDao.REMOVED_COLUMN) Date removed; @@ -144,6 +150,22 @@ public class VpcOfferingVO implements VpcOffering { return isDefault; } + public boolean isForNsx() { + return forNsx; + } + + public void setForNsx(boolean forNsx) { + this.forNsx = forNsx; + } + + public String getNsxMode() { + return nsxMode; + } + + public void setNsxMode(String nsxMode) { + this.nsxMode = nsxMode; + } + public void setUniqueName(String uniqueName) { this.uniqueName = uniqueName; } diff --git a/engine/schema/src/main/java/com/cloud/offerings/NetworkOfferingVO.java b/engine/schema/src/main/java/com/cloud/offerings/NetworkOfferingVO.java index edc89f3cb9a..b2fabf2e3cd 100644 --- a/engine/schema/src/main/java/com/cloud/offerings/NetworkOfferingVO.java +++ b/engine/schema/src/main/java/com/cloud/offerings/NetworkOfferingVO.java @@ -139,6 +139,9 @@ public class NetworkOfferingVO implements NetworkOffering { @Column(name = "for_nsx") boolean forNsx = false; + @Column(name = "nsx_mode") + String nsxMode; + @Column(name = "egress_default_policy") boolean egressdefaultpolicy; @@ -207,6 +210,15 @@ public class NetworkOfferingVO implements NetworkOffering { this.forNsx = forNsx; } + @Override + public String getNsxMode() { + return nsxMode; + } + + public void setNsxMode(String nsxMode) { + this.nsxMode = nsxMode; + } + @Override public long getId() { return id; diff --git a/engine/schema/src/main/resources/META-INF/db/schema-41810to41900.sql b/engine/schema/src/main/resources/META-INF/db/schema-41810to41900.sql index a429c37d4d6..0a461570ac5 100644 --- a/engine/schema/src/main/resources/META-INF/db/schema-41810to41900.sql +++ b/engine/schema/src/main/resources/META-INF/db/schema-41810to41900.sql @@ -214,8 +214,11 @@ BEGIN -- NSX Plugin -- CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.network_offerings','for_nsx', 'int(1) unsigned DEFAULT "0" COMMENT "is nsx enabled for the resource"'); +CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.network_offerings','nsx_mode', 'varchar(32) COMMENT "mode in which the network would route traffic"'); +CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.vpc_offerings','for_nsx', 'int(1) unsigned DEFAULT "0" COMMENT "is nsx enabled for the resource"'); +CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.vpc_offerings','nsx_mode', 'varchar(32) COMMENT "mode in which the network would route traffic"'); --- Network offering with multi-domains and multi-zones +-- Network offering with NSX related columns DROP VIEW IF EXISTS `cloud`.`network_offering_view`; CREATE VIEW `cloud`.`network_offering_view` AS SELECT @@ -259,6 +262,7 @@ SELECT `network_offerings`.`for_vpc` AS `for_vpc`, `network_offerings`.`for_tungsten` AS `for_tungsten`, `network_offerings`.`for_nsx` AS `for_nsx`, + `network_offerings`.`nsx_mode` AS `nsx_mode`, `network_offerings`.`service_package_id` AS `service_package_id`, GROUP_CONCAT(DISTINCT(domain.id)) AS domain_id, GROUP_CONCAT(DISTINCT(domain.uuid)) AS domain_uuid, @@ -285,3 +289,46 @@ GROUP BY -- Set removed state for all removed accounts UPDATE `cloud`.`account` SET state='removed' WHERE `removed` IS NOT NULL; + +-- VPC offering with NSX related columns +DROP VIEW IF EXISTS `cloud`.`vpc_offering_view`; +CREATE VIEW `cloud`.`vpc_offering_view` AS +SELECT + `vpc_offerings`.`id` AS `id`, + `vpc_offerings`.`uuid` AS `uuid`, + `vpc_offerings`.`name` AS `name`, + `vpc_offerings`.`unique_name` AS `unique_name`, + `vpc_offerings`.`display_text` AS `display_text`, + `vpc_offerings`.`state` AS `state`, + `vpc_offerings`.`default` AS `default`, + `vpc_offerings`.`for_nsx` AS `for_nsx`, + `vpc_offerings`.`nsx_mode` AS `nsx_mode`, + `vpc_offerings`.`created` AS `created`, + `vpc_offerings`.`removed` AS `removed`, + `vpc_offerings`.`service_offering_id` AS `service_offering_id`, + `vpc_offerings`.`supports_distributed_router` AS `supports_distributed_router`, + `vpc_offerings`.`supports_region_level_vpc` AS `supports_region_level_vpc`, + `vpc_offerings`.`redundant_router_service` AS `redundant_router_service`, + `vpc_offerings`.`sort_key` AS `sort_key`, + GROUP_CONCAT(DISTINCT(domain.id)) AS domain_id, + GROUP_CONCAT(DISTINCT(domain.uuid)) AS domain_uuid, + GROUP_CONCAT(DISTINCT(domain.name)) AS domain_name, + GROUP_CONCAT(DISTINCT(domain.path)) AS domain_path, + GROUP_CONCAT(DISTINCT(zone.id)) AS zone_id, + GROUP_CONCAT(DISTINCT(zone.uuid)) AS zone_uuid, + GROUP_CONCAT(DISTINCT(zone.name)) AS zone_name, + `offering_details`.value AS internet_protocol +FROM + `cloud`.`vpc_offerings` + LEFT JOIN + `cloud`.`vpc_offering_details` AS `domain_details` ON `domain_details`.`offering_id` = `vpc_offerings`.`id` AND `domain_details`.`name`='domainid' + LEFT JOIN + `cloud`.`domain` AS `domain` ON FIND_IN_SET(`domain`.`id`, `domain_details`.`value`) + LEFT JOIN + `cloud`.`vpc_offering_details` AS `zone_details` ON `zone_details`.`offering_id` = `vpc_offerings`.`id` AND `zone_details`.`name`='zoneid' + LEFT JOIN + `cloud`.`data_center` AS `zone` ON FIND_IN_SET(`zone`.`id`, `zone_details`.`value`) + LEFT JOIN + `cloud`.`vpc_offering_details` AS `offering_details` ON `offering_details`.`offering_id` = `vpc_offerings`.`id` AND `offering_details`.`name`='internetprotocol' +GROUP BY + `vpc_offerings`.`id`; diff --git a/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailManagerImpl.java b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailManagerImpl.java index 372e268a2ff..6ce4c91bea6 100644 --- a/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailManagerImpl.java +++ b/plugins/network-elements/juniper-contrail/src/main/java/org/apache/cloudstack/network/contrail/management/ContrailManagerImpl.java @@ -219,7 +219,7 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager ConfigurationManager configMgr = (ConfigurationManager) _configService; NetworkOfferingVO voffer = configMgr.createNetworkOffering(offeringName, offeringDisplayText, TrafficType.Public, null, true, Availability.Optional, null, serviceProviderMap, true, - Network.GuestType.Shared, false, null, false, null, true, false, null, true, null, false, false, false, false, null, null, true, null); + Network.GuestType.Shared, false, null, false, null, true, false, null, true, null, false, false, false, false, null, null, null, true, null); long id = voffer.getId(); _networkOfferingDao.update(id, voffer); return _networkOfferingDao.findById(id); @@ -254,7 +254,7 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager ConfigurationManager configMgr = (ConfigurationManager)_configService; NetworkOfferingVO voffer = configMgr.createNetworkOffering(offeringName, offeringDisplayText, TrafficType.Guest, null, false, Availability.Optional, null, serviceProviderMap, true, - Network.GuestType.Isolated, false, null, false, null, false, true, null, true, null, false, offeringName.equals(vpcRouterOfferingName), false, false, null, null, true, null); + Network.GuestType.Isolated, false, null, false, null, false, true, null, true, null, false, offeringName.equals(vpcRouterOfferingName), false, false, null, null, null, true, null); if (offeringName.equals(vpcRouterOfferingName)) { voffer.setInternalLb(true); } @@ -295,7 +295,7 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager } serviceProviderMap.put(svc, providerSet); } - vpcOffer = _vpcProvSvc.createVpcOffering(juniperVPCOfferingName, juniperVPCOfferingDisplayText, services, serviceProviderMap, null, null, null, null, null, VpcOffering.State.Enabled); + vpcOffer = _vpcProvSvc.createVpcOffering(juniperVPCOfferingName, juniperVPCOfferingDisplayText, services, serviceProviderMap, null, null, null, false, null, null, null, VpcOffering.State.Enabled); long id = vpcOffer.getId(); _vpcOffDao.update(id, (VpcOfferingVO)vpcOffer); return _vpcOffDao.findById(id); 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 b01700cfe2c..edbc2eebffe 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 @@ -118,7 +118,9 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, DnsS capabilities.put(Network.Service.Dns, dnsCapabilities); capabilities.put(Network.Service.StaticNat, null); - + capabilities.put(Network.Service.Lb, null); + capabilities.put(Network.Service.PortForwarding, null); + capabilities.put(Network.Service.NetworkACL, null); Map sourceNatCapabilities = new HashMap<>(); sourceNatCapabilities.put(Network.Capability.RedundantRouter, "true"); sourceNatCapabilities.put(Network.Capability.SupportedSourceNatTypes, "peraccount"); @@ -226,7 +228,7 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, DnsS @Override public boolean verifyServicesCombination(Set services) { - return false; + return true; } @Override diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxGuestNetworkGuru.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxGuestNetworkGuru.java index 70102ec8295..6b0c2472b41 100644 --- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxGuestNetworkGuru.java +++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxGuestNetworkGuru.java @@ -50,6 +50,7 @@ import org.apache.cloudstack.NsxAnswer; import org.apache.cloudstack.agent.api.CreateNsxDhcpRelayConfigCommand; import org.apache.cloudstack.agent.api.CreateNsxSegmentCommand; import org.apache.cloudstack.utils.NsxControllerUtils; + import org.apache.cloudstack.utils.NsxHelper; import org.apache.log4j.Logger; diff --git a/server/src/main/java/com/cloud/api/ApiResponseHelper.java b/server/src/main/java/com/cloud/api/ApiResponseHelper.java index 6d4972573ae..0a174e51de0 100644 --- a/server/src/main/java/com/cloud/api/ApiResponseHelper.java +++ b/server/src/main/java/com/cloud/api/ApiResponseHelper.java @@ -2321,6 +2321,7 @@ public class ApiResponseHelper implements ResponseGenerator { response.setForVpc(_configMgr.isOfferingForVpc(offering)); response.setForTungsten(offering.isForTungsten()); response.setForNsx(offering.isForNsx()); + response.setNsxMode(offering.getNsxMode()); response.setServices(serviceResponses); //set network offering details Map details = _ntwkModel.getNtwkOffDetails(offering.getId()); diff --git a/server/src/main/java/com/cloud/api/query/dao/VpcOfferingJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/VpcOfferingJoinDaoImpl.java index af0940609ba..bab22178e61 100644 --- a/server/src/main/java/com/cloud/api/query/dao/VpcOfferingJoinDaoImpl.java +++ b/server/src/main/java/com/cloud/api/query/dao/VpcOfferingJoinDaoImpl.java @@ -72,6 +72,8 @@ public class VpcOfferingJoinDaoImpl extends GenericDaoBase detailsStr = cmd.getDetails(); final Boolean egressDefaultPolicy = cmd.getEgressDefaultPolicy(); Boolean forVpc = cmd.getForVpc(); + Boolean forNsx = cmd.isForNsx(); Boolean forTungsten = cmd.getForTungsten(); + String nsxMode = cmd.getNsxMode(); Integer maxconn = null; boolean enableKeepAlive = false; String servicePackageuuid = cmd.getServicePackageId(); @@ -5960,6 +5963,26 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati } } + if (Boolean.TRUE.equals(forNsx) && Boolean.TRUE.equals(forTungsten)) { + throw new InvalidParameterValueException("Network Offering cannot be for both Tungsten-Fabric and NSX"); + } + + if (Boolean.TRUE.equals(forNsx)) { + if (Objects.isNull(nsxMode)) { + throw new InvalidParameterValueException("Mode for an NSX offering needs to be specified. Valid values: " + Arrays.toString(NetworkOffering.NsxMode.values())); + } + if (!EnumUtils.isValidEnum(NetworkOffering.NsxMode.class, nsxMode)) { + throw new InvalidParameterValueException("Invalid mode passed. Valid values: " + Arrays.toString(NetworkOffering.NsxMode.values())); + } + } else { + if (Objects.nonNull(nsxMode)) { + if (s_logger.isTraceEnabled()) { + s_logger.trace("nsxMode has is ignored for non-NSX enabled zones"); + } + nsxMode = null; + } + } + // Verify traffic type for (final TrafficType tType : TrafficType.values()) { if (tType.name().equalsIgnoreCase(trafficTypeString)) { @@ -6224,7 +6247,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati } final NetworkOfferingVO offering = createNetworkOffering(name, displayText, trafficType, tags, specifyVlan, availability, networkRate, serviceProviderMap, false, guestType, false, - serviceOfferingId, conserveMode, serviceCapabilityMap, specifyIpRanges, isPersistent, details, egressDefaultPolicy, maxconn, enableKeepAlive, forVpc, forTungsten, false, domainIds, zoneIds, enable, internetProtocol); + serviceOfferingId, conserveMode, serviceCapabilityMap, specifyIpRanges, isPersistent, details, egressDefaultPolicy, maxconn, enableKeepAlive, forVpc, forTungsten, forNsx, nsxMode, domainIds, zoneIds, enable, internetProtocol); CallContext.current().setEventDetails(" Id: " + offering.getId() + " Name: " + name); CallContext.current().putContextParameter(NetworkOffering.class, offering.getId()); return offering; @@ -6369,7 +6392,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati final Long serviceOfferingId, final boolean conserveMode, final Map> serviceCapabilityMap, final boolean specifyIpRanges, final boolean isPersistent, final Map details, final boolean egressDefaultPolicy, final Integer maxconn, final boolean enableKeepAlive, Boolean forVpc, - Boolean forTungsten, Boolean forNsx, final List domainIds, final List zoneIds, final boolean enableOffering, final NetUtils.InternetProtocol internetProtocol) { + Boolean forTungsten, Boolean forNsx, String mode, final List domainIds, final List zoneIds, final boolean enableOffering, final NetUtils.InternetProtocol internetProtocol) { String servicePackageUuid; String spDescription = null; @@ -6595,7 +6618,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati s_logger.trace("Added service for the network offering: " + offService + " with provider " + provider.getName()); } - if (vpcOff) { + if (vpcOff && !forNsx) { final List supportedSvcs = new ArrayList(); supportedSvcs.addAll(serviceProviderMap.keySet()); _vpcMgr.validateNtwkOffForVpc(offering, supportedSvcs); diff --git a/server/src/main/java/com/cloud/network/vpc/VpcManagerImpl.java b/server/src/main/java/com/cloud/network/vpc/VpcManagerImpl.java index 7088933f584..6e6cfedc2a0 100644 --- a/server/src/main/java/com/cloud/network/vpc/VpcManagerImpl.java +++ b/server/src/main/java/com/cloud/network/vpc/VpcManagerImpl.java @@ -62,6 +62,7 @@ import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.managed.context.ManagedContextRunnable; import org.apache.cloudstack.query.QueryService; import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.EnumUtils; import org.apache.commons.lang3.ObjectUtils; import org.apache.log4j.Logger; import org.jetbrains.annotations.Nullable; @@ -325,7 +326,9 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis svcProviderMap.put(svc, defaultProviders); } } - createVpcOffering(VpcOffering.defaultVPCOfferingName, VpcOffering.defaultVPCOfferingName, svcProviderMap, true, State.Enabled, null, false, false, false); + createVpcOffering(VpcOffering.defaultVPCOfferingName, VpcOffering.defaultVPCOfferingName, svcProviderMap, + true, State.Enabled, null, false, + false, false, false, null); } // configure default vpc offering with Netscaler as LB Provider @@ -344,7 +347,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis svcProviderMap.put(svc, defaultProviders); } } - createVpcOffering(VpcOffering.defaultVPCNSOfferingName, VpcOffering.defaultVPCNSOfferingName, svcProviderMap, false, State.Enabled, null, false, false, false); + createVpcOffering(VpcOffering.defaultVPCNSOfferingName, VpcOffering.defaultVPCNSOfferingName, svcProviderMap, false, State.Enabled, null, false, false, false, false, null); } @@ -364,12 +367,13 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis svcProviderMap.put(svc, defaultProviders); } } - createVpcOffering(VpcOffering.redundantVPCOfferingName, VpcOffering.redundantVPCOfferingName, svcProviderMap, true, State.Enabled, null, false, false, true); + createVpcOffering(VpcOffering.redundantVPCOfferingName, VpcOffering.redundantVPCOfferingName, svcProviderMap, true, State.Enabled, + null, false, false, true, false, null); } - // configure default vpc offering with NSX as network service provider - if (_vpcOffDao.findByUniqueName(VpcOffering.DEFAULT_VPC_NSX_OFFERING_NAME) == null) { - s_logger.debug("Creating default VPC offering with NSX as network service provider" + VpcOffering.DEFAULT_VPC_NSX_OFFERING_NAME); + // configure default vpc offering with NSX as network service provider in NAT mode + if (_vpcOffDao.findByUniqueName(VpcOffering.DEFAULT_VPC_NAT_NSX_OFFERING_NAME) == null) { + s_logger.debug("Creating default VPC offering with NSX as network service provider" + VpcOffering.DEFAULT_VPC_NAT_NSX_OFFERING_NAME); final Map> svcProviderMap = new HashMap>(); final Set defaultProviders = Set.of(Provider.Nsx); for (final Service svc : getSupportedServices()) { @@ -380,7 +384,26 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis svcProviderMap.put(svc, defaultProviders); } } - createVpcOffering(VpcOffering.DEFAULT_VPC_NSX_OFFERING_NAME, VpcOffering.DEFAULT_VPC_NSX_OFFERING_NAME, svcProviderMap, false, State.Enabled, null, false, false, false); + createVpcOffering(VpcOffering.DEFAULT_VPC_NAT_NSX_OFFERING_NAME, VpcOffering.DEFAULT_VPC_NAT_NSX_OFFERING_NAME, svcProviderMap, false, + State.Enabled, null, false, false, false, true, NetworkOffering.NsxMode.NATTED.name()); + + } + + // configure default vpc offering with NSX as network service provider in Route mode + if (_vpcOffDao.findByUniqueName(VpcOffering.DEFAULT_VPC_ROUTE_NSX_OFFERING_NAME) == null) { + s_logger.debug("Creating default VPC offering with NSX as network service provider" + VpcOffering.DEFAULT_VPC_ROUTE_NSX_OFFERING_NAME); + final Map> svcProviderMap = new HashMap>(); + final Set defaultProviders = Set.of(Provider.Nsx); + for (final Service svc : getSupportedServices()) { + if (List.of(Service.UserData, Service.Dhcp, Service.Dns).contains(svc)) { + final Set userDataProvider = Set.of(Provider.VPCVirtualRouter); + svcProviderMap.put(svc, userDataProvider); + } else { + svcProviderMap.put(svc, defaultProviders); + } + } + createVpcOffering(VpcOffering.DEFAULT_VPC_ROUTE_NSX_OFFERING_NAME, VpcOffering.DEFAULT_VPC_ROUTE_NSX_OFFERING_NAME, svcProviderMap, false, + State.Enabled, null, false, false, false, true, NetworkOffering.NsxMode.ROUTED.name()); } } @@ -440,7 +463,25 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis final Long serviceOfferingId = cmd.getServiceOfferingId(); final List domainIds = cmd.getDomainIds(); final List zoneIds = cmd.getZoneIds(); + final Boolean forNsx = cmd.isForNsx(); + String nsxMode = cmd.getNsxMode(); final boolean enable = cmd.getEnable(); + + if (Boolean.TRUE.equals(forNsx)) { + if (Objects.isNull(nsxMode)) { + throw new InvalidParameterValueException("Mode for an NSX offering needs to be specified.Valid values: " + Arrays.toString(NetworkOffering.NsxMode.values())); + } + if (!EnumUtils.isValidEnum(NetworkOffering.NsxMode.class, nsxMode)) { + throw new InvalidParameterValueException("Invalid mode passed. Valid values: " + Arrays.toString(NetworkOffering.NsxMode.values())); + } + } else { + if (Objects.nonNull(nsxMode)) { + if (s_logger.isTraceEnabled()) { + s_logger.trace("nsxMode has is ignored for non-NSX enabled zones"); + } + nsxMode = null; + } + } // check if valid domain if (CollectionUtils.isNotEmpty(cmd.getDomainIds())) { for (final Long domainId: cmd.getDomainIds()) { @@ -463,14 +504,15 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis } return createVpcOffering(vpcOfferingName, displayText, supportedServices, - serviceProviderList, serviceCapabilityList, internetProtocol, serviceOfferingId, + serviceProviderList, serviceCapabilityList, internetProtocol, serviceOfferingId, forNsx, nsxMode, domainIds, zoneIds, (enable ? State.Enabled : State.Disabled)); } @Override @ActionEvent(eventType = EventTypes.EVENT_VPC_OFFERING_CREATE, eventDescription = "creating vpc offering", create = true) public VpcOffering createVpcOffering(final String name, final String displayText, final List supportedServices, final Map> serviceProviders, - final Map serviceCapabilityList, final NetUtils.InternetProtocol internetProtocol, final Long serviceOfferingId, List domainIds, List zoneIds, State state) { + final Map serviceCapabilityList, final NetUtils.InternetProtocol internetProtocol, final Long serviceOfferingId, + final Boolean forNsx, final String mode, List domainIds, List zoneIds, State state) { if (!Ipv6Service.Ipv6OfferingCreationEnabled.value() && !(internetProtocol == null || NetUtils.InternetProtocol.IPv4.equals(internetProtocol))) { throw new InvalidParameterValueException(String.format("Configuration %s needs to be enabled for creating IPv6 supported VPC offering", Ipv6Service.Ipv6OfferingCreationEnabled.key())); @@ -555,7 +597,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis final boolean offersRegionLevelVPC = isVpcOfferingForRegionLevelVpc(serviceCapabilityList); final boolean redundantRouter = isVpcOfferingRedundantRouter(serviceCapabilityList); final VpcOfferingVO offering = createVpcOffering(name, displayText, svcProviderMap, false, state, serviceOfferingId, supportsDistributedRouter, offersRegionLevelVPC, - redundantRouter); + redundantRouter, forNsx, mode); if (offering != null) { List detailsVO = new ArrayList<>(); @@ -583,7 +625,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis @DB protected VpcOfferingVO createVpcOffering(final String name, final String displayText, final Map> svcProviderMap, final boolean isDefault, final State state, final Long serviceOfferingId, final boolean supportsDistributedRouter, final boolean offersRegionLevelVPC, - final boolean redundantRouter) { + final boolean redundantRouter, Boolean forNsx, String mode) { return Transaction.execute(new TransactionCallback() { @Override @@ -594,6 +636,8 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis if (state != null) { offering.setState(state); } + offering.setForNsx(forNsx); + offering.setMode(mode); s_logger.debug("Adding vpc offering " + offering); offering = _vpcOffDao.persist(offering); // populate services and providers diff --git a/server/src/main/java/com/cloud/server/ConfigurationServerImpl.java b/server/src/main/java/com/cloud/server/ConfigurationServerImpl.java index 75298b73e64..f7ada1fccf1 100644 --- a/server/src/main/java/com/cloud/server/ConfigurationServerImpl.java +++ b/server/src/main/java/com/cloud/server/ConfigurationServerImpl.java @@ -1206,17 +1206,34 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio } _networkOfferingDao.persistDefaultL2NetworkOfferings(); - // Offering #9 - network offering for nsx provider - NetworkOfferingVO defaultNSXNetworkOffering = - new NetworkOfferingVO(NetworkOffering.DEFAULT_NSX_OFFERING, "Offering for NSX enabled networks", + // Offering #9 - network offering for nsx provider - NATTED mode + NetworkOfferingVO defaultNatNSXNetworkOffering = + new NetworkOfferingVO(NetworkOffering.DEFAULT_NAT_NSX_OFFERING, "Offering for NSX enabled networks - NAT mode", TrafficType.Guest, false, false, null, null, true, Availability.Optional, null, GuestType.Isolated, false, false, false, false, false, true); - defaultNSXNetworkOffering.setForNsx(true); - defaultNSXNetworkOffering.setState(NetworkOffering.State.Enabled); - defaultNSXNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultNSXNetworkOffering); + defaultNatNSXNetworkOffering.setForNsx(true); + defaultNatNSXNetworkOffering.setNsxMode(NetworkOffering.NsxMode.NATTED.name()); + defaultNatNSXNetworkOffering.setState(NetworkOffering.State.Enabled); + defaultNatNSXNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultNatNSXNetworkOffering); for (Map.Entry service : defaultNSXNetworkOfferingProviders.entrySet()) { NetworkOfferingServiceMapVO offService = - new NetworkOfferingServiceMapVO(defaultNSXNetworkOffering.getId(), service.getKey(), service.getValue()); + new NetworkOfferingServiceMapVO(defaultNatNSXNetworkOffering.getId(), service.getKey(), service.getValue()); + _ntwkOfferingServiceMapDao.persist(offService); + s_logger.trace("Added service for the network offering: " + offService); + } + + // Offering #10 - network offering for nsx provider - ROUTED mode + NetworkOfferingVO defaultRouteNSXNetworkOffering = + new NetworkOfferingVO(NetworkOffering.DEFAULT_NAT_NSX_OFFERING, "Offering for NSX enabled networks - NAT mode", + TrafficType.Guest, false, false, null, null, true, Availability.Optional, null, GuestType.Isolated, false, false, false, false, false, true); + defaultRouteNSXNetworkOffering.setForNsx(true); + defaultRouteNSXNetworkOffering.setNsxMode(NetworkOffering.NsxMode.ROUTED.name()); + defaultRouteNSXNetworkOffering.setState(NetworkOffering.State.Enabled); + defaultRouteNSXNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultRouteNSXNetworkOffering); + + for (Map.Entry service : defaultNSXNetworkOfferingProviders.entrySet()) { + NetworkOfferingServiceMapVO offService = + new NetworkOfferingServiceMapVO(defaultRouteNSXNetworkOffering.getId(), service.getKey(), service.getValue()); _ntwkOfferingServiceMapDao.persist(offService); s_logger.trace("Added service for the network offering: " + offService); } diff --git a/server/src/test/java/com/cloud/vpc/MockConfigurationManagerImpl.java b/server/src/test/java/com/cloud/vpc/MockConfigurationManagerImpl.java index 21bf3d57ff2..5b29061585c 100644 --- a/server/src/test/java/com/cloud/vpc/MockConfigurationManagerImpl.java +++ b/server/src/test/java/com/cloud/vpc/MockConfigurationManagerImpl.java @@ -546,7 +546,7 @@ public class MockConfigurationManagerImpl extends ManagerBase implements Configu Integer networkRate, Map> serviceProviderMap, boolean isDefault, GuestType type, boolean systemOnly, Long serviceOfferingId, boolean conserveMode, Map> serviceCapabilityMap, boolean specifyIpRanges, boolean isPersistent, Map details, boolean egressDefaultPolicy, Integer maxconn, boolean enableKeepAlive, Boolean forVpc, - Boolean forTungsten, Boolean forNsx, List domainIds, List zoneIds, boolean enableOffering, NetUtils.InternetProtocol internetProtocol) { + Boolean forTungsten, Boolean forNsx, String mode, List domainIds, List zoneIds, boolean enableOffering, NetUtils.InternetProtocol internetProtocol) { // TODO Auto-generated method stub return null; } diff --git a/server/src/test/java/org/apache/cloudstack/networkoffering/CreateNetworkOfferingTest.java b/server/src/test/java/org/apache/cloudstack/networkoffering/CreateNetworkOfferingTest.java index 1038420f9a5..52885c43753 100644 --- a/server/src/test/java/org/apache/cloudstack/networkoffering/CreateNetworkOfferingTest.java +++ b/server/src/test/java/org/apache/cloudstack/networkoffering/CreateNetworkOfferingTest.java @@ -129,7 +129,7 @@ public class CreateNetworkOfferingTest extends TestCase { public void createSharedNtwkOffWithVlan() { NetworkOfferingVO off = configMgr.createNetworkOffering("shared", "shared", TrafficType.Guest, null, true, Availability.Optional, 200, null, false, Network.GuestType.Shared, false, - null, false, null, true, false, null, false, null, true, false, false, false, null, null, false, null); + null, false, null, true, false, null, false, null, true, false, false, false, null,null, null, false, null); assertNotNull("Shared network offering with specifyVlan=true failed to create ", off); } @@ -137,7 +137,7 @@ public class CreateNetworkOfferingTest extends TestCase { public void createSharedNtwkOffWithNoVlan() { NetworkOfferingVO off = configMgr.createNetworkOffering("shared", "shared", TrafficType.Guest, null, false, Availability.Optional, 200, null, false, Network.GuestType.Shared, - false, null, false, null, true, false, null, false, null, true, false, false, false, null, null, false, null); + false, null, false, null, true, false, null, false, null, true, false, false, false, null, null,null, false, null); assertNotNull("Shared network offering with specifyVlan=false was created", off); } @@ -145,7 +145,7 @@ public class CreateNetworkOfferingTest extends TestCase { public void createSharedNtwkOffWithSpecifyIpRanges() { NetworkOfferingVO off = configMgr.createNetworkOffering("shared", "shared", TrafficType.Guest, null, true, Availability.Optional, 200, null, false, Network.GuestType.Shared, false, - null, false, null, true, false, null, false, null, true, false, false, false, null, null, false, null); + null, false, null, true, false, null, false, null, true, false, false, false, null,null, null, false, null); assertNotNull("Shared network offering with specifyIpRanges=true failed to create ", off); } @@ -154,7 +154,7 @@ public class CreateNetworkOfferingTest extends TestCase { public void createSharedNtwkOffWithoutSpecifyIpRanges() { NetworkOfferingVO off = configMgr.createNetworkOffering("shared", "shared", TrafficType.Guest, null, true, Availability.Optional, 200, null, false, Network.GuestType.Shared, - false, null, false, null, false, false, null, false, null, true, false, false, false, null, null, false, null); + false, null, false, null, false, false, null, false, null, true, false, false, false, null,null, null, false, null); assertNull("Shared network offering with specifyIpRanges=false was created", off); } @@ -167,7 +167,7 @@ public class CreateNetworkOfferingTest extends TestCase { serviceProviderMap.put(Network.Service.SourceNat, vrProvider); NetworkOfferingVO off = configMgr.createNetworkOffering("isolated", "isolated", TrafficType.Guest, null, false, Availability.Optional, 200, serviceProviderMap, false, - Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, false, false, false, null, null, false, null); + Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, false, false, false, null, null, null, false, null); assertNotNull("Isolated network offering with specifyIpRanges=false failed to create ", off); } @@ -180,7 +180,7 @@ public class CreateNetworkOfferingTest extends TestCase { serviceProviderMap.put(Network.Service.SourceNat, vrProvider); NetworkOfferingVO off = configMgr.createNetworkOffering("isolated", "isolated", TrafficType.Guest, null, true, Availability.Optional, 200, serviceProviderMap, false, - Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, false, false, false, null, null, false, null); + Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, false, false, false, null,null, null, false, null); assertNotNull("Isolated network offering with specifyVlan=true wasn't created", off); } @@ -193,7 +193,7 @@ public class CreateNetworkOfferingTest extends TestCase { serviceProviderMap.put(Network.Service.SourceNat, vrProvider); NetworkOfferingVO off = configMgr.createNetworkOffering("isolated", "isolated", TrafficType.Guest, null, false, Availability.Optional, 200, serviceProviderMap, false, - Network.GuestType.Isolated, false, null, false, null, true, false, null, false, null, true, false, false, false, null, null, false, null); + Network.GuestType.Isolated, false, null, false, null, true, false, null, false, null, true, false, false, false, null,null, null, false, null); assertNull("Isolated network offering with specifyIpRanges=true and source nat service enabled, was created", off); } @@ -204,7 +204,7 @@ public class CreateNetworkOfferingTest extends TestCase { Set vrProvider = new HashSet(); NetworkOfferingVO off = configMgr.createNetworkOffering("isolated", "isolated", TrafficType.Guest, null, false, Availability.Optional, 200, serviceProviderMap, false, - Network.GuestType.Isolated, false, null, false, null, true, false, null, false, null, true, false, false, false, null, null, false, null); + Network.GuestType.Isolated, false, null, false, null, true, false, null, false, null, true, false, false, false, null,null, null, false, null); assertNotNull("Isolated network offering with specifyIpRanges=true and with no sourceNatService, failed to create", off); } @@ -222,7 +222,7 @@ public class CreateNetworkOfferingTest extends TestCase { serviceProviderMap.put(Network.Service.Lb, vrProvider); NetworkOfferingVO off = configMgr.createNetworkOffering("isolated", "isolated", TrafficType.Guest, null, true, Availability.Optional, 200, serviceProviderMap, false, - Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, true, false, false, null, null, false, null); + Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, true, false, false, null, null, null, false, null); // System.out.println("Creating Vpc Network Offering"); assertNotNull("Vpc Isolated network offering with Vpc provider ", off); } @@ -242,7 +242,7 @@ public class CreateNetworkOfferingTest extends TestCase { serviceProviderMap.put(Network.Service.Lb, lbProvider); NetworkOfferingVO off = configMgr.createNetworkOffering("isolated", "isolated", TrafficType.Guest, null, true, Availability.Optional, 200, serviceProviderMap, false, - Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, true, false, false, null, null, false, null); + Network.GuestType.Isolated, false, null, false, null, false, false, null, false, null, true, true, false, false, null, null, null, false, null); // System.out.println("Creating Vpc Network Offering"); assertNotNull("Vpc Isolated network offering with Vpc and Netscaler provider ", off); } diff --git a/ui/public/locales/en.json b/ui/public/locales/en.json index aa3b843780b..43cb291e8db 100644 --- a/ui/public/locales/en.json +++ b/ui/public/locales/en.json @@ -871,6 +871,7 @@ "label.forceencap": "Force UDP encapsulation of ESP packets", "label.forgedtransmits": "Forged transmits", "label.format": "Format", +"label.fornsx": "NSX", "label.free": "Free", "label.french.azerty.keyboard": "French AZERTY keyboard", "label.friday": "Friday", @@ -1284,6 +1285,7 @@ "label.minorsequence": "Minor Sequence", "label.minsize": "Minimum size", "label.minute.past.hour": "minute(s) past the hour", +"label.mode": "Mode", "label.monday": "Monday", "label.monitor": "Monitor", "label.monitor.expected.code": "Expected HTTP Status Code", @@ -1377,6 +1379,8 @@ "label.not.found": "Not found", "label.not.suitable": "Not suitable", "label.notifications": "Notifications", +"label.nsx": "NSX", +"label.nsx.mode": "NSX Mode", "label.nsx.provider": "NSX Provider", "label.nsx.provider.name": "NSX provider name", "label.nsx.provider.hostname": "NSX provider hostname", @@ -1555,6 +1559,7 @@ "label.public.ips": "Public IP addresses", "label.public.lb": "Public LB", "label.public.traffic": "Public traffic", +"label.public.traffic.nsx": "NSX Public traffic", "label.publicinterface": "Public interface", "label.publicip": "IP address", "label.publicipid": "IP address ID", diff --git a/ui/src/components/CheckBoxSelectPair.vue b/ui/src/components/CheckBoxSelectPair.vue index de6aed473cb..4fba1da2556 100644 --- a/ui/src/components/CheckBoxSelectPair.vue +++ b/ui/src/components/CheckBoxSelectPair.vue @@ -21,6 +21,7 @@ {{ checkBoxLabel }} @@ -30,7 +31,8 @@ v-if="reversed !== checked" :label="selectLabel">
- {{ service.name }} : {{ service.provider[0].name }} + {{ service.name }} : {{ service.provider?.[0]?.name }}
diff --git a/ui/src/config/section/offering.js b/ui/src/config/section/offering.js index c44de61fb79..df4e264276b 100644 --- a/ui/src/config/section/offering.js +++ b/ui/src/config/section/offering.js @@ -262,7 +262,7 @@ export default { docHelp: 'adminguide/networking.html#network-offerings', permission: ['listNetworkOfferings'], columns: ['name', 'state', 'guestiptype', 'traffictype', 'networkrate', 'domain', 'zone', 'order'], - details: ['name', 'id', 'displaytext', 'guestiptype', 'traffictype', 'internetprotocol', 'networkrate', 'ispersistent', 'egressdefaultpolicy', 'availability', 'conservemode', 'specifyvlan', 'specifyipranges', 'supportspublicaccess', 'supportsstrechedl2subnet', 'service', 'tags', 'domain', 'zone'], + details: ['name', 'id', 'displaytext', 'guestiptype', 'traffictype', 'internetprotocol', 'networkrate', 'ispersistent', 'egressdefaultpolicy', 'availability', 'conservemode', 'specifyvlan', 'specifyipranges', 'supportspublicaccess', 'supportsstrechedl2subnet', 'forvpc', 'fornsx', 'nsxmode', 'service', 'tags', 'domain', 'zone'], resourceType: 'NetworkOffering', tabs: [ { @@ -355,7 +355,7 @@ export default { permission: ['listVPCOfferings'], resourceType: 'VpcOffering', columns: ['name', 'state', 'displaytext', 'domain', 'zone', 'order'], - details: ['name', 'id', 'displaytext', 'internetprotocol', 'distributedvpcrouter', 'tags', 'service', 'domain', 'zone', 'created'], + details: ['name', 'id', 'displaytext', 'internetprotocol', 'distributedvpcrouter', 'tags', 'service', 'fornsx', 'nsxmode', 'domain', 'zone', 'created'], related: [{ name: 'vpc', title: 'label.vpc', diff --git a/ui/src/views/offering/AddNetworkOffering.vue b/ui/src/views/offering/AddNetworkOffering.vue index 17359e4e0c0..5af0c000165 100644 --- a/ui/src/views/offering/AddNetworkOffering.vue +++ b/ui/src/views/offering/AddNetworkOffering.vue @@ -41,7 +41,7 @@ v-model:value="form.displaytext" :placeholder="apiParams.displaytext.description"/> - + @@ -60,10 +60,10 @@ {{ $t('label.isolated') }} - + {{ $t('label.l2') }} - + {{ $t('label.shared') }} @@ -93,7 +93,7 @@ - +