mirror of
https://github.com/apache/cloudstack.git
synced 2025-11-02 11:52:28 +01:00
Global ACL for VPCs (#7150)
This commit is contained in:
parent
26b01f6f3b
commit
cb62ce6767
3
.github/workflows/ci.yml
vendored
3
.github/workflows/ci.yml
vendored
@ -111,7 +111,8 @@ jobs:
|
||||
smoke/test_reset_configuration_settings
|
||||
smoke/test_reset_vm_on_reboot
|
||||
smoke/test_resource_accounting
|
||||
smoke/test_resource_detail",
|
||||
smoke/test_resource_detail
|
||||
smoke/test_global_acls",
|
||||
"smoke/test_router_dhcphosts
|
||||
smoke/test_router_dns
|
||||
smoke/test_router_dnsservice
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
// under the License.
|
||||
package org.apache.cloudstack.api.command.user.network;
|
||||
|
||||
import com.cloud.exception.PermissionDeniedException;
|
||||
import org.apache.cloudstack.acl.RoleType;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiCommandResourceType;
|
||||
@ -26,6 +27,7 @@ import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.NetworkACLResponse;
|
||||
import org.apache.cloudstack.api.response.VpcResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.event.EventTypes;
|
||||
@ -35,7 +37,8 @@ import com.cloud.network.vpc.NetworkACL;
|
||||
import com.cloud.network.vpc.Vpc;
|
||||
import com.cloud.user.Account;
|
||||
|
||||
@APICommand(name = "createNetworkACLList", description = "Creates a network ACL for the given VPC", responseObject = NetworkACLResponse.class,
|
||||
@APICommand(name = "createNetworkACLList", description = "Creates a network ACL. If no VPC is given, then it creates a global ACL that can be used by everyone.",
|
||||
responseObject = NetworkACLResponse.class,
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
||||
public class CreateNetworkACLListCmd extends BaseAsyncCreateCmd {
|
||||
public static final Logger s_logger = Logger.getLogger(CreateNetworkACLListCmd.class.getName());
|
||||
@ -53,7 +56,6 @@ public class CreateNetworkACLListCmd extends BaseAsyncCreateCmd {
|
||||
|
||||
@Parameter(name = ApiConstants.VPC_ID,
|
||||
type = CommandType.UUID,
|
||||
required = true,
|
||||
entityType = VpcResponse.class,
|
||||
description = "ID of the VPC associated with this network ACL list")
|
||||
private Long vpcId;
|
||||
@ -77,6 +79,10 @@ public class CreateNetworkACLListCmd extends BaseAsyncCreateCmd {
|
||||
return vpcId;
|
||||
}
|
||||
|
||||
public void setVpcId(Long vpcId) {
|
||||
this.vpcId = vpcId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDisplay() {
|
||||
if (display != null) {
|
||||
@ -92,6 +98,9 @@ public class CreateNetworkACLListCmd extends BaseAsyncCreateCmd {
|
||||
|
||||
@Override
|
||||
public void create() {
|
||||
if (getVpcId() == null) {
|
||||
setVpcId(0L);
|
||||
}
|
||||
NetworkACL result = _networkACLService.createNetworkACL(getName(), getDescription(), getVpcId(), isDisplay());
|
||||
setEntityId(result.getId());
|
||||
setEntityUuid(result.getUuid());
|
||||
@ -111,12 +120,21 @@ public class CreateNetworkACLListCmd extends BaseAsyncCreateCmd {
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
Vpc vpc = _entityMgr.findById(Vpc.class, getVpcId());
|
||||
if (vpc == null) {
|
||||
throw new InvalidParameterValueException("Invalid vpcId is given");
|
||||
}
|
||||
Account account;
|
||||
if (isAclAttachedToVpc(this.vpcId)) {
|
||||
Vpc vpc = _entityMgr.findById(Vpc.class, this.vpcId);
|
||||
if (vpc == null) {
|
||||
throw new InvalidParameterValueException(String.format("Invalid VPC ID [%s] provided.", this.vpcId));
|
||||
}
|
||||
account = _accountService.getAccount(vpc.getAccountId());
|
||||
} else {
|
||||
account = CallContext.current().getCallingAccount();
|
||||
if (!Account.Type.ADMIN.equals(account.getType())) {
|
||||
s_logger.warn(String.format("Only Root Admin can create global ACLs. Account [%s] cannot create any global ACL.", account));
|
||||
throw new PermissionDeniedException("Only Root Admin can create global ACLs.");
|
||||
}
|
||||
|
||||
Account account = _accountService.getAccount(vpc.getAccountId());
|
||||
}
|
||||
return account.getId();
|
||||
}
|
||||
|
||||
@ -139,4 +157,8 @@ public class CreateNetworkACLListCmd extends BaseAsyncCreateCmd {
|
||||
public ApiCommandResourceType getApiResourceType() {
|
||||
return ApiCommandResourceType.NetworkAcl;
|
||||
}
|
||||
|
||||
public boolean isAclAttachedToVpc(Long aclVpcId) {
|
||||
return aclVpcId != null && aclVpcId != 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,6 +17,8 @@
|
||||
|
||||
package com.cloud.network.vpc;
|
||||
|
||||
import org.apache.cloudstack.utils.reflectiontostringbuilderutils.ReflectionToStringBuilderUtils;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.persistence.Column;
|
||||
@ -85,6 +87,11 @@ public class NetworkACLVO implements NetworkACL {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return ReflectionToStringBuilderUtils.reflectOnlySelectedFields(this, "uuid", "name", "vpcId");
|
||||
}
|
||||
|
||||
public void setUuid(String uuid) {
|
||||
this.uuid = uuid;
|
||||
}
|
||||
|
||||
@ -2100,12 +2100,9 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
||||
throw new InvalidParameterValueException("Unable to find specified NetworkACL");
|
||||
}
|
||||
|
||||
if (aclId != NetworkACL.DEFAULT_DENY && aclId != NetworkACL.DEFAULT_ALLOW) {
|
||||
// ACL is not default DENY/ALLOW
|
||||
// ACL should be associated with a VPC
|
||||
if (!vpcId.equals(acl.getVpcId())) {
|
||||
throw new InvalidParameterValueException("ACL: " + aclId + " do not belong to the VPC");
|
||||
}
|
||||
Long aclVpcId = acl.getVpcId();
|
||||
if (!isDefaultAcl(aclId) && isAclAttachedToVpc(aclVpcId, vpcId)) {
|
||||
throw new InvalidParameterValueException(String.format("ACL [%s] does not belong to the VPC [%s].", aclId, aclVpcId));
|
||||
}
|
||||
}
|
||||
network = _vpcMgr.createVpcGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId, networkDomain, owner, sharedDomainId, pNtwk, zoneId, aclType,
|
||||
@ -5950,6 +5947,14 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C
|
||||
return new ConfigKey<?>[] {AllowDuplicateNetworkName, AllowEmptyStartEndIpAddress, VRPrivateInterfaceMtu, VRPublicInterfaceMtu, AllowUsersToSpecifyVRMtu};
|
||||
}
|
||||
|
||||
public boolean isDefaultAcl(Long aclId) {
|
||||
return aclId == NetworkACL.DEFAULT_DENY || aclId == NetworkACL.DEFAULT_ALLOW;
|
||||
}
|
||||
|
||||
public boolean isAclAttachedToVpc(Long aclVpcId, Long vpcId) {
|
||||
return aclVpcId != 0 && !vpcId.equals(aclVpcId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PublicIpQuarantine updatePublicIpAddressInQuarantine(UpdateQuarantinedIpCmd cmd) throws CloudRuntimeException {
|
||||
Long ipId = cmd.getId();
|
||||
|
||||
@ -24,6 +24,7 @@ import java.util.Map;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.cloud.exception.PermissionDeniedException;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.command.user.network.CreateNetworkACLCmd;
|
||||
@ -103,12 +104,15 @@ public class NetworkACLServiceImpl extends ManagerBase implements NetworkACLServ
|
||||
|
||||
@Override
|
||||
public NetworkACL createNetworkACL(final String name, final String description, final long vpcId, final Boolean forDisplay) {
|
||||
final Account caller = CallContext.current().getCallingAccount();
|
||||
final Vpc vpc = _entityMgr.findById(Vpc.class, vpcId);
|
||||
if (vpc == null) {
|
||||
throw new InvalidParameterValueException("Unable to find VPC");
|
||||
if (vpcId != 0) {
|
||||
final Account caller = CallContext.current().getCallingAccount();
|
||||
final Vpc vpc = _vpcDao.findById(vpcId);
|
||||
if (vpc == null) {
|
||||
throw new InvalidParameterValueException(String.format("Unable to find VPC with ID [%s].", vpcId));
|
||||
}
|
||||
_accountMgr.checkAccess(caller, null, true, vpc);
|
||||
|
||||
}
|
||||
_accountMgr.checkAccess(caller, null, true, vpc);
|
||||
return _networkAclMgr.createNetworkACL(name, description, vpcId, forDisplay);
|
||||
}
|
||||
|
||||
@ -212,22 +216,17 @@ public class NetworkACLServiceImpl extends ManagerBase implements NetworkACLServ
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_NETWORK_ACL_DELETE, eventDescription = "Deleting Network ACL List", async = true)
|
||||
public boolean deleteNetworkACL(final long id) {
|
||||
final Account caller = CallContext.current().getCallingAccount();
|
||||
final NetworkACL acl = _networkACLDao.findById(id);
|
||||
Account account = CallContext.current().getCallingAccount();
|
||||
if (acl == null) {
|
||||
throw new InvalidParameterValueException("Unable to find specified ACL");
|
||||
}
|
||||
|
||||
//Do not allow deletion of default ACLs
|
||||
if (acl.getId() == NetworkACL.DEFAULT_ALLOW || acl.getId() == NetworkACL.DEFAULT_DENY) {
|
||||
if (isDefaultAcl(acl.getId())) {
|
||||
throw new InvalidParameterValueException("Default ACL cannot be removed");
|
||||
}
|
||||
|
||||
final Vpc vpc = _entityMgr.findById(Vpc.class, acl.getVpcId());
|
||||
if (vpc == null) {
|
||||
throw new InvalidParameterValueException("Unable to find specified VPC associated with the ACL");
|
||||
}
|
||||
_accountMgr.checkAccess(caller, null, true, vpc);
|
||||
validateGlobalAclPermissionAndAclAssociatedToVpc(acl, account, "Only Root Admin can delete global ACLs.");
|
||||
return _networkAclMgr.deleteNetworkACL(acl);
|
||||
}
|
||||
|
||||
@ -253,7 +252,7 @@ public class NetworkACLServiceImpl extends ManagerBase implements NetworkACLServ
|
||||
throw new InvalidParameterValueException("Unable to find specified vpc id");
|
||||
}
|
||||
|
||||
if (aclId != NetworkACL.DEFAULT_DENY && aclId != NetworkACL.DEFAULT_ALLOW) {
|
||||
if (!isDefaultAcl(aclId)) {
|
||||
final Vpc vpc = _entityMgr.findById(Vpc.class, acl.getVpcId());
|
||||
if (vpc == null) {
|
||||
throw new InvalidParameterValueException("Unable to find Vpc associated with the NetworkACL");
|
||||
@ -293,15 +292,9 @@ public class NetworkACLServiceImpl extends ManagerBase implements NetworkACLServ
|
||||
throw new InvalidParameterValueException("Network ACL can be created just for networks of type " + Networks.TrafficType.Guest);
|
||||
}
|
||||
|
||||
if (aclId != NetworkACL.DEFAULT_DENY && aclId != NetworkACL.DEFAULT_ALLOW) {
|
||||
//ACL is not default DENY/ALLOW
|
||||
// ACL should be associated with a VPC
|
||||
final Vpc vpc = _entityMgr.findById(Vpc.class, acl.getVpcId());
|
||||
if (vpc == null) {
|
||||
throw new InvalidParameterValueException("Unable to find Vpc associated with the NetworkACL");
|
||||
}
|
||||
if (!isDefaultAcl(aclId) && !isGlobalAcl(acl.getVpcId())) {
|
||||
validateAclAssociatedToVpc(acl.getVpcId(), caller, acl.getUuid());
|
||||
|
||||
_accountMgr.checkAccess(caller, null, true, vpc);
|
||||
if (!network.getVpcId().equals(acl.getVpcId())) {
|
||||
throw new InvalidParameterValueException("Network: " + networkId + " and ACL: " + aclId + " do not belong to the same VPC");
|
||||
}
|
||||
@ -340,6 +333,11 @@ public class NetworkACLServiceImpl extends ManagerBase implements NetworkACLServ
|
||||
NetworkACL acl = _networkAclMgr.getNetworkACL(aclId);
|
||||
|
||||
validateNetworkAcl(acl);
|
||||
Account caller = CallContext.current().getCallingAccount();
|
||||
|
||||
if (isGlobalAcl(acl.getVpcId()) && !Account.Type.ADMIN.equals(caller.getType())) {
|
||||
throw new PermissionDeniedException("Only Root Admins can create rules for a global ACL.");
|
||||
}
|
||||
validateAclRuleNumber(createNetworkACLCmd, acl);
|
||||
|
||||
NetworkACLItem.Action ruleAction = validateAndCreateNetworkAclRuleAction(action);
|
||||
@ -409,7 +407,8 @@ public class NetworkACLServiceImpl extends ManagerBase implements NetworkACLServ
|
||||
* <ul>
|
||||
* <li>If the parameter is null, we return an {@link InvalidParameterValueException};
|
||||
* <li>Default ACLs {@link NetworkACL#DEFAULT_ALLOW} and {@link NetworkACL#DEFAULT_DENY} cannot be modified. Therefore, if any of them is provided we throw a {@link InvalidParameterValueException};
|
||||
* <li>If the network does not have a VPC, we will throw an {@link InvalidParameterValueException}.
|
||||
* <li>If no VPC is given, then it is a global ACL and there is no need to check any VPC ID. However, if a VPC is given and it does not exist, throws an
|
||||
* {@link InvalidParameterValueException}.
|
||||
* </ul>
|
||||
*
|
||||
* After all validations, we check if the user has access to the given network ACL using {@link AccountManager#checkAccess(Account, org.apache.cloudstack.acl.SecurityChecker.AccessType, boolean, org.apache.cloudstack.acl.ControlledEntity...)}.
|
||||
@ -419,16 +418,14 @@ public class NetworkACLServiceImpl extends ManagerBase implements NetworkACLServ
|
||||
throw new InvalidParameterValueException("Unable to find specified ACL.");
|
||||
}
|
||||
|
||||
if (acl.getId() == NetworkACL.DEFAULT_DENY || acl.getId() == NetworkACL.DEFAULT_ALLOW) {
|
||||
if (isDefaultAcl(acl.getId())) {
|
||||
throw new InvalidParameterValueException("Default ACL cannot be modified");
|
||||
}
|
||||
|
||||
Vpc vpc = _entityMgr.findById(Vpc.class, acl.getVpcId());
|
||||
if (vpc == null) {
|
||||
throw new InvalidParameterValueException(String.format("Unable to find Vpc associated with the NetworkACL [%s]", acl.getUuid()));
|
||||
Long aclVpcId = acl.getVpcId();
|
||||
if (!isGlobalAcl(aclVpcId)) {
|
||||
validateAclAssociatedToVpc(aclVpcId, CallContext.current().getCallingAccount(), acl.getUuid());
|
||||
}
|
||||
Account caller = CallContext.current().getCallingAccount();
|
||||
_accountMgr.checkAccess(caller, null, true, vpc);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -792,17 +789,12 @@ public class NetworkACLServiceImpl extends ManagerBase implements NetworkACLServ
|
||||
final NetworkACLItemVO aclItem = _networkACLItemDao.findById(ruleId);
|
||||
if (aclItem != null) {
|
||||
final NetworkACL acl = _networkAclMgr.getNetworkACL(aclItem.getAclId());
|
||||
final Account account = CallContext.current().getCallingAccount();
|
||||
|
||||
final Vpc vpc = _entityMgr.findById(Vpc.class, acl.getVpcId());
|
||||
|
||||
if (aclItem.getAclId() == NetworkACL.DEFAULT_ALLOW || aclItem.getAclId() == NetworkACL.DEFAULT_DENY) {
|
||||
if (isDefaultAcl(aclItem.getAclId())) {
|
||||
throw new InvalidParameterValueException("ACL Items in default ACL cannot be deleted");
|
||||
}
|
||||
|
||||
final Account caller = CallContext.current().getCallingAccount();
|
||||
|
||||
_accountMgr.checkAccess(caller, null, true, vpc);
|
||||
|
||||
validateGlobalAclPermissionAndAclAssociatedToVpc(acl, account, "Only Root Admin can delete global ACL rules.");
|
||||
}
|
||||
return _networkAclMgr.revokeNetworkACLItem(ruleId);
|
||||
}
|
||||
@ -826,6 +818,9 @@ public class NetworkACLServiceImpl extends ManagerBase implements NetworkACLServ
|
||||
NetworkACL acl = _networkAclMgr.getNetworkACL(networkACLItemVo.getAclId());
|
||||
validateNetworkAcl(acl);
|
||||
|
||||
Account account = CallContext.current().getCallingAccount();
|
||||
validateGlobalAclPermissionAndAclAssociatedToVpc(acl, account, "Only Root Admins can update global ACLs.");
|
||||
|
||||
transferDataToNetworkAclRulePojo(updateNetworkACLItemCmd, networkACLItemVo, acl);
|
||||
validateNetworkACLItem(networkACLItemVo);
|
||||
return _networkAclMgr.updateNetworkACLItem(networkACLItemVo);
|
||||
@ -912,14 +907,13 @@ public class NetworkACLServiceImpl extends ManagerBase implements NetworkACLServ
|
||||
}
|
||||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_NETWORK_ACL_UPDATE, eventDescription = "updating network acl", async = true)
|
||||
@ActionEvent(eventType = EventTypes.EVENT_NETWORK_ACL_UPDATE, eventDescription = "Updating Network ACL", async = true)
|
||||
public NetworkACL updateNetworkACL(UpdateNetworkACLListCmd updateNetworkACLListCmd) {
|
||||
Long id = updateNetworkACLListCmd.getId();
|
||||
NetworkACLVO acl = _networkACLDao.findById(id);
|
||||
Vpc vpc = _entityMgr.findById(Vpc.class, acl.getVpcId());
|
||||
Account account = CallContext.current().getCallingAccount();
|
||||
|
||||
Account caller = CallContext.current().getCallingAccount();
|
||||
_accountMgr.checkAccess(caller, null, true, vpc);
|
||||
validateGlobalAclPermissionAndAclAssociatedToVpc(acl, account, "Must be Root Admin to update a global ACL.");
|
||||
|
||||
String name = updateNetworkACLListCmd.getName();
|
||||
if (StringUtils.isNotBlank(name)) {
|
||||
@ -1149,14 +1143,59 @@ public class NetworkACLServiceImpl extends ManagerBase implements NetworkACLServ
|
||||
long aclId = ruleBeingMoved.getAclId();
|
||||
|
||||
if ((nextRule != null && nextRule.getAclId() != aclId) || (previousRule != null && previousRule.getAclId() != aclId)) {
|
||||
throw new InvalidParameterValueException("Cannot use ACL rules from differenting ACLs. Rule being moved.");
|
||||
throw new InvalidParameterValueException("Cannot use ACL rules from differentiating ACLs. Rule being moved.");
|
||||
}
|
||||
NetworkACLVO acl = _networkACLDao.findById(aclId);
|
||||
Vpc vpc = _entityMgr.findById(Vpc.class, acl.getVpcId());
|
||||
if (vpc == null) {
|
||||
throw new InvalidParameterValueException("Re-ordering rules for a default ACL is prohibited");
|
||||
Account account = CallContext.current().getCallingAccount();
|
||||
|
||||
if (isDefaultAcl(aclId)) {
|
||||
throw new InvalidParameterValueException("Default ACL rules cannot be moved.");
|
||||
}
|
||||
Account caller = CallContext.current().getCallingAccount();
|
||||
_accountMgr.checkAccess(caller, null, true, vpc);
|
||||
|
||||
validateGlobalAclPermissionAndAclAssociatedToVpc(acl, account,"Must be Root Admin to move global ACL rules.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given ACL is a global ACL. If it is, then checks if the account is Root Admin, and throws an exception according to {@code exceptionMessage} param if it
|
||||
* does not have permission.
|
||||
*/
|
||||
protected void checkGlobalAclPermission(Long aclVpcId, Account account, String exceptionMessage) {
|
||||
if (isGlobalAcl(aclVpcId) && !Account.Type.ADMIN.equals(account.getType())) {
|
||||
throw new PermissionDeniedException(exceptionMessage);
|
||||
}
|
||||
}
|
||||
|
||||
protected void validateAclAssociatedToVpc(Long aclVpcId, Account account, String aclUuid) {
|
||||
final Vpc vpc = _vpcDao.findById(aclVpcId);
|
||||
if (vpc == null) {
|
||||
throw new InvalidParameterValueException(String.format("Unable to find specified VPC [%s] associated with the ACL [%s].", aclVpcId, aclUuid));
|
||||
}
|
||||
_accountMgr.checkAccess(account, null, true, vpc);
|
||||
}
|
||||
|
||||
/**
|
||||
* It performs two different verifications depending on if the ACL is global or not.
|
||||
* <ul>
|
||||
* <li> If the given ACL is a Global ACL, i.e. has VPC ID = 0, then checks if the account is Root Admin, and throws an exception if it isn't.
|
||||
* <li> If the given ACL is associated to a VPC, i.e. VPC ID != 0, then calls {@link #validateAclAssociatedToVpc(Long, Account, String)} and checks if the given {@code
|
||||
* aclVpcId} is from a valid VPC.
|
||||
* </ul>
|
||||
*/
|
||||
protected void validateGlobalAclPermissionAndAclAssociatedToVpc(NetworkACL acl, Account account, String exception){
|
||||
if (isGlobalAcl(acl.getVpcId())) {
|
||||
s_logger.info(String.format("Checking if account [%s] has permission to manipulate global ACL [%s].", account, acl));
|
||||
checkGlobalAclPermission(acl.getVpcId(), account, exception);
|
||||
} else {
|
||||
s_logger.info(String.format("Validating ACL [%s] associated to VPC [%s] with account [%s].", acl, acl.getVpcId(), account));
|
||||
validateAclAssociatedToVpc(acl.getVpcId(), account, acl.getUuid());
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isGlobalAcl(Long aclVpcId) {
|
||||
return aclVpcId != null && aclVpcId == 0;
|
||||
}
|
||||
|
||||
protected boolean isDefaultAcl(long aclId) {
|
||||
return aclId == NetworkACL.DEFAULT_ALLOW || aclId == NetworkACL.DEFAULT_DENY;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1977,16 +1977,14 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
|
||||
|
||||
searchBuilder.and("vpcId", searchBuilder.entity().getVpcId(), Op.IN);
|
||||
final SearchCriteria<NetworkACLVO> searchCriteria = searchBuilder.create();
|
||||
searchCriteria.setParameters("vpcId", vpcId, 0);
|
||||
searchCriteria.setParameters("vpcId", vpcId);
|
||||
|
||||
final Filter filter = new Filter(NetworkACLVO.class, "id", false, null, null);
|
||||
final Pair<List<NetworkACLVO>, Integer> aclsCountPair = _networkAclDao.searchAndCount(searchCriteria, filter);
|
||||
|
||||
final List<NetworkACLVO> acls = aclsCountPair.first();
|
||||
for (final NetworkACLVO networkAcl : acls) {
|
||||
if (networkAcl.getId() != NetworkACL.DEFAULT_ALLOW && networkAcl.getId() != NetworkACL.DEFAULT_DENY) {
|
||||
_networkAclMgr.deleteNetworkACL(networkAcl);
|
||||
}
|
||||
_networkAclMgr.deleteNetworkACL(networkAcl);
|
||||
}
|
||||
|
||||
VpcVO vpc = vpcDao.findById(vpcId);
|
||||
@ -3175,4 +3173,12 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
|
||||
}
|
||||
return filteredDomainIds;
|
||||
}
|
||||
|
||||
protected boolean isGlobalAcl(Long aclVpcId) {
|
||||
return aclVpcId != null && aclVpcId == 0;
|
||||
}
|
||||
|
||||
protected boolean isDefaultAcl(long aclId) {
|
||||
return aclId == NetworkACL.DEFAULT_ALLOW || aclId == NetworkACL.DEFAULT_DENY;
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,6 +17,40 @@
|
||||
|
||||
package com.cloud.network.vpc;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.isNull;
|
||||
import static org.mockito.ArgumentMatchers.nullable;
|
||||
import static org.mockito.Mockito.times;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.cloud.exception.PermissionDeniedException;
|
||||
import com.cloud.network.vpc.dao.VpcDao;
|
||||
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.command.user.network.CreateNetworkACLCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.MoveNetworkAclItemCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.UpdateNetworkACLItemCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.UpdateNetworkACLListCmd;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InOrder;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.Spy;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.network.Network;
|
||||
@ -30,40 +64,9 @@ import com.cloud.user.AccountManager;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.utils.db.EntityManager;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.command.user.network.CreateNetworkACLCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.MoveNetworkAclItemCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.UpdateNetworkACLItemCmd;
|
||||
import org.apache.cloudstack.api.command.user.network.UpdateNetworkACLListCmd;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InOrder;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockedStatic;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.Spy;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.isNull;
|
||||
import static org.mockito.ArgumentMatchers.nullable;
|
||||
import static org.mockito.Mockito.times;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class NetworkACLServiceImplTest {
|
||||
@ -80,6 +83,8 @@ public class NetworkACLServiceImplTest {
|
||||
@Mock
|
||||
private EntityManager entityManagerMock;
|
||||
@Mock
|
||||
private VpcDao vpcDaoMock;
|
||||
@Mock
|
||||
private AccountManager accountManagerMock;
|
||||
@Mock
|
||||
private NetworkACLDao networkAclDaoMock;
|
||||
@ -99,10 +104,11 @@ public class NetworkACLServiceImplTest {
|
||||
@Mock
|
||||
private UpdateNetworkACLListCmd updateNetworkACLListCmdMock;
|
||||
|
||||
private Long networkAclMockId = 1L;
|
||||
private Long networkAclMockId = 5L;
|
||||
private Long networkOfferingMockId = 2L;
|
||||
private Long networkMockVpcMockId = 3L;
|
||||
private long networkAclListId = 1l;
|
||||
private static final String SOME_UUID = "someUuid";
|
||||
|
||||
@Mock
|
||||
private MoveNetworkAclItemCmd moveNetworkAclItemCmdMock;
|
||||
@ -121,6 +127,12 @@ public class NetworkACLServiceImplTest {
|
||||
@Mock
|
||||
private CallContext callContextMock;
|
||||
|
||||
@Mock
|
||||
private VpcVO vpcVOMock;
|
||||
|
||||
@Mock
|
||||
private Account accountMock;
|
||||
|
||||
private MockedStatic<CallContext> callContextMocked;
|
||||
|
||||
@Before
|
||||
@ -178,9 +190,9 @@ public class NetworkACLServiceImplTest {
|
||||
}
|
||||
});
|
||||
|
||||
NetworkACLItem netowkrAclRuleCreated = networkAclServiceImpl.createNetworkACLItem(createNetworkAclCmdMock);
|
||||
NetworkACLItem networkAclRuleCreated = networkAclServiceImpl.createNetworkACLItem(createNetworkAclCmdMock);
|
||||
|
||||
Assert.assertEquals(number == null ? 6 : number, netowkrAclRuleCreated.getNumber());
|
||||
Assert.assertEquals(number == null ? 6 : number, networkAclRuleCreated.getNumber());
|
||||
|
||||
InOrder inOrder = Mockito.inOrder( networkAclServiceImpl, networkAclManagerMock, networkAclItemDaoMock);
|
||||
inOrder.verify(networkAclServiceImpl).createAclListIfNeeded(createNetworkAclCmdMock);
|
||||
@ -392,13 +404,13 @@ public class NetworkACLServiceImplTest {
|
||||
@Test(expected = InvalidParameterValueException.class)
|
||||
public void validateNetworkAclTestAclNotDefaulWithoutVpc() {
|
||||
Mockito.when(networkAclMock.getId()).thenReturn(3L);
|
||||
Mockito.doReturn(null).when(entityManagerMock).findById(Vpc.class, networkMockVpcMockId);
|
||||
Mockito.doReturn(null).when(vpcDaoMock).findById(networkMockVpcMockId);
|
||||
|
||||
networkAclServiceImpl.validateNetworkAcl(networkAclMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateNetworkAclTestAclNotDefaulWithVpc() {
|
||||
public void validateNetworkAclTestAclNotDefaultWithVpc() {
|
||||
CallContext callContextMock = Mockito.mock(CallContext.class);
|
||||
Mockito.doReturn(Mockito.mock(Account.class)).when(callContextMock).getCallingAccount();
|
||||
|
||||
@ -407,12 +419,11 @@ public class NetworkACLServiceImplTest {
|
||||
Mockito.when(networkAclMock.getId()).thenReturn(3L);
|
||||
Mockito.when(networkAclMock.getVpcId()).thenReturn(networkMockVpcMockId);
|
||||
|
||||
Mockito.doReturn(Mockito.mock(Vpc.class)).when(entityManagerMock).findById(Vpc.class, networkMockVpcMockId);
|
||||
Mockito.doReturn(vpcVOMock).when(vpcDaoMock).findById(networkMockVpcMockId);
|
||||
Mockito.doNothing().when(accountManagerMock).checkAccess(Mockito.any(Account.class), Mockito.isNull(AccessType.class), Mockito.eq(true), Mockito.any(Vpc.class));
|
||||
|
||||
networkAclServiceImpl.validateNetworkAcl(networkAclMock);
|
||||
|
||||
Mockito.verify(entityManagerMock).findById(Vpc.class, networkMockVpcMockId);
|
||||
Mockito.verify(accountManagerMock).checkAccess(Mockito.any(Account.class), Mockito.isNull(AccessType.class), Mockito.eq(true), Mockito.any(Vpc.class));
|
||||
|
||||
callContextMocked.verify(() -> CallContext.current());
|
||||
@ -702,16 +713,22 @@ public class NetworkACLServiceImplTest {
|
||||
Mockito.doReturn(networkAclItemVoMock).when(networkAclServiceImpl).validateNetworkAclRuleIdAndRetrieveIt(updateNetworkACLItemCmdMock);
|
||||
Mockito.doReturn(networkAclMock).when(networkAclManagerMock).getNetworkACL(networkAclMockId);
|
||||
Mockito.doNothing().when(networkAclServiceImpl).validateNetworkAcl(Mockito.eq(networkAclMock));
|
||||
Mockito.doNothing().when(networkAclServiceImpl).validateGlobalAclPermissionAndAclAssociatedToVpc(Mockito.any(NetworkACL.class), Mockito.any(Account.class), Mockito.anyString());
|
||||
Mockito.doNothing().when(networkAclServiceImpl).transferDataToNetworkAclRulePojo(Mockito.eq(updateNetworkACLItemCmdMock), Mockito.eq(networkAclItemVoMock), Mockito.eq(networkAclMock));
|
||||
Mockito.doNothing().when(networkAclServiceImpl).validateNetworkACLItem(networkAclItemVoMock);
|
||||
Mockito.doReturn(networkAclItemVoMock).when(networkAclManagerMock).updateNetworkACLItem(networkAclItemVoMock);
|
||||
|
||||
CallContext callContextMock = Mockito.mock(CallContext.class);
|
||||
Mockito.doReturn(accountMock).when(callContextMock).getCallingAccount();
|
||||
Mockito.when(CallContext.current()).thenReturn(callContextMock);
|
||||
|
||||
networkAclServiceImpl.updateNetworkACLItem(updateNetworkACLItemCmdMock);
|
||||
|
||||
InOrder inOrder = Mockito.inOrder(networkAclServiceImpl, networkAclManagerMock);
|
||||
inOrder.verify(networkAclServiceImpl).validateNetworkAclRuleIdAndRetrieveIt(updateNetworkACLItemCmdMock);
|
||||
inOrder.verify(networkAclManagerMock).getNetworkACL(networkAclMockId);
|
||||
inOrder.verify(networkAclServiceImpl).validateNetworkAcl(networkAclMock);
|
||||
inOrder.verify(networkAclServiceImpl).validateGlobalAclPermissionAndAclAssociatedToVpc(networkAclMock, accountMock, "Only Root Admins can update global ACLs.");
|
||||
inOrder.verify(networkAclServiceImpl).transferDataToNetworkAclRulePojo(Mockito.eq(updateNetworkACLItemCmdMock), Mockito.eq(networkAclItemVoMock), Mockito.eq(networkAclMock));
|
||||
inOrder.verify(networkAclServiceImpl).validateNetworkACLItem(networkAclItemVoMock);
|
||||
inOrder.verify(networkAclManagerMock).updateNetworkACLItem(networkAclItemVoMock);
|
||||
@ -865,13 +882,18 @@ public class NetworkACLServiceImplTest {
|
||||
Mockito.when(updateNetworkACLListCmdMock.getCustomId()).thenReturn(customId);
|
||||
Mockito.when(updateNetworkACLListCmdMock.getId()).thenReturn(networkAclListId);
|
||||
Mockito.when(updateNetworkACLListCmdMock.getDisplay()).thenReturn(false);
|
||||
Mockito.when(networkACLVOMock.getVpcId()).thenReturn(networkMockVpcMockId);
|
||||
Mockito.doReturn(vpcVOMock).when(vpcDaoMock).findById(networkMockVpcMockId);
|
||||
Mockito.doNothing().when(accountManagerMock).checkAccess(Mockito.any(Account.class),
|
||||
Mockito.isNull(AccessType.class), Mockito.eq(true), Mockito.any(Vpc.class));
|
||||
|
||||
|
||||
networkAclServiceImpl.updateNetworkACL(updateNetworkACLListCmdMock);
|
||||
|
||||
InOrder inOrder = Mockito.inOrder(networkAclDaoMock, entityManagerMock, entityManagerMock, accountManagerMock, networkACLVOMock);
|
||||
InOrder inOrder = Mockito.inOrder(networkAclDaoMock, vpcDaoMock, accountManagerMock, networkACLVOMock);
|
||||
|
||||
inOrder.verify(networkAclDaoMock).findById(networkAclListId);
|
||||
inOrder.verify(entityManagerMock).findById(Mockito.eq(Vpc.class), Mockito.anyLong());
|
||||
inOrder.verify(vpcDaoMock).findById(Mockito.anyLong());
|
||||
inOrder.verify(accountManagerMock).checkAccess(Mockito.any(Account.class), Mockito.isNull(AccessType.class), Mockito.eq(true), nullable(Vpc.class));
|
||||
|
||||
|
||||
@ -1063,13 +1085,17 @@ public class NetworkACLServiceImplTest {
|
||||
Mockito.when(updateNetworkACLListCmdMock.getCustomId()).thenReturn(null);
|
||||
Mockito.when(updateNetworkACLListCmdMock.getId()).thenReturn(networkAclListId);
|
||||
Mockito.when(updateNetworkACLListCmdMock.getDisplay()).thenReturn(null);
|
||||
Mockito.when(networkACLVOMock.getVpcId()).thenReturn(networkMockVpcMockId);
|
||||
Mockito.doReturn(vpcVOMock).when(vpcDaoMock).findById(networkMockVpcMockId);
|
||||
Mockito.doNothing().when(accountManagerMock).checkAccess(Mockito.any(Account.class),
|
||||
Mockito.isNull(AccessType.class), Mockito.eq(true), Mockito.any(Vpc.class));
|
||||
|
||||
networkAclServiceImpl.updateNetworkACL(updateNetworkACLListCmdMock);
|
||||
|
||||
InOrder inOrder = Mockito.inOrder(networkAclDaoMock, entityManagerMock, accountManagerMock, networkACLVOMock);
|
||||
InOrder inOrder = Mockito.inOrder(networkAclDaoMock, vpcDaoMock, accountManagerMock, networkACLVOMock);
|
||||
|
||||
inOrder.verify(networkAclDaoMock).findById(networkAclListId);
|
||||
inOrder.verify(entityManagerMock).findById(eq(Vpc.class), Mockito.anyLong());
|
||||
inOrder.verify(vpcDaoMock).findById(Mockito.anyLong());
|
||||
inOrder.verify(accountManagerMock).checkAccess(any(Account.class), isNull(), eq(true), nullable(Vpc.class));
|
||||
|
||||
Mockito.verify(networkACLVOMock, Mockito.times(0)).setName(null);
|
||||
@ -1086,21 +1112,18 @@ public class NetworkACLServiceImplTest {
|
||||
Mockito.when(nextAclRuleMock.getAclId()).thenReturn(networkAclMockId);
|
||||
Mockito.when(previousAclRuleMock.getAclId()).thenReturn(networkAclMockId);
|
||||
|
||||
Mockito.doReturn(networkAclMock).when(networkAclDaoMock).findById(networkAclMockId);
|
||||
Mockito.doReturn(Mockito.mock(Vpc.class)).when(entityManagerMock).findById(Vpc.class, networkMockVpcMockId);
|
||||
|
||||
CallContext callContextMock = Mockito.mock(CallContext.class);
|
||||
Mockito.doReturn(Mockito.mock(Account.class)).when(callContextMock).getCallingAccount();
|
||||
|
||||
Mockito.doReturn(networkAclMock).when(networkAclDaoMock).findById(networkAclMockId);
|
||||
Mockito.when(CallContext.current()).thenReturn(callContextMock);
|
||||
|
||||
Mockito.doNothing().when(accountManagerMock).checkAccess(Mockito.any(Account.class), Mockito.isNull(AccessType.class), Mockito.eq(true), Mockito.any(Vpc.class));
|
||||
Mockito.doNothing().when(networkAclServiceImpl).validateGlobalAclPermissionAndAclAssociatedToVpc(Mockito.any(NetworkACL.class), Mockito.any(Account.class), Mockito.anyString());
|
||||
|
||||
networkAclServiceImpl.validateMoveAclRulesData(aclRuleBeingMovedMock, previousAclRuleMock, nextAclRuleMock);
|
||||
|
||||
Mockito.verify(networkAclDaoMock).findById(networkAclMockId);
|
||||
Mockito.verify(entityManagerMock).findById(Vpc.class, networkMockVpcMockId);
|
||||
Mockito.verify(accountManagerMock).checkAccess(Mockito.any(Account.class), Mockito.isNull(AccessType.class), Mockito.eq(true), Mockito.any(Vpc.class));
|
||||
Mockito.verify(networkAclServiceImpl).validateGlobalAclPermissionAndAclAssociatedToVpc(Mockito.any(NetworkACL.class), Mockito.any(Account.class), Mockito.anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -1359,9 +1382,41 @@ public class NetworkACLServiceImplTest {
|
||||
ArrayList<NetworkACLItemVO> allAclRules = new ArrayList<>();
|
||||
allAclRules.add(networkAclItemVoMock);
|
||||
|
||||
Mockito.doReturn("someUuid").when(networkAclItemVoMock).getUuid();
|
||||
Mockito.doReturn(SOME_UUID).when(networkAclItemVoMock).getUuid();
|
||||
networkAclServiceImpl.validateAclConsistency(moveNetworkAclItemCmdMock, networkACLVOMock, allAclRules);
|
||||
|
||||
Mockito.verify(moveNetworkAclItemCmdMock, Mockito.times(1)).getAclConsistencyHash();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkGlobalAclPermissionTestGlobalAclWithRootAccountShouldWork() {
|
||||
Mockito.doReturn(Account.Type.ADMIN).when(accountMock).getType();
|
||||
Mockito.doReturn(true).when(networkAclServiceImpl).isGlobalAcl(Mockito.anyLong());
|
||||
|
||||
networkAclServiceImpl.checkGlobalAclPermission(networkMockVpcMockId, accountMock, "exception");
|
||||
}
|
||||
|
||||
@Test(expected = PermissionDeniedException.class)
|
||||
public void checkGlobalAclPermissionTestGlobalAclWithNonRootAccountShouldThrow() {
|
||||
Mockito.doReturn(Account.Type.NORMAL).when(accountMock).getType();
|
||||
Mockito.doReturn(true).when(networkAclServiceImpl).isGlobalAcl(Mockito.anyLong());
|
||||
|
||||
networkAclServiceImpl.checkGlobalAclPermission(networkMockVpcMockId, accountMock, "exception");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateAclAssociatedToVpcTestNonNullVpcShouldCheckAccess() {
|
||||
Mockito.doReturn(vpcVOMock).when(vpcDaoMock).findById(Mockito.anyLong());
|
||||
|
||||
networkAclServiceImpl.validateAclAssociatedToVpc(networkMockVpcMockId, accountMock, SOME_UUID);
|
||||
|
||||
Mockito.verify(accountManagerMock, Mockito.times(1)).checkAccess(Mockito.any(Account.class), isNull(), Mockito.anyBoolean(), Mockito.any(Vpc.class));
|
||||
}
|
||||
|
||||
@Test(expected = InvalidParameterValueException.class)
|
||||
public void validateAclAssociatedToVpcTestNullVpcShouldThrowInvalidParameterValueException() {
|
||||
Mockito.doReturn(null).when(vpcDaoMock).findById(Mockito.anyLong());
|
||||
|
||||
networkAclServiceImpl.validateAclAssociatedToVpc(networkMockVpcMockId, accountMock, SOME_UUID);
|
||||
}
|
||||
}
|
||||
|
||||
245
test/integration/smoke/test_global_acls.py
Normal file
245
test/integration/smoke/test_global_acls.py
Normal file
@ -0,0 +1,245 @@
|
||||
# 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.cloudstackTestCase import cloudstackTestCase
|
||||
from marvin.lib.utils import cleanup_resources
|
||||
from marvin.lib.base import (Network, NetworkACLList, NetworkOffering, VpcOffering, VPC, NetworkACL)
|
||||
from marvin.lib.common import (get_domain, get_zone)
|
||||
from nose.plugins.attrib import attr
|
||||
from marvin.cloudstackException import CloudstackAPIException
|
||||
|
||||
|
||||
class Services:
|
||||
"""Test Global ACLs
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.services = {
|
||||
"root_domain": {
|
||||
"name": "ROOT",
|
||||
},
|
||||
"domain": {
|
||||
"name": "Domain",
|
||||
},
|
||||
"user": {
|
||||
"username": "user",
|
||||
"roletype": 0,
|
||||
},
|
||||
"domain_admin": {
|
||||
"username": "Domain admin",
|
||||
"roletype": 2,
|
||||
},
|
||||
"root_admin": {
|
||||
"username": "Root admin",
|
||||
"roletype": 1,
|
||||
},
|
||||
"vpc": {
|
||||
"name": "vpc-networkacl",
|
||||
"displaytext": "vpc-networkacl",
|
||||
"cidr": "10.1.1.0/24",
|
||||
},
|
||||
"vpcnetwork": {
|
||||
"name": "vpcnetwork",
|
||||
"displaytext": "vpcnetwork",
|
||||
},
|
||||
"rule": {
|
||||
"protocol": "all",
|
||||
"traffictype": "ingress",
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class TestGlobalACLs(cloudstackTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.testClient = super(TestGlobalACLs, cls).getClsTestClient()
|
||||
cls.apiclient = cls.testClient.getApiClient()
|
||||
|
||||
cls.services = Services().services
|
||||
cls.domain = get_domain(cls.apiclient)
|
||||
cls.zone = get_zone(cls.apiclient, cls.testClient.getZoneForTests())
|
||||
return
|
||||
|
||||
def setUp(self):
|
||||
self.user_apiclient = self.testClient.getUserApiClient(self.services["user"]["username"],
|
||||
self.services["domain"]["name"],
|
||||
self.services["user"]["roletype"])
|
||||
|
||||
self.domain_admin_apiclient = self.testClient.getUserApiClient(self.services["domain_admin"]["username"],
|
||||
self.services["domain"]["name"],
|
||||
self.services["domain_admin"]["roletype"])
|
||||
|
||||
self.admin_apiclient = self.testClient.getUserApiClient(self.services["root_admin"]["username"],
|
||||
self.services["root_domain"]["name"],
|
||||
self.services["root_admin"]["roletype"])
|
||||
|
||||
self.cleanup = []
|
||||
return
|
||||
|
||||
def tearDown(self):
|
||||
super(TestGlobalACLs, self).tearDown()
|
||||
|
||||
@attr(tags=["advanced", "basic"], required_hardware="false")
|
||||
def test_create_global_acl(self):
|
||||
""" Test create global ACL as a normal user, domain admin and root admin users.
|
||||
"""
|
||||
|
||||
self.debug("Creating ACL list as a normal user, should raise exception.")
|
||||
self.assertRaisesRegex(CloudstackAPIException, "Only Root Admin can create global ACLs.",
|
||||
NetworkACLList.create, apiclient=self.user_apiclient, services={},
|
||||
name="acl", description="acl")
|
||||
|
||||
self.debug("Creating ACL list as a domain admin, should raise exception.")
|
||||
self.assertRaisesRegex(CloudstackAPIException, "Only Root Admin can create global ACLs.",
|
||||
NetworkACLList.create, apiclient=self.domain_admin_apiclient, services={},
|
||||
name="acl", description="acl")
|
||||
|
||||
self.debug("Creating ACL list as a root admin, should work.")
|
||||
acl = NetworkACLList.create(apiclient=self.admin_apiclient, services={}, name="acl", description="acl")
|
||||
self.cleanup.append(acl)
|
||||
self.assertIsNotNone(acl, "A root admin user should be able to create a global ACL.")
|
||||
|
||||
return
|
||||
|
||||
@attr(tags=["advanced", "basic"], required_hardware="false")
|
||||
def test_replace_acl_of_network(self):
|
||||
""" Test to replace ACL of a VPC as a normal user, domain admin and root admin users.
|
||||
"""
|
||||
# Get network offering
|
||||
networkOffering = NetworkOffering.list(self.apiclient, name="DefaultIsolatedNetworkOfferingForVpcNetworks")
|
||||
self.assertTrue(networkOffering is not None and len(networkOffering) > 0, "No VPC network offering")
|
||||
|
||||
# Getting VPC offering
|
||||
vpcOffering = VpcOffering.list(self.apiclient, name="Default VPC offering")
|
||||
self.assertTrue(vpcOffering is not None and len(vpcOffering) > 0, "No VPC offerings found")
|
||||
|
||||
# Creating VPC
|
||||
vpc = VPC.create(
|
||||
apiclient=self.apiclient,
|
||||
services=self.services["vpc"],
|
||||
networkDomain="vpc.networkacl",
|
||||
vpcofferingid=vpcOffering[0].id,
|
||||
zoneid=self.zone.id,
|
||||
domainid=self.domain.id
|
||||
)
|
||||
self.cleanup.append(vpc)
|
||||
self.assertTrue(vpc is not None, "VPC creation failed")
|
||||
|
||||
# Creating ACL list
|
||||
acl = NetworkACLList.create(apiclient=self.apiclient, services={}, name="acl", description="acl")
|
||||
|
||||
# Creating tier on VPC with ACL list
|
||||
network = Network.create(
|
||||
apiclient=self.apiclient,
|
||||
services=self.services["vpcnetwork"],
|
||||
accountid="Admin",
|
||||
domainid=self.domain.id,
|
||||
networkofferingid=networkOffering[0].id,
|
||||
zoneid=self.zone.id,
|
||||
vpcid=vpc.id,
|
||||
aclid=acl.id,
|
||||
gateway="10.1.1.1",
|
||||
netmask="255.255.255.192"
|
||||
)
|
||||
self.cleanup.append(network)
|
||||
|
||||
# User should be able to replace ACL
|
||||
network.replaceACLList(apiclient=self.user_apiclient, aclid=acl.id)
|
||||
# Domain Admin should be able to replace ACL
|
||||
network.replaceACLList(apiclient=self.domain_admin_apiclient, aclid=acl.id)
|
||||
# Admin should be able to replace ACL
|
||||
network.replaceACLList(apiclient=self.admin_apiclient, aclid=acl.id)
|
||||
|
||||
return
|
||||
|
||||
@attr(tags=["advanced", "basic"], required_hardware="false")
|
||||
def test_create_acl_rule(self):
|
||||
""" Test to create ACL rule as a normal user, domain admin and root admin users.
|
||||
"""
|
||||
# Creating ACL list
|
||||
acl = NetworkACLList.create(apiclient=self.admin_apiclient, services={}, name="acl", description="acl")
|
||||
self.cleanup.append(acl)
|
||||
|
||||
self.debug("Creating ACL rule as a user, should raise exception.")
|
||||
self.assertRaisesRegex(CloudstackAPIException, "Only Root Admins can create rules for a global ACL.",
|
||||
NetworkACL.create, self.user_apiclient, services=self.services["rule"], aclid=acl.id)
|
||||
self.debug("Creating ACL rule as a domain admin, should raise exception.")
|
||||
self.assertRaisesRegex(CloudstackAPIException, "Only Root Admins can create rules for a global ACL.",
|
||||
NetworkACL.create, self.domain_admin_apiclient, services=self.services["rule"], aclid=acl.id)
|
||||
self.debug("Creating ACL rule as a root admin, should work.")
|
||||
acl_rule = NetworkACL.create(self.admin_apiclient, services=self.services["rule"], aclid=acl.id)
|
||||
self.cleanup.append(acl_rule)
|
||||
|
||||
return
|
||||
|
||||
@attr(tags=["advanced", "basic"], required_hardware="false")
|
||||
def test_delete_acl_rule(self):
|
||||
""" Test to delete ACL rule as a normal user, domain admin and root admin users.
|
||||
"""
|
||||
# Creating ACL list
|
||||
acl = NetworkACLList.create(apiclient=self.apiclient, services={}, name="acl", description="acl")
|
||||
self.cleanup.append(acl)
|
||||
|
||||
# Creating ACL rule
|
||||
acl_rule = NetworkACL.create(self.apiclient, services=self.services["rule"], aclid=acl.id)
|
||||
self.cleanup.append(acl_rule)
|
||||
|
||||
self.debug("Deleting ACL rule as a user, should raise exception.")
|
||||
self.assertRaisesRegex(Exception, "Only Root Admin can delete global ACL rules.",
|
||||
NetworkACL.delete, acl_rule, self.user_apiclient)
|
||||
self.debug("Deleting ACL rule as a domain admin, should raise exception.")
|
||||
self.assertRaisesRegex(Exception, "Only Root Admin can delete global ACL rules.",
|
||||
NetworkACL.delete, acl_rule, self.domain_admin_apiclient)
|
||||
|
||||
self.debug("Deleting ACL rule as a root admin, should work.")
|
||||
NetworkACL.delete(acl_rule, self.admin_apiclient)
|
||||
self.cleanup.remove(acl_rule)
|
||||
|
||||
# Verify if the number of ACL rules is equal to four, i.e. the number of rules
|
||||
# for the default ACLs `default_allow` (2 rules) and `default_deny` (2 rules) ACLs
|
||||
number_of_acl_rules = acl_rule.list(apiclient=self.admin_apiclient)
|
||||
self.assertEqual(len(number_of_acl_rules), 4)
|
||||
|
||||
return
|
||||
|
||||
|
||||
@attr(tags=["advanced", "basic"], required_hardware="false")
|
||||
def test_delete_global_acl(self):
|
||||
""" Test delete global ACL as a normal user, domain admin and root admin users.
|
||||
"""
|
||||
|
||||
# Creating ACL list. Not adding to cleanup as it will be deleted in this method
|
||||
acl = NetworkACLList.create(apiclient=self.apiclient, services={}, name="acl", description="acl")
|
||||
self.cleanup.append(acl)
|
||||
|
||||
self.debug("Deleting ACL list as a normal user, should raise exception.")
|
||||
self.assertRaisesRegex(Exception, "Only Root Admin can delete global ACLs.",
|
||||
NetworkACLList.delete, acl, apiclient=self.user_apiclient)
|
||||
|
||||
self.debug("Deleting ACL list as a domain admin, should raise exception.")
|
||||
self.assertRaisesRegex(Exception, "Only Root Admin can delete global ACLs.",
|
||||
NetworkACLList.delete, acl, apiclient=self.domain_admin_apiclient)
|
||||
|
||||
self.debug("Deleting ACL list as a root admin, should work.")
|
||||
acl.delete(apiclient=self.admin_apiclient)
|
||||
self.cleanup.remove(acl)
|
||||
|
||||
# Verify if number of ACLs is equal to two, i.e. the number of default ACLs `default_allow` and `default_deny`
|
||||
number_of_acls = NetworkACLList.list(apiclient=self.admin_apiclient)
|
||||
self.assertEqual(len(number_of_acls), 2)
|
||||
|
||||
return
|
||||
Loading…
x
Reference in New Issue
Block a user