Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion api/src/main/java/com/cloud/projects/ProjectService.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public interface ProjectService {
* - project id
* @return true if the project was deleted successfully, false otherwise
*/
boolean deleteProject(long id);
boolean deleteProject(long id, Boolean cleanup);

/**
* Gets a project by id
Expand Down
2 changes: 1 addition & 1 deletion api/src/main/java/com/cloud/storage/VolumeApiService.java
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ Snapshot takeSnapshot(Long volumeId, Long policyId, Long snapshotId, Account acc

Snapshot allocSnapshot(Long volumeId, Long policyId, String snapshotName, Snapshot.LocationType locationType) throws ResourceAllocationException;

Volume updateVolume(long volumeId, String path, String state, Long storageId, Boolean displayVolume, String customId, long owner, String chainInfo);
Volume updateVolume(long volumeId, String path, String state, Long storageId, Boolean displayVolume, String customId, long owner, String chainInfo, String name);

/**
* Extracts the volume to a particular location.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ public class DeleteProjectCmd extends BaseAsyncCmd {
@Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = ProjectResponse.class, required = true, description = "id of the project to be deleted")
private Long id;

@Parameter(name = ApiConstants.CLEANUP, type = CommandType.BOOLEAN, description = "true if all project resources have to be cleaned up, false otherwise")
private Boolean cleanup;

/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
Expand All @@ -56,6 +59,10 @@ public Long geId() {
return id;
}

public Boolean isCleanup() {
return cleanup;
}

@Override
public String getCommandName() {
return s_name;
Expand All @@ -68,7 +75,7 @@ public String getCommandName() {
@Override
public void execute() {
CallContext.current().setEventDetails("Project Id: " + id);
boolean result = _projectService.deleteProject(id);
boolean result = _projectService.deleteProject(id, isCleanup());
if (result) {
SuccessResponse response = new SuccessResponse(getCommandName());
this.setResponseObject(response);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,30 +52,33 @@ public class UpdateVolumeCmd extends BaseAsyncCustomIdCmd implements UserCmd {
@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, description = "The path of the volume")
@Parameter(name = ApiConstants.PATH, type = CommandType.STRING, description = "The path of the volume", authorized = {RoleType.Admin})
private String path;

@Parameter(name = ApiConstants.CHAIN_INFO,
type = CommandType.STRING,
description = "The chain info of the volume",
since = "4.4")
since = "4.4", authorized = {RoleType.Admin})
private String chainInfo;

@Parameter(name = ApiConstants.STORAGE_ID,
type = CommandType.UUID,
entityType = StoragePoolResponse.class,
description = "Destination storage pool UUID for the volume",
since = "4.3")
since = "4.3", authorized = {RoleType.Admin})
private Long storageId;

@Parameter(name = ApiConstants.STATE, type = CommandType.STRING, description = "The state of the volume", since = "4.3")
@Parameter(name = ApiConstants.STATE, type = CommandType.STRING, description = "The state of the volume", since = "4.3", authorized = {RoleType.Admin})
private String state;

@Parameter(name = ApiConstants.DISPLAY_VOLUME,
type = CommandType.BOOLEAN,
description = "an optional field, whether to the display the volume to the end user or not.", authorized = {RoleType.Admin})
private Boolean displayVolume;

@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "new name of the volume", since = "4.16")
private String name;

/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
Expand Down Expand Up @@ -103,6 +106,11 @@ public Boolean getDisplayVolume() {
public String getChainInfo() {
return chainInfo;
}

public String getName() {
return name;
}

/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
Expand Down Expand Up @@ -150,14 +158,19 @@ public String getEventDescription() {
if (getState() != null) {
desc.append(", state " + getState());
}

if (getName() != null) {
desc.append(", name " + getName());
}

return desc.toString();
}

@Override
public void execute() {
CallContext.current().setEventDetails("Volume Id: " + this._uuidMgr.getUuid(Volume.class, getId()));
Volume result = _volumeService.updateVolume(getId(), getPath(), getState(), getStorageId(), getDisplayVolume(),
getCustomId(), getEntityOwnerId(), getChainInfo());
getCustomId(), getEntityOwnerId(), getChainInfo(), getName());
if (result != null) {
VolumeResponse response = _responseGenerator.createVolumeResponse(getResponseView(), result);
response.setResponseName(getCommandName());
Expand Down
51 changes: 49 additions & 2 deletions server/src/main/java/com/cloud/projects/ProjectManagerImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import javax.inject.Inject;
import javax.mail.Authenticator;
Expand All @@ -40,6 +41,18 @@
import javax.mail.internet.InternetAddress;
import javax.naming.ConfigurationException;

import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkVO;
import com.cloud.network.vpc.Vpc;
import com.cloud.network.vpc.VpcManager;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.storage.dao.VolumeDao;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.snapshot.VMSnapshotVO;
import com.cloud.vm.snapshot.dao.VMSnapshotDao;
import org.apache.cloudstack.acl.ProjectRole;
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
import org.apache.cloudstack.acl.dao.ProjectRoleDao;
Expand Down Expand Up @@ -131,6 +144,18 @@ public class ProjectManagerImpl extends ManagerBase implements ProjectManager {
private ProjectRoleDao projectRoleDao;
@Inject
private UserDao userDao;
@Inject
private VolumeDao _volumeDao;
@Inject
private UserVmDao _userVmDao;
@Inject
private VMTemplateDao _templateDao;
@Inject
private NetworkDao _networkDao;
@Inject
private VMSnapshotDao _vmSnapshotDao;
@Inject
private VpcManager _vpcMgr;

protected boolean _invitationRequired = false;
protected long _invitationTimeOut = 86400000;
Expand Down Expand Up @@ -301,7 +326,7 @@ public Project enableProject(long projectId) {

@Override
@ActionEvent(eventType = EventTypes.EVENT_PROJECT_DELETE, eventDescription = "deleting project", async = true)
public boolean deleteProject(long projectId) {
public boolean deleteProject(long projectId, Boolean isCleanup) {
CallContext ctx = CallContext.current();

ProjectVO project = getProject(projectId);
Expand All @@ -313,7 +338,29 @@ public boolean deleteProject(long projectId) {
CallContext.current().setProject(project);
_accountMgr.checkAccess(ctx.getCallingAccount(), AccessType.ModifyProject, true, _accountMgr.getAccount(project.getProjectAccountId()));

return deleteProject(ctx.getCallingAccount(), ctx.getCallingUserId(), project);
if (isCleanup != null && isCleanup) {
return deleteProject(ctx.getCallingAccount(), ctx.getCallingUserId(), project);
} else {
List<VMTemplateVO> userTemplates = _templateDao.listByAccountId(project.getProjectAccountId());
List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.listByAccountId(project.getProjectAccountId());
List<UserVmVO> vms = _userVmDao.listByAccountId(project.getProjectAccountId());
List<VolumeVO> volumes = _volumeDao.findDetachedByAccount(project.getProjectAccountId());
List<NetworkVO> networks = _networkDao.listByOwner(project.getProjectAccountId());
List<? extends Vpc> vpcs = _vpcMgr.getVpcsForAccount(project.getProjectAccountId());

Optional<String> message = Stream.of(userTemplates, vmSnapshots, vms, volumes, networks, vpcs)
.filter(entity -> !entity.isEmpty())
.map(entity -> entity.size() + " " + entity.get(0).getEntityType().getSimpleName() + " to clean up")
.findFirst();

if (message.isEmpty()) {
return deleteProject(ctx.getCallingAccount(), ctx.getCallingUserId(), project);
}

CloudRuntimeException e = new CloudRuntimeException("Can't delete the project yet because it has " + message.get());
e.addProxyObject(project.getUuid(), "projectId");
throw e;
}
}

@DB
Expand Down
14 changes: 13 additions & 1 deletion server/src/main/java/com/cloud/storage/VolumeApiServiceImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -1763,7 +1763,15 @@ public Volume attachVolumeToVM(Long vmId, Long volumeId, Long deviceId) {

@Override
@ActionEvent(eventType = EventTypes.EVENT_VOLUME_UPDATE, eventDescription = "updating volume", async = true)
public Volume updateVolume(long volumeId, String path, String state, Long storageId, Boolean displayVolume, String customId, long entityOwnerId, String chainInfo) {
public Volume updateVolume(long volumeId, String path, String state, Long storageId, Boolean displayVolume,
String customId, long entityOwnerId, String chainInfo, String name) {

Account caller = CallContext.current().getCallingAccount();
if (!_accountMgr.isRootAdmin(caller.getId())) {
if (path != null || state != null || storageId != null || displayVolume != null || customId != null || chainInfo != null) {
throw new InvalidParameterValueException("The domain admin and normal user are not allowed to update volume except volume name");
}
}

VolumeVO volume = _volsDao.findById(volumeId);

Expand Down Expand Up @@ -1806,6 +1814,10 @@ public Volume updateVolume(long volumeId, String path, String state, Long storag
volume.setUuid(customId);
}

if (name != null) {
volume.setName(name);
}

updateDisplay(volume, displayVolume);

_volsDao.update(volumeId, volume);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public Project createProject(String name, String displayText, String accountName
}

@Override
public boolean deleteProject(long id) {
public boolean deleteProject(long id, Boolean cleanup) {
// TODO Auto-generated method stub
return false;
}
Expand Down
Loading