Merge pull request #2124 from GabrielBrascher/CLOUDSTACK-9432

CLOUDSTACK-9432: cluster/host dedicated to a domain is owned by the root domain
This commit is contained in:
Gabriel Beims Bräscher 2017-11-28 10:31:23 -02:00 committed by GitHub
commit bd5604428b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 77 additions and 39 deletions

View File

@ -158,7 +158,7 @@ public class AffinityGroupServiceImpl extends ManagerBase implements AffinityGro
verifyAffinityGroupNameInUse(owner.getAccountId(), owner.getDomainId(), affinityGroupName);
verifyDomainLevelAffinityGroupName(domainLevel, owner.getDomainId(), affinityGroupName);
AffinityGroupVO group = createAffinityGroup(processor, owner, aclType, affinityGroupName, affinityGroupType, description);
AffinityGroupVO group = createAffinityGroup(processor, owner, aclType, affinityGroupName, affinityGroupType, description, domainLevel, domainId);
if (s_logger.isDebugEnabled()) {
s_logger.debug("Created affinity group =" + affinityGroupName);
@ -176,25 +176,27 @@ public class AffinityGroupServiceImpl extends ManagerBase implements AffinityGro
}
}
private AffinityGroupVO createAffinityGroup(final AffinityGroupProcessor processor, final Account owner, final ACLType aclType, final String affinityGroupName, final String affinityGroupType, final String description) {
private AffinityGroupVO createAffinityGroup(final AffinityGroupProcessor processor, final Account owner, final ACLType aclType, final String affinityGroupName, final String affinityGroupType, final String description, boolean domainLevel, Long domainId) {
final Long affinityGroupDomainId = getDomainIdBasedOnDomainLevel(owner, domainLevel, domainId);
return Transaction.execute(new TransactionCallback<AffinityGroupVO>() {
@Override
public AffinityGroupVO doInTransaction(TransactionStatus status) {
AffinityGroupVO group =
new AffinityGroupVO(affinityGroupName, affinityGroupType, description, owner.getDomainId(), owner.getId(), aclType);
AffinityGroupVO group = new AffinityGroupVO(affinityGroupName, affinityGroupType, description, affinityGroupDomainId, owner.getId(), aclType);
_affinityGroupDao.persist(group);
if (aclType == ACLType.Domain) {
boolean subDomainAccess = false;
subDomainAccess = processor.subDomainAccess();
AffinityGroupDomainMapVO domainMap = new AffinityGroupDomainMapVO(group.getId(), owner.getDomainId(),
AffinityGroupDomainMapVO domainMap = new AffinityGroupDomainMapVO(group.getId(), affinityGroupDomainId,
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.DOMAIN_ID, affinityGroupDomainId);
params.put(ApiConstants.SUBDOMAIN_ACCESS, subDomainAccess);
_messageBus.publish(_name, EntityManager.MESSAGE_ADD_DOMAIN_WIDE_ENTITY_EVENT, PublishScope.LOCAL,
params);
@ -205,6 +207,20 @@ public class AffinityGroupServiceImpl extends ManagerBase implements AffinityGro
});
}
/**
* If the account is null (domainLevel is true), then returns the domain id passed as a
* parameter; otherwise (domainLevel is false) it returns the domain id from the owner account.
*
* @note: this method fixes a critical bug. More details in JIRA ticket CLOUDSTACK-9432.
*/
protected Long getDomainIdBasedOnDomainLevel(final Account owner, boolean domainLevel, Long domainId) {
Long domainIdBasedOnDomainLevel = owner.getDomainId();
if (domainLevel) {
domainIdBasedOnDomainLevel = domainId;
}
return domainIdBasedOnDomainLevel;
}
private DomainVO getDomain(Long domainId) {
DomainVO domain = _domainDao.findById(domainId);
if (domain == null) {
@ -225,6 +241,7 @@ public class AffinityGroupServiceImpl extends ManagerBase implements AffinityGro
}
}
@Override
@DB
@ActionEvent(eventType = EventTypes.EVENT_AFFINITY_GROUP_DELETE, eventDescription = "Deleting affinity group")
public boolean deleteAffinityGroup(Long affinityGroupId, String account, Long projectId, Long domainId, String affinityGroupName) {

View File

@ -32,12 +32,14 @@ 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.acl.ControlledEntity;
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.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 org.apache.cloudstack.test.utils.SpringUtils;
import org.junit.After;
import org.junit.Before;
@ -57,33 +59,32 @@ 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.ActionEventUtils;
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.projects.dao.ProjectDao;
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.User;
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.utils.db.EntityManager;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.projects.dao.ProjectDao;
import org.junit.Assert;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
@ -191,6 +192,26 @@ public class AffinityGroupServiceImplTest {
}
private AccountVO mockOwnerForTestGetDomainIdBasedOnDomainLevel() {
AccountVO mockOwner = Mockito.mock(AccountVO.class);
when(mockOwner.getDomainId()).thenReturn(0l);
return mockOwner;
}
@Test
public void getDomainIdBasedOnDomainLevelTestDomainLevelTrue() {
AccountVO owner = mockOwnerForTestGetDomainIdBasedOnDomainLevel();
Long domainIdBasedOnDomainLevel = _affinityService.getDomainIdBasedOnDomainLevel(owner, true, 1l);
Assert.assertEquals(new Long(1), domainIdBasedOnDomainLevel);
}
@Test
public void getDomainIdBasedOnDomainLevelTestDomainLevelFalse() {
AccountVO owner = mockOwnerForTestGetDomainIdBasedOnDomainLevel();
Long domainIdBasedOnDomainLevel = _affinityService.getDomainIdBasedOnDomainLevel(owner, false, 1l);
Assert.assertEquals(new Long(0), domainIdBasedOnDomainLevel);
}
@Test
public void shouldDeleteDomainLevelAffinityGroup() {
AffinityGroupVO mockGroup = Mockito.mock(AffinityGroupVO.class);