Remove VM from backup policy and improvements

This commit is contained in:
nvazquez 2018-05-30 00:17:40 -03:00
parent bc0c2472e1
commit 01059d9d5f
13 changed files with 287 additions and 53 deletions

View File

@ -108,7 +108,7 @@ public class ImportBackupPolicyCmd extends BaseCmd {
@Override
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
try {
BackupPolicy policy = backupManager.addBackupPolicy(zoneId, policyExternalId, policyName, description);
BackupPolicy policy = backupManager.importBackupPolicy(zoneId, policyExternalId, policyName, description);
if (policy != null) {
BackupPolicyResponse response = _responseGenerator.createBackupPolicyResponse(policy);
response.setResponseName(getCommandName());

View File

@ -38,12 +38,12 @@ import com.cloud.exception.NetworkRuleConflictException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
@APICommand(name = AssignBackupPolicyCmd.APINAME,
@APICommand(name = AddVMToBackupPolicyCmd.APINAME,
description = "Assigns a VM to an existing backup policy",
responseObject = SuccessResponse.class, since = "4.12.0",
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
public class AssignBackupPolicyCmd extends BaseCmd {
public static final String APINAME = "assignBackupPolicy";
public class AddVMToBackupPolicyCmd extends BaseCmd {
public static final String APINAME = "addVirtualMachineToBackupPolicy";
@Inject
BackupManager backupManager;
@ -88,7 +88,7 @@ public class AssignBackupPolicyCmd extends BaseCmd {
@Override
public String getCommandName() {
return AssignBackupPolicyCmd.APINAME + RESPONSE_SUFFIX;
return AddVMToBackupPolicyCmd.APINAME.toLowerCase() + RESPONSE_SUFFIX;
}
@Override
@ -103,10 +103,7 @@ public class AssignBackupPolicyCmd extends BaseCmd {
@Override
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException {
try {
Long virtualMachineId = getVirtualMachineId();
Long policyId = getPolicyId();
Long zoneId = getZoneId();
boolean result = backupManager.assignVMToBackupPolicy(zoneId, policyId, virtualMachineId);
boolean result = backupManager.addVMToBackupPolicy(zoneId, policyId, virtualMachineId);
if (result) {
SuccessResponse response = new SuccessResponse(getCommandName());
response.setResponseName(getCommandName());

View File

@ -54,8 +54,12 @@ public class ListBackupPoliciesCmd extends BaseBackupListCmd {
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name = ApiConstants.ID, type = BaseCmd.CommandType.UUID, entityType = BackupPolicyResponse.class,
description = "The backup policy ID")
private Long policyId;
@Parameter(name = ApiConstants.ZONE_ID, type = BaseCmd.CommandType.UUID, entityType = ZoneResponse.class,
description = "The zone ID", required = true)
description = "The zone ID")
private Long zoneId;
@Parameter(name = ApiConstants.EXTERNAL, type = CommandType.BOOLEAN,
@ -74,6 +78,10 @@ public class ListBackupPoliciesCmd extends BaseBackupListCmd {
return BooleanUtils.isTrue(external);
}
public Long getPolicyId() {
return policyId;
}
@Override
public String getCommandName() {
return APINAME.toLowerCase() + RESPONSE_SUFFIX;
@ -86,7 +94,7 @@ public class ListBackupPoliciesCmd extends BaseBackupListCmd {
@Override
public void execute() throws ResourceUnavailableException, ServerApiException, ConcurrentOperationException {
try {
List<BackupPolicy> backupPolicies = backupManager.listBackupPolicies(zoneId, external);
List<BackupPolicy> backupPolicies = backupManager.listBackupPolicies(zoneId, external, policyId);
setupResponseBackupPolicyList(backupPolicies);
} catch (InvalidParameterValueException e) {
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, e.getMessage());

View File

@ -0,0 +1,121 @@
// 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;
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.BackupPolicyResponse;
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 = RemoveVMFromBackupPolicy.APINAME,
description = "Removes a VM from an existing backup policy",
responseObject = SuccessResponse.class, since = "4.12.0",
authorized = {RoleType.Admin, RoleType.ResourceAdmin, RoleType.DomainAdmin, RoleType.User})
public class RemoveVMFromBackupPolicy extends BaseCmd {
public static final String APINAME = "removeVirtualMachineFromBackupPolicy";
@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 removed from the backup policy")
private Long virtualMachineId;
@Parameter(name = ApiConstants.BACKUP_POLICY_ID,
type = CommandType.UUID,
entityType = BackupPolicyResponse.class,
required = true,
description = "id of the backup policy")
private Long policyId;
@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;
}
public Long getPolicyId() {
return policyId;
}
public Long getZoneId() {
return zoneId;
}
@Override
public String getCommandName() {
return APINAME.toLowerCase() + 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.removeVMFromBackupPolicy(zoneId, policyId, virtualMachineId);
if (result) {
SuccessResponse response = new SuccessResponse(getCommandName());
response.setResponseName(getCommandName());
setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to remove VM from backup policy");
}
} catch (Exception e) {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, e.getMessage());
}
}
}

View File

@ -47,12 +47,12 @@ public interface BackupManager extends BackupService, Configurable, PluggableSer
* @param policyName internal name for the backup policy
* @param policyDescription internal description for the backup policy
*/
BackupPolicy addBackupPolicy(Long zoneId, String policyExternalId, String policyName, String policyDescription);
BackupPolicy importBackupPolicy(Long zoneId, String policyExternalId, String policyName, String policyDescription);
/**
* Assign VM to existing backup policy
*/
boolean assignVMToBackupPolicy(Long zoneId, Long policyId, Long virtualMachineId);
boolean addVMToBackupPolicy(Long zoneId, Long policyId, Long virtualMachineId);
/**
* List existing backups for a VM
@ -63,8 +63,9 @@ public interface BackupManager extends BackupService, Configurable, PluggableSer
* List backup policies
* @param zoneId zone id
* @param external if true, only external backup policies are listed
* @param policyId if not null, only the policy with this id is listed
*/
List<BackupPolicy> listBackupPolicies(Long zoneId, Boolean external);
List<BackupPolicy> listBackupPolicies(Long zoneId, Boolean external, Long policyId);
/**
* Restore a full backed up VM
@ -80,4 +81,9 @@ public interface BackupManager extends BackupService, Configurable, PluggableSer
* Deletes a backup policy
*/
boolean deleteBackupPolicy(Long policyId);
/**
* Remove a VM from a backup policy
*/
boolean removeVMFromBackupPolicy(Long zoneId, Long policyId, Long vmId);
}

View File

@ -38,7 +38,12 @@ public interface BackupProvider {
* Assign VM to backup policy
* @return true if VM is successfully assigned, false if not
*/
boolean assignVMToBackupPolicy(String vmUuid, String policyUuid);
boolean addVMToBackupPolicy(String vmUuid, String policyUuid);
/**
* Remove a VM form a backup policy
*/
boolean removeVMFromBackupPolicy(String vmUuid, String policyUuid);
/**
* Returns the list of existing backup policies on the provider

View File

@ -28,4 +28,5 @@ public interface BackupPolicyVMMapDao extends GenericDao<BackupPolicyVMMapVO, Lo
BackupPolicyVMMapVO findByVMId(long vmId);
List<BackupPolicyVMMapVO> listByPolicyId(long policyId);
BackupPolicyVMMapVO findByPolicyIdAndVMId(long policyId, long vmId);
}

View File

@ -66,4 +66,12 @@ public class BackupPolicyVMMapDaoImpl extends GenericDaoBase<BackupPolicyVMMapVO
sc.setParameters("policy_id", policyId);
return listBy(sc);
}
@Override
public BackupPolicyVMMapVO findByPolicyIdAndVMId(long policyId, long vmId) {
SearchCriteria<BackupPolicyVMMapVO> sc = mapSearch.create();
sc.setParameters("policy_id", policyId);
sc.setParameters("vm_id", vmId);
return findOneBy(sc);
}
}

View File

@ -40,11 +40,17 @@ public class DummyBackupProvider extends AdapterBase implements BackupProvider {
}
@Override
public boolean assignVMToBackupPolicy(String vmUuid, String policyUuid) {
public boolean addVMToBackupPolicy(String vmUuid, String policyUuid) {
s_logger.debug("Assigning VM " + vmUuid + " to backup policy " + policyUuid);
return true;
}
@Override
public boolean removeVMFromBackupPolicy(String vmUuid, String policyUuid) {
s_logger.debug("Removing VM " + vmUuid + " to backup policy " + policyUuid);
return true;
}
@Override
public List<BackupPolicy> listBackupPolicies(Long zoneId) {
s_logger.debug("Listing backup policies on Dummy B&R Plugin");

View File

@ -79,7 +79,12 @@ public class VeeamBackupProvider extends AdapterBase implements BackupProvider,
}
@Override
public boolean assignVMToBackupPolicy(String vmUuid, String policyUuid) {
public boolean addVMToBackupPolicy(String vmUuid, String policyUuid) {
return false;
}
@Override
public boolean removeVMFromBackupPolicy(String vmUuid, String policyUuid) {
return false;
}

View File

@ -17,6 +17,7 @@
package org.apache.cloudstack.backup;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -34,11 +35,12 @@ import com.cloud.user.AccountService;
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.user.backup.AssignBackupPolicyCmd;
import org.apache.cloudstack.api.command.user.backup.AddVMToBackupPolicyCmd;
import org.apache.cloudstack.api.command.admin.backup.ImportBackupPolicyCmd;
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.RemoveVMFromBackupPolicy;
import org.apache.cloudstack.api.command.user.backup.RestoreBackupCmd;
import org.apache.cloudstack.api.command.user.backup.RestoreBackupVolumeCmd;
import org.apache.cloudstack.backup.dao.BackupDao;
@ -82,7 +84,7 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
private List<BackupProvider> backupProviders;
@Override
public BackupPolicy addBackupPolicy(Long zoneId, String policyExternalId, String policyName, String policyDescription) {
public BackupPolicy importBackupPolicy(Long zoneId, String policyExternalId, String policyName, String policyDescription) {
BackupProvider provider = getBackupProvider(zoneId);
if (!provider.isBackupPolicy(policyExternalId)) {
throw new CloudRuntimeException("Policy " + policyExternalId + " does not exist on provider " + provider.getName() + " on zone " + zoneId);
@ -98,7 +100,7 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
}
@Override
public boolean assignVMToBackupPolicy(Long zoneId, Long policyId, Long virtualMachineId) {
public boolean addVMToBackupPolicy(Long zoneId, Long policyId, Long virtualMachineId) {
VMInstanceVO vmInstanceVO = vmInstanceDao.findById(virtualMachineId);
if (vmInstanceVO == null) {
throw new CloudRuntimeException("VM " + virtualMachineId + " does not exist");
@ -109,7 +111,7 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
}
String vmUuid = vmInstanceVO.getUuid();
BackupProvider backupProvider = getBackupProvider(zoneId);
boolean result = backupProvider.assignVMToBackupPolicy(vmUuid, policy.getUuid());
boolean result = backupProvider.addVMToBackupPolicy(vmUuid, policy.getExternalId());
if (result) {
BackupPolicyVMMapVO map = backupPolicyVMMapDao.findByVMId(virtualMachineId);
if (map != null) {
@ -124,6 +126,28 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
return result;
}
@Override
public boolean removeVMFromBackupPolicy(Long zoneId, Long policyId, Long vmId) {
BackupPolicyVO policy = backupPolicyDao.findById(policyId);
if (policy == null) {
throw new CloudRuntimeException("Policy " + policyId + " does not exist");
}
VMInstanceVO vm = vmInstanceDao.findById(vmId);
if (vm == null) {
throw new CloudRuntimeException("VM " + vmId + " does not exist");
}
BackupProvider backupProvider = getBackupProvider(zoneId);
boolean result = backupProvider.removeVMFromBackupPolicy(vm.getUuid(), policy.getExternalId());
if (result) {
BackupPolicyVMMapVO map = backupPolicyVMMapDao.findByPolicyIdAndVMId(policyId, vmId);
backupPolicyVMMapDao.expunge(map.getId());
LOG.debug("Successfully removed VM " + vmId + " from backup policy " + policy.getName());
} else {
LOG.debug("Could not remove VM " + vmId + " from backup policy " + policyId);
}
return result;
}
@Override
public List<Backup> listBackups(Long vmId) {
return backupDao.listByVmId(vmId);
@ -150,9 +174,25 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
return backupPolicyDao.listByZone(zoneId);
}
/**
* List imported backup policy with id policyId
*/
private List<BackupPolicy> listInternalPolicyById(Long policyId) {
BackupPolicyVO policy = backupPolicyDao.findById(policyId);
if (policy == null) {
throw new CloudRuntimeException("Policy " + policyId + " does not exist");
}
LOG.debug("Listing imported backup policy with id: " + policyId);
return Collections.singletonList(policy);
}
@Override
public List<BackupPolicy> listBackupPolicies(Long zoneId, Boolean external) {
return BooleanUtils.isTrue(external) ? listExternalPolicies(zoneId) : listInternalPolicies(zoneId);
public List<BackupPolicy> listBackupPolicies(Long zoneId, Boolean external, Long policyId) {
if (policyId != null) {
return listInternalPolicyById(policyId);
} else {
return BooleanUtils.isTrue(external) ? listExternalPolicies(zoneId) : listInternalPolicies(zoneId);
}
}
@Override
@ -237,7 +277,8 @@ public class BackupManagerImpl extends ManagerBase implements BackupManager {
cmdList.add(ListBackupProvidersCmd.class);
cmdList.add(ListBackupPoliciesCmd.class);
cmdList.add(ImportBackupPolicyCmd.class);
cmdList.add(AssignBackupPolicyCmd.class);
cmdList.add(AddVMToBackupPolicyCmd.class);
cmdList.add(RemoveVMFromBackupPolicy.class);
cmdList.add(DeleteBackupPolicyCmd.class);
cmdList.add(ListBackupsCmd.class);
cmdList.add(RestoreBackupCmd.class);

View File

@ -27,6 +27,8 @@ class TestDummyBackupAndRecovery(cloudstackTestCase):
@classmethod
def setUpClass(cls):
# Setup
cls.testClient = super(TestDummyBackupAndRecovery, cls).getClsTestClient()
cls.api_client = cls.testClient.getApiClient()
cls.services = cls.testClient.getParsedTestDataConfig()
@ -46,6 +48,8 @@ class TestDummyBackupAndRecovery(cloudstackTestCase):
mode=cls.services["mode"])
cls._cleanup = [cls.offering, cls.account]
# Check backup configuration values, set them to enable the dummy provider
backup_enabled_cfg = Configurations.list(cls.api_client, name='backup.framework.enabled')
backup_provider_cfg = Configurations.list(cls.api_client, name='backup.framework.provider.plugin')
cls.backup_enabled = backup_enabled_cfg[0].value
@ -56,6 +60,8 @@ class TestDummyBackupAndRecovery(cloudstackTestCase):
if not cls.backup_provider == "dummy":
Configurations.update(cls.api_client, 'backup.framework.provider.plugin', 'dummy', zoneid=cls.zone.id)
# Import a dummy backup policy to use on tests
cls.external_policies = BackupPolicy.listExternal(cls.api_client, cls.zone.id)
cls.debug("Importing backup policy %s - %s" % (cls.external_policies[0].externalid, cls.external_policies[0].name))
cls.policy = BackupPolicy.importExisting(cls.api_client, cls.zone.id, cls.external_policies[0].externalid,
@ -93,11 +99,17 @@ class TestDummyBackupAndRecovery(cloudstackTestCase):
return
@attr(tags=["advanced", "backup"], required_hardware="false")
def test_ImportBackupPolicies(self):
def test_import_backup_policies(self):
"""
Import existing backup policies from Dummy Backup and Recovery Provider
"""
# Validate the following:
# 1. Import a backup policy from the dummy provider
# 2. List internal backup policies, policy id should be listed
# 3. Delete backup policy
# 4. List internal backup policies, policy id should not be listed
ext_policy = self.external_policies[1]
self.debug("Importing backup policy %s - %s" % (ext_policy.externalid, ext_policy.name))
policy = BackupPolicy.importExisting(self.apiclient, self.zone.id, ext_policy.externalid,
@ -106,44 +118,51 @@ class TestDummyBackupAndRecovery(cloudstackTestCase):
imported_policies = BackupPolicy.listInternal(self.apiclient, self.zone.id)
self.assertIsInstance(imported_policies, list, "List Backup Policies should return a valid response")
self.assertNotEqual(len(imported_policies), 0, "Check if the list API returns a non-empty response")
matching_policies = [x for x in imported_policies if x.id == policy.id]
self.assertNotEqual(len(matching_policies), 0, "Check if there is a matching policy")
self.debug("Deleting backup policy %s" % policy.id)
policy.delete(self.apiclient)
imported_policies = BackupPolicy.listInternal(self.apiclient, self.zone.id)
self.assertIsInstance(imported_policies, list, "List Backup Policies should return a valid response")
matching_policies = [x for x in imported_policies if x.id == policy.id]
self.assertEqual(len(matching_policies), 0, "Check there is not a matching policy")
@attr(tags=["advanced", "backup"], required_hardware="false")
def test_AssignVMToBackupPolicy(self):
def test_add_vm_to_backup_Policy(self):
"""
Assign a VM to a backup policy
"""
self.debug("Assigning VM %s to backup policy %s" % (self.vm.id, self.policy.id))
# Validate the following:
# 1. Add VM to backup policy
# 2. Verify a mapping between the VM and the backup policy exists
# 3. Remove VM from backup policy
# 4. Verify there is no mapping between the VM and the backup policy
self.policy.assignVM(
self.apiclient,
self.vm.id,
self.zone.id
)
self.debug("Adding VM %s to backup policy %s" % (self.vm.id, self.policy.id))
self.policy.addVM(self.apiclient, self.vm.id, self.zone.id)
qresultset = self.dbclient.execute(
"select id from vm_instance where uuid='%s';"
% self.vm.id
)
# Verify a mapping between backup policy and VM is created on DB
qresultset = self.dbclient.execute("select id from vm_instance where uuid='%s';" % self.vm.id)
vm_id = qresultset[0][0]
qresultset = self.dbclient.execute(
"select id from backup_policy where uuid='%s';"
% self.policy.id
)
qresultset = self.dbclient.execute("select id from backup_policy where uuid='%s';" % self.policy.id)
policy_id = qresultset[0][0]
qresultset = self.dbclient.execute(
"select id from backup_policy_vm_map where policy_id='%d' and vm_id = '%d';"
% (policy_id, vm_id)
)
qresultset = self.dbclient.execute("select id from backup_policy_vm_map where policy_id='%d' and vm_id = '%d';"
% (policy_id, vm_id))
map = qresultset[0]
self.assertNotEqual(
map[0],
None,
"A mapping between VM and backup policy should exist on DB"
)
self.assertNotEqual(len(map), 0, "A mapping between VM and backup policy should exist on DB")
self.assertNotEqual(map[0], None, "A mapping between VM and backup policy should exist on DB")
self.debug("Removing VM %s from backup policy %s" % (self.vm.id, self.policy.id))
self.policy.removeVM(self.apiclient, self.vm.id, self.zone.id)
# Verify mapping is removed from DB
qresultset = self.dbclient.execute("select id from backup_policy_vm_map where policy_id='%d' and vm_id = '%d';"
% (policy_id, vm_id))
self.assertEqual(len(qresultset), 0, "The mapping between VM and backup policy should be removed from DB")

View File

@ -5394,6 +5394,14 @@ class BackupPolicy:
cmd.description = description
return BackupPolicy(apiclient.importBackupPolicy(cmd).__dict__)
@classmethod
def listInternalById(self, apiclient, id):
"""List imported backup policies by id"""
cmd = listBackupPolicies.listBackupPoliciesCmd()
cmd.id = id
return (apiclient.listBackupPolicies(cmd))
@classmethod
def listInternal(self, apiclient, zoneid):
"""List imported backup policies"""
@ -5418,11 +5426,20 @@ class BackupPolicy:
cmd.id = self.id
return (apiclient.deleteBackupPolicy(cmd))
def assignVM(self, apiclient, vmid, zoneid):
"""Assign a VM to a backup policy"""
def addVM(self, apiclient, vmid, zoneid):
"""Add a VM to a backup policy"""
cmd = assignBackupPolicy.assignBackupPolicyCmd()
cmd = addVirtualMachineToBackupPolicy.addVirtualMachineToBackupPolicyCmd()
cmd.backuppolicyid = self.id
cmd.virtualmachineid = vmid
cmd.zoneid = zoneid
return (apiclient.assignBackupPolicy(cmd))
return (apiclient.addVirtualMachineToBackupPolicy(cmd))
def removeVM(self, apiclient, vmid, zoneid):
"""Remove a VM from a backup policy"""
cmd = removeVirtualMachineFromBackupPolicy.removeVirtualMachineFromBackupPolicyCmd()
cmd.backuppolicyid = self.id
cmd.virtualmachineid = vmid
cmd.zoneid = zoneid
return (apiclient.removeVirtualMachineFromBackupPolicy(cmd))