mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Added user_vm_details table and corresponding access objects.
Moved saved encrypted passwds for getVMPassword API cmd to this new table. Removed SSH keypair id from UserVm - only public key is needed.
This commit is contained in:
parent
ee923e5797
commit
3e59707dd2
@ -69,9 +69,5 @@ public interface UserVm extends VirtualMachine, ControlledEntity {
|
||||
|
||||
void setUserData(String userData);
|
||||
|
||||
String getEncryptedPassword();
|
||||
|
||||
Long getSSHKeyPairId();
|
||||
|
||||
String getSSHPublicKey();
|
||||
}
|
||||
|
||||
67
core/src/com/cloud/vm/UserVmDetailVO.java
Normal file
67
core/src/com/cloud/vm/UserVmDetailVO.java
Normal file
@ -0,0 +1,67 @@
|
||||
package com.cloud.vm;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name="user_vm_details")
|
||||
public class UserVmDetailVO {
|
||||
@Id
|
||||
@GeneratedValue(strategy=GenerationType.IDENTITY)
|
||||
@Column(name="id")
|
||||
private long id;
|
||||
|
||||
@Column(name="vm_id")
|
||||
private long vmId;
|
||||
|
||||
@Column(name="name")
|
||||
private String name;
|
||||
|
||||
@Column(name="value")
|
||||
private String value;
|
||||
|
||||
public UserVmDetailVO() {}
|
||||
|
||||
public UserVmDetailVO(long vmId, String name, String value) {
|
||||
this.vmId = vmId;
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public long getVmId() {
|
||||
return vmId;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void setVmId(long vmId) {
|
||||
this.vmId = vmId;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
}
|
||||
@ -64,12 +64,6 @@ public class UserVmVO extends VMInstanceVO implements UserVm {
|
||||
@Column(name="display_name", updatable=true, nullable=true)
|
||||
private String displayName;
|
||||
|
||||
@Column(name="encrypted_password", updatable=true, nullable=true)
|
||||
private String encryptedPassword;
|
||||
|
||||
@Column(name="ssh_keypair_id", updatable=true, nullable=true)
|
||||
private Long sshKeyPairId;
|
||||
|
||||
@Column(name="ssh_public_key", updatable=true, nullable=true)
|
||||
private String sshPublicKey;
|
||||
|
||||
@ -91,24 +85,6 @@ public class UserVmVO extends VMInstanceVO implements UserVm {
|
||||
public void setSSHPublicKey(String publicKey) {
|
||||
this.sshPublicKey = publicKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEncryptedPassword() {
|
||||
return encryptedPassword;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getSSHKeyPairId() {
|
||||
return sshKeyPairId;
|
||||
}
|
||||
|
||||
public void setEncryptedPassword(String encryptedPassword) {
|
||||
this.encryptedPassword = encryptedPassword;
|
||||
}
|
||||
|
||||
public void setSSHKeyPairId(Long sshKeyPairId) {
|
||||
this.sshKeyPairId = sshKeyPairId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGuestIpAddress() {
|
||||
@ -181,10 +157,13 @@ public class UserVmVO extends VMInstanceVO implements UserVm {
|
||||
long domainId,
|
||||
long accountId,
|
||||
long serviceOfferingId,
|
||||
String userData, String name) {
|
||||
String userData,
|
||||
String name,
|
||||
String sshPublicKey) {
|
||||
super(id, serviceOfferingId, name, instanceName, Type.User, templateId, guestOsId, domainId, accountId, haEnabled);
|
||||
this.userData = userData;
|
||||
this.displayName = displayName != null ? displayName : null;
|
||||
this.sshPublicKey = sshPublicKey;
|
||||
}
|
||||
|
||||
public UserVmVO(long id,
|
||||
@ -219,24 +198,6 @@ public class UserVmVO extends VMInstanceVO implements UserVm {
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
||||
public UserVmVO(long id,
|
||||
String instanceName,
|
||||
String displayName,
|
||||
long templateId,
|
||||
long guestOsId,
|
||||
boolean haEnabled,
|
||||
long domainId,
|
||||
long accountId,
|
||||
long serviceOfferingId,
|
||||
String userData,
|
||||
String name,
|
||||
Long sshKeyPairId,
|
||||
String sshPublicKey) {
|
||||
this(id, instanceName, displayName, templateId, guestOsId, haEnabled, domainId, accountId, serviceOfferingId, userData, name);
|
||||
this.sshKeyPairId = sshKeyPairId;
|
||||
this.sshPublicKey = sshPublicKey;
|
||||
}
|
||||
|
||||
protected UserVmVO() {
|
||||
super();
|
||||
}
|
||||
|
||||
@ -130,6 +130,7 @@ import com.cloud.vm.dao.InstanceGroupVMMapDaoImpl;
|
||||
import com.cloud.vm.dao.NicDaoImpl;
|
||||
import com.cloud.vm.dao.SecondaryStorageVmDaoImpl;
|
||||
import com.cloud.vm.dao.UserVmDaoImpl;
|
||||
import com.cloud.vm.dao.UserVmDetailsDaoImpl;
|
||||
import com.cloud.vm.dao.VMInstanceDaoImpl;
|
||||
|
||||
public class DefaultComponentLibrary implements ComponentLibrary {
|
||||
@ -238,6 +239,8 @@ public class DefaultComponentLibrary implements ComponentLibrary {
|
||||
addDao("SSHKeyPairDao", SSHKeyPairDaoImpl.class);
|
||||
addDao("UsageEventDao", UsageEventDaoImpl.class);
|
||||
addDao("ClusterDetailsDao", ClusterDetailsDaoImpl.class);
|
||||
addDao("UserVmDetailsDao", UserVmDetailsDaoImpl.class);
|
||||
|
||||
}
|
||||
|
||||
Map<String, ComponentInfo<Manager>> _managers = new HashMap<String, ComponentInfo<Manager>>();
|
||||
|
||||
@ -262,6 +262,7 @@ import com.cloud.vm.ConsoleProxyVO;
|
||||
import com.cloud.vm.DomainRouterVO;
|
||||
import com.cloud.vm.InstanceGroupVO;
|
||||
import com.cloud.vm.SecondaryStorageVmVO;
|
||||
import com.cloud.vm.UserVmDetailVO;
|
||||
import com.cloud.vm.UserVmManager;
|
||||
import com.cloud.vm.UserVmVO;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
@ -272,6 +273,7 @@ import com.cloud.vm.dao.DomainRouterDao;
|
||||
import com.cloud.vm.dao.InstanceGroupDao;
|
||||
import com.cloud.vm.dao.SecondaryStorageVmDao;
|
||||
import com.cloud.vm.dao.UserVmDao;
|
||||
import com.cloud.vm.dao.UserVmDetailsDao;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
|
||||
public class ManagementServerImpl implements ManagementServer {
|
||||
@ -330,6 +332,7 @@ public class ManagementServerImpl implements ManagementServer {
|
||||
private final UploadDao _uploadDao;
|
||||
private final CertificateDao _certDao;
|
||||
private final SSHKeyPairDao _sshKeyPairDao;
|
||||
private final UserVmDetailsDao _userVmDetailsDao;
|
||||
|
||||
|
||||
private final ScheduledExecutorService _eventExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("EventChecker"));
|
||||
@ -403,6 +406,7 @@ public class ManagementServerImpl implements ManagementServer {
|
||||
_tmpltMgr = locator.getManager(TemplateManager.class);
|
||||
_uploadMonitor = locator.getManager(UploadMonitor.class);
|
||||
_sshKeyPairDao = locator.getDao(SSHKeyPairDao.class);
|
||||
_userVmDetailsDao = locator.getDao(UserVmDetailsDao.class);
|
||||
|
||||
_userAuthenticators = locator.getAdapters(UserAuthenticator.class);
|
||||
if (_userAuthenticators == null || !_userAuthenticators.isSet()) {
|
||||
@ -4750,13 +4754,15 @@ public class ManagementServerImpl implements ManagementServer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVMPassword(GetVMPasswordCmd cmd) {
|
||||
public String getVMPassword(GetVMPasswordCmd cmd) {
|
||||
Account account = UserContext.current().getCaller();
|
||||
UserVmVO vm = _userVmDao.findById(cmd.getId());
|
||||
if (vm == null || vm.getEncryptedPassword() == null || vm.getEncryptedPassword().equals("") || vm.getAccountId() != account.getAccountId())
|
||||
throw new InvalidParameterValueException("No password for VM with id '" + getId() + "' found.");
|
||||
UserVmDetailVO password = _userVmDetailsDao.findDetail(cmd.getId(), "Encrypted.Password");
|
||||
|
||||
if (vm == null || password == null || password.getValue() == null || password.getValue().equals("") || vm.getAccountId() != account.getAccountId())
|
||||
throw new InvalidParameterValueException("No password for VM with id '" + getId() + "' found.");
|
||||
|
||||
return vm.getEncryptedPassword();
|
||||
return password.getValue();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -207,6 +207,7 @@ import com.cloud.vm.dao.InstanceGroupDao;
|
||||
import com.cloud.vm.dao.InstanceGroupVMMapDao;
|
||||
import com.cloud.vm.dao.NicDao;
|
||||
import com.cloud.vm.dao.UserVmDao;
|
||||
import com.cloud.vm.dao.UserVmDetailsDao;
|
||||
@Local(value={UserVmManager.class, UserVmService.class})
|
||||
public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager {
|
||||
private static final Logger s_logger = Logger.getLogger(UserVmManagerImpl.class);
|
||||
@ -264,6 +265,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
|
||||
@Inject LoadBalancingRulesManager _lbMgr;
|
||||
@Inject UsageEventDao _usageEventDao;
|
||||
@Inject SSHKeyPairDao _sshKeyPairDao;
|
||||
@Inject UserVmDetailsDao _vmDetailsDao;
|
||||
|
||||
private IpAddrAllocator _IpAllocator;
|
||||
ScheduledExecutorService _executor = null;
|
||||
@ -2237,7 +2239,6 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
|
||||
}
|
||||
|
||||
// Find an SSH public key corresponding to the key pair name, if one is given
|
||||
Long sshKeyPairId = null;
|
||||
String sshPublicKey = null;
|
||||
if (cmd.getSSHKeyPairName() != null && !cmd.getSSHKeyPairName().equals("")) {
|
||||
Account account = UserContext.current().getCaller();
|
||||
@ -2245,7 +2246,6 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
|
||||
if (pair == null)
|
||||
throw new InvalidParameterValueException("A key pair with name '" + cmd.getSSHKeyPairName() + "' was not found.");
|
||||
|
||||
sshKeyPairId = pair.getId();
|
||||
sshPublicKey = pair.getPublicKey();
|
||||
}
|
||||
|
||||
@ -2306,7 +2306,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
|
||||
|
||||
UserVmVO vm = new UserVmVO(id, instanceName, cmd.getDisplayName(),
|
||||
template.getId(), template.getGuestOSId(), offering.getOfferHA(), domainId, owner.getId(), offering.getId(),
|
||||
userData, hostName, sshKeyPairId, sshPublicKey);
|
||||
userData, hostName, sshPublicKey);
|
||||
|
||||
|
||||
if (_itMgr.allocate(vm, template, offering, rootDiskOffering, dataDiskOfferings, networks, null, plan, cmd.getHypervisor(), owner) == null) {
|
||||
@ -2340,6 +2340,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
|
||||
public UserVm startVirtualMachine(DeployVMCmd cmd) throws ResourceUnavailableException, InsufficientCapacityException, ConcurrentOperationException {
|
||||
long vmId = cmd.getEntityId();
|
||||
UserVmVO vm = _vmDao.findById(vmId);
|
||||
Map<String, String> vmDetails = _vmDetailsDao.findDetails(vm.getId());
|
||||
|
||||
// Check that the password was passed in and is valid
|
||||
VMTemplateVO template = _templateDao.findById(vm.getTemplateId());
|
||||
@ -2355,13 +2356,13 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
|
||||
vm.setPassword(password);
|
||||
|
||||
// Check if an SSH key pair was selected for the instance and if so use it to encrypt & save the vm password
|
||||
if (vm.getSSHKeyPairId() != null && vm.getSSHPublicKey() != null && password != null && !password.equals("saved_password") ) {
|
||||
if (vm.getSSHPublicKey() != null && password != null && !password.equals("saved_password") ) {
|
||||
String encryptedPasswd = RSAHelper.encryptWithSSHPublicKey(vm.getSSHPublicKey(), password);
|
||||
if (encryptedPasswd == null)
|
||||
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Error encrypting password");
|
||||
|
||||
vm.setEncryptedPassword(encryptedPasswd);
|
||||
_vmDao.update(vm.getId(), vm);
|
||||
vmDetails.put("Encrypted.Password", encryptedPasswd);
|
||||
_vmDetailsDao.persist(vm.getId(), vmDetails);
|
||||
}
|
||||
|
||||
long userId = UserContext.current().getCallerUserId();
|
||||
|
||||
16
server/src/com/cloud/vm/dao/UserVmDetailsDao.java
Normal file
16
server/src/com/cloud/vm/dao/UserVmDetailsDao.java
Normal file
@ -0,0 +1,16 @@
|
||||
package com.cloud.vm.dao;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import com.cloud.vm.UserVmDetailVO;
|
||||
|
||||
public interface UserVmDetailsDao extends GenericDao<UserVmDetailVO, Long> {
|
||||
Map<String, String> findDetails(long vmId);
|
||||
|
||||
void persist(long vmId, Map<String, String> details);
|
||||
|
||||
UserVmDetailVO findDetail(long vmId, String name);
|
||||
|
||||
void deleteDetails(long vmId);
|
||||
}
|
||||
80
server/src/com/cloud/vm/dao/UserVmDetailsDaoImpl.java
Normal file
80
server/src/com/cloud/vm/dao/UserVmDetailsDaoImpl.java
Normal file
@ -0,0 +1,80 @@
|
||||
package com.cloud.vm.dao;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.ejb.Local;
|
||||
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.Transaction;
|
||||
import com.cloud.vm.UserVmDetailVO;
|
||||
|
||||
@Local(value=UserVmDetailsDao.class)
|
||||
public class UserVmDetailsDaoImpl extends GenericDaoBase<UserVmDetailVO, Long> implements UserVmDetailsDao {
|
||||
protected final SearchBuilder<UserVmDetailVO> VmSearch;
|
||||
protected final SearchBuilder<UserVmDetailVO> DetailSearch;
|
||||
|
||||
protected UserVmDetailsDaoImpl() {
|
||||
VmSearch = createSearchBuilder();
|
||||
VmSearch.and("vmId", VmSearch.entity().getVmId(), SearchCriteria.Op.EQ);
|
||||
VmSearch.done();
|
||||
|
||||
DetailSearch = createSearchBuilder();
|
||||
DetailSearch.and("hostId", DetailSearch.entity().getVmId(), SearchCriteria.Op.EQ);
|
||||
DetailSearch.and("name", DetailSearch.entity().getName(), SearchCriteria.Op.EQ);
|
||||
DetailSearch.done();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteDetails(long vmId) {
|
||||
SearchCriteria<UserVmDetailVO> sc = VmSearch.create();
|
||||
sc.setParameters("vmId", vmId);
|
||||
|
||||
List<UserVmDetailVO> results = search(sc, null);
|
||||
for (UserVmDetailVO result : results) {
|
||||
remove(result.getId());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserVmDetailVO findDetail(long vmId, String name) {
|
||||
SearchCriteria<UserVmDetailVO> sc = DetailSearch.create();
|
||||
sc.setParameters("vmId", vmId);
|
||||
sc.setParameters("name", name);
|
||||
|
||||
return findOneBy(sc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> findDetails(long vmId) {
|
||||
SearchCriteria<UserVmDetailVO> sc = VmSearch.create();
|
||||
sc.setParameters("vmId", vmId);
|
||||
|
||||
List<UserVmDetailVO> results = search(sc, null);
|
||||
Map<String, String> details = new HashMap<String, String>(results.size());
|
||||
for (UserVmDetailVO result : results) {
|
||||
details.put(result.getName(), result.getValue());
|
||||
}
|
||||
|
||||
return details;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void persist(long vmId, Map<String, String> details) {
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
txn.start();
|
||||
SearchCriteria<UserVmDetailVO> sc = VmSearch.create();
|
||||
sc.setParameters("vmId", vmId);
|
||||
expunge(sc);
|
||||
|
||||
for (Map.Entry<String, String> detail : details.entrySet()) {
|
||||
UserVmDetailVO vo = new UserVmDetailVO(vmId, detail.getKey(), detail.getValue());
|
||||
persist(vo);
|
||||
}
|
||||
txn.commit();
|
||||
}
|
||||
|
||||
}
|
||||
@ -123,6 +123,8 @@ ALTER TABLE `cloud`.`user_vm` ADD INDEX `i_user_vm__external_ip_address`(`extern
|
||||
ALTER TABLE `cloud`.`user_vm` ADD CONSTRAINT `fk_user_vm__external_vlan_db_id` FOREIGN KEY `fk_user_vm__external_vlan_db_id` (`external_vlan_db_id`) REFERENCES `vlan` (`id`);
|
||||
ALTER TABLE `cloud`.`user_vm` ADD INDEX `i_user_vm__external_vlan_db_id`(`external_vlan_db_id`);
|
||||
|
||||
ALTER TABLE `cloud`.`user_vm_details` ADD CONSTRAINT `fk_user_vm_details__vm_id` FOREIGN KEY `fk_user_vm_details__vm_id`(`vm_id`) REFERENCES `vm_instance`(`id`) ON DELETE CASCADE;
|
||||
|
||||
#ALTER TABLE `cloud`.`domain_router` ADD CONSTRAINT `fk_domain_router__public_ip_address` FOREIGN KEY `fk_domain_router__public_ip_address` (`public_ip_address`) REFERENCES `user_ip_address` (`public_ip_address`);
|
||||
ALTER TABLE `cloud`.`domain_router` ADD INDEX `i_domain_router__public_ip_address`(`public_ip_address`);
|
||||
ALTER TABLE `cloud`.`domain_router` ADD CONSTRAINT `fk_domain_router__id` FOREIGN KEY `fk_domain_router__id` (`id`) REFERENCES `vm_instance`(`id`) ON DELETE CASCADE;
|
||||
|
||||
@ -760,12 +760,19 @@ CREATE TABLE `cloud`.`user_vm` (
|
||||
`external_mac_address` varchar(17) COMMENT 'mac address within the external network',
|
||||
`external_vlan_db_id` bigint unsigned COMMENT 'foreign key into vlan table',
|
||||
`user_data` varchar(2048),
|
||||
`encrypted_password` varchar(1024) COMMENT 'vm password encrypted with the public key referenced in ssh_keypair',
|
||||
`ssh_keypair_id` bigint unsigned COMMENT 'id of the ssh keypair used to access the vm and/or encrypt the password',
|
||||
`ssh_public_key` varchar(5120) COMMENT 'ssh public key',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE `cloud`.`user_vm_details` (
|
||||
`id` bigint unsigned NOT NULL auto_increment,
|
||||
`vm_id` bigint unsigned NOT NULL COMMENT 'vm id',
|
||||
`name` varchar(255) NOT NULL,
|
||||
`value` varchar(1024) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
|
||||
CREATE TABLE `cloud`.`domain_router` (
|
||||
`id` bigint unsigned UNIQUE NOT NULL COMMENT 'Primary Key',
|
||||
`gateway` varchar(15) COMMENT 'ip address of the gateway to this domR',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user