mirror of
https://github.com/apache/cloudstack.git
synced 2025-12-16 18:43:26 +01:00
Add policies to domain group for CreateNetwork usecase for a domain wide shared network
This commit is contained in:
parent
ce95f3122b
commit
d12422bf68
@ -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);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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());
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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";
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user