This is an automated email from the ASF dual-hosted git repository.
DaanHoogland pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudstack.git
The following commit(s) were added to refs/heads/main by this push:
new c07f1fd5d29 Number of running and stopped VMs as preset variables for
`Network` type Quota tariffs (#11689)
c07f1fd5d29 is described below
commit c07f1fd5d29ab2c6ba3a419dbf6d21b0a4f3900b
Author: Henrique Sato <[email protected]>
AuthorDate: Fri May 1 06:54:40 2026 -0300
Number of running and stopped VMs as preset variables for `Network` type
Quota tariffs (#11689)
Co-authored-by: Fabricio Duarte <[email protected]>
---
.../presetvariables/PresetVariableHelper.java | 14 +++++-
.../presetvariables/ResourceCounting.java | 52 ++++++++++++++++++++++
.../activationrule/presetvariables/Value.java | 11 +++++
.../presetvariables/PresetVariableHelperTest.java | 37 +++++++++++++--
.../api/response/QuotaResponseBuilderImpl.java | 3 +-
5 files changed, 112 insertions(+), 5 deletions(-)
diff --git
a/framework/quota/src/main/java/org/apache/cloudstack/quota/activationrule/presetvariables/PresetVariableHelper.java
b/framework/quota/src/main/java/org/apache/cloudstack/quota/activationrule/presetvariables/PresetVariableHelper.java
index cd87052e878..23020292027 100644
---
a/framework/quota/src/main/java/org/apache/cloudstack/quota/activationrule/presetvariables/PresetVariableHelper.java
+++
b/framework/quota/src/main/java/org/apache/cloudstack/quota/activationrule/presetvariables/PresetVariableHelper.java
@@ -35,6 +35,7 @@ import com.cloud.network.vpc.VpcVO;
import javax.inject.Inject;
import com.cloud.storage.StoragePoolTagVO;
+import com.cloud.vm.VirtualMachine;
import org.apache.cloudstack.acl.RoleVO;
import org.apache.cloudstack.acl.dao.RoleDao;
import org.apache.cloudstack.backup.BackupOfferingVO;
@@ -783,10 +784,21 @@ public class PresetVariableHelper {
value.setId(network.getUuid());
value.setName(network.getName());
value.setState(usageRecord.getState());
-
+
value.setResourceCounting(getPresetVariableValueNetworkResourceCounting(networkId));
value.setNetworkOffering(getPresetVariableValueNetworkOffering(network.getNetworkOfferingId()));
}
+ protected ResourceCounting
getPresetVariableValueNetworkResourceCounting(Long networkId) {
+ ResourceCounting resourceCounting = new ResourceCounting();
+ List<VMInstanceVO> vmInstancesVO =
vmInstanceDao.listNonRemovedVmsByTypeAndNetwork(networkId,
VirtualMachine.Type.User);
+ int runningVms = (int) vmInstancesVO.stream().filter(vm ->
vm.getState().equals(VirtualMachine.State.Running)).count();
+ int stoppedVms = (int) vmInstancesVO.stream().filter(vm ->
vm.getState().equals(VirtualMachine.State.Stopped)).count();
+
+ resourceCounting.setRunningVms(runningVms);
+ resourceCounting.setStoppedVms(stoppedVms);
+ return resourceCounting;
+ }
+
protected GenericPresetVariable getPresetVariableValueNetworkOffering(Long
networkOfferingId) {
NetworkOfferingVO networkOfferingVo =
networkOfferingDao.findByIdIncludingRemoved(networkOfferingId);
validateIfObjectIsNull(networkOfferingVo, networkOfferingId, "network
offering");
diff --git
a/framework/quota/src/main/java/org/apache/cloudstack/quota/activationrule/presetvariables/ResourceCounting.java
b/framework/quota/src/main/java/org/apache/cloudstack/quota/activationrule/presetvariables/ResourceCounting.java
new file mode 100644
index 00000000000..75049c3486a
--- /dev/null
+++
b/framework/quota/src/main/java/org/apache/cloudstack/quota/activationrule/presetvariables/ResourceCounting.java
@@ -0,0 +1,52 @@
+// 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.
+
+package org.apache.cloudstack.quota.activationrule.presetvariables;
+
+
+import org.apache.cloudstack.quota.constant.QuotaTypes;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+public class ResourceCounting {
+
+ @PresetVariableDefinition(description = "The number of running user
instances.", supportedTypes = {QuotaTypes.NETWORK})
+ private int runningVms;
+ @PresetVariableDefinition(description = "The number of stopped user
instances.", supportedTypes = {QuotaTypes.NETWORK})
+ private int stoppedVms;
+
+ public int getRunningVms() {
+ return runningVms;
+ }
+
+ public void setRunningVms(int runningVms) {
+ this.runningVms = runningVms;
+ }
+
+ public int getStoppedVms() {
+ return stoppedVms;
+ }
+
+ public void setStoppedVms(int stoppedVms) {
+ this.stoppedVms = stoppedVms;
+ }
+
+ @Override
+ public String toString() {
+ return ToStringBuilder.reflectionToString(this,
ToStringStyle.JSON_STYLE);
+ }
+}
diff --git
a/framework/quota/src/main/java/org/apache/cloudstack/quota/activationrule/presetvariables/Value.java
b/framework/quota/src/main/java/org/apache/cloudstack/quota/activationrule/presetvariables/Value.java
index aff2c040e74..286fe5c60fd 100644
---
a/framework/quota/src/main/java/org/apache/cloudstack/quota/activationrule/presetvariables/Value.java
+++
b/framework/quota/src/main/java/org/apache/cloudstack/quota/activationrule/presetvariables/Value.java
@@ -84,6 +84,9 @@ public class Value extends GenericPresetVariable {
@PresetVariableDefinition(description = "Backup offering of the backup.",
supportedTypes = {QuotaTypes.BACKUP})
private BackupOffering backupOffering;
+ @PresetVariableDefinition(description = "The amount of resources of the
usage type.")
+ private ResourceCounting resourceCounting;
+
@PresetVariableDefinition(description = "The hypervisor where the resource
was deployed. Values can be: XenServer, KVM, VMware, Hyperv, BareMetal, Ovm,
Ovm3 and LXC.",
supportedTypes = {QuotaTypes.RUNNING_VM, QuotaTypes.ALLOCATED_VM,
QuotaTypes.VM_SNAPSHOT, QuotaTypes.SNAPSHOT})
private String hypervisorType;
@@ -262,6 +265,14 @@ public class Value extends GenericPresetVariable {
this.state = state;
}
+ public ResourceCounting getResourceCounting() {
+ return resourceCounting;
+ }
+
+ public void setResourceCounting(ResourceCounting resourceCounting) {
+ this.resourceCounting = resourceCounting;
+ }
+
public GenericPresetVariable getNetworkOffering() {
return networkOffering;
}
diff --git
a/framework/quota/src/test/java/org/apache/cloudstack/quota/activationrule/presetvariables/PresetVariableHelperTest.java
b/framework/quota/src/test/java/org/apache/cloudstack/quota/activationrule/presetvariables/PresetVariableHelperTest.java
index fb093a45679..bcdbc3b46ce 100644
---
a/framework/quota/src/test/java/org/apache/cloudstack/quota/activationrule/presetvariables/PresetVariableHelperTest.java
+++
b/framework/quota/src/test/java/org/apache/cloudstack/quota/activationrule/presetvariables/PresetVariableHelperTest.java
@@ -31,11 +31,13 @@ import com.cloud.dc.ClusterDetailsDao;
import com.cloud.dc.ClusterDetailsVO;
import com.cloud.host.HostTagVO;
import com.cloud.hypervisor.Hypervisor;
+import com.cloud.network.Network;
import com.cloud.network.dao.NetworkVO;
import com.cloud.network.vpc.VpcOfferingVO;
import com.cloud.network.vpc.VpcVO;
import com.cloud.network.vpc.dao.VpcOfferingDao;
import com.cloud.storage.StoragePoolTagVO;
+import com.cloud.vm.VirtualMachine;
import org.apache.cloudstack.acl.RoleType;
import org.apache.cloudstack.acl.RoleVO;
import org.apache.cloudstack.acl.dao.RoleDao;
@@ -238,6 +240,8 @@ public class PresetVariableHelperTest {
value.setVmSnapshotType(VMSnapshot.Type.Disk.toString());
value.setComputingResources(getComputingResourcesForTests());
value.setVolumeType(Volume.Type.DATADISK.toString());
+ value.setState(Network.State.Implemented.toString());
+ value.setResourceCounting(getResourceCountingForTests());
value.setNetworkOffering(getNetworkOfferingForTests());
value.setVpcOffering(getVpcOfferingForTests());
return value;
@@ -276,6 +280,13 @@ public class PresetVariableHelperTest {
return configuration;
}
+ private ResourceCounting getResourceCountingForTests() {
+ ResourceCounting resourceCounting = new ResourceCounting();
+ resourceCounting.setRunningVms(1);
+ resourceCounting.setStoppedVms(1);
+ return resourceCounting;
+ }
+
private List<HostTagVO> getHostTagsForTests() {
return Arrays.asList(new HostTagVO(1, "tag1", false), new HostTagVO(1,
"tag2", false));
}
@@ -1343,8 +1354,8 @@ public class PresetVariableHelperTest {
Mockito.doReturn(expected.getId()).when(networkVoMock).getUuid();
Mockito.doReturn(expected.getName()).when(networkVoMock).getName();
Mockito.doReturn(expected.getState()).when(usageVoMock).getState();
+
Mockito.doReturn(expected.getResourceCounting()).when(presetVariableHelperSpy).getPresetVariableValueNetworkResourceCounting(Mockito.anyLong());
Mockito.doReturn(expected.getNetworkOffering()).when(presetVariableHelperSpy).getPresetVariableValueNetworkOffering(Mockito.anyLong());
-
Mockito.doReturn(UsageTypes.NETWORK).when(usageVoMock).getUsageType();
Value result = new Value();
@@ -1352,7 +1363,27 @@ public class PresetVariableHelperTest {
assertPresetVariableIdAndName(expected, result);
Assert.assertEquals(expected.getState(), result.getState());
- Assert.assertEquals(expected.getNetworkOffering(),
result.getNetworkOffering());
+ Assert.assertEquals(expected.getResourceCounting(),
result.getResourceCounting());
+ }
+
+ @Test
+ public void
getPresetVariableValueNetworkResourceCountingTestSetValueAndReturnObject() {
+ VMInstanceVO vmInstanceVoMock1 = Mockito.spy(VMInstanceVO.class);
+ vmInstanceVoMock1.setState(VirtualMachine.State.Stopped);
+
+ VMInstanceVO vmInstanceVoMock2 = Mockito.spy(VMInstanceVO.class);
+ vmInstanceVoMock2.setState(VirtualMachine.State.Running);
+
+ Mockito.doReturn(List.of(vmInstanceVoMock1,
vmInstanceVoMock2)).when(vmInstanceDaoMock).listNonRemovedVmsByTypeAndNetwork(Mockito.anyLong(),
Mockito.any());
+
+ mockMethodValidateIfObjectIsNull();
+
+ ResourceCounting expected = getResourceCountingForTests();
+
+ ResourceCounting result =
presetVariableHelperSpy.getPresetVariableValueNetworkResourceCounting(1L);
+
+ Assert.assertEquals(expected.getRunningVms(), result.getRunningVms());
+ Assert.assertEquals(expected.getStoppedVms(), result.getStoppedVms());
}
@Test
@@ -1362,7 +1393,7 @@ public class PresetVariableHelperTest {
presetVariableHelperSpy.loadPresetVariableValueForVpc(usageVoMock,
null);
});
- Mockito.verifyNoInteractions(networkDaoMock);
+ Mockito.verifyNoInteractions(vpcDaoMock);
}
@Test
diff --git
a/plugins/database/quota/src/main/java/org/apache/cloudstack/api/response/QuotaResponseBuilderImpl.java
b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/response/QuotaResponseBuilderImpl.java
index 173c0723731..c919bb5887c 100644
---
a/plugins/database/quota/src/main/java/org/apache/cloudstack/api/response/QuotaResponseBuilderImpl.java
+++
b/plugins/database/quota/src/main/java/org/apache/cloudstack/api/response/QuotaResponseBuilderImpl.java
@@ -98,6 +98,7 @@ import
org.apache.cloudstack.quota.activationrule.presetvariables.ComputingResou
import
org.apache.cloudstack.quota.activationrule.presetvariables.GenericPresetVariable;
import
org.apache.cloudstack.quota.activationrule.presetvariables.PresetVariableDefinition;
import
org.apache.cloudstack.quota.activationrule.presetvariables.PresetVariables;
+import
org.apache.cloudstack.quota.activationrule.presetvariables.ResourceCounting;
import org.apache.cloudstack.quota.activationrule.presetvariables.Value;
import org.apache.cloudstack.quota.constant.QuotaConfig;
import org.apache.cloudstack.quota.constant.QuotaTypes;
@@ -185,7 +186,7 @@ public class QuotaResponseBuilderImpl implements
QuotaResponseBuilder {
private VolumeDao volumeDao;
- private final Class<?>[] assignableClasses = {GenericPresetVariable.class,
ComputingResources.class};
+ private final Class<?>[] assignableClasses = {GenericPresetVariable.class,
ComputingResources.class, ResourceCounting.class};
private Set<Account.Type> accountTypesThatCanListAllQuotaSummaries =
Sets.newHashSet(Account.Type.ADMIN, Account.Type.DOMAIN_ADMIN);