Add policies to domain group for CreateNetwork usecase for a domain wide shared network

This commit is contained in:
Prachi Damle 2014-01-29 23:47:08 -08:00
parent ce95f3122b
commit d12422bf68
10 changed files with 119 additions and 28 deletions

View File

@ -36,6 +36,7 @@ import javax.ejb.Local;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.apache.cloudstack.acl.AclEntityType;
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
@ -43,6 +44,8 @@ import org.apache.cloudstack.framework.config.ConfigDepot;
import org.apache.cloudstack.framework.config.ConfigKey;
import org.apache.cloudstack.framework.config.Configurable;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.cloudstack.framework.messagebus.MessageBus;
import org.apache.cloudstack.framework.messagebus.PublishScope;
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
import org.apache.cloudstack.region.PortableIpDao;
import org.apache.log4j.Logger;
@ -253,6 +256,8 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
protected IPAddressDao _publicIpAddressDao;
@Inject
protected IpAddressManager _ipAddrMgr;
@Inject
MessageBus _messageBus;
List<NetworkGuru> networkGurus;
@ -664,6 +669,11 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
if (domainId != null && aclType == ACLType.Domain) {
_networksDao.addDomainToNetwork(id, domainId, subdomainAccess == null ? true : subdomainAccess);
//send event for storing the domain wide resource access
// remove its related ACL permission
Pair<AclEntityType, Long> network = new Pair<AclEntityType, Long>(AclEntityType.Network, id);
_messageBus.publish(_name, EntityManager.MESSAGE_ADD_DOMAIN_WIDE_ENTITY_EVENT,
PublishScope.LOCAL, network);
}
}
});

View File

@ -120,19 +120,19 @@ public class RoleBasedAPIAccessChecker extends AdapterBase implements APIChecker
// add the system-domain capability
_iamSrv.addAclPermissionToAclPolicy(new Long(Account.ACCOUNT_TYPE_ADMIN + 1), null, null, null,
"SystemCapability", null, Permission.Allow);
"SystemCapability", null, Permission.Allow, false);
_iamSrv.addAclPermissionToAclPolicy(new Long(Account.ACCOUNT_TYPE_DOMAIN_ADMIN + 1), null, null, null,
"DomainCapability", null, Permission.Allow);
"DomainCapability", null, Permission.Allow, false);
_iamSrv.addAclPermissionToAclPolicy(new Long(Account.ACCOUNT_TYPE_RESOURCE_DOMAIN_ADMIN + 1), null, null, null,
"DomainResourceCapability", null, Permission.Allow);
"DomainResourceCapability", null, Permission.Allow, false);
// add permissions for public templates
List<VMTemplateVO> pTmplts = _templateDao.listByPublic();
for (VMTemplateVO tmpl : pTmplts){
_iamSrv.addAclPermissionToAclPolicy(new Long(Account.ACCOUNT_TYPE_DOMAIN_ADMIN + 1), AclEntityType.VirtualMachineTemplate.toString(),
PermissionScope.RESOURCE.toString(), tmpl.getId(), "listTemplates", AccessType.UseEntry.toString(), Permission.Allow);
PermissionScope.RESOURCE.toString(), tmpl.getId(), "listTemplates", AccessType.UseEntry.toString(), Permission.Allow, false);
_iamSrv.addAclPermissionToAclPolicy(new Long(Account.ACCOUNT_TYPE_NORMAL + 1), AclEntityType.VirtualMachineTemplate.toString(),
PermissionScope.RESOURCE.toString(), tmpl.getId(), "listTemplates", AccessType.UseEntry.toString(), Permission.Allow);
PermissionScope.RESOURCE.toString(), tmpl.getId(), "listTemplates", AccessType.UseEntry.toString(), Permission.Allow, false);
}
for (PluggableService service : _services) {
@ -256,11 +256,11 @@ public class RoleBasedAPIAccessChecker extends AdapterBase implements APIChecker
if (entityTypes == null || entityTypes.length == 0) {
_iamSrv.addAclPermissionToAclPolicy(policyId, null, permissionScope.toString(), new Long(AclPolicyPermission.PERMISSION_SCOPE_ID_CURRENT_CALLER),
apiName, (accessType == null) ? null : accessType.toString(), Permission.Allow);
apiName, (accessType == null) ? null : accessType.toString(), Permission.Allow, false);
} else {
for (AclEntityType entityType : entityTypes) {
_iamSrv.addAclPermissionToAclPolicy(policyId, entityType.toString(), permissionScope.toString(), new Long(AclPolicyPermission.PERMISSION_SCOPE_ID_CURRENT_CALLER),
apiName, (accessType == null) ? null : accessType.toString(), Permission.Allow);
apiName, (accessType == null) ? null : accessType.toString(), Permission.Allow, false);
}
}

