mirror of https://github.com/apache/cloudstack.git
changes for user assignement; refactor
- make service account configurable - allow assigning vm, volume to network account Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
This commit is contained in:
parent
a0be1fb772
commit
05a5b03d95
|
|
@ -88,10 +88,14 @@ public interface AccountService {
|
|||
|
||||
Account getActiveAccountById(long accountId);
|
||||
|
||||
Account getActiveAccountByUuid(String accountUuid);
|
||||
|
||||
Account getAccount(long accountId);
|
||||
|
||||
User getActiveUser(long userId);
|
||||
|
||||
User getOneActiveUserForAccount(Account account);
|
||||
|
||||
User getUserIncludingRemoved(long userId);
|
||||
|
||||
boolean isRootAdmin(Long accountId);
|
||||
|
|
|
|||
|
|
@ -85,6 +85,8 @@ public class AssignVMCmd extends BaseCmd {
|
|||
"In case no security groups are provided the Instance is part of the default security group.")
|
||||
private List<Long> securityGroupIdList;
|
||||
|
||||
private boolean skipNetwork = false;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
@ -113,6 +115,34 @@ public class AssignVMCmd extends BaseCmd {
|
|||
return securityGroupIdList;
|
||||
}
|
||||
|
||||
public boolean isSkipNetwork() {
|
||||
return skipNetwork;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Setters /////////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public void setVirtualMachineId(Long virtualMachineId) {
|
||||
this.virtualMachineId = virtualMachineId;
|
||||
}
|
||||
|
||||
public void setAccountName(String accountName) {
|
||||
this.accountName = accountName;
|
||||
}
|
||||
|
||||
public void setDomainId(Long domainId) {
|
||||
this.domainId = domainId;
|
||||
}
|
||||
|
||||
public void setProjectId(Long projectId) {
|
||||
this.projectId = projectId;
|
||||
}
|
||||
|
||||
public void setSkipNetwork(boolean skipNetwork) {
|
||||
this.skipNetwork = skipNetwork;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -70,6 +70,21 @@ public class AssignVolumeCmd extends BaseCmd implements UserCmd {
|
|||
return projectid;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Setter///////////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
public void setVolumeId(Long volumeId) {
|
||||
this.volumeId = volumeId;
|
||||
}
|
||||
|
||||
public void setAccountId(Long accountId) {
|
||||
this.accountId = accountId;
|
||||
}
|
||||
|
||||
public void setProjectId(Long projectid) {
|
||||
this.projectid = projectid;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -50,4 +50,6 @@ public interface AsyncJobDao extends GenericDao<AsyncJobVO, Long> {
|
|||
// Returns the number of pending jobs for the given Management server msids.
|
||||
// NOTE: This is the msid and NOT the id
|
||||
long countPendingNonPseudoJobs(Long... msIds);
|
||||
|
||||
List<Long> listPendingJobIdsForAccount(long accountId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -266,4 +266,14 @@ public class AsyncJobDaoImpl extends GenericDaoBase<AsyncJobVO, Long> implements
|
|||
List<Long> results = customSearch(sc, null);
|
||||
return results.get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> listPendingJobIdsForAccount(long accountId) {
|
||||
GenericSearchBuilder<AsyncJobVO, Long> sb = createSearchBuilder(Long.class);
|
||||
sb.and("accountId", sb.entity().getAccountId(), SearchCriteria.Op.EQ);
|
||||
sb.selectFields(sb.entity().getId());
|
||||
SearchCriteria<Long> sc = sb.create();
|
||||
sc.setParameters("accountId", accountId);
|
||||
return customSearch(sc, null);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,8 +88,8 @@ public class LibvirtStartBackupCommandWrapper extends CommandWrapper<StartBackup
|
|||
script.add(backupCmd);
|
||||
String result = script.execute();
|
||||
|
||||
backupXmlFile.delete();
|
||||
checkpointXmlFile.delete();
|
||||
// backupXmlFile.delete();
|
||||
// checkpointXmlFile.delete();
|
||||
|
||||
if (result != null) {
|
||||
return new StartBackupAnswer(cmd, false, "Backup begin failed: " + result);
|
||||
|
|
|
|||
|
|
@ -31,8 +31,19 @@ public interface VeeamControlService extends PluggableService, Configurable {
|
|||
"8090", "Port for Veeam Integration REST API server", false);
|
||||
ConfigKey<String> ContextPath = new ConfigKey<>("Advanced", String.class, "integration.veeam.control.context.path",
|
||||
"/ovirt-engine", "Context path for Veeam Integration REST API server", false);
|
||||
ConfigKey<String> Username = new ConfigKey<>("Advanced", String.class, "integration.veeam.api.username",
|
||||
ConfigKey<String> Username = new ConfigKey<>("Advanced", String.class, "integration.veeam.control.api.username",
|
||||
"veeam", "Username for Basic Auth on Veeam Integration REST API server", true);
|
||||
ConfigKey<String> Password = new ConfigKey<>("Advanced", String.class, "integration.veeam.api.password",
|
||||
ConfigKey<String> Password = new ConfigKey<>("Advanced", String.class, "integration.veeam.control.api.password",
|
||||
"change-me", "Password for Basic Auth on Veeam Integration REST API server", true);
|
||||
ConfigKey<String> ServiceAccountId = new ConfigKey<>("Advanced", String.class,
|
||||
"integration.veeam.control.service.account", "",
|
||||
"ID of the service account used to perform operations on resources. " +
|
||||
"Preferably an admin-level account with permissions to access resources across the environment " +
|
||||
"and optionally assign them to other users.",
|
||||
true);
|
||||
ConfigKey<Boolean> InstanceRestoreAssignOwner = new ConfigKey<>("Advanced", Boolean.class,
|
||||
"integration.veeam.instance.restore.assign.owner",
|
||||
"false", "Attempt to assign restored Instance to the owner based on OVF and network " +
|
||||
"details. If the assignment fails or set to false then the Instance will remain owned by the service " +
|
||||
"account", true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,7 +76,9 @@ public class VeeamControlServiceImpl extends ManagerBase implements VeeamControl
|
|||
Port,
|
||||
ContextPath,
|
||||
Username,
|
||||
Password
|
||||
Password,
|
||||
ServiceAccountId,
|
||||
InstanceRestoreAssignOwner
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ import org.apache.cloudstack.api.BaseCmd;
|
|||
import org.apache.cloudstack.api.command.admin.backup.DeleteVmCheckpointCmd;
|
||||
import org.apache.cloudstack.api.command.admin.backup.FinalizeBackupCmd;
|
||||
import org.apache.cloudstack.api.command.admin.backup.StartBackupCmd;
|
||||
import org.apache.cloudstack.api.command.admin.vm.AssignVMCmd;
|
||||
import org.apache.cloudstack.api.command.admin.vm.DeployVMCmdByAdmin;
|
||||
import org.apache.cloudstack.api.command.user.job.QueryAsyncJobResultCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.ListNetworksCmd;
|
||||
|
|
@ -54,6 +55,8 @@ import org.apache.cloudstack.api.command.user.vm.StartVMCmd;
|
|||
import org.apache.cloudstack.api.command.user.vm.StopVMCmd;
|
||||
import org.apache.cloudstack.api.command.user.vmsnapshot.CreateVMSnapshotCmd;
|
||||
import org.apache.cloudstack.api.command.user.vmsnapshot.DeleteVMSnapshotCmd;
|
||||
import org.apache.cloudstack.api.command.user.vmsnapshot.RevertToVMSnapshotCmd;
|
||||
import org.apache.cloudstack.api.command.user.volume.AssignVolumeCmd;
|
||||
import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd;
|
||||
import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd;
|
||||
import org.apache.cloudstack.api.command.user.volume.DeleteVolumeCmd;
|
||||
|
|
@ -72,7 +75,6 @@ import org.apache.cloudstack.backup.dao.ImageTransferDao;
|
|||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.framework.jobs.dao.AsyncJobDao;
|
||||
import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
|
||||
import org.apache.cloudstack.jobs.JobInfo;
|
||||
import org.apache.cloudstack.query.QueryService;
|
||||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||
|
|
@ -116,7 +118,6 @@ import org.apache.cloudstack.veeam.api.dto.VnicProfile;
|
|||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.cloud.api.query.dao.AsyncJobJoinDao;
|
||||
import com.cloud.api.query.dao.DataCenterJoinDao;
|
||||
|
|
@ -138,9 +139,11 @@ import com.cloud.dc.dao.ClusterDao;
|
|||
import com.cloud.dc.dao.DataCenterDao;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.PermissionDeniedException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.hypervisor.Hypervisor;
|
||||
import com.cloud.network.NetworkModel;
|
||||
import com.cloud.network.dao.NetworkDao;
|
||||
import com.cloud.network.dao.NetworkVO;
|
||||
import com.cloud.offering.ServiceOffering;
|
||||
|
|
@ -173,6 +176,9 @@ import com.cloud.vm.dao.UserVmDao;
|
|||
import com.cloud.vm.snapshot.VMSnapshotVO;
|
||||
import com.cloud.vm.snapshot.dao.VMSnapshotDao;
|
||||
|
||||
// ToDo: fix list APIs to support pagination, etc
|
||||
// ToDo: check access on objects
|
||||
|
||||
public class ServerAdapter extends ManagerBase {
|
||||
private static final String SERVICE_ACCOUNT_NAME = "veemserviceuser";
|
||||
private static final String SERVICE_ACCOUNT_ROLE_NAME = "Veeam Service Role";
|
||||
|
|
@ -279,7 +285,8 @@ public class ServerAdapter extends ManagerBase {
|
|||
@Inject
|
||||
ResourceTagDao resourceTagDao;
|
||||
|
||||
//ToDo: check access on objects
|
||||
@Inject
|
||||
NetworkModel networkModel;
|
||||
|
||||
protected static Tag getDummyTagByName(String name) {
|
||||
Tag tag = new Tag();
|
||||
|
|
@ -340,7 +347,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
}
|
||||
}
|
||||
|
||||
protected Pair<User, Account> createServiceAccountIfNeeded() {
|
||||
protected Pair<User, Account> getDefaultServiceAccount() {
|
||||
UserAccount userAccount = accountService.getActiveUserAccount(SERVICE_ACCOUNT_NAME, 1L);
|
||||
if (userAccount == null) {
|
||||
userAccount = createServiceAccount();
|
||||
|
|
@ -351,9 +358,64 @@ public class ServerAdapter extends ManagerBase {
|
|||
accountService.getActiveAccountById(userAccount.getAccountId()));
|
||||
}
|
||||
|
||||
protected Pair<User, Account> getServiceAccount() {
|
||||
String serviceAccountUuid = VeeamControlService.ServiceAccountId.value();
|
||||
if (StringUtils.isEmpty(serviceAccountUuid)) {
|
||||
throw new CloudRuntimeException("Service account is not configured, unable to proceed");
|
||||
}
|
||||
Account account = accountService.getActiveAccountByUuid(serviceAccountUuid);
|
||||
if (account == null) {
|
||||
throw new CloudRuntimeException("Service account with ID " + serviceAccountUuid + " not found, unable to proceed");
|
||||
}
|
||||
User user = accountService.getOneActiveUserForAccount(account);
|
||||
if (user == null) {
|
||||
throw new CloudRuntimeException("No active user found for service account with ID " + serviceAccountUuid);
|
||||
}
|
||||
return new Pair<>(user, account);
|
||||
}
|
||||
|
||||
protected void waitForJobCompletion(long jobId) {
|
||||
long timeoutNanos = TimeUnit.MINUTES.toNanos(5);
|
||||
final long deadline = System.nanoTime() + timeoutNanos;
|
||||
long sleepMillis = 500;
|
||||
while (true) {
|
||||
AsyncJobVO job = asyncJobDao.findById(jobId);
|
||||
if (job == null) {
|
||||
logger.warn("Async job with ID {} not found", jobId);
|
||||
return;
|
||||
}
|
||||
if (job.getStatus() == AsyncJobVO.Status.SUCCEEDED || job.getStatus() == AsyncJobVO.Status.FAILED) {
|
||||
return;
|
||||
}
|
||||
if (System.nanoTime() > deadline) {
|
||||
logger.warn("Timed out waiting for {} completion", job);
|
||||
}
|
||||
try {
|
||||
Thread.sleep(sleepMillis);
|
||||
// back off gradually to reduce DB pressure
|
||||
sleepMillis = Math.min(5000, sleepMillis + 500);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
logger.warn("Interrupted while waiting for async job completion");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void waitForJobCompletion(AsyncJobJoinVO job) {
|
||||
if (job == null) {
|
||||
logger.warn("Async job not found");
|
||||
return;
|
||||
}
|
||||
if (job.getStatus() == AsyncJobVO.Status.SUCCEEDED.ordinal() ||
|
||||
job.getStatus() == AsyncJobVO.Status.FAILED.ordinal()) {
|
||||
logger.warn("Async job with ID {} already completed with status {}", job.getId(), job.getStatus());
|
||||
}
|
||||
waitForJobCompletion(job.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean start() {
|
||||
createServiceAccountIfNeeded();
|
||||
getServiceAccount();
|
||||
//find public custom disk offering
|
||||
return true;
|
||||
}
|
||||
|
|
@ -445,7 +507,6 @@ public class ServerAdapter extends ManagerBase {
|
|||
}
|
||||
|
||||
public List<Vm> listAllInstances() {
|
||||
// Todo: add filtering, pagination
|
||||
List<UserVmJoinVO> vms = userVmJoinDao.listAll();
|
||||
return UserVmJoinVOToVmConverter.toVmList(vms, this::getHostById);
|
||||
}
|
||||
|
|
@ -512,7 +573,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
bootType = ApiConstants.BootType.UEFI;
|
||||
bootMode = ApiConstants.BootMode.SECURE;
|
||||
}
|
||||
Pair<User, Account> serviceUserAccount = createServiceAccountIfNeeded();
|
||||
Pair<User, Account> serviceUserAccount = getServiceAccount();
|
||||
CallContext ctx = CallContext.register(serviceUserAccount.first(), serviceUserAccount.second());
|
||||
try {
|
||||
return createInstance(zoneId, clusterId, name, displayName, cpu, memory, userdata, bootType, bootMode);
|
||||
|
|
@ -561,7 +622,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
if (bootMode != null) {
|
||||
cmd.setBootMode(bootMode.toString());
|
||||
}
|
||||
// ToDo: handle other.
|
||||
// ToDo: handle any other field?
|
||||
cmd.setHypervisor(Hypervisor.HypervisorType.KVM.name());
|
||||
cmd.setBlankInstance(true);
|
||||
Map<String, String> details = new HashMap<>();
|
||||
|
|
@ -581,19 +642,33 @@ public class ServerAdapter extends ManagerBase {
|
|||
}
|
||||
|
||||
public Vm updateInstance(String uuid, Vm request) {
|
||||
// ToDo: what to do?!
|
||||
logger.warn("Received request to update VM with ID {}. No action, returning existing VM data.", uuid);
|
||||
return getInstance(uuid, false, false, false);
|
||||
}
|
||||
|
||||
public void deleteInstance(String uuid) {
|
||||
public VmAction deleteInstance(String uuid) {
|
||||
UserVmVO vo = userVmDao.findByUuid(uuid);
|
||||
if (vo == null) {
|
||||
throw new InvalidParameterValueException("VM with ID " + uuid + " not found");
|
||||
}
|
||||
Pair<User, Account> serviceUserAccount = getServiceAccount();
|
||||
CallContext ctx = CallContext.register(serviceUserAccount.first(), serviceUserAccount.second());
|
||||
try {
|
||||
userVmService.destroyVm(vo.getId(), true);
|
||||
} catch (ResourceUnavailableException e) {
|
||||
DestroyVMCmd cmd = new DestroyVMCmd();
|
||||
cmd.setHttpMethod(BaseCmd.HTTPMethod.POST.name());
|
||||
ComponentContext.inject(cmd);
|
||||
Map<String, String> params = new HashMap<>();
|
||||
params.put(ApiConstants.ID, vo.getUuid());
|
||||
params.put(ApiConstants.EXPUNGE, Boolean.TRUE.toString());
|
||||
ApiServerService.AsyncCmdResult result =
|
||||
apiServerService.processAsyncCmd(cmd, params, ctx, serviceUserAccount.first().getId(),
|
||||
serviceUserAccount.second());
|
||||
AsyncJobJoinVO asyncJobJoinVO = asyncJobJoinDao.findById(result.jobId);
|
||||
return AsyncJobJoinVOToJobConverter.toVmAction(asyncJobJoinVO, userVmJoinDao.findById(vo.getId()));
|
||||
} catch (Exception e) {
|
||||
throw new CloudRuntimeException("Failed to delete VM: " + e.getMessage(), e);
|
||||
} finally {
|
||||
CallContext.unregister();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -602,7 +677,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
if (vo == null) {
|
||||
throw new InvalidParameterValueException("VM with ID " + uuid + " not found");
|
||||
}
|
||||
Pair<User, Account> serviceUserAccount = createServiceAccountIfNeeded();
|
||||
Pair<User, Account> serviceUserAccount = getServiceAccount();
|
||||
CallContext ctx = CallContext.register(serviceUserAccount.first(), serviceUserAccount.second());
|
||||
try {
|
||||
StartVMCmd cmd = new StartVMCmd();
|
||||
|
|
@ -627,7 +702,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
if (vo == null) {
|
||||
throw new InvalidParameterValueException("VM with ID " + uuid + " not found");
|
||||
}
|
||||
Pair<User, Account> serviceUserAccount = createServiceAccountIfNeeded();
|
||||
Pair<User, Account> serviceUserAccount = getServiceAccount();
|
||||
CallContext ctx = CallContext.register(serviceUserAccount.first(), serviceUserAccount.second());
|
||||
try {
|
||||
StopVMCmd cmd = new StopVMCmd();
|
||||
|
|
@ -653,7 +728,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
if (vo == null) {
|
||||
throw new InvalidParameterValueException("VM with ID " + uuid + " not found");
|
||||
}
|
||||
Pair<User, Account> serviceUserAccount = createServiceAccountIfNeeded();
|
||||
Pair<User, Account> serviceUserAccount = getServiceAccount();
|
||||
CallContext ctx = CallContext.register(serviceUserAccount.first(), serviceUserAccount.second());
|
||||
try {
|
||||
StopVMCmd cmd = new StopVMCmd();
|
||||
|
|
@ -674,9 +749,13 @@ public class ServerAdapter extends ManagerBase {
|
|||
}
|
||||
}
|
||||
|
||||
protected Long getVolumePhysicalSize(VolumeJoinVO vo) {
|
||||
return volumeApiService.getVolumePhysicalSize(vo.getFormat(), vo.getPath(), vo.getChainInfo());
|
||||
}
|
||||
|
||||
public List<Disk> listAllDisks() {
|
||||
List<VolumeJoinVO> kvmVolumes = volumeJoinDao.listByHypervisor(Hypervisor.HypervisorType.KVM);
|
||||
return VolumeJoinVOToDiskConverter.toDiskList(kvmVolumes);
|
||||
return VolumeJoinVOToDiskConverter.toDiskList(kvmVolumes, this::getVolumePhysicalSize);
|
||||
}
|
||||
|
||||
public Disk getDisk(String uuid) {
|
||||
|
|
@ -684,7 +763,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
if (vo == null) {
|
||||
throw new InvalidParameterValueException("Disk with ID " + uuid + " not found");
|
||||
}
|
||||
return VolumeJoinVOToDiskConverter.toDisk(vo);
|
||||
return VolumeJoinVOToDiskConverter.toDisk(vo, this::getVolumePhysicalSize);
|
||||
}
|
||||
|
||||
public Disk copyDisk(String uuid) {
|
||||
|
|
@ -723,7 +802,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
|
||||
protected List<DiskAttachment> listDiskAttachmentsByInstanceId(final long instanceId) {
|
||||
List<VolumeJoinVO> kvmVolumes = volumeJoinDao.listByInstanceId(instanceId);
|
||||
return VolumeJoinVOToDiskConverter.toDiskAttachmentList(kvmVolumes);
|
||||
return VolumeJoinVOToDiskConverter.toDiskAttachmentList(kvmVolumes, this::getVolumePhysicalSize);
|
||||
}
|
||||
|
||||
public List<DiskAttachment> listDiskAttachmentsByInstanceUuid(final String uuid) {
|
||||
|
|
@ -734,7 +813,35 @@ public class ServerAdapter extends ManagerBase {
|
|||
return listDiskAttachmentsByInstanceId(vo.getId());
|
||||
}
|
||||
|
||||
public DiskAttachment handleInstanceAttachDisk(final String vmUuid, final DiskAttachment request) {
|
||||
protected void assignVolumeToAccount(VolumeVO volumeVO, long accountId, Pair<User, Account> serviceUserAccount) {
|
||||
Account account = accountService.getActiveAccountById(accountId);
|
||||
if (account == null) {
|
||||
throw new InvalidParameterValueException("Account with ID " + accountId + " not found");
|
||||
}
|
||||
CallContext.register(serviceUserAccount.first(), serviceUserAccount.second());
|
||||
try {
|
||||
AssignVolumeCmd cmd = new AssignVolumeCmd();
|
||||
ComponentContext.inject(cmd);
|
||||
Map<String, String> params = new HashMap<>();
|
||||
cmd.setVolumeId(volumeVO.getId());
|
||||
params.put(ApiConstants.VOLUME_ID, volumeVO.getUuid());
|
||||
if (Account.Type.PROJECT.equals(account.getType())) {
|
||||
cmd.setProjectId(account.getId());
|
||||
params.put(ApiConstants.PROJECT_ID, account.getUuid());
|
||||
} else {
|
||||
cmd.setAccountId(account.getId());
|
||||
params.put(ApiConstants.ACCOUNT_ID, account.getUuid());
|
||||
}
|
||||
cmd.setFullUrlParams(params);
|
||||
volumeApiService.assignVolumeToAccount(cmd);
|
||||
} catch (ResourceAllocationException | CloudRuntimeException e) {
|
||||
logger.error("Failed to assign {} to {}: {}", volumeVO, account, e.getMessage(), e);
|
||||
} finally {
|
||||
CallContext.unregister();
|
||||
}
|
||||
}
|
||||
|
||||
public DiskAttachment attachInstanceDisk(final String vmUuid, final DiskAttachment request) {
|
||||
UserVmVO vmVo = userVmDao.findByUuid(vmUuid);
|
||||
if (vmVo == null) {
|
||||
throw new InvalidParameterValueException("VM with ID " + vmUuid + " not found");
|
||||
|
|
@ -746,12 +853,25 @@ public class ServerAdapter extends ManagerBase {
|
|||
if (volumeVO == null) {
|
||||
throw new InvalidParameterValueException("Disk with ID " + request.getDisk().getId() + " not found");
|
||||
}
|
||||
Pair<User, Account> serviceUserAccount = createServiceAccountIfNeeded();
|
||||
Pair<User, Account> serviceUserAccount = getServiceAccount();
|
||||
if (vmVo.getAccountId() != volumeVO.getAccountId()) {
|
||||
if (VeeamControlService.InstanceRestoreAssignOwner.value()) {
|
||||
assignVolumeToAccount(volumeVO, vmVo.getAccountId(), serviceUserAccount);
|
||||
} else {
|
||||
throw new PermissionDeniedException("Disk with ID " + request.getDisk().getId() +
|
||||
" belongs to a different account and cannot be attached to the VM");
|
||||
}
|
||||
}
|
||||
CallContext.register(serviceUserAccount.first(), serviceUserAccount.second());
|
||||
try {
|
||||
Volume volume = volumeApiService.attachVolumeToVM(vmVo.getId(), volumeVO.getId(), 0L, false);
|
||||
Long deviceId = null;
|
||||
List<VolumeVO> volumes = volumeDao.findUsableVolumesForInstance(vmVo.getId());
|
||||
if (CollectionUtils.isEmpty(volumes)) {
|
||||
deviceId = 0L;
|
||||
}
|
||||
Volume volume = volumeApiService.attachVolumeToVM(vmVo.getId(), volumeVO.getId(), deviceId, false);
|
||||
VolumeJoinVO attachedVolumeVO = volumeJoinDao.findById(volume.getId());
|
||||
return VolumeJoinVOToDiskConverter.toDiskAttachment(attachedVolumeVO);
|
||||
return VolumeJoinVOToDiskConverter.toDiskAttachment(attachedVolumeVO, this::getVolumePhysicalSize);
|
||||
} finally {
|
||||
CallContext.unregister();
|
||||
}
|
||||
|
|
@ -765,7 +885,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
volumeApiService.deleteVolume(vo.getId(), accountService.getSystemAccount());
|
||||
}
|
||||
|
||||
public Disk handleCreateDisk(Disk request) {
|
||||
public Disk createDisk(Disk request) {
|
||||
if (request == null) {
|
||||
throw new InvalidParameterValueException("Request disk data is empty");
|
||||
}
|
||||
|
|
@ -805,7 +925,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
initialSize = Long.parseLong(request.getInitialSize());
|
||||
} catch (NumberFormatException ignored) {}
|
||||
}
|
||||
Pair<User, Account> serviceUserAccount = createServiceAccountIfNeeded();
|
||||
Pair<User, Account> serviceUserAccount = getServiceAccount();
|
||||
Account serviceAccount = serviceUserAccount.second();
|
||||
DataCenterVO zone = dataCenterDao.findById(pool.getDataCenterId());
|
||||
if (zone == null || !Grouping.AllocationState.Enabled.equals(zone.getAllocationState())) {
|
||||
|
|
@ -815,7 +935,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
if (diskOfferingId == null) {
|
||||
throw new CloudRuntimeException("Failed to find custom offering for disk" + zone.getName());
|
||||
}
|
||||
CallContext ctx = CallContext.register(serviceUserAccount.first(), serviceUserAccount.second());
|
||||
CallContext.register(serviceUserAccount.first(), serviceUserAccount.second());
|
||||
try {
|
||||
return createDisk(serviceAccount, pool, name, diskOfferingId, provisionedSizeInGb, initialSize);
|
||||
} finally {
|
||||
|
|
@ -841,7 +961,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
}
|
||||
|
||||
// Implementation for creating a Disk resource
|
||||
return VolumeJoinVOToDiskConverter.toDisk(volumeJoinDao.findById(volume.getId()));
|
||||
return VolumeJoinVOToDiskConverter.toDisk(volumeJoinDao.findById(volume.getId()), this::getVolumePhysicalSize);
|
||||
}
|
||||
|
||||
protected List<Nic> listNicsByInstance(final long instanceId, final String instanceUuid) {
|
||||
|
|
@ -861,7 +981,42 @@ public class ServerAdapter extends ManagerBase {
|
|||
return listNicsByInstance(vo.getId(), vo.getUuid());
|
||||
}
|
||||
|
||||
public Nic handleAttachInstanceNic(final String vmUuid, final Nic request) {
|
||||
protected boolean accountCannotAccessNetwork(NetworkVO networkVO, long accountId) {
|
||||
Account account = accountService.getActiveAccountById(accountId);
|
||||
try {
|
||||
networkModel.checkNetworkPermissions(account, networkVO);
|
||||
return false;
|
||||
} catch (CloudRuntimeException e) {
|
||||
logger.debug("{} cannot access {}: {}", account, networkVO, e.getMessage());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected void assignVmToAccount(UserVmVO vmVO, long accountId, Pair<User, Account> serviceUserAccount) {
|
||||
Account account = accountService.getActiveAccountById(accountId);
|
||||
if (account == null) {
|
||||
throw new InvalidParameterValueException("Account with ID " + accountId + " not found");
|
||||
}
|
||||
CallContext.register(serviceUserAccount.first(), serviceUserAccount.second());
|
||||
try {
|
||||
AssignVMCmd cmd = new AssignVMCmd();
|
||||
ComponentContext.inject(cmd);
|
||||
cmd.setVirtualMachineId(vmVO.getId());
|
||||
cmd.setAccountName(account.getAccountName());
|
||||
cmd.setDomainId(account.getDomainId());
|
||||
if (Account.Type.PROJECT.equals(account.getType())) {
|
||||
cmd.setProjectId(account.getId());
|
||||
}
|
||||
userVmService.moveVmToUser(cmd);
|
||||
} catch (ResourceAllocationException | CloudRuntimeException | ResourceUnavailableException |
|
||||
InsufficientCapacityException e) {
|
||||
logger.error("Failed to assign {} to {}: {}", vmVO, account, e.getMessage(), e);
|
||||
} finally {
|
||||
CallContext.unregister();
|
||||
}
|
||||
}
|
||||
|
||||
public Nic attachInstanceNic(final String vmUuid, final Nic request) {
|
||||
UserVmVO vmVo = userVmDao.findByUuid(vmUuid);
|
||||
if (vmVo == null) {
|
||||
throw new InvalidParameterValueException("VM with ID " + vmUuid + " not found");
|
||||
|
|
@ -873,7 +1028,13 @@ public class ServerAdapter extends ManagerBase {
|
|||
if (networkVO == null) {
|
||||
throw new InvalidParameterValueException("VNic profile " + request.getVnicProfile().getId() + " not found");
|
||||
}
|
||||
Pair<User, Account> serviceUserAccount = createServiceAccountIfNeeded();
|
||||
Pair<User, Account> serviceUserAccount = getServiceAccount();
|
||||
if (vmVo.getAccountId() != networkVO.getAccountId() &&
|
||||
networkVO.getAccountId() != Account.ACCOUNT_ID_SYSTEM &&
|
||||
VeeamControlService.InstanceRestoreAssignOwner.value() &&
|
||||
accountCannotAccessNetwork(networkVO, vmVo.getAccountId())) {
|
||||
assignVmToAccount(vmVo, networkVO.getAccountId(), serviceUserAccount);
|
||||
}
|
||||
CallContext.register(serviceUserAccount.first(), serviceUserAccount.second());
|
||||
try {
|
||||
AddNicToVMCmd cmd = new AddNicToVMCmd();
|
||||
|
|
@ -907,7 +1068,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
return ImageTransferVOToImageTransferConverter.toImageTransfer(vo, this::getHostById, this::getVolumeById);
|
||||
}
|
||||
|
||||
public ImageTransfer handleCreateImageTransfer(ImageTransfer request) {
|
||||
public ImageTransfer createImageTransfer(ImageTransfer request) {
|
||||
if (request == null) {
|
||||
throw new InvalidParameterValueException("Request image transfer data is empty");
|
||||
}
|
||||
|
|
@ -934,7 +1095,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
return createImageTransfer(backupId, volumeVO.getId(), direction, format);
|
||||
}
|
||||
|
||||
public boolean handleCancelImageTransfer(String uuid) {
|
||||
public boolean cancelImageTransfer(String uuid) {
|
||||
ImageTransferVO vo = imageTransferDao.findByUuid(uuid);
|
||||
if (vo == null) {
|
||||
throw new InvalidParameterValueException("Image transfer with ID " + uuid + " not found");
|
||||
|
|
@ -942,7 +1103,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
return incrementalBackupService.cancelImageTransfer(vo.getId());
|
||||
}
|
||||
|
||||
public boolean handleFinalizeImageTransfer(String uuid) {
|
||||
public boolean finalizeImageTransfer(String uuid) {
|
||||
ImageTransferVO vo = imageTransferDao.findByUuid(uuid);
|
||||
if (vo == null) {
|
||||
throw new InvalidParameterValueException("Image transfer with ID " + uuid + " not found");
|
||||
|
|
@ -951,7 +1112,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
}
|
||||
|
||||
private ImageTransfer createImageTransfer(Long backupId, Long volumeId, Direction direction, Format format) {
|
||||
Pair<User, Account> serviceUserAccount = createServiceAccountIfNeeded();
|
||||
Pair<User, Account> serviceUserAccount = getServiceAccount();
|
||||
CallContext.register(serviceUserAccount.first(), serviceUserAccount.second());
|
||||
try {
|
||||
org.apache.cloudstack.backup.ImageTransfer imageTransfer =
|
||||
|
|
@ -992,8 +1153,10 @@ public class ServerAdapter extends ManagerBase {
|
|||
}
|
||||
|
||||
public List<Job> listAllJobs() {
|
||||
// ToDo: find active jobs for service account
|
||||
return Collections.emptyList();
|
||||
Pair<User, Account> serviceUserAccount = getServiceAccount();
|
||||
List<Long> jobIds = asyncJobDao.listPendingJobIdsForAccount(serviceUserAccount.second().getId());
|
||||
List<AsyncJobJoinVO> jobJoinVOs = asyncJobJoinDao.listByIds(jobIds);
|
||||
return AsyncJobJoinVOToJobConverter.toJobList(jobJoinVOs);
|
||||
}
|
||||
|
||||
public Job getJob(String uuid) {
|
||||
|
|
@ -1013,12 +1176,12 @@ public class ServerAdapter extends ManagerBase {
|
|||
return VmSnapshotVOToSnapshotConverter.toSnapshotList(snapshots, vo.getUuid());
|
||||
}
|
||||
|
||||
public Snapshot handleCreateInstanceSnapshot(final String vmUuid, final Snapshot request) {
|
||||
public Snapshot createInstanceSnapshot(final String vmUuid, final Snapshot request) {
|
||||
UserVmVO vmVo = userVmDao.findByUuid(vmUuid);
|
||||
if (vmVo == null) {
|
||||
throw new InvalidParameterValueException("VM with ID " + vmUuid + " not found");
|
||||
}
|
||||
Pair<User, Account> serviceUserAccount = createServiceAccountIfNeeded();
|
||||
Pair<User, Account> serviceUserAccount = getServiceAccount();
|
||||
CallContext ctx = CallContext.register(serviceUserAccount.first(), serviceUserAccount.second());
|
||||
try {
|
||||
CreateVMSnapshotCmd cmd = new CreateVMSnapshotCmd();
|
||||
|
|
@ -1060,7 +1223,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
if (vo == null) {
|
||||
throw new InvalidParameterValueException("Snapshot with ID " + uuid + " not found");
|
||||
}
|
||||
Pair<User, Account> serviceUserAccount = createServiceAccountIfNeeded();
|
||||
Pair<User, Account> serviceUserAccount = getServiceAccount();
|
||||
CallContext ctx = CallContext.register(serviceUserAccount.first(), serviceUserAccount.second());
|
||||
try {
|
||||
DeleteVMSnapshotCmd cmd = new DeleteVMSnapshotCmd();
|
||||
|
|
@ -1074,10 +1237,10 @@ public class ServerAdapter extends ManagerBase {
|
|||
if (jobVo == null) {
|
||||
throw new CloudRuntimeException("Failed to find job for snapshot deletion");
|
||||
}
|
||||
action = AsyncJobJoinVOToJobConverter.toAction(jobVo);
|
||||
if (async) {
|
||||
// ToDo: wait for job completion?
|
||||
if (!async) {
|
||||
waitForJobCompletion(jobVo);
|
||||
}
|
||||
action = AsyncJobJoinVOToJobConverter.toAction(jobVo);
|
||||
} catch (Exception e) {
|
||||
throw new CloudRuntimeException("Failed to delete snapshot: " + e.getMessage(), e);
|
||||
} finally {
|
||||
|
|
@ -1086,34 +1249,33 @@ public class ServerAdapter extends ManagerBase {
|
|||
return action;
|
||||
}
|
||||
|
||||
public ResourceAction revertToSnapshot(String uuid) {
|
||||
throw new InvalidParameterValueException("revertToSnapshot with ID " + uuid + " not implemented");
|
||||
// ResourceAction action = null;
|
||||
// VMSnapshotVO vo = vmSnapshotDao.findByUuid(uuid);
|
||||
// if (vo == null) {
|
||||
// throw new InvalidParameterValueException("Snapshot with ID " + uuid + " not found");
|
||||
// }
|
||||
// Pair<User, Account> serviceUserAccount = createServiceAccountIfNeeded();
|
||||
// CallContext ctx = CallContext.register(serviceUserAccount.first(), serviceUserAccount.second());
|
||||
// try {
|
||||
// RevertToVMSnapshotCmd cmd = new RevertToVMSnapshotCmd();
|
||||
// ComponentContext.inject(cmd);
|
||||
// Map<String, String> params = new HashMap<>();
|
||||
// params.put(ApiConstants.VM_SNAPSHOT_ID, vo.getUuid());
|
||||
// ApiServerService.AsyncCmdResult result =
|
||||
// apiServerService.processAsyncCmd(cmd, params, ctx, serviceUserAccount.first().getId(),
|
||||
// serviceUserAccount.second());
|
||||
// AsyncJobJoinVO jobVo = asyncJobJoinDao.findById(result.jobId);
|
||||
// if (jobVo == null) {
|
||||
// throw new CloudRuntimeException("Failed to find job for snapshot revert");
|
||||
// }
|
||||
// action = AsyncJobJoinVOToJobConverter.toAction(jobVo);
|
||||
// } catch (Exception e) {
|
||||
// throw new CloudRuntimeException("Failed to revert to snapshot: " + e.getMessage(), e);
|
||||
// } finally {
|
||||
// CallContext.unregister();
|
||||
// }
|
||||
// return action;
|
||||
public ResourceAction revertInstanceToSnapshot(String uuid) {
|
||||
ResourceAction action = null;
|
||||
VMSnapshotVO vo = vmSnapshotDao.findByUuid(uuid);
|
||||
if (vo == null) {
|
||||
throw new InvalidParameterValueException("Snapshot with ID " + uuid + " not found");
|
||||
}
|
||||
Pair<User, Account> serviceUserAccount = getServiceAccount();
|
||||
CallContext ctx = CallContext.register(serviceUserAccount.first(), serviceUserAccount.second());
|
||||
try {
|
||||
RevertToVMSnapshotCmd cmd = new RevertToVMSnapshotCmd();
|
||||
ComponentContext.inject(cmd);
|
||||
Map<String, String> params = new HashMap<>();
|
||||
params.put(ApiConstants.VM_SNAPSHOT_ID, vo.getUuid());
|
||||
ApiServerService.AsyncCmdResult result =
|
||||
apiServerService.processAsyncCmd(cmd, params, ctx, serviceUserAccount.first().getId(),
|
||||
serviceUserAccount.second());
|
||||
AsyncJobJoinVO jobVo = asyncJobJoinDao.findById(result.jobId);
|
||||
if (jobVo == null) {
|
||||
throw new CloudRuntimeException("Failed to find job for snapshot revert");
|
||||
}
|
||||
action = AsyncJobJoinVOToJobConverter.toAction(jobVo);
|
||||
} catch (Exception e) {
|
||||
throw new CloudRuntimeException("Failed to revert to snapshot: " + e.getMessage(), e);
|
||||
} finally {
|
||||
CallContext.unregister();
|
||||
}
|
||||
return action;
|
||||
}
|
||||
|
||||
public List<Backup> listBackupsByInstanceUuid(final String uuid) {
|
||||
|
|
@ -1130,7 +1292,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
if (vmVo == null) {
|
||||
throw new InvalidParameterValueException("VM with ID " + vmUuid + " not found");
|
||||
}
|
||||
Pair<User, Account> serviceUserAccount = createServiceAccountIfNeeded();
|
||||
Pair<User, Account> serviceUserAccount = getServiceAccount();
|
||||
CallContext ctx = CallContext.register(serviceUserAccount.first(), serviceUserAccount.second());
|
||||
try {
|
||||
StartBackupCmd cmd = new StartBackupCmd();
|
||||
|
|
@ -1156,42 +1318,6 @@ public class ServerAdapter extends ManagerBase {
|
|||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private BackupVO getBackupFromJob(ApiServerService.AsyncCmdResult result, UserVmVO vmVo) {
|
||||
AsyncJobVO jobVo = null;
|
||||
// wait for job to complete and get backup ID
|
||||
long timeoutNanos = TimeUnit.MINUTES.toNanos(2);
|
||||
final long deadline = System.nanoTime() + timeoutNanos;
|
||||
long sleepMillis = 1000;
|
||||
while (System.nanoTime() < deadline) {
|
||||
jobVo = asyncJobDao.findByIdIncludingRemoved(result.jobId);
|
||||
if (jobVo == null) {
|
||||
throw new CloudRuntimeException("Failed to find job for backup creation");
|
||||
}
|
||||
if (!JobInfo.Status.IN_PROGRESS.equals(jobVo.getStatus())) {
|
||||
break;
|
||||
}
|
||||
try {
|
||||
Thread.sleep(sleepMillis);
|
||||
// back off gradually to reduce DB pressure
|
||||
sleepMillis = Math.min(5000, sleepMillis + 500);
|
||||
} catch (InterruptedException ie) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new CloudRuntimeException("Interrupted while waiting for backup creation job", ie);
|
||||
}
|
||||
}
|
||||
// if still in progress after timeout, fail fast
|
||||
if (jobVo != null && JobInfo.Status.IN_PROGRESS.equals(jobVo.getStatus())) {
|
||||
throw new CloudRuntimeException("Timed out waiting for backup creation job");
|
||||
}
|
||||
BackupVO vo = null;
|
||||
List<BackupVO> backups = backupDao.searchByVmIds(List.of(vmVo.getId()));
|
||||
if (CollectionUtils.isNotEmpty(backups)) {
|
||||
vo = backups.get(0);
|
||||
}
|
||||
return vo;
|
||||
}
|
||||
|
||||
public Backup getBackup(String uuid) {
|
||||
BackupVO vo = backupDao.findByUuidIncludingRemoved(uuid);
|
||||
if (vo == null) {
|
||||
|
|
@ -1203,12 +1329,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
|
||||
public List<Disk> listDisksByBackupUuid(final String uuid) {
|
||||
throw new InvalidParameterValueException("List Backup Disks with ID " + uuid + " not implemented");
|
||||
// ToDo: implement
|
||||
// BackupVO vo = backupDao.findByUuid(uuid);
|
||||
// if (vo == null) {
|
||||
// throw new InvalidParameterValueException("Backup with ID " + uuid + " not found");
|
||||
// }
|
||||
// return VolumeJoinVOToDiskConverter.toDiskList(volumes);
|
||||
// This won't be feasible with current structure
|
||||
}
|
||||
|
||||
public Backup finalizeBackup(final String vmUuid, final String backupUuid) {
|
||||
|
|
@ -1220,7 +1341,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
if (backup == null) {
|
||||
throw new InvalidParameterValueException("Backup with ID " + backupUuid + " not found");
|
||||
}
|
||||
Pair<User, Account> serviceUserAccount = createServiceAccountIfNeeded();
|
||||
Pair<User, Account> serviceUserAccount = getServiceAccount();
|
||||
CallContext ctx = CallContext.register(serviceUserAccount.first(), serviceUserAccount.second());
|
||||
try {
|
||||
FinalizeBackupCmd cmd = new FinalizeBackupCmd();
|
||||
|
|
@ -1271,7 +1392,7 @@ public class ServerAdapter extends ManagerBase {
|
|||
logger.warn("Checkpoint ID {} does not match active checkpoint for VM {}", checkpointId, vmUuid);
|
||||
return;
|
||||
}
|
||||
Pair<User, Account> serviceUserAccount = createServiceAccountIfNeeded();
|
||||
Pair<User, Account> serviceUserAccount = getServiceAccount();
|
||||
CallContext.register(serviceUserAccount.first(), serviceUserAccount.second());
|
||||
try {
|
||||
DeleteVmCheckpointCmd cmd = new DeleteVmCheckpointCmd();
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ public class DisksRouteHandler extends ManagerBase implements RouteHandler {
|
|||
String data = RouteHandler.getRequestData(req, logger);
|
||||
try {
|
||||
Disk request = io.getMapper().jsonMapper().readValue(data, Disk.class);
|
||||
Disk response = serverAdapter.handleCreateDisk(request);
|
||||
Disk response = serverAdapter.createDisk(request);
|
||||
io.getWriter().write(resp, HttpServletResponse.SC_CREATED, response, outFormat);
|
||||
} catch (JsonProcessingException | CloudRuntimeException e) {
|
||||
io.badRequest(resp, e.getMessage(), outFormat);
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ public class ImageTransfersRouteHandler extends ManagerBase implements RouteHand
|
|||
String data = RouteHandler.getRequestData(req, logger);
|
||||
try {
|
||||
ImageTransfer request = io.getMapper().jsonMapper().readValue(data, ImageTransfer.class);
|
||||
ImageTransfer response = serverAdapter.handleCreateImageTransfer(request);
|
||||
ImageTransfer response = serverAdapter.createImageTransfer(request);
|
||||
io.getWriter().write(resp, HttpServletResponse.SC_CREATED, response, outFormat);
|
||||
} catch (JsonProcessingException | CloudRuntimeException e) {
|
||||
io.badRequest(resp, e.getMessage(), outFormat);
|
||||
|
|
@ -128,27 +128,27 @@ public class ImageTransfersRouteHandler extends ManagerBase implements RouteHand
|
|||
ImageTransfer response = serverAdapter.getImageTransfer(id);
|
||||
io.getWriter().write(resp, HttpServletResponse.SC_OK, response, outFormat);
|
||||
} catch (InvalidParameterValueException e) {
|
||||
io.notFound(resp, e.getMessage(), outFormat);
|
||||
io.badRequest(resp, e.getMessage(), outFormat);
|
||||
}
|
||||
}
|
||||
|
||||
protected void handleCancelById(final String id, final HttpServletResponse resp, final Negotiation.OutFormat outFormat,
|
||||
final VeeamControlServlet io) throws IOException {
|
||||
try {
|
||||
serverAdapter.handleCancelImageTransfer(id);
|
||||
serverAdapter.cancelImageTransfer(id);
|
||||
io.getWriter().write(resp, HttpServletResponse.SC_OK, "Image transfer cancelled successfully", outFormat);
|
||||
} catch (InvalidParameterValueException e) {
|
||||
io.notFound(resp, e.getMessage(), outFormat);
|
||||
} catch (CloudRuntimeException e) {
|
||||
io.badRequest(resp, e.getMessage(), outFormat);
|
||||
}
|
||||
}
|
||||
|
||||
protected void handleFinalizeById(final String id, final HttpServletResponse resp, final Negotiation.OutFormat outFormat,
|
||||
final VeeamControlServlet io) throws IOException {
|
||||
try {
|
||||
serverAdapter.handleFinalizeImageTransfer(id);
|
||||
serverAdapter.finalizeImageTransfer(id);
|
||||
io.getWriter().write(resp, HttpServletResponse.SC_OK, "Image transfer finalized successfully", outFormat);
|
||||
} catch (CloudRuntimeException e) {
|
||||
io.notFound(resp, e.getMessage(), outFormat);
|
||||
io.badRequest(resp, e.getMessage(), outFormat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -345,15 +345,15 @@ public class VmsRouteHandler extends ManagerBase implements RouteHandler {
|
|||
protected void handleDeleteById(final String id, final HttpServletResponse resp, final Negotiation.OutFormat outFormat,
|
||||
final VeeamControlServlet io) throws IOException {
|
||||
try {
|
||||
serverAdapter.deleteInstance(id);
|
||||
io.getWriter().write(resp, HttpServletResponse.SC_OK, "", outFormat);
|
||||
VmAction vm = serverAdapter.deleteInstance(id);
|
||||
io.getWriter().write(resp, HttpServletResponse.SC_OK, vm, outFormat);
|
||||
} catch (CloudRuntimeException e) {
|
||||
io.notFound(resp, e.getMessage(), outFormat);
|
||||
}
|
||||
}
|
||||
|
||||
protected void handleStartVmById(final String id, final HttpServletRequest req, final HttpServletResponse resp, final Negotiation.OutFormat outFormat,
|
||||
final VeeamControlServlet io) throws IOException {
|
||||
protected void handleStartVmById(final String id, final HttpServletRequest req, final HttpServletResponse resp,
|
||||
final Negotiation.OutFormat outFormat, final VeeamControlServlet io) throws IOException {
|
||||
try {
|
||||
VmAction vm = serverAdapter.startInstance(id);
|
||||
io.getWriter().write(resp, HttpServletResponse.SC_ACCEPTED, vm, outFormat);
|
||||
|
|
@ -362,8 +362,8 @@ public class VmsRouteHandler extends ManagerBase implements RouteHandler {
|
|||
}
|
||||
}
|
||||
|
||||
protected void handleStopVmById(final String id, final HttpServletRequest req, final HttpServletResponse resp, final Negotiation.OutFormat outFormat,
|
||||
final VeeamControlServlet io) throws IOException {
|
||||
protected void handleStopVmById(final String id, final HttpServletRequest req, final HttpServletResponse resp,
|
||||
final Negotiation.OutFormat outFormat, final VeeamControlServlet io) throws IOException {
|
||||
try {
|
||||
VmAction vm = serverAdapter.stopInstance(id);
|
||||
io.getWriter().write(resp, HttpServletResponse.SC_ACCEPTED, vm, outFormat);
|
||||
|
|
@ -372,8 +372,8 @@ public class VmsRouteHandler extends ManagerBase implements RouteHandler {
|
|||
}
|
||||
}
|
||||
|
||||
protected void handleShutdownVmById(final String id, final HttpServletRequest req, final HttpServletResponse resp, final Negotiation.OutFormat outFormat,
|
||||
final VeeamControlServlet io) throws IOException {
|
||||
protected void handleShutdownVmById(final String id, final HttpServletRequest req, final HttpServletResponse resp,
|
||||
final Negotiation.OutFormat outFormat, final VeeamControlServlet io) throws IOException {
|
||||
try {
|
||||
VmAction vm = serverAdapter.shutdownInstance(id);
|
||||
io.getWriter().write(resp, HttpServletResponse.SC_ACCEPTED, vm, outFormat);
|
||||
|
|
@ -382,8 +382,8 @@ public class VmsRouteHandler extends ManagerBase implements RouteHandler {
|
|||
}
|
||||
}
|
||||
|
||||
protected void handleGetDiskAttachmentsByVmId(final String id, final HttpServletResponse resp, final Negotiation.OutFormat outFormat,
|
||||
final VeeamControlServlet io) throws IOException {
|
||||
protected void handleGetDiskAttachmentsByVmId(final String id, final HttpServletResponse resp,
|
||||
final Negotiation.OutFormat outFormat, final VeeamControlServlet io) throws IOException {
|
||||
try {
|
||||
List<DiskAttachment> disks = serverAdapter.listDiskAttachmentsByInstanceUuid(id);
|
||||
NamedList<DiskAttachment> response = NamedList.of("disk_attachment", disks);
|
||||
|
|
@ -399,15 +399,15 @@ public class VmsRouteHandler extends ManagerBase implements RouteHandler {
|
|||
String data = RouteHandler.getRequestData(req, logger);
|
||||
try {
|
||||
DiskAttachment request = io.getMapper().jsonMapper().readValue(data, DiskAttachment.class);
|
||||
DiskAttachment response = serverAdapter.handleInstanceAttachDisk(id, request);
|
||||
DiskAttachment response = serverAdapter.attachInstanceDisk(id, request);
|
||||
io.getWriter().write(resp, HttpServletResponse.SC_CREATED, response, outFormat);
|
||||
} catch (JsonProcessingException | CloudRuntimeException e) {
|
||||
io.badRequest(resp, e.getMessage(), outFormat);
|
||||
}
|
||||
}
|
||||
|
||||
protected void handleGetNicsByVmId(final String id, final HttpServletResponse resp, final Negotiation.OutFormat outFormat,
|
||||
final VeeamControlServlet io) throws IOException {
|
||||
protected void handleGetNicsByVmId(final String id, final HttpServletResponse resp,
|
||||
final Negotiation.OutFormat outFormat, final VeeamControlServlet io) throws IOException {
|
||||
try {
|
||||
List<Nic> nics = serverAdapter.listNicsByInstanceUuid(id);
|
||||
NamedList<Nic> response = NamedList.of("nic", nics);
|
||||
|
|
@ -423,7 +423,7 @@ public class VmsRouteHandler extends ManagerBase implements RouteHandler {
|
|||
String data = RouteHandler.getRequestData(req, logger);
|
||||
try {
|
||||
Nic request = io.getMapper().jsonMapper().readValue(data, Nic.class);
|
||||
Nic response = serverAdapter.handleAttachInstanceNic(id, request);
|
||||
Nic response = serverAdapter.attachInstanceNic(id, request);
|
||||
io.getWriter().write(resp, HttpServletResponse.SC_CREATED, response, outFormat);
|
||||
} catch (JsonProcessingException | CloudRuntimeException e) {
|
||||
io.badRequest(resp, e.getMessage(), outFormat);
|
||||
|
|
@ -447,7 +447,7 @@ public class VmsRouteHandler extends ManagerBase implements RouteHandler {
|
|||
String data = RouteHandler.getRequestData(req, logger);
|
||||
try {
|
||||
Snapshot request = io.getMapper().jsonMapper().readValue(data, Snapshot.class);
|
||||
Snapshot response = serverAdapter.handleCreateInstanceSnapshot(id, request);
|
||||
Snapshot response = serverAdapter.createInstanceSnapshot(id, request);
|
||||
io.getWriter().write(resp, HttpServletResponse.SC_ACCEPTED, response, outFormat);
|
||||
} catch (JsonProcessingException | CloudRuntimeException e) {
|
||||
io.badRequest(resp, e.getMessage(), outFormat);
|
||||
|
|
@ -455,7 +455,7 @@ public class VmsRouteHandler extends ManagerBase implements RouteHandler {
|
|||
}
|
||||
|
||||
protected void handleGetSnapshotById(final String id, final HttpServletResponse resp,
|
||||
final Negotiation.OutFormat outFormat, final VeeamControlServlet io) throws IOException {
|
||||
final Negotiation.OutFormat outFormat, final VeeamControlServlet io) throws IOException {
|
||||
try {
|
||||
Snapshot response = serverAdapter.getSnapshot(id);
|
||||
io.getWriter().write(resp, HttpServletResponse.SC_OK, response, outFormat);
|
||||
|
|
@ -484,9 +484,13 @@ public class VmsRouteHandler extends ManagerBase implements RouteHandler {
|
|||
protected void handleRestoreSnapshotById(final String id, final HttpServletRequest req,
|
||||
final HttpServletResponse resp, final Negotiation.OutFormat outFormat, final VeeamControlServlet io)
|
||||
throws IOException {
|
||||
//ToDo: implement
|
||||
String data = RouteHandler.getRequestData(req, logger);
|
||||
io.badRequest(resp, "Not implemented", outFormat);
|
||||
try {
|
||||
ResourceAction response = serverAdapter.revertInstanceToSnapshot(id);
|
||||
io.getWriter().write(resp, HttpServletResponse.SC_ACCEPTED, response, outFormat);
|
||||
} catch (CloudRuntimeException e) {
|
||||
io.badRequest(resp, e.getMessage(), outFormat);
|
||||
}
|
||||
}
|
||||
|
||||
protected void handleGetBackupsByVmId(final String id, final HttpServletResponse resp,
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@
|
|||
package org.apache.cloudstack.veeam.api.converter;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.cloudstack.jobs.JobInfo;
|
||||
import org.apache.cloudstack.veeam.VeeamControlService;
|
||||
|
|
@ -83,6 +85,10 @@ public class AsyncJobJoinVOToJobConverter {
|
|||
return job;
|
||||
}
|
||||
|
||||
public static List<Job> toJobList(List<AsyncJobJoinVO> vos) {
|
||||
return vos.stream().map(AsyncJobJoinVOToJobConverter::toJob).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
protected static void fillAction(final ResourceAction action, final AsyncJobJoinVO vo) {
|
||||
final String basePath = VeeamControlService.ContextPath.value();
|
||||
action.setJob(Ref.of(basePath + JobsRouteHandler.BASE_ROUTE + vo.getUuid(), vo.getUuid()));
|
||||
|
|
|
|||
|
|
@ -160,16 +160,16 @@ public final class UserVmJoinVOToVmConverter {
|
|||
basePath + ApiService.BASE_ROUTE + "/cpuprofiles/" + src.getServiceOfferingUuid(),
|
||||
src.getServiceOfferingUuid()));
|
||||
if (allContent) {
|
||||
dst.setInitialization(getOvfInitialization(dst));
|
||||
dst.setInitialization(getOvfInitialization(dst, src));
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
private static Vm.Initialization getOvfInitialization(Vm vm) {
|
||||
private static Vm.Initialization getOvfInitialization(Vm vm, UserVmJoinVO vo) {
|
||||
final Vm.Initialization.Configuration configuration = new Vm.Initialization.Configuration();
|
||||
configuration.setType("ovf");
|
||||
configuration.setData(OvfXmlUtil.toXml(vm));
|
||||
configuration.setData(OvfXmlUtil.toXml(vm, vo));
|
||||
|
||||
final Vm.Initialization initialization = new Vm.Initialization();
|
||||
initialization.setConfiguration(configuration);
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ package org.apache.cloudstack.veeam.api.converter;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.cloudstack.backup.Backup;
|
||||
|
|
@ -34,14 +35,12 @@ import org.apache.cloudstack.veeam.api.dto.Ref;
|
|||
import org.apache.cloudstack.veeam.api.dto.StorageDomain;
|
||||
import org.apache.cloudstack.veeam.api.dto.Vm;
|
||||
|
||||
import com.cloud.api.ApiDBUtils;
|
||||
import com.cloud.api.query.vo.VolumeJoinVO;
|
||||
import com.cloud.storage.Storage;
|
||||
import com.cloud.storage.Volume;
|
||||
import com.cloud.storage.VolumeStats;
|
||||
|
||||
public class VolumeJoinVOToDiskConverter {
|
||||
public static Disk toDisk(final VolumeJoinVO vol) {
|
||||
public static Disk toDisk(final VolumeJoinVO vol, final Function<VolumeJoinVO, Long> physicalSizeResolver) {
|
||||
final Disk disk = new Disk();
|
||||
final String basePath = VeeamControlService.ContextPath.value();
|
||||
final String apiBasePath = basePath + ApiService.BASE_ROUTE;
|
||||
|
|
@ -64,19 +63,12 @@ public class VolumeJoinVOToDiskConverter {
|
|||
disk.setProvisionedSize(String.valueOf(size));
|
||||
disk.setActualSize(String.valueOf(actualSize));
|
||||
disk.setTotalSize(String.valueOf(size));
|
||||
VolumeStats vs = null;
|
||||
if (List.of(Storage.ImageFormat.VHD, Storage.ImageFormat.QCOW2, Storage.ImageFormat.RAW).contains(vol.getFormat())) {
|
||||
if (vol.getPath() != null) {
|
||||
vs = ApiDBUtils.getVolumeStatistics(vol.getPath());
|
||||
}
|
||||
} else if (vol.getFormat() == Storage.ImageFormat.OVA) {
|
||||
if (vol.getChainInfo() != null) {
|
||||
vs = ApiDBUtils.getVolumeStatistics(vol.getChainInfo());
|
||||
}
|
||||
Long physicalSize = null;
|
||||
if (physicalSizeResolver != null) {
|
||||
physicalSize = physicalSizeResolver.apply(vol);
|
||||
}
|
||||
if (vs != null) {
|
||||
disk.setTotalSize(String.valueOf(vs.getVirtualSize()));
|
||||
disk.setActualSize(String.valueOf(vs.getPhysicalSize()));
|
||||
if (physicalSize != null) {
|
||||
disk.setActualSize(String.valueOf(physicalSize));
|
||||
}
|
||||
|
||||
// Disk format
|
||||
|
|
@ -122,9 +114,10 @@ public class VolumeJoinVOToDiskConverter {
|
|||
return disk;
|
||||
}
|
||||
|
||||
public static List<Disk> toDiskList(final List<VolumeJoinVO> srcList) {
|
||||
public static List<Disk> toDiskList(final List<VolumeJoinVO> srcList,
|
||||
final Function<VolumeJoinVO, Long> physicalSizeResolver) {
|
||||
return srcList.stream()
|
||||
.map(VolumeJoinVOToDiskConverter::toDisk)
|
||||
.map(vo -> toDisk(vo, physicalSizeResolver))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
|
@ -143,7 +136,8 @@ public class VolumeJoinVOToDiskConverter {
|
|||
return disks;
|
||||
}
|
||||
|
||||
public static DiskAttachment toDiskAttachment(final VolumeJoinVO vol) {
|
||||
public static DiskAttachment toDiskAttachment(final VolumeJoinVO vol,
|
||||
final Function<VolumeJoinVO, Long> physicalSizeResolver) {
|
||||
final DiskAttachment da = new DiskAttachment();
|
||||
final String basePath = VeeamControlService.ContextPath.value();
|
||||
|
||||
|
|
@ -154,7 +148,7 @@ public class VolumeJoinVOToDiskConverter {
|
|||
da.setHref(da.getVm().getHref() + "/diskattachments/" + diskAttachmentId);;
|
||||
|
||||
// Links
|
||||
da.setDisk(toDisk(vol));
|
||||
da.setDisk(toDisk(vol, physicalSizeResolver));
|
||||
|
||||
// Properties
|
||||
da.setActive("true");
|
||||
|
|
@ -167,9 +161,10 @@ public class VolumeJoinVOToDiskConverter {
|
|||
return da;
|
||||
}
|
||||
|
||||
public static List<DiskAttachment> toDiskAttachmentList(final List<VolumeJoinVO> srcList) {
|
||||
public static List<DiskAttachment> toDiskAttachmentList(final List<VolumeJoinVO> srcList,
|
||||
final Function<VolumeJoinVO, Long> physicalSizeResolver) {
|
||||
return srcList.stream()
|
||||
.map(VolumeJoinVOToDiskConverter::toDiskAttachment)
|
||||
.map(vo -> toDiskAttachment(vo, physicalSizeResolver))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
|
@ -190,9 +185,9 @@ public class VolumeJoinVOToDiskConverter {
|
|||
if (state == null) {
|
||||
return "ok";
|
||||
}
|
||||
switch (state.name().toLowerCase()) {
|
||||
case "ready":
|
||||
case "allocated":
|
||||
switch (state) {
|
||||
case Ready:
|
||||
case Allocated:
|
||||
return "ok";
|
||||
default:
|
||||
return "locked";
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@ import org.w3c.dom.Document;
|
|||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
import com.cloud.api.query.vo.UserVmJoinVO;
|
||||
|
||||
public class OvfXmlUtil {
|
||||
|
||||
private static final String NS_OVF = "http://schemas.dmtf.org/ovf/envelope/1/";
|
||||
|
|
@ -58,7 +60,7 @@ public class OvfXmlUtil {
|
|||
return sdf;
|
||||
});
|
||||
|
||||
public static String toXml(final Vm vm) {
|
||||
public static String toXml(final Vm vm, final UserVmJoinVO vo) {
|
||||
final String vmId = vm.getId();
|
||||
final String vmName = vm.getName();
|
||||
final String vmDesc = defaultString(vm.getDescription());
|
||||
|
|
@ -169,6 +171,32 @@ public class OvfXmlUtil {
|
|||
}
|
||||
sb.append("</Section>");
|
||||
|
||||
if (vo != null) {
|
||||
// -- Add a section for CloudStack-specific metadata that some consumers might look for (e.g. for import back into CloudStack) ---
|
||||
// Add CloudStack-specific metadata section
|
||||
sb.append("<Section xsi:type=\"ovf:CloudStackMetadata_Type\">");
|
||||
sb.append("<Info>CloudStack specific metadata</Info>");
|
||||
sb.append("<CloudStack>");
|
||||
sb.append("<AccountId>").append(vo.getAccountUuid()).append("</AccountId>");
|
||||
sb.append("<DomainId>").append(vo.getDomainUuid()).append("</DomainId>");
|
||||
sb.append("<ProjectId>").append(escapeText(vo.getProjectUuid())).append("</ProjectId>");
|
||||
sb.append("<ServiceOfferingId>").append(vo.getServiceOfferingUuid()).append("</ServiceOfferingId>");
|
||||
sb.append("<DataDiskOfferingIdMap>");
|
||||
for (DiskAttachment da : diskAttachments(vm)) {
|
||||
if (da == null || da.getDisk() == null || StringUtils.isBlank(da.getDisk().getId())) {
|
||||
continue;
|
||||
}
|
||||
final org.apache.cloudstack.veeam.api.dto.Disk d = da.getDisk();
|
||||
sb.append("<Entry>");
|
||||
sb.append("<DiskId>").append(escapeText(d.getId())).append("</DiskId>");
|
||||
sb.append("<OfferingId>").append(d.getDiskProfile().getId()).append("</OfferingId>");
|
||||
sb.append("</Entry>");
|
||||
}
|
||||
sb.append("</DataDiskOfferingIdMap>");
|
||||
sb.append("</CloudStack>");
|
||||
sb.append("</Section>");
|
||||
}
|
||||
|
||||
// --- Content / VirtualSystem ---
|
||||
sb.append("<Content ovf:id=\"out\" xsi:type=\"ovf:VirtualSystem_Type\">");
|
||||
sb.append("<Name>").append(escapeText(vmName)).append("</Name>");
|
||||
|
|
@ -191,7 +219,7 @@ public class OvfXmlUtil {
|
|||
sb.append("<IsRunAndPause>false</IsRunAndPause>");
|
||||
sb.append("<AutoStartup>false</AutoStartup>");
|
||||
sb.append("<Priority>0</Priority>");
|
||||
sb.append("<CreatedByUserId>").append(ZERO_UUID).append("</CreatedByUserId>");
|
||||
sb.append("<CreatedByUserId>").append(vo.getAccountUuid()).append("</CreatedByUserId>");
|
||||
sb.append("<MigrationSupport>0</MigrationSupport>");
|
||||
sb.append("<IsBootMenuEnabled>").append(escapeText(booleanString(vm.getBios() != null && vm.getBios().getBootMenu() != null ? vm.getBios().getBootMenu().getEnabled() : null, "false"))).append("</IsBootMenuEnabled>");
|
||||
sb.append("<IsSpiceFileTransferEnabled>true</IsSpiceFileTransferEnabled>");
|
||||
|
|
|
|||
|
|
@ -17,18 +17,22 @@
|
|||
|
||||
package org.apache.cloudstack.network.contrail.management;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.net.InetAddress;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import com.cloud.api.auth.SetupUserTwoFactorAuthenticationCmd;
|
||||
import org.apache.cloudstack.acl.ControlledEntity;
|
||||
import org.apache.cloudstack.acl.RolePermissionEntity;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
||||
import org.apache.cloudstack.acl.apikeypair.ApiKeyPair;
|
||||
import org.apache.cloudstack.acl.apikeypair.ApiKeyPairPermission;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.command.admin.account.CreateAccountCmd;
|
||||
import org.apache.cloudstack.api.command.admin.account.UpdateAccountCmd;
|
||||
import org.apache.cloudstack.api.command.admin.user.DeleteUserCmd;
|
||||
import org.apache.cloudstack.api.command.admin.user.DeleteUserKeysCmd;
|
||||
import org.apache.cloudstack.api.command.admin.user.GetUserKeysCmd;
|
||||
|
|
@ -37,20 +41,15 @@ import org.apache.cloudstack.api.command.admin.user.ListUserKeysCmd;
|
|||
import org.apache.cloudstack.api.command.admin.user.MoveUserCmd;
|
||||
import org.apache.cloudstack.api.command.admin.user.RegisterUserKeysCmd;
|
||||
import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd;
|
||||
import org.apache.cloudstack.api.response.ApiKeyPairResponse;
|
||||
import org.apache.cloudstack.api.response.ListResponse;
|
||||
import org.apache.cloudstack.api.response.UserTwoFactorAuthenticationSetupResponse;
|
||||
import org.apache.cloudstack.auth.UserTwoFactorAuthenticator;
|
||||
import org.apache.cloudstack.backup.BackupOffering;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
|
||||
import org.apache.cloudstack.acl.apikeypair.ApiKeyPair;
|
||||
import org.apache.cloudstack.acl.ControlledEntity;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.response.ApiKeyPairResponse;
|
||||
import org.apache.cloudstack.api.response.ListResponse;
|
||||
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
||||
import org.apache.cloudstack.api.command.admin.account.UpdateAccountCmd;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
|
||||
import com.cloud.api.auth.SetupUserTwoFactorAuthenticationCmd;
|
||||
import com.cloud.api.query.vo.ControlledViewEntity;
|
||||
import com.cloud.configuration.ResourceLimit;
|
||||
import com.cloud.configuration.dao.ResourceCountDao;
|
||||
|
|
@ -614,4 +613,14 @@ public class MockAccountManager extends ManagerBase implements AccountManager {
|
|||
@Override
|
||||
public void checkCallerRoleTypeAllowedForUserOrAccountOperations(Account userAccount, User user) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Account getActiveAccountByUuid(String accountUuid) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public User getOneActiveUserForAccount(Account account) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@
|
|||
// under the License.
|
||||
package com.cloud.api.query.dao;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.api.response.AsyncJobResponse;
|
||||
import org.apache.cloudstack.framework.jobs.AsyncJob;
|
||||
|
||||
|
|
@ -28,4 +30,6 @@ public interface AsyncJobJoinDao extends GenericDao<AsyncJobJoinVO, Long> {
|
|||
|
||||
AsyncJobJoinVO newAsyncJobView(AsyncJob vol);
|
||||
|
||||
List<AsyncJobJoinVO> listByIds(List<Long> ids);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,17 +16,17 @@
|
|||
// under the License.
|
||||
package com.cloud.api.query.dao;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import org.apache.cloudstack.api.ResponseObject;
|
||||
import org.apache.cloudstack.api.response.AsyncJobResponse;
|
||||
import org.apache.cloudstack.framework.jobs.AsyncJob;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.api.ApiResponseHelper;
|
||||
import com.cloud.api.ApiSerializerHelper;
|
||||
|
|
@ -115,4 +115,16 @@ public class AsyncJobJoinDaoImpl extends GenericDaoBase<AsyncJobJoinVO, Long> im
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AsyncJobJoinVO> listByIds(List<Long> ids) {
|
||||
if (CollectionUtils.isEmpty(ids)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
SearchBuilder<AsyncJobJoinVO> idsSearch = createSearchBuilder();
|
||||
idsSearch.and("ids", idsSearch.entity().getId(), SearchCriteria.Op.IN);
|
||||
idsSearch.done();
|
||||
SearchCriteria<AsyncJobJoinVO> sc = idsSearch.create();
|
||||
sc.setParameters("ids", ids.toArray());
|
||||
return listBy(sc);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2755,6 +2755,11 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
return _accountDao.findById(accountId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Account getActiveAccountByUuid(String accountUuid) {
|
||||
return _accountDao.findByUuid(accountUuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Account getAccount(long accountId) {
|
||||
return _accountDao.findByIdIncludingRemoved(accountId);
|
||||
|
|
@ -2773,6 +2778,15 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
return _userDao.findById(userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public User getOneActiveUserForAccount(Account account) {
|
||||
List<UserVO> users = _userDao.listByAccount(account.getId());
|
||||
if (CollectionUtils.isEmpty(users)) {
|
||||
return null;
|
||||
}
|
||||
return users.get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public User getUserIncludingRemoved(long userId) {
|
||||
return _userDao.findByIdIncludingRemoved(userId);
|
||||
|
|
|
|||
|
|
@ -8017,7 +8017,10 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
logger.trace("Verifying if the new account [{}] has access to the specified domain [{}].", newAccount, domain);
|
||||
_accountMgr.checkAccess(newAccount, domain);
|
||||
|
||||
Network newNetwork = ensureDestinationNetwork(cmd, vm, newAccount);
|
||||
Network newNetwork = null;
|
||||
if (!cmd.isSkipNetwork()) {
|
||||
newNetwork = ensureDestinationNetwork(cmd, vm, newAccount);
|
||||
}
|
||||
try {
|
||||
Transaction.execute(new TransactionCallbackNoReturn() {
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ public class IncrementalBackupServiceImpl extends ManagerBase implements Increme
|
|||
backup.setAccountId(vm.getAccountId());
|
||||
backup.setDomainId(vm.getDomainId());
|
||||
backup.setZoneId(vm.getDataCenterId());
|
||||
backup.setStatus(Backup.Status.ReadyForTransfer);
|
||||
backup.setStatus(Backup.Status.Queued);
|
||||
backup.setBackupOfferingId(vm.getBackupOfferingId());
|
||||
backup.setDate(new Date());
|
||||
|
||||
|
|
@ -236,6 +236,7 @@ public class IncrementalBackupServiceImpl extends ManagerBase implements Increme
|
|||
// todo: set it in the backend
|
||||
backup.setType("Incremental");
|
||||
}
|
||||
updateBackupState(backup, Backup.Status.ReadyForTransfer);
|
||||
return backup;
|
||||
}
|
||||
|
||||
|
|
@ -308,12 +309,12 @@ public class IncrementalBackupServiceImpl extends ManagerBase implements Increme
|
|||
// Delete old checkpoint if exists (POC: skip actual libvirt call)
|
||||
if (oldCheckpointId != null) {
|
||||
// todo: In production: send command to delete oldCheckpointId via virsh checkpoint-delete
|
||||
logger.debug("Would delete old checkpoint: " + oldCheckpointId);
|
||||
logger.debug("Would delete old checkpoint: {}", oldCheckpointId);
|
||||
}
|
||||
|
||||
// Delete backup session record
|
||||
backup.setStatus(Backup.Status.BackedUp);
|
||||
backupDao.update(backupId, backup);
|
||||
updateBackupState(backup, Backup.Status.BackedUp);
|
||||
backupDao.remove(backup.getId());
|
||||
|
||||
return backup;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue