API final additions and schema

This commit is contained in:
nvazquez 2018-05-17 13:09:21 -03:00
parent dc4bf22487
commit 9a692752c4
30 changed files with 1190 additions and 50 deletions

View File

@ -32,6 +32,7 @@ public class ApiConstants {
public static final String APPLIED = "applied";
public static final String LIST_LB_VMIPS = "lbvmips";
public static final String AVAILABLE = "available";
public static final String BACKUP_ID = "backupid";
public static final String BITS = "bits";
public static final String BOOTABLE = "bootable";
public static final String BIND_DN = "binddn";
@ -121,6 +122,7 @@ public class ApiConstants {
public static final String EXTRA_DHCP_OPTION_NAME = "extradhcpoptionname";
public static final String EXTRA_DHCP_OPTION_CODE = "extradhcpoptioncode";
public static final String EXTRA_DHCP_OPTION_VALUE = "extradhcpvalue";
public static final String EXTERNAL = "external";
public static final String FENCE = "fence";
public static final String FETCH_LATEST = "fetchlatest";
public static final String FIRSTNAME = "firstname";
@ -335,6 +337,7 @@ public class ApiConstants {
public static final String VNET = "vnet";
public static final String IS_VOLATILE = "isvolatile";
public static final String VOLUME_ID = "volumeid";
public static final String VOLUME_IDS = "volumeids";
public static final String ZONE_ID = "zoneid";
public static final String ZONE_NAME = "zonename";
public static final String NETWORK_TYPE = "networktype";

View File

@ -18,16 +18,18 @@
package org.apache.cloudstack.api;
import org.apache.cloudstack.api.response.BackupPolicyResponse;
import org.apache.cloudstack.api.response.BackupResponse;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.framework.backup.Backup;
import org.apache.cloudstack.framework.backup.BackupPolicy;
import java.util.ArrayList;
import java.util.List;
public abstract class BaseBackupPolicyListCmd extends BaseListCmd {
public abstract class BaseBackupListCmd extends BaseListCmd {
protected void setupResponse(final List<BackupPolicy> policies) {
protected void setupResponseBackupPolicyList(final List<BackupPolicy> policies) {
final ListResponse<BackupPolicyResponse> response = new ListResponse<>();
final List<BackupPolicyResponse> responses = new ArrayList<>();
for (final BackupPolicy policy : policies) {
@ -35,7 +37,7 @@ public abstract class BaseBackupPolicyListCmd extends BaseListCmd {
continue;
}
final BackupPolicyResponse backupPolicyResponse = new BackupPolicyResponse();
if (!policy.isExternal()) {
if (!policy.isImported()) {
backupPolicyResponse.setId(policy.getUuid());
}
backupPolicyResponse.setName(policy.getName());
@ -48,6 +50,21 @@ public abstract class BaseBackupPolicyListCmd extends BaseListCmd {
setResponseObject(response);
}
protected void setupResponseBackupList(final List<Backup> backups) {
final ListResponse<BackupResponse> response = new ListResponse<>();
final List<BackupResponse> responses = new ArrayList<>();
for (Backup backup : backups) {
if (backup == null) {
continue;
}
BackupResponse backupResponse = _responseGenerator.createBackupResponse(backup);
responses.add(backupResponse);
}
response.setResponses(responses);
response.setResponseName(getCommandName());
setResponseObject(response);
}
@Override
public long getEntityOwnerId() {
return CallContext.current().getCallingAccount().getId();

View File

@ -34,6 +34,7 @@ import org.apache.cloudstack.api.response.AsyncJobResponse;
import org.apache.cloudstack.api.response.AutoScalePolicyResponse;
import org.apache.cloudstack.api.response.AutoScaleVmGroupResponse;
import org.apache.cloudstack.api.response.AutoScaleVmProfileResponse;
import org.apache.cloudstack.api.response.BackupResponse;
import org.apache.cloudstack.api.response.CapacityResponse;
import org.apache.cloudstack.api.response.ClusterResponse;
import org.apache.cloudstack.api.response.ConditionResponse;
@ -117,6 +118,7 @@ import org.apache.cloudstack.api.response.VpcResponse;
import org.apache.cloudstack.api.response.VpnUsersResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.cloudstack.config.Configuration;
import org.apache.cloudstack.framework.backup.Backup;
import org.apache.cloudstack.network.lb.ApplicationLoadBalancerRule;
import org.apache.cloudstack.region.PortableIp;
import org.apache.cloudstack.region.PortableIpRange;
@ -462,4 +464,6 @@ public interface ResponseGenerator {
ListResponse<UpgradeRouterTemplateResponse> createUpgradeRouterTemplateResponse(List<Long> jobIds);
SSHKeyPairResponse createSSHKeyPairResponse(SSHKeyPair sshkeyPair, boolean privatekey);
BackupResponse createBackupResponse(Backup backup);
}

View File

@ -111,7 +111,7 @@ public class AssignBackupPolicyCmd extends BaseCmd {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to assign VM to backup policy");
}
} catch (Exception e) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.getMessage());
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
}
}
}

View File

@ -21,10 +21,14 @@ import java.util.List;
import javax.inject.Inject;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseBackupPolicyListCmd;
import org.apache.cloudstack.api.BaseBackupListCmd;
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.BackupPolicyResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.cloudstack.backup.BackupManager;
import org.apache.cloudstack.framework.backup.BackupPolicy;
@ -36,13 +40,37 @@ import com.cloud.utils.exception.CloudRuntimeException;
@APICommand(name = ListBackupPoliciesCmd.APINAME,
description = "Lists backup policies",
responseObject = BackupPolicyResponse.class, since = "4.12.0")
public class ListBackupPoliciesCmd extends BaseBackupPolicyListCmd {
public class ListBackupPoliciesCmd extends BaseBackupListCmd {
public static final String APINAME = "listBackupPolicies";
@Inject
BackupManager backupManager;
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name = ApiConstants.ZONE_ID, type = BaseCmd.CommandType.UUID, entityType = ZoneResponse.class,
description = "The zone ID")
private Long zoneId;
@Parameter(name = ApiConstants.EXTERNAL, type = CommandType.BOOLEAN,
description = "True if list external backup policies")
private Boolean external;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getZoneId() {
return zoneId;
}
public Boolean isExternal() {
return external;
}
@Override
public String getCommandName() {
return APINAME.toLowerCase() + RESPONSE_SUFFIX;
@ -55,8 +83,8 @@ public class ListBackupPoliciesCmd extends BaseBackupPolicyListCmd {
@Override
public void execute() throws ResourceUnavailableException, ServerApiException, ConcurrentOperationException {
try {
List<BackupPolicy> backupPolicies = backupManager.listBackupPolicies();
setupResponse(backupPolicies);
List<BackupPolicy> backupPolicies = backupManager.listBackupPolicies(zoneId, external);
setupResponseBackupPolicyList(backupPolicies);
} catch (InvalidParameterValueException e) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.getMessage());
} catch (CloudRuntimeException e) {

View File

@ -17,5 +17,82 @@
package org.apache.cloudstack.api.command.user.backup;
public class ListBackupsCmd {
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.NetworkRuleConflictException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseBackupListCmd;
import org.apache.cloudstack.api.BaseCmd;
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.backup.BackupManager;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.framework.backup.Backup;
import javax.inject.Inject;
import java.util.List;
@APICommand(name = ListBackupsCmd.APINAME,
description = "Lists backups",
responseObject = BackupResponse.class, since = "4.12.0")
public class ListBackupsCmd extends BaseBackupListCmd {
public static final String APINAME = "listBackups";
@Inject
BackupManager backupManager;
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID,
type = CommandType.UUID,
entityType = UserVmResponse.class,
required = true,
description = "id of the VM")
private Long virtualMachineId;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getVirtualMachineId() {
return virtualMachineId;
}
@Override
public String getCommandName() {
return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
}
@Override
public long getEntityOwnerId() {
return CallContext.current().getCallingAccount().getId();
}
/////////////////////////////////////////////////////
/////////////// 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);
setupResponseBackupList(backups);
} catch (Exception e) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
}
}
}

View File

@ -17,5 +17,101 @@
package org.apache.cloudstack.api.command.user.backup;
public class RestoreBackupCmd {
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.NetworkRuleConflictException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.utils.exception.CloudRuntimeException;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.SuccessResponse;
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 javax.inject.Inject;
@APICommand(name = RestoreBackupCmd.APINAME,
description = "Restore backup",
responseObject = SuccessResponse.class, since = "4.12.0")
public class RestoreBackupCmd extends BaseCmd {
public static final String APINAME = "restoreBackup";
@Inject
BackupManager backupManager;
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID,
type = CommandType.UUID,
entityType = UserVmResponse.class,
required = true,
description = "id of the VM")
private Long virtualMachineId;
@Parameter(name = ApiConstants.BACKUP_ID,
type = CommandType.STRING,
required = true,
description = "id of the backup")
private String backupId;
@Parameter(name = ApiConstants.ZONE_ID, type = BaseCmd.CommandType.UUID, entityType = ZoneResponse.class,
description = "The zone ID")
private Long zoneId;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getVirtualMachineId() {
return virtualMachineId;
}
public String getBackupId() {
return backupId;
}
public Long getZoneId() {
return zoneId;
}
@Override
public String getCommandName() {
return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
}
@Override
public long getEntityOwnerId() {
return CallContext.current().getCallingAccount().getId();
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
try {
boolean result = backupManager.restoreBackup(virtualMachineId, backupId, zoneId);
if (result) {
SuccessResponse response = new SuccessResponse(getCommandName());
response.setResponseName(getCommandName());
setResponseObject(response);
} else {
throw new CloudRuntimeException("Error while restoring VM from backup");
}
} catch (Exception e) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
}
}
}

View File

@ -15,40 +15,35 @@
// specific language governing permissions and limitations
// under the License.
package org.apache.cloudstack.api.command.admin.backup;
package org.apache.cloudstack.api.command.user.backup;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.NetworkRuleConflictException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.utils.exception.CloudRuntimeException;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseBackupPolicyListCmd;
import org.apache.cloudstack.api.BaseCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.command.user.backup.AssignBackupPolicyCmd;
import org.apache.cloudstack.api.response.BackupPolicyResponse;
import org.apache.cloudstack.api.response.SuccessResponse;
import org.apache.cloudstack.api.response.UserVmResponse;
import org.apache.cloudstack.api.response.VolumeResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.cloudstack.backup.BackupManager;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.framework.backup.BackupPolicy;
import javax.inject.Inject;
import java.util.List;
@APICommand(name = ListBackupProviderPoliciesCmd.APINAME,
description = "Lists backup policies existing on the Backup and Recovery provider side",
responseObject = BackupPolicyResponse.class, since = "4.12.0",
authorized = {RoleType.Admin})
public class ListBackupProviderPoliciesCmd extends BaseBackupPolicyListCmd {
@APICommand(name = RestoreBackupVolumeCmd.APINAME,
description = "Restore and attach a backed up volume to VM",
responseObject = SuccessResponse.class, since = "4.12.0")
public class RestoreBackupVolumeCmd extends BaseCmd {
public static final String APINAME = "listBackupProviderPolicies";
public static final String APINAME = "restoreBackupVolume";
@Inject
BackupManager backupManager;
@ -57,6 +52,26 @@ public class ListBackupProviderPoliciesCmd extends BaseBackupPolicyListCmd {
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name = ApiConstants.VOLUME_ID,
type = CommandType.UUID,
entityType = VolumeResponse.class,
required = true,
description = "id of the volume")
private Long volumeId;
@Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID,
type = CommandType.UUID,
entityType = UserVmResponse.class,
required = true,
description = "id of the VM")
private Long virtualMachineId;
@Parameter(name = ApiConstants.BACKUP_ID,
type = CommandType.STRING,
required = true,
description = "id of the backup")
private String backupId;
@Parameter(name = ApiConstants.ZONE_ID, type = BaseCmd.CommandType.UUID, entityType = ZoneResponse.class,
description = "The zone ID")
private Long zoneId;
@ -65,13 +80,25 @@ public class ListBackupProviderPoliciesCmd extends BaseBackupPolicyListCmd {
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getVolumeId() {
return volumeId;
}
public Long getVirtualMachineId() {
return virtualMachineId;
}
public String getBackupId() {
return backupId;
}
public Long getZoneId() {
return zoneId;
}
@Override
public String getCommandName() {
return AssignBackupPolicyCmd.APINAME + RESPONSE_SUFFIX;
return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX;
}
@Override
@ -86,11 +113,15 @@ public class ListBackupProviderPoliciesCmd extends BaseBackupPolicyListCmd {
@Override
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
try {
List<BackupPolicy> policies = backupManager.listBackupProviderPolicies(zoneId);
setupResponse(policies);
} catch (InvalidParameterValueException e) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.getMessage());
} catch (CloudRuntimeException e) {
boolean result = backupManager.restoreBackupVolume(volumeId, virtualMachineId, backupId, zoneId);
if (result) {
SuccessResponse response = new SuccessResponse(getCommandName());
response.setResponseName(getCommandName());
setResponseObject(response);
} else {
throw new CloudRuntimeException("Error restoring volume and attaching to VM");
}
} catch (Exception e) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
}
}

View File

@ -0,0 +1,122 @@
package org.apache.cloudstack.api.response;
import com.cloud.serializer.Param;
import com.google.gson.annotations.SerializedName;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseResponse;
import org.apache.cloudstack.api.EntityReference;
import org.apache.cloudstack.framework.backup.Backup;
import java.util.List;
@EntityReference(value = Backup.class)
public class BackupResponse extends BaseResponse {
@SerializedName(ApiConstants.ID)
@Param(description = "internal id of the backup")
private String id;
@SerializedName(ApiConstants.ACCOUNT_ID)
@Param(description = "account id")
private String accountId;
@SerializedName(ApiConstants.USER_ID)
@Param(description = "user id")
private String userId;
@SerializedName(ApiConstants.NAME)
@Param(description = "backup name")
private String name;
@SerializedName(ApiConstants.DESCRIPTION)
@Param(description = "backup description")
private String description;
@SerializedName(ApiConstants.PARENT_ID)
@Param(description = "backup parent id")
private String parentId;
@SerializedName(ApiConstants.VIRTUAL_MACHINE_ID)
@Param(description = "backup vm id")
private String vmId;
@SerializedName(ApiConstants.VOLUME_IDS)
@Param(description = "backup volume ids")
private List<String> volumeIds;
@SerializedName(ApiConstants.STATUS)
@Param(description = "backup volume ids")
private Backup.Status status;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getAccountId() {
return accountId;
}
public void setAccountId(String accountId) {
this.accountId = accountId;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getParentId() {
return parentId;
}
public void setParentId(String parentId) {
this.parentId = parentId;
}
public String getVmId() {
return vmId;
}
public void setVmId(String vmId) {
this.vmId = vmId;
}
public Backup.Status getStatus() {
return status;
}
public void setStatus(Backup.Status status) {
this.status = status;
}
public List<String> getVolumeIds() {
return volumeIds;
}
public void setVolumeIds(List<String> volumeIds) {
this.volumeIds = volumeIds;
}
}

View File

@ -20,6 +20,7 @@ package org.apache.cloudstack.backup;
import java.util.List;
import org.apache.cloudstack.api.response.BackupPolicyResponse;
import org.apache.cloudstack.framework.backup.Backup;
import org.apache.cloudstack.framework.backup.BackupPolicy;
import org.apache.cloudstack.framework.backup.BackupService;
import org.apache.cloudstack.framework.config.ConfigKey;
@ -59,14 +60,24 @@ public interface BackupManager extends BackupService, Configurable, PluggableSer
boolean assignVMToBackupPolicy(String policyUuid, Long virtualMachineId, Long zoneId);
/**
* List existing backup policies
* List existing backups for a VM
*/
List<BackupPolicy> listBackupPolicies();
List<Backup> listBackups(Long vmId);
/**
* List backup policies existing on the backup provider
* List backup policies
* @param zoneId zone id
* @param external if true, only external backup policies are listed
*/
List<BackupPolicy> listBackupProviderPolicies(Long zoneId);
List<BackupPolicy> listBackupPolicies(Long zoneId, Boolean external);
/**
* Restore a full backed up VM
*/
boolean restoreBackup(Long vmId, String backupId, Long zoneId);
//TODO
boolean restoreBackupVolume(Long volumeId, Long vmId, String backupId, Long zoneId);
/**
* Deletes a backup policy

View File

@ -29,7 +29,7 @@ public class BackupPolicyTO implements BackupPolicy {
private long id;
private String name;
private String policyUuid;
private boolean external = true;
private boolean imported = false;
public BackupPolicyTO() {
this.uuid = UUID.randomUUID().toString();
@ -61,7 +61,7 @@ public class BackupPolicyTO implements BackupPolicy {
}
@Override
public boolean isExternal() {
return external;
public boolean isImported() {
return imported;
}
}

View File

@ -0,0 +1,77 @@
/*
* 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 org.apache.cloudstack.api.InternalIdentity;
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 = "backup_policy_vm_map")
public class BackupPolicyVMMapVO implements InternalIdentity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private long id;
@Column(name = "policy_id")
private long policyId;
@Column(name = "vm_id")
private long vmId;
public BackupPolicyVMMapVO() {
}
public BackupPolicyVMMapVO(long policyId, long vmId) {
this.policyId = policyId;
this.vmId = vmId;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public long getPolicyId() {
return policyId;
}
public void setPolicyId(long policyId) {
this.policyId = policyId;
}
public long getVmId() {
return vmId;
}
public void setVmId(long vmId) {
this.vmId = vmId;
}
}

View File

@ -44,6 +44,7 @@ public class BackupPolicyVO implements BackupPolicy {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private long id;
@Column(name = "uuid")
@ -55,6 +56,9 @@ public class BackupPolicyVO implements BackupPolicy {
@Column(name = "policy_uuid")
private String policyUuid;
@Column(name = "imported")
private boolean imported = true;
public String getUuid() {
return uuid;
}
@ -87,7 +91,8 @@ public class BackupPolicyVO implements BackupPolicy {
this.policyUuid = policyUuid;
}
public boolean isExternal() {
return false;
@Override
public boolean isImported() {
return imported;
}
}

View File

@ -0,0 +1,214 @@
//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
//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 org.apache.cloudstack.framework.backup.Backup;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.StringJoiner;
import java.util.UUID;
@Entity
@Table(name = "backup")
public class BackupVO implements Backup {
public BackupVO() {
this.uuid = UUID.randomUUID().toString();
volumeIds = new ArrayList<>();
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private long id;
@Column(name = "uuid")
private String uuid;
@Column(name = "account_id")
private long accountId;
@Column(name = "user_id")
private long userId;
@Column(name = "name")
private String name;
@Column(name = "description")
private String description;
@Column(name = "parent_id")
private Long parentId;
@Column(name = "vm_id")
private long vmId;
@Column(name = "volumes")
private String volumes;
@Column(name = "status")
private Status status;
@Column(name = "start")
private Date start;
private List<Long> volumeIds;
@Override
public Long getId() {
return id;
}
@Override
public String getUuid() {
return uuid;
}
@Override
public Long getAccountId() {
return accountId;
}
@Override
public Long getUserId() {
return userId;
}
@Override
public String getName() {
return name;
}
@Override
public String getDescription() {
return description;
}
@Override
public Long getParentId() {
return parentId;
}
@Override
public Long getVMId() {
return vmId;
}
@Override
public Status getStatus() {
return status;
}
@Override
public Date getStartTime() {
return start;
}
public void setId(long id) {
this.id = id;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
public void setAccountId(long accountId) {
this.accountId = accountId;
}
public void setUserId(long userId) {
this.userId = userId;
}
public void setName(String name) {
this.name = name;
}
public void setDescription(String description) {
this.description = description;
}
public void setParentId(Long parentId) {
this.parentId = parentId;
}
public void setVmId(long vmId) {
this.vmId = vmId;
}
public void setStatus(Status status) {
this.status = status;
}
public void setStart(Date start) {
this.start = start;
}
protected void convertVolumeStringToList() {
volumeIds = new ArrayList<>();
if (StringUtils.isNotBlank(volumes)) {
String[] strIds = StringUtils.substringBetween(volumes,"[", "]").split(",");
for (String strId: strIds) {
volumeIds.add(Long.valueOf(strId));
}
}
}
@Override
public List<Long> getVolumeIds() {
convertVolumeStringToList();
return volumeIds;
}
public void setVolumeIds(List<Long> volumes) {
if (CollectionUtils.isEmpty(volumes)) {
this.volumeIds = new ArrayList<>();
} else {
this.volumeIds = new ArrayList<>(volumes);
}
convertVolumeIdsToString();
}
private void convertVolumeIdsToString() {
StringJoiner stringJoiner = new StringJoiner(",", "[", "]");
if (CollectionUtils.isNotEmpty(this.volumeIds)) {
for (Long volId : this.volumeIds) {
stringJoiner.add(String.valueOf(volId));
}
}
this.volumes = stringJoiner.toString();
}
protected String getVolumes() {
return volumes;
}
protected void setVolumes(String volumes) {
this.volumes = volumes;
}
}

View File

@ -0,0 +1,33 @@
// 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.dao;
import com.cloud.utils.db.GenericDao;
import org.apache.cloudstack.api.response.BackupResponse;
import org.apache.cloudstack.backup.BackupVO;
import org.apache.cloudstack.framework.backup.Backup;
import java.util.List;
public interface BackupDao extends GenericDao<BackupVO, Long> {
List<Backup> listByVmId(Long vmId);
List<Backup> listByUserId(Long userId);
BackupResponse newBackupResponse(Backup backup);
}

View File

@ -0,0 +1,110 @@
// 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.dao;
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.BackupVO;
import org.apache.cloudstack.framework.backup.Backup;
import org.apache.commons.collections.CollectionUtils;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.List;
public class BackupDaoImpl extends GenericDaoBase<BackupVO, Long> implements BackupDao {
@Inject
AccountDao accountDao;
@Inject
UserDao userDao;
@Inject
VMInstanceDao vmInstanceDao;
@Inject
VolumeDao volumeDao;
private SearchBuilder<BackupVO> backupSearch;
public BackupDaoImpl() {
}
@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.done();
}
@Override
public List<Backup> listByVmId(Long vmId) {
SearchCriteria<BackupVO> sc = backupSearch.create();
sc.setParameters("vm_id", vmId);
return new ArrayList<>(listBy(sc));
}
@Override
public List<Backup> listByUserId(Long userId) {
SearchCriteria<BackupVO> sc = backupSearch.create();
sc.setParameters("user_id", userId);
return new ArrayList<>(listBy(sc));
}
@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());
BackupResponse backupResponse = new BackupResponse();
backupResponse.setId(backup.getUuid());
backupResponse.setAccountId(account.getUuid());
backupResponse.setUserId(user.getUuid());
backupResponse.setName(backup.getName());
backupResponse.setDescription(backup.getDescription());
if (parent != null) {
backupResponse.setParentId(parent.getUuid());
}
backupResponse.setVmId(vm.getUuid());
if (CollectionUtils.isNotEmpty(backup.getVolumeIds())) {
List<String> volIds = new ArrayList<>();
for (Long volId : backup.getVolumeIds()) {
VolumeVO volume = volumeDao.findById(volId);
volIds.add(volume.getUuid());
}
backupResponse.setVolumeIds(volIds);
}
backupResponse.setStatus(backup.getStatus());
backupResponse.setObjectName("backup");
return backupResponse;
}
}

View File

@ -28,7 +28,7 @@ import com.cloud.utils.db.SearchBuilder;
@Component
public class BackupPolicyDaoImpl extends GenericDaoBase<BackupPolicyVO, Long> implements BackupPolicyDao {
protected SearchBuilder<BackupPolicyVO> backupPoliciesSearch;
private SearchBuilder<BackupPolicyVO> backupPoliciesSearch;
public BackupPolicyDaoImpl() {
}

View File

@ -0,0 +1,31 @@
/*
* 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.dao;
import com.cloud.utils.db.GenericDao;
import org.apache.cloudstack.backup.BackupPolicyVMMapVO;
import java.util.List;
public interface BackupPolicyVMMapDao extends GenericDao<BackupPolicyVMMapVO, Long> {
BackupPolicyVMMapVO findByVMId(long vmId);
List<BackupPolicyVMMapVO> listByPolicyId(long policyId);
}

View File

@ -0,0 +1,69 @@
/*
* 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.dao;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.exception.CloudRuntimeException;
import org.apache.cloudstack.backup.BackupPolicyVMMapVO;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.List;
@Component
public class BackupPolicyVMMapDaoImpl extends GenericDaoBase<BackupPolicyVMMapVO, Long> implements BackupPolicyVMMapDao {
private SearchBuilder<BackupPolicyVMMapVO> mapSearch;
public BackupPolicyVMMapDaoImpl() {
}
@PostConstruct
protected void init() {
mapSearch = createSearchBuilder();
mapSearch.and("vm_id", mapSearch.entity().getVmId(), SearchCriteria.Op.EQ);
mapSearch.and("policy_id", mapSearch.entity().getPolicyId(), SearchCriteria.Op.EQ);
mapSearch.done();
}
@Override
public BackupPolicyVMMapVO findByVMId(long vmId) {
SearchCriteria<BackupPolicyVMMapVO> sc = mapSearch.create();
sc.setParameters("vm_id", vmId);
List<BackupPolicyVMMapVO> maps = listBy(sc);
if (CollectionUtils.isNotEmpty(maps)) {
if (maps.size() > 1) {
throw new CloudRuntimeException("Error: Vm " + vmId + " is assigned to multiple policies");
}
return maps.get(0);
}
return null;
}
@Override
public List<BackupPolicyVMMapVO> listByPolicyId(long policyId) {
SearchCriteria<BackupPolicyVMMapVO> sc = mapSearch.create();
sc.setParameters("policy_id", policyId);
return listBy(sc);
}
}

View File

@ -356,5 +356,7 @@
<bean id="outOfBandManagementDaoImpl" class="org.apache.cloudstack.outofbandmanagement.dao.OutOfBandManagementDaoImpl" />
<bean id="GuestOsDetailsDaoImpl" class="org.apache.cloudstack.resourcedetail.dao.GuestOsDetailsDaoImpl" />
<bean id="annotationDaoImpl" class="org.apache.cloudstack.annotation.dao.AnnotationDaoImpl" />
<bean id="brPoliciesDaoImpl" class="org.apache.cloudstack.backup.dao.BackupPolicyDaoImpl" />
<bean id="backupPolicyDaoImpl" class="org.apache.cloudstack.backup.dao.BackupPolicyDaoImpl" />
<bean id="backupPolicyVMMapDaoImpl" class="org.apache.cloudstack.backup.dao.BackupPolicyVMMapDaoImpl" />
<bean id="backupDaoImpl" class="org.apache.cloudstack.backup.dao.BackupDaoImpl" />
</beans>

View File

@ -41,6 +41,35 @@ CREATE TABLE IF NOT EXISTS `cloud`.`backup_policy` (
`uuid` varchar(40) NOT NULL,
`name` varchar(255) NOT NULL COMMENT 'backup policy name',
`policy_uuid` varchar(40) NOT NULL COMMENT 'backup policy ID on provider side',
`imported` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT 'true if policy has been imported from the backup provider',
PRIMARY KEY (`id`),
UNIQUE KEY `uuid` (`uuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `cloud`.`backup_policy_vm_map` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`policy_id` bigint(20) unsigned NOT NULL,
`vm_id` bigint(20) unsigned NOT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `fk_backup_policy_vm_map__policy_id` FOREIGN KEY (`policy_id`) REFERENCES `backup_policy` (`id`) ON DELETE CASCADE,
CONSTRAINT `fk_backup_policy_vm_map__vm_id` FOREIGN KEY (`vm_id`) REFERENCES `vm_instance` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
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,
`name` varchar(255) NOT NULL COMMENT 'backup name',
`description` varchar(255) COMMENT 'backup description',
`parent_id` bigint(20) unsigned COMMENT 'backup parent id',
`vm_id` bigint(20) unsigned NOT NULL,
`volumes` varchar(100),
`status` varchar(20) NOT NULL,
`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__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

@ -0,0 +1,61 @@
//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
//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 org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@RunWith(JUnit4.class)
public class BackupVOTest {
private BackupVO vo = new BackupVO();
private final List<Long> ids = Arrays.asList(1L, 2L, 3L, 4L);
@Test
public void testVolumeIdsNotEmptyList() {
vo.setVolumeIds(ids);
Assert.assertEquals("[1,2,3,4]", vo.getVolumes());
Assert.assertEquals(ids, vo.getVolumeIds());
}
@Test
public void testVolumeIdsEmptyList() {
vo.setVolumeIds(new ArrayList<>());
Assert.assertEquals("[]", vo.getVolumes());
Assert.assertEquals(new ArrayList<>(), vo.getVolumeIds());
}
@Test
public void testVolumeIdsUnsetVolumeIds() {
Assert.assertEquals(null, vo.getVolumes());
Assert.assertEquals(new ArrayList<>(), vo.getVolumeIds());
}
@Test
public void testDecodeVolumesString() {
vo.setVolumes("[1,2,3,4]");
Assert.assertEquals(ids, vo.getVolumeIds());
}
}

View File

@ -0,0 +1,40 @@
//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
//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.framework.backup;
import java.util.Date;
import java.util.List;
public interface Backup {
enum Status {
BackingUp, BackedUp, Failed, Queued, Restoring
}
Long getId();
String getUuid();
Long getAccountId();
Long getUserId();
String getName();
String getDescription();
Long getParentId();
Long getVMId();
List<Long> getVolumeIds();
Status getStatus();
Date getStartTime();
}

View File

@ -22,6 +22,6 @@ public interface BackupPolicy {
String getUuid();
String getPolicyUuid();
String getName();
boolean isExternal();
boolean isImported();
}

View File

@ -48,4 +48,9 @@ public interface BackupProvider {
* True if policy with id uuid exists on the backup provider
*/
boolean isBackupPolicy(String uuid);
/**
* Restore VM from backup
*/
boolean restoreVMFromBackup(String vmUuid, String backupUuid);
}

View File

@ -58,4 +58,10 @@ public class DummyBackupProvider extends AdapterBase implements BackupProvider {
s_logger.debug("Checking if backup policy exists on the Dummy Backup Provider");
return true;
}
@Override
public boolean restoreVMFromBackup(String vmUuid, String backupUuid) {
s_logger.debug("Restoring vm " + vmUuid + "from backup " + backupUuid + " on the Dummy Backup Provider");
return true;
}
}

View File

@ -85,6 +85,11 @@ public class VeeamBackupProvider extends AdapterBase implements BackupProvider,
return false;
}
@Override
public boolean restoreVMFromBackup(String vmUuid, String backupUuid) {
return false;
}
@Override
public String getConfigComponentName() {
return BackupService.class.getSimpleName();

View File

@ -39,6 +39,7 @@ import org.apache.cloudstack.api.ApiConstants.VMDetails;
import org.apache.cloudstack.api.ResponseObject.ResponseView;
import org.apache.cloudstack.api.response.AccountResponse;
import org.apache.cloudstack.api.response.AsyncJobResponse;
import org.apache.cloudstack.api.response.BackupResponse;
import org.apache.cloudstack.api.response.DiskOfferingResponse;
import org.apache.cloudstack.api.response.DomainResponse;
import org.apache.cloudstack.api.response.DomainRouterResponse;
@ -61,9 +62,11 @@ import org.apache.cloudstack.api.response.UserResponse;
import org.apache.cloudstack.api.response.UserVmResponse;
import org.apache.cloudstack.api.response.VolumeResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.cloudstack.backup.dao.BackupDao;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
import org.apache.cloudstack.framework.backup.Backup;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.cloudstack.framework.jobs.AsyncJob;
import org.apache.cloudstack.framework.jobs.AsyncJobManager;
@ -434,6 +437,7 @@ public class ApiDBUtils {
static ResourceMetaDataService s_resourceDetailsService;
static HostGpuGroupsDao s_hostGpuGroupsDao;
static VGPUTypesDao s_vgpuTypesDao;
static BackupDao s_backupDao;
@Inject
private ManagementServer ms;
@ -666,6 +670,8 @@ public class ApiDBUtils {
private HostGpuGroupsDao hostGpuGroupsDao;
@Inject
private VGPUTypesDao vgpuTypesDao;
@Inject
private BackupDao backupDao;
@PostConstruct
void init() {
@ -785,6 +791,7 @@ public class ApiDBUtils {
s_resourceDetailsService = resourceDetailsService;
s_hostGpuGroupsDao = hostGpuGroupsDao;
s_vgpuTypesDao = vgpuTypesDao;
s_backupDao = backupDao;
}
// ///////////////////////////////////////////////////////////
@ -2000,4 +2007,8 @@ public class ApiDBUtils {
public static List<ResourceTagJoinVO> listResourceTagViewByResourceUUID(String resourceUUID, ResourceObjectType resourceType) {
return s_tagJoinDao.listBy(resourceUUID, resourceType);
}
public static BackupResponse newBackupResponse(Backup backup) {
return s_backupDao.newBackupResponse(backup);
}
}

View File

@ -199,6 +199,7 @@ import org.apache.cloudstack.api.response.AsyncJobResponse;
import org.apache.cloudstack.api.response.AutoScalePolicyResponse;
import org.apache.cloudstack.api.response.AutoScaleVmGroupResponse;
import org.apache.cloudstack.api.response.AutoScaleVmProfileResponse;
import org.apache.cloudstack.api.response.BackupResponse;
import org.apache.cloudstack.api.response.CapabilityResponse;
import org.apache.cloudstack.api.response.CapacityResponse;
import org.apache.cloudstack.api.response.ClusterResponse;
@ -296,6 +297,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreCapabilities;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotDataFactory;
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
import org.apache.cloudstack.framework.backup.Backup;
import org.apache.cloudstack.framework.jobs.AsyncJob;
import org.apache.cloudstack.framework.jobs.AsyncJobManager;
import org.apache.cloudstack.network.lb.ApplicationLoadBalancerRule;
@ -3964,4 +3966,9 @@ public class ApiResponseHelper implements ResponseGenerator {
response.setDomainName(domain.getName());
return response;
}
@Override
public BackupResponse createBackupResponse(Backup backup) {
return ApiDBUtils.newBackupResponse(backup);
}
}

View File

@ -27,17 +27,23 @@ import javax.naming.ConfigurationException;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.dao.VMInstanceDao;
import org.apache.cloudstack.api.command.admin.backup.DeleteBackupPolicyCmd;
import org.apache.cloudstack.api.command.admin.backup.ListBackupProviderPoliciesCmd;
import org.apache.cloudstack.api.command.user.backup.AssignBackupPolicyCmd;
import org.apache.cloudstack.api.command.admin.backup.CreateBackupPolicyCmd;
import org.apache.cloudstack.api.command.user.backup.ListBackupPoliciesCmd;
import org.apache.cloudstack.api.command.admin.backup.ListBackupProvidersCmd;
import org.apache.cloudstack.api.command.user.backup.ListBackupsCmd;
import org.apache.cloudstack.api.command.user.backup.RestoreBackupCmd;
import org.apache.cloudstack.api.command.user.backup.RestoreBackupVolumeCmd;
import org.apache.cloudstack.api.response.BackupPolicyResponse;
import org.apache.cloudstack.backup.dao.BackupDao;
import org.apache.cloudstack.backup.dao.BackupPolicyDao;
import org.apache.cloudstack.backup.dao.BackupPolicyVMMapDao;
import org.apache.cloudstack.framework.backup.Backup;
import org.apache.cloudstack.framework.backup.BackupPolicy;
import org.apache.cloudstack.framework.backup.BackupProvider;
import org.apache.cloudstack.framework.backup.BackupService;
import org.apache.cloudstack.framework.config.ConfigKey;
import org.apache.commons.lang.BooleanUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
@ -58,6 +64,12 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
@Inject
DataCenterDao dataCenterDao;
@Inject
BackupPolicyVMMapDao backupPolicyVMMapDao;
@Inject
BackupDao backupDao;
private static Map<String, BackupProvider> backupProvidersMap = new HashMap<>();
private List<BackupProvider> backupProviders;
@ -83,23 +95,55 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
if (vmInstanceVO == null) {
throw new CloudRuntimeException("VM " + virtualMachineId + " does not exist");
}
BackupPolicyVO policy = backupPolicyDao.findByUuid(policyUuid);
if (policy == null) {
throw new CloudRuntimeException("Policy " + policyUuid + " does not exist");
}
String vmUuid = vmInstanceVO.getUuid();
BackupProvider backupProvider = getBackupProvider(zoneId);
if (backupProvider == null) {
throw new CloudRuntimeException("Could not find a backup provider on zone " + zoneId);
boolean result = backupProvider.assignVMToBackupPolicy(vmUuid, policyUuid);
if (result) {
BackupPolicyVMMapVO map = backupPolicyVMMapDao.findByVMId(virtualMachineId);
if (map != null) {
backupPolicyVMMapDao.expunge(map.getId());
}
map = new BackupPolicyVMMapVO(policy.getId(), virtualMachineId);
backupPolicyVMMapDao.persist(map);
LOG.debug("Successfully assigned VM " + virtualMachineId + " to backup policy " + policy.getName());
} else {
LOG.debug("Could not assign VM " + virtualMachineId + " to backup policy " + policyUuid);
}
return backupProvider.assignVMToBackupPolicy(vmUuid, policyUuid);
return result;
}
@Override
public List<BackupPolicy> listBackupPolicies() {
public List<Backup> listBackups(Long vmId) {
return backupDao.listByVmId(vmId);
}
@Override
public List<BackupPolicy> listBackupPolicies(Long zoneId, Boolean external) {
if (BooleanUtils.isTrue(external)) {
BackupProvider backupProvider = getBackupProvider(zoneId);
return backupProvider.listBackupPolicies();
}
return new ArrayList<>(backupPolicyDao.listAll());
}
@Override
public List<BackupPolicy> listBackupProviderPolicies(Long zoneId) {
public boolean restoreBackup(Long vmId, String backupId, Long zoneId) {
BackupProvider backupProvider = getBackupProvider(zoneId);
return backupProvider.listBackupPolicies();
VMInstanceVO vm = vmInstanceDao.findById(vmId);
if (vm == null) {
throw new CloudRuntimeException("VM " + vmId + " does not exist");
}
return backupProvider.restoreVMFromBackup(vm.getUuid(), backupId);
}
@Override
public boolean restoreBackupVolume(Long volumeId, Long vmId, String backupId, Long zoneId) {
//TODO
return false;
}
@Override
@ -147,8 +191,10 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
cmdList.add(ListBackupPoliciesCmd.class);
cmdList.add(CreateBackupPolicyCmd.class);
cmdList.add(AssignBackupPolicyCmd.class);
cmdList.add(ListBackupProviderPoliciesCmd.class);
cmdList.add(DeleteBackupPolicyCmd.class);
cmdList.add(ListBackupsCmd.class);
cmdList.add(RestoreBackupCmd.class);
cmdList.add(RestoreBackupVolumeCmd.class);
return cmdList;
}