Add list backups and list policy-VM mappings

This commit is contained in:
nvazquez 2018-06-01 14:01:41 -03:00
parent 979f3947b2
commit 5ed0cf5bdd
15 changed files with 347 additions and 52 deletions

View File

@ -32,6 +32,7 @@ import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.BackupResponse;
import org.apache.cloudstack.api.response.UserVmResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.cloudstack.backup.BackupManager;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.backup.Backup;
@ -44,7 +45,7 @@ import java.util.List;
responseObject = BackupResponse.class, since = "4.12.0",
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
public class ListBackupsCmd extends BaseBackupListCmd {
public static final String APINAME = "listBackups";
public static final String APINAME = "listVMBackups";
@Inject
BackupManager backupManager;
@ -60,6 +61,10 @@ public class ListBackupsCmd extends BaseBackupListCmd {
description = "id of the VM")
private Long virtualMachineId;
@Parameter(name = ApiConstants.ZONE_ID, type = BaseCmd.CommandType.UUID, entityType = ZoneResponse.class,
description = "The zone ID")
private Long zoneId;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@ -68,6 +73,10 @@ public class ListBackupsCmd extends BaseBackupListCmd {
return virtualMachineId;
}
public Long getZoneId() {
return zoneId;
}
@Override
public String getCommandName() {
return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
@ -82,14 +91,10 @@ public class ListBackupsCmd extends BaseBackupListCmd {
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
private void setupResponse(List<Backup> backups) {
}
@Override
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
try{
List<Backup> backups = backupManager.listBackups(virtualMachineId);
List<Backup> backups = backupManager.listVMBackups(zoneId, virtualMachineId);
setupResponseBackupList(backups);
} catch (Exception e) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());

View File

@ -33,13 +33,17 @@ public class BackupResponse extends BaseResponse {
@Param(description = "internal id of the backup")
private String id;
@SerializedName(ApiConstants.ZONE_ID)
@Param(description = "zone id")
private String zoneId;
@SerializedName(ApiConstants.ACCOUNT_ID)
@Param(description = "account id")
private String accountId;
@SerializedName(ApiConstants.USER_ID)
@Param(description = "user id")
private String userId;
@SerializedName(ApiConstants.EXTERNAL_ID)
@Param(description = "external backup id")
private String externalId;
@SerializedName(ApiConstants.NAME)
@Param(description = "backup name")
@ -81,12 +85,20 @@ public class BackupResponse extends BaseResponse {
this.accountId = accountId;
}
public String getUserId() {
return userId;
public String getZoneId() {
return zoneId;
}
public void setUserId(String userId) {
this.userId = userId;
public void setZoneId(String zoneId) {
this.zoneId = zoneId;
}
public String getExternalId() {
return externalId;
}
public void setExternalId(String externalId) {
this.externalId = externalId;
}
public String getName() {

View File

@ -29,12 +29,13 @@ public interface Backup extends InternalIdentity, Identity {
BackingUp, BackedUp, Failed, Queued, Restoring
}
Long getZoneId();
Long getAccountId();
Long getUserId();
String getExternalId();
String getName();
String getDescription();
Long getParentId();
Long getVMId();
Long getVmId();
List<Long> getVolumeIds();
Status getStatus();
Date getStartTime();

View File

@ -57,7 +57,7 @@ public interface BackupManager extends BackupService, Configurable, PluggableSer
/**
* List existing backups for a VM
*/
List<Backup> listBackups(Long vmId);
List<Backup> listVMBackups(Long zoneId, Long vmId);
/**
* List backup policies

View File

@ -66,4 +66,9 @@ public interface BackupProvider {
* Restore a volume from a backup
*/
VolumeTO restoreVolumeFromBackup(String volumeUuid, String backupUuid);
/**
* List VM Backups
*/
List<Backup> listVMBackups(Long zoneId, VirtualMachine vm);
}

View File

@ -0,0 +1,171 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.backup;
import java.util.Date;
import java.util.List;
public class BackupTO implements Backup {
private long id;
private String uuid;
private Long accountId;
private String name;
private String description;
private Long parentId;
private Long vmId;
private List<Long> volumeIds;
private Status status;
private Date startTime;
private Long zoneId;
private String externalId;
private String parentExternalId;
public BackupTO() {
}
public BackupTO(final Long zoneId, final Long accountId, final String externalId, final String name, final String description,
final String parentExternalId, final Long vmId, final List<Long> volumeIds, final Status status, final Date startTime) {
this.zoneId = zoneId;
this.accountId = accountId;
this.externalId = externalId;
this.name = name;
this.description = description;
this.parentExternalId = parentExternalId;
this.vmId = vmId;
this.volumeIds = volumeIds;
this.status = status;
this.startTime = startTime;
}
@Override
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
@Override
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
@Override
public Long getAccountId() {
return accountId;
}
public void setAccountId(Long accountId) {
this.accountId = accountId;
}
@Override
public Long getZoneId() {
return zoneId;
}
public void setZoneId(Long zoneId) {
this.zoneId = zoneId;
}
public String getParentExternalId() {
return parentExternalId;
}
public void setParentExternalId(String parentExternalId) {
this.parentExternalId = parentExternalId;
}
@Override
public String getExternalId() {
return externalId;
}
public void setExternalId(String externalId) {
this.externalId = externalId;
}
@Override
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@Override
public Long getParentId() {
return parentId;
}
public void setParentId(Long parentId) {
this.parentId = parentId;
}
public Long getVmId() {
return vmId;
}
public void setVmId(Long vmId) {
this.vmId = vmId;
}
@Override
public List<Long> getVolumeIds() {
return volumeIds;
}
public void setVolumeIds(List<Long> volumeIds) {
this.volumeIds = volumeIds;
}
@Override
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
@Override
public Date getStartTime() {
return startTime;
}
public void setStartTime(Date startTime) {
this.startTime = startTime;
}
}

View File

@ -26,6 +26,9 @@ import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@ -52,8 +55,11 @@ public class BackupVO implements Backup {
@Column(name = "account_id")
private long accountId;
@Column(name = "user_id")
private long userId;
@Column(name = "zone_id")
private Long zoneId;
@Column(name = "external_id")
private String externalId;
@Column(name = "name")
private String name;
@ -74,8 +80,10 @@ public class BackupVO implements Backup {
private Status status;
@Column(name = "start")
private Date start;
@Temporal(value = TemporalType.TIMESTAMP)
private Date startTime;
@Transient
private List<Long> volumeIds;
@Override
@ -89,13 +97,26 @@ public class BackupVO implements Backup {
}
@Override
public Long getAccountId() {
return accountId;
public Long getZoneId() {
return zoneId;
}
public void setZoneId(Long zoneId) {
this.zoneId = zoneId;
}
@Override
public Long getUserId() {
return userId;
public String getExternalId() {
return externalId;
}
public void setExternalId(String externalId) {
this.externalId = externalId;
}
@Override
public Long getAccountId() {
return accountId;
}
@Override
@ -114,7 +135,7 @@ public class BackupVO implements Backup {
}
@Override
public Long getVMId() {
public Long getVmId() {
return vmId;
}
@ -125,7 +146,7 @@ public class BackupVO implements Backup {
@Override
public Date getStartTime() {
return start;
return startTime;
}
public void setId(long id) {
@ -140,10 +161,6 @@ public class BackupVO implements Backup {
this.accountId = accountId;
}
public void setUserId(long userId) {
this.userId = userId;
}
public void setName(String name) {
this.name = name;
}
@ -164,8 +181,8 @@ public class BackupVO implements Backup {
this.status = status;
}
public void setStart(Date start) {
this.start = start;
public void setStartTime(Date start) {
this.startTime = start;
}
protected void convertVolumeStringToList() {

View File

@ -26,8 +26,8 @@ import java.util.List;
public interface BackupDao extends GenericDao<BackupVO, Long> {
List<Backup> listByVmId(Long vmId);
List<Backup> listByUserId(Long userId);
List<Backup> listByVmId(Long zoneId, Long vmId);
List<Backup> syncVMBackups(Long zoneId, Long vmId, List<Backup> externalBackups);
BackupResponse newBackupResponse(Backup backup);
}

View File

@ -17,21 +17,23 @@
package org.apache.cloudstack.backup.dao;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.VolumeDao;
import com.cloud.user.AccountVO;
import com.cloud.user.UserVO;
import com.cloud.user.dao.AccountDao;
import com.cloud.user.dao.UserDao;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.dao.VMInstanceDao;
import org.apache.cloudstack.api.response.BackupResponse;
import org.apache.cloudstack.backup.BackupTO;
import org.apache.cloudstack.backup.BackupVO;
import org.apache.cloudstack.backup.Backup;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
@ -44,7 +46,7 @@ public class BackupDaoImpl extends GenericDaoBase<BackupVO, Long> implements Bac
AccountDao accountDao;
@Inject
UserDao userDao;
DataCenterDao dataCenterDao;
@Inject
VMInstanceDao vmInstanceDao;
@ -60,35 +62,79 @@ public class BackupDaoImpl extends GenericDaoBase<BackupVO, Long> implements Bac
@PostConstruct
protected void init() {
backupSearch = createSearchBuilder();
backupSearch.and("vm_id", backupSearch.entity().getVMId(), SearchCriteria.Op.EQ);
backupSearch.and("user_id", backupSearch.entity().getUserId(), SearchCriteria.Op.EQ);
backupSearch.and("vm_id", backupSearch.entity().getVmId(), SearchCriteria.Op.EQ);
backupSearch.and("zone_id", backupSearch.entity().getZoneId(), SearchCriteria.Op.EQ);
backupSearch.and("external_id", backupSearch.entity().getExternalId(), SearchCriteria.Op.EQ);
backupSearch.done();
}
@Override
public List<Backup> listByVmId(Long vmId) {
public List<Backup> listByVmId(Long zoneId, Long vmId) {
SearchCriteria<BackupVO> sc = backupSearch.create();
sc.setParameters("vm_id", vmId);
sc.setParameters("zone_id", zoneId);
return new ArrayList<>(listBy(sc));
}
@Override
public List<Backup> listByUserId(Long userId) {
private Backup findByExternalId(Long zoneId, String externalId) {
SearchCriteria<BackupVO> sc = backupSearch.create();
sc.setParameters("user_id", userId);
return new ArrayList<>(listBy(sc));
sc.setParameters("external_id", externalId);
sc.setParameters("zone_id", zoneId);
return findOneBy(sc);
}
private BackupVO getBackupVO(Backup backup) {
BackupVO backupVO = new BackupVO();
backupVO.setZoneId(backup.getZoneId());
backupVO.setAccountId(backup.getAccountId());
backupVO.setExternalId(backup.getExternalId());
backupVO.setName(backup.getName());
backupVO.setDescription(backup.getDescription());
if (backup instanceof BackupTO) {
String parentExternalId = ((BackupTO) backup).getParentExternalId();
if (StringUtils.isNotBlank(parentExternalId)) {
Backup parent = findByExternalId(backup.getZoneId(), parentExternalId);
backupVO.setParentId(parent.getId());
}
}
backupVO.setVmId(backup.getVmId());
backupVO.setVolumeIds(backup.getVolumeIds());
backupVO.setStatus(backup.getStatus());
backupVO.setStartTime(backup.getStartTime());
return backupVO;
}
public void removeExistingVMBackups(Long zoneId, Long vmId) {
SearchCriteria<BackupVO> sc = backupSearch.create();
sc.setParameters("vm_id", vmId);
sc.setParameters("zone_id", zoneId);
expunge(sc);
}
@Override
public List<Backup> syncVMBackups(Long zoneId, Long vmId, List<Backup> externalBackups) {
List<Backup> existingVMBackups = listByVmId(zoneId, vmId);
if (CollectionUtils.isNotEmpty(existingVMBackups)) {
removeExistingVMBackups(zoneId, vmId);
}
for (Backup backup : externalBackups) {
BackupVO backupVO = getBackupVO(backup);
persist(backupVO);
}
return listByVmId(zoneId, vmId);
}
@Override
public BackupResponse newBackupResponse(Backup backup) {
AccountVO account = accountDao.findById(backup.getAccountId());
UserVO user = userDao.findById(backup.getUserId());
BackupVO parent = findById(backup.getParentId());
VMInstanceVO vm = vmInstanceDao.findById(backup.getVMId());
VMInstanceVO vm = vmInstanceDao.findById(backup.getVmId());
DataCenterVO zone = dataCenterDao.findById(backup.getZoneId());
BackupResponse backupResponse = new BackupResponse();
backupResponse.setZoneId(zone.getUuid());
backupResponse.setId(backup.getUuid());
backupResponse.setAccountId(account.getUuid());
backupResponse.setUserId(user.getUuid());
backupResponse.setExternalId(backup.getExternalId());
backupResponse.setName(backup.getName());
backupResponse.setDescription(backup.getDescription());
if (parent != null) {

View File

@ -118,6 +118,7 @@ public class BackupPolicyVMMapDaoImpl extends GenericDaoBase<BackupPolicyVMMapVO
response.setBackupPolicyId(policy.getUuid());
response.setVmId(vm.getUuid());
response.setZoneId(zone.getUuid());
response.setObjectName("backuppolicyvmmap");
return response;
}
}

View File

@ -63,7 +63,8 @@ CREATE TABLE IF NOT EXISTS `cloud`.`backup` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`uuid` varchar(40) NOT NULL,
`account_id` bigint(20) unsigned NOT NULL,
`user_id` bigint(20) unsigned NOT NULL,
`zone_id` bigint(20) unsigned NOT NULL,
`external_id` varchar(40) NOT NULL COMMENT 'backup ID on provider side',
`name` varchar(255) NOT NULL COMMENT 'backup name',
`description` varchar(255) COMMENT 'backup description',
`parent_id` bigint(20) unsigned COMMENT 'backup parent id',
@ -73,7 +74,7 @@ CREATE TABLE IF NOT EXISTS `cloud`.`backup` (
`start` timestamp,
PRIMARY KEY (`id`),
CONSTRAINT `fk_backup__account_id` FOREIGN KEY (`account_id`) REFERENCES `account` (`id`) ON DELETE CASCADE,
CONSTRAINT `fk_backup__user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE,
CONSTRAINT `fk_backup__zone_id` FOREIGN KEY (`zone_id`) REFERENCES `data_center` (`id`) ON DELETE CASCADE,
CONSTRAINT `fk_backup__parent_id` FOREIGN KEY (`parent_id`) REFERENCES `backup` (`id`) ON DELETE CASCADE,
CONSTRAINT `fk_backup__vm_id` FOREIGN KEY (`vm_id`) REFERENCES `vm_instance` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

View File

@ -24,6 +24,7 @@ import com.cloud.vm.VirtualMachine;
import org.apache.log4j.Logger;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
public class DummyBackupProvider extends AdapterBase implements BackupProvider {
@ -78,4 +79,19 @@ public class DummyBackupProvider extends AdapterBase implements BackupProvider {
return new VolumeTO(0L, Volume.Type.DATADISK, Storage.StoragePoolType.NetworkFilesystem, "pool-aaaa", "volumeTest",
"/test", "volTest", 1024L, "", "");
}
@Override
public List<Backup> listVMBackups(Long zoneId, VirtualMachine vm) {
s_logger.debug("Listing VM " + vm.getInstanceName() + "backups on the Dummy Backup Provider");
BackupTO backup1 = new BackupTO(zoneId, vm.getAccountId(),
"xxxx-xxxx", "Backup-1", "VM-" + vm.getInstanceName() + "-backup-1",
null, vm.getId(), null, Backup.Status.BackedUp, new Date());
BackupTO backup2 = new BackupTO(zoneId, vm.getAccountId(), "yyyy-yyyy",
"Backup-2", "VM-" + vm.getInstanceName() + "-backup-2",
backup1.getExternalId(), vm.getId(), null, Backup.Status.BackedUp, new Date());
return Arrays.asList(backup1, backup2);
}
}

View File

@ -89,16 +89,25 @@ public class VeeamBackupProvider extends AdapterBase implements BackupProvider,
@Override
public boolean isBackupPolicy(String uuid) {
//TODO
return true;
}
@Override
public boolean restoreVMFromBackup(String vmUuid, String backupUuid) {
//TODO
return false;
}
@Override
public VolumeTO restoreVolumeFromBackup(String volumeUuid, String backupUuid) {
//TODO
return null;
}
@Override
public List<Backup> listVMBackups(Long zoneId, VirtualMachine vm) {
//TODO
return null;
}

View File

@ -32,13 +32,18 @@ public class VeeamBackup implements Backup {
this.uid = uid;
}
@Override
public Long getZoneId() {
return null;
}
@Override
public Long getAccountId() {
return null;
}
@Override
public Long getUserId() {
public String getExternalId() {
return null;
}
@ -58,7 +63,7 @@ public class VeeamBackup implements Backup {
}
@Override
public Long getVMId() {
public Long getVmId() {
return null;
}

View File

@ -159,8 +159,14 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
}
@Override
public List<Backup> listBackups(Long vmId) {
return backupDao.listByVmId(vmId);
public List<Backup> listVMBackups(Long zoneId, Long vmId) {
BackupProvider backupProvider = getBackupProvider(zoneId);
VMInstanceVO vm = vmInstanceDao.findById(vmId);
if (vm == null) {
throw new CloudRuntimeException("VM " + vmId + " does not exist");
}
List<Backup> externalBackups = backupProvider.listVMBackups(zoneId, vm);
return backupDao.syncVMBackups(zoneId, vmId, externalBackups);
}
/**