View File

@ -59,7 +59,8 @@ public interface AclApiService extends PluggableService {
void removeAclPolicyFromAccounts(Long policyId, List<Long> accountIds);
AclPolicy addAclPermissionToAclPolicy(long aclPolicyId, String entityType, PermissionScope scope, Long scopeId, String action, Permission perm);
AclPolicy addAclPermissionToAclPolicy(long aclPolicyId, String entityType, PermissionScope scope, Long scopeId,
String action, Permission perm, Boolean recursive);
AclPolicy removeAclPermissionFromAclPolicy(long aclPolicyId, String entityType, PermissionScope scope, Long scopeId, String action);

View File

@ -67,6 +67,8 @@ import com.cloud.domain.dao.DomainDao;
import com.cloud.event.ActionEvent;
import com.cloud.event.EventTypes;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.network.dao.NetworkDomainDao;
import com.cloud.network.dao.NetworkDomainVO;
import com.cloud.template.TemplateManager;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
@ -103,6 +105,9 @@ public class AclApiServiceImpl extends ManagerBase implements AclApiService, Man
@Inject
MessageBus _messageBus;
@Inject
NetworkDomainDao _networkDomainDao;
@Override
public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
_messageBus.subscribe(AccountManager.MESSAGE_ADD_ACCOUNT_EVENT, new MessageSubscriber() {
@ -118,10 +123,10 @@ public class AclApiServiceImpl extends ManagerBase implements AclApiService, Man
AccountVO account = _accountDao.findById(accountId);
Domain domain = _domainDao.findById(account.getDomainId());
if (domain != null) {
ListResponse<AclGroupResponse> domainGroups = listAclGroups(null,
"DomainGrp-" + domain.getUuid(), domain.getId(), null, null);
if (domainGroups.getResponses() != null) {
for (AclGroupResponse group : domainGroups.getResponses()) {
List<AclGroup> domainGroups = listDomainGroup(domain);
if (domainGroups != null) {
for (AclGroup group : domainGroups) {
addAccountToAclGroup(accountId, new Long(group.getId()));
}
}
@ -161,9 +166,9 @@ public class AclApiServiceImpl extends ManagerBase implements AclApiService, Man
if (templateId != null) {
s_logger.debug("MessageBus message: new public template registered: " + templateId + ", grant permission to domain admin and normal user policies");
_iamSrv.addAclPermissionToAclPolicy(new Long(Account.ACCOUNT_TYPE_DOMAIN_ADMIN + 1), AclEntityType.VirtualMachineTemplate.toString(),
PermissionScope.RESOURCE.toString(), templateId, "listTemplates", AccessType.UseEntry.toString(), Permission.Allow);
PermissionScope.RESOURCE.toString(), templateId, "listTemplates", AccessType.UseEntry.toString(), Permission.Allow, false);
_iamSrv.addAclPermissionToAclPolicy(new Long(Account.ACCOUNT_TYPE_NORMAL + 1), AclEntityType.VirtualMachineTemplate.toString(),
PermissionScope.RESOURCE.toString(), templateId, "listTemplates", AccessType.UseEntry.toString(), Permission.Allow);
PermissionScope.RESOURCE.toString(), templateId, "listTemplates", AccessType.UseEntry.toString(), Permission.Allow, false);
}
}
});
@ -181,6 +186,7 @@ public class AclApiServiceImpl extends ManagerBase implements AclApiService, Man
}
});
_messageBus.subscribe(EntityManager.MESSAGE_GRANT_ENTITY_EVENT, new MessageSubscriber() {
@Override
public void onPublishMessage(String senderAddress, String subject, Object obj) {
@ -197,9 +203,58 @@ public class AclApiServiceImpl extends ManagerBase implements AclApiService, Man
}
});
_messageBus.subscribe(EntityManager.MESSAGE_ADD_DOMAIN_WIDE_ENTITY_EVENT, new MessageSubscriber() {
@Override
public void onPublishMessage(String senderAddress, String subject, Object obj) {
Pair<AclEntityType, Long> entity = (Pair<AclEntityType, Long>) obj;
if (entity != null) {
addDomainWideResourceAccess(entity);
}
}
});
return super.configure(name, params);
}
private void addDomainWideResourceAccess(Pair<AclEntityType, Long> entity) {
String entityType = entity.first().toString();
Long entityId = entity.second();
if (AclEntityType.Network.toString().equals(entityType)) {
NetworkDomainVO networkDomainMap = _networkDomainDao.getDomainNetworkMapByNetworkId(entityId);
if (networkDomainMap != null) {
createPolicyAndAddToDomainGroup("DomainWideNetwork-" + entityId, "domain wide network", entityType,
entityId, "listNetworks", AccessType.UseEntry, networkDomainMap.getDomainId(),
networkDomainMap.isSubdomainAccess());
}
} else if (AclEntityType.AffinityGroup.toString().equals(entityType)) {
}
}
private void createPolicyAndAddToDomainGroup(String policyName, String description, String entityType,
Long entityId, String action, AccessType accessType, Long domainId, Boolean recursive) {
AclPolicy policy = _iamSrv.createAclPolicy(policyName, description, null);
_iamSrv.addAclPermissionToAclPolicy(policy.getId(), entityType, PermissionScope.RESOURCE.toString(),
entityId, action, accessType.toString(), Permission.Allow, recursive);
List<Long> policyList = new ArrayList<Long>();
policyList.add(new Long(policy.getId()));
Domain domain = _domainDao.findById(domainId);
if (domain != null) {
List<AclGroup> domainGroups = listDomainGroup(domain);
if (domainGroups != null) {
for (AclGroup group : domainGroups) {
_iamSrv.attachAclPoliciesToGroup(policyList, group.getId());
}
}
}
}
@DB
@Override
@ActionEvent(eventType = EventTypes.EVENT_ACL_GROUP_CREATE, eventDescription = "Creating Acl Group", create = true)
@ -309,13 +364,15 @@ public class AclApiServiceImpl extends ManagerBase implements AclApiService, Man
@DB
@Override
@ActionEvent(eventType = EventTypes.EVENT_ACL_POLICY_GRANT, eventDescription = "Granting acl permission to Acl Policy")
public AclPolicy addAclPermissionToAclPolicy(long aclPolicyId, String entityType, PermissionScope scope, Long scopeId, String action, Permission perm) {
public AclPolicy addAclPermissionToAclPolicy(long aclPolicyId, String entityType, PermissionScope scope,
Long scopeId, String action, Permission perm, Boolean recursive) {
Class<?> cmdClass = _apiServer.getCmdClass(action);
AccessType accessType = null;
if (BaseListCmd.class.isAssignableFrom(cmdClass)) {
accessType = AccessType.ListEntry;
}
return _iamSrv.addAclPermissionToAclPolicy(aclPolicyId, entityType, scope.toString(), scopeId, action, accessType.toString(), perm);
return _iamSrv.addAclPermissionToAclPolicy(aclPolicyId, entityType, scope.toString(), scopeId, action,
accessType.toString(), perm, recursive);
}
@DB
@ -426,6 +483,19 @@ public class AclApiServiceImpl extends ManagerBase implements AclApiService, Man
}
public List<AclGroup> listDomainGroup(Domain domain) {
if (domain != null) {
String domainPath = domain.getPath();
// search for groups
Pair<List<AclGroup>, Integer> result = _iamSrv.listAclGroups(null, "DomainGrp-" + domain.getUuid(),
domainPath, null, null);
return result.first();
}
return new ArrayList<AclGroup>();
}
@Override
public ListResponse<AclGroupResponse> listAclGroups(Long aclGroupId, String aclGroupName, Long domainId, Long startIndex, Long pageSize) {
// acl check
@ -498,7 +568,7 @@ public class AclApiServiceImpl extends ManagerBase implements AclApiService, Man
String description = "Policy to grant permission to " + entityType + entityId;
policy = createAclPolicy(caller, aclPolicyName, description, null);
// add permission to this policy
addAclPermissionToAclPolicy(policy.getId(), entityType, PermissionScope.RESOURCE, entityId, action, Permission.Allow);
addAclPermissionToAclPolicy(policy.getId(), entityType, PermissionScope.RESOURCE, entityId, action, Permission.Allow, false);
}
// attach this policy to list of accounts if not attached already
Long policyId = policy.getId();

