Skip to content

Commit 0a13fb2

Browse files
authored
Prevent scaling of cluster if count / resources exceed account resource limits (#12167)
1 parent 223fc25 commit 0a13fb2

File tree

1 file changed

+54
-0
lines changed

1 file changed

+54
-0
lines changed

plugins/integrations/kubernetes-service/src/main/java/com/cloud/kubernetes/cluster/KubernetesClusterManagerImpl.java

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@
4747
import javax.inject.Inject;
4848
import javax.naming.ConfigurationException;
4949

50+
import com.cloud.configuration.Resource;
51+
import com.cloud.user.ResourceLimitService;
5052
import org.apache.cloudstack.acl.ControlledEntity;
5153
import org.apache.cloudstack.acl.Role;
5254
import org.apache.cloudstack.acl.RolePermissionEntity;
@@ -398,6 +400,8 @@ public class KubernetesClusterManagerImpl extends ManagerBase implements Kuberne
398400
public ProjectManager projectManager;
399401
@Inject
400402
RoleService roleService;
403+
@Inject
404+
ResourceLimitService resourceLimitService;
401405

402406
private void logMessage(final Level logLevel, final String message, final Exception e) {
403407
if (logLevel == Level.WARN) {
@@ -1341,8 +1345,58 @@ private void validateKubernetesClusterScaleParameters(ScaleKubernetesClusterCmd
13411345
validateServiceOfferingsForNodeTypesScale(serviceOfferingNodeTypeMap, defaultServiceOfferingId, kubernetesCluster, clusterVersion);
13421346

13431347
validateKubernetesClusterScaleSize(kubernetesCluster, clusterSize, maxClusterSize, zone);
1348+
1349+
ensureResourceLimitsForScale(kubernetesCluster, serviceOfferingNodeTypeMap,
1350+
clusterSize != null ? clusterSize : null,
1351+
kubernetesCluster.getAccountId());
1352+
}
1353+
1354+
protected void ensureResourceLimitsForScale(final KubernetesClusterVO cluster,
1355+
final Map<String, Long> requestedServiceOfferingIds,
1356+
final Long targetNodeCounts,
1357+
final Long accountId) {
1358+
1359+
long totalAdditionalVms = 0L;
1360+
long totalAdditionalCpuUnits = 0L;
1361+
long totalAdditionalRamMb = 0L;
1362+
1363+
1364+
List<KubernetesClusterVmMapVO> clusterVmMapVOS = kubernetesClusterVmMapDao.listByClusterIdAndVmType(cluster.getId(), WORKER);
1365+
long currentCount = clusterVmMapVOS != null ? clusterVmMapVOS.size() : 0L;
1366+
long desiredCount = targetNodeCounts != null ? targetNodeCounts : currentCount;
1367+
long additional = Math.max(0L, desiredCount - currentCount);
1368+
if (additional == 0L) {
1369+
return;
1370+
}
1371+
1372+
Long offeringId = (requestedServiceOfferingIds != null && requestedServiceOfferingIds.containsKey(WORKER.name())) ?
1373+
requestedServiceOfferingIds.get(WORKER.name()) :
1374+
getExistingServiceOfferingIdForNodeType(WORKER.name(), cluster);
1375+
1376+
if (offeringId == null) {
1377+
offeringId = cluster.getServiceOfferingId();
1378+
}
1379+
1380+
ServiceOffering so = serviceOfferingDao.findById(offeringId);
1381+
if (so == null) {
1382+
throw new InvalidParameterValueException(String.format("Invalid service offering for node type %s", WORKER.name()));
1383+
}
1384+
1385+
totalAdditionalVms += additional;
1386+
long effectiveCpu = (long) so.getCpu() * so.getSpeed();
1387+
totalAdditionalCpuUnits += effectiveCpu * additional;
1388+
totalAdditionalRamMb += so.getRamSize() * additional;
1389+
1390+
try {
1391+
resourceLimitService.checkResourceLimit(accountDao.findById(accountId), Resource.ResourceType.user_vm, totalAdditionalVms);
1392+
resourceLimitService.checkResourceLimit(accountDao.findById(accountId), Resource.ResourceType.cpu, totalAdditionalCpuUnits);
1393+
resourceLimitService.checkResourceLimit(accountDao.findById(accountId), Resource.ResourceType.memory, totalAdditionalRamMb);
1394+
} catch (Exception e) {
1395+
throw new CloudRuntimeException("Resource limits prevent scaling the cluster: " + e.getMessage(), e);
1396+
}
13441397
}
13451398

1399+
13461400
protected void validateServiceOfferingsForNodeTypesScale(Map<String, Long> map, Long defaultServiceOfferingId, KubernetesClusterVO kubernetesCluster, KubernetesSupportedVersion clusterVersion) {
13471401
for (String key : CLUSTER_NODES_TYPES_LIST) {
13481402
Long serviceOfferingId = map.getOrDefault(key, defaultServiceOfferingId);

0 commit comments

Comments
 (0)