mirror of https://github.com/apache/cloudstack.git
[4.22] Prevent unmanaging or reinstalling a VM if it is part of a CKS cluster (#12800)
This commit is contained in:
parent
84676afd5c
commit
c1af36f8fc
|
|
@ -199,4 +199,9 @@ public interface UserVmManager extends UserVmService {
|
|||
|
||||
Boolean getDestroyRootVolumeOnVmDestruction(Long domainId);
|
||||
|
||||
/**
|
||||
* @return true if the VM is part of a CKS cluster, false otherwise.
|
||||
*/
|
||||
boolean isVMPartOfAnyCKSCluster(VMInstanceVO vm);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8785,6 +8785,10 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
throw new InvalidParameterValueException(String.format("Operation not supported for instance: %s",
|
||||
vm.getName()));
|
||||
}
|
||||
if (isVMPartOfAnyCKSCluster(vm)) {
|
||||
throw new UnsupportedServiceException("Cannot restore VM with id = " + vm.getUuid() +
|
||||
" as it belongs to a CKS cluster. Please remove the VM from the CKS cluster before restoring.");
|
||||
}
|
||||
_accountMgr.checkAccess(caller, null, true, vm);
|
||||
|
||||
VMTemplateVO template;
|
||||
|
|
@ -9986,6 +9990,11 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
return DestroyRootVolumeOnVmDestruction.valueIn(domainId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVMPartOfAnyCKSCluster(VMInstanceVO vm) {
|
||||
return kubernetesServiceHelpers.get(0).findByVmId(vm.getId()) != null;
|
||||
}
|
||||
|
||||
private void setVncPasswordForKvmIfAvailable(Map<String, String> customParameters, UserVmVO vm) {
|
||||
if (customParameters.containsKey(VmDetailConstants.KVM_VNC_PASSWORD)
|
||||
&& StringUtils.isNotEmpty(customParameters.get(VmDetailConstants.KVM_VNC_PASSWORD))) {
|
||||
|
|
|
|||
|
|
@ -2304,6 +2304,8 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||
* Perform validations before attempting to unmanage a VM from CloudStack:
|
||||
* - VM must not have any associated volume snapshot
|
||||
* - VM must not have an attached ISO
|
||||
* - VM must not belong to any CKS cluster
|
||||
* @throws UnsupportedServiceException in case any of the validations above fail
|
||||
*/
|
||||
void performUnmanageVMInstancePrechecks(VMInstanceVO vmVO) {
|
||||
if (hasVolumeSnapshotsPriorToUnmanageVM(vmVO)) {
|
||||
|
|
@ -2315,6 +2317,11 @@ public class UnmanagedVMsManagerImpl implements UnmanagedVMsManager {
|
|||
throw new UnsupportedServiceException("Cannot unmanage VM with id = " + vmVO.getUuid() +
|
||||
" as there is an ISO attached. Please detach ISO before unmanaging.");
|
||||
}
|
||||
|
||||
if (userVmManager.isVMPartOfAnyCKSCluster(vmVO)) {
|
||||
throw new UnsupportedServiceException("Cannot unmanage VM with id = " + vmVO.getUuid() +
|
||||
" as it belongs to a CKS cluster. Please remove the VM from the CKS cluster before unmanaging.");
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasVolumeSnapshotsPriorToUnmanageVM(VMInstanceVO vmVO) {
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ import java.util.Map;
|
|||
import java.util.TimeZone;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.cloud.kubernetes.cluster.KubernetesServiceHelper;
|
||||
import com.cloud.storage.dao.SnapshotPolicyDao;
|
||||
import com.cloud.utils.fsm.NoTransitionException;
|
||||
import org.apache.cloudstack.acl.ControlledEntity;
|
||||
|
|
@ -1476,6 +1477,9 @@ public class UserVmManagerImplTest {
|
|||
when(cmd.getVmId()).thenReturn(vmId);
|
||||
when(cmd.getTemplateId()).thenReturn(2L);
|
||||
when(userVmDao.findById(vmId)).thenReturn(userVmVoMock);
|
||||
KubernetesServiceHelper helper = mock(KubernetesServiceHelper.class);
|
||||
when(helper.findByVmId(anyLong())).thenReturn(null);
|
||||
userVmManagerImpl.setKubernetesServiceHelpers(Collections.singletonList(helper));
|
||||
|
||||
userVmManagerImpl.restoreVM(cmd);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ import static org.mockito.Mockito.when;
|
|||
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
|
|
@ -39,6 +40,9 @@ import java.util.Map;
|
|||
import java.util.UUID;
|
||||
|
||||
import com.cloud.offering.DiskOffering;
|
||||
import com.cloud.storage.Snapshot;
|
||||
import com.cloud.storage.SnapshotVO;
|
||||
import com.cloud.storage.dao.SnapshotDao;
|
||||
import com.cloud.vm.ImportVMTaskVO;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ResponseGenerator;
|
||||
|
|
@ -241,6 +245,8 @@ public class UnmanagedVMsManagerImplTest {
|
|||
private StoragePoolHostDao storagePoolHostDao;
|
||||
@Mock
|
||||
private ImportVmTasksManager importVmTasksManager;
|
||||
@Mock
|
||||
private SnapshotDao snapshotDao;
|
||||
|
||||
@Mock
|
||||
private VMInstanceVO virtualMachine;
|
||||
|
|
@ -568,6 +574,53 @@ public class UnmanagedVMsManagerImplTest {
|
|||
unmanagedVMsManager.unmanageVMInstance(virtualMachineId, null, false);
|
||||
}
|
||||
|
||||
@Test(expected = UnsupportedServiceException.class)
|
||||
public void testUnmanageVMInstanceWithVolumeSnapshotsFail() {
|
||||
when(virtualMachine.getType()).thenReturn(VirtualMachine.Type.User);
|
||||
when(virtualMachine.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.KVM);
|
||||
when(virtualMachine.getState()).thenReturn(VirtualMachine.State.Stopped);
|
||||
when(virtualMachine.getId()).thenReturn(virtualMachineId);
|
||||
UserVmVO userVmVO = mock(UserVmVO.class);
|
||||
when(userVmDao.findById(anyLong())).thenReturn(userVmVO);
|
||||
when(vmDao.findById(virtualMachineId)).thenReturn(virtualMachine);
|
||||
VolumeVO volumeVO = mock(VolumeVO.class);
|
||||
long volumeId = 20L;
|
||||
when(volumeVO.getId()).thenReturn(volumeId);
|
||||
SnapshotVO snapshotVO = mock(SnapshotVO.class);
|
||||
when(snapshotVO.getState()).thenReturn(Snapshot.State.BackedUp);
|
||||
when(snapshotDao.listByVolumeId(volumeId)).thenReturn(Collections.singletonList(snapshotVO));
|
||||
when(volumeDao.findByInstance(virtualMachineId)).thenReturn(Collections.singletonList(volumeVO));
|
||||
unmanagedVMsManager.unmanageVMInstance(virtualMachineId, null, false);
|
||||
}
|
||||
|
||||
@Test(expected = UnsupportedServiceException.class)
|
||||
public void testUnmanageVMInstanceWithAssociatedIsoFail() {
|
||||
when(virtualMachine.getType()).thenReturn(VirtualMachine.Type.User);
|
||||
when(virtualMachine.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.KVM);
|
||||
when(virtualMachine.getState()).thenReturn(VirtualMachine.State.Stopped);
|
||||
when(virtualMachine.getId()).thenReturn(virtualMachineId);
|
||||
UserVmVO userVmVO = mock(UserVmVO.class);
|
||||
when(userVmVO.getIsoId()).thenReturn(null);
|
||||
when(userVmDao.findById(anyLong())).thenReturn(userVmVO);
|
||||
when(vmDao.findById(virtualMachineId)).thenReturn(virtualMachine);
|
||||
when(userVmVO.getIsoId()).thenReturn(1L);
|
||||
unmanagedVMsManager.unmanageVMInstance(virtualMachineId, null, false);
|
||||
}
|
||||
|
||||
@Test(expected = UnsupportedServiceException.class)
|
||||
public void testUnmanageVMInstanceBelongingToCksClusterFail() {
|
||||
when(virtualMachine.getType()).thenReturn(VirtualMachine.Type.User);
|
||||
when(virtualMachine.getHypervisorType()).thenReturn(Hypervisor.HypervisorType.KVM);
|
||||
when(virtualMachine.getState()).thenReturn(VirtualMachine.State.Stopped);
|
||||
when(virtualMachine.getId()).thenReturn(virtualMachineId);
|
||||
UserVmVO userVmVO = mock(UserVmVO.class);
|
||||
when(userVmVO.getIsoId()).thenReturn(null);
|
||||
when(userVmDao.findById(anyLong())).thenReturn(userVmVO);
|
||||
when(vmDao.findById(virtualMachineId)).thenReturn(virtualMachine);
|
||||
when(userVmManager.isVMPartOfAnyCKSCluster(virtualMachine)).thenReturn(true);
|
||||
unmanagedVMsManager.unmanageVMInstance(virtualMachineId, null, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testListRemoteInstancesTest() {
|
||||
ListVmsForImportCmd cmd = Mockito.mock(ListVmsForImportCmd.class);
|
||||
|
|
|
|||
Loading…
Reference in New Issue