mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Merge release branch 4.6 to master
* 4.6: CLOUDSTACK-9075 - Uses the same vlan since it should have been already released CLOUDSTACK-9075 - Adds VPC static routes test CLOUDSTACK-9075 - Covers Private GW ACL with Redundant VPCs CLOUDSTACK-9075 - Add method to get list of Physical Networks per zone CLOUDSTACK-6276 Removing unused parameter in integration test for projects CLOUDSTACK-6276 Removing unused parameter in integration test CLOUDSTACK-6276 Fixing affinity groups for projects
This commit is contained in:
commit
7e902cd505
@ -56,12 +56,20 @@ public class AffinityGroupResponse extends BaseResponse implements ControlledVie
|
||||
@Param(description = "the domain name of the affinity group")
|
||||
private String domainName;
|
||||
|
||||
@SerializedName(ApiConstants.PROJECT_ID)
|
||||
@Param(description = "the project ID of the affinity group")
|
||||
private String projectId;
|
||||
|
||||
@SerializedName(ApiConstants.PROJECT)
|
||||
@Param(description = "the project name of the affinity group")
|
||||
private String projectName;
|
||||
|
||||
@SerializedName(ApiConstants.TYPE)
|
||||
@Param(description = "the type of the affinity group")
|
||||
private String type;
|
||||
|
||||
@SerializedName("virtualmachineIds")
|
||||
@Param(description = "virtual machine Ids associated with this affinity group ")
|
||||
@Param(description = "virtual machine IDs associated with this affinity group")
|
||||
private List<String> vmIdList;
|
||||
|
||||
public AffinityGroupResponse() {
|
||||
@ -134,14 +142,12 @@ public class AffinityGroupResponse extends BaseResponse implements ControlledVie
|
||||
|
||||
@Override
|
||||
public void setProjectId(String projectId) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
this.projectId = projectId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProjectName(String projectName) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
this.projectName = projectName;
|
||||
}
|
||||
|
||||
public void setVMIdList(List<String> vmIdList) {
|
||||
|
||||
@ -18,47 +18,36 @@ package org.apache.cloudstack.affinity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.api.command.user.affinitygroup.CreateAffinityGroupCmd;
|
||||
|
||||
import com.cloud.uservm.UserVm;
|
||||
import com.cloud.utils.Pair;
|
||||
|
||||
public interface AffinityGroupService {
|
||||
|
||||
/**
|
||||
* Creates an affinity/anti-affinity group for the given account/domain.
|
||||
*
|
||||
* @param account
|
||||
* @param accountName
|
||||
* @param projectId
|
||||
* @param domainId
|
||||
* @param name
|
||||
* @param type
|
||||
* @param affinityGroupName
|
||||
* @param affinityGroupType
|
||||
* @param description
|
||||
* @return AffinityGroup
|
||||
*/
|
||||
AffinityGroup createAffinityGroup(String accountName, Long projectId, Long domainId, String affinityGroupName, String affinityGroupType, String description);
|
||||
|
||||
AffinityGroup createAffinityGroup(String account, Long domainId, String affinityGroupName, String affinityGroupType, String description);
|
||||
AffinityGroup createAffinityGroup(CreateAffinityGroupCmd createAffinityGroupCmd);
|
||||
|
||||
/**
|
||||
* Creates an affinity/anti-affinity group.
|
||||
*
|
||||
* @param affinityGroupId
|
||||
* @param account
|
||||
* @param accountName
|
||||
* @param domainId
|
||||
* @param affinityGroupName
|
||||
*/
|
||||
boolean deleteAffinityGroup(Long affinityGroupId, String account, Long domainId, String affinityGroupName);
|
||||
|
||||
/** Lists Affinity Groups in your account
|
||||
* @param account
|
||||
* @param domainId
|
||||
* @param affinityGroupId
|
||||
* @param affinityGroupName
|
||||
* @param affinityGroupType
|
||||
* @param vmId
|
||||
* @param startIndex
|
||||
* @param pageSize
|
||||
* @return
|
||||
*/
|
||||
Pair<List<? extends AffinityGroup>, Integer> listAffinityGroups(Long affinityGroupId, String affinityGroupName, String affinityGroupType, Long vmId, Long startIndex,
|
||||
Long pageSize);
|
||||
boolean deleteAffinityGroup(Long affinityGroupId, String accountName, Long projectId, Long domainId, String affinityGroupName);
|
||||
|
||||
/**
|
||||
* List group types available in deployment
|
||||
@ -77,6 +66,5 @@ public interface AffinityGroupService {
|
||||
|
||||
boolean isAffinityGroupAvailableInDomain(long affinityGroupId, long domainId);
|
||||
|
||||
AffinityGroup createAffinityGroupInternal(String account, Long domainId, String affinityGroupName, String affinityGroupType, String description);
|
||||
|
||||
}
|
||||
|
||||
@ -17,7 +17,6 @@
|
||||
package org.apache.cloudstack.api.command.user.affinitygroup;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.affinity.AffinityGroup;
|
||||
import org.apache.cloudstack.affinity.AffinityGroupResponse;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
@ -28,6 +27,7 @@ import org.apache.cloudstack.api.BaseAsyncCreateCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.DomainResponse;
|
||||
import org.apache.cloudstack.api.response.ProjectResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
|
||||
import com.cloud.event.EventTypes;
|
||||
@ -54,6 +54,12 @@ public class CreateAffinityGroupCmd extends BaseAsyncCreateCmd {
|
||||
entityType = DomainResponse.class)
|
||||
private Long domainId;
|
||||
|
||||
@Parameter(name = ApiConstants.PROJECT_ID,
|
||||
type = CommandType.UUID,
|
||||
entityType = ProjectResponse.class,
|
||||
description = "create affinity group for project")
|
||||
private Long projectId;
|
||||
|
||||
@Parameter(name = ApiConstants.DESCRIPTION, type = CommandType.STRING, description = "optional description of the affinity group")
|
||||
private String description;
|
||||
|
||||
@ -90,6 +96,10 @@ public class CreateAffinityGroupCmd extends BaseAsyncCreateCmd {
|
||||
return affinityGroupType;
|
||||
}
|
||||
|
||||
public Long getProjectId() {
|
||||
return projectId;
|
||||
}
|
||||
|
||||
// ///////////////////////////////////////////////////
|
||||
// ///////////// API Implementation///////////////////
|
||||
// ///////////////////////////////////////////////////
|
||||
@ -101,23 +111,17 @@ public class CreateAffinityGroupCmd extends BaseAsyncCreateCmd {
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
Account account = CallContext.current().getCallingAccount();
|
||||
if ((account == null) || _accountService.isAdmin(account.getId())) {
|
||||
if ((domainId != null) && (accountName != null)) {
|
||||
Account userAccount = _responseGenerator.findAccountByNameDomain(accountName, domainId);
|
||||
if (userAccount != null) {
|
||||
return userAccount.getId();
|
||||
}
|
||||
}
|
||||
}
|
||||
Account caller = CallContext.current().getCallingAccount();
|
||||
|
||||
if (account != null) {
|
||||
return account.getId();
|
||||
//For domain wide affinity groups (if the affinity group processor type allows it)
|
||||
if(projectId == null && domainId != null && accountName == null && _accountService.isRootAdmin(caller.getId())){
|
||||
return Account.ACCOUNT_ID_SYSTEM;
|
||||
}
|
||||
|
||||
return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this
|
||||
// command to SYSTEM so ERROR events
|
||||
// are tracked
|
||||
Account owner = _accountService.finalizeOwner(caller, accountName, domainId, projectId);
|
||||
if(owner == null){
|
||||
return caller.getAccountId();
|
||||
}
|
||||
return owner.getAccountId();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -134,7 +138,7 @@ public class CreateAffinityGroupCmd extends BaseAsyncCreateCmd {
|
||||
|
||||
@Override
|
||||
public void create() throws ResourceAllocationException {
|
||||
AffinityGroup result = _affinityGroupService.createAffinityGroup(accountName, domainId, affinityGroupName, affinityGroupType, description);
|
||||
AffinityGroup result = _affinityGroupService.createAffinityGroup(this);
|
||||
if (result != null) {
|
||||
setEntityId(result.getId());
|
||||
setEntityUuid(result.getUuid());
|
||||
|
||||
@ -17,8 +17,8 @@
|
||||
package org.apache.cloudstack.api.command.user.affinitygroup;
|
||||
|
||||
|
||||
import org.apache.cloudstack.api.response.ProjectResponse;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
||||
import org.apache.cloudstack.affinity.AffinityGroup;
|
||||
import org.apache.cloudstack.affinity.AffinityGroupResponse;
|
||||
@ -35,7 +35,6 @@ import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.user.Account;
|
||||
|
||||
@APICommand(name = "deleteAffinityGroup", description = "Deletes affinity group", responseObject = SuccessResponse.class, entityType = {AffinityGroup.class},
|
||||
@ -67,6 +66,9 @@ public class DeleteAffinityGroupCmd extends BaseAsyncCmd {
|
||||
@Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "The name of the affinity group. Mutually exclusive with ID parameter")
|
||||
private String name;
|
||||
|
||||
@Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, description = "the project of the affinity group", entityType = ProjectResponse.class)
|
||||
private Long projectId;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
@ -79,22 +81,11 @@ public class DeleteAffinityGroupCmd extends BaseAsyncCmd {
|
||||
return domainId;
|
||||
}
|
||||
|
||||
public Long getProjectId() {
|
||||
return projectId;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
if (id != null && name != null) {
|
||||
throw new InvalidParameterValueException("name and id parameters are mutually exclusive");
|
||||
}
|
||||
|
||||
if (name != null) {
|
||||
id = _responseGenerator.getAffinityGroupId(name, getEntityOwnerId());
|
||||
if (id == null) {
|
||||
throw new InvalidParameterValueException("Unable to find affinity group by name " + name + " for the account ID=" + getEntityOwnerId());
|
||||
}
|
||||
}
|
||||
|
||||
if (id == null) {
|
||||
throw new InvalidParameterValueException("Either ID or name parameter is required by deleteAffinityGroup command");
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
@ -109,29 +100,22 @@ public class DeleteAffinityGroupCmd extends BaseAsyncCmd {
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
Account account = CallContext.current().getCallingAccount();
|
||||
if ((account == null) || _accountService.isAdmin(account.getId())) {
|
||||
if ((domainId != null) && (accountName != null)) {
|
||||
Account userAccount = _responseGenerator.findAccountByNameDomain(accountName, domainId);
|
||||
if (userAccount != null) {
|
||||
return userAccount.getId();
|
||||
}
|
||||
}
|
||||
Account caller = CallContext.current().getCallingAccount();
|
||||
|
||||
//For domain wide affinity groups (if the affinity group processor type allows it)
|
||||
if(projectId == null && domainId != null && accountName == null && _accountService.isRootAdmin(caller.getId())){
|
||||
return Account.ACCOUNT_ID_SYSTEM;
|
||||
}
|
||||
|
||||
if (account != null) {
|
||||
return account.getId();
|
||||
Account owner = _accountService.finalizeOwner(caller, accountName, domainId, projectId);
|
||||
if(owner == null){
|
||||
return caller.getAccountId();
|
||||
}
|
||||
|
||||
return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this
|
||||
// command to SYSTEM so ERROR events
|
||||
// are tracked
|
||||
|
||||
return owner.getAccountId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
boolean result = _affinityGroupService.deleteAffinityGroup(id, accountName, domainId, name);
|
||||
boolean result = _affinityGroupService.deleteAffinityGroup(id, accountName, projectId, domainId, name);
|
||||
if (result) {
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
setResponseObject(response);
|
||||
|
||||
@ -23,14 +23,14 @@ import org.apache.cloudstack.affinity.AffinityGroupResponse;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiCommandJobType;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseListAccountResourcesCmd;
|
||||
import org.apache.cloudstack.api.BaseListProjectAndAccountResourcesCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.response.ListResponse;
|
||||
import org.apache.cloudstack.api.response.UserVmResponse;
|
||||
|
||||
@APICommand(name = "listAffinityGroups", description = "Lists affinity groups", responseObject = AffinityGroupResponse.class, entityType = {AffinityGroup.class},
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
||||
public class ListAffinityGroupsCmd extends BaseListAccountResourcesCmd {
|
||||
public class ListAffinityGroupsCmd extends BaseListProjectAndAccountResourcesCmd {
|
||||
public static final Logger s_logger = Logger.getLogger(ListAffinityGroupsCmd.class.getName());
|
||||
|
||||
private static final String s_name = "listaffinitygroupsresponse";
|
||||
@ -69,6 +69,10 @@ public class ListAffinityGroupsCmd extends BaseListAccountResourcesCmd {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getAffinityGroupType() {
|
||||
return affinityGroupType;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
@ -80,13 +84,9 @@ public class ListAffinityGroupsCmd extends BaseListAccountResourcesCmd {
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
|
||||
ListResponse<AffinityGroupResponse> response = _queryService.listAffinityGroups(id, affinityGroupName,
|
||||
affinityGroupType, virtualMachineId, getAccountName(), getDomainId(), isRecursive(),
|
||||
listAll(), getStartIndex(), getPageSizeVal(), getKeyword());
|
||||
ListResponse<AffinityGroupResponse> response = _queryService.searchForAffinityGroups(this);
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -31,6 +31,7 @@ import org.apache.cloudstack.api.command.admin.storage.ListStorageTagsCmd;
|
||||
import org.apache.cloudstack.api.command.admin.user.ListUsersCmd;
|
||||
import org.apache.cloudstack.api.command.user.account.ListAccountsCmd;
|
||||
import org.apache.cloudstack.api.command.user.account.ListProjectAccountsCmd;
|
||||
import org.apache.cloudstack.api.command.user.affinitygroup.ListAffinityGroupsCmd;
|
||||
import org.apache.cloudstack.api.command.user.event.ListEventsCmd;
|
||||
import org.apache.cloudstack.api.command.user.iso.ListIsosCmd;
|
||||
import org.apache.cloudstack.api.command.user.job.ListAsyncJobsCmd;
|
||||
@ -131,9 +132,7 @@ public interface QueryService {
|
||||
|
||||
ListResponse<TemplateResponse> listIsos(ListIsosCmd cmd);
|
||||
|
||||
ListResponse<AffinityGroupResponse> listAffinityGroups(Long affinityGroupId, String affinityGroupName,
|
||||
String affinityGroupType, Long vmId, String accountName, Long domainId, boolean isRecursive,
|
||||
boolean listAll, Long startIndex, Long pageSize, String keyword);
|
||||
ListResponse<AffinityGroupResponse> searchForAffinityGroups(ListAffinityGroupsCmd cmd);
|
||||
|
||||
List<ResourceDetailResponse> listResourceDetails(ListResourceDetailsCmd cmd);
|
||||
|
||||
@ -142,5 +141,4 @@ public interface QueryService {
|
||||
ListResponse<StorageTagResponse> searchForStorageTags(ListStorageTagsCmd cmd);
|
||||
|
||||
ListResponse<HostTagResponse> searchForHostTags(ListHostTagsCmd cmd);
|
||||
|
||||
}
|
||||
|
||||
@ -192,7 +192,7 @@ public class VMEntityManagerImpl implements VMEntityManager {
|
||||
try {
|
||||
dest = _dpMgr.planDeployment(vmProfile, plan, exclude, plannerToUse);
|
||||
} catch (AffinityConflictException e) {
|
||||
throw new CloudRuntimeException("Unable to create deployment, affinity rules associted to the VM conflict");
|
||||
throw new CloudRuntimeException("Unable to create deployment, affinity rules associated to the VM conflict");
|
||||
}
|
||||
|
||||
if (dest != null) {
|
||||
|
||||
@ -18,7 +18,6 @@ package org.apache.cloudstack.affinity.dao;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.affinity.AffinityGroup;
|
||||
import org.apache.cloudstack.affinity.AffinityGroupVO;
|
||||
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
@ -34,9 +33,9 @@ public interface AffinityGroupDao extends GenericDao<AffinityGroupVO, Long> {
|
||||
|
||||
int removeByAccountId(long accountId);
|
||||
|
||||
AffinityGroup findDomainLevelGroupByName(Long domainId, String affinityGroupName);
|
||||
AffinityGroupVO findDomainLevelGroupByName(Long domainId, String affinityGroupName);
|
||||
|
||||
AffinityGroup findByAccountAndType(Long accountId, String string);
|
||||
AffinityGroupVO findByAccountAndType(Long accountId, String string);
|
||||
|
||||
AffinityGroup findDomainLevelGroupByType(Long domainId, String string);
|
||||
AffinityGroupVO findDomainLevelGroupByType(Long domainId, String string);
|
||||
}
|
||||
|
||||
@ -22,7 +22,6 @@ import javax.annotation.PostConstruct;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.cloudstack.acl.ControlledEntity;
|
||||
import org.apache.cloudstack.affinity.AffinityGroup;
|
||||
import org.apache.cloudstack.affinity.AffinityGroupDomainMapVO;
|
||||
import org.apache.cloudstack.affinity.AffinityGroupVO;
|
||||
|
||||
@ -134,7 +133,7 @@ public class AffinityGroupDaoImpl extends GenericDaoBase<AffinityGroupVO, Long>
|
||||
}
|
||||
|
||||
@Override
|
||||
public AffinityGroup findDomainLevelGroupByName(Long domainId, String affinityGroupName) {
|
||||
public AffinityGroupVO findDomainLevelGroupByName(Long domainId, String affinityGroupName) {
|
||||
SearchCriteria<AffinityGroupVO> sc = DomainLevelNameSearch.create();
|
||||
sc.setParameters("aclType", ControlledEntity.ACLType.Domain);
|
||||
sc.setParameters("name", affinityGroupName);
|
||||
@ -143,7 +142,7 @@ public class AffinityGroupDaoImpl extends GenericDaoBase<AffinityGroupVO, Long>
|
||||
}
|
||||
|
||||
@Override
|
||||
public AffinityGroup findByAccountAndType(Long accountId, String type) {
|
||||
public AffinityGroupVO findByAccountAndType(Long accountId, String type) {
|
||||
SearchCriteria<AffinityGroupVO> sc = AccountIdTypeSearch.create();
|
||||
sc.setParameters("accountId", accountId);
|
||||
sc.setParameters("type", type);
|
||||
@ -152,7 +151,7 @@ public class AffinityGroupDaoImpl extends GenericDaoBase<AffinityGroupVO, Long>
|
||||
}
|
||||
|
||||
@Override
|
||||
public AffinityGroup findDomainLevelGroupByType(Long domainId, String type) {
|
||||
public AffinityGroupVO findDomainLevelGroupByType(Long domainId, String type) {
|
||||
SearchCriteria<AffinityGroupVO> sc = DomainLevelTypeSearch.create();
|
||||
sc.setParameters("aclType", ControlledEntity.ACLType.Domain);
|
||||
sc.setParameters("type", type);
|
||||
|
||||
@ -639,7 +639,7 @@ public class DedicatedResourceManagerImpl implements DedicatedService {
|
||||
affinityGroupName = "DedicatedGrp-domain-" + domainName;
|
||||
}
|
||||
|
||||
group = _affinityGroupService.createAffinityGroupInternal(accountName, domainId, affinityGroupName, "ExplicitDedication", "dedicated resources group");
|
||||
group = _affinityGroupService.createAffinityGroup(accountName, null, domainId, affinityGroupName, "ExplicitDedication", "dedicated resources group");
|
||||
|
||||
return group;
|
||||
|
||||
@ -948,7 +948,7 @@ public class DedicatedResourceManagerImpl implements DedicatedService {
|
||||
List<DedicatedResourceVO> resourcesInGroup = _dedicatedDao.listByAffinityGroupId(resource.getAffinityGroupId());
|
||||
if (resourcesInGroup.isEmpty()) {
|
||||
// delete the group
|
||||
_affinityGroupService.deleteAffinityGroup(resource.getAffinityGroupId(), null, null, null);
|
||||
_affinityGroupService.deleteAffinityGroup(resource.getAffinityGroupId(), null, null, null, null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -389,7 +389,7 @@ public class IntegrationTestConfiguration {
|
||||
}
|
||||
});
|
||||
Mockito.when(
|
||||
mock.createAffinityGroupInternal(Matchers.any(String.class), Matchers.any(Long.class), Matchers.any(String.class), Matchers.any(String.class),
|
||||
mock.createAffinityGroup(Matchers.any(String.class), Matchers.any(Long.class), Matchers.any(Long.class), Matchers.any(String.class), Matchers.any(String.class),
|
||||
Matchers.any(String.class))).thenReturn(gmock);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
||||
@ -18,16 +18,18 @@ package com.cloud.acl;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import org.apache.cloudstack.acl.ControlledEntity;
|
||||
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
|
||||
import org.apache.cloudstack.affinity.AffinityGroup;
|
||||
import org.apache.cloudstack.affinity.AffinityGroupService;
|
||||
import org.apache.cloudstack.affinity.dao.AffinityGroupDomainMapDao;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.domain.DomainVO;
|
||||
import com.cloud.exception.PermissionDeniedException;
|
||||
import com.cloud.projects.ProjectVO;
|
||||
import com.cloud.projects.dao.ProjectAccountDao;
|
||||
import com.cloud.projects.dao.ProjectDao;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountManager;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
@ -41,6 +43,10 @@ public class AffinityGroupAccessChecker extends DomainChecker {
|
||||
AccountManager _accountMgr;
|
||||
@Inject
|
||||
AffinityGroupDomainMapDao _affinityGroupDomainMapDao;
|
||||
@Inject
|
||||
ProjectDao _projectDao;
|
||||
@Inject
|
||||
ProjectAccountDao _projectAccountDao;
|
||||
|
||||
@Override
|
||||
public boolean checkAccess(Account caller, ControlledEntity entity, AccessType accessType) throws PermissionDeniedException {
|
||||
@ -48,8 +54,7 @@ public class AffinityGroupAccessChecker extends DomainChecker {
|
||||
AffinityGroup group = (AffinityGroup)entity;
|
||||
|
||||
if (_affinityGroupService.isAdminControlledGroup(group)) {
|
||||
if (accessType != null && accessType == AccessType.OperateEntry
|
||||
&& !_accountMgr.isRootAdmin(caller.getId())) {
|
||||
if (accessType == AccessType.OperateEntry && !_accountMgr.isRootAdmin(caller.getId())) {
|
||||
throw new PermissionDeniedException(caller + " does not have permission to operate with resource "
|
||||
+ entity);
|
||||
}
|
||||
@ -69,6 +74,15 @@ public class AffinityGroupAccessChecker extends DomainChecker {
|
||||
} else {
|
||||
//acl_type account
|
||||
if (caller.getId() != group.getAccountId()) {
|
||||
//check if the group belongs to a project
|
||||
ProjectVO project = _projectDao.findByProjectAccountId(group.getAccountId());
|
||||
if (project != null) {
|
||||
if (AccessType.ModifyProject.equals(accessType) && _projectAccountDao.canModifyProjectAccount(caller.getId(), group.getAccountId())) {
|
||||
return true;
|
||||
} else if (!AccessType.ModifyProject.equals(accessType) && _projectAccountDao.canAccessProjectAccount(caller.getId(), group.getAccountId())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
throw new PermissionDeniedException(caller + " does not have permission to operate with resource " + entity);
|
||||
} else {
|
||||
return true;
|
||||
|
||||
@ -25,9 +25,6 @@ import java.util.Set;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.cloud.utils.StringUtils;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
|
||||
import org.apache.cloudstack.affinity.AffinityGroupDomainMapVO;
|
||||
import org.apache.cloudstack.affinity.AffinityGroupResponse;
|
||||
@ -56,6 +53,7 @@ import org.apache.cloudstack.api.command.admin.volume.ListVolumesCmdByAdmin;
|
||||
import org.apache.cloudstack.api.command.admin.zone.ListZonesCmdByAdmin;
|
||||
import org.apache.cloudstack.api.command.user.account.ListAccountsCmd;
|
||||
import org.apache.cloudstack.api.command.user.account.ListProjectAccountsCmd;
|
||||
import org.apache.cloudstack.api.command.user.affinitygroup.ListAffinityGroupsCmd;
|
||||
import org.apache.cloudstack.api.command.user.event.ListEventsCmd;
|
||||
import org.apache.cloudstack.api.command.user.iso.ListIsosCmd;
|
||||
import org.apache.cloudstack.api.command.user.job.ListAsyncJobsCmd;
|
||||
@ -195,7 +193,6 @@ import com.cloud.storage.Storage.TemplateType;
|
||||
import com.cloud.storage.VMTemplateVO;
|
||||
import com.cloud.storage.Volume;
|
||||
import com.cloud.storage.dao.VMTemplateDao;
|
||||
import com.cloud.storage.dao.VolumeDetailsDao;
|
||||
import com.cloud.tags.ResourceTagVO;
|
||||
import com.cloud.tags.dao.ResourceTagDao;
|
||||
import com.cloud.template.VirtualMachineTemplate.State;
|
||||
@ -206,6 +203,7 @@ import com.cloud.user.DomainManager;
|
||||
import com.cloud.user.dao.AccountDao;
|
||||
import com.cloud.utils.DateUtil;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.StringUtils;
|
||||
import com.cloud.utils.Ternary;
|
||||
import com.cloud.utils.component.ManagerBase;
|
||||
import com.cloud.utils.db.Filter;
|
||||
@ -216,17 +214,20 @@ import com.cloud.utils.db.SearchCriteria.Func;
|
||||
import com.cloud.utils.db.SearchCriteria.Op;
|
||||
import com.cloud.vm.DomainRouterVO;
|
||||
import com.cloud.vm.UserVmVO;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.dao.DomainRouterDao;
|
||||
import com.cloud.vm.dao.NicDetailsDao;
|
||||
import com.cloud.vm.dao.UserVmDao;
|
||||
import com.cloud.vm.dao.UserVmDetailsDao;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
|
||||
@Component
|
||||
public class QueryManagerImpl extends ManagerBase implements QueryService, Configurable {
|
||||
|
||||
public static final Logger s_logger = Logger.getLogger(QueryManagerImpl.class);
|
||||
|
||||
private static final String ID_FIELD = "id";
|
||||
|
||||
@Inject
|
||||
private AccountManager _accountMgr;
|
||||
|
||||
@ -329,12 +330,6 @@ public class QueryManagerImpl extends ManagerBase implements QueryService, Confi
|
||||
@Inject
|
||||
private DomainRouterDao _routerDao;
|
||||
|
||||
@Inject
|
||||
private VolumeDetailsDao _volumeDetailDao;
|
||||
|
||||
@Inject
|
||||
private NicDetailsDao _nicDetailDao;
|
||||
|
||||
@Inject
|
||||
UserVmDetailsDao _userVmDetailDao;
|
||||
|
||||
@ -373,11 +368,11 @@ public class QueryManagerImpl extends ManagerBase implements QueryService, Confi
|
||||
@Inject
|
||||
AffinityGroupDomainMapDao _affinityGroupDomainMapDao;
|
||||
|
||||
|
||||
@Inject NetworkDetailsDao _networkDetailsDao;
|
||||
|
||||
@Inject
|
||||
ResourceTagDao _resourceTagDao;
|
||||
|
||||
@Inject
|
||||
DataStoreManager dataStoreManager;
|
||||
|
||||
@ -3393,55 +3388,60 @@ public class QueryManagerImpl extends ManagerBase implements QueryService, Confi
|
||||
cmd.listInReadyState(), permittedAccounts, caller, listProjectResourcesCriteria, tags, showRemovedISO);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ListResponse<AffinityGroupResponse> listAffinityGroups(Long affinityGroupId, String affinityGroupName,
|
||||
String affinityGroupType, Long vmId, String accountName, Long domainId, boolean isRecursive,
|
||||
boolean listAll, Long startIndex, Long pageSize, String keyword) {
|
||||
Pair<List<AffinityGroupJoinVO>, Integer> result = listAffinityGroupsInternal(affinityGroupId,
|
||||
affinityGroupName, affinityGroupType, vmId, accountName, domainId, isRecursive, listAll, startIndex,
|
||||
pageSize, keyword);
|
||||
public ListResponse<AffinityGroupResponse> searchForAffinityGroups(ListAffinityGroupsCmd cmd) {
|
||||
Pair<List<AffinityGroupJoinVO>, Integer> result = searchForAffinityGroupsInternal(cmd);
|
||||
ListResponse<AffinityGroupResponse> response = new ListResponse<AffinityGroupResponse>();
|
||||
List<AffinityGroupResponse> agResponses = ViewResponseHelper.createAffinityGroupResponses(result.first());
|
||||
response.setResponses(agResponses, result.second());
|
||||
return response;
|
||||
}
|
||||
|
||||
public Pair<List<AffinityGroupJoinVO>, Integer> listAffinityGroupsInternal(Long affinityGroupId,
|
||||
String affinityGroupName, String affinityGroupType, Long vmId, String accountName, Long domainId,
|
||||
boolean isRecursive, boolean listAll, Long startIndex, Long pageSize, String keyword) {
|
||||
public Pair<List<AffinityGroupJoinVO>, Integer> searchForAffinityGroupsInternal(ListAffinityGroupsCmd cmd) {
|
||||
|
||||
final Long affinityGroupId = cmd.getId();
|
||||
final String affinityGroupName = cmd.getAffinityGroupName();
|
||||
final String affinityGroupType = cmd.getAffinityGroupType();
|
||||
final Long vmId = cmd.getVirtualMachineId();
|
||||
final String accountName = cmd.getAccountName();
|
||||
Long domainId = cmd.getDomainId();
|
||||
final Long projectId = cmd.getProjectId();
|
||||
Boolean isRecursive = cmd.isRecursive();
|
||||
final Boolean listAll = cmd.listAll();
|
||||
final Long startIndex = cmd.getStartIndex();
|
||||
final Long pageSize = cmd.getPageSizeVal();
|
||||
final String keyword = cmd.getKeyword();
|
||||
|
||||
Account caller = CallContext.current().getCallingAccount();
|
||||
|
||||
caller.getAccountId();
|
||||
|
||||
if (vmId != null) {
|
||||
UserVmVO userVM = _userVmDao.findById(vmId);
|
||||
if (userVM == null) {
|
||||
throw new InvalidParameterValueException("Unable to list affinity groups for virtual machine instance "
|
||||
+ vmId + "; instance not found.");
|
||||
throw new InvalidParameterValueException("Unable to list affinity groups for virtual machine instance " + vmId + "; instance not found.");
|
||||
}
|
||||
_accountMgr.checkAccess(caller, null, true, userVM);
|
||||
return listAffinityGroupsByVM(vmId.longValue(), startIndex, pageSize);
|
||||
}
|
||||
|
||||
List<Long> permittedAccounts = new ArrayList<Long>();
|
||||
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(
|
||||
domainId, isRecursive, null);
|
||||
_accountMgr.buildACLSearchParameters(caller, affinityGroupId, accountName, null, permittedAccounts,
|
||||
domainIdRecursiveListProject, listAll, true);
|
||||
domainId = domainIdRecursiveListProject.first();
|
||||
isRecursive = domainIdRecursiveListProject.second();
|
||||
ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
|
||||
Ternary<Long, Boolean, ListProjectResourcesCriteria> ternary = new Ternary<Long, Boolean, ListProjectResourcesCriteria>(domainId, isRecursive, null);
|
||||
|
||||
Filter searchFilter = new Filter(AffinityGroupJoinVO.class, "id", true, startIndex, pageSize);
|
||||
SearchCriteria<AffinityGroupJoinVO> sc = buildAffinityGroupSearchCriteria(domainId, isRecursive,
|
||||
permittedAccounts, listProjectResourcesCriteria, affinityGroupId, affinityGroupName, affinityGroupType, keyword);
|
||||
_accountMgr.buildACLSearchParameters(caller, affinityGroupId, accountName, projectId, permittedAccounts, ternary, listAll, false);
|
||||
|
||||
domainId = ternary.first();
|
||||
isRecursive = ternary.second();
|
||||
ListProjectResourcesCriteria listProjectResourcesCriteria = ternary.third();
|
||||
|
||||
Filter searchFilter = new Filter(AffinityGroupJoinVO.class, ID_FIELD, true, startIndex, pageSize);
|
||||
|
||||
SearchCriteria<AffinityGroupJoinVO> sc = buildAffinityGroupSearchCriteria(domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria, affinityGroupId,
|
||||
affinityGroupName, affinityGroupType, keyword);
|
||||
|
||||
Pair<List<AffinityGroupJoinVO>, Integer> uniqueGroupsPair = _affinityGroupJoinDao.searchAndCount(sc, searchFilter);
|
||||
|
||||
Pair<List<AffinityGroupJoinVO>, Integer> uniqueGroupsPair = _affinityGroupJoinDao.searchAndCount(sc,
|
||||
searchFilter);
|
||||
// search group details by ids
|
||||
List<AffinityGroupJoinVO> vrs = new ArrayList<AffinityGroupJoinVO>();
|
||||
List<AffinityGroupJoinVO> affinityGroups = new ArrayList<AffinityGroupJoinVO>();
|
||||
|
||||
Integer count = uniqueGroupsPair.second();
|
||||
if (count.intValue() != 0) {
|
||||
List<AffinityGroupJoinVO> uniqueGroups = uniqueGroupsPair.first();
|
||||
@ -3450,36 +3450,33 @@ public class QueryManagerImpl extends ManagerBase implements QueryService, Confi
|
||||
for (AffinityGroupJoinVO v : uniqueGroups) {
|
||||
vrIds[i++] = v.getId();
|
||||
}
|
||||
vrs = _affinityGroupJoinDao.searchByIds(vrIds);
|
||||
affinityGroups = _affinityGroupJoinDao.searchByIds(vrIds);
|
||||
}
|
||||
|
||||
if (!permittedAccounts.isEmpty()) {
|
||||
// add domain level affinity groups
|
||||
if (domainId != null) {
|
||||
SearchCriteria<AffinityGroupJoinVO> scDomain = buildAffinityGroupSearchCriteria(null, isRecursive,
|
||||
new ArrayList<Long>(), listProjectResourcesCriteria, affinityGroupId, affinityGroupName,
|
||||
affinityGroupType, keyword);
|
||||
vrs.addAll(listDomainLevelAffinityGroups(scDomain, searchFilter, domainId));
|
||||
SearchCriteria<AffinityGroupJoinVO> scDomain = buildAffinityGroupSearchCriteria(null, isRecursive, new ArrayList<Long>(), listProjectResourcesCriteria,
|
||||
affinityGroupId, affinityGroupName, affinityGroupType, keyword);
|
||||
affinityGroups.addAll(listDomainLevelAffinityGroups(scDomain, searchFilter, domainId));
|
||||
} else {
|
||||
|
||||
for (Long permAcctId : permittedAccounts) {
|
||||
Account permittedAcct = _accountDao.findById(permAcctId);
|
||||
SearchCriteria<AffinityGroupJoinVO> scDomain = buildAffinityGroupSearchCriteria(
|
||||
null, isRecursive, new ArrayList<Long>(),
|
||||
listProjectResourcesCriteria, affinityGroupId, affinityGroupName, affinityGroupType, keyword);
|
||||
SearchCriteria<AffinityGroupJoinVO> scDomain = buildAffinityGroupSearchCriteria(null, isRecursive, new ArrayList<Long>(), listProjectResourcesCriteria,
|
||||
affinityGroupId, affinityGroupName, affinityGroupType, keyword);
|
||||
|
||||
vrs.addAll(listDomainLevelAffinityGroups(scDomain, searchFilter, permittedAcct.getDomainId()));
|
||||
affinityGroups.addAll(listDomainLevelAffinityGroups(scDomain, searchFilter, permittedAcct.getDomainId()));
|
||||
}
|
||||
}
|
||||
} else if (((permittedAccounts.isEmpty()) && (domainId != null) && isRecursive)) {
|
||||
// list all domain level affinity groups for the domain admin case
|
||||
SearchCriteria<AffinityGroupJoinVO> scDomain = buildAffinityGroupSearchCriteria(null, isRecursive,
|
||||
new ArrayList<Long>(), listProjectResourcesCriteria, affinityGroupId, affinityGroupName,
|
||||
affinityGroupType, keyword);
|
||||
vrs.addAll(listDomainLevelAffinityGroups(scDomain, searchFilter, domainId));
|
||||
SearchCriteria<AffinityGroupJoinVO> scDomain = buildAffinityGroupSearchCriteria(null, isRecursive, new ArrayList<Long>(), listProjectResourcesCriteria,
|
||||
affinityGroupId, affinityGroupName, affinityGroupType, keyword);
|
||||
affinityGroups.addAll(listDomainLevelAffinityGroups(scDomain, searchFilter, domainId));
|
||||
}
|
||||
|
||||
return new Pair<List<AffinityGroupJoinVO>, Integer>(vrs, vrs.size());
|
||||
return new Pair<List<AffinityGroupJoinVO>, Integer>(affinityGroups, affinityGroups.size());
|
||||
|
||||
}
|
||||
|
||||
@ -3524,9 +3521,8 @@ public class QueryManagerImpl extends ManagerBase implements QueryService, Confi
|
||||
}
|
||||
}
|
||||
|
||||
private SearchCriteria<AffinityGroupJoinVO> buildAffinityGroupSearchCriteria(Long domainId, boolean isRecursive,
|
||||
List<Long> permittedAccounts, ListProjectResourcesCriteria listProjectResourcesCriteria,
|
||||
Long affinityGroupId, String affinityGroupName, String affinityGroupType, String keyword) {
|
||||
private SearchCriteria<AffinityGroupJoinVO> buildAffinityGroupSearchCriteria(Long domainId, boolean isRecursive, List<Long> permittedAccounts,
|
||||
ListProjectResourcesCriteria listProjectResourcesCriteria, Long affinityGroupId, String affinityGroupName, String affinityGroupType, String keyword) {
|
||||
|
||||
SearchBuilder<AffinityGroupJoinVO> groupSearch = _affinityGroupJoinDao.createSearchBuilder();
|
||||
buildAffinityGroupViewSearchBuilder(groupSearch, domainId, isRecursive, permittedAccounts,
|
||||
@ -3536,8 +3532,7 @@ public class QueryManagerImpl extends ManagerBase implements QueryService, Confi
|
||||
// distinct
|
||||
|
||||
SearchCriteria<AffinityGroupJoinVO> sc = groupSearch.create();
|
||||
buildAffinityGroupViewSearchCriteria(sc, domainId, isRecursive, permittedAccounts,
|
||||
listProjectResourcesCriteria);
|
||||
buildAffinityGroupViewSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
|
||||
|
||||
if (affinityGroupId != null) {
|
||||
sc.addAnd("id", SearchCriteria.Op.EQ, affinityGroupId);
|
||||
|
||||
@ -72,6 +72,15 @@ public class AffinityGroupJoinVO extends BaseViewVO implements ControlledViewEnt
|
||||
@Column(name = "domain_path")
|
||||
private String domainPath = null;
|
||||
|
||||
@Column(name = "project_id")
|
||||
private long projectId;
|
||||
|
||||
@Column(name = "project_uuid")
|
||||
private String projectUuid;
|
||||
|
||||
@Column(name = "project_name")
|
||||
private String projectName;
|
||||
|
||||
@Column(name = "vm_id")
|
||||
private long vmId;
|
||||
|
||||
@ -153,6 +162,20 @@ public class AffinityGroupJoinVO extends BaseViewVO implements ControlledViewEnt
|
||||
return domainPath;
|
||||
}
|
||||
|
||||
public long getProjectId() {
|
||||
return projectId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProjectUuid() {
|
||||
return projectUuid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProjectName() {
|
||||
return projectName;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
@ -177,18 +200,6 @@ public class AffinityGroupJoinVO extends BaseViewVO implements ControlledViewEnt
|
||||
return vmState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProjectUuid() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProjectName() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public ControlledEntity.ACLType getAclType() {
|
||||
return aclType;
|
||||
}
|
||||
|
||||
@ -1495,7 +1495,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
||||
final List<DedicatedResourceVO> resourcesInGroup = _dedicatedDao.listByAffinityGroupId(dr.getAffinityGroupId());
|
||||
if (resourcesInGroup.isEmpty()) {
|
||||
// delete the group
|
||||
_affinityGroupService.deleteAffinityGroup(dr.getAffinityGroupId(), null, null, null);
|
||||
_affinityGroupService.deleteAffinityGroup(dr.getAffinityGroupId(), null, null, null, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1713,7 +1713,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
||||
final List<DedicatedResourceVO> resourcesInGroup = _dedicatedDao.listByAffinityGroupId(resource.getAffinityGroupId());
|
||||
if (resourcesInGroup.isEmpty()) {
|
||||
// delete the group
|
||||
_affinityGroupService.deleteAffinityGroup(resource.getAffinityGroupId(), null, null, null);
|
||||
_affinityGroupService.deleteAffinityGroup(resource.getAffinityGroupId(), null, null, null, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1811,7 +1811,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
|
||||
}
|
||||
}
|
||||
|
||||
group = _affinityGroupService.createAffinityGroupInternal(accountName, domainId, affinityGroupName, "ExplicitDedication", "dedicated resources group");
|
||||
group = _affinityGroupService.createAffinityGroup(accountName, null, domainId, affinityGroupName, "ExplicitDedication", "dedicated resources group");
|
||||
|
||||
return group;
|
||||
|
||||
|
||||
@ -2404,98 +2404,10 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
||||
}
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public void buildACLSearchParameters(Account caller, Long id, String accountName, Long projectId, List<Long>
|
||||
// permittedAccounts, Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject,
|
||||
// boolean listAll, boolean forProjectInvitation) {
|
||||
// Long domainId = domainIdRecursiveListProject.first();
|
||||
// if (domainId != null) {
|
||||
// Domain domain = _domainDao.findById(domainId);
|
||||
// if (domain == null) {
|
||||
// throw new InvalidParameterValueException("Unable to find domain by id " + domainId);
|
||||
// }
|
||||
// // check permissions
|
||||
// checkAccess(caller, domain);
|
||||
// }
|
||||
//
|
||||
// if (accountName != null) {
|
||||
// if (projectId != null) {
|
||||
// throw new InvalidParameterValueException("Account and projectId can't be specified together");
|
||||
// }
|
||||
//
|
||||
// Account userAccount = null;
|
||||
// Domain domain = null;
|
||||
// if (domainId != null) {
|
||||
// userAccount = _accountDao.findActiveAccount(accountName, domainId);
|
||||
// domain = _domainDao.findById(domainId);
|
||||
// } else {
|
||||
// userAccount = _accountDao.findActiveAccount(accountName, caller.getDomainId());
|
||||
// domain = _domainDao.findById(caller.getDomainId());
|
||||
// }
|
||||
//
|
||||
// if (userAccount != null) {
|
||||
// checkAccess(caller, null, false, userAccount);
|
||||
// //check permissions
|
||||
// permittedAccounts.add(userAccount.getId());
|
||||
// } else {
|
||||
// throw new InvalidParameterValueException("could not find account " + accountName + " in domain " + domain.getUuid());
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // set project information
|
||||
// if (projectId != null) {
|
||||
// if (!forProjectInvitation) {
|
||||
// if (projectId.longValue() == -1) {
|
||||
// if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) {
|
||||
// permittedAccounts.addAll(_projectMgr.listPermittedProjectAccounts(caller.getId()));
|
||||
// } else {
|
||||
// domainIdRecursiveListProject.third(Project.ListProjectResourcesCriteria.ListProjectResourcesOnly);
|
||||
// }
|
||||
// } else {
|
||||
// Project project = _projectMgr.getProject(projectId);
|
||||
// if (project == null) {
|
||||
// throw new InvalidParameterValueException("Unable to find project by id " + projectId);
|
||||
// }
|
||||
// if (!_projectMgr.canAccessProjectAccount(caller, project.getProjectAccountId())) {
|
||||
// throw new PermissionDeniedException("Account " + caller + " can't access project id=" + projectId);
|
||||
// }
|
||||
// permittedAccounts.add(project.getProjectAccountId());
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// if (id == null) {
|
||||
// domainIdRecursiveListProject.third(Project.ListProjectResourcesCriteria.SkipProjectResources);
|
||||
// }
|
||||
// if (permittedAccounts.isEmpty() && domainId == null) {
|
||||
// if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) {
|
||||
// permittedAccounts.add(caller.getId());
|
||||
// } else if (!listAll) {
|
||||
// if (id == null) {
|
||||
// permittedAccounts.add(caller.getId());
|
||||
// } else if (!isRootAdmin(caller.getId())) {
|
||||
// domainIdRecursiveListProject.first(caller.getDomainId());
|
||||
// domainIdRecursiveListProject.second(true);
|
||||
// }
|
||||
// } else if (domainId == null) {
|
||||
// if (caller.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) {
|
||||
// domainIdRecursiveListProject.first(caller.getDomainId());
|
||||
// domainIdRecursiveListProject.second(true);
|
||||
// }
|
||||
// }
|
||||
// } else if (domainId != null) {
|
||||
// if (caller.getType() == Account.ACCOUNT_TYPE_NORMAL) {
|
||||
// permittedAccounts.add(caller.getId());
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// }
|
||||
|
||||
//TODO: deprecate this to use the new buildACLSearchParameters with permittedDomains, permittedAccounts, and permittedResources as return
|
||||
@Override
|
||||
public void buildACLSearchParameters(Account caller, Long id, String accountName, Long projectId, List<Long>
|
||||
permittedAccounts, Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject,
|
||||
boolean listAll, boolean forProjectInvitation) {
|
||||
public void buildACLSearchParameters(Account caller, Long id, String accountName, Long projectId, List<Long> permittedAccounts,
|
||||
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject, boolean listAll, boolean forProjectInvitation) {
|
||||
Long domainId = domainIdRecursiveListProject.first();
|
||||
if (domainId != null) {
|
||||
Domain domain = _domainDao.findById(domainId);
|
||||
|
||||
@ -26,8 +26,8 @@ import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import com.cloud.utils.fsm.StateMachine2;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.apache.cloudstack.acl.ControlledEntity;
|
||||
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
|
||||
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
||||
@ -35,6 +35,7 @@ import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
|
||||
import org.apache.cloudstack.affinity.dao.AffinityGroupDomainMapDao;
|
||||
import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.command.user.affinitygroup.CreateAffinityGroupCmd;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.framework.messagebus.MessageBus;
|
||||
import org.apache.cloudstack.framework.messagebus.PublishScope;
|
||||
@ -54,8 +55,6 @@ import com.cloud.utils.component.Manager;
|
||||
import com.cloud.utils.component.ManagerBase;
|
||||
import com.cloud.utils.db.DB;
|
||||
import com.cloud.utils.db.EntityManager;
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.JoinBuilder;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.Transaction;
|
||||
@ -111,48 +110,29 @@ public class AffinityGroupServiceImpl extends ManagerBase implements AffinityGro
|
||||
@DB
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_AFFINITY_GROUP_CREATE, eventDescription = "Creating Affinity Group", create = true)
|
||||
public AffinityGroup createAffinityGroup(String account, Long domainId, String affinityGroupName, String affinityGroupType, String description) {
|
||||
public AffinityGroup createAffinityGroup(CreateAffinityGroupCmd createAffinityGroupCmd) {
|
||||
return createAffinityGroup(createAffinityGroupCmd.getAccountName(), createAffinityGroupCmd.getProjectId(), createAffinityGroupCmd.getDomainId(), createAffinityGroupCmd.getAffinityGroupName(), createAffinityGroupCmd.getAffinityGroupType(), createAffinityGroupCmd.getDescription());
|
||||
}
|
||||
|
||||
Account caller = CallContext.current().getCallingAccount();
|
||||
@DB
|
||||
@Override
|
||||
public AffinityGroup createAffinityGroup(final String accountName, final Long projectId, final Long domainId, final String affinityGroupName, final String affinityGroupType,
|
||||
final String description) {
|
||||
|
||||
//validate the affinityGroupType
|
||||
// validate the affinityGroupType
|
||||
Map<String, AffinityGroupProcessor> typeProcessorMap = getAffinityTypeToProcessorMap();
|
||||
if (typeProcessorMap != null && !typeProcessorMap.isEmpty()) {
|
||||
if (!typeProcessorMap.containsKey(affinityGroupType)) {
|
||||
throw new InvalidParameterValueException("Unable to create affinity group, invalid affinity group type" + affinityGroupType);
|
||||
}
|
||||
} else {
|
||||
|
||||
if (typeProcessorMap == null || typeProcessorMap.isEmpty()) {
|
||||
throw new InvalidParameterValueException("Unable to create affinity group, no Affinity Group Types configured");
|
||||
}
|
||||
|
||||
AffinityGroupProcessor processor = typeProcessorMap.get(affinityGroupType);
|
||||
|
||||
if (processor.isAdminControlledGroup()) {
|
||||
throw new PermissionDeniedException("Cannot create the affinity group");
|
||||
if(processor == null){
|
||||
throw new InvalidParameterValueException("Unable to create affinity group, invalid affinity group type" + affinityGroupType);
|
||||
}
|
||||
|
||||
return createAffinityGroupInternal(account, domainId, affinityGroupName, affinityGroupType, description);
|
||||
}
|
||||
|
||||
@DB
|
||||
@Override
|
||||
public AffinityGroup createAffinityGroupInternal(String account, final Long domainId, final String affinityGroupName, final String affinityGroupType,
|
||||
final String description) {
|
||||
|
||||
Account caller = CallContext.current().getCallingAccount();
|
||||
|
||||
// validate the affinityGroupType
|
||||
Map<String, AffinityGroupProcessor> typeProcessorMap = getAffinityTypeToProcessorMap();
|
||||
if (typeProcessorMap != null && !typeProcessorMap.isEmpty()) {
|
||||
if (!typeProcessorMap.containsKey(affinityGroupType)) {
|
||||
throw new InvalidParameterValueException("Unable to create affinity group, invalid affinity group type" + affinityGroupType);
|
||||
}
|
||||
} else {
|
||||
throw new InvalidParameterValueException("Unable to create affinity group, no Affinity Group Types configured");
|
||||
}
|
||||
|
||||
final AffinityGroupProcessor processor = typeProcessorMap.get(affinityGroupType);
|
||||
|
||||
if (processor.isAdminControlledGroup() && !_accountMgr.isRootAdmin(caller.getId())) {
|
||||
throw new PermissionDeniedException("Cannot create the affinity group");
|
||||
}
|
||||
@ -161,72 +141,24 @@ public class AffinityGroupServiceImpl extends ManagerBase implements AffinityGro
|
||||
Account owner = null;
|
||||
boolean domainLevel = false;
|
||||
|
||||
if (account != null && domainId != null) {
|
||||
|
||||
owner = _accountMgr.finalizeOwner(caller, account, domainId, null);
|
||||
aclType = ControlledEntity.ACLType.Account;
|
||||
|
||||
} else if (domainId != null && account == null) {
|
||||
|
||||
if (!_accountMgr.isRootAdmin(caller.getId())) {
|
||||
// non root admin need to pass both account and domain
|
||||
throw new InvalidParameterValueException("Unable to create affinity group, account name must be passed with the domainId");
|
||||
} else if (!processor.canBeSharedDomainWide()) {
|
||||
// cannot be domain level
|
||||
throw new InvalidParameterValueException("Unable to create affinity group, account name is needed");
|
||||
}
|
||||
|
||||
DomainVO domain = _domainDao.findById(domainId);
|
||||
if (domain == null) {
|
||||
throw new InvalidParameterValueException("Unable to find domain by specified id");
|
||||
}
|
||||
if (projectId == null && domainId != null && accountName == null) {
|
||||
verifyAccessToDomainWideProcessor(caller, processor);
|
||||
DomainVO domain = getDomain(domainId);
|
||||
_accountMgr.checkAccess(caller, domain);
|
||||
|
||||
// domain level group, owner is SYSTEM.
|
||||
owner = _accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM);
|
||||
aclType = ControlledEntity.ACLType.Domain;
|
||||
domainLevel = true;
|
||||
|
||||
} else {
|
||||
owner = caller;
|
||||
owner = _accountMgr.finalizeOwner(caller, accountName, domainId, projectId);
|
||||
aclType = ControlledEntity.ACLType.Account;
|
||||
}
|
||||
|
||||
if (_affinityGroupDao.isNameInUse(owner.getAccountId(), owner.getDomainId(), affinityGroupName)) {
|
||||
throw new InvalidParameterValueException("Unable to create affinity group, a group with name " + affinityGroupName + " already exists.");
|
||||
}
|
||||
if (domainLevel && _affinityGroupDao.findDomainLevelGroupByName(domainId, affinityGroupName) != null) {
|
||||
throw new InvalidParameterValueException("Unable to create affinity group, a group with name " + affinityGroupName + " already exists under the domain.");
|
||||
}
|
||||
verifyAffinityGroupNameInUse(owner.getAccountId(), owner.getDomainId(), affinityGroupName);
|
||||
verifyDomainLevelAffinityGroupName(domainLevel, owner.getDomainId(), affinityGroupName);
|
||||
|
||||
final Account ownerFinal = owner;
|
||||
final ControlledEntity.ACLType aclTypeFinal = aclType;
|
||||
AffinityGroupVO group = Transaction.execute(new TransactionCallback<AffinityGroupVO>() {
|
||||
@Override
|
||||
public AffinityGroupVO doInTransaction(TransactionStatus status) {
|
||||
AffinityGroupVO group =
|
||||
new AffinityGroupVO(affinityGroupName, affinityGroupType, description, ownerFinal.getDomainId(), ownerFinal.getId(), aclTypeFinal);
|
||||
_affinityGroupDao.persist(group);
|
||||
|
||||
if (domainId != null && aclTypeFinal == ACLType.Domain) {
|
||||
boolean subDomainAccess = false;
|
||||
subDomainAccess = processor.subDomainAccess();
|
||||
AffinityGroupDomainMapVO domainMap = new AffinityGroupDomainMapVO(group.getId(), domainId,
|
||||
subDomainAccess);
|
||||
_affinityGroupDomainMapDao.persist(domainMap);
|
||||
//send event for storing the domain wide resource access
|
||||
Map<String, Object> params = new HashMap<String, Object>();
|
||||
params.put(ApiConstants.ENTITY_TYPE, AffinityGroup.class);
|
||||
params.put(ApiConstants.ENTITY_ID, group.getId());
|
||||
params.put(ApiConstants.DOMAIN_ID, domainId);
|
||||
params.put(ApiConstants.SUBDOMAIN_ACCESS, subDomainAccess);
|
||||
_messageBus.publish(_name, EntityManager.MESSAGE_ADD_DOMAIN_WIDE_ENTITY_EVENT, PublishScope.LOCAL,
|
||||
params);
|
||||
}
|
||||
|
||||
return group;
|
||||
}
|
||||
});
|
||||
AffinityGroupVO group = createAffinityGroup(processor, owner, aclType, affinityGroupName, affinityGroupType, description);
|
||||
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Created affinity group =" + affinityGroupName);
|
||||
@ -235,51 +167,135 @@ public class AffinityGroupServiceImpl extends ManagerBase implements AffinityGro
|
||||
return group;
|
||||
}
|
||||
|
||||
private void verifyAccessToDomainWideProcessor(Account caller, AffinityGroupProcessor processor) {
|
||||
if (!_accountMgr.isRootAdmin(caller.getId())) {
|
||||
throw new InvalidParameterValueException("Unable to create affinity group, account name must be passed with the domainId");
|
||||
}
|
||||
if (!processor.canBeSharedDomainWide()) {
|
||||
throw new InvalidParameterValueException("Unable to create affinity group, account name is needed. Affinity group type "+ processor.getType() +" cannot be shared domain wide");
|
||||
}
|
||||
}
|
||||
|
||||
private AffinityGroupVO createAffinityGroup(final AffinityGroupProcessor processor, final Account owner, final ACLType aclType, final String affinityGroupName, final String affinityGroupType, final String description) {
|
||||
return Transaction.execute(new TransactionCallback<AffinityGroupVO>() {
|
||||
@Override
|
||||
public AffinityGroupVO doInTransaction(TransactionStatus status) {
|
||||
AffinityGroupVO group =
|
||||
new AffinityGroupVO(affinityGroupName, affinityGroupType, description, owner.getDomainId(), owner.getId(), aclType);
|
||||
_affinityGroupDao.persist(group);
|
||||
|
||||
if (aclType == ACLType.Domain) {
|
||||
boolean subDomainAccess = false;
|
||||
subDomainAccess = processor.subDomainAccess();
|
||||
AffinityGroupDomainMapVO domainMap = new AffinityGroupDomainMapVO(group.getId(), owner.getDomainId(),
|
||||
subDomainAccess);
|
||||
_affinityGroupDomainMapDao.persist(domainMap);
|
||||
//send event for storing the domain wide resource access
|
||||
Map<String, Object> params = new HashMap<String, Object>();
|
||||
params.put(ApiConstants.ENTITY_TYPE, AffinityGroup.class);
|
||||
params.put(ApiConstants.ENTITY_ID, group.getId());
|
||||
params.put(ApiConstants.DOMAIN_ID, owner.getDomainId());
|
||||
params.put(ApiConstants.SUBDOMAIN_ACCESS, subDomainAccess);
|
||||
_messageBus.publish(_name, EntityManager.MESSAGE_ADD_DOMAIN_WIDE_ENTITY_EVENT, PublishScope.LOCAL,
|
||||
params);
|
||||
}
|
||||
|
||||
return group;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private DomainVO getDomain(Long domainId) {
|
||||
DomainVO domain = _domainDao.findById(domainId);
|
||||
if (domain == null) {
|
||||
throw new InvalidParameterValueException("Unable to find domain by specified id");
|
||||
}
|
||||
return domain;
|
||||
}
|
||||
|
||||
private void verifyAffinityGroupNameInUse(long accountId, long domainId, String affinityGroupName) {
|
||||
if (_affinityGroupDao.isNameInUse(accountId, domainId, affinityGroupName)) {
|
||||
throw new InvalidParameterValueException("Unable to create affinity group, a group with name " + affinityGroupName + " already exists.");
|
||||
}
|
||||
}
|
||||
|
||||
private void verifyDomainLevelAffinityGroupName(boolean domainLevel, long domainId, String affinityGroupName) {
|
||||
if (domainLevel && _affinityGroupDao.findDomainLevelGroupByName(domainId, affinityGroupName) != null) {
|
||||
throw new InvalidParameterValueException("Unable to create affinity group, a group with name " + affinityGroupName + " already exists under the domain.");
|
||||
}
|
||||
}
|
||||
|
||||
@DB
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_AFFINITY_GROUP_DELETE, eventDescription = "Deleting affinity group")
|
||||
public boolean deleteAffinityGroup(Long affinityGroupId, String account, Long domainId, String affinityGroupName) {
|
||||
public boolean deleteAffinityGroup(Long affinityGroupId, String account, Long projectId, Long domainId, String affinityGroupName) {
|
||||
|
||||
AffinityGroupVO group = getAffinityGroup(affinityGroupId, account, projectId, domainId, affinityGroupName);
|
||||
|
||||
// check permissions
|
||||
Account caller = CallContext.current().getCallingAccount();
|
||||
Account owner = _accountMgr.finalizeOwner(caller, account, domainId, null);
|
||||
_accountMgr.checkAccess(caller, AccessType.OperateEntry, true, group);
|
||||
|
||||
final Long affinityGroupIdFinal = group.getId();
|
||||
deleteAffinityGroup(affinityGroupIdFinal);
|
||||
|
||||
// remove its related ACL permission
|
||||
Pair<Class<?>, Long> params = new Pair<Class<?>, Long>(AffinityGroup.class, affinityGroupIdFinal);
|
||||
_messageBus.publish(_name, EntityManager.MESSAGE_REMOVE_ENTITY_EVENT, PublishScope.LOCAL, params);
|
||||
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Deleted affinity group id=" + affinityGroupIdFinal);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private AffinityGroupVO getAffinityGroup(Long affinityGroupId, String account, Long projectId, Long domainId, String affinityGroupName) {
|
||||
AffinityGroupVO group = null;
|
||||
if (affinityGroupId != null) {
|
||||
group = _affinityGroupDao.findById(affinityGroupId);
|
||||
if (group == null) {
|
||||
throw new InvalidParameterValueException("Unable to find affinity group: " + affinityGroupId + "; failed to delete group.");
|
||||
}
|
||||
} else if (affinityGroupName != null) {
|
||||
group = _affinityGroupDao.findByAccountAndName(owner.getAccountId(), affinityGroupName);
|
||||
if (group == null) {
|
||||
throw new InvalidParameterValueException("Unable to find affinity group: " + affinityGroupName + "; failed to delete group.");
|
||||
}
|
||||
group = getAffinityGroupByName(account, projectId, domainId, affinityGroupName);
|
||||
} else {
|
||||
throw new InvalidParameterValueException("Either the affinity group Id or group name must be specified to delete the group");
|
||||
}
|
||||
if (affinityGroupId == null) {
|
||||
affinityGroupId = group.getId();
|
||||
if (group == null) {
|
||||
throw new InvalidParameterValueException("Unable to find affinity group " + (affinityGroupId == null ? affinityGroupName : affinityGroupId));
|
||||
}
|
||||
// check permissions
|
||||
_accountMgr.checkAccess(caller, AccessType.OperateEntry, true, group);
|
||||
return group;
|
||||
}
|
||||
|
||||
final Long affinityGroupIdFinal = affinityGroupId;
|
||||
private AffinityGroupVO getAffinityGroupByName(String account, Long projectId, Long domainId, String affinityGroupName) {
|
||||
AffinityGroupVO group = null;
|
||||
if(account == null && domainId != null){
|
||||
group = _affinityGroupDao.findDomainLevelGroupByName(domainId, affinityGroupName);
|
||||
}else{
|
||||
Long accountId = _accountMgr.finalyzeAccountId(account, domainId, projectId, true);
|
||||
if(accountId == null){
|
||||
Account caller = CallContext.current().getCallingAccount();
|
||||
group = _affinityGroupDao.findByAccountAndName(caller.getAccountId(), affinityGroupName);
|
||||
}else{
|
||||
group = _affinityGroupDao.findByAccountAndName(accountId, affinityGroupName);
|
||||
}
|
||||
}
|
||||
return group;
|
||||
}
|
||||
|
||||
private void deleteAffinityGroup(final Long affinityGroupId) {
|
||||
Transaction.execute(new TransactionCallbackNoReturn() {
|
||||
@Override
|
||||
public void doInTransactionWithoutResult(TransactionStatus status) {
|
||||
|
||||
AffinityGroupVO group = _affinityGroupDao.lockRow(affinityGroupIdFinal, true);
|
||||
AffinityGroupVO group = _affinityGroupDao.lockRow(affinityGroupId, true);
|
||||
if (group == null) {
|
||||
throw new InvalidParameterValueException("Unable to find affinity group by id " + affinityGroupIdFinal);
|
||||
throw new InvalidParameterValueException("Unable to find affinity group by id " + affinityGroupId);
|
||||
}
|
||||
|
||||
List<AffinityGroupVMMapVO> affinityGroupVmMap = _affinityGroupVMMapDao.listByAffinityGroup(affinityGroupIdFinal);
|
||||
List<AffinityGroupVMMapVO> affinityGroupVmMap = _affinityGroupVMMapDao.listByAffinityGroup(affinityGroupId);
|
||||
if (!affinityGroupVmMap.isEmpty()) {
|
||||
SearchBuilder<AffinityGroupVMMapVO> listByAffinityGroup = _affinityGroupVMMapDao.createSearchBuilder();
|
||||
listByAffinityGroup.and("affinityGroupId", listByAffinityGroup.entity().getAffinityGroupId(), SearchCriteria.Op.EQ);
|
||||
listByAffinityGroup.done();
|
||||
SearchCriteria<AffinityGroupVMMapVO> sc = listByAffinityGroup.create();
|
||||
sc.setParameters("affinityGroupId", affinityGroupIdFinal);
|
||||
sc.setParameters("affinityGroupId", affinityGroupId);
|
||||
|
||||
_affinityGroupVMMapDao.lockRows(sc, null, true);
|
||||
_affinityGroupVMMapDao.remove(sc);
|
||||
@ -291,77 +307,15 @@ public class AffinityGroupServiceImpl extends ManagerBase implements AffinityGro
|
||||
processor.handleDeleteGroup(group);
|
||||
}
|
||||
|
||||
if(_affinityGroupDao.expunge(affinityGroupIdFinal)){
|
||||
if(_affinityGroupDao.expunge(affinityGroupId)){
|
||||
AffinityGroupDomainMapVO groupDomain = _affinityGroupDomainMapDao
|
||||
.findByAffinityGroup(affinityGroupIdFinal);
|
||||
.findByAffinityGroup(affinityGroupId);
|
||||
if (groupDomain != null) {
|
||||
_affinityGroupDomainMapDao.remove(groupDomain.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// remove its related ACL permission
|
||||
Pair<Class<?>, Long> params = new Pair<Class<?>, Long>(AffinityGroup.class, affinityGroupIdFinal);
|
||||
_messageBus.publish(_name, EntityManager.MESSAGE_REMOVE_ENTITY_EVENT, PublishScope.LOCAL, params);
|
||||
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Deleted affinity group id=" + affinityGroupId);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<List<? extends AffinityGroup>, Integer> listAffinityGroups(Long affinityGroupId, String affinityGroupName, String affinityGroupType, Long vmId,
|
||||
Long startIndex, Long pageSize) {
|
||||
Filter searchFilter = new Filter(AffinityGroupVO.class, "id", Boolean.TRUE, startIndex, pageSize);
|
||||
|
||||
Account caller = CallContext.current().getCallingAccount();
|
||||
|
||||
Long accountId = caller.getAccountId();
|
||||
Long domainId = caller.getDomainId();
|
||||
|
||||
SearchBuilder<AffinityGroupVMMapVO> vmInstanceSearch = _affinityGroupVMMapDao.createSearchBuilder();
|
||||
vmInstanceSearch.and("instanceId", vmInstanceSearch.entity().getInstanceId(), SearchCriteria.Op.EQ);
|
||||
|
||||
SearchBuilder<AffinityGroupVO> groupSearch = _affinityGroupDao.createSearchBuilder();
|
||||
|
||||
SearchCriteria<AffinityGroupVO> sc = groupSearch.create();
|
||||
|
||||
if (accountId != null) {
|
||||
sc.addAnd("accountId", SearchCriteria.Op.EQ, accountId);
|
||||
}
|
||||
|
||||
if (domainId != null) {
|
||||
sc.addAnd("domainId", SearchCriteria.Op.EQ, domainId);
|
||||
}
|
||||
|
||||
if (affinityGroupId != null) {
|
||||
sc.addAnd("id", SearchCriteria.Op.EQ, affinityGroupId);
|
||||
}
|
||||
|
||||
if (affinityGroupName != null) {
|
||||
sc.addAnd("name", SearchCriteria.Op.EQ, affinityGroupName);
|
||||
}
|
||||
|
||||
if (affinityGroupType != null) {
|
||||
sc.addAnd("type", SearchCriteria.Op.EQ, affinityGroupType);
|
||||
}
|
||||
|
||||
if (vmId != null) {
|
||||
UserVmVO userVM = _userVmDao.findById(vmId);
|
||||
if (userVM == null) {
|
||||
throw new InvalidParameterValueException("Unable to list affinity groups for virtual machine instance " + vmId + "; instance not found.");
|
||||
}
|
||||
_accountMgr.checkAccess(caller, null, true, userVM);
|
||||
// add join to affinity_groups_vm_map
|
||||
groupSearch.join("vmInstanceSearch", vmInstanceSearch, groupSearch.entity().getId(), vmInstanceSearch.entity().getAffinityGroupId(),
|
||||
JoinBuilder.JoinType.INNER);
|
||||
sc.setJoinParameters("vmInstanceSearch", "instanceId", vmId);
|
||||
}
|
||||
|
||||
Pair<List<AffinityGroupVO>, Integer> result = _affinityGroupDao.searchAndCount(sc, searchFilter);
|
||||
return new Pair<List<? extends AffinityGroup>, Integer>(result.first(), result.second());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -458,7 +412,7 @@ public class AffinityGroupServiceImpl extends ManagerBase implements AffinityGro
|
||||
// Verify input parameters
|
||||
UserVmVO vmInstance = _userVmDao.findById(vmId);
|
||||
if (vmInstance == null) {
|
||||
throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId);
|
||||
throw new InvalidParameterValueException("Unable to find a virtual machine with id " + vmId);
|
||||
}
|
||||
|
||||
// Check that the VM is stopped
|
||||
|
||||
@ -167,38 +167,39 @@ public class AffinityApiUnitTest {
|
||||
@Test
|
||||
public void createAffinityGroupTest() {
|
||||
when(_groupDao.isNameInUse(anyLong(), anyLong(), eq("group1"))).thenReturn(false);
|
||||
AffinityGroup group = _affinityService.createAffinityGroup("user", domainId, "group1", "mock", "affinity group one");
|
||||
AffinityGroup group = _affinityService.createAffinityGroup("user", null, domainId, "group1", "mock", "affinity group one");
|
||||
assertNotNull("Affinity group 'group1' of type 'mock' failed to create ", group);
|
||||
|
||||
}
|
||||
|
||||
@Test(expected = InvalidParameterValueException.class)
|
||||
public void invalidAffinityTypeTest() {
|
||||
AffinityGroup group = _affinityService.createAffinityGroup("user", domainId, "group1", "invalid", "affinity group one");
|
||||
AffinityGroup group = _affinityService.createAffinityGroup("user", null, domainId, "group1", "invalid", "affinity group one");
|
||||
|
||||
}
|
||||
|
||||
@Test(expected = InvalidParameterValueException.class)
|
||||
public void uniqueAffinityNameTest() {
|
||||
when(_groupDao.isNameInUse(anyLong(), anyLong(), eq("group1"))).thenReturn(true);
|
||||
AffinityGroup group2 = _affinityService.createAffinityGroup("user", domainId, "group1", "mock", "affinity group two");
|
||||
AffinityGroup group2 = _affinityService.createAffinityGroup("user", null, domainId, "group1", "mock", "affinity group two");
|
||||
}
|
||||
|
||||
@Test(expected = InvalidParameterValueException.class)
|
||||
public void deleteAffinityGroupInvalidIdTest() throws ResourceInUseException {
|
||||
when(_groupDao.findById(20L)).thenReturn(null);
|
||||
_affinityService.deleteAffinityGroup(20L, "user", domainId, "group1");
|
||||
_affinityService.deleteAffinityGroup(20L, "user", null, domainId, "group1");
|
||||
}
|
||||
|
||||
@Test(expected = InvalidParameterValueException.class)
|
||||
public void deleteAffinityGroupInvalidIdName() throws ResourceInUseException {
|
||||
when(_acctMgr.finalyzeAccountId("user", domainId, null, true)).thenReturn(200L);
|
||||
when(_groupDao.findByAccountAndName(200L, "group1")).thenReturn(null);
|
||||
_affinityService.deleteAffinityGroup(null, "user", domainId, "group1");
|
||||
_affinityService.deleteAffinityGroup(null, "user", null, domainId, "group1");
|
||||
}
|
||||
|
||||
@Test(expected = InvalidParameterValueException.class)
|
||||
public void deleteAffinityGroupNullIdName() throws ResourceInUseException {
|
||||
_affinityService.deleteAffinityGroup(null, "user", domainId, null);
|
||||
_affinityService.deleteAffinityGroup(null, "user", null, domainId, null);
|
||||
}
|
||||
|
||||
@Test(expected = InvalidParameterValueException.class)
|
||||
|
||||
@ -0,0 +1,358 @@
|
||||
// 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.affinity;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.mockito.Matchers.anyBoolean;
|
||||
import static org.mockito.Matchers.anyLong;
|
||||
import static org.mockito.Matchers.anyObject;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import com.cloud.utils.db.EntityManager;
|
||||
import com.cloud.event.ActionEventUtils;
|
||||
import com.cloud.user.User;
|
||||
|
||||
import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
|
||||
import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
|
||||
import org.apache.cloudstack.test.utils.SpringUtils;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Matchers;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.ComponentScan.Filter;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.FilterType;
|
||||
import org.springframework.core.type.classreading.MetadataReader;
|
||||
import org.springframework.core.type.classreading.MetadataReaderFactory;
|
||||
import org.springframework.core.type.filter.TypeFilter;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.support.AnnotationConfigContextLoader;
|
||||
import org.apache.cloudstack.acl.ControlledEntity;
|
||||
import org.apache.cloudstack.affinity.dao.AffinityGroupDomainMapDao;
|
||||
import org.apache.cloudstack.api.command.user.affinitygroup.CreateAffinityGroupCmd;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||
import org.apache.cloudstack.framework.messagebus.MessageBus;
|
||||
|
||||
import com.cloud.dc.dao.DedicatedResourceDao;
|
||||
import com.cloud.domain.dao.DomainDao;
|
||||
import com.cloud.event.EventVO;
|
||||
import com.cloud.event.dao.EventDao;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.ResourceInUseException;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountManager;
|
||||
import com.cloud.user.AccountService;
|
||||
import com.cloud.user.AccountVO;
|
||||
import com.cloud.user.DomainManager;
|
||||
import com.cloud.user.UserVO;
|
||||
import com.cloud.user.dao.AccountDao;
|
||||
import com.cloud.user.dao.UserDao;
|
||||
import com.cloud.utils.component.ComponentContext;
|
||||
import com.cloud.vm.UserVmVO;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.dao.UserVmDao;
|
||||
import com.cloud.projects.dao.ProjectDao;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
|
||||
public class AffinityGroupServiceImplTest {
|
||||
|
||||
@Inject
|
||||
AffinityGroupServiceImpl _affinityService;
|
||||
|
||||
@Inject
|
||||
AccountManager _acctMgr;
|
||||
|
||||
@Inject
|
||||
AffinityGroupProcessor _processor;
|
||||
|
||||
@Inject
|
||||
AffinityGroupDao _groupDao;
|
||||
|
||||
@Inject
|
||||
UserVmDao _vmDao;
|
||||
|
||||
@Inject
|
||||
AffinityGroupVMMapDao _affinityGroupVMMapDao;
|
||||
|
||||
@Inject
|
||||
AffinityGroupDao _affinityGroupDao;
|
||||
|
||||
@Inject
|
||||
ActionEventUtils _eventUtils;
|
||||
|
||||
@Inject
|
||||
AccountDao _accountDao;
|
||||
|
||||
@Inject
|
||||
ProjectDao _projectDao;
|
||||
|
||||
@Inject
|
||||
EventDao _eventDao;
|
||||
|
||||
@Inject
|
||||
DedicatedResourceDao _dedicatedDao;
|
||||
|
||||
private static final long DOMAIN_ID = 5L;
|
||||
private static final long PROJECT_ID = 10L;
|
||||
private static final String ACCOUNT_NAME = "user";
|
||||
private static final String AFFINITY_GROUP_NAME = "group1";
|
||||
|
||||
private AccountVO acct;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpClass() throws ConfigurationException {
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
ComponentContext.initComponentsLifeCycle();
|
||||
acct = new AccountVO(200L);
|
||||
acct.setType(Account.ACCOUNT_TYPE_NORMAL);
|
||||
acct.setAccountName(ACCOUNT_NAME);
|
||||
acct.setDomainId(DOMAIN_ID);
|
||||
|
||||
UserVO user = new UserVO(1, "testuser", "password", "firstname", "lastName", "email", "timezone", UUID.randomUUID().toString(), User.Source.UNKNOWN);
|
||||
|
||||
CallContext.register(user, acct);
|
||||
|
||||
when(_processor.getType()).thenReturn("mock");
|
||||
when(_accountDao.findByIdIncludingRemoved(0L)).thenReturn(acct);
|
||||
|
||||
List<AffinityGroupProcessor> affinityProcessors = new ArrayList<AffinityGroupProcessor>();
|
||||
affinityProcessors.add(_processor);
|
||||
_affinityService.setAffinityGroupProcessors(affinityProcessors);
|
||||
|
||||
AffinityGroupVO group = new AffinityGroupVO(AFFINITY_GROUP_NAME, "mock", "mock group", DOMAIN_ID, 200L, ControlledEntity.ACLType.Account);
|
||||
Mockito.when(_affinityGroupDao.persist(Matchers.any(AffinityGroupVO.class))).thenReturn(group);
|
||||
Mockito.when(_affinityGroupDao.findById(Matchers.anyLong())).thenReturn(group);
|
||||
Mockito.when(_affinityGroupDao.findByAccountAndName(Matchers.anyLong(), Matchers.anyString())).thenReturn(group);
|
||||
Mockito.when(_affinityGroupDao.lockRow(Matchers.anyLong(), anyBoolean())).thenReturn(group);
|
||||
Mockito.when(_affinityGroupDao.expunge(Matchers.anyLong())).thenReturn(true);
|
||||
Mockito.when(_eventDao.persist(Matchers.any(EventVO.class))).thenReturn(new EventVO());
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
CallContext.unregister();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createAffinityGroupFromCmdTest() {
|
||||
when(_acctMgr.finalizeOwner((Account)anyObject(), anyString(), anyLong(), anyLong())).thenReturn(acct);
|
||||
when(_groupDao.isNameInUse(anyLong(), anyLong(), eq(AFFINITY_GROUP_NAME))).thenReturn(false);
|
||||
CreateAffinityGroupCmd mockCreateAffinityGroupCmd = Mockito.mock(CreateAffinityGroupCmd.class);
|
||||
when(mockCreateAffinityGroupCmd.getProjectId()).thenReturn(PROJECT_ID);
|
||||
when(mockCreateAffinityGroupCmd.getAffinityGroupName()).thenReturn(AFFINITY_GROUP_NAME);
|
||||
when(mockCreateAffinityGroupCmd.getAffinityGroupType()).thenReturn("mock");
|
||||
when(mockCreateAffinityGroupCmd.getDescription()).thenReturn("affinity group one");
|
||||
AffinityGroup group = _affinityService.createAffinityGroup(mockCreateAffinityGroupCmd);
|
||||
assertNotNull("Affinity group 'group1' of type 'mock' failed to create ", group);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createAffinityGroupTest() {
|
||||
when(_acctMgr.finalizeOwner((Account)anyObject(), anyString(), anyLong(), anyLong())).thenReturn(acct);
|
||||
when(_groupDao.isNameInUse(anyLong(), anyLong(), eq(AFFINITY_GROUP_NAME))).thenReturn(false);
|
||||
AffinityGroup group = _affinityService.createAffinityGroup(ACCOUNT_NAME, null, DOMAIN_ID, AFFINITY_GROUP_NAME, "mock", "affinity group one");
|
||||
assertNotNull("Affinity group 'group1' of type 'mock' failed to create ", group);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldDeleteDomainLevelAffinityGroup() {
|
||||
AffinityGroupVO mockGroup = Mockito.mock(AffinityGroupVO.class);
|
||||
when(mockGroup.getId()).thenReturn(2L);
|
||||
when(_affinityGroupDao.findById(Matchers.anyLong())).thenReturn(mockGroup);
|
||||
_affinityService.deleteAffinityGroup(2L, null, null, DOMAIN_ID, null);
|
||||
Mockito.verify(_affinityGroupDao).expunge(2L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldDeleteAffintyGroupById() {
|
||||
AffinityGroupVO mockGroup = Mockito.mock(AffinityGroupVO.class);
|
||||
when(mockGroup.getId()).thenReturn(1L);
|
||||
when(_affinityGroupDao.findById(Matchers.anyLong())).thenReturn(mockGroup);
|
||||
_affinityService.deleteAffinityGroup(1L, ACCOUNT_NAME, null, DOMAIN_ID, null);
|
||||
Mockito.verify(_affinityGroupDao).expunge(1L);
|
||||
}
|
||||
|
||||
@Test(expected = InvalidParameterValueException.class)
|
||||
public void invalidAffinityTypeTest() {
|
||||
when(_acctMgr.finalizeOwner((Account)anyObject(), anyString(), anyLong(), anyLong())).thenReturn(acct);
|
||||
_affinityService.createAffinityGroup(ACCOUNT_NAME, null, DOMAIN_ID, AFFINITY_GROUP_NAME, "invalid", "affinity group one");
|
||||
|
||||
}
|
||||
|
||||
@Test(expected = InvalidParameterValueException.class)
|
||||
public void uniqueAffinityNameTest() {
|
||||
when(_acctMgr.finalizeOwner((Account)anyObject(), anyString(), anyLong(), anyLong())).thenReturn(acct);
|
||||
when(_groupDao.isNameInUse(anyLong(), anyLong(), eq(AFFINITY_GROUP_NAME))).thenReturn(true);
|
||||
_affinityService.createAffinityGroup(ACCOUNT_NAME, null, DOMAIN_ID, AFFINITY_GROUP_NAME, "mock", "affinity group two");
|
||||
}
|
||||
|
||||
@Test(expected = InvalidParameterValueException.class)
|
||||
public void deleteAffinityGroupInvalidIdTest() throws ResourceInUseException {
|
||||
when(_acctMgr.finalizeOwner((Account)anyObject(), anyString(), anyLong(), anyLong())).thenReturn(acct);
|
||||
when(_groupDao.findById(20L)).thenReturn(null);
|
||||
_affinityService.deleteAffinityGroup(20L, ACCOUNT_NAME, null, DOMAIN_ID, AFFINITY_GROUP_NAME);
|
||||
}
|
||||
|
||||
@Test(expected = InvalidParameterValueException.class)
|
||||
public void deleteAffinityGroupInvalidIdName() throws ResourceInUseException {
|
||||
when(_acctMgr.finalizeOwner((Account)anyObject(), anyString(), anyLong(), anyLong())).thenReturn(acct);
|
||||
when(_acctMgr.finalyzeAccountId(ACCOUNT_NAME, DOMAIN_ID, null, true)).thenReturn(200L);
|
||||
when(_groupDao.findByAccountAndName(200L, AFFINITY_GROUP_NAME)).thenReturn(null);
|
||||
_affinityService.deleteAffinityGroup(null, ACCOUNT_NAME, null, DOMAIN_ID, AFFINITY_GROUP_NAME);
|
||||
}
|
||||
|
||||
@Test(expected = InvalidParameterValueException.class)
|
||||
public void deleteAffinityGroupNullIdName() throws ResourceInUseException {
|
||||
when(_acctMgr.finalizeOwner((Account)anyObject(), anyString(), anyLong(), anyLong())).thenReturn(acct);
|
||||
_affinityService.deleteAffinityGroup(null, ACCOUNT_NAME, null, DOMAIN_ID, null);
|
||||
}
|
||||
|
||||
@Test(expected = InvalidParameterValueException.class)
|
||||
public void updateAffinityGroupVMRunning() throws ResourceInUseException {
|
||||
when(_acctMgr.finalizeOwner((Account)anyObject(), anyString(), anyLong(), anyLong())).thenReturn(acct);
|
||||
UserVmVO vm = new UserVmVO(10L, "test", "test", 101L, HypervisorType.Any, 21L, false, false, DOMAIN_ID, 200L, 1, 5L, "", "test", 1L);
|
||||
vm.setState(VirtualMachine.State.Running);
|
||||
when(_vmDao.findById(10L)).thenReturn(vm);
|
||||
|
||||
List<Long> affinityGroupIds = new ArrayList<Long>();
|
||||
affinityGroupIds.add(20L);
|
||||
|
||||
_affinityService.updateVMAffinityGroups(10L, affinityGroupIds);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ComponentScan(basePackageClasses = {AffinityGroupServiceImpl.class, ActionEventUtils.class}, includeFilters = {@Filter(value = TestConfiguration.Library.class, type = FilterType.CUSTOM)}, useDefaultFilters = false)
|
||||
public static class TestConfiguration extends SpringUtils.CloudStackTestConfiguration {
|
||||
|
||||
@Bean
|
||||
public AccountDao accountDao() {
|
||||
return Mockito.mock(AccountDao.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ProjectDao projectDao() {
|
||||
return Mockito.mock(ProjectDao.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AccountService accountService() {
|
||||
return Mockito.mock(AccountService.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AffinityGroupProcessor affinityGroupProcessor() {
|
||||
return Mockito.mock(AffinityGroupProcessor.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AffinityGroupDao affinityGroupDao() {
|
||||
return Mockito.mock(AffinityGroupDao.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AffinityGroupVMMapDao affinityGroupVMMapDao() {
|
||||
return Mockito.mock(AffinityGroupVMMapDao.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DedicatedResourceDao dedicatedResourceDao() {
|
||||
return Mockito.mock(DedicatedResourceDao.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AccountManager accountManager() {
|
||||
return Mockito.mock(AccountManager.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DomainManager domainManager() {
|
||||
return Mockito.mock(DomainManager.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public EventDao eventDao() {
|
||||
return Mockito.mock(EventDao.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public UserVmDao userVMDao() {
|
||||
return Mockito.mock(UserVmDao.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public UserDao userDao() {
|
||||
return Mockito.mock(UserDao.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AffinityGroupDomainMapDao affinityGroupDomainMapDao() {
|
||||
return Mockito.mock(AffinityGroupDomainMapDao.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public EntityManager entityManager() {
|
||||
return Mockito.mock(EntityManager.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DomainDao domainDao() {
|
||||
return Mockito.mock(DomainDao.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MessageBus messageBus() {
|
||||
return Mockito.mock(MessageBus.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ConfigurationDao configDao() {
|
||||
return Mockito.mock(ConfigurationDao.class);
|
||||
}
|
||||
|
||||
public static class Library implements TypeFilter {
|
||||
|
||||
@Override
|
||||
public boolean match(MetadataReader mdr, MetadataReaderFactory arg1) throws IOException {
|
||||
ComponentScan cs = TestConfiguration.class.getAnnotation(ComponentScan.class);
|
||||
return SpringUtils.includedInBasePackageClasses(mdr.getClassMetadata().getClassName(), cs);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -18,3 +18,35 @@
|
||||
--;
|
||||
-- Schema upgrade from 4.6.0 to 4.6.1;
|
||||
--;
|
||||
DROP VIEW IF EXISTS `cloud`.`affinity_group_view`;
|
||||
CREATE VIEW `affinity_group_view`
|
||||
AS SELECT
|
||||
`affinity_group`.`id` AS `id`,
|
||||
`affinity_group`.`name` AS `name`,
|
||||
`affinity_group`.`type` AS `type`,
|
||||
`affinity_group`.`description` AS `description`,
|
||||
`affinity_group`.`uuid` AS `uuid`,
|
||||
`affinity_group`.`acl_type` AS `acl_type`,
|
||||
`account`.`id` AS `account_id`,
|
||||
`account`.`uuid` AS `account_uuid`,
|
||||
`account`.`account_name` AS `account_name`,
|
||||
`account`.`type` AS `account_type`,
|
||||
`domain`.`id` AS `domain_id`,
|
||||
`domain`.`uuid` AS `domain_uuid`,
|
||||
`domain`.`name` AS `domain_name`,
|
||||
`domain`.`path` AS `domain_path`,
|
||||
`projects`.`id` AS `project_id`,
|
||||
`projects`.`uuid` AS `project_uuid`,
|
||||
`projects`.`name` AS `project_name`,
|
||||
`vm_instance`.`id` AS `vm_id`,
|
||||
`vm_instance`.`uuid` AS `vm_uuid`,
|
||||
`vm_instance`.`name` AS `vm_name`,
|
||||
`vm_instance`.`state` AS `vm_state`,
|
||||
`user_vm`.`display_name` AS `vm_display_name`
|
||||
FROM `affinity_group`
|
||||
JOIN `account` ON`affinity_group`.`account_id` = `account`.`id`
|
||||
JOIN `domain` ON`affinity_group`.`domain_id` = `domain`.`id`
|
||||
LEFT JOIN `projects` ON`projects`.`project_account_id` = `account`.`id`
|
||||
LEFT JOIN `affinity_group_vm_map` ON`affinity_group`.`id` = `affinity_group_vm_map`.`affinity_group_id`
|
||||
LEFT JOIN `vm_instance` ON`vm_instance`.`id` = `affinity_group_vm_map`.`instance_id`
|
||||
LEFT JOIN `user_vm` ON`user_vm`.`id` = `vm_instance`.`id`;
|
||||
|
||||
@ -74,6 +74,27 @@ class CsPassword(CsDataBag):
|
||||
logging.debug("Update password server result ==> %s" % result)
|
||||
|
||||
|
||||
class CsStaticRoutes(CsDataBag):
|
||||
|
||||
def process(self):
|
||||
logging.debug("Processing CsStaticRoutes file ==> %s" % self.dbag)
|
||||
for item in self.dbag:
|
||||
if item == "id":
|
||||
continue
|
||||
self.__update(self.dbag[item])
|
||||
|
||||
def __update(self, route):
|
||||
if route['revoke']:
|
||||
command = "route del -net %s gw %s" % (route['network'], route['gateway'])
|
||||
result = CsHelper.execute(command)
|
||||
else:
|
||||
command = "ip route show | grep %s | awk '{print $1, $3}'" % route['network']
|
||||
result = CsHelper.execute(command)
|
||||
if not result:
|
||||
route_command = "route add -net %s gw %s" % (route['network'], route['gateway'])
|
||||
result = CsHelper.execute(route_command)
|
||||
|
||||
|
||||
class CsAcl(CsDataBag):
|
||||
"""
|
||||
Deal with Network acls
|
||||
@ -932,13 +953,17 @@ def main(argv):
|
||||
mon = CsMonitor("monitorservice", config)
|
||||
mon.process()
|
||||
|
||||
logging.debug("Configuring iptables rules .....")
|
||||
logging.debug("Configuring iptables rules")
|
||||
nf = CsNetfilters()
|
||||
nf.compare(config.get_fw())
|
||||
|
||||
|
||||
red = CsRedundant(config)
|
||||
red.set()
|
||||
|
||||
logging.debug("Configuring static routes")
|
||||
static_routes = CsStaticRoutes("staticroutes", config)
|
||||
static_routes.process()
|
||||
|
||||
logging.debug("Configuring iptables rules done ...saving rules")
|
||||
|
||||
# Save iptables configuration - will be loaded on reboot by the iptables-restore that is configured on /etc/rc.local
|
||||
|
||||
30
systemvm/patches/debian/config/opt/cloud/bin/cs_staticroutes.py
Executable file
30
systemvm/patches/debian/config/opt/cloud/bin/cs_staticroutes.py
Executable file
@ -0,0 +1,30 @@
|
||||
# -- coding: utf-8 --
|
||||
# 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.
|
||||
from pprint import pprint
|
||||
|
||||
|
||||
def merge(dbag, staticroutes):
|
||||
for route in staticroutes['routes']:
|
||||
key = route['ip_address']
|
||||
revoke = route['revoke']
|
||||
if revoke:
|
||||
del dbag[key]
|
||||
else:
|
||||
dbag[key] = route
|
||||
|
||||
return dbag
|
||||
@ -34,6 +34,7 @@ import cs_forwardingrules
|
||||
import cs_site2sitevpn
|
||||
import cs_remoteaccessvpn
|
||||
import cs_vpnusers
|
||||
import cs_staticroutes
|
||||
|
||||
from pprint import pprint
|
||||
|
||||
@ -126,6 +127,8 @@ class updateDataBag:
|
||||
dbag = self.process_remoteaccessvpn(self.db.getDataBag())
|
||||
elif self.qFile.type == 'vpnuserlist':
|
||||
dbag = self.process_vpnusers(self.db.getDataBag())
|
||||
elif self.qFile.type == 'staticroutes':
|
||||
dbag = self.process_staticroutes(self.db.getDataBag())
|
||||
else:
|
||||
logging.error("Error I do not know what to do with file of type %s", self.qFile.type)
|
||||
return
|
||||
@ -172,6 +175,9 @@ class updateDataBag:
|
||||
def process_monitorservice(self, dbag):
|
||||
return cs_monitorservice.merge(dbag, self.qFile.data)
|
||||
|
||||
def process_staticroutes(self, dbag):
|
||||
return cs_staticroutes.merge(dbag, self.qFile.data)
|
||||
|
||||
def processVMpassword(self, dbag):
|
||||
return cs_vmp.merge(dbag, self.qFile.data)
|
||||
|
||||
|
||||
@ -64,7 +64,7 @@ class Services:
|
||||
"type": "host anti-affinity",
|
||||
},
|
||||
"virtual_machine" : {
|
||||
"hypervisor" : "KVM",
|
||||
|
||||
},
|
||||
"new_domain": {
|
||||
"name": "New Domain",
|
||||
|
||||
1082
test/integration/component/test_affinity_groups_projects.py
Normal file
1082
test/integration/component/test_affinity_groups_projects.py
Normal file
File diff suppressed because it is too large
Load Diff
188
test/integration/smoke/test_affinity_groups_projects.py
Normal file
188
test/integration/smoke/test_affinity_groups_projects.py
Normal file
@ -0,0 +1,188 @@
|
||||
#!/usr/bin/env python
|
||||
# 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.
|
||||
|
||||
from marvin.codes import FAILED
|
||||
from marvin.cloudstackTestCase import *
|
||||
from marvin.cloudstackAPI import *
|
||||
from marvin.lib.utils import *
|
||||
from marvin.lib.base import *
|
||||
from marvin.lib.common import *
|
||||
from marvin.sshClient import SshClient
|
||||
from nose.plugins.attrib import attr
|
||||
|
||||
class TestDeployVmWithAffinityGroup(cloudstackTestCase):
|
||||
"""
|
||||
This test deploys a virtual machine for a project
|
||||
using the small service offering and builtin template
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.testClient = super(TestDeployVmWithAffinityGroup, cls).getClsTestClient()
|
||||
zone_name = cls.testClient.getZoneForTests()
|
||||
cls.apiclient = cls.testClient.getApiClient()
|
||||
cls.domain = get_domain(cls.apiclient)
|
||||
cls.services = cls.testClient.getParsedTestDataConfig()
|
||||
# Get Zone, Domain and templates
|
||||
cls.zone = get_zone(cls.apiclient, cls.testClient.getZoneForTests())
|
||||
|
||||
cls.template = get_template(
|
||||
cls.apiclient,
|
||||
cls.zone.id,
|
||||
cls.services["ostype"]
|
||||
)
|
||||
|
||||
if cls.template == FAILED:
|
||||
assert False, "get_template() failed to return template with description %s" % cls.services["ostype"]
|
||||
|
||||
cls.services["virtual_machine"]["zoneid"] = cls.zone.id
|
||||
|
||||
cls.services["template"] = cls.template.id
|
||||
cls.services["zoneid"] = cls.zone.id
|
||||
|
||||
cls.account = Account.create(
|
||||
cls.apiclient,
|
||||
cls.services["account"],
|
||||
domainid=cls.domain.id
|
||||
)
|
||||
|
||||
projectData = {
|
||||
"name": "Project",
|
||||
"displaytext": "Test project",
|
||||
}
|
||||
|
||||
cls.project = Project.create(
|
||||
cls.apiclient,
|
||||
projectData,
|
||||
account=cls.account.name,
|
||||
domainid=cls.account.domainid
|
||||
)
|
||||
|
||||
# Add user to the project
|
||||
cls.project.addAccount(
|
||||
cls.apiclient,
|
||||
cls.account.name
|
||||
)
|
||||
|
||||
cls.service_offering = ServiceOffering.create(
|
||||
cls.apiclient,
|
||||
cls.services["service_offerings"]["tiny"]
|
||||
)
|
||||
|
||||
cls.ag = AffinityGroup.create(cls.apiclient, cls.services["virtual_machine"]["affinity"],projectid=cls.project.id)
|
||||
|
||||
cls._cleanup = [
|
||||
cls.service_offering,
|
||||
cls.ag,
|
||||
cls.project,
|
||||
cls.account,
|
||||
]
|
||||
return
|
||||
|
||||
@attr(tags=["basic", "advanced", "multihost"], required_hardware="false")
|
||||
def test_DeployVmAntiAffinityGroup_in_project(self):
|
||||
"""
|
||||
test DeployVM in anti-affinity groups for project
|
||||
|
||||
deploy VM1 and VM2 in the same host-anti-affinity groups
|
||||
Verify that the vms are deployed on separate hosts
|
||||
"""
|
||||
#deploy VM1 in affinity group created in setUp
|
||||
vm1 = VirtualMachine.create(
|
||||
self.apiclient,
|
||||
self.services["virtual_machine"],
|
||||
templateid=self.template.id,
|
||||
projectid=self.project.id,
|
||||
serviceofferingid=self.service_offering.id,
|
||||
affinitygroupnames=[self.ag.name]
|
||||
)
|
||||
|
||||
list_vm1 = list_virtual_machines(
|
||||
self.apiclient,
|
||||
id=vm1.id
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_vm1, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
self.assertNotEqual(
|
||||
len(list_vm1),
|
||||
0,
|
||||
"Check VM available in List Virtual Machines"
|
||||
)
|
||||
vm1_response = list_vm1[0]
|
||||
self.assertEqual(
|
||||
vm1_response.state,
|
||||
'Running',
|
||||
msg="VM is not in Running state"
|
||||
)
|
||||
self.assertEqual(
|
||||
vm1_response.projectid,
|
||||
self.project.id,
|
||||
msg="VM1 is not deployed in project"
|
||||
)
|
||||
host_of_vm1 = vm1_response.hostid
|
||||
|
||||
#deploy VM2 in affinity group created in setUp
|
||||
vm2 = VirtualMachine.create(
|
||||
self.apiclient,
|
||||
self.services["virtual_machine"],
|
||||
templateid=self.template.id,
|
||||
projectid=self.project.id,
|
||||
serviceofferingid=self.service_offering.id,
|
||||
affinitygroupnames=[self.ag.name]
|
||||
)
|
||||
list_vm2 = list_virtual_machines(
|
||||
self.apiclient,
|
||||
id=vm2.id
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(list_vm2, list),
|
||||
True,
|
||||
"Check list response returns a valid list"
|
||||
)
|
||||
self.assertNotEqual(
|
||||
len(list_vm2),
|
||||
0,
|
||||
"Check VM available in List Virtual Machines"
|
||||
)
|
||||
vm2_response = list_vm2[0]
|
||||
self.assertEqual(
|
||||
vm2_response.state,
|
||||
'Running',
|
||||
msg="VM is not in Running state"
|
||||
)
|
||||
self.assertEqual(
|
||||
vm2_response.projectid,
|
||||
self.project.id,
|
||||
msg="VM2 is not deployed in project"
|
||||
)
|
||||
host_of_vm2 = vm2_response.hostid
|
||||
|
||||
self.assertNotEqual(host_of_vm1, host_of_vm2,
|
||||
msg="Both VMs of affinity group %s are on the same host" % self.ag.name)
|
||||
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
try:
|
||||
#Clean up, terminate the created templates
|
||||
cleanup_resources(cls.apiclient, cls._cleanup)
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
@ -14,6 +14,7 @@
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
from marvin.cloudstackAPI.createStaticRoute import createStaticRouteCmd
|
||||
""" Tests for Network ACLs in VPC
|
||||
"""
|
||||
#Import Local Modules
|
||||
@ -87,6 +88,27 @@ class Services:
|
||||
"NetworkACL": 'VpcVirtualRouter'
|
||||
},
|
||||
},
|
||||
"redundant_vpc_offering": {
|
||||
"name": 'Redundant VPC off',
|
||||
"displaytext": 'Redundant VPC off',
|
||||
"supportedservices": 'Dhcp,Dns,SourceNat,PortForwarding,Vpn,Lb,UserData,StaticNat',
|
||||
"serviceProviderList": {
|
||||
"Vpn": 'VpcVirtualRouter',
|
||||
"Dhcp": 'VpcVirtualRouter',
|
||||
"Dns": 'VpcVirtualRouter',
|
||||
"SourceNat": 'VpcVirtualRouter',
|
||||
"PortForwarding": 'VpcVirtualRouter',
|
||||
"Lb": 'VpcVirtualRouter',
|
||||
"UserData": 'VpcVirtualRouter',
|
||||
"StaticNat": 'VpcVirtualRouter',
|
||||
"NetworkACL": 'VpcVirtualRouter'
|
||||
},
|
||||
"serviceCapabilityList": {
|
||||
"SourceNat": {
|
||||
"RedundantRouter": 'true'
|
||||
}
|
||||
},
|
||||
},
|
||||
"vpc_offering": {
|
||||
"name": "VPC off",
|
||||
"displaytext": "VPC off",
|
||||
@ -112,6 +134,14 @@ class Services:
|
||||
"publicport": 22,
|
||||
"protocol": 'TCP',
|
||||
},
|
||||
"natrule": {
|
||||
"privateport": 22,
|
||||
"publicport": 22,
|
||||
"startport": 22,
|
||||
"endport": 22,
|
||||
"protocol": "TCP",
|
||||
"cidrlist": '0.0.0.0/0',
|
||||
},
|
||||
"ostype": 'CentOS 5.3 (64-bit)',
|
||||
"timeout": 10,
|
||||
}
|
||||
@ -128,10 +158,12 @@ class TestPrivateGwACL(cloudstackTestCase):
|
||||
# Get Zone, Domain and templates
|
||||
cls.domain = get_domain(cls.api_client)
|
||||
cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests())
|
||||
cls.services['mode'] = cls.zone.networktype
|
||||
cls.template = get_template(
|
||||
cls.api_client,
|
||||
cls.zone.id,
|
||||
cls.services["ostype"])
|
||||
|
||||
cls.services["virtual_machine"]["zoneid"] = cls.zone.id
|
||||
cls.services["virtual_machine"]["template"] = cls.template.id
|
||||
|
||||
@ -156,32 +188,14 @@ class TestPrivateGwACL(cloudstackTestCase):
|
||||
def setUp(self):
|
||||
self.apiclient = self.testClient.getApiClient()
|
||||
|
||||
self.logger.debug("Creating Admin Account for Domain ID ==> %s" %self.domain.id)
|
||||
self.logger.debug("Creating Admin Account for Domain ID ==> %s" % self.domain.id)
|
||||
self.account = Account.create(
|
||||
self.apiclient,
|
||||
self.services["account"],
|
||||
admin=True,
|
||||
domainid=self.domain.id)
|
||||
|
||||
self.logger.debug("Creating a VPC offering..")
|
||||
self.vpc_off = VpcOffering.create(
|
||||
self.apiclient,
|
||||
self.services["vpc_offering"])
|
||||
|
||||
self.logger.debug("Enabling the VPC offering created")
|
||||
self.vpc_off.update(self.apiclient, state='Enabled')
|
||||
|
||||
self.logger.debug("Creating a VPC network in the account: %s" % self.account.name)
|
||||
self.services["vpc"]["cidr"] = '10.1.1.1/16'
|
||||
self.vpc = VPC.create(
|
||||
self.apiclient,
|
||||
self.services["vpc"],
|
||||
vpcofferingid=self.vpc_off.id,
|
||||
zoneid=self.zone.id,
|
||||
account=self.account.name,
|
||||
domainid=self.account.domainid)
|
||||
|
||||
self.cleanup = [self.vpc, self.vpc_off, self.account]
|
||||
self.cleanup = []
|
||||
return
|
||||
|
||||
def tearDown(self):
|
||||
@ -191,41 +205,203 @@ class TestPrivateGwACL(cloudstackTestCase):
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
return
|
||||
|
||||
@attr(tags=["advanced"], required_hardware="false")
|
||||
def test_privategw_acl(self):
|
||||
self.createACL()
|
||||
self.createACLItem()
|
||||
self.createNetwork()
|
||||
self.createPvtGw()
|
||||
self.replaceacl()
|
||||
def _replaceAcl(self, command):
|
||||
try:
|
||||
successResponse = self.apiclient.replaceNetworkACLList(command);
|
||||
except Exception as e:
|
||||
self.fail("Failed to replace ACL list due to %s" % e)
|
||||
|
||||
def createACL(self):
|
||||
self.assertTrue(successResponse.success, "Failed to replace ACL list.")
|
||||
|
||||
@attr(tags=["advanced"], required_hardware="true")
|
||||
def test_01_vpc_privategw_acl(self):
|
||||
self.logger.debug("Creating a VPC offering..")
|
||||
vpc_off = VpcOffering.create(
|
||||
self.apiclient,
|
||||
self.services["vpc_offering"])
|
||||
|
||||
self.logger.debug("Enabling the VPC offering created")
|
||||
vpc_off.update(self.apiclient, state='Enabled')
|
||||
|
||||
vpc = self.createVPC(vpc_off)
|
||||
|
||||
self.cleanup = [vpc, vpc_off, self.account]
|
||||
|
||||
physical_networks = get_physical_networks(self.apiclient, self.zone.id)
|
||||
if not physical_networks:
|
||||
self.fail("No Physical Networks found!")
|
||||
|
||||
vlans = physical_networks[0].vlan.split('-')
|
||||
vlan_1 = int(vlans[0])
|
||||
|
||||
acl = self.createACL(vpc)
|
||||
self.createACLItem(acl.id)
|
||||
self.createNetwork(vpc)
|
||||
privateGw = self.createPvtGw(vpc, "10.0.3.99", "10.0.3.100", acl.id, vlan_1)
|
||||
self.replacePvtGwACL(acl.id, privateGw.id)
|
||||
|
||||
@attr(tags=["advanced"], required_hardware="true")
|
||||
def test_02_vpc_privategw_static_routes(self):
|
||||
|
||||
self.logger.debug("Creating a VPC offering..")
|
||||
vpc_off = VpcOffering.create(
|
||||
self.apiclient,
|
||||
self.services["vpc_offering"])
|
||||
|
||||
self.logger.debug("Enabling the VPC offering created")
|
||||
vpc_off.update(self.apiclient, state='Enabled')
|
||||
|
||||
self.performVPCTests(vpc_off)
|
||||
|
||||
@attr(tags=["advanced"], required_hardware="true")
|
||||
def test_03_rvpc_privategw_static_routes(self):
|
||||
self.skipTest("Redundant VPC Routers have to be fixed. Private Gateway not working yet.")
|
||||
|
||||
self.logger.debug("Creating a Redundant VPC offering..")
|
||||
vpc_off = VpcOffering.create(
|
||||
self.apiclient,
|
||||
self.services["redundant_vpc_offering"])
|
||||
|
||||
self.logger.debug("Enabling the Redundant VPC offering created")
|
||||
vpc_off.update(self.apiclient, state='Enabled')
|
||||
|
||||
self.performVPCTests(vpc_off)
|
||||
|
||||
def performVPCTests(self, vpc_off):
|
||||
|
||||
self.logger.debug("Creating VPCs with offering ID %s" % vpc_off.id)
|
||||
vpc_1 = self.createVPC(vpc_off, cidr = '10.0.1.0/24')
|
||||
vpc_2 = self.createVPC(vpc_off, cidr = '10.0.2.0/24')
|
||||
|
||||
self.cleanup = [vpc_1, vpc_2, vpc_off, self.account]
|
||||
|
||||
physical_networks = get_physical_networks(self.apiclient, self.zone.id)
|
||||
if not physical_networks:
|
||||
self.fail("No Physical Networks found!")
|
||||
|
||||
vlans = physical_networks[0].vlan.split('-')
|
||||
vlan_1 = int(vlans[0])
|
||||
|
||||
network_1 = self.createNetwork(vpc_1, gateway = '10.0.1.1')
|
||||
network_2 = self.createNetwork(vpc_2, gateway = '10.0.2.1')
|
||||
|
||||
vm1 = self.createVM(network_1)
|
||||
vm2 = self.createVM(network_2)
|
||||
|
||||
self.cleanup.insert(0, vm1)
|
||||
self.cleanup.insert(0, vm2)
|
||||
|
||||
acl1 = self.createACL(vpc_1)
|
||||
self.createACLItem(acl1.id, cidr = "0.0.0.0/0")
|
||||
privateGw_1 = self.createPvtGw(vpc_1, "10.0.3.100", "10.0.3.101", acl1.id, vlan_1)
|
||||
self.replacePvtGwACL(acl1.id, privateGw_1.id)
|
||||
|
||||
acl2 = self.createACL(vpc_2)
|
||||
self.createACLItem(acl2.id, cidr = "0.0.0.0/0")
|
||||
privateGw_2 = self.createPvtGw(vpc_2, "10.0.3.101", "10.0.3.100", acl2.id, vlan_1)
|
||||
self.replacePvtGwACL(acl2.id, privateGw_2.id)
|
||||
|
||||
self.replaceNetworkAcl(acl1.id, network_1)
|
||||
self.replaceNetworkAcl(acl2.id, network_2)
|
||||
|
||||
staticRoute_1 = self.createStaticRoute(privateGw_1.id, cidr = '10.0.2.0/24')
|
||||
staticRoute_2 = self.createStaticRoute(privateGw_2.id, cidr = '10.0.1.0/24')
|
||||
|
||||
public_ip_1 = self.acquire_publicip(vpc_1, network_1)
|
||||
public_ip_2 = self.acquire_publicip(vpc_2, network_2)
|
||||
|
||||
nat_rule_1 = self.create_natrule(vpc_1, vm1, public_ip_1, network_1)
|
||||
nat_rule_2 = self.create_natrule(vpc_2, vm2, public_ip_2, network_2)
|
||||
|
||||
self.check_pvt_gw_connectivity(vm1, public_ip_1, vm2.nic[0].ipaddress)
|
||||
self.check_pvt_gw_connectivity(vm2, public_ip_2, vm1.nic[0].ipaddress)
|
||||
|
||||
def createVPC(self, vpc_offering, cidr = '10.1.1.1/16'):
|
||||
try:
|
||||
self.logger.debug("Creating a VPC network in the account: %s" % self.account.name)
|
||||
self.services["vpc"]["cidr"] = cidr
|
||||
|
||||
vpc = VPC.create(
|
||||
self.apiclient,
|
||||
self.services["vpc"],
|
||||
vpcofferingid=vpc_offering.id,
|
||||
zoneid=self.zone.id,
|
||||
account=self.account.name,
|
||||
domainid=self.account.domainid)
|
||||
|
||||
self.logger.debug("Created VPC with ID: %s" % vpc.id)
|
||||
except Exception, e:
|
||||
self.fail('Unable to create VPC due to %s ' % e)
|
||||
|
||||
return vpc
|
||||
|
||||
def createVM(self, network):
|
||||
try:
|
||||
self.logger.debug('Creating VM in network=%s' % network.name)
|
||||
vm = VirtualMachine.create(
|
||||
self.apiclient,
|
||||
self.services["virtual_machine"],
|
||||
accountid=self.account.name,
|
||||
domainid=self.account.domainid,
|
||||
serviceofferingid=self.service_offering.id,
|
||||
networkids=[str(network.id)]
|
||||
)
|
||||
self.logger.debug("Created VM with ID: %s" % vm.id)
|
||||
except Exception, e:
|
||||
self.fail('Unable to create virtual machine due to %s ' % e)
|
||||
|
||||
return vm
|
||||
|
||||
def createStaticRoute(self, privateGwId, cidr = '10.0.0.0/16'):
|
||||
staticRouteCmd = createStaticRoute.createStaticRouteCmd()
|
||||
staticRouteCmd.cidr = cidr
|
||||
staticRouteCmd.gatewayid = privateGwId
|
||||
|
||||
try:
|
||||
staticRoute = self.apiclient.createStaticRoute(staticRouteCmd)
|
||||
self.assertIsNotNone(staticRoute.id, "Failed to create static route.")
|
||||
|
||||
self.logger.debug("Created staticRoute with ID: %s" % staticRoute.id)
|
||||
except Exception, e:
|
||||
self.fail('Unable to create static route due to %s ' % e)
|
||||
|
||||
return staticRoute
|
||||
|
||||
def createACL(self, vpc):
|
||||
createAclCmd = createNetworkACLList.createNetworkACLListCmd()
|
||||
createAclCmd.name = "acl1"
|
||||
createAclCmd.description = "new acl"
|
||||
createAclCmd.vpcid = self.vpc.id
|
||||
createAclResponse = self.apiclient.createNetworkACLList(createAclCmd)
|
||||
createAclCmd.name = "ACL-Test-%s" % vpc.id
|
||||
createAclCmd.description = createAclCmd.name
|
||||
createAclCmd.vpcid = vpc.id
|
||||
try:
|
||||
acl = self.apiclient.createNetworkACLList(createAclCmd)
|
||||
self.assertIsNotNone(acl.id, "Failed to create ACL.")
|
||||
|
||||
self.aclId = createAclResponse.id
|
||||
self.logger.debug("Created ACL with ID: %s" % acl.id)
|
||||
except Exception, e:
|
||||
self.fail('Unable to create ACL due to %s ' % e)
|
||||
|
||||
self.assertIsNotNone(self.aclId, "Failed to create ACL.")
|
||||
return acl
|
||||
|
||||
def createACLItem(self):
|
||||
def createACLItem(self, aclId, cidr = "0.0.0.0/0"):
|
||||
createAclItemCmd = createNetworkACL.createNetworkACLCmd()
|
||||
createAclItemCmd.cidr = "0.0.0.0/0"
|
||||
createAclItemCmd.protocol = "TCP"
|
||||
createAclItemCmd.cidr = cidr
|
||||
createAclItemCmd.protocol = "All"
|
||||
createAclItemCmd.number = "1"
|
||||
createAclItemCmd.action = "Deny"
|
||||
createAclItemCmd.aclid = self.aclId
|
||||
createAclItemResponse = self.apiclient.createNetworkACL(createAclItemCmd)
|
||||
createAclItemCmd.action = "Allow"
|
||||
createAclItemCmd.aclid = aclId
|
||||
try:
|
||||
aclItem = self.apiclient.createNetworkACL(createAclItemCmd)
|
||||
self.assertIsNotNone(aclItem.id, "Failed to create ACL item.")
|
||||
|
||||
self.assertIsNotNone(createAclItemResponse.id, "Failed to create ACL item.")
|
||||
self.logger.debug("Created ACL Item ID: %s" % aclItem.id)
|
||||
except Exception, e:
|
||||
self.fail('Unable to create ACL Item due to %s ' % e)
|
||||
|
||||
def createNetwork(self):
|
||||
def createNetwork(self, vpc, gateway = '10.1.1.1'):
|
||||
try:
|
||||
self.logger.debug('Create NetworkOffering')
|
||||
net_offerring = self.services["network_offering"]
|
||||
net_offerring["name"] = "NET_OFF-10.1.1.1"
|
||||
net_offerring["name"] = "NET_OFF-%s" % gateway
|
||||
nw_off = NetworkOffering.create(
|
||||
self.apiclient,
|
||||
net_offerring,
|
||||
@ -235,7 +411,7 @@ class TestPrivateGwACL(cloudstackTestCase):
|
||||
|
||||
self.logger.debug('Created and Enabled NetworkOffering')
|
||||
|
||||
self.services["network"]["name"] = "NETWORK-10.1.1.1"
|
||||
self.services["network"]["name"] = "NETWORK-%s" % gateway
|
||||
|
||||
self.logger.debug('Adding Network=%s' % self.services["network"])
|
||||
obj_network = Network.create(
|
||||
@ -245,43 +421,125 @@ class TestPrivateGwACL(cloudstackTestCase):
|
||||
domainid=self.account.domainid,
|
||||
networkofferingid=nw_off.id,
|
||||
zoneid=self.zone.id,
|
||||
gateway="10.1.1.1",
|
||||
vpcid=self.vpc.id
|
||||
gateway=gateway,
|
||||
vpcid=vpc.id
|
||||
)
|
||||
|
||||
self.logger.debug("Created network with ID: %s" % obj_network.id)
|
||||
except Exception, e:
|
||||
self.fail('Unable to create a Network with offering=%s because of %s ' % (net_offerring, e))
|
||||
|
||||
self.network = obj_network
|
||||
|
||||
self.cleanup.insert(0, nw_off)
|
||||
self.cleanup.insert(0, obj_network)
|
||||
|
||||
def createPvtGw(self):
|
||||
return obj_network
|
||||
|
||||
def createPvtGw(self, vpc, ip_address, gateway, aclId, vlan):
|
||||
physical_networks = get_physical_networks(self.apiclient, self.zone.id)
|
||||
if not physical_networks:
|
||||
self.fail("No Physical Networks found!")
|
||||
|
||||
self.logger.debug('::: Physical Networks ::: ==> %s' % physical_networks)
|
||||
|
||||
createPrivateGatewayCmd = createPrivateGateway.createPrivateGatewayCmd()
|
||||
createPrivateGatewayCmd.physicalnetworkid = 200
|
||||
createPrivateGatewayCmd.gateway = "10.147.30.1"
|
||||
createPrivateGatewayCmd.physicalnetworkid = physical_networks[0].id
|
||||
createPrivateGatewayCmd.gateway = gateway
|
||||
createPrivateGatewayCmd.netmask = "255.255.255.0"
|
||||
createPrivateGatewayCmd.ipaddress = "10.147.30.200"
|
||||
createPrivateGatewayCmd.vlan = "30"
|
||||
createPrivateGatewayCmd.vpcid = self.vpc.id
|
||||
createPrivateGatewayCmd.sourcenatsupported = "true"
|
||||
createPrivateGatewayCmd.aclid = self.aclId
|
||||
createPrivateGatewayCmd.ipaddress = ip_address
|
||||
createPrivateGatewayCmd.vlan = vlan
|
||||
createPrivateGatewayCmd.vpcid = vpc.id
|
||||
createPrivateGatewayCmd.sourcenatsupported = "false"
|
||||
createPrivateGatewayCmd.aclid = aclId
|
||||
|
||||
try:
|
||||
privateGatewayResponse = self.apiclient.createPrivateGateway(createPrivateGatewayCmd)
|
||||
privateGw = self.apiclient.createPrivateGateway(createPrivateGatewayCmd)
|
||||
except Exception as e:
|
||||
self.fail("Failed to create Private Gateway ==> %s" % e)
|
||||
|
||||
self.privateGwId = privateGatewayResponse.id
|
||||
self.assertIsNotNone(privateGw.id, "Failed to create ACL.")
|
||||
|
||||
return privateGw
|
||||
|
||||
self.assertIsNotNone(self.privateGwId, "Failed to create ACL.")
|
||||
def replaceNetworkAcl(self, aclId, network):
|
||||
self.logger.debug("Replacing Network ACL with ACL ID ==> %s" % aclId)
|
||||
|
||||
def replaceacl(self):
|
||||
replaceNetworkACLListCmd = replaceNetworkACLList.replaceNetworkACLListCmd()
|
||||
replaceNetworkACLListCmd.aclid = self.aclId
|
||||
replaceNetworkACLListCmd.gatewayid = self.privateGwId
|
||||
successResponse = self.apiclient.replaceNetworkACLList(replaceNetworkACLListCmd);
|
||||
replaceNetworkACLListCmd.aclid = aclId
|
||||
replaceNetworkACLListCmd.networkid = network.id
|
||||
|
||||
self.assertTrue(successResponse.success, "Failed to replace ACL list.")
|
||||
self._replaceAcl(replaceNetworkACLListCmd)
|
||||
|
||||
def replacePvtGwACL(self, aclId, privateGwId):
|
||||
self.logger.debug("Replacing Private GW ACL with ACL ID ==> %s" % aclId)
|
||||
|
||||
replaceNetworkACLListCmd = replaceNetworkACLList.replaceNetworkACLListCmd()
|
||||
replaceNetworkACLListCmd.aclid = aclId
|
||||
replaceNetworkACLListCmd.gatewayid = privateGwId
|
||||
|
||||
self._replaceAcl(replaceNetworkACLListCmd)
|
||||
|
||||
def acquire_publicip(self, vpc, network):
|
||||
self.logger.debug("Associating public IP for network: %s" % network.name)
|
||||
public_ip = PublicIPAddress.create(
|
||||
self.apiclient,
|
||||
accountid=self.account.name,
|
||||
zoneid=self.zone.id,
|
||||
domainid=self.account.domainid,
|
||||
networkid=network.id,
|
||||
vpcid=vpc.id
|
||||
)
|
||||
self.logger.debug("Associated %s with network %s" % (
|
||||
public_ip.ipaddress.ipaddress,
|
||||
network.id
|
||||
))
|
||||
|
||||
return public_ip
|
||||
|
||||
def create_natrule(self, vpc, virtual_machine, public_ip, network):
|
||||
self.logger.debug("Creating NAT rule in network for vm with public IP")
|
||||
|
||||
nat_service = self.services["natrule"]
|
||||
nat_rule = NATRule.create(
|
||||
self.apiclient,
|
||||
virtual_machine,
|
||||
nat_service,
|
||||
ipaddressid=public_ip.ipaddress.id,
|
||||
openfirewall=False,
|
||||
networkid=network.id,
|
||||
vpcid=vpc.id)
|
||||
|
||||
self.logger.debug("Adding NetworkACL rules to make NAT rule accessible")
|
||||
nwacl_nat = NetworkACL.create(
|
||||
self.apiclient,
|
||||
networkid=network.id,
|
||||
services=nat_service,
|
||||
traffictype='Ingress'
|
||||
)
|
||||
self.logger.debug('nwacl_nat=%s' % nwacl_nat.__dict__)
|
||||
|
||||
return nat_rule
|
||||
|
||||
def check_pvt_gw_connectivity(self, virtual_machine, public_ip, vm_ip):
|
||||
ssh_command = "ping -c 3 %s" % vm_ip
|
||||
|
||||
# Should be able to SSH VM
|
||||
result = 'failed'
|
||||
try:
|
||||
self.logger.debug("SSH into VM: %s" % public_ip.ipaddress.ipaddress)
|
||||
|
||||
ssh = virtual_machine.get_ssh_client(ipaddress=public_ip.ipaddress.ipaddress)
|
||||
|
||||
self.logger.debug("Ping to VM inside another VPC")
|
||||
result = str(ssh.execute(ssh_command))
|
||||
|
||||
self.logger.debug("SSH result: %s; COUNT is ==> %s" % (result, result.count("3 packets received")))
|
||||
except Exception as e:
|
||||
self.fail("SSH Access failed for %s: %s" % \
|
||||
(vmObj.get_ip(), e)
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
result.count("3 packets received"),
|
||||
1,
|
||||
"Ping to outside world from VM should be successful"
|
||||
)
|
||||
|
||||
@ -4220,7 +4220,7 @@ class AffinityGroup:
|
||||
self.__dict__.update(items)
|
||||
|
||||
@classmethod
|
||||
def create(cls, apiclient, aff_grp, account=None, domainid=None):
|
||||
def create(cls, apiclient, aff_grp, account=None, domainid=None, projectid=None):
|
||||
cmd = createAffinityGroup.createAffinityGroupCmd()
|
||||
cmd.name = aff_grp['name']
|
||||
cmd.displayText = aff_grp['name']
|
||||
@ -4229,6 +4229,8 @@ class AffinityGroup:
|
||||
cmd.account = account
|
||||
if domainid:
|
||||
cmd.domainid = domainid
|
||||
if projectid:
|
||||
cmd.projectid = projectid
|
||||
return AffinityGroup(apiclient.createAffinityGroup(cmd).__dict__)
|
||||
|
||||
def update(self, apiclient):
|
||||
|
||||
@ -259,6 +259,17 @@ def get_zone(apiclient, zone_name=None, zone_id=None):
|
||||
'''
|
||||
return cmd_out[0]
|
||||
|
||||
def get_physical_networks(apiclient, zoneid):
|
||||
'''
|
||||
@name : get_physical_networks
|
||||
@Desc :Returns A list of the Physical Networks in the given Zone
|
||||
@Input : zoneid: The Zone ID
|
||||
@Output : 1. A list containing the Physical Networks
|
||||
'''
|
||||
cmd = listPhysicalNetworks.listPhysicalNetworksCmd()
|
||||
cmd.zoneid = zoneid
|
||||
physical_networks = apiclient.listPhysicalNetworks(cmd)
|
||||
return physical_networks
|
||||
|
||||
def get_pod(apiclient, zone_id=None, pod_id=None, pod_name=None):
|
||||
'''
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user