use of com.emc.storageos.db.client.model.BlockSnapshot in project coprhd-controller by CoprHD.
the class SnapshotService method deleteSnapshot.
/**
* Delete a specific snapshot
*
* @prereq none
*
* @param tenant_id
* the URN of the tenant
* @param snapshot_id
* the URN of the snapshot
*
* @brief Delete Snapshot
* @return Task result
*/
@DELETE
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Path("/{snapshot_id}")
@CheckPermission(roles = { Role.SYSTEM_MONITOR, Role.TENANT_ADMIN }, acls = { ACL.ANY })
public Response deleteSnapshot(@PathParam("tenant_id") String openstack_tenant_id, @PathParam("snapshot_id") String snapshot_id) {
_log.info("Delete Snapshot: id = {}", snapshot_id);
BlockSnapshot snap = findSnapshot(snapshot_id, openstack_tenant_id);
if (snap == null) {
_log.error("Not Found : Invalid volume snapshot id");
return CinderApiUtils.createErrorResponse(404, "Not Found : Invalid volume snapshot id");
} else if (snap.hasConsistencyGroup()) {
_log.error("Not Found : Snapshot belongs to a consistency group");
return CinderApiUtils.createErrorResponse(400, "Invalid snapshot: Snapshot belongs to consistency group");
}
URI snapshotURI = snap.getId();
String task = UUID.randomUUID().toString();
TaskList response = new TaskList();
ArgValidator.checkReference(BlockSnapshot.class, snapshotURI, checkForDelete(snap));
// Not an error if the snapshot we try to delete is already deleted
if (snap.getInactive()) {
Operation op = new Operation();
op.ready("The snapshot has already been deleted");
op.setResourceType(ResourceOperationTypeEnum.DELETE_VOLUME_SNAPSHOT);
_dbClient.createTaskOpStatus(BlockSnapshot.class, snap.getId(), task, op);
response.getTaskList().add(toTask(snap, task, op));
return Response.status(202).build();
}
StorageSystem device = _dbClient.queryObject(StorageSystem.class, snap.getStorageController());
List<BlockSnapshot> snapshots = new ArrayList<BlockSnapshot>();
final URI cgId = snap.getConsistencyGroup();
if (!NullColumnValueGetter.isNullURI(cgId)) {
// Collect all the BlockSnapshots if part of a CG.
URIQueryResultList results = new URIQueryResultList();
_dbClient.queryByConstraint(AlternateIdConstraint.Factory.getBlockSnapshotsBySnapsetLabel(snap.getSnapsetLabel()), results);
while (results.iterator().hasNext()) {
URI uri = results.iterator().next();
_log.info("BlockSnapshot being deactivated: " + uri);
BlockSnapshot snapshot = _dbClient.queryObject(BlockSnapshot.class, uri);
if (snapshot != null) {
snapshots.add(snapshot);
}
}
} else {
// Snap is not part of a CG so only delete the snap
snapshots.add(snap);
}
for (BlockSnapshot snapshot : snapshots) {
Operation snapOp = _dbClient.createTaskOpStatus(BlockSnapshot.class, snapshot.getId(), task, ResourceOperationTypeEnum.DELETE_VOLUME_SNAPSHOT);
response.getTaskList().add(toTask(snapshot, task, snapOp));
}
// Note that for snapshots of VPLEX volumes, the parent volume for the
// snapshot is the source side backend volume, which will have the same
// vpool as the VPLEX volume and therefore, the correct implementation
// should be returned.
Volume volume = _permissionsHelper.getObjectById(snap.getParent(), Volume.class);
BlockServiceApi blockServiceApiImpl = BlockService.getBlockServiceImpl(volume, _dbClient);
blockServiceApiImpl.deleteSnapshot(snap, snapshots, task, VolumeDeleteTypeEnum.FULL.name());
StringMap extensions = snap.getExtensions();
if (extensions == null) {
extensions = new StringMap();
}
for (TaskResourceRep rep : response.getTaskList()) {
extensions.put("taskid", rep.getId().toString());
break;
}
snap.setExtensions(extensions);
_dbClient.updateObject(snap);
auditOp(OperationTypeEnum.DELETE_VOLUME_SNAPSHOT, true, AuditLogManager.AUDITOP_BEGIN, snapshot_id, snap.getLabel(), snap.getParent().getName(), device.getId().toString());
return Response.status(202).build();
}
use of com.emc.storageos.db.client.model.BlockSnapshot in project coprhd-controller by CoprHD.
the class VPlexBlockServiceApiImpl method changeVirtualArrayForVolumes.
/**
* {@inheritDoc}
*/
@Override
public void changeVirtualArrayForVolumes(List<Volume> volumes, BlockConsistencyGroup cg, List<Volume> cgVolumes, VirtualArray newVirtualArray, String taskId) throws InternalException {
// if they remove the snapshots, they can perform the varray change.
for (Volume volume : volumes) {
List<BlockSnapshot> snapshots = getSnapshots(volume);
if (!snapshots.isEmpty()) {
for (BlockSnapshot snapshot : snapshots) {
if (!snapshot.getInactive()) {
throw APIException.badRequests.volumeForVarrayChangeHasSnaps(volume.getId().toString());
}
}
}
// If the volume has mirrors then varray change will not
// be allowed. User needs to explicitly delete mirrors first.
// This is applicable for both Local and Distributed volumes.
// For distributed volume getMirrors will get mirror if any
// on source or HA side.
StringSet mirrorURIs = volume.getMirrors();
if (mirrorURIs != null && !mirrorURIs.isEmpty()) {
List<VplexMirror> mirrors = _dbClient.queryObject(VplexMirror.class, StringSetUtil.stringSetToUriList(mirrorURIs));
if (mirrors != null && !mirrors.isEmpty()) {
throw APIException.badRequests.volumeForVarrayChangeHasMirrors(volume.getId().toString(), volume.getLabel());
}
}
}
// vpool change.
if ((cg != null) && (volumes.size() > _maxCgVolumesForMigration)) {
throw APIException.badRequests.cgContainsTooManyVolumesForVArrayChange(cg.getLabel(), volumes.size(), _maxCgVolumesForMigration);
}
// we don't allow the varray change.
if ((cg != null) && (cg.checkForType(Types.LOCAL)) && (cgVolumes.size() > 1)) {
verifyTargetSystemsForCGDataMigration(volumes, null, newVirtualArray.getId());
}
// Create the volume descriptors for the virtual array change.
List<VolumeDescriptor> descriptors = createVolumeDescriptorsForVarrayChange(volumes, newVirtualArray, taskId);
try {
// Orchestrate the virtual array change.
BlockOrchestrationController controller = getController(BlockOrchestrationController.class, BlockOrchestrationController.BLOCK_ORCHESTRATION_DEVICE);
controller.changeVirtualArray(descriptors, taskId);
s_logger.info("Successfully invoked block orchestrator.");
} catch (InternalException e) {
s_logger.error("Controller error", e);
for (VolumeDescriptor descriptor : descriptors) {
// migration targets and migrations.
if (VolumeDescriptor.Type.VPLEX_MIGRATE_VOLUME.equals(descriptor.getType())) {
_dbClient.error(Volume.class, descriptor.getVolumeURI(), taskId, e);
_dbClient.error(Migration.class, descriptor.getMigrationId(), taskId, e);
}
}
throw e;
}
}
use of com.emc.storageos.db.client.model.BlockSnapshot in project coprhd-controller by CoprHD.
the class VPlexBlockServiceApiImpl method updateConsistencyGroup.
/**
* {@inheritDoc}
*/
@Override
public TaskResourceRep updateConsistencyGroup(StorageSystem cgStorageSystem, List<Volume> cgVolumes, BlockConsistencyGroup consistencyGroup, List<URI> addVolumesList, List<URI> removeVolumesList, String taskId) throws ControllerException {
// addVolumesList could be volumes, or full copies, or snapshots or mirrors.
List<URI> addVolumes = new ArrayList<URI>();
List<URI> addSnapshots = new ArrayList<URI>();
List<URI> addFullcopies = new ArrayList<URI>();
for (URI volumeURI : addVolumesList) {
BlockObject blockObject = BlockObject.fetch(_dbClient, volumeURI);
if (blockObject instanceof BlockMirror) {
throw APIException.badRequests.actionNotApplicableForVplexVolumeMirrors(ResourceOperationTypeEnum.UPDATE_CONSISTENCY_GROUP.name());
} else if (blockObject instanceof BlockSnapshot) {
addSnapshots.add(volumeURI);
} else if (blockObject instanceof Volume) {
boolean isFullCopy = ControllerUtils.isVolumeFullCopy((Volume) blockObject, _dbClient);
if (isFullCopy) {
addFullcopies.add(volumeURI);
} else {
addVolumes.add(volumeURI);
}
}
}
if ((!addVolumes.isEmpty() && (!addSnapshots.isEmpty() || !addFullcopies.isEmpty())) || (!addSnapshots.isEmpty() && !addFullcopies.isEmpty())) {
throw APIException.badRequests.cantUpdateCGWithMixedBlockObjects(consistencyGroup.getLabel());
}
// group.
if (!addVolumes.isEmpty()) {
Iterator<Volume> cgVolumesIter = cgVolumes.iterator();
if (cgVolumesIter.hasNext()) {
Volume cgVolume = cgVolumesIter.next();
VirtualPool cgVPool = _permissionsHelper.getObjectById(cgVolume.getVirtualPool(), VirtualPool.class);
URI cgVArrayURI = cgVolume.getVirtualArray();
String cgHAType = cgVPool.getHighAvailability();
for (URI volumeURI : addVolumes) {
Volume addVolume = _permissionsHelper.getObjectById(volumeURI, Volume.class);
VirtualPool addVolumeVPool = _permissionsHelper.getObjectById(addVolume.getVirtualPool(), VirtualPool.class);
if (!addVolumeVPool.getHighAvailability().equals(cgHAType)) {
throw APIException.badRequests.invalidParameterConsistencyGroupVolumeHasIncorrectHighAvailability(cgVolume.getId(), cgHAType);
} else if (!cgVArrayURI.equals(addVolume.getVirtualArray())) {
throw APIException.badRequests.invalidParameterConsistencyGroupVolumeHasIncorrectVArray(cgVolume.getId(), cgVArrayURI);
}
}
}
// Check if the volumes have been in the CG, and not ingestion case
if (consistencyGroup.getTypes().contains(Types.LOCAL.toString()) && !cgVolumes.isEmpty()) {
Set<String> cgVolumesURISet = new HashSet<String>();
for (Volume cgVolume : cgVolumes) {
cgVolumesURISet.add(cgVolume.getId().toString());
}
Iterator<URI> iter = addVolumes.iterator();
while (iter.hasNext()) {
if (cgVolumesURISet.contains(iter.next().toString())) {
iter.remove();
}
}
if (addVolumes.isEmpty()) {
// All volumes in the addVolumes list have been in the CG. return success
s_logger.info("The volumes have been added to the CG");
Operation op = new Operation();
op.setResourceType(ResourceOperationTypeEnum.UPDATE_CONSISTENCY_GROUP);
op.ready("Volumes have been added to the consistency group");
_dbClient.createTaskOpStatus(BlockConsistencyGroup.class, consistencyGroup.getId(), taskId, op);
return toTask(consistencyGroup, taskId, op);
}
}
}
// Only add snapshot or full copies to CG if backend volumes are from the same storage system.
if (!addSnapshots.isEmpty() || !addFullcopies.isEmpty()) {
if (!VPlexUtil.isVPLEXCGBackendVolumesInSameStorage(cgVolumes, _dbClient)) {
throw APIException.badRequests.cantUpdateCGWithReplicaFromMultipleSystems(consistencyGroup.getLabel());
}
}
Operation op = _dbClient.createTaskOpStatus(BlockConsistencyGroup.class, consistencyGroup.getId(), taskId, ResourceOperationTypeEnum.UPDATE_CONSISTENCY_GROUP);
// When adding snapshots to CG, just call block implementation.
if (!addSnapshots.isEmpty()) {
BlockSnapshot snapshot = _permissionsHelper.getObjectById(addSnapshots.get(0), BlockSnapshot.class);
URI systemURI = snapshot.getStorageController();
StorageSystem system = _permissionsHelper.getObjectById(systemURI, StorageSystem.class);
BlockController controller = getController(BlockController.class, system.getSystemType());
controller.updateConsistencyGroup(system.getId(), consistencyGroup.getId(), addVolumesList, removeVolumesList, taskId);
return toTask(consistencyGroup, taskId, op);
}
// all the virtual volumes in the CG have to be selected.
if (!addVolumes.isEmpty()) {
verifyAddVolumesToIngestedCG(consistencyGroup, addVolumes);
}
if (!addFullcopies.isEmpty()) {
addVolumes.addAll(addFullcopies);
}
// Get VPlex controller
VPlexController controller = getController();
controller.updateConsistencyGroup(cgStorageSystem.getId(), consistencyGroup.getId(), addVolumes, removeVolumesList, taskId);
return toTask(consistencyGroup, taskId, op);
}
use of com.emc.storageos.db.client.model.BlockSnapshot in project coprhd-controller by CoprHD.
the class BlockSnapshotSessionUtils method querySnapshotSessionSource.
/**
* Returns the volume or block snapshot instance for the passed URI.
*
* @param sourceURI The URI for the Volume or BlockSnapshot instance.
* @param uriInfo A reference to the URI information.
* @param checkAssociatedVolumes check if the passed source is an associated volume for another volume.
* @param dbClient A reference to a database client.
*
* @return A reference to the block object.
*/
public static BlockObject querySnapshotSessionSource(URI sourceURI, UriInfo uriInfo, boolean checkAssociatedVolumes, DbClient dbClient) {
ArgValidator.checkUri(sourceURI);
if ((!URIUtil.isType(sourceURI, Volume.class)) && (!URIUtil.isType(sourceURI, BlockSnapshot.class))) {
throw APIException.badRequests.invalidSnapshotSessionSource(sourceURI.toString());
}
BlockObject sourceObj = BlockObject.fetch(dbClient, sourceURI);
ArgValidator.checkEntity(sourceObj, sourceURI, BlockServiceUtils.isIdEmbeddedInURL(sourceURI, uriInfo), true);
// is returned.
if (URIUtil.isType(sourceURI, Volume.class) && (checkAssociatedVolumes)) {
List<Volume> volumes = CustomQueryUtility.queryActiveResourcesByConstraint(dbClient, Volume.class, AlternateIdConstraint.Factory.getVolumeByAssociatedVolumesConstraint(sourceURI.toString()));
if (!volumes.isEmpty()) {
sourceObj = volumes.get(0);
}
}
return sourceObj;
}
use of com.emc.storageos.db.client.model.BlockSnapshot in project coprhd-controller by CoprHD.
the class BlockSnapshotSessionUtils method querySnapshotSessionSourceProject.
/**
* Returns the project for the snapshot session source.
*
* @param sourceObj A reference to the Volume or BlockSnapshot instance.
* @param dbClient A reference to a database client.
*
* @return A reference to the project for the snapshot session source.
*/
public static Project querySnapshotSessionSourceProject(BlockObject sourceObj, DbClient dbClient) {
URI sourceURI = sourceObj.getId();
URI projectURI = null;
if (URIUtil.isType(sourceURI, Volume.class)) {
projectURI = ((Volume) sourceObj).getProject().getURI();
} else if (URIUtil.isType(sourceURI, BlockSnapshot.class)) {
projectURI = ((BlockSnapshot) sourceObj).getProject().getURI();
}
if (projectURI == null) {
throw APIException.badRequests.invalidSnapshotSessionSource(sourceURI.toString());
}
Project project = dbClient.queryObject(Project.class, projectURI);
return project;
}
Aggregations