Add limit configuration for number of projects (#9172)

This commit is contained in:
Alain-Christian Courtines 2024-07-14 23:47:14 -07:00 committed by GitHub
parent b9c7275c25
commit afdf4d7d46
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 117 additions and 1 deletions

View File

@ -46,6 +46,10 @@ public interface ResourceLimitService {
"A comma-separated list of tags for host resource limits", true);
static final ConfigKey<String> ResourceLimitStorageTags = new ConfigKey<>("Advanced", String.class, "resource.limit.storage.tags", "",
"A comma-separated list of tags for storage resource limits", true);
static final ConfigKey<Long> DefaultMaxAccountProjects = new ConfigKey<>("Account Defaults",Long.class,"max.account.projects","10",
"The default maximum number of projects that can be created for an account",false);
static final ConfigKey<Long> DefaultMaxDomainProjects = new ConfigKey<>("Domain Defaults",Long.class,"max.domain.projects","50",
"The default maximum number of projects that can be created for a domain",false);
static final List<ResourceType> HostTagsSupportingTypes = List.of(ResourceType.user_vm, ResourceType.cpu, ResourceType.memory);
static final List<ResourceType> StorageTagsSupportingTypes = List.of(ResourceType.volume, ResourceType.primary_storage);

View File

@ -62,6 +62,7 @@ public class UpdateResourceLimitCmd extends BaseCmd {
+ "2 - Volume. Number of disk volumes a user can create. "
+ "3 - Snapshot. Number of snapshots a user can create. "
+ "4 - Template. Number of templates that a user can register/create. "
+ "5 - Project. Number of projects a user can create. "
+ "6 - Network. Number of guest network a user can create. "
+ "7 - VPC. Number of VPC a user can create. "
+ "8 - CPU. Total number of CPU cores a user can use. "

View File

@ -1365,6 +1365,14 @@ public enum Config {
"200",
"The default maximum primary storage space (in GiB) that can be used for an account",
null),
DefaultMaxAccountProjects(
"Account Defaults",
ManagementServer.class,
Long.class,
"max.account.projects",
"10",
"The default maximum number of projects that can be created for an account",
null),
//disabling lb as cluster sync does not work with distributed cluster
SubDomainNetworkAccess(
@ -1414,6 +1422,7 @@ public enum Config {
DefaultMaxDomainMemory("Domain Defaults", ManagementServer.class, Long.class, "max.domain.memory", "81920", "The default maximum memory (in MB) that can be used for a domain", null),
DefaultMaxDomainPrimaryStorage("Domain Defaults", ManagementServer.class, Long.class, "max.domain.primary.storage", "400", "The default maximum primary storage space (in GiB) that can be used for a domain", null),
DefaultMaxDomainSecondaryStorage("Domain Defaults", ManagementServer.class, Long.class, "max.domain.secondary.storage", "800", "The default maximum secondary storage space (in GiB) that can be used for a domain", null),
DefaultMaxDomainProjects("Domain Defaults",ManagementServer.class,Long.class,"max.domain.projects","50","The default maximum number of projects that can be created for a domain",null),
DefaultMaxProjectUserVms(
"Project Defaults",

View File

@ -301,6 +301,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
accountResourceLimitMap.put(Resource.ResourceType.memory.name(), Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountMemory.key())));
accountResourceLimitMap.put(Resource.ResourceType.primary_storage.name(), Long.parseLong(_configDao.getValue(Config.DefaultMaxAccountPrimaryStorage.key())));
accountResourceLimitMap.put(Resource.ResourceType.secondary_storage.name(), MaxAccountSecondaryStorage.value());
accountResourceLimitMap.put(Resource.ResourceType.project.name(), DefaultMaxAccountProjects.value());
domainResourceLimitMap.put(Resource.ResourceType.public_ip.name(), Long.parseLong(_configDao.getValue(Config.DefaultMaxDomainPublicIPs.key())));
domainResourceLimitMap.put(Resource.ResourceType.snapshot.name(), Long.parseLong(_configDao.getValue(Config.DefaultMaxDomainSnapshots.key())));
@ -313,6 +314,7 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
domainResourceLimitMap.put(Resource.ResourceType.memory.name(), Long.parseLong(_configDao.getValue(Config.DefaultMaxDomainMemory.key())));
domainResourceLimitMap.put(Resource.ResourceType.primary_storage.name(), Long.parseLong(_configDao.getValue(Config.DefaultMaxDomainPrimaryStorage.key())));
domainResourceLimitMap.put(Resource.ResourceType.secondary_storage.name(), Long.parseLong(_configDao.getValue(Config.DefaultMaxDomainSecondaryStorage.key())));
domainResourceLimitMap.put(Resource.ResourceType.project.name(), DefaultMaxDomainProjects.value());
} catch (NumberFormatException e) {
logger.error("NumberFormatException during configuration", e);
throw new ConfigurationException("Configuration failed due to NumberFormatException, see log for the stacktrace");
@ -2137,7 +2139,9 @@ public class ResourceLimitManagerImpl extends ManagerBase implements ResourceLim
MaxAccountSecondaryStorage,
MaxProjectSecondaryStorage,
ResourceLimitHostTags,
ResourceLimitStorageTags
ResourceLimitStorageTags,
DefaultMaxAccountProjects,
DefaultMaxDomainProjects
};
}

View File

@ -190,6 +190,12 @@ public class ResourceLimitManagerImplTest extends TestCase {
// update resource Limit for a domain for resource_type = 11 (Secondary storage (in GiB))
resourceLimitServiceCall(null, (long)1, 10, (long)400);
// update resource Limit for an account for resource_type = 5 (Project)
resourceLimitServiceCall((long) 1, (long) 1, 5, (long) 50);
// update resource Limit for a domain for resource_type = 5 (Project)
resourceLimitServiceCall(null, (long) 1, 5, (long) 100);
}
private void resourceLimitServiceCall(Long accountId, Long domainId, Integer resourceType, Long max) {
@ -413,6 +419,36 @@ public class ResourceLimitManagerImplTest extends TestCase {
Assert.assertEquals(defaultAccountCpuMax, result);
}
@Test
public void testFindCorrectResourceLimitForAccountProjects() {
AccountVO account = Mockito.mock(AccountVO.class);
Mockito.when(account.getId()).thenReturn(1L);
Mockito.when(accountManager.isRootAdmin(1L)).thenReturn(true);
long result = resourceLimitManager.findCorrectResourceLimitForAccount(account,
Resource.ResourceType.project, hostTags.get(0));
Assert.assertEquals(Resource.RESOURCE_UNLIMITED, result);
Mockito.when(accountManager.isRootAdmin(1L)).thenReturn(false);
ResourceLimitVO limit = new ResourceLimitVO();
limit.setMax(10L);
Mockito.when(resourceLimitDao.findByOwnerIdAndTypeAndTag(1L, Resource.ResourceOwnerType.Account,
Resource.ResourceType.project, hostTags.get(0))).thenReturn(limit);
result = resourceLimitManager.findCorrectResourceLimitForAccount(account, Resource.ResourceType.project,
hostTags.get(0));
Assert.assertEquals(10L, result);
long defaultAccountProjectsMax = 15L;
Map<String, Long> accountResourceLimitMap = new HashMap<>();
accountResourceLimitMap.put(Resource.ResourceType.project.name(), defaultAccountProjectsMax);
resourceLimitManager.accountResourceLimitMap = accountResourceLimitMap;
Mockito.when(resourceLimitDao.findByOwnerIdAndTypeAndTag(1L, Resource.ResourceOwnerType.Account,
Resource.ResourceType.project, hostTags.get(0))).thenReturn(null);
result = resourceLimitManager.findCorrectResourceLimitForAccount(account, Resource.ResourceType.project,
hostTags.get(0));
Assert.assertEquals(defaultAccountProjectsMax, result);
}
@Test
public void testFindCorrectResourceLimitForAccountId1() {
// long accountId = 1L;
@ -472,6 +508,68 @@ public class ResourceLimitManagerImplTest extends TestCase {
Assert.assertEquals(defaultDomainCpuMax, result);
}
@Test
public void testResourceUnlimitedForDomainProjects() {
DomainVO domain = Mockito.mock(DomainVO.class);
Mockito.when(domain.getId()).thenReturn(1L);
long result = resourceLimitManager.findCorrectResourceLimitForDomain(domain, Resource.ResourceType.project,
hostTags.get(0));
Assert.assertEquals(Resource.RESOURCE_UNLIMITED, result);
}
@Test
public void testSpecificLimitForDomainProjects() {
DomainVO domain = Mockito.mock(DomainVO.class);
Mockito.when(domain.getId()).thenReturn(2L);
ResourceLimitVO limit = new ResourceLimitVO();
limit.setMax(100L);
Mockito.when(resourceLimitDao.findByOwnerIdAndTypeAndTag(2L, Resource.ResourceOwnerType.Domain, Resource.ResourceType.project, hostTags.get(0))).thenReturn(limit);
long result = resourceLimitManager.findCorrectResourceLimitForDomain(domain, Resource.ResourceType.project, hostTags.get(0));
Assert.assertEquals(100L, result);
}
@Test
public void testParentDomainLimitForDomainProjects() {
DomainVO domain = Mockito.mock(DomainVO.class);
Mockito.when(domain.getId()).thenReturn(3L);
DomainVO parentDomain = Mockito.mock(DomainVO.class);
Mockito.when(domain.getParent()).thenReturn(5L);
Mockito.when(domainDao.findById(5L)).thenReturn(parentDomain);
ResourceLimitVO limit = new ResourceLimitVO();
limit.setMax(200L);
Mockito.when(resourceLimitDao.findByOwnerIdAndTypeAndTag(3L, Resource.ResourceOwnerType.Domain,
Resource.ResourceType.project, hostTags.get(0))).thenReturn(null);
Mockito.when(resourceLimitDao.findByOwnerIdAndTypeAndTag(5L, Resource.ResourceOwnerType.Domain,
Resource.ResourceType.project, hostTags.get(0))).thenReturn(limit);
long result = resourceLimitManager.findCorrectResourceLimitForDomain(domain, Resource.ResourceType.project,
hostTags.get(0));
Assert.assertEquals(200L, result);
}
@Test
public void testDefaultDomainProjectLimit() {
DomainVO domain = Mockito.mock(DomainVO.class);
Mockito.when(domain.getId()).thenReturn(4L);
Mockito.when(domain.getParent()).thenReturn(null);
long defaultDomainProjectsMax = 250L;
Map<String, Long> domainResourceLimitMap = new HashMap<>();
domainResourceLimitMap.put(Resource.ResourceType.project.name(), defaultDomainProjectsMax);
resourceLimitManager.domainResourceLimitMap = domainResourceLimitMap;
Mockito.when(resourceLimitDao.findByOwnerIdAndTypeAndTag(4L, Resource.ResourceOwnerType.Domain,
Resource.ResourceType.project, hostTags.get(0))).thenReturn(null);
long result = resourceLimitManager.findCorrectResourceLimitForDomain(domain, Resource.ResourceType.project,
hostTags.get(0));
Assert.assertEquals(defaultDomainProjectsMax, result);
}
@Test
public void testCheckResourceLimitWithTag() {
AccountVO account = Mockito.mock(AccountVO.class);