Merge branch 'nsx-integration' of https://github.com/apache/cloudstack into nsx-static-nat

This commit is contained in:
Pearl Dsilva 2023-10-23 11:12:16 -04:00
commit 015a3a11da
26 changed files with 1416 additions and 450 deletions

View File

@ -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);
@ -1470,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<UserVmJoinVO> userVmJoinVOs = userVmJoinDao.searchByIds(vm.getId());
Map<Long, String> networkToNetworkNameMap = new HashMap<>();
@ -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 {

View File

@ -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<UserVmJoinVO> 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");
}
}

View File

@ -24,9 +24,9 @@ public class CreateNsxDhcpRelayConfigCommand extends NsxCommand {
private String networkName;
private List<String> addresses;
public CreateNsxDhcpRelayConfigCommand(String zoneName, Long zoneId, String accountName, Long accountId,
public CreateNsxDhcpRelayConfigCommand(String domainName, String accountName, String zoneName,
String vpcName, String networkName, List<String> addresses) {
super(zoneName, zoneId, accountName, accountId);
super(domainName, accountName, zoneName);
this.vpcName = vpcName;
this.networkName = networkName;
this.addresses = addresses;

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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 accountName, String vpcName, NetworkVO network) {
super(null, 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;
}
}

View File

@ -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;
}
}

View File

@ -22,48 +22,30 @@ 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() {
}
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 +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(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);
}
}

View File

@ -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,13 +65,12 @@ public class NsxResource implements ServerResource {
protected String transportZone;
protected String zoneId;
protected NsxApi nsxApi;
protected NsxApiClient nsxApiClient;
@Override
public Host.Type getType() {
return Host.Type.Routing;
}
@Override
public StartupCommand[] initialize() {
StartupNsxCommand sc = new StartupNsxCommand();
@ -236,56 +205,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<String> 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 +250,21 @@ public class NsxResource implements ServerResource {
return new ReadyAnswer(cmd);
}
private Function<Class<? extends Service>, 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<com.vmware.nsx_policy.model.LocaleServices> 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,140 +273,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<TransportZone> 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);
segmentService.delete(segmentName);
DhcpRelayConfigs dhcpRelayConfig = (DhcpRelayConfigs) nsxService.apply(DhcpRelayConfigs.class);
dhcpRelayConfig.delete(getDhcpRelayId(cmd.getZoneName(), cmd.getAccountName(), cmd.getVpcName(), cmd.getTierNetwork().getName()));
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<com.vmware.nsx_policy.model.LocaleServices> 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;

View File

@ -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;
}
}

View File

@ -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<Class<? extends Service>, 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<String> 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<com.vmware.nsx_policy.model.LocaleServices> 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<com.vmware.nsx_policy.model.LocaleServices> 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<TransportZone> 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);
}
}
}

View File

@ -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;
@ -59,6 +61,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;
@ -96,6 +99,8 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, DnsS
PhysicalNetworkDao physicalNetworkDao;
@Inject
NetworkModel networkModel;
@Inject
DomainDao domainDao;
private static final Logger LOGGER = Logger.getLogger(NsxElement.class);
@ -112,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<Network.Capability, String> sourceNatCapabilities = new HashMap<>();
@ -195,7 +199,14 @@ 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());
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(), domain.getName(), networkVO);
}
@Override
@ -222,7 +233,7 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, DnsS
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
agentManager.registerForHostEvents(this, true, true, true);
resourceManager.registerResourceStateAdapter(this.getClass().getSimpleName(), this);
return false;
return true;
}
@Override
@ -254,6 +265,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());
@ -265,7 +286,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
@ -279,8 +301,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<Boolean, Account> validateVpcConfigurationAndGetAccount(DataCenterVO zone, Vpc vpc) {

View File

@ -20,9 +20,10 @@ 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;
import com.cloud.domain.dao.DomainDao;
import com.cloud.exception.InsufficientAddressCapacityException;
import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
import com.cloud.exception.InvalidParameterValueException;
@ -48,6 +49,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;
@ -62,9 +65,9 @@ public class NsxGuestNetworkGuru extends GuestNetworkGuru implements NetworkMigr
@Inject
NsxControllerUtils nsxControllerUtils;
@Inject
DataCenterDao zoneDao;
@Inject
AccountDao accountDao;
@Inject
DomainDao domainDao;
public NsxGuestNetworkGuru() {
super();
@ -132,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));
}
@ -173,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;
}
@ -211,12 +204,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<String> 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 +263,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 +275,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");

View File

@ -53,9 +53,6 @@ import java.util.Map;
import java.util.Objects;
import java.util.UUID;
public class NsxProviderServiceImpl implements NsxProviderService {
@Inject

View File

@ -23,37 +23,38 @@ 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;
public class NsxServiceImpl implements NsxService {
@Inject
private NsxControllerUtils nsxControllerUtils;
NsxControllerUtils nsxControllerUtils;
@Inject
private VpcDao vpcDao;
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 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(accountName, vpcName, network);
DeleteNsxSegmentCommand deleteNsxSegmentCommand = new DeleteNsxSegmentCommand(domainName, accountName, zoneName, vpcName, network.getName());
NsxAnswer result = nsxControllerUtils.sendNsxCommand(deleteNsxSegmentCommand, network.getDataCenterId());
return result.getResult();
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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<String> 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());
}
}

View File

@ -33,6 +33,6 @@
</bean>
<bean id="nsxProviderService" class="org.apache.cloudstack.service.NsxProviderServiceImpl"/>
<bean id="nsxService" class="org.apache.cloudstack.service.NsxServiceImpl"/>
<bean id="nsxControllerUtils" class="org.apache.cloudstack.service.NsxControllerUtils" />
<bean id="nsxControllerUtils" class="org.apache.cloudstack.utils.NsxControllerUtils" />
</beans>

View File

@ -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<String, Object> 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<String, Object> 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<Site> siteList = List.of(site);
EnforcementPoint enforcementPoint = mock(EnforcementPoint.class);
List<EnforcementPoint> enforcementPointList = List.of(enforcementPoint);
List<TransportZone> 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());
}
}

View File

@ -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<PhysicalNetworkVO> 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));
}
}

View File

@ -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());
}
}

View File

@ -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<BaseResponse> baseResponseList = nsxProviderService.listNsxProviders(1L);
assertEquals(1, baseResponseList.size());
}
@Test
public void testDeleteNsxController() {
NsxProviderVO nsxProviderVO = Mockito.mock(NsxProviderVO.class);
PhysicalNetworkVO physicalNetworkVO = mock(PhysicalNetworkVO.class);
List<PhysicalNetworkVO> physicalNetworkVOList = List.of(physicalNetworkVO);
NetworkVO networkVO = mock(NetworkVO.class);
List<NetworkVO> 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));
}
}

View File

@ -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));
}
}

View File

@ -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;
}

View File

@ -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<ManagedObjectReference, String> 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);
}
}