Skip to content

Commit a3f39db

Browse files
GutoVeroneziDaniel Augusto Veronezi Salvador
andauthored
server: Remove meaningless password regeneration on resetSSHKeyForVirtualMachine (#4819)
On API `resetSSHKeyForVirtualMachine`, ACS also regenerates VM password when it uses a template with `Password Enabled` as true; there is already anAPI to reset VM password, therefore, the reset SSH keys API should not reset the VM SSH password as well. Besides running a meaningless process, the VM's password regeneration slows down the main process and may cause a confusion in operations due to password change in the VM without being explicity requested. Co-authored-by: Daniel Augusto Veronezi Salvador <daniel@scclouds.com.br>
1 parent d2ab350 commit a3f39db

File tree

3 files changed

+36
-29
lines changed

3 files changed

+36
-29
lines changed

server/src/main/java/com/cloud/server/ManagementServerImpl.java

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4233,26 +4233,23 @@ private SSHKeyPair createAndSaveSSHKeyPair(final String name, final String finge
42334233
}
42344234

42354235
@Override
4236-
public String getVMPassword(final GetVMPasswordCmd cmd) {
4237-
final Account caller = getCaller();
4236+
public String getVMPassword(GetVMPasswordCmd cmd) {
4237+
Account caller = getCaller();
4238+
long vmId = cmd.getId();
4239+
UserVmVO vm = _userVmDao.findById(vmId);
42384240

4239-
final UserVmVO vm = _userVmDao.findById(cmd.getId());
42404241
if (vm == null) {
4241-
final InvalidParameterValueException ex = new InvalidParameterValueException("No VM with specified id found.");
4242-
ex.addProxyObject(cmd.getId().toString(), "vmId");
4243-
throw ex;
4242+
throw new InvalidParameterValueException(String.format("No VM found with id [%s].", vmId));
42444243
}
42454244

4246-
// make permission check
42474245
_accountMgr.checkAccess(caller, null, true, vm);
42484246

42494247
_userVmDao.loadDetails(vm);
4250-
final String password = vm.getDetail("Encrypted.Password");
4251-
if (password == null || password.equals("")) {
4252-
final InvalidParameterValueException ex = new InvalidParameterValueException(
4253-
"No password for VM with specified id found. " + "If VM is created from password enabled template and SSH keypair is assigned to VM then only password can be retrieved.");
4254-
ex.addProxyObject(vm.getUuid(), "vmId");
4255-
throw ex;
4248+
String password = vm.getDetail("Encrypted.Password");
4249+
4250+
if (StringUtils.isEmpty(password)) {
4251+
throw new InvalidParameterValueException(String.format("No password found for VM with id [%s]. When the VM's SSH keypair is changed, the current encrypted password is "
4252+
+ "removed due to incosistency in the encryptation, as the new SSH keypair is different from which the password was encrypted. To get a new password, it must be reseted.", vmId));
42564253
}
42574254

42584255
return password;

server/src/main/java/com/cloud/vm/UserVmManagerImpl.java

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -862,22 +862,28 @@ public UserVm resetVMSSHKey(ResetVMSSHKeyCmd cmd) throws ResourceUnavailableExce
862862
}
863863

864864
_accountMgr.checkAccess(caller, null, true, userVm);
865-
String password = null;
865+
866866
String sshPublicKey = s.getPublicKey();
867-
if (template != null && template.isEnablePassword()) {
868-
password = _mgr.generateRandomPassword();
869-
}
870867

871-
boolean result = resetVMSSHKeyInternal(vmId, sshPublicKey, password);
868+
boolean result = resetVMSSHKeyInternal(vmId, sshPublicKey);
872869

873870
if (!result) {
874871
throw new CloudRuntimeException("Failed to reset SSH Key for the virtual machine ");
875872
}
876-
userVm.setPassword(password);
873+
874+
removeEncryptedPasswordFromUserVmVoDetails(userVm);
875+
877876
return userVm;
878877
}
879878

880-
private boolean resetVMSSHKeyInternal(Long vmId, String sshPublicKey, String password) throws ResourceUnavailableException, InsufficientCapacityException {
879+
protected void removeEncryptedPasswordFromUserVmVoDetails(UserVmVO userVmVo) {
880+
Map<String, String> details = userVmVo.getDetails();
881+
details.remove(VmDetailConstants.ENCRYPTED_PASSWORD);
882+
userVmVo.setDetails(details);
883+
_vmDao.saveDetails(userVmVo);
884+
}
885+
886+
private boolean resetVMSSHKeyInternal(Long vmId, String sshPublicKey) throws ResourceUnavailableException, InsufficientCapacityException {
881887
Long userId = CallContext.current().getCallingUserId();
882888
VMInstanceVO vmInstance = _vmDao.findById(vmId);
883889

@@ -894,10 +900,6 @@ private boolean resetVMSSHKeyInternal(Long vmId, String sshPublicKey, String pas
894900

895901
VirtualMachineProfile vmProfile = new VirtualMachineProfileImpl(vmInstance);
896902

897-
if (template.isEnablePassword()) {
898-
vmProfile.setParameter(VirtualMachineProfile.Param.VmPassword, password);
899-
}
900-
901903
UserDataServiceProvider element = _networkMgr.getSSHKeyResetProvider(defaultNetwork);
902904
if (element == null) {
903905
throw new CloudRuntimeException("Can't find network element for " + Service.UserData.getName() + " provider needed for SSH Key reset");
@@ -912,11 +914,6 @@ private boolean resetVMSSHKeyInternal(Long vmId, String sshPublicKey, String pas
912914
final UserVmVO userVm = _vmDao.findById(vmId);
913915
_vmDao.loadDetails(userVm);
914916
userVm.setDetail(VmDetailConstants.SSH_PUBLIC_KEY, sshPublicKey);
915-
if (template.isEnablePassword()) {
916-
userVm.setPassword(password);
917-
//update the encrypted password in vm_details table too
918-
encryptAndStorePassword(userVm, password);
919-
}
920917
_vmDao.saveDetails(userVm);
921918

922919
if (vmInstance.getState() == State.Stopped) {

server/src/test/java/com/cloud/vm/UserVmManagerImplTest.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,4 +558,17 @@ private DiskOfferingVO prepareDiskOffering(long rootSize, long diskOfferingId, l
558558
Mockito.when(newRootDiskOffering.getName()).thenReturn("OfferingName");
559559
return newRootDiskOffering;
560560
}
561+
562+
@Test
563+
public void validateRemoveEncryptedPasswordFromUserVmVoDetails(){
564+
Map<String, String> detailsMock = Mockito.mock(HashMap.class);
565+
566+
Mockito.doReturn(detailsMock).when(userVmVoMock).getDetails();
567+
Mockito.doNothing().when(userVmDao).saveDetails(userVmVoMock);
568+
userVmManagerImpl.removeEncryptedPasswordFromUserVmVoDetails(userVmVoMock);
569+
570+
Mockito.verify(detailsMock, Mockito.times(1)).remove(VmDetailConstants.ENCRYPTED_PASSWORD);
571+
Mockito.verify(userVmVoMock, Mockito.times(1)).setDetails(detailsMock);
572+
Mockito.verify(userVmDao, Mockito.times(1)).saveDetails(userVmVoMock);
573+
}
561574
}

0 commit comments

Comments
 (0)