mirror of https://github.com/apache/cloudstack.git
Merge branch '4.16' into main
This commit is contained in:
commit
e1b56be67c
|
|
@ -47,8 +47,8 @@ public interface Volume extends ControlledEntity, Identity, InternalIdentity, Ba
|
|||
RevertSnapshotting("There is a snapshot created on this volume, the volume is being reverting from snapshot"),
|
||||
Resizing("The volume is being resized"),
|
||||
Expunging("The volume is being expunging"),
|
||||
Expunged("The volume has been expunged"),
|
||||
Destroy("The volume is destroyed, and can't be recovered."),
|
||||
Expunged("The volume has been expunged, and can no longer be recovered"),
|
||||
Destroy("The volume is destroyed, and can be recovered."),
|
||||
Destroying("The volume is destroying, and can't be recovered."),
|
||||
UploadOp("The volume upload operation is in progress or in short the volume is on secondary storage"),
|
||||
Copying("Volume is copying from image store to primary, in case it's an uploaded volume"),
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ package org.apache.cloudstack.api.command.admin.vm;
|
|||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
||||
import org.apache.cloudstack.api.ACL;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
|
|
@ -43,6 +45,7 @@ public class RecoverVMCmd extends BaseCmd {
|
|||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@ACL(accessType = AccessType.OperateEntry)
|
||||
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = UserVmResponse.class, required = true, description = "The ID of the virtual machine")
|
||||
private Long id;
|
||||
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ import java.util.stream.Collectors;
|
|||
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
import javax.persistence.EntityExistsException;
|
||||
|
||||
import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
|
||||
import org.apache.cloudstack.annotation.AnnotationService;
|
||||
|
|
@ -191,7 +192,6 @@ import com.cloud.offering.NetworkOffering;
|
|||
import com.cloud.offering.ServiceOffering;
|
||||
import com.cloud.offerings.NetworkOfferingVO;
|
||||
import com.cloud.offerings.dao.NetworkOfferingDao;
|
||||
import com.cloud.offerings.dao.NetworkOfferingDetailsDao;
|
||||
import com.cloud.org.Cluster;
|
||||
import com.cloud.resource.ResourceManager;
|
||||
import com.cloud.resource.ResourceState;
|
||||
|
|
@ -354,8 +354,6 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
@Inject
|
||||
private StorageManager storageMgr;
|
||||
@Inject
|
||||
private NetworkOfferingDetailsDao networkOfferingDetailsDao;
|
||||
@Inject
|
||||
private NetworkDetailsDao networkDetailsDao;
|
||||
@Inject
|
||||
private SecurityGroupManager _securityGroupManager;
|
||||
|
|
@ -3820,8 +3818,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
|
||||
final AsyncJobExecutionContext jobContext = AsyncJobExecutionContext.getCurrentExecutionContext();
|
||||
if (jobContext.isJobDispatchedBy(VmWorkConstants.VM_WORK_JOB_DISPATCHER)) {
|
||||
VmWorkJobVO placeHolder = createPlaceHolderWork(vm.getId());
|
||||
|
||||
VmWorkJobVO placeHolder = createPlaceHolderWork(vm.getId(), network.getUuid());
|
||||
try {
|
||||
return orchestrateAddVmToNetwork(vm, network, requested);
|
||||
} finally {
|
||||
|
|
@ -3840,7 +3837,19 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
return (NicProfile) jobResult;
|
||||
}
|
||||
|
||||
throw new RuntimeException("Unexpected job execution result");
|
||||
throw new RuntimeException("null job execution result");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* duplicated in {@see UserVmManagerImpl} for a {@see UserVmVO}
|
||||
*/
|
||||
private void checkIfNetworkExistsForVM(VirtualMachine virtualMachine, Network network) {
|
||||
List<NicVO> allNics = _nicsDao.listByVmId(virtualMachine.getId());
|
||||
for (NicVO nic : allNics) {
|
||||
if (nic.getNetworkId() == network.getId()) {
|
||||
throw new CloudRuntimeException("A NIC already exists for VM:" + virtualMachine.getInstanceName() + " in network: " + network.getUuid());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3848,6 +3857,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
InsufficientCapacityException {
|
||||
final CallContext cctx = CallContext.current();
|
||||
|
||||
checkIfNetworkExistsForVM(vm, network);
|
||||
s_logger.debug("Adding vm " + vm + " to network " + network + "; requested nic profile " + requested);
|
||||
final VMInstanceVO vmVO = _vmDao.findById(vm.getId());
|
||||
final ReservationContext context = new ReservationContextImpl(null, null, cctx.getCallingUser(), cctx.getCallingAccount());
|
||||
|
|
@ -5141,37 +5151,64 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
|
||||
final List<VmWorkJobVO> pendingWorkJobs = _workJobDao.listPendingWorkJobs(
|
||||
VirtualMachine.Type.Instance, vm.getId(),
|
||||
VmWorkAddVmToNetwork.class.getName());
|
||||
VmWorkAddVmToNetwork.class.getName(), network.getUuid());
|
||||
|
||||
VmWorkJobVO workJob = null;
|
||||
if (pendingWorkJobs != null && pendingWorkJobs.size() > 0) {
|
||||
assert pendingWorkJobs.size() == 1;
|
||||
if (pendingWorkJobs.size() > 1) {
|
||||
throw new CloudRuntimeException(String.format("The number of jobs to add network %s to vm %s are %d", network.getUuid(), vm.getInstanceName(), pendingWorkJobs.size()));
|
||||
}
|
||||
workJob = pendingWorkJobs.get(0);
|
||||
} else {
|
||||
if (s_logger.isTraceEnabled()) {
|
||||
s_logger.trace(String.format("no jobs to add network %s for vm %s yet", network, vm));
|
||||
}
|
||||
|
||||
workJob = new VmWorkJobVO(context.getContextId());
|
||||
|
||||
workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
|
||||
workJob.setCmd(VmWorkAddVmToNetwork.class.getName());
|
||||
|
||||
workJob.setAccountId(account.getId());
|
||||
workJob.setUserId(user.getId());
|
||||
workJob.setVmType(VirtualMachine.Type.Instance);
|
||||
workJob.setVmInstanceId(vm.getId());
|
||||
workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
|
||||
|
||||
// save work context info (there are some duplications)
|
||||
final VmWorkAddVmToNetwork workInfo = new VmWorkAddVmToNetwork(user.getId(), account.getId(), vm.getId(),
|
||||
VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, network.getId(), requested);
|
||||
workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
|
||||
|
||||
_jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
|
||||
workJob = createVmWorkJobToAddNetwork(vm, network, requested, context, user, account);
|
||||
}
|
||||
AsyncJobExecutionContext.getCurrentExecutionContext().joinJob(workJob.getId());
|
||||
|
||||
return new VmJobVirtualMachineOutcome(workJob, vm.getId());
|
||||
}
|
||||
|
||||
private VmWorkJobVO createVmWorkJobToAddNetwork(
|
||||
VirtualMachine vm,
|
||||
Network network,
|
||||
NicProfile requested,
|
||||
CallContext context,
|
||||
User user,
|
||||
Account account) {
|
||||
VmWorkJobVO workJob;
|
||||
workJob = new VmWorkJobVO(context.getContextId());
|
||||
|
||||
workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_DISPATCHER);
|
||||
workJob.setCmd(VmWorkAddVmToNetwork.class.getName());
|
||||
|
||||
workJob.setAccountId(account.getId());
|
||||
workJob.setUserId(user.getId());
|
||||
workJob.setVmType(VirtualMachine.Type.Instance);
|
||||
workJob.setVmInstanceId(vm.getId());
|
||||
workJob.setRelated(AsyncJobExecutionContext.getOriginJobId());
|
||||
workJob.setSecondaryObjectIdentifier(network.getUuid());
|
||||
|
||||
// save work context info as there might be some duplicates
|
||||
final VmWorkAddVmToNetwork workInfo = new VmWorkAddVmToNetwork(user.getId(), account.getId(), vm.getId(),
|
||||
VirtualMachineManagerImpl.VM_WORK_JOB_HANDLER, network.getId(), requested);
|
||||
workJob.setCmdInfo(VmWorkSerializer.serialize(workInfo));
|
||||
|
||||
try {
|
||||
_jobMgr.submitAsyncJob(workJob, VmWorkConstants.VM_WORK_QUEUE, vm.getId());
|
||||
} catch (CloudRuntimeException e) {
|
||||
if (e.getCause() instanceof EntityExistsException) {
|
||||
String msg = String.format("A job to add a nic for network %s to vm %s already exists", network.getUuid(), vm.getUuid());
|
||||
s_logger.warn(msg, e);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
||||
return workJob;
|
||||
}
|
||||
|
||||
public Outcome<VirtualMachine> removeNicFromVmThroughJobQueue(
|
||||
final VirtualMachine vm, final Nic nic) {
|
||||
Long vmId = vm.getId();
|
||||
|
|
@ -5374,6 +5411,10 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
}
|
||||
|
||||
private VmWorkJobVO createPlaceHolderWork(final long instanceId) {
|
||||
return createPlaceHolderWork(instanceId, null);
|
||||
}
|
||||
|
||||
private VmWorkJobVO createPlaceHolderWork(final long instanceId, String secondaryObjectIdentifier) {
|
||||
final VmWorkJobVO workJob = new VmWorkJobVO("");
|
||||
|
||||
workJob.setDispatcher(VmWorkConstants.VM_WORK_JOB_PLACEHOLDER);
|
||||
|
|
@ -5385,6 +5426,9 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
|
|||
workJob.setStep(VmWorkJobVO.Step.Starting);
|
||||
workJob.setVmType(VirtualMachine.Type.Instance);
|
||||
workJob.setVmInstanceId(instanceId);
|
||||
if(org.apache.commons.lang3.StringUtils.isNotBlank(secondaryObjectIdentifier)) {
|
||||
workJob.setSecondaryObjectIdentifier(secondaryObjectIdentifier);
|
||||
}
|
||||
workJob.setInitMsid(ManagementServerNode.getManagementServerId());
|
||||
|
||||
_workJobDao.persist(workJob);
|
||||
|
|
|
|||
|
|
@ -17,4 +17,6 @@
|
|||
|
||||
--;
|
||||
-- Schema upgrade from 4.16.0.0 to 4.16.1.0
|
||||
--;
|
||||
--;
|
||||
|
||||
ALTER TABLE `cloud`.`vm_work_job` ADD COLUMN `secondary_object` char(100) COMMENT 'any additional item that must be checked during queueing' AFTER `vm_instance_id`;
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ public interface VmWorkJobDao extends GenericDao<VmWorkJobVO, Long> {
|
|||
|
||||
List<VmWorkJobVO> listPendingWorkJobs(VirtualMachine.Type type, long instanceId, String jobCmd);
|
||||
|
||||
List<VmWorkJobVO> listPendingWorkJobs(VirtualMachine.Type type, long instanceId, String jobCmd, String secondaryObjectIdentifier);
|
||||
|
||||
void updateStep(long workJobId, Step step);
|
||||
|
||||
void expungeCompletedWorkJobs(Date cutDate);
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ public class VmWorkJobDaoImpl extends GenericDaoBase<VmWorkJobVO, Long> implemen
|
|||
PendingWorkJobByCommandSearch.and("jobStatus", PendingWorkJobByCommandSearch.entity().getStatus(), Op.EQ);
|
||||
PendingWorkJobByCommandSearch.and("vmType", PendingWorkJobByCommandSearch.entity().getVmType(), Op.EQ);
|
||||
PendingWorkJobByCommandSearch.and("vmInstanceId", PendingWorkJobByCommandSearch.entity().getVmInstanceId(), Op.EQ);
|
||||
PendingWorkJobByCommandSearch.and("secondaryObjectIdentifier", PendingWorkJobByCommandSearch.entity().getSecondaryObjectIdentifier(), Op.EQ);
|
||||
PendingWorkJobByCommandSearch.and("step", PendingWorkJobByCommandSearch.entity().getStep(), Op.NEQ);
|
||||
PendingWorkJobByCommandSearch.and("cmd", PendingWorkJobByCommandSearch.entity().getCmd(), Op.EQ);
|
||||
PendingWorkJobByCommandSearch.done();
|
||||
|
|
@ -119,6 +120,19 @@ public class VmWorkJobDaoImpl extends GenericDaoBase<VmWorkJobVO, Long> implemen
|
|||
return this.listBy(sc, filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<VmWorkJobVO> listPendingWorkJobs(VirtualMachine.Type type, long instanceId, String jobCmd, String secondaryObjectIdentifier) {
|
||||
SearchCriteria<VmWorkJobVO> sc = PendingWorkJobByCommandSearch.create();
|
||||
sc.setParameters("jobStatus", JobInfo.Status.IN_PROGRESS);
|
||||
sc.setParameters("vmType", type);
|
||||
sc.setParameters("vmInstanceId", instanceId);
|
||||
sc.setParameters("secondaryObjectIdentifier", secondaryObjectIdentifier);
|
||||
sc.setParameters("cmd", jobCmd);
|
||||
|
||||
Filter filter = new Filter(VmWorkJobVO.class, "created", true, null, null);
|
||||
return this.listBy(sc, filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateStep(long workJobId, Step step) {
|
||||
VmWorkJobVO jobVo = findById(workJobId);
|
||||
|
|
|
|||
|
|
@ -384,7 +384,7 @@ public class AsyncJobVO implements AsyncJob, JobInfo {
|
|||
@Override
|
||||
public String toString() {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append("AsyncJobVO {id:").append(getId());
|
||||
sb.append("AsyncJobVO: {id:").append(getId());
|
||||
sb.append(", userId: ").append(getUserId());
|
||||
sb.append(", accountId: ").append(getAccountId());
|
||||
sb.append(", instanceType: ").append(getInstanceType());
|
||||
|
|
|
|||
|
|
@ -58,6 +58,9 @@ public class VmWorkJobVO extends AsyncJobVO {
|
|||
@Column(name = "vm_instance_id")
|
||||
long vmInstanceId;
|
||||
|
||||
@Column(name = "secondary_object")
|
||||
String secondaryObjectIdentifier;
|
||||
|
||||
protected VmWorkJobVO() {
|
||||
}
|
||||
|
||||
|
|
@ -89,4 +92,25 @@ public class VmWorkJobVO extends AsyncJobVO {
|
|||
public void setVmInstanceId(long vmInstanceId) {
|
||||
this.vmInstanceId = vmInstanceId;
|
||||
}
|
||||
|
||||
public String getSecondaryObjectIdentifier() {
|
||||
return secondaryObjectIdentifier;
|
||||
}
|
||||
|
||||
public void setSecondaryObjectIdentifier(String secondaryObjectIdentifier) {
|
||||
this.secondaryObjectIdentifier = secondaryObjectIdentifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append("VmWorkJobVO : {").
|
||||
append(", step: ").append(getStep()).
|
||||
append(", vmType: ").append(getVmType()).
|
||||
append(", vmInstanceId: ").append(getVmInstanceId()).
|
||||
append(", secondaryObjectIdentifier: ").append(getSecondaryObjectIdentifier()).
|
||||
append(super.toString()).
|
||||
append("}");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,6 +37,9 @@ public final class LibvirtGetStorageStatsCommandWrapper extends CommandWrapper<G
|
|||
try {
|
||||
final KVMStoragePoolManager storagePoolMgr = libvirtComputingResource.getStoragePoolMgr();
|
||||
final KVMStoragePool sp = storagePoolMgr.getStoragePool(command.getPooltype(), command.getStorageId(), true);
|
||||
if (sp == null) {
|
||||
return new GetStorageStatsAnswer(command, "no storage pool to get statistics from");
|
||||
}
|
||||
return new GetStorageStatsAnswer(command, sp.getCapacity(), sp.getUsed());
|
||||
} catch (final CloudRuntimeException e) {
|
||||
return new GetStorageStatsAnswer(command, e.toString());
|
||||
|
|
|
|||
|
|
@ -1463,7 +1463,7 @@ public class KVMStorageProcessor implements StorageProcessor {
|
|||
primaryPool = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid());
|
||||
disksize = volume.getSize();
|
||||
PhysicalDiskFormat format;
|
||||
if (volume.getFormat() == null) {
|
||||
if (volume.getFormat() == null || StoragePoolType.RBD.equals(primaryStore.getPoolType())) {
|
||||
format = primaryPool.getDefaultFormat();
|
||||
} else {
|
||||
format = PhysicalDiskFormat.valueOf(volume.getFormat().toString().toUpperCase());
|
||||
|
|
|
|||
|
|
@ -1659,8 +1659,7 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel, Confi
|
|||
throw new CloudRuntimeException("cannot check permissions on (Network) <null>");
|
||||
}
|
||||
// Perform account permission check
|
||||
if ((network.getGuestType() != GuestType.Shared && network.getGuestType() != GuestType.L2) ||
|
||||
(network.getGuestType() == GuestType.Shared && network.getAclType() == ACLType.Account)) {
|
||||
if (network.getGuestType() != GuestType.Shared || network.getAclType() == ACLType.Account) {
|
||||
AccountVO networkOwner = _accountDao.findById(network.getAccountId());
|
||||
if (networkOwner == null)
|
||||
throw new PermissionDeniedException("Unable to use network with id= " + ((NetworkVO)network).getUuid() +
|
||||
|
|
@ -1838,14 +1837,14 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel, Confi
|
|||
public boolean isNetworkAvailableInDomain(long networkId, long domainId) {
|
||||
Long networkDomainId = null;
|
||||
Network network = getNetwork(networkId);
|
||||
if (network.getGuestType() != GuestType.Shared && network.getGuestType() != GuestType.L2) {
|
||||
s_logger.trace("Network id=" + networkId + " is not shared or L2");
|
||||
if (network.getGuestType() != GuestType.Shared) {
|
||||
s_logger.trace("Network id=" + networkId + " is not shared");
|
||||
return false;
|
||||
}
|
||||
|
||||
NetworkDomainVO networkDomainMap = _networkDomainDao.getDomainNetworkMapByNetworkId(networkId);
|
||||
if (networkDomainMap == null) {
|
||||
s_logger.trace("Network id=" + networkId + " is shared or L2, but not domain specific");
|
||||
s_logger.trace("Network id=" + networkId + " is shared, but not domain specific");
|
||||
return true;
|
||||
} else {
|
||||
networkDomainId = networkDomainMap.getDomainId();
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import java.util.Set;
|
|||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.cloud.exception.UnsupportedServiceException;
|
||||
import com.cloud.network.element.UserDataServiceProvider;
|
||||
import com.cloud.storage.VMTemplateVO;
|
||||
import com.cloud.storage.dao.VMTemplateDao;
|
||||
|
|
@ -605,7 +606,7 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
|
|||
// enable static nat on the backend
|
||||
s_logger.trace("Enabling static nat for ip address " + ipAddress + " and vm id=" + vmId + " on the backend");
|
||||
if (applyStaticNatForIp(ipId, false, caller, false)) {
|
||||
applyUserData(vmId, network, guestNic);
|
||||
applyUserDataIfNeeded(vmId, network, guestNic);
|
||||
performedIpAssoc = false; // ignor unassignIPFromVpcNetwork in finally block
|
||||
return true;
|
||||
} else {
|
||||
|
|
@ -629,8 +630,14 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
|
|||
return false;
|
||||
}
|
||||
|
||||
protected void applyUserData(long vmId, Network network, Nic guestNic) throws ResourceUnavailableException {
|
||||
UserDataServiceProvider element = _networkModel.getUserDataUpdateProvider(network);
|
||||
protected void applyUserDataIfNeeded(long vmId, Network network, Nic guestNic) throws ResourceUnavailableException {
|
||||
UserDataServiceProvider element = null;
|
||||
try {
|
||||
element = _networkModel.getUserDataUpdateProvider(network);
|
||||
} catch (UnsupportedServiceException ex) {
|
||||
s_logger.info(String.format("%s is not supported by network %s, skipping.", Service.UserData.getName(), network));
|
||||
return;
|
||||
}
|
||||
if (element == null) {
|
||||
s_logger.error("Can't find network element for " + Service.UserData.getName() + " provider needed for UserData update");
|
||||
} else {
|
||||
|
|
@ -1144,7 +1151,7 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
|
|||
Nic guestNic = _networkModel.getNicInNetwork(vmId, guestNetwork.getId());
|
||||
if (applyStaticNatForIp(ipId, false, caller, true)) {
|
||||
if (ipAddress.getState() == IpAddress.State.Releasing) {
|
||||
applyUserData(vmId, guestNetwork, guestNic);
|
||||
applyUserDataIfNeeded(vmId, guestNetwork, guestNic);
|
||||
}
|
||||
} else {
|
||||
success = false;
|
||||
|
|
@ -1289,7 +1296,7 @@ public class RulesManagerImpl extends ManagerBase implements RulesManager, Rules
|
|||
|
||||
if (disableStaticNat(ipId, caller, ctx.getCallingUserId(), false)) {
|
||||
Nic guestNic = _networkModel.getNicInNetworkIncludingRemoved(vmId, guestNetwork.getId());
|
||||
applyUserData(vmId, guestNetwork, guestNic);
|
||||
applyUserDataIfNeeded(vmId, guestNetwork, guestNic);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -1389,12 +1389,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
Account vmOwner = _accountMgr.getAccount(vmInstance.getAccountId());
|
||||
_networkModel.checkNetworkPermissions(vmOwner, network);
|
||||
|
||||
List<NicVO> allNics = _nicDao.listByVmId(vmInstance.getId());
|
||||
for (NicVO nic : allNics) {
|
||||
if (nic.getNetworkId() == network.getId()) {
|
||||
throw new CloudRuntimeException("A NIC already exists for VM:" + vmInstance.getInstanceName() + " in network: " + network.getUuid());
|
||||
}
|
||||
}
|
||||
checkIfNetExistsForVM(vmInstance, network);
|
||||
|
||||
macAddress = validateOrReplaceMacAddress(macAddress, network.getId());
|
||||
|
||||
|
|
@ -1461,10 +1456,22 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
}
|
||||
}
|
||||
CallContext.current().putContextParameter(Nic.class, guestNic.getUuid());
|
||||
s_logger.debug("Successful addition of " + network + " from " + vmInstance);
|
||||
s_logger.debug(String.format("Successful addition of %s from %s through %s", network, vmInstance, guestNic));
|
||||
return _vmDao.findById(vmInstance.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* duplicated in {@see VirtualMachineManagerImpl} for a {@see VMInstanceVO}
|
||||
*/
|
||||
private void checkIfNetExistsForVM(VirtualMachine virtualMachine, Network network) {
|
||||
List<NicVO> allNics = _nicDao.listByVmId(virtualMachine.getId());
|
||||
for (NicVO nic : allNics) {
|
||||
if (nic.getNetworkId() == network.getId()) {
|
||||
throw new CloudRuntimeException("A NIC already exists for VM:" + virtualMachine.getInstanceName() + " in network: " + network.getUuid());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the given MAC address is invalid it replaces the given MAC with the next available MAC address
|
||||
*/
|
||||
|
|
@ -4419,6 +4426,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
value = DBEncryptionUtil.encrypt(value);
|
||||
}
|
||||
}
|
||||
} else if (value == null) {
|
||||
value = "";
|
||||
}
|
||||
if (s_logger.isTraceEnabled()) {
|
||||
s_logger.trace(String.format("setting property '%s' as '%s' with value '%s'", key, detailKey, value));
|
||||
|
|
|
|||
|
|
@ -192,6 +192,8 @@ class TestVMWareStoragePolicies(cloudstackTestCase):
|
|||
self.apiclient,
|
||||
self.testdata["l2-network"],
|
||||
zoneid=self.zone.id,
|
||||
accountid=self.account.name,
|
||||
domainid=self.account.domainid,
|
||||
networkofferingid=self.network_offering.id
|
||||
)
|
||||
self.cleanup.append(l2_network)
|
||||
|
|
|
|||
|
|
@ -2956,6 +2956,9 @@
|
|||
"message.error.retrieve.kubeconfig": "Unable to retrieve Kubernetes cluster config",
|
||||
"message.error.s3nfs.path": "Please enter S3 NFS Path",
|
||||
"message.error.s3nfs.server": "Please enter S3 NFS Server",
|
||||
"message.error.swift.account": "Please enter account",
|
||||
"message.error.swift.key": "Please enter key",
|
||||
"message.error.swift.username": "Please enter username",
|
||||
"message.error.save.setting": "There was an error saving this setting.",
|
||||
"message.error.sbdomain": "Please enter SMB Domain",
|
||||
"message.error.sbdomain.password": "Please enter SMB Domain Password",
|
||||
|
|
|
|||
|
|
@ -1133,7 +1133,7 @@ export default {
|
|||
this.vm.hostname = host.name
|
||||
}
|
||||
|
||||
if (this.serviceOffering.rootdisksize) {
|
||||
if (this.serviceOffering?.rootdisksize) {
|
||||
this.vm.disksizetotalgb = this.serviceOffering.rootdisksize
|
||||
} else if (this.diskSize) {
|
||||
this.vm.disksizetotalgb = this.diskSize
|
||||
|
|
@ -2097,6 +2097,7 @@ export default {
|
|||
this.updateComputeOffering(null)
|
||||
},
|
||||
updateTemplateConfigurationOfferingDetails (offeringId) {
|
||||
this.rootDiskSizeFixed = 0
|
||||
var offering = this.serviceOffering
|
||||
if (!offering || offering.id !== offeringId) {
|
||||
offering = _.find(this.options.serviceOfferings, (option) => option.id === offeringId)
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@
|
|||
>{{ prov }}</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<div v-if="provider !== 'Swift'">
|
||||
<div v-if="!['Swift', 'S3'].includes(provider)">
|
||||
<a-form-item :label="$t('label.zone')">
|
||||
<a-select
|
||||
v-decorator="[
|
||||
|
|
@ -163,6 +163,91 @@
|
|||
/>
|
||||
</a-form-item>
|
||||
</div>
|
||||
<div v-if="provider === 'S3'">
|
||||
<a-form-item :label="$t('label.zone')">
|
||||
<a-select
|
||||
v-decorator="[
|
||||
'zone',
|
||||
{
|
||||
initialValue: this.zoneSelected,
|
||||
rules: [{ required: true, message: `${$t('label.required')}`}]
|
||||
}]"
|
||||
@change="val => { zoneSelected = val }"
|
||||
showSearch
|
||||
optionFilterProp="children"
|
||||
:filterOption="(input, option) => {
|
||||
return option.componentOptions.propsData.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
}" >
|
||||
<a-select-option
|
||||
:value="zone.id"
|
||||
v-for="(zone) in zones"
|
||||
:key="zone.id"
|
||||
:label="zone.name">
|
||||
<span>
|
||||
<resource-icon v-if="zone.icon" :image="zone.icon.base64image" size="1x" style="margin-right: 5px"/>
|
||||
<a-icon v-else type="global" style="margin-right: 5px" />
|
||||
{{ zone.name }}
|
||||
</span>
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item :label="$t('label.s3.access.key')">
|
||||
<a-input
|
||||
v-decorator="[
|
||||
'secondaryStorageAccessKey',
|
||||
{
|
||||
rules: [{ required: true, message: `${$t('label.required')}` }]
|
||||
}]"/>
|
||||
</a-form-item>
|
||||
<a-form-item :label="$t('label.s3.secret.key')">
|
||||
<a-input
|
||||
v-decorator="[
|
||||
'secondaryStorageSecretKey',
|
||||
{
|
||||
rules: [{ required: true, message: `${$t('label.required')}` }]
|
||||
}]"/>
|
||||
</a-form-item>
|
||||
<a-form-item :label="$t('label.s3.bucket')">
|
||||
<a-input
|
||||
v-decorator="[
|
||||
'secondaryStorageBucket',
|
||||
{
|
||||
rules: [{ required: true, message: `${$t('label.required')}` }]
|
||||
}]"/>
|
||||
</a-form-item>
|
||||
<a-form-item :label="$t('label.s3.endpoint')">
|
||||
<a-input v-decorator="['secondaryStorageEndpoint']"/>
|
||||
</a-form-item>
|
||||
<a-form-item :label="$t('label.s3.use.https')">
|
||||
<a-switch v-decorator="['secondaryStorageHttps', { initialValue: true }]" :default-checked="true" />
|
||||
</a-form-item>
|
||||
<a-form-item :label="$t('label.s3.connection.timeout')">
|
||||
<a-input v-decorator="['secondaryStorageConnectionTimeout']"/>
|
||||
</a-form-item>
|
||||
<a-form-item :label="$t('label.s3.max.error.retry')">
|
||||
<a-input v-decorator="['secondaryStorageMaxError']"/>
|
||||
</a-form-item>
|
||||
<a-form-item :label="$t('label.s3.socket.timeout')">
|
||||
<a-input v-decorator="['secondaryStorageSocketTimeout']"/>
|
||||
</a-form-item>
|
||||
<a-form-item :label="$t('label.create.nfs.secondary.staging.storage')">
|
||||
<a-switch v-decorator="['secondaryStorageNFSStaging']" @change="val => secondaryStorageNFSStaging = val" />
|
||||
</a-form-item>
|
||||
</div>
|
||||
<div v-if="secondaryStorageNFSStaging">
|
||||
<a-form-item :label="$t('label.s3.nfs.server')">
|
||||
<a-input
|
||||
v-decorator="['secondaryStorageNFSServer', {
|
||||
rules: [{ required: true, message: `${$t('label.required')}` }]
|
||||
}]"/>
|
||||
</a-form-item>
|
||||
<a-form-item :label="$t('label.s3.nfs.path')">
|
||||
<a-input
|
||||
v-decorator="['secondaryStorageNFSPath', {
|
||||
rules: [{ required: true, message: `${$t('label.required')}` }]
|
||||
}]"/>
|
||||
</a-form-item>
|
||||
</div>
|
||||
<div :span="24" class="action-button">
|
||||
<a-button @click="closeModal">{{ $t('label.cancel') }}</a-button>
|
||||
<a-button type="primary" ref="submit" @click="handleSubmit">{{ $t('label.ok') }}</a-button>
|
||||
|
|
@ -189,11 +274,12 @@ export default {
|
|||
inject: ['parentFetchData'],
|
||||
data () {
|
||||
return {
|
||||
providers: ['NFS', 'SMB/CIFS', 'Swift'],
|
||||
providers: ['NFS', 'SMB/CIFS', 'S3', 'Swift'],
|
||||
provider: '',
|
||||
zones: [],
|
||||
zoneSelected: '',
|
||||
loading: false
|
||||
loading: false,
|
||||
secondaryStorageNFSStaging: false
|
||||
}
|
||||
},
|
||||
beforeCreate () {
|
||||
|
|
@ -245,7 +331,7 @@ export default {
|
|||
handleSubmit (e) {
|
||||
e.preventDefault()
|
||||
if (this.loading) return
|
||||
this.form.validateFieldsAndScroll((err, values) => {
|
||||
this.form.validateFieldsAndScroll(async (err, values) => {
|
||||
if (err) {
|
||||
return
|
||||
}
|
||||
|
|
@ -283,26 +369,100 @@ export default {
|
|||
data['details[' + index.toString() + '].key'] = key
|
||||
data['details[' + index.toString() + '].value'] = swiftParams[key]
|
||||
})
|
||||
} else if (provider === 'S3') {
|
||||
let detailIdx = 0
|
||||
const s3Params = {
|
||||
accesskey: values.secondaryStorageAccessKey,
|
||||
secretkey: values.secondaryStorageSecretKey,
|
||||
bucket: values.secondaryStorageBucket,
|
||||
usehttps: values.secondaryStorageHttps ? values.secondaryStorageHttps : false
|
||||
}
|
||||
Object.keys(s3Params).forEach((key, index) => {
|
||||
data['details[' + index.toString() + '].key'] = key
|
||||
data['details[' + index.toString() + '].value'] = s3Params[key]
|
||||
detailIdx = index
|
||||
})
|
||||
|
||||
if (values.secondaryStorageEndpoint && values.secondaryStorageEndpoint.length > 0) {
|
||||
detailIdx++
|
||||
data['details[' + detailIdx.toString() + '].key'] = 'endpoint'
|
||||
data['details[' + detailIdx.toString() + '].value'] = values.secondaryStorageEndpoint
|
||||
}
|
||||
|
||||
if (values.secondaryStorageConnectionTimeout && values.secondaryStorageConnectionTimeout.length > 0) {
|
||||
detailIdx++
|
||||
data['details[' + detailIdx.toString() + '].key'] = 'connectiontimeout'
|
||||
data['details[' + detailIdx.toString() + '].value'] = values.secondaryStorageConnectionTimeout
|
||||
}
|
||||
|
||||
if (values.secondaryStorageMaxError && values.secondaryStorageMaxError.length > 0) {
|
||||
detailIdx++
|
||||
data['details[' + detailIdx.toString() + '].key'] = 'maxerrorretry'
|
||||
data['details[' + detailIdx.toString() + '].value'] = values.secondaryStorageMaxError
|
||||
}
|
||||
|
||||
if (values.secondaryStorageSocketTimeout && values.secondaryStorageSocketTimeout.length > 0) {
|
||||
detailIdx++
|
||||
data['details[' + detailIdx.toString() + '].key'] = 'sockettimeout'
|
||||
data['details[' + detailIdx.toString() + '].value'] = values.secondaryStorageSocketTimeout
|
||||
}
|
||||
}
|
||||
|
||||
data.url = url
|
||||
if (provider !== 'S3') {
|
||||
data.url = url
|
||||
}
|
||||
data.provider = provider
|
||||
if (values.zone && provider !== 'Swift') {
|
||||
if (values.zone && !['Swift', 'S3'].includes(provider)) {
|
||||
data.zoneid = values.zone
|
||||
}
|
||||
|
||||
const nfsParams = {}
|
||||
if (values.secondaryStorageNFSStaging) {
|
||||
const nfsServer = values.secondaryStorageNFSServer
|
||||
const path = values.secondaryStorageNFSPath
|
||||
const nfsUrl = this.nfsURL(nfsServer, path)
|
||||
|
||||
nfsParams.provider = 'nfs'
|
||||
nfsParams.zoneid = values.zone
|
||||
nfsParams.url = nfsUrl
|
||||
}
|
||||
|
||||
this.loading = true
|
||||
api('addImageStore', data).then(json => {
|
||||
|
||||
try {
|
||||
await this.addImageStore(data)
|
||||
|
||||
if (values.secondaryStorageNFSStaging) {
|
||||
await this.createSecondaryStagingStore(nfsParams)
|
||||
}
|
||||
this.$notification.success({
|
||||
message: this.$t('label.add.secondary.storage'),
|
||||
description: this.$t('label.add.secondary.storage')
|
||||
})
|
||||
this.loading = false
|
||||
this.closeModal()
|
||||
this.parentFetchData()
|
||||
}).catch(error => {
|
||||
} catch (error) {
|
||||
this.$notifyError(error)
|
||||
}).finally(() => {
|
||||
this.loading = false
|
||||
}
|
||||
})
|
||||
},
|
||||
addImageStore (params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
api('addImageStore', params).then(json => {
|
||||
resolve()
|
||||
}).catch(error => {
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
},
|
||||
createSecondaryStagingStore (params) {
|
||||
return new Promise((resolve, reject) => {
|
||||
api('createSecondaryStagingStore', params).then(json => {
|
||||
resolve()
|
||||
}).catch(error => {
|
||||
reject(error)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -216,21 +216,19 @@ export default {
|
|||
if (!conditions || Object.keys(conditions).length === 0) {
|
||||
return true
|
||||
}
|
||||
let isShow = false
|
||||
let isShow = true
|
||||
Object.keys(conditions).forEach(key => {
|
||||
const condition = conditions[key]
|
||||
const fieldVal = this.form.getFieldValue(key)
|
||||
? this.form.getFieldValue(key)
|
||||
: (this.prefillContent[key] ? this.prefillContent[key].value : null)
|
||||
if (Array.isArray(condition) && condition.includes(fieldVal)) {
|
||||
isShow = true
|
||||
return false
|
||||
} else if (!Array.isArray(condition) && fieldVal === condition) {
|
||||
isShow = true
|
||||
return false
|
||||
if (isShow) {
|
||||
const condition = conditions[key]
|
||||
const fieldVal = this.form.getFieldValue(key)
|
||||
? this.form.getFieldValue(key)
|
||||
: (this.prefillContent[key] ? this.prefillContent[key].value : null)
|
||||
if (Array.isArray(condition) && !condition.includes(fieldVal)) {
|
||||
isShow = false
|
||||
} else if (!Array.isArray(condition) && fieldVal !== condition) {
|
||||
isShow = false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
})
|
||||
|
||||
return isShow
|
||||
|
|
|
|||
|
|
@ -570,7 +570,7 @@ export default {
|
|||
}
|
||||
},
|
||||
{
|
||||
title: 'label.s3.access_key',
|
||||
title: 'label.s3.access.key',
|
||||
key: 'secondaryStorageAccessKey',
|
||||
required: true,
|
||||
placeHolder: 'message.error.access.key',
|
||||
|
|
@ -579,7 +579,7 @@ export default {
|
|||
}
|
||||
},
|
||||
{
|
||||
title: 'label.s3.secret_key',
|
||||
title: 'label.s3.secret.key',
|
||||
key: 'secondaryStorageSecretKey',
|
||||
required: true,
|
||||
placeHolder: 'message.error.secret.key',
|
||||
|
|
@ -605,7 +605,7 @@ export default {
|
|||
}
|
||||
},
|
||||
{
|
||||
title: 'label.s3.use_https',
|
||||
title: 'label.s3.use.https',
|
||||
key: 'secondaryStorageHttps',
|
||||
required: false,
|
||||
switch: true,
|
||||
|
|
@ -615,7 +615,7 @@ export default {
|
|||
}
|
||||
},
|
||||
{
|
||||
title: 'label.s3.connection_timeoutt',
|
||||
title: 'label.s3.connection.timeout',
|
||||
key: 'secondaryStorageConnectionTimeout',
|
||||
required: false,
|
||||
display: {
|
||||
|
|
@ -623,7 +623,7 @@ export default {
|
|||
}
|
||||
},
|
||||
{
|
||||
title: 'label.s3.max_error_retry',
|
||||
title: 'label.s3.max.error.retry',
|
||||
key: 'secondaryStorageMaxError',
|
||||
required: false,
|
||||
display: {
|
||||
|
|
@ -631,7 +631,7 @@ export default {
|
|||
}
|
||||
},
|
||||
{
|
||||
title: 'label.s3.socket_timeout',
|
||||
title: 'label.s3.socket.timeout',
|
||||
key: 'secondaryStorageSocketTimeout',
|
||||
required: false,
|
||||
display: {
|
||||
|
|
@ -653,7 +653,8 @@ export default {
|
|||
required: true,
|
||||
placeHolder: 'message.error.s3nfs.server',
|
||||
display: {
|
||||
secondaryStorageProvider: ['S3']
|
||||
secondaryStorageProvider: ['S3'],
|
||||
secondaryStorageNFSStaging: true
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -662,7 +663,8 @@ export default {
|
|||
required: true,
|
||||
placeHolder: 'message.error.s3nfs.path',
|
||||
display: {
|
||||
secondaryStorageProvider: ['S3']
|
||||
secondaryStorageProvider: ['S3'],
|
||||
secondaryStorageNFSStaging: true
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -677,7 +679,8 @@ export default {
|
|||
{
|
||||
title: 'label.account',
|
||||
key: 'secondaryStorageAccount',
|
||||
required: false,
|
||||
required: true,
|
||||
placeHolder: 'message.error.swift.account',
|
||||
display: {
|
||||
secondaryStorageProvider: ['Swift']
|
||||
}
|
||||
|
|
@ -685,7 +688,8 @@ export default {
|
|||
{
|
||||
title: 'label.username',
|
||||
key: 'secondaryStorageUsername',
|
||||
required: false,
|
||||
required: true,
|
||||
placeHolder: 'message.error.swift.username',
|
||||
display: {
|
||||
secondaryStorageProvider: ['Swift']
|
||||
}
|
||||
|
|
@ -693,6 +697,15 @@ export default {
|
|||
{
|
||||
title: 'label.key',
|
||||
key: 'secondaryStorageKey',
|
||||
required: true,
|
||||
placeHolder: 'message.error.swift.key',
|
||||
display: {
|
||||
secondaryStorageProvider: ['Swift']
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'label.storagepolicy',
|
||||
key: 'secondaryStoragePolicy',
|
||||
required: false,
|
||||
display: {
|
||||
secondaryStorageProvider: ['Swift']
|
||||
|
|
|
|||
|
|
@ -1471,6 +1471,12 @@ export default {
|
|||
params['details[' + index.toString() + '].value'] = this.prefillContent.secondaryStorageKey.value
|
||||
index++
|
||||
}
|
||||
if (this.prefillContent.secondaryStoragePolicy &&
|
||||
this.prefillContent.secondaryStoragePolicy.value.length > 0) {
|
||||
params['details[' + index.toString() + '].key'] = 'storagepolicy'
|
||||
params['details[' + index.toString() + '].value'] = this.prefillContent.secondaryStoragePolicy.value
|
||||
index++
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -253,7 +253,7 @@
|
|||
<a-form-item :label="$t('label.service.lb.elasticlbcheckbox')" v-if="guestType == 'shared' && lbServiceChecked && lbServiceProvider === 'Netscaler'">
|
||||
<a-switch v-decorator="['elasticlb', {initialValue: false}]" />
|
||||
</a-form-item>
|
||||
<a-form-item :label="$t('label.service.lb.inlinemodedropdown')" v-if="(guestType === 'shared' || guestType === 'isolated') && lbServiceChecked && firewallServiceChecked && lbServiceProvider === 'F5BigIp' && firewallServiceProvider === 'JuniperSRX'">
|
||||
<a-form-item :label="$t('label.service.lb.inlinemodedropdown')" v-if="['shared', 'isolated'].includes(guestType) && lbServiceChecked && firewallServiceChecked && ['F5BigIp', 'Netscaler'].includes(lbServiceProvider) && ['JuniperSRX'].includes(firewallServiceProvider)">
|
||||
<a-radio-group
|
||||
v-decorator="['inlinemode', {
|
||||
initialValue: 'false'
|
||||
|
|
@ -756,23 +756,14 @@ export default {
|
|||
this.loading = true
|
||||
var params = {}
|
||||
|
||||
var self = this
|
||||
var selectedServices = null
|
||||
var keys = Object.keys(values)
|
||||
const detailsKey = ['promiscuousmode', 'macaddresschanges', 'forgedtransmits', 'maclearning']
|
||||
const ignoredKeys = [...detailsKey, 'state', 'status', 'allocationstate', 'forvpc', 'lbType', 'specifyvlan', 'ispublic', 'domainid', 'zoneid', 'egressdefaultpolicy', 'isolation', 'supportspublicaccess']
|
||||
keys.forEach(function (key, keyIndex) {
|
||||
if (self.isSupportedServiceObject(values[key])) {
|
||||
if (selectedServices == null) {
|
||||
selectedServices = {}
|
||||
}
|
||||
selectedServices[key] = values[key]
|
||||
} else {
|
||||
if (!ignoredKeys.includes(key) &&
|
||||
values[key] != null && values[key] !== undefined &&
|
||||
!(key === 'availability' && values[key] === 'Optional')) {
|
||||
params[key] = values[key]
|
||||
}
|
||||
if (!ignoredKeys.includes(key) &&
|
||||
values[key] != null && values[key] !== undefined &&
|
||||
!(key === 'availability' && values[key] === 'Optional')) {
|
||||
params[key] = values[key]
|
||||
}
|
||||
})
|
||||
|
||||
|
|
@ -810,12 +801,12 @@ export default {
|
|||
params.conservemode = false
|
||||
}
|
||||
}
|
||||
if (selectedServices != null) {
|
||||
var supportedServices = Object.keys(selectedServices)
|
||||
if (this.selectedServiceProviderMap != null) {
|
||||
var supportedServices = Object.keys(this.selectedServiceProviderMap)
|
||||
params.supportedservices = supportedServices.join(',')
|
||||
for (var k in supportedServices) {
|
||||
params['serviceProviderList[' + k + '].service'] = supportedServices[k]
|
||||
params['serviceProviderList[' + k + '].provider'] = selectedServices[supportedServices[k]].provider
|
||||
params['serviceProviderList[' + k + '].provider'] = this.selectedServiceProviderMap[supportedServices[k]]
|
||||
}
|
||||
var serviceCapabilityIndex = 0
|
||||
if (supportedServices.includes('Connectivity')) {
|
||||
|
|
@ -871,7 +862,7 @@ export default {
|
|||
params['servicecapabilitylist[' + serviceCapabilityIndex + '].capabilityvalue'] = true
|
||||
serviceCapabilityIndex++
|
||||
}
|
||||
if (values.inlinemode === true && ((selectedServices.Lb.provider === 'F5BigIp') || (selectedServices.Lb.provider === 'Netscaler'))) {
|
||||
if (values.inlinemode === true && ((this.selectedServiceProviderMap.Lb === 'F5BigIp') || (this.selectedServiceProviderMap.Lb === 'Netscaler'))) {
|
||||
params['servicecapabilitylist[' + serviceCapabilityIndex + '].service'] = 'lb'
|
||||
params['servicecapabilitylist[' + serviceCapabilityIndex + '].capabilitytype'] = 'InlineMode'
|
||||
params['servicecapabilitylist[' + serviceCapabilityIndex + '].capabilityvalue'] = values.inlinemode
|
||||
|
|
@ -881,7 +872,7 @@ export default {
|
|||
params['servicecapabilitylist[' + serviceCapabilityIndex + '].capabilitytype'] = 'SupportedLbIsolation'
|
||||
params['servicecapabilitylist[' + serviceCapabilityIndex + '].capabilityvalue'] = values.isolation
|
||||
serviceCapabilityIndex++
|
||||
if (selectedServices.Lb.provider === 'InternalLbVm') {
|
||||
if (this.selectedServiceProviderMap.Lb === 'InternalLbVm') {
|
||||
params['servicecapabilitylist[' + serviceCapabilityIndex + '].service'] = 'lb'
|
||||
params['servicecapabilitylist[' + serviceCapabilityIndex + '].capabilitytype'] = 'lbSchemes'
|
||||
params['servicecapabilitylist[' + serviceCapabilityIndex + '].capabilityvalue'] = 'internal'
|
||||
|
|
|
|||
|
|
@ -166,7 +166,8 @@ export default {
|
|||
supportedServices: [],
|
||||
supportedServiceLoading: false,
|
||||
connectivityServiceChecked: false,
|
||||
sourceNatServiceChecked: false
|
||||
sourceNatServiceChecked: false,
|
||||
selectedServiceProviderMap: {}
|
||||
}
|
||||
},
|
||||
beforeCreate () {
|
||||
|
|
@ -191,9 +192,6 @@ export default {
|
|||
isAdmin () {
|
||||
return isAdmin()
|
||||
},
|
||||
isSupportedServiceObject (obj) {
|
||||
return (obj !== null && obj !== undefined && Object.keys(obj).length > 0 && obj.constructor === Object && 'provider' in obj)
|
||||
},
|
||||
fetchDomainData () {
|
||||
const params = {}
|
||||
params.listAll = true
|
||||
|
|
@ -307,6 +305,11 @@ export default {
|
|||
if (service === 'SourceNat') {
|
||||
this.sourceNatServiceChecked = checked
|
||||
}
|
||||
if (checked && provider != null & provider !== undefined) {
|
||||
this.selectedServiceProviderMap[service] = provider
|
||||
} else {
|
||||
delete this.selectedServiceProviderMap[service]
|
||||
}
|
||||
},
|
||||
handleSubmit (e) {
|
||||
e.preventDefault()
|
||||
|
|
@ -345,23 +348,12 @@ export default {
|
|||
if (zoneId) {
|
||||
params.zoneid = zoneId
|
||||
}
|
||||
var selectedServices = null
|
||||
var keys = Object.keys(values)
|
||||
var self = this
|
||||
keys.forEach(function (key, keyIndex) {
|
||||
if (self.isSupportedServiceObject(values[key])) {
|
||||
if (selectedServices == null) {
|
||||
selectedServices = {}
|
||||
}
|
||||
selectedServices[key] = values[key]
|
||||
}
|
||||
})
|
||||
if (selectedServices != null) {
|
||||
var supportedServices = Object.keys(selectedServices)
|
||||
if (this.selectedServiceProviderMap != null) {
|
||||
var supportedServices = Object.keys(this.selectedServiceProviderMap)
|
||||
params.supportedservices = supportedServices.join(',')
|
||||
for (var k in supportedServices) {
|
||||
params['serviceProviderList[' + k + '].service'] = supportedServices[k]
|
||||
params['serviceProviderList[' + k + '].provider'] = selectedServices[supportedServices[k]].provider
|
||||
params['serviceProviderList[' + k + '].provider'] = this.selectedServiceProviderMap[supportedServices[k]]
|
||||
}
|
||||
var serviceCapabilityIndex = 0
|
||||
if (supportedServices.includes('Connectivity')) {
|
||||
|
|
|
|||
|
|
@ -57,7 +57,11 @@ mocks = {
|
|||
return option
|
||||
}),
|
||||
info: jest.fn((option) => {
|
||||
return option
|
||||
return {
|
||||
message: option.message,
|
||||
description: 'test-description',
|
||||
duration: option.duration
|
||||
}
|
||||
}),
|
||||
success: jest.fn((option) => {
|
||||
return option
|
||||
|
|
|
|||
Loading…
Reference in New Issue