VPC: CS-15798 - added vpc resource limit. Check vpc functional spec for more details:

http://wiki.cloudstack.org/display/RelOps/Inter-VLAN+Routing+functional+spec

Conflicts:

	server/src/com/cloud/api/ApiResponseHelper.java
	server/src/com/cloud/network/vpc/VpcManagerImpl.java
	server/src/com/cloud/resourcelimit/ResourceLimitManagerImpl.java
This commit is contained in:
Alena Prokharchyk 2012-08-01 16:15:06 -07:00
parent 5cbe3d9722
commit b92d2336ad
9 changed files with 92 additions and 23 deletions

View File

@ -20,10 +20,11 @@ import java.util.List;
import java.util.Map;
import com.cloud.api.ApiConstants;
import com.cloud.utils.IdentityProxy;
import com.cloud.serializer.Param;
import com.cloud.utils.IdentityProxy;
import com.google.gson.annotations.SerializedName;
@SuppressWarnings("unused")
public class AccountResponse extends BaseResponse {
@SerializedName(ApiConstants.ID) @Param(description="the id of the account")
private IdentityProxy id = new IdentityProxy("account");
@ -118,6 +119,15 @@ public class AccountResponse extends BaseResponse {
@SerializedName("networkavailable") @Param(description="the total number of networks available to be created for this account", since="3.0.1")
private String networkAvailable;
@SerializedName("vpclimit") @Param(description="the total number of vpcs the account can own", since="3.0.5")
private String vpcLimit;
@SerializedName("vpctotal") @Param(description="the total number of vpcs owned by account", since="3.0.5")
private Long vpcTotal;
@SerializedName("vpcavailable") @Param(description="the total number of vpcs available to be created for this account", since="3.0.5")
private String vpcAvailable;
@SerializedName(ApiConstants.STATE) @Param(description="the state of the account")
private String state;

View File

@ -27,7 +27,8 @@ public interface Resource {
snapshot("snapshot", 3, ResourceOwnerType.Account, ResourceOwnerType.Domain),
template("template", 4, ResourceOwnerType.Account, ResourceOwnerType.Domain),
project("project", 5, ResourceOwnerType.Account, ResourceOwnerType.Domain),
network("network", 6, ResourceOwnerType.Account, ResourceOwnerType.Domain);
network("network", 6, ResourceOwnerType.Account, ResourceOwnerType.Domain),
vpc("vpc", 7, ResourceOwnerType.Account, ResourceOwnerType.Domain);
private String name;
private ResourceOwnerType[] supportedOwners;

View File

@ -76,8 +76,9 @@ public interface VpcService {
* @param cidr
* @param networkDomain TODO
* @return
* @throws ResourceAllocationException TODO
*/
public Vpc createVpc(long zoneId, long vpcOffId, long vpcOwnerId, String vpcName, String displayText, String cidr, String networkDomain);
public Vpc createVpc(long zoneId, long vpcOffId, long vpcOwnerId, String vpcName, String displayText, String cidr, String networkDomain) throws ResourceAllocationException;
/**
* @param vpcId

View File

@ -265,6 +265,7 @@ public class ApiResponseHelper implements ResponseGenerator {
accountResponse.setDomainName(ApiDBUtils.findDomainById(account.getDomainId()).getName());
accountResponse.setState(account.getState().toString());
accountResponse.setNetworkDomain(account.getNetworkDomain());
accountResponse.setDefaultZone(account.getDefaultZoneId());
// get network stat
List<UserStatisticsVO> stats = ApiDBUtils.listUserStatsBy(account.getId());
@ -361,7 +362,7 @@ public class ApiResponseHelper implements ResponseGenerator {
accountResponse.setVmStopped(vmStopped);
accountResponse.setVmRunning(vmRunning);
accountResponse.setObjectName("account");
//get resource limits for projects
Long projectLimit = ApiDBUtils.findCorrectResourceLimit(ResourceType.project, account.getId());
String projectLimitDisplay = (accountIsAdmin || projectLimit == -1) ? "Unlimited" : String.valueOf(projectLimit);
@ -370,7 +371,7 @@ public class ApiResponseHelper implements ResponseGenerator {
accountResponse.setProjectLimit(projectLimitDisplay);
accountResponse.setProjectTotal(projectTotal);
accountResponse.setProjectAvailable(projectAvail);
//get resource limits for networks
Long networkLimit = ApiDBUtils.findCorrectResourceLimit(ResourceType.network, account.getId());
String networkLimitDisplay = (accountIsAdmin || networkLimit == -1) ? "Unlimited" : String.valueOf(networkLimit);
@ -379,7 +380,16 @@ public class ApiResponseHelper implements ResponseGenerator {
accountResponse.setNetworkLimit(networkLimitDisplay);
accountResponse.setNetworkTotal(networkTotal);
accountResponse.setNetworkAvailable(networkAvail);
//get resource limits for vpcs
Long vpcLimit = ApiDBUtils.findCorrectResourceLimit(ResourceType.vpc, account.getId());
String vpcLimitDisplay = (accountIsAdmin || vpcLimit == -1) ? "Unlimited" : String.valueOf(vpcLimit);
Long vpcTotal = ApiDBUtils.getResourceCount(ResourceType.vpc, account.getId());
String vpcAvail = (accountIsAdmin || vpcLimit == -1) ? "Unlimited" : String.valueOf(vpcLimit - vpcTotal);
accountResponse.setNetworkLimit(vpcLimitDisplay);
accountResponse.setNetworkTotal(vpcTotal);
accountResponse.setNetworkAvailable(vpcAvail);
// adding all the users for an account as part of the response obj
List<UserVO> usersForAccount = ApiDBUtils.listUsersByAccount(account.getAccountId());
List<UserResponse> userResponseList = new ArrayList<UserResponse>();
@ -392,7 +402,8 @@ public class ApiResponseHelper implements ResponseGenerator {
accountResponse.setDetails(ApiDBUtils.getAccountDetails(account.getId()));
return accountResponse;
}
@Override
public UserResponse createUserResponse(UserAccount user) {
UserResponse userResponse = new UserResponse();
@ -3876,4 +3887,4 @@ public class ApiResponseHelper implements ResponseGenerator {
response.setObjectName("vpnconnection");
return response;
}
}
}

View File

@ -299,6 +299,8 @@ public enum Config {
DefaultMaxAccountSnapshots("Account Defaults", ManagementServer.class, Long.class, "max.account.snapshots", "20", "The default maximum number of snapshots that can be created for an account", null),
DefaultMaxAccountVolumes("Account Defaults", ManagementServer.class, Long.class, "max.account.volumes", "20", "The default maximum number of volumes that can be created for an account", null),
DefaultMaxAccountNetworks("Account Defaults", ManagementServer.class, Long.class, "max.account.networks", "20", "The default maximum number of networks that can be created for an account", null),
DefaultMaxAccountVpcs("Account Defaults", ManagementServer.class, Long.class, "max.account.vpcs", "20", "The default maximum number of vpcs that can be created for an account", null),
ResourceCountCheckInterval("Advanced", ManagementServer.class, Long.class, "resourcecount.check.interval", "0", "Time (in seconds) to wait before retrying resource count check task. Default is 0 which is to never run the task", "Seconds"),
DirectAgentLoadSize("Advanced", ManagementServer.class, Integer.class, "direct.agent.load.size", "16", "The number of direct agents to load each time", null),
@ -321,6 +323,7 @@ public enum Config {
DefaultMaxProjectSnapshots("Project Defaults", ManagementServer.class, Long.class, "max.project.snapshots", "20", "The default maximum number of snapshots that can be created for a project", null),
DefaultMaxProjectVolumes("Project Defaults", ManagementServer.class, Long.class, "max.project.volumes", "20", "The default maximum number of volumes that can be created for a project", null),
DefaultMaxProjectNetworks("Project Defaults", ManagementServer.class, Long.class, "max.project.networks", "20", "The default maximum number of networks that can be created for a project", null),
DefaultMaxProjectVpcs("Project Defaults", ManagementServer.class, Long.class, "max.project.vpcs", "20", "The default maximum number of vpcs that can be created for a project", null),
ProjectInviteRequired("Project Defaults", ManagementServer.class, Boolean.class, "project.invite.required", "false", "If invitation confirmation is required when add account to project. Default value is false", null),
ProjectInvitationExpirationTime("Project Defaults", ManagementServer.class, Long.class, "project.invite.timeout", "86400", "Invitation expiration time (in seconds). Default is 1 day - 86400 seconds", null),

View File

@ -36,5 +36,7 @@ public interface VpcDao extends GenericDao<VpcVO, Long>{
List<? extends Vpc> listByAccountId(long accountId);
List<VpcVO> listInactiveVpcs();
long countByAccountId(long accountId);
}

View File

@ -40,6 +40,7 @@ import com.cloud.utils.db.Transaction;
public class VpcDaoImpl extends GenericDaoBase<VpcVO, Long> implements VpcDao{
final GenericSearchBuilder<VpcVO, Integer> CountByOfferingId;
final SearchBuilder<VpcVO> AllFieldsSearch;
final GenericSearchBuilder<VpcVO, Long> CountByAccountId;
ResourceTagsDaoImpl _tagsDao = ComponentLocator.inject(ResourceTagsDaoImpl.class);
protected VpcDaoImpl() {
@ -56,6 +57,12 @@ public class VpcDaoImpl extends GenericDaoBase<VpcVO, Long> implements VpcDao{
AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), Op.EQ);
AllFieldsSearch.and("accountId", AllFieldsSearch.entity().getAccountId(), Op.EQ);
AllFieldsSearch.done();
CountByAccountId = createSearchBuilder(Long.class);
CountByAccountId.select(null, Func.COUNT, CountByAccountId.entity().getId());
CountByAccountId.and("offeringId", CountByAccountId.entity().getAccountId(), Op.EQ);
CountByAccountId.and("removed", CountByAccountId.entity().getRemoved(), Op.NULL);
CountByAccountId.done();
}
@ -102,5 +109,13 @@ public class VpcDaoImpl extends GenericDaoBase<VpcVO, Long> implements VpcDao{
txn.commit();
return result;
}
@Override
public long countByAccountId(long accountId) {
SearchCriteria<Long> sc = CountByAccountId.create();
sc.setParameters("accountId", accountId);
List<Long> results = customSearch(sc, null);
return results.get(0);
}
}

View File

@ -36,6 +36,7 @@ import com.cloud.api.commands.ListPrivateGatewaysCmd;
import com.cloud.api.commands.ListStaticRoutesCmd;
import com.cloud.configuration.Config;
import com.cloud.configuration.ConfigurationManager;
import com.cloud.configuration.Resource.ResourceType;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.dc.DataCenter;
import com.cloud.dc.Vlan.VlanType;
@ -89,6 +90,7 @@ import com.cloud.tags.ResourceTagVO;
import com.cloud.tags.dao.ResourceTagDao;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.ResourceLimitService;
import com.cloud.user.User;
import com.cloud.user.UserContext;
import com.cloud.utils.NumbersUtil;
@ -158,6 +160,8 @@ public class VpcManagerImpl implements VpcManager, Manager{
Site2SiteVpnManager _s2sVpnMgr;
@Inject
VlanDao _vlanDao = null;
@Inject
ResourceLimitService _resourceLimitMgr;
private final ScheduledExecutorService _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("VpcChecker"));
@ -510,13 +514,16 @@ public class VpcManagerImpl implements VpcManager, Manager{
@Override
@ActionEvent(eventType = EventTypes.EVENT_VPC_CREATE, eventDescription = "creating vpc", create=true)
public Vpc createVpc(long zoneId, long vpcOffId, long vpcOwnerId, String vpcName, String displayText, String cidr,
String networkDomain) {
String networkDomain) throws ResourceAllocationException {
Account caller = UserContext.current().getCaller();
Account owner = _accountMgr.getAccount(vpcOwnerId);
//Verify that caller can perform actions in behalf of vpc owner
_accountMgr.checkAccess(caller, null, false, owner);
//check resource limit
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.vpc);
// Validate vpc offering
VpcOfferingVO vpcOff = _vpcOffDao.findById(vpcOffId);
if (vpcOff == null) {
@ -561,7 +568,8 @@ public class VpcManagerImpl implements VpcManager, Manager{
return false;
}
@DB
protected Vpc createVpc(long zoneId, long vpcOffId, Account vpcOwner, String vpcName, String displayText, String cidr,
String networkDomain) {
@ -593,16 +601,17 @@ public class VpcManagerImpl implements VpcManager, Manager{
" that overlaps the cidr specified: " + cidr);
}
}
Transaction txn = Transaction.currentTxn();
txn.start();
VpcVO vpc = new VpcVO (zoneId, vpcName, displayText, vpcOwner.getId(), vpcOwner.getDomainId(), vpcOffId, cidr,
networkDomain);
vpc = _vpcDao.persist(vpc);
if (vpc != null) {
s_logger.debug("Created VPC " + vpc);
} else {
s_logger.debug("Failed to create VPC");
}
_resourceLimitMgr.incrementResourceCount(vpcOwner.getId(), ResourceType.vpc);
txn.commit();
s_logger.debug("Created VPC " + vpc);
return vpc;
}
@ -625,6 +634,7 @@ public class VpcManagerImpl implements VpcManager, Manager{
}
@Override
@DB
public boolean destroyVpc(Vpc vpc) throws ConcurrentOperationException, ResourceUnavailableException {
UserContext ctx = UserContext.current();
@ -633,13 +643,22 @@ public class VpcManagerImpl implements VpcManager, Manager{
if (networksCount > 0) {
throw new InvalidParameterValueException("Can't delete VPC " + vpc + " as its used by " + networksCount + " networks");
}
//mark VPC as disabled
s_logger.debug("Updating VPC " + vpc + " with state " + Vpc.State.Inactive + " as a part of vpc delete");
VpcVO vpcVO = _vpcDao.findById(vpc.getId());
vpcVO.setState(Vpc.State.Inactive);
_vpcDao.update(vpc.getId(), vpcVO);
//mark VPC as inactive
if (vpc.getState() != Vpc.State.Inactive) {
s_logger.debug("Updating VPC " + vpc + " with state " + Vpc.State.Inactive + " as a part of vpc delete");
VpcVO vpcVO = _vpcDao.findById(vpc.getId());
vpcVO.setState(Vpc.State.Inactive);
Transaction txn = Transaction.currentTxn();
txn.start();
_vpcDao.update(vpc.getId(), vpcVO);
//decrement resource count
_resourceLimitMgr.decrementResourceCount(vpc.getAccountId(), ResourceType.vpc);
txn.commit();
}
//shutdown VPC
if (!shutdownVpc(vpc.getId())) {
s_logger.warn("Failed to shutdown vpc " + vpc + " as a part of vpc destroy process");

View File

@ -52,6 +52,7 @@ import com.cloud.exception.PermissionDeniedException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.network.dao.IPAddressDao;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.vpc.Dao.VpcDao;
import com.cloud.projects.Project;
import com.cloud.projects.ProjectAccount.Role;
import com.cloud.projects.dao.ProjectAccountDao;
@ -119,6 +120,8 @@ public class ResourceLimitManagerImpl implements ResourceLimitService, Manager {
private ProjectAccountDao _projectAccountDao;
@Inject
private NetworkDao _networkDao;
@Inject
private VpcDao _vpcDao;
protected SearchBuilder<ResourceCountVO> ResourceCountSearch;
ScheduledExecutorService _rcExecutor;
@ -165,6 +168,7 @@ public class ResourceLimitManagerImpl implements ResourceLimitService, Manager {
projectResourceLimitMap.put(Resource.ResourceType.user_vm, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectUserVms.key())));
projectResourceLimitMap.put(Resource.ResourceType.volume, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectVolumes.key())));
projectResourceLimitMap.put(Resource.ResourceType.network, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectNetworks.key())));
projectResourceLimitMap.put(Resource.ResourceType.vpc, Long.parseLong(_configDao.getValue(Config.DefaultMaxProjectVpcs.key())));
accountResourceLimitMap.put(Resource.ResourceType.public_ip, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountPublicIPs.key())));
accountResourceLimitMap.put(Resource.ResourceType.snapshot, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountSnapshots.key())));
@ -172,6 +176,7 @@ public class ResourceLimitManagerImpl implements ResourceLimitService, Manager {
accountResourceLimitMap.put(Resource.ResourceType.user_vm, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountUserVms.key())));
accountResourceLimitMap.put(Resource.ResourceType.volume, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountVolumes.key())));
accountResourceLimitMap.put(Resource.ResourceType.network, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountNetworks.key())));
accountResourceLimitMap.put(Resource.ResourceType.vpc, Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountVpcs.key())));
return true;
}
@ -737,6 +742,8 @@ public class ResourceLimitManagerImpl implements ResourceLimitService, Manager {
newCount = _projectAccountDao.countByAccountIdAndRole(accountId, Role.Admin);
} else if (type == Resource.ResourceType.network) {
newCount = _networkDao.countNetworksUserCanCreate(accountId);
} else if (type == Resource.ResourceType.vpc) {
newCount = _vpcDao.countByAccountId(accountId);
} else {
throw new InvalidParameterValueException("Unsupported resource type " + type);
}