mirror of https://github.com/apache/cloudstack.git
Merge branch 'nsx-integration' of https://github.com/apache/cloudstack into nsx-static-nat
This commit is contained in:
commit
015a3a11da
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -53,9 +53,6 @@ import java.util.Map;
|
|||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
|
||||
|
||||
|
||||
public class NsxProviderServiceImpl implements NsxProviderService {
|
||||
|
||||
@Inject
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue