Add IOPS and bytes preset variables to VOLUME usage type (#10326)

* Add bytes and iops preset variables to volume usage type

* Add new line at the end of file

Co-authored-by: dahn <daan.hoogland@gmail.com>

* Change disk offering preset variable class name

---------

Co-authored-by: Lucas Martins <lucas.martins@scclouds.com.br>
Co-authored-by: dahn <daan.hoogland@gmail.com>
This commit is contained in:
Lucas Martins 2025-02-14 08:28:06 -03:00 committed by GitHub
parent 2a4a1f73d0
commit a093f00ab5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 216 additions and 10 deletions

View File

@ -0,0 +1,165 @@
// 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;
public class DiskOfferingPresetVariables extends GenericPresetVariable {
@PresetVariableDefinition(description = "A long informing the bytes read rate of the disk offering.")
private Long bytesReadRate;
@PresetVariableDefinition(description = "A long informing the burst bytes read rate of the disk offering.")
private Long bytesReadBurst;
@PresetVariableDefinition(description = "The length (in seconds) of the bytes read burst.")
private Long bytesReadBurstLength;
@PresetVariableDefinition(description = "A long informing the bytes write rate of the disk offering.")
private Long bytesWriteRate;
@PresetVariableDefinition(description = "A long informing the burst bytes write rate of the disk offering.")
private Long bytesWriteBurst;
@PresetVariableDefinition(description = "The length (in seconds) of the bytes write burst.")
private Long bytesWriteBurstLength;
@PresetVariableDefinition(description = "A long informing the I/O requests read rate of the disk offering.")
private Long iopsReadRate;
@PresetVariableDefinition(description = "A long informing the burst I/O requests read rate of the disk offering.")
private Long iopsReadBurst;
@PresetVariableDefinition(description = "The length (in seconds) of the IOPS read burst.")
private Long iopsReadBurstLength;
@PresetVariableDefinition(description = "A long informing the I/O requests write rate of the disk offering.")
private Long iopsWriteRate;
@PresetVariableDefinition(description = "A long informing the burst I/O requests write rate of the disk offering.")
private Long iopsWriteBurst;
@PresetVariableDefinition(description = "The length (in seconds) of the IOPS write burst.")
private Long iopsWriteBurstLength;
public Long getBytesReadRate() {
return bytesReadRate;
}
public void setBytesReadRate(Long bytesReadRate) {
this.bytesReadRate = bytesReadRate;
fieldNamesToIncludeInToString.add("bytesReadRate");
}
public Long getBytesReadBurst() {
return bytesReadBurst;
}
public void setBytesReadBurst(Long bytesReadBurst) {
this.bytesReadBurst = bytesReadBurst;
fieldNamesToIncludeInToString.add("bytesReadBurst");
}
public Long getBytesReadBurstLength() {
return bytesReadBurstLength;
}
public void setBytesReadBurstLength(Long bytesReadBurstLength) {
this.bytesReadBurstLength = bytesReadBurstLength;
fieldNamesToIncludeInToString.add("bytesReadBurstLength");
}
public Long getBytesWriteRate() {
return bytesWriteRate;
}
public void setBytesWriteRate(Long bytesWriteRate) {
this.bytesWriteRate = bytesWriteRate;
fieldNamesToIncludeInToString.add("bytesWriteRate");
}
public Long getBytesWriteBurst() {
return bytesWriteBurst;
}
public void setBytesWriteBurst(Long bytesWriteBurst) {
this.bytesWriteBurst = bytesWriteBurst;
fieldNamesToIncludeInToString.add("bytesWriteBurst");
}
public Long getBytesWriteBurstLength() {
return bytesWriteBurstLength;
}
public void setBytesWriteBurstLength(Long bytesWriteBurstLength) {
this.bytesWriteBurstLength = bytesWriteBurstLength;
fieldNamesToIncludeInToString.add("bytesWriteBurstLength");
}
public Long getIopsReadRate() {
return iopsReadRate;
}
public void setIopsReadRate(Long iopsReadRate) {
this.iopsReadRate = iopsReadRate;
fieldNamesToIncludeInToString.add("iopsReadRate");
}
public Long getIopsReadBurst() {
return iopsReadBurst;
}
public void setIopsReadBurst(Long iopsReadBurst) {
this.iopsReadBurst = iopsReadBurst;
fieldNamesToIncludeInToString.add("iopsReadBurst");
}
public Long getIopsReadBurstLength() {
return iopsReadBurstLength;
}
public void setIopsReadBurstLength(Long iopsReadBurstLength) {
this.iopsReadBurstLength = iopsReadBurstLength;
fieldNamesToIncludeInToString.add("iopsReadBurstLength");
}
public Long getIopsWriteRate() {
return iopsWriteRate;
}
public void setIopsWriteRate(Long iopsWriteRate) {
this.iopsWriteRate = iopsWriteRate;
fieldNamesToIncludeInToString.add("iopsWriteRate");
}
public Long getIopsWriteBurst() {
return iopsWriteBurst;
}
public void setIopsWriteBurst(Long iopsWriteBurst) {
this.iopsWriteBurst = iopsWriteBurst;
fieldNamesToIncludeInToString.add("iopsWriteBurst");
}
public Long getIopsWriteBurstLength() {
return iopsWriteBurstLength;
}
public void setIopsWriteBurstLength(Long iopsWriteBurstLength) {
this.iopsWriteBurstLength = iopsWriteBurstLength;
fieldNamesToIncludeInToString.add("iopsWriteBurstLength");
}
}

View File

@ -492,6 +492,7 @@ public class PresetVariableHelper {
value.setId(volumeVo.getUuid());
value.setName(volumeVo.getName());
value.setProvisioningType(volumeVo.getProvisioningType());
value.setVolumeType(volumeVo.getVolumeType());
Long poolId = volumeVo.getPoolId();
if (poolId == null) {
@ -510,13 +511,25 @@ public class PresetVariableHelper {
}
}
protected GenericPresetVariable getPresetVariableValueDiskOffering(Long diskOfferingId) {
protected DiskOfferingPresetVariables getPresetVariableValueDiskOffering(Long diskOfferingId) {
DiskOfferingVO diskOfferingVo = diskOfferingDao.findByIdIncludingRemoved(diskOfferingId);
validateIfObjectIsNull(diskOfferingVo, diskOfferingId, "disk offering");
GenericPresetVariable diskOffering = new GenericPresetVariable();
DiskOfferingPresetVariables diskOffering = new DiskOfferingPresetVariables();
diskOffering.setId(diskOfferingVo.getUuid());
diskOffering.setName(diskOfferingVo.getName());
diskOffering.setBytesReadRate(diskOfferingVo.getBytesReadRate());
diskOffering.setBytesReadBurst(diskOfferingVo.getBytesReadRateMax());
diskOffering.setBytesReadBurstLength(diskOfferingVo.getBytesReadRateMaxLength());
diskOffering.setBytesWriteRate(diskOfferingVo.getBytesWriteRate());
diskOffering.setBytesWriteBurst(diskOfferingVo.getBytesWriteRateMax());
diskOffering.setBytesWriteBurstLength(diskOfferingVo.getBytesWriteRateMaxLength());
diskOffering.setIopsReadRate(diskOfferingVo.getIopsReadRate());
diskOffering.setIopsReadBurst(diskOfferingVo.getIopsReadRateMax());
diskOffering.setIopsReadBurstLength(diskOfferingVo.getIopsReadRateMaxLength());
diskOffering.setIopsWriteRate(diskOfferingVo.getIopsWriteRate());
diskOffering.setIopsWriteBurst(diskOfferingVo.getIopsWriteRateMax());
diskOffering.setIopsWriteBurstLength(diskOfferingVo.getIopsWriteRateMaxLength());
return diskOffering;
}

View File

@ -22,6 +22,7 @@ import java.util.Map;
import com.cloud.storage.Snapshot;
import com.cloud.storage.Storage.ProvisioningType;
import com.cloud.storage.Volume;
import com.cloud.vm.snapshot.VMSnapshot;
import org.apache.cloudstack.quota.constant.QuotaTypes;
@ -75,7 +76,7 @@ public class Value extends GenericPresetVariable {
private GenericPresetVariable template;
@PresetVariableDefinition(description = "Disk offering of the volume.", supportedTypes = {QuotaTypes.VOLUME})
private GenericPresetVariable diskOffering;
private DiskOfferingPresetVariables diskOffering;
@PresetVariableDefinition(description = "Storage where the volume or snapshot is. While handling with snapshots, this value can be from the primary storage if the global " +
"setting 'snapshot.backup.to.secondary' is false, otherwise it will be from secondary storage.", supportedTypes = {QuotaTypes.VOLUME, QuotaTypes.SNAPSHOT})
@ -93,6 +94,10 @@ public class Value extends GenericPresetVariable {
@PresetVariableDefinition(description = "The volume format. Values can be: RAW, VHD, VHDX, OVA and QCOW2.", supportedTypes = {QuotaTypes.VOLUME, QuotaTypes.VOLUME_SECONDARY})
private String volumeFormat;
@PresetVariableDefinition(description = "The volume type. Values can be: UNKNOWN, ROOT, SWAP, DATADISK and ISO.", supportedTypes = {QuotaTypes.VOLUME})
private Volume.Type volumeType;
private String state;
public Host getHost() {
@ -194,11 +199,11 @@ public class Value extends GenericPresetVariable {
fieldNamesToIncludeInToString.add("template");
}
public GenericPresetVariable getDiskOffering() {
public DiskOfferingPresetVariables getDiskOffering() {
return diskOffering;
}
public void setDiskOffering(GenericPresetVariable diskOffering) {
public void setDiskOffering(DiskOfferingPresetVariables diskOffering) {
this.diskOffering = diskOffering;
fieldNamesToIncludeInToString.add("diskOffering");
}
@ -257,6 +262,15 @@ public class Value extends GenericPresetVariable {
return volumeFormat;
}
public Volume.Type getVolumeType() {
return volumeType;
}
public void setVolumeType(Volume.Type volumeType) {
this.volumeType = volumeType;
fieldNamesToIncludeInToString.add("volumeType");
}
public String getState() {
return state;
}

View File

@ -76,6 +76,7 @@ import com.cloud.storage.SnapshotVO;
import com.cloud.storage.Storage.ImageFormat;
import com.cloud.storage.Storage.ProvisioningType;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.Volume;
import com.cloud.storage.VolumeVO;
import com.cloud.storage.dao.DiskOfferingDao;
import com.cloud.storage.dao.GuestOSDao;
@ -208,7 +209,7 @@ public class PresetVariableHelperTest {
value.setComputeOffering(getComputeOfferingForTests());
value.setTags(Collections.singletonMap("tag1", "value1"));
value.setTemplate(getGenericPresetVariableForTests());
value.setDiskOffering(getGenericPresetVariableForTests());
value.setDiskOffering(getDiskOfferingForTests());
value.setProvisioningType(ProvisioningType.THIN);
value.setStorage(getStorageForTests());
value.setSize(ByteScaleUtils.GiB);
@ -216,6 +217,7 @@ public class PresetVariableHelperTest {
value.setTag("tag_test");
value.setVmSnapshotType(VMSnapshot.Type.Disk);
value.setComputingResources(getComputingResourcesForTests());
value.setVolumeType(Volume.Type.DATADISK);
return value;
}
@ -308,6 +310,13 @@ public class PresetVariableHelperTest {
return backupOffering;
}
private DiskOfferingPresetVariables getDiskOfferingForTests() {
DiskOfferingPresetVariables diskOffering = new DiskOfferingPresetVariables();
diskOffering.setId("disk_offering_id");
diskOffering.setName("disk_offering_name");
return diskOffering;
}
private void mockMethodValidateIfObjectIsNull() {
Mockito.doNothing().when(presetVariableHelperSpy).validateIfObjectIsNull(Mockito.any(), Mockito.anyLong(), Mockito.anyString());
}
@ -698,6 +707,7 @@ public class PresetVariableHelperTest {
Mockito.doReturn(expected.getName()).when(volumeVoMock).getName();
Mockito.doReturn(expected.getDiskOffering()).when(presetVariableHelperSpy).getPresetVariableValueDiskOffering(Mockito.anyLong());
Mockito.doReturn(expected.getProvisioningType()).when(volumeVoMock).getProvisioningType();
Mockito.doReturn(expected.getVolumeType()).when(volumeVoMock).getVolumeType();
Mockito.doReturn(expected.getStorage()).when(presetVariableHelperSpy).getPresetVariableValueStorage(Mockito.anyLong(), Mockito.anyInt());
Mockito.doReturn(expected.getTags()).when(presetVariableHelperSpy).getPresetVariableValueResourceTags(Mockito.anyLong(), Mockito.any(ResourceObjectType.class));
Mockito.doReturn(expected.getSize()).when(volumeVoMock).getSize();
@ -713,12 +723,13 @@ public class PresetVariableHelperTest {
assertPresetVariableIdAndName(expected, result);
Assert.assertEquals(expected.getDiskOffering(), result.getDiskOffering());
Assert.assertEquals(expected.getProvisioningType(), result.getProvisioningType());
Assert.assertEquals(expected.getVolumeType(), result.getVolumeType());
Assert.assertEquals(expected.getStorage(), result.getStorage());
Assert.assertEquals(expected.getTags(), result.getTags());
Assert.assertEquals(expectedSize, result.getSize());
Assert.assertEquals(imageFormat.name(), result.getVolumeFormat());
validateFieldNamesToIncludeInToString(Arrays.asList("id", "name", "diskOffering", "provisioningType", "storage", "tags", "size", "volumeFormat"), result);
validateFieldNamesToIncludeInToString(Arrays.asList("id", "name", "diskOffering", "provisioningType", "volumeType", "storage", "tags", "size", "volumeFormat"), result);
}
Mockito.verify(presetVariableHelperSpy, Mockito.times(ImageFormat.values().length)).getPresetVariableValueResourceTags(Mockito.anyLong(),
@ -740,6 +751,7 @@ public class PresetVariableHelperTest {
Mockito.doReturn(expected.getName()).when(volumeVoMock).getName();
Mockito.doReturn(expected.getDiskOffering()).when(presetVariableHelperSpy).getPresetVariableValueDiskOffering(Mockito.anyLong());
Mockito.doReturn(expected.getProvisioningType()).when(volumeVoMock).getProvisioningType();
Mockito.doReturn(expected.getVolumeType()).when(volumeVoMock).getVolumeType();
Mockito.doReturn(expected.getTags()).when(presetVariableHelperSpy).getPresetVariableValueResourceTags(Mockito.anyLong(), Mockito.any(ResourceObjectType.class));
Mockito.doReturn(expected.getSize()).when(volumeVoMock).getSize();
Mockito.doReturn(imageFormat).when(volumeVoMock).getFormat();
@ -754,12 +766,13 @@ public class PresetVariableHelperTest {
assertPresetVariableIdAndName(expected, result);
Assert.assertEquals(expected.getDiskOffering(), result.getDiskOffering());
Assert.assertEquals(expected.getProvisioningType(), result.getProvisioningType());
Assert.assertEquals(expected.getVolumeType(), result.getVolumeType());
Assert.assertNull(result.getStorage());
Assert.assertEquals(expected.getTags(), result.getTags());
Assert.assertEquals(expectedSize, result.getSize());
Assert.assertEquals(imageFormat.name(), result.getVolumeFormat());
validateFieldNamesToIncludeInToString(Arrays.asList("id", "name", "diskOffering", "provisioningType", "tags", "size", "volumeFormat"), result);
validateFieldNamesToIncludeInToString(Arrays.asList("id", "name", "diskOffering", "provisioningType", "volumeType", "tags", "size", "volumeFormat"), result);
}
Mockito.verify(presetVariableHelperSpy, Mockito.times(ImageFormat.values().length)).getPresetVariableValueResourceTags(Mockito.anyLong(),
@ -772,14 +785,15 @@ public class PresetVariableHelperTest {
Mockito.doReturn(diskOfferingVoMock).when(diskOfferingDaoMock).findByIdIncludingRemoved(Mockito.anyLong());
mockMethodValidateIfObjectIsNull();
GenericPresetVariable expected = getGenericPresetVariableForTests();
DiskOfferingPresetVariables expected = getDiskOfferingForTests();
Mockito.doReturn(expected.getId()).when(diskOfferingVoMock).getUuid();
Mockito.doReturn(expected.getName()).when(diskOfferingVoMock).getName();
GenericPresetVariable result = presetVariableHelperSpy.getPresetVariableValueDiskOffering(1l);
assertPresetVariableIdAndName(expected, result);
validateFieldNamesToIncludeInToString(Arrays.asList("id", "name"), result);
validateFieldNamesToIncludeInToString(Arrays.asList("bytesReadBurst", "bytesReadBurstLength", "bytesReadRate", "bytesWriteBurst", "bytesWriteBurstLength", "bytesWriteRate",
"id", "iopsReadBurst", "iopsReadBurstLength", "iopsReadRate", "iopsWriteBurst", "iopsWriteBurstLength", "iopsWriteRate", "name"), result);
}
@Test