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:
Remi Bergsma 2015-12-03 20:42:41 +01:00
commit 7e902cd505
29 changed files with 2372 additions and 515 deletions

View File

@ -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) {

View File

@ -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);
}

View File

@ -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());

View File

@ -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);

View File

@ -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

View File

@ -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);
}

View File

@ -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) {

View File

@ -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);
}

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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();

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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)

View File

@ -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);
}
}
}
}

View File

@ -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`;

View File

@ -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

View 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

View File

@ -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)

View File

@ -64,7 +64,7 @@ class Services:
"type": "host anti-affinity",
},
"virtual_machine" : {
"hypervisor" : "KVM",
},
"new_domain": {
"name": "New Domain",

File diff suppressed because it is too large Load Diff

View 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)

View File

@ -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"
)

View File

@ -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):

View File

@ -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):
'''