diff --git a/api/src/main/java/org/apache/cloudstack/api/BaseBackupPolicyListCmd.java b/api/src/main/java/org/apache/cloudstack/api/BaseBackupPolicyListCmd.java new file mode 100644 index 00000000000..31aacc91ac6 --- /dev/null +++ b/api/src/main/java/org/apache/cloudstack/api/BaseBackupPolicyListCmd.java @@ -0,0 +1,55 @@ +// 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.api; + +import org.apache.cloudstack.api.response.BackupPolicyResponse; +import org.apache.cloudstack.api.response.ListResponse; +import org.apache.cloudstack.context.CallContext; +import org.apache.cloudstack.framework.backup.BackupPolicy; + +import java.util.ArrayList; +import java.util.List; + +public abstract class BaseBackupPolicyListCmd extends BaseListCmd { + + protected void setupResponse(final List policies) { + final ListResponse response = new ListResponse<>(); + final List responses = new ArrayList<>(); + for (final BackupPolicy policy : policies) { + if (policy == null) { + continue; + } + final BackupPolicyResponse backupPolicyResponse = new BackupPolicyResponse(); + if (!policy.isExternal()) { + backupPolicyResponse.setId(policy.getUuid()); + } + backupPolicyResponse.setName(policy.getName()); + backupPolicyResponse.setPolicyId(policy.getPolicyUuid()); + backupPolicyResponse.setObjectName("policy"); + responses.add(backupPolicyResponse); + } + response.setResponses(responses); + response.setResponseName(getCommandName()); + setResponseObject(response); + } + + @Override + public long getEntityOwnerId() { + return CallContext.current().getCallingAccount().getId(); + } +} diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/backup/CreateBackupPolicyCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/CreateBackupPolicyCmd.java similarity index 68% rename from api/src/main/java/org/apache/cloudstack/api/command/user/backup/CreateBackupPolicyCmd.java rename to api/src/main/java/org/apache/cloudstack/api/command/admin/backup/CreateBackupPolicyCmd.java index 2f1ddacd531..96554deb411 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/backup/CreateBackupPolicyCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/CreateBackupPolicyCmd.java @@ -14,7 +14,7 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package org.apache.cloudstack.api.command.user.backup; +package org.apache.cloudstack.api.command.admin.backup; import javax.inject.Inject; @@ -26,6 +26,7 @@ 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.context.CallContext; import org.apache.cloudstack.framework.backup.BackupPolicy; @@ -39,7 +40,7 @@ import com.cloud.exception.ResourceUnavailableException; import com.cloud.utils.exception.CloudRuntimeException; @APICommand(name = CreateBackupPolicyCmd.APINAME, - description = "Creates a backup policy", + description = "Creates a backup policy by mapping it to an existing policy on the provider", responseObject = BackupPolicyResponse.class, since = "4.12.0", authorized = {RoleType.Admin}) public class CreateBackupPolicyCmd extends BaseCmd { @@ -48,20 +49,27 @@ public class CreateBackupPolicyCmd extends BaseCmd { @Inject BackupManager backupManager; - @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, description = "the name of the policy") + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + //////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = true, + description = "the name of the backup policy") private String policyName; @Parameter(name = ApiConstants.POLICY_ID, type = CommandType.STRING, required = true, - description = "Backup Recovery Provider ID") + description = "The backup policy ID (on backup provider side)") private String policyId; - @Parameter(name = ApiConstants.PROVIDER, - type = CommandType.STRING, - required = true, - description = "Backup Recovery Provider ID") - private String providerId; + @Parameter(name = ApiConstants.ZONE_ID, type = BaseCmd.CommandType.UUID, entityType = ZoneResponse.class, + description = "The zone ID") + private Long zoneId; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// public String getPolicyName() { return policyName; @@ -71,30 +79,8 @@ public class CreateBackupPolicyCmd extends BaseCmd { return policyId; } - public String getProviderId() { - return providerId; - } - - @Override - public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException { - try { - BackupPolicy policy = backupManager.addBackupPolicy(policyId, policyName, providerId); - if (policy != null) { - BackupPolicyResponse response = new BackupPolicyResponse(); - response.setId(policy.getUuid()); - response.setPolicyId(policy.getPolicyUuid()); - response.setName(policy.getName()); - response.setObjectName("policy"); - response.setResponseName(getCommandName()); - setResponseObject(response); - } else { - throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add a Backup policy"); - } - } catch (InvalidParameterValueException e) { - throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.getMessage()); - } catch (CloudRuntimeException e) { - throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage()); - } + public Long getZoneId() { + return zoneId; } @Override @@ -106,4 +92,34 @@ public class CreateBackupPolicyCmd extends BaseCmd { public long getEntityOwnerId() { return CallContext.current().getCallingAccount().getId(); } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + private void setupResponse(BackupPolicy policy) { + BackupPolicyResponse response = new BackupPolicyResponse(); + response.setId(policy.getUuid()); + response.setPolicyId(policy.getPolicyUuid()); + response.setName(policy.getName()); + response.setObjectName("policy"); + response.setResponseName(getCommandName()); + setResponseObject(response); + } + + @Override + public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException { + try { + BackupPolicy policy = backupManager.addBackupPolicy(policyId, policyName, zoneId); + if (policy != null) { + setupResponse(policy); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to add a Backup policy"); + } + } catch (InvalidParameterValueException e) { + throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.getMessage()); + } catch (CloudRuntimeException e) { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage()); + } + } } diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/DeleteBackupPolicyCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/DeleteBackupPolicyCmd.java new file mode 100644 index 00000000000..f4c1771e5e1 --- /dev/null +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/DeleteBackupPolicyCmd.java @@ -0,0 +1,90 @@ +// 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.api.command.admin.backup; + +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.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.BaseCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.SuccessResponse; +import org.apache.cloudstack.backup.BackupManager; +import org.apache.cloudstack.context.CallContext; + +import javax.inject.Inject; + +@APICommand(name = DeleteBackupPolicyCmd.APINAME, + description = "Deletes a backup policy", + responseObject = SuccessResponse.class, since = "4.12.0", + authorized = {RoleType.Admin}) +public class DeleteBackupPolicyCmd extends BaseCmd { + + public static final String APINAME = "deleteBackupPolicy"; + + @Inject + BackupManager backupManager; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + //////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.ID, + type = CommandType.STRING, + required = true, + description = "The backup policy internal ID") + private String id; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public String getId() { + return id; + } + + @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 { + if (backupManager.deleteBackupPolicy(id)) { + SuccessResponse response = new SuccessResponse(getCommandName()); + setResponseObject(response); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Unable to remove backup policy: " + id); + } + } +} diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/ListBackupProviderPoliciesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/ListBackupProviderPoliciesCmd.java new file mode 100644 index 00000000000..bc0c4b77894 --- /dev/null +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/ListBackupProviderPoliciesCmd.java @@ -0,0 +1,97 @@ +// 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.api.command.admin.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.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 { + + public static final String APINAME = "listBackupProviderPolicies"; + + @Inject + BackupManager backupManager; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.ZONE_ID, type = BaseCmd.CommandType.UUID, entityType = ZoneResponse.class, + description = "The zone ID") + private Long zoneId; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public Long getZoneId() { + return zoneId; + } + + @Override + public String getCommandName() { + return AssignBackupPolicyCmd.APINAME + 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 { + List policies = backupManager.listBackupProviderPolicies(zoneId); + setupResponse(policies); + } catch (InvalidParameterValueException e) { + throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.getMessage()); + } catch (CloudRuntimeException e) { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage()); + } + } +} diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/backup/ListBackupProvidersCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/ListBackupProvidersCmd.java similarity index 98% rename from api/src/main/java/org/apache/cloudstack/api/command/user/backup/ListBackupProvidersCmd.java rename to api/src/main/java/org/apache/cloudstack/api/command/admin/backup/ListBackupProvidersCmd.java index bbc707e3e57..e93b6e7c909 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/backup/ListBackupProvidersCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/backup/ListBackupProvidersCmd.java @@ -14,7 +14,7 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package org.apache.cloudstack.api.command.user.backup; +package org.apache.cloudstack.api.command.admin.backup; import java.util.ArrayList; import java.util.List; diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/backup/AssignBackupPolicyCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/backup/AssignBackupPolicyCmd.java index e1ec19b5add..b84300dbd95 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/backup/AssignBackupPolicyCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/backup/AssignBackupPolicyCmd.java @@ -26,6 +26,7 @@ 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; @@ -41,20 +42,35 @@ import com.cloud.exception.ResourceUnavailableException; public class AssignBackupPolicyCmd extends BaseCmd { public static final String APINAME = "assignBackupPolicy"; + @Inject + BackupManager backupManager; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + @Parameter(name = ApiConstants.VIRTUAL_MACHINE_ID, type = CommandType.UUID, entityType = UserVmResponse.class, required = true, description = "id of the VM to be moved") - private String virtualMachineId; + private Long virtualMachineId; @Parameter(name = ApiConstants.POLICY_ID, type = CommandType.STRING, required = true, - description = "Backup Recovery Provider ID") + description = "id of the backup policy") private String policyId; - public String getVirtualMachineId() { + @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, entityType = ZoneResponse.class, + description = "the zone ID", required = true) + private Long zoneId; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public Long getVirtualMachineId() { return virtualMachineId; } @@ -62,24 +78,8 @@ public class AssignBackupPolicyCmd extends BaseCmd { return policyId; } - @Inject - BackupManager backupManager; - - @Override - public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException { - try { - ; - boolean result = backupManager.assignVMToBackupPolicy(); - if (result) { - SuccessResponse response = new SuccessResponse(getCommandName()); - response.setResponseName(getCommandName()); - setResponseObject(response); - } else { - throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to assign VM to backup policy"); - } - } catch (Exception e) { - throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.getMessage()); - } + public Long getZoneId() { + return zoneId; } @Override @@ -91,4 +91,27 @@ public class AssignBackupPolicyCmd extends BaseCmd { public long getEntityOwnerId() { return CallContext.current().getCallingAccount().getId(); } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException { + try { + Long virtualMachineId = getVirtualMachineId(); + String policyUuid = getPolicyId(); + Long zoneId = getZoneId(); + boolean result = backupManager.assignVMToBackupPolicy(policyUuid, virtualMachineId, zoneId); + if (result) { + SuccessResponse response = new SuccessResponse(getCommandName()); + response.setResponseName(getCommandName()); + setResponseObject(response); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to assign VM to backup policy"); + } + } catch (Exception e) { + throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.getMessage()); + } + } } diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/backup/DeleteBackupPolicyCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/backup/DeleteBackupPolicyCmd.java deleted file mode 100644 index 66d8d2fc7ed..00000000000 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/backup/DeleteBackupPolicyCmd.java +++ /dev/null @@ -1,21 +0,0 @@ -// 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.api.command.user.backup; - -public class DeleteBackupPolicyCmd { -} diff --git a/api/src/main/java/org/apache/cloudstack/api/command/user/backup/ListBackupPoliciesCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/user/backup/ListBackupPoliciesCmd.java index a10ed5baf4b..8b8ef6e7088 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/user/backup/ListBackupPoliciesCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/user/backup/ListBackupPoliciesCmd.java @@ -16,20 +16,15 @@ // under the License. package org.apache.cloudstack.api.command.user.backup; -import java.util.ArrayList; import java.util.List; import javax.inject.Inject; -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.BaseListCmd; -import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.BaseBackupPolicyListCmd; import org.apache.cloudstack.api.ServerApiException; import org.apache.cloudstack.api.response.BackupPolicyResponse; -import org.apache.cloudstack.api.response.ListResponse; import org.apache.cloudstack.backup.BackupManager; import org.apache.cloudstack.framework.backup.BackupPolicy; @@ -39,51 +34,33 @@ import com.cloud.exception.ResourceUnavailableException; import com.cloud.utils.exception.CloudRuntimeException; @APICommand(name = ListBackupPoliciesCmd.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 ListBackupPoliciesCmd extends BaseListCmd { + description = "Lists backup policies", + responseObject = BackupPolicyResponse.class, since = "4.12.0") +public class ListBackupPoliciesCmd extends BaseBackupPolicyListCmd { public static final String APINAME = "listBackupPolicies"; @Inject BackupManager backupManager; - @Parameter(name = ApiConstants.PROVIDER, - type = CommandType.STRING, - required = true, - description = "Backup Recovery Provider ID") - private String providerId; - - public String getProviderId() { - return providerId; + @Override + public String getCommandName() { + return APINAME.toLowerCase() + RESPONSE_SUFFIX; } + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + @Override public void execute() throws ResourceUnavailableException, ServerApiException, ConcurrentOperationException { - List responses = new ArrayList<>(); - ListResponse response = new ListResponse(); try { - List policies = backupManager.listBackupPolicies(); - if (policies == null) { - throw new CloudRuntimeException("Error while retrieving backup provider policies"); - } - for (BackupPolicy policy : policies) { - responses.add(backupManager.createBackupPolicyResponse(policy)); - } - response.setResponses(responses, responses.size()); - response.setObjectName("policy"); - response.setResponseName(getCommandName()); - setResponseObject(response); + List backupPolicies = backupManager.listBackupPolicies(); + setupResponse(backupPolicies); } catch (InvalidParameterValueException e) { throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.getMessage()); } catch (CloudRuntimeException e) { throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage()); } } - - @Override - public String getCommandName() { - return APINAME.toLowerCase() + RESPONSE_SUFFIX; - } } diff --git a/api/src/main/java/org/apache/cloudstack/api/response/BackupPolicyResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/BackupPolicyResponse.java index 3c2e7509b67..a658f31ead6 100644 --- a/api/src/main/java/org/apache/cloudstack/api/response/BackupPolicyResponse.java +++ b/api/src/main/java/org/apache/cloudstack/api/response/BackupPolicyResponse.java @@ -31,10 +31,6 @@ public class BackupPolicyResponse extends BaseResponse { @Param(description = "internal id of the backup policy") private String id; - @SerializedName(ApiConstants.UUID) - @Param(description = "internal uuid of the backup policy") - private String uuid; - @SerializedName(ApiConstants.NAME) @Param(description = "internal name for the backup policy") private String name; @@ -43,10 +39,6 @@ public class BackupPolicyResponse extends BaseResponse { @Param(description = "policy id on the provider side") private String policyId; - @SerializedName(ApiConstants.PROVIDER) - @Param(description = "id of the backup and Recovery provider") - private String providerId; - public void setId(String id) { this.id = id; } @@ -55,15 +47,7 @@ public class BackupPolicyResponse extends BaseResponse { this.policyId = policyId; } - public void setProviderId(String providerId) { - this.providerId = providerId; - } - public void setName(String name) { this.name = name; } - - public void setUuid(String uuid) { - this.uuid = uuid; - } } diff --git a/api/src/main/java/org/apache/cloudstack/backup/BackupManager.java b/api/src/main/java/org/apache/cloudstack/backup/BackupManager.java index 7443fc135f8..95b11ca12cd 100644 --- a/api/src/main/java/org/apache/cloudstack/backup/BackupManager.java +++ b/api/src/main/java/org/apache/cloudstack/backup/BackupManager.java @@ -51,9 +51,25 @@ public interface BackupManager extends BackupService, Configurable, PluggableSer /** * Add a new Backup and Recovery policy */ - BackupPolicy addBackupPolicy(String policyId, String policyName, String providerId); + BackupPolicy addBackupPolicy(String policyId, String policyName, Long zoneId); - boolean assignVMToBackupPolicy(); + /** + * Assign VM to existing backup policy + */ + boolean assignVMToBackupPolicy(String policyUuid, Long virtualMachineId, Long zoneId); + /** + * List existing backup policies + */ List listBackupPolicies(); + + /** + * List backup policies existing on the backup provider + */ + List listBackupProviderPolicies(Long zoneId); + + /** + * Deletes a backup policy + */ + boolean deleteBackupPolicy(String policyId); } diff --git a/engine/schema/src/main/java/org/apache/cloudstack/backup/BackupPolicyTO.java b/engine/schema/src/main/java/org/apache/cloudstack/backup/BackupPolicyTO.java index a1e729d8cb7..05d8fbe0b92 100644 --- a/engine/schema/src/main/java/org/apache/cloudstack/backup/BackupPolicyTO.java +++ b/engine/schema/src/main/java/org/apache/cloudstack/backup/BackupPolicyTO.java @@ -21,17 +21,23 @@ package org.apache.cloudstack.backup; import org.apache.cloudstack.framework.backup.BackupPolicy; +import java.util.UUID; + public class BackupPolicyTO implements BackupPolicy { - private long id; private String uuid; + private long id; private String name; private String policyUuid; + private boolean external = true; - public BackupPolicyTO(final long id, final String uuid, final String name, final String policyUuid) { + public BackupPolicyTO() { + this.uuid = UUID.randomUUID().toString(); + } + + public BackupPolicyTO(final String name, final String policyUuid) { + this(); this.name = name; - this.uuid = uuid; - this.id = id; this.policyUuid = policyUuid; } @@ -53,4 +59,9 @@ public class BackupPolicyTO implements BackupPolicy { public long getId() { return id; } + + @Override + public boolean isExternal() { + return external; + } } diff --git a/engine/schema/src/main/java/org/apache/cloudstack/backup/BackupPolicyVO.java b/engine/schema/src/main/java/org/apache/cloudstack/backup/BackupPolicyVO.java index d8fb433072d..18a76dd1dbb 100644 --- a/engine/schema/src/main/java/org/apache/cloudstack/backup/BackupPolicyVO.java +++ b/engine/schema/src/main/java/org/apache/cloudstack/backup/BackupPolicyVO.java @@ -17,6 +17,8 @@ package org.apache.cloudstack.backup; +import org.apache.cloudstack.framework.backup.BackupPolicy; + import java.util.UUID; import javax.persistence.Column; @@ -26,8 +28,6 @@ import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; -import org.apache.cloudstack.framework.backup.BackupPolicy; - @Entity @Table(name = "backup_policy") public class BackupPolicyVO implements BackupPolicy { @@ -86,4 +86,8 @@ public class BackupPolicyVO implements BackupPolicy { public void setPolicyUuid(String policyUuid) { this.policyUuid = policyUuid; } + + public boolean isExternal() { + return false; + } } diff --git a/framework/backup/src/main/java/org/apache/cloudstack/framework/backup/BackupPolicy.java b/framework/backup/src/main/java/org/apache/cloudstack/framework/backup/BackupPolicy.java index 53edb30f8ab..d07a36d66cc 100644 --- a/framework/backup/src/main/java/org/apache/cloudstack/framework/backup/BackupPolicy.java +++ b/framework/backup/src/main/java/org/apache/cloudstack/framework/backup/BackupPolicy.java @@ -17,8 +17,11 @@ package org.apache.cloudstack.framework.backup; public interface BackupPolicy { + long getId(); String getUuid(); String getPolicyUuid(); String getName(); + boolean isExternal(); + } diff --git a/framework/backup/src/main/java/org/apache/cloudstack/framework/backup/BackupProvider.java b/framework/backup/src/main/java/org/apache/cloudstack/framework/backup/BackupProvider.java index 69f999ee427..f3d9b136ae0 100644 --- a/framework/backup/src/main/java/org/apache/cloudstack/framework/backup/BackupProvider.java +++ b/framework/backup/src/main/java/org/apache/cloudstack/framework/backup/BackupProvider.java @@ -16,6 +16,8 @@ //under the License. package org.apache.cloudstack.framework.backup; +import java.util.List; + public interface BackupProvider { /** @@ -29,4 +31,21 @@ public interface BackupProvider { * @return returns description */ String getDescription(); + + /** + * Assign VM to backup policy + * @return true if VM is successfully assigned, false if not + */ + boolean assignVMToBackupPolicy(String vmUuid, String policyUuid); + + /** + * Returns the list of existing backup policies on the provider + * @return backup policies list + */ + List listBackupPolicies(); + + /** + * True if policy with id uuid exists on the backup provider + */ + boolean isBackupPolicy(String uuid); } diff --git a/framework/backup/src/main/java/org/apache/cloudstack/framework/backup/BackupService.java b/framework/backup/src/main/java/org/apache/cloudstack/framework/backup/BackupService.java index 419fb1adb76..6f5417d6d27 100644 --- a/framework/backup/src/main/java/org/apache/cloudstack/framework/backup/BackupService.java +++ b/framework/backup/src/main/java/org/apache/cloudstack/framework/backup/BackupService.java @@ -29,11 +29,9 @@ public interface BackupService { List listBackupProviders(); /** - * Find backup provider by name and zone ID - * When null is provided as name, the configured provider is returned - * @param providerName - * @param zoneId + * Find backup provider by zone ID + * @param zoneId zone id * @return backup provider */ - BackupProvider getBackupProvider(final String providerName, final Long zoneId); + BackupProvider getBackupProvider(final Long zoneId); } diff --git a/plugins/backup/dummy/src/main/java/org/apache/cloudstack/backup/DummyBackupProvider.java b/plugins/backup/dummy/src/main/java/org/apache/cloudstack/backup/DummyBackupProvider.java index 40fdb6fc2c3..42d5cfddac0 100644 --- a/plugins/backup/dummy/src/main/java/org/apache/cloudstack/backup/DummyBackupProvider.java +++ b/plugins/backup/dummy/src/main/java/org/apache/cloudstack/backup/DummyBackupProvider.java @@ -16,12 +16,19 @@ // under the License. package org.apache.cloudstack.backup; +import org.apache.cloudstack.framework.backup.BackupPolicy; import org.apache.cloudstack.framework.backup.BackupProvider; import com.cloud.utils.component.AdapterBase; +import org.apache.log4j.Logger; + +import java.util.Arrays; +import java.util.List; public class DummyBackupProvider extends AdapterBase implements BackupProvider { + private static final Logger s_logger = Logger.getLogger(DummyBackupProvider.class); + @Override public String getName() { return "dummy"; @@ -31,4 +38,24 @@ public class DummyBackupProvider extends AdapterBase implements BackupProvider { public String getDescription() { return "Dummy B&R Plugin"; } + + @Override + public boolean assignVMToBackupPolicy(String vmUuid, String policyUuid) { + s_logger.debug("Assigning VM " + vmUuid + " to backup policy " + policyUuid); + return true; + } + + @Override + public List listBackupPolicies() { + s_logger.debug("Listing backup policies on Dummy B&R Plugin"); + BackupPolicy policy1 = new BackupPolicyTO("Golden Policy", "aaaa-aaaa"); + BackupPolicy policy2 = new BackupPolicyTO("Silver Policy", "bbbb-bbbb"); + return Arrays.asList(policy1, policy2); + } + + @Override + public boolean isBackupPolicy(String uuid) { + s_logger.debug("Checking if backup policy exists on the Dummy Backup Provider"); + return true; + } } diff --git a/plugins/backup/veeam/src/main/java/org/apache/cloudstack/backup/VeeamBackupProvider.java b/plugins/backup/veeam/src/main/java/org/apache/cloudstack/backup/VeeamBackupProvider.java index f4f62849130..e8fbf812de6 100644 --- a/plugins/backup/veeam/src/main/java/org/apache/cloudstack/backup/VeeamBackupProvider.java +++ b/plugins/backup/veeam/src/main/java/org/apache/cloudstack/backup/VeeamBackupProvider.java @@ -17,6 +17,7 @@ package org.apache.cloudstack.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; @@ -25,6 +26,8 @@ import org.apache.log4j.Logger; import com.cloud.utils.component.AdapterBase; +import java.util.List; + public class VeeamBackupProvider extends AdapterBase implements BackupProvider, Configurable { private static final Logger LOG = Logger.getLogger(VeeamBackupProvider.class); @@ -67,4 +70,19 @@ public class VeeamBackupProvider extends AdapterBase implements BackupProvider, public String getDescription() { return "Veeam B&R Plugin"; } + + @Override + public boolean assignVMToBackupPolicy(String vmUuid, String policyUuid) { + return false; + } + + @Override + public List listBackupPolicies() { + return null; + } + + @Override + public boolean isBackupPolicy(String uuid) { + return false; + } } diff --git a/server/src/main/java/org/apache/cloudstack/backup/BackupManagerImpl.java b/server/src/main/java/org/apache/cloudstack/backup/BackupManagerImpl.java index c5aebf33f02..828b41753a8 100644 --- a/server/src/main/java/org/apache/cloudstack/backup/BackupManagerImpl.java +++ b/server/src/main/java/org/apache/cloudstack/backup/BackupManagerImpl.java @@ -24,9 +24,14 @@ import java.util.Map; import javax.inject.Inject; import javax.naming.ConfigurationException; -import org.apache.cloudstack.api.command.user.backup.CreateBackupPolicyCmd; +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.user.backup.ListBackupProvidersCmd; +import org.apache.cloudstack.api.command.admin.backup.ListBackupProvidersCmd; import org.apache.cloudstack.api.response.BackupPolicyResponse; import org.apache.cloudstack.backup.dao.BackupPolicyDao; import org.apache.cloudstack.framework.backup.BackupPolicy; @@ -39,7 +44,6 @@ import org.springframework.stereotype.Component; import com.cloud.dc.dao.DataCenterDao; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.exception.CloudRuntimeException; -import com.google.common.base.Strings; @Component public class BackupManagerImpl extends ManagerBase implements BackupManager { @@ -48,6 +52,9 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager { @Inject BackupPolicyDao backupPolicyDao; + @Inject + VMInstanceDao vmInstanceDao; + @Inject DataCenterDao dataCenterDao; @@ -55,25 +62,53 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager { private List backupProviders; @Override - public BackupPolicy addBackupPolicy(String policyId, String policyName, String providerId) { - BackupProvider provider = getBackupProvider(null, null); - boolean exists = false; //provider.policyExists(policyId, policyName); - if (!exists) { + public BackupPolicy addBackupPolicy(String policyId, String policyName, Long zoneId) { + BackupProvider provider = getBackupProvider(zoneId); + if (!provider.isBackupPolicy(policyId)) { throw new CloudRuntimeException("Policy " + policyId + " does not exist on provider " + provider.getName()); } BackupPolicyVO policy = new BackupPolicyVO(policyName, policyId); - return backupPolicyDao.persist(policy); + BackupPolicyVO vo = backupPolicyDao.persist(policy); + if (vo == null) { + throw new CloudRuntimeException("Unable to create backup policy: " + policyId + ", name: " + policyName); + } + LOG.debug("Successfully created backup policy " + policyName + " mapped to backup provider policy " + policyId); + return vo; } @Override - public boolean assignVMToBackupPolicy() { - return false; + public boolean assignVMToBackupPolicy(String policyUuid, Long virtualMachineId, Long zoneId) { + VMInstanceVO vmInstanceVO = vmInstanceDao.findById(virtualMachineId); + if (vmInstanceVO == null) { + throw new CloudRuntimeException("VM " + virtualMachineId + " 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); + } + return backupProvider.assignVMToBackupPolicy(vmUuid, policyUuid); } @Override public List listBackupPolicies() { - return null; + return new ArrayList<>(backupPolicyDao.listAll()); + } + + @Override + public List listBackupProviderPolicies(Long zoneId) { + BackupProvider backupProvider = getBackupProvider(zoneId); + return backupProvider.listBackupPolicies(); + } + + @Override + public boolean deleteBackupPolicy(String policyId) { + BackupPolicyVO policy = backupPolicyDao.findByUuid(policyId); + if (policy == null) { + throw new CloudRuntimeException("Could not find a backup policy with id: " + policyId); + } + return backupPolicyDao.expunge(policy.getId()); } @Override @@ -97,12 +132,12 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager { } @Override - public BackupProvider getBackupProvider(final String providerName, final Long zoneId) { - String name = providerName; - if (Strings.isNullOrEmpty(name)) { - name = BackupProviderPlugin.valueIn(zoneId); + public BackupProvider getBackupProvider(final Long zoneId) { + String name = BackupProviderPlugin.valueIn(zoneId); + if (!backupProvidersMap.containsKey(name)) { + throw new CloudRuntimeException("Could not find a backup provider on zone " + zoneId); } - return backupProvidersMap.getOrDefault(name, null); + return backupProvidersMap.get(name); } @Override @@ -111,6 +146,9 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager { cmdList.add(ListBackupProvidersCmd.class); cmdList.add(ListBackupPoliciesCmd.class); cmdList.add(CreateBackupPolicyCmd.class); + cmdList.add(AssignBackupPolicyCmd.class); + cmdList.add(ListBackupProviderPoliciesCmd.class); + cmdList.add(DeleteBackupPolicyCmd.class); return cmdList; } @@ -126,11 +164,16 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager { public void setBackupProviders(final List backupProviders) { this.backupProviders = backupProviders; + } + + @Override + public boolean start() { initializeBackupProviderMap(); + return true; } private void initializeBackupProviderMap() { - if (backupProviders != null && backupProviders.size() != backupProviders.size()) { + if (backupProviders != null) { for (final BackupProvider backupProvider : backupProviders) { backupProvidersMap.put(backupProvider.getName().toLowerCase(), backupProvider); }