Skip to content

Commit 617fee8

Browse files
lucas-a-martinsLucas Martinswinterhazel
authored
Add offerHa and forceHa preset variables to RUNNING_VM usage type (#9500)
* Add offerHA and forceHa presets to Running VM * apply winterhazel's suggestion Co-authored-by: Fabricio Duarte <fabricio.duarte.jr@gmail.com> * Add ObjectUtils import --------- Co-authored-by: Lucas Martins <lucas.martins@scclouds.com.br> Co-authored-by: Fabricio Duarte <fabricio.duarte.jr@gmail.com>
1 parent a093f00 commit 617fee8

File tree

7 files changed

+180
-5
lines changed

7 files changed

+180
-5
lines changed

framework/quota/src/main/java/org/apache/cloudstack/quota/QuotaManagerImpl.java

+6
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434

3535
import com.cloud.user.Account;
3636
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
37+
import org.apache.cloudstack.quota.activationrule.presetvariables.Configuration;
3738
import org.apache.cloudstack.quota.activationrule.presetvariables.GenericPresetVariable;
3839
import org.apache.cloudstack.quota.activationrule.presetvariables.PresetVariableHelper;
3940
import org.apache.cloudstack.quota.activationrule.presetvariables.PresetVariables;
@@ -467,6 +468,11 @@ protected void injectPresetVariablesIntoJsInterpreter(JsInterpreter jsInterprete
467468

468469
}
469470

471+
Configuration configuration = presetVariables.getConfiguration();
472+
if (configuration != null) {
473+
jsInterpreter.injectVariable("configuration", configuration.toString());
474+
}
475+
470476
jsInterpreter.injectStringVariable("resourceType", presetVariables.getResourceType());
471477
jsInterpreter.injectVariable("value", presetVariables.getValue().toString());
472478
jsInterpreter.injectVariable("zone", presetVariables.getZone().toString());

framework/quota/src/main/java/org/apache/cloudstack/quota/activationrule/presetvariables/ComputeOffering.java

+14
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,15 @@
1717

1818
package org.apache.cloudstack.quota.activationrule.presetvariables;
1919

20+
import org.apache.cloudstack.quota.constant.QuotaTypes;
21+
2022
public class ComputeOffering extends GenericPresetVariable {
2123
@PresetVariableDefinition(description = "A boolean informing if the compute offering is customized or not.")
2224
private boolean customized;
2325

26+
@PresetVariableDefinition(description = "A boolean informing if the compute offering offers HA or not.", supportedTypes = {QuotaTypes.RUNNING_VM})
27+
private boolean offerHa;
28+
2429
public boolean isCustomized() {
2530
return customized;
2631
}
@@ -30,4 +35,13 @@ public void setCustomized(boolean customized) {
3035
fieldNamesToIncludeInToString.add("customized");
3136
}
3237

38+
public boolean offerHa() {
39+
return offerHa;
40+
}
41+
42+
public void setOfferHa(boolean offerHa) {
43+
this.offerHa = offerHa;
44+
fieldNamesToIncludeInToString.add("offerHa");
45+
}
46+
3347
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
package org.apache.cloudstack.quota.activationrule.presetvariables;
19+
20+
import org.apache.cloudstack.quota.constant.QuotaTypes;
21+
22+
public class Configuration extends GenericPresetVariable{
23+
24+
@PresetVariableDefinition(description = "A boolean informing if the cluster configuration force.ha is enabled or not.", supportedTypes = {QuotaTypes.RUNNING_VM})
25+
private boolean forceHa;
26+
27+
public boolean getForceHa() {
28+
return forceHa;
29+
}
30+
31+
public void setForceHa(boolean forceHa) {
32+
this.forceHa = forceHa;
33+
fieldNamesToIncludeInToString.add("forceHa");
34+
}
35+
}

framework/quota/src/main/java/org/apache/cloudstack/quota/activationrule/presetvariables/PresetVariableHelper.java

+49-2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
import java.util.Map;
2626
import java.util.stream.Collectors;
2727

28+
import com.cloud.dc.ClusterDetailsDao;
29+
import com.cloud.dc.ClusterDetailsVO;
2830
import com.cloud.host.HostTagVO;
2931
import com.cloud.network.dao.NetworkVO;
3032
import com.cloud.network.vpc.VpcVO;
@@ -37,6 +39,7 @@
3739
import org.apache.cloudstack.backup.BackupOfferingVO;
3840
import org.apache.cloudstack.backup.dao.BackupOfferingDao;
3941
import org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo;
42+
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
4043
import org.apache.cloudstack.quota.constant.QuotaTypes;
4144
import org.apache.cloudstack.quota.dao.NetworkDao;
4245
import org.apache.cloudstack.quota.dao.VmTemplateDao;
@@ -51,6 +54,7 @@
5154
import org.apache.cloudstack.utils.bytescale.ByteScaleUtils;
5255
import org.apache.cloudstack.utils.jsinterpreter.JsInterpreter;
5356
import org.apache.commons.collections.CollectionUtils;
57+
import org.apache.commons.lang3.ObjectUtils;
5458
import org.apache.logging.log4j.Logger;
5559
import org.apache.logging.log4j.LogManager;
5660
import org.springframework.stereotype.Component;
@@ -181,6 +185,11 @@ public class PresetVariableHelper {
181185
@Inject
182186
VpcDao vpcDao;
183187

188+
@Inject
189+
ConfigurationDao configDao;
190+
191+
@Inject
192+
ClusterDetailsDao clusterDetailsDao;
184193

185194
protected boolean backupSnapshotAfterTakingSnapshot = SnapshotInfo.BackupSnapshotAfterTakingSnapshot.value();
186195

@@ -194,6 +203,7 @@ public PresetVariables getPresetVariables(UsageVO usageRecord) {
194203

195204
presetVariables.setAccount(getPresetVariableAccount(usageRecord.getAccountId()));
196205
setPresetVariableProject(presetVariables);
206+
setPresetVariableConfiguration(presetVariables, usageRecord);
197207

198208
presetVariables.setDomain(getPresetVariableDomain(usageRecord.getDomainId()));
199209
presetVariables.setResourceType(usageRecord.getType());
@@ -272,6 +282,39 @@ protected GenericPresetVariable getPresetVariableZone(Long zoneId) {
272282
return zone;
273283
}
274284

285+
protected void setPresetVariableConfiguration(PresetVariables presetVariables, UsageVO usageRecord) {
286+
if (usageRecord.getUsageType() != UsageTypes.RUNNING_VM) {
287+
return;
288+
}
289+
290+
Configuration configuration = new Configuration();
291+
setForceHaInConfiguration(configuration, usageRecord);
292+
293+
presetVariables.setConfiguration(configuration);
294+
}
295+
296+
protected void setForceHaInConfiguration(Configuration configuration, UsageVO usageRecord) {
297+
Long vmId = usageRecord.getUsageId();
298+
VMInstanceVO vmVo = vmInstanceDao.findByIdIncludingRemoved(vmId);
299+
validateIfObjectIsNull(vmVo, vmId, "VM");
300+
301+
Long hostId = ObjectUtils.defaultIfNull(vmVo.getHostId(), vmVo.getLastHostId());
302+
303+
HostVO hostVo = hostDao.findByIdIncludingRemoved(hostId);
304+
validateIfObjectIsNull(hostVo, hostId, "host");
305+
ClusterDetailsVO forceHa = clusterDetailsDao.findDetail(hostVo.getClusterId(), "force.ha");
306+
307+
String forceHaValue;
308+
309+
if (forceHa != null) {
310+
forceHaValue = forceHa.getValue();
311+
} else {
312+
forceHaValue = configDao.getValue("force.ha");
313+
}
314+
315+
configuration.setForceHa((Boolean.parseBoolean(forceHaValue)));
316+
}
317+
275318
protected Value getPresetVariableValue(UsageVO usageRecord) {
276319
Long accountId = usageRecord.getAccountId();
277320
int usageType = usageRecord.getUsageType();
@@ -390,12 +433,16 @@ protected String getPresetVariableValueOsName(Long guestOsId) {
390433
return guestOsVo.getDisplayName();
391434
}
392435

393-
protected ComputeOffering getPresetVariableValueComputeOffering(ServiceOfferingVO serviceOfferingVo) {
436+
protected ComputeOffering getPresetVariableValueComputeOffering(ServiceOfferingVO serviceOfferingVo, int usageType) {
394437
ComputeOffering computeOffering = new ComputeOffering();
395438
computeOffering.setId(serviceOfferingVo.getUuid());
396439
computeOffering.setName(serviceOfferingVo.getName());
397440
computeOffering.setCustomized(serviceOfferingVo.isDynamic());
398441

442+
if (usageType == UsageTypes.RUNNING_VM) {
443+
computeOffering.setOfferHa(serviceOfferingVo.isOfferHA());
444+
}
445+
399446
return computeOffering;
400447
}
401448

@@ -404,7 +451,7 @@ protected void setPresetVariableValueServiceOfferingAndComputingResources(Value
404451
long computeOfferingId = vmVo.getServiceOfferingId();
405452
ServiceOfferingVO serviceOfferingVo = serviceOfferingDao.findByIdIncludingRemoved(computeOfferingId);
406453
validateIfObjectIsNull(serviceOfferingVo, computeOfferingId, "compute offering");
407-
value.setComputeOffering(getPresetVariableValueComputeOffering(serviceOfferingVo));
454+
value.setComputeOffering(getPresetVariableValueComputeOffering(serviceOfferingVo, usageType));
408455

409456
if (usageType == UsageTypes.RUNNING_VM) {
410457
value.setComputingResources(getPresetVariableValueComputingResource(vmVo, serviceOfferingVo));

framework/quota/src/main/java/org/apache/cloudstack/quota/activationrule/presetvariables/PresetVariables.java

+11
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ public class PresetVariables {
3939
@PresetVariableDefinition(description = "Zone where the resource is.")
4040
private GenericPresetVariable zone;
4141

42+
@PresetVariableDefinition(description = "Configurations of the resource.")
43+
private Configuration configuration;
44+
4245
@PresetVariableDefinition(description = "A list containing the tariffs ordered by the field 'position'.")
4346
private List<Tariff> lastTariffs;
4447

@@ -90,6 +93,14 @@ public void setZone(GenericPresetVariable zone) {
9093
this.zone = zone;
9194
}
9295

96+
public Configuration getConfiguration() {
97+
return configuration;
98+
}
99+
100+
public void setConfiguration(Configuration configuration) {
101+
this.configuration = configuration;
102+
}
103+
93104
public List<Tariff> getLastTariffs() {
94105
return lastTariffs;
95106
}

framework/quota/src/test/java/org/apache/cloudstack/quota/QuotaManagerImplTest.java

+1
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ public void injectPresetVariablesIntoJsInterpreterTestProjectIsNullDoNotInjectPr
270270
Mockito.verify(jsInterpreterMock).injectVariable(Mockito.eq("account"), Mockito.anyString());
271271
Mockito.verify(jsInterpreterMock).injectVariable(Mockito.eq("domain"), Mockito.anyString());
272272
Mockito.verify(jsInterpreterMock, Mockito.never()).injectVariable(Mockito.eq("project"), Mockito.anyString());
273+
Mockito.verify(jsInterpreterMock, Mockito.never()).injectVariable(Mockito.eq("configuration"), Mockito.anyString());
273274
Mockito.verify(jsInterpreterMock).injectStringVariable(Mockito.eq("resourceType"), Mockito.anyString());
274275
Mockito.verify(jsInterpreterMock).injectVariable(Mockito.eq("value"), Mockito.anyString());
275276
Mockito.verify(jsInterpreterMock).injectVariable(Mockito.eq("zone"), Mockito.anyString());

framework/quota/src/test/java/org/apache/cloudstack/quota/activationrule/presetvariables/PresetVariableHelperTest.java

+64-3
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
import java.util.Map;
2828
import java.util.Set;
2929

30+
import com.cloud.dc.ClusterDetailsDao;
31+
import com.cloud.dc.ClusterDetailsVO;
3032
import com.cloud.host.HostTagVO;
3133
import com.cloud.hypervisor.Hypervisor;
3234
import com.cloud.storage.StoragePoolTagVO;
@@ -123,6 +125,9 @@ public class PresetVariableHelperTest {
123125
@Mock
124126
HostTagsDao hostTagsDaoMock;
125127

128+
@Mock
129+
ClusterDetailsDao clusterDetailsDaoMock;
130+
126131
@Mock
127132
ImageStoreDao imageStoreDaoMock;
128133

@@ -234,6 +239,7 @@ private ComputeOffering getComputeOfferingForTests() {
234239
computeOffering.setId("compute_offering_id");
235240
computeOffering.setName("compute_offering_name");
236241
computeOffering.setCustomized(false);
242+
computeOffering.setOfferHa(false);
237243
return computeOffering;
238244
}
239245

@@ -245,6 +251,14 @@ private Host getHostForTests() {
245251
return host;
246252
}
247253

254+
private Configuration getConfigurationForTests() {
255+
Configuration configuration = new Configuration();
256+
configuration.setId("config_id");
257+
configuration.setName("config_name");
258+
configuration.setForceHa(false);
259+
return configuration;
260+
}
261+
248262
private List<HostTagVO> getHostTagsForTests() {
249263
return Arrays.asList(new HostTagVO(1, "tag1", false), new HostTagVO(1, "tag2", false));
250264
}
@@ -338,6 +352,7 @@ public void getPresetVariablesTestSetFieldsAndReturnObject() {
338352

339353
Mockito.doReturn(expected.getAccount()).when(presetVariableHelperSpy).getPresetVariableAccount(Mockito.anyLong());
340354
Mockito.doNothing().when(presetVariableHelperSpy).setPresetVariableProject(Mockito.any());
355+
Mockito.doNothing().when(presetVariableHelperSpy).setPresetVariableConfiguration(Mockito.any(), Mockito.any());
341356
Mockito.doReturn(expected.getDomain()).when(presetVariableHelperSpy).getPresetVariableDomain(Mockito.anyLong());
342357
Mockito.doReturn(expected.getValue()).when(presetVariableHelperSpy).getPresetVariableValue(Mockito.any(UsageVO.class));
343358
Mockito.doReturn(expected.getZone()).when(presetVariableHelperSpy).getPresetVariableZone(Mockito.anyLong());
@@ -361,6 +376,35 @@ public void setPresetVariableProjectTestAccountWithRoleDoNotSetAsProject() {
361376
Assert.assertNull(result.getProject());
362377
}
363378

379+
@Test
380+
public void setPresetVariableConfigurationTestQuotaTypeDifferentFromRunningVmDoNothing() {
381+
getQuotaTypesForTests(UsageTypes.RUNNING_VM).forEach(type -> {
382+
PresetVariables result = new PresetVariables();
383+
Mockito.doReturn(type.getKey()).when(usageVoMock).getUsageType();
384+
presetVariableHelperSpy.setPresetVariableConfiguration(result, usageVoMock);
385+
386+
Assert.assertNull(result.getConfiguration());
387+
});
388+
}
389+
390+
@Test
391+
public void setPresetVariableConfigurationTestQuotaTypeIsRunningVmSetConfiguration() {
392+
PresetVariables result = new PresetVariables();
393+
Configuration expectedConfig = getConfigurationForTests();
394+
HostVO hostVoMock = Mockito.mock(HostVO.class);
395+
ClusterDetailsVO clusterDetailsVoMock = Mockito.mock(ClusterDetailsVO.class);
396+
397+
Mockito.doReturn(vmInstanceVoMock).when(vmInstanceDaoMock).findByIdIncludingRemoved(Mockito.anyLong());
398+
Mockito.doReturn(hostVoMock).when(hostDaoMock).findByIdIncludingRemoved(Mockito.anyLong());
399+
Mockito.doReturn(1L).when(vmInstanceVoMock).getHostId();
400+
Mockito.doReturn(1).when(usageVoMock).getUsageType();
401+
Mockito.doReturn(clusterDetailsVoMock).when(clusterDetailsDaoMock).findDetail(Mockito.anyLong(), Mockito.anyString());
402+
presetVariableHelperSpy.setPresetVariableConfiguration(result, usageVoMock);
403+
404+
Assert.assertNotNull(result.getConfiguration());
405+
Assert.assertEquals(expectedConfig.getForceHa(), result.getConfiguration().getForceHa());
406+
}
407+
364408
@Test
365409
public void setPresetVariableProjectTestAccountWithoutRoleSetAsProject() {
366410
PresetVariables result = new PresetVariables();
@@ -636,19 +680,36 @@ public void getPresetVariableValueOsNameTestReturnDisplayName() {
636680
}
637681

638682
@Test
639-
public void getPresetVariableValueComputeOfferingTestSetFieldsAndReturnObject() {
683+
public void getPresetVariableValueComputeOfferingForTestSetFieldsAndReturnObjectForRunningVm() {
640684
ComputeOffering expected = getComputeOfferingForTests();
641685
Mockito.doReturn(expected.getId()).when(serviceOfferingVoMock).getUuid();
642686
Mockito.doReturn(expected.getName()).when(serviceOfferingVoMock).getName();
643687
Mockito.doReturn(expected.isCustomized()).when(serviceOfferingVoMock).isDynamic();
688+
Mockito.doReturn(expected.offerHa()).when(serviceOfferingVoMock).isOfferHA();
644689

645-
ComputeOffering result = presetVariableHelperSpy.getPresetVariableValueComputeOffering(serviceOfferingVoMock);
690+
ComputeOffering result = presetVariableHelperSpy.getPresetVariableValueComputeOffering(serviceOfferingVoMock, UsageTypes.RUNNING_VM);
691+
692+
assertPresetVariableIdAndName(expected, result);
693+
Assert.assertEquals(expected.isCustomized(), result.isCustomized());
694+
Assert.assertEquals(expected.offerHa(), result.offerHa());
695+
validateFieldNamesToIncludeInToString(Arrays.asList("id", "name", "customized", "offerHa"), result);
696+
}
697+
698+
@Test
699+
public void getPresetVariableValueComputeOfferingForTestSetFieldsAndReturnObjectForAllocatedVm() {
700+
ComputeOffering expected = getComputeOfferingForTests();
701+
Mockito.doReturn(expected.getId()).when(serviceOfferingVoMock).getUuid();
702+
Mockito.doReturn(expected.getName()).when(serviceOfferingVoMock).getName();
703+
Mockito.doReturn(expected.isCustomized()).when(serviceOfferingVoMock).isDynamic();
704+
705+
ComputeOffering result = presetVariableHelperSpy.getPresetVariableValueComputeOffering(serviceOfferingVoMock, UsageTypes.ALLOCATED_VM);
646706

647707
assertPresetVariableIdAndName(expected, result);
648708
Assert.assertEquals(expected.isCustomized(), result.isCustomized());
649709
validateFieldNamesToIncludeInToString(Arrays.asList("id", "name", "customized"), result);
650710
}
651711

712+
652713
@Test
653714
public void getPresetVariableValueTemplateTestSetValuesAndReturnObject() {
654715
VMTemplateVO vmTemplateVoMock = Mockito.mock(VMTemplateVO.class);
@@ -1127,7 +1188,7 @@ public void setPresetVariableValueServiceOfferingAndComputingResourcesTestSetCom
11271188
Mockito.doReturn(serviceOfferingVoMock).when(serviceOfferingDaoMock).findByIdIncludingRemoved(Mockito.anyLong());
11281189
mockMethodValidateIfObjectIsNull();
11291190

1130-
Mockito.doReturn(expected.getComputeOffering()).when(presetVariableHelperSpy).getPresetVariableValueComputeOffering(Mockito.any());
1191+
Mockito.doReturn(expected.getComputeOffering()).when(presetVariableHelperSpy).getPresetVariableValueComputeOffering(Mockito.any(), Mockito.anyInt());
11311192
Mockito.doReturn(expected.getComputingResources()).when(presetVariableHelperSpy).getPresetVariableValueComputingResource(Mockito.any(), Mockito.any());
11321193

11331194
QuotaTypes.listQuotaTypes().forEach((typeInt, value) -> {

0 commit comments

Comments
 (0)