View File

@ -122,7 +122,8 @@ public class AddAclPermissionToAclPolicyCmd extends BaseAsyncCmd {
InsufficientCapacityException, ServerApiException {
CallContext.current().setEventDetails("Acl policy Id: " + getId());
// Only explicit ALLOW is supported for this release, no explicit deny
AclPolicy result = _aclApiSrv.addAclPermissionToAclPolicy(id, entityType, PermissionScope.valueOf(scope), scopeId, action, Permission.Allow);
AclPolicy result = _aclApiSrv.addAclPermissionToAclPolicy(id, entityType, PermissionScope.valueOf(scope),
scopeId, action, Permission.Allow, false);
if (result != null) {
AclPolicyResponse response = _aclApiSrv.createAclPolicyResponse(result);
response.setResponseName(getCommandName());

View File

@ -63,6 +63,7 @@ import com.cloud.user.UserVO;
import com.cloud.user.dao.AccountDao;
import com.cloud.utils.Pair;
import com.cloud.utils.component.ComponentContext;
import com.cloud.network.dao.NetworkDomainDao;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
@ -272,13 +273,13 @@ public class AclApiServiceTest {
when(_apiServer.getCmdClass("listVirtualMachines")).thenReturn(clz);
when(
_iamSrv.addAclPermissionToAclPolicy(policyId, AclEntityType.VirtualMachine.toString(), PermissionScope.RESOURCE.toString(), resId, "listVirtualMachines",
AccessType.ListEntry.toString(), Permission.Allow)).thenReturn(policy);
_aclSrv.addAclPermissionToAclPolicy(policyId, AclEntityType.VirtualMachine.toString(), PermissionScope.RESOURCE, resId, "listVirtualMachines", Permission.Allow);
AccessType.ListEntry.toString(), Permission.Allow, false)).thenReturn(policy);
_aclSrv.addAclPermissionToAclPolicy(policyId, AclEntityType.VirtualMachine.toString(), PermissionScope.RESOURCE, resId, "listVirtualMachines", Permission.Allow, false);
Pair<List<AclPolicy>, Integer> policyList = new Pair<List<AclPolicy>, Integer>(policies, 1);
List<AclPolicyPermission> policyPerms = new ArrayList<AclPolicyPermission>();
AclPolicyPermission perm = new AclPolicyPermissionVO(policyId, "listVirtualMachines", AclEntityType.VirtualMachine.toString(), AccessType.ListEntry.toString(),
PermissionScope.RESOURCE.toString(),
resId, Permission.Allow);
resId, Permission.Allow, false);
policyPerms.add(perm);
when(_iamSrv.listAclPolicies(null, "policy1", callerDomainPath, 0L, 20L)).thenReturn(policyList);
when(_iamSrv.listPolicyPermissions(policyId)).thenReturn(policyPerms);
@ -323,6 +324,11 @@ public class AclApiServiceTest {
return Mockito.mock(AccountDao.class);
}
@Bean
public NetworkDomainDao networkDomainDao() {
return Mockito.mock(NetworkDomainDao.class);
}
@Bean
public AccountManager accountManager() {
return Mockito.mock(AccountManager.class);

View File

@ -59,7 +59,7 @@ public interface IAMService {
void removeAclPolicyFromAccounts(Long policyId, List<Long> acctIds);
AclPolicy addAclPermissionToAclPolicy(long aclPolicyId, String entityType, String scope, Long scopeId,
String action, String accessType, Permission perm);
String action, String accessType, Permission perm, Boolean recursive);
AclPolicy removeAclPermissionFromAclPolicy(long aclPolicyId, String entityType, String scope, Long scopeId,
String action);

View File

@ -60,9 +60,9 @@ public class AclPolicyPermissionVO implements AclPolicyPermission {
@Column(name = "permission")
@Enumerated(value = EnumType.STRING)
private Permission permission;
@Column(name = "recursive")
private Boolean recursive;
private Boolean recursive;
@Column(name = GenericDao.REMOVED_COLUMN)
private Date removed;
@ -173,9 +173,9 @@ public class AclPolicyPermissionVO implements AclPolicyPermission {
public Date getCreated() {
return created;
}
public Boolean isRecursive() {
return recursive;
}
}

View File

@ -543,7 +543,7 @@ public class IAMServiceImpl extends ManagerBase implements IAMService, Manager {
@DB
@Override
public AclPolicy addAclPermissionToAclPolicy(long aclPolicyId, String entityType, String scope, Long scopeId,
String action, String accessType, Permission perm) {
String action, String accessType, Permission perm, Boolean recursive) {
// get the Acl Policy entity
AclPolicy policy = _aclPolicyDao.findById(aclPolicyId);
if (policy == null) {
@ -555,7 +555,8 @@ public class IAMServiceImpl extends ManagerBase implements IAMService, Manager {
AclPolicyPermissionVO permit = _policyPermissionDao.findByPolicyAndEntity(aclPolicyId, entityType, scope, scopeId, action, perm);
if (permit == null) {
// not there already
permit = new AclPolicyPermissionVO(aclPolicyId, action, entityType, accessType, scope, scopeId, perm, false);
permit = new AclPolicyPermissionVO(aclPolicyId, action, entityType, accessType, scope, scopeId, perm,
recursive);
_policyPermissionDao.persist(permit);
}
return policy;

View File

@ -72,5 +72,7 @@ public interface EntityManager {
public <T, K extends Serializable> void remove(Class<T> entityType, K id);
public static final String MESSAGE_REMOVE_ENTITY_EVENT = "Message.RemoveEntity.Event";
public static final String MESSAGE_GRANT_ENTITY_EVENT = "Message.GrantEntity.Event";
public static final String MESSAGE_ADD_DOMAIN_WIDE_ENTITY_EVENT = "Message.AddDomainWideEntity.Event";
}