mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
CLOUDSTACK-4744: enhanced root admin API updateVolume with state/storageId parameters as a part of "Better control over first party objects" feature.
Also fixed existing bugs for the API: * corrected action event to be VOLUME.UPDATE (was VOLUME.ATTACH) * all parameters to update, should be optional - fixed that. If nothing is specified, the db object will remain with its original fields
This commit is contained in:
parent
b998fba4da
commit
43770e0cb2
@ -188,6 +188,8 @@ public class EventTypes {
|
||||
public static final String EVENT_VOLUME_DETAIL_UPDATE = "VOLUME.DETAIL.UPDATE";
|
||||
public static final String EVENT_VOLUME_DETAIL_ADD = "VOLUME.DETAIL.ADD";
|
||||
public static final String EVENT_VOLUME_DETAIL_REMOVE = "VOLUME.DETAIL.REMOVE";
|
||||
public static final String EVENT_VOLUME_UPDATE = "VOLUME.UPDATE";
|
||||
|
||||
|
||||
// Domains
|
||||
public static final String EVENT_DOMAIN_CREATE = "DOMAIN.CREATE";
|
||||
|
||||
@ -84,7 +84,7 @@ public interface VolumeApiService {
|
||||
|
||||
Snapshot allocSnapshot(Long volumeId, Long policyId)
|
||||
throws ResourceAllocationException;
|
||||
Volume updateVolume(UpdateVolumeCmd updateVolumeCmd);
|
||||
Volume updateVolume(long volumeId, String path, String state, Long storageId);
|
||||
|
||||
/**
|
||||
* Extracts the volume to a particular location.
|
||||
|
||||
@ -23,15 +23,14 @@ import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseAsyncCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||
import org.apache.cloudstack.api.response.StoragePoolResponse;
|
||||
import org.apache.cloudstack.api.response.VolumeResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.storage.Volume;
|
||||
import com.cloud.user.Account;
|
||||
|
||||
@APICommand(name = "updateVolume", description="Updates the volume.", responseObject=VolumeResponse.class)
|
||||
public class UpdateVolumeCmd extends BaseAsyncCmd {
|
||||
@ -42,13 +41,18 @@ public class UpdateVolumeCmd extends BaseAsyncCmd {
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=VolumeResponse.class,
|
||||
required=true, description="the ID of the disk volume")
|
||||
@Parameter(name=ApiConstants.ID, type=CommandType.UUID, entityType=VolumeResponse.class, description="the ID of the disk volume")
|
||||
private Long id;
|
||||
|
||||
@Parameter(name=ApiConstants.PATH, type=CommandType.STRING,
|
||||
required=true, description="the path of the volume")
|
||||
@Parameter(name=ApiConstants.PATH, type=CommandType.STRING, description="The path of the volume")
|
||||
private String path;
|
||||
|
||||
@Parameter(name=ApiConstants.STORAGE_ID, type=CommandType.UUID, entityType=StoragePoolResponse.class,
|
||||
description="Destination storage pool UUID for the volume", since="4.3")
|
||||
private Long storageId;
|
||||
|
||||
@Parameter(name=ApiConstants.STATE, type=CommandType.STRING, description="The state of the volume", since="4.3")
|
||||
private String state;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
@ -61,6 +65,15 @@ public class UpdateVolumeCmd extends BaseAsyncCmd {
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public Long getStorageId() {
|
||||
return storageId;
|
||||
}
|
||||
|
||||
public String getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
@ -83,25 +96,37 @@ public class UpdateVolumeCmd extends BaseAsyncCmd {
|
||||
public long getEntityOwnerId() {
|
||||
Volume volume = _responseGenerator.findVolumeById(getId());
|
||||
if (volume == null) {
|
||||
return Account.ACCOUNT_ID_SYSTEM; // bad id given, parent this command to SYSTEM so ERROR events are tracked
|
||||
throw new InvalidParameterValueException("Invalid volume id was provided");
|
||||
}
|
||||
return volume.getAccountId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventType() {
|
||||
return EventTypes.EVENT_VOLUME_ATTACH;
|
||||
return EventTypes.EVENT_VOLUME_UPDATE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
return "adding detail to the volume: " + getId();
|
||||
StringBuffer desc = new StringBuffer();
|
||||
desc.append(" with");
|
||||
if (getPath() != null) {
|
||||
desc.append(" path " + getPath());
|
||||
}
|
||||
if (getStorageId() != null) {
|
||||
desc.append(", storage id " + getStorageId());
|
||||
}
|
||||
|
||||
if (getState() != null) {
|
||||
desc.append(", state " + getState());
|
||||
}
|
||||
return "Updating volume: " + getId() + desc.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(){
|
||||
CallContext.current().setEventDetails("Volume Id: "+getId());
|
||||
Volume result = _volumeService.updateVolume(this);
|
||||
Volume result = _volumeService.updateVolume(getId(), getPath(), getState(), getStorageId());
|
||||
if (result != null) {
|
||||
VolumeResponse response = _responseGenerator.createVolumeResponse(result);
|
||||
response.setResponseName(getCommandName());
|
||||
|
||||
@ -35,6 +35,7 @@ import javax.persistence.Transient;
|
||||
import com.cloud.storage.Storage.StoragePoolType;
|
||||
import com.cloud.utils.NumbersUtil;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import com.cloud.vm.VirtualMachine.State;
|
||||
|
||||
@Entity
|
||||
@Table(name = "volumes")
|
||||
@ -573,4 +574,10 @@ public class VolumeVO implements Volume {
|
||||
public void setIsoId(long isoId) {
|
||||
this.isoId =isoId;
|
||||
}
|
||||
|
||||
// don't use this directly, use volume state machine instead
|
||||
// This method is used by UpdateVolume as a part of "Better control over first class objects in CS"
|
||||
public void setState(State state) {
|
||||
this.state = state;
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,8 +25,6 @@ import java.util.concurrent.ExecutionException;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd;
|
||||
import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd;
|
||||
@ -34,7 +32,6 @@ import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd;
|
||||
import org.apache.cloudstack.api.command.user.volume.ExtractVolumeCmd;
|
||||
import org.apache.cloudstack.api.command.user.volume.MigrateVolumeCmd;
|
||||
import org.apache.cloudstack.api.command.user.volume.ResizeVolumeCmd;
|
||||
import org.apache.cloudstack.api.command.user.volume.UpdateVolumeCmd;
|
||||
import org.apache.cloudstack.api.command.user.volume.UploadVolumeCmd;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.engine.orchestration.service.VolumeOrchestrationService;
|
||||
@ -67,6 +64,7 @@ import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
|
||||
import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
|
||||
import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
import com.cloud.agent.api.Answer;
|
||||
@ -1108,16 +1106,32 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
|
||||
}
|
||||
|
||||
@Override
|
||||
public Volume updateVolume(UpdateVolumeCmd cmd) {
|
||||
Long volumeId = cmd.getId();
|
||||
String path = cmd.getPath();
|
||||
|
||||
if (path == null) {
|
||||
throw new InvalidParameterValueException("Failed to update the volume as path was null");
|
||||
@ActionEvent(eventType = EventTypes.EVENT_VOLUME_UPDATE, eventDescription = "updating volume", async = true)
|
||||
public Volume updateVolume(long volumeId, String path, String state, Long storageId) {
|
||||
VolumeVO volume = _volumeDao.findById(volumeId);
|
||||
|
||||
if (path != null) {
|
||||
volume.setPath(path);
|
||||
}
|
||||
|
||||
VolumeVO volume = ApiDBUtils.findVolumeById(volumeId);
|
||||
volume.setPath(path);
|
||||
|
||||
if (state != null) {
|
||||
try {
|
||||
Volume.State volumeState = Volume.State.valueOf(state);
|
||||
volume.setState(volumeState);
|
||||
}
|
||||
catch(IllegalArgumentException ex) {
|
||||
throw new InvalidParameterValueException("Invalid volume state specified");
|
||||
}
|
||||
}
|
||||
|
||||
if (storageId != null) {
|
||||
StoragePool pool = _storagePoolDao.findById(storageId);
|
||||
if (pool.getDataCenterId() != volume.getDataCenterId()) {
|
||||
throw new InvalidParameterValueException("Invalid storageId specified; refers to the pool outside of the volume's zone");
|
||||
}
|
||||
volume.setPoolId(pool.getId());
|
||||
}
|
||||
|
||||
_volumeDao.update(volumeId, volume);
|
||||
|
||||
return volume;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user