Skip to content

Commit c7b0005

Browse files
abh1sarLocharla, Sandeep
authored andcommitted
UI support for extraconfig in deploy and update instance (apache#11719)
1 parent 9bcd988 commit c7b0005

File tree

7 files changed

+36
-6
lines changed

7 files changed

+36
-6
lines changed

api/src/main/java/org/apache/cloudstack/api/ApiConstants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ public class ApiConstants {
2727
public static final String ACTIVATION_RULE = "activationrule";
2828
public static final String ACTIVITY = "activity";
2929
public static final String ADAPTER_TYPE = "adaptertype";
30+
public static final String ADDITONAL_CONFIG_ENABLED = "additionalconfigenabled";
3031
public static final String ADDRESS = "address";
3132
public static final String ALGORITHM = "algorithm";
3233
public static final String ALIAS = "alias";

api/src/main/java/org/apache/cloudstack/api/command/user/config/ListCapabilitiesCmd.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ public void execute() {
7575
response.setInstanceLeaseEnabled((Boolean) capabilities.get(ApiConstants.INSTANCE_LEASE_ENABLED));
7676
response.setExtensionsPath((String)capabilities.get(ApiConstants.EXTENSIONS_PATH));
7777
response.setDynamicScalingEnabled((Boolean) capabilities.get(ApiConstants.DYNAMIC_SCALING_ENABLED));
78+
response.setAdditionalConfigEnabled((Boolean) capabilities.get(ApiConstants.ADDITONAL_CONFIG_ENABLED));
7879
response.setObjectName("capability");
7980
response.setResponseName(getCommandName());
8081
this.setResponseObject(response);

api/src/main/java/org/apache/cloudstack/api/response/CapabilitiesResponse.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,10 @@ public class CapabilitiesResponse extends BaseResponse {
149149
@Param(description = "true if dynamically scaling for instances is enabled", since = "4.21.0")
150150
private Boolean dynamicScalingEnabled;
151151

152+
@SerializedName(ApiConstants.ADDITONAL_CONFIG_ENABLED)
153+
@Param(description = "true if additional configurations or extraconfig can be passed to Instances", since = "4.20.2")
154+
private Boolean additionalConfigEnabled;
155+
152156
public void setSecurityGroupsEnabled(boolean securityGroupsEnabled) {
153157
this.securityGroupsEnabled = securityGroupsEnabled;
154158
}
@@ -272,4 +276,8 @@ public void setExtensionsPath(String extensionsPath) {
272276
public void setDynamicScalingEnabled(Boolean dynamicScalingEnabled) {
273277
this.dynamicScalingEnabled = dynamicScalingEnabled;
274278
}
279+
280+
public void setAdditionalConfigEnabled(Boolean additionalConfigEnabled) {
281+
this.additionalConfigEnabled = additionalConfigEnabled;
282+
}
275283
}

server/src/main/java/com/cloud/vm/UserVmManager.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,15 @@ public interface UserVmManager extends UserVmService {
8383
"If set to true, tags specified in `resource.limit.host.tags` are also included in vm.strict.host.tags.",
8484
true);
8585

86+
ConfigKey<Boolean> EnableAdditionalVmConfig = new ConfigKey<>(
87+
"Advanced",
88+
Boolean.class,
89+
"enable.additional.vm.configuration",
90+
"false",
91+
"allow additional arbitrary configuration to vm",
92+
true,
93+
ConfigKey.Scope.Account);
94+
8695
static final int MAX_USER_DATA_LENGTH_BYTES = 2048;
8796

8897
public static final String CKS_NODE = "cksnode";

server/src/main/java/com/cloud/vm/UserVmManagerImpl.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -689,9 +689,6 @@ public void setKubernetesServiceHelpers(final List<KubernetesServiceHelper> kube
689689
private static final ConfigKey<Boolean> AllowDeployVmIfGivenHostFails = new ConfigKey<Boolean>("Advanced", Boolean.class, "allow.deploy.vm.if.deploy.on.given.host.fails", "false",
690690
"allow vm to deploy on different host if vm fails to deploy on the given host ", true);
691691

692-
private static final ConfigKey<Boolean> EnableAdditionalVmConfig = new ConfigKey<>("Advanced", Boolean.class,
693-
"enable.additional.vm.configuration", "false", "allow additional arbitrary configuration to vm", true, ConfigKey.Scope.Account);
694-
695692
private static final ConfigKey<String> KvmAdditionalConfigAllowList = new ConfigKey<>(String.class,
696693
"allow.additional.vm.configuration.list.kvm", "Advanced", "", "Comma separated list of allowed additional configuration options.", true, ConfigKey.Scope.Account, null, null, EnableAdditionalVmConfig.key(), null, null, ConfigKey.Kind.CSV, null);
697694

@@ -6604,7 +6601,7 @@ private void checkIfVolumeTemplateIsTheSameAsTheProvided(VolumeInfo volume, Long
66046601
protected void persistExtraConfigVmware(String decodedUrl, UserVm vm) {
66056602
boolean isValidConfig = isValidKeyValuePair(decodedUrl);
66066603
if (isValidConfig) {
6607-
String[] extraConfigs = decodedUrl.split("\\r?\\n");
6604+
String[] extraConfigs = decodedUrl.split("\\r?\\n+");
66086605
for (String cfg : extraConfigs) {
66096606
// Validate cfg against unsupported operations set by admin here
66106607
String[] allowedKeyList = VmwareAdditionalConfigAllowList.value().split(",");
@@ -6632,7 +6629,7 @@ protected void persistExtraConfigVmware(String decodedUrl, UserVm vm) {
66326629
protected void persistExtraConfigXenServer(String decodedUrl, UserVm vm) {
66336630
boolean isValidConfig = isValidKeyValuePair(decodedUrl);
66346631
if (isValidConfig) {
6635-
String[] extraConfigs = decodedUrl.split("\\r?\\n");
6632+
String[] extraConfigs = decodedUrl.split("\\r?\\n+");
66366633
int i = 1;
66376634
String extraConfigKey = ApiConstants.EXTRA_CONFIG + "-";
66386635
for (String cfg : extraConfigs) {
@@ -6712,8 +6709,8 @@ protected void persistExtraConfigKvm(String decodedUrl, UserVm vm) {
67126709
// validate config against denied cfg commands
67136710
validateKvmExtraConfig(decodedUrl, vm.getAccountId());
67146711
String[] extraConfigs = decodedUrl.split("\n\n");
6712+
int i = 1;
67156713
for (String cfg : extraConfigs) {
6716-
int i = 1;
67176714
String[] cfgParts = cfg.split("\n");
67186715
String extraConfigKey = ApiConstants.EXTRA_CONFIG;
67196716
String extraConfigValue;

ui/public/locales/en.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,6 +1051,8 @@
10511051
"label.externalid": "External Id",
10521052
"label.externalloadbalanceripaddress": "External load balancer IP address.",
10531053
"label.extra": "Extra arguments",
1054+
"label.extraconfig": "Additional Configuration",
1055+
"label.extraconfig.tooltip": "Additional configuration parameters (extraconfig) to pass to the instance in plain text",
10541056
"label.f5": "F5",
10551057
"label.f5.ip.loadbalancer": "F5 BIG-IP load balancer.",
10561058
"label.failed": "Failed",

ui/src/views/compute/DeployVM.vue

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -762,6 +762,12 @@
762762
</div>
763763
</a-card>
764764
</a-form-item>
765+
<a-form-item v-if="extraConfigEnabled" name="extraconfig" ref="extraconfig">
766+
<template #label>
767+
<tooltip-label :title="$t('label.extraconfig')" :tooltip="$t('label.extraconfig.tooltip')"/>
768+
</template>
769+
<a-textarea v-model:value="form.extraconfig"/>
770+
</a-form-item>
765771
<a-form-item :label="$t('label.affinity.groups')">
766772
<affinity-group-selection
767773
:items="options.affinityGroups"
@@ -1510,6 +1516,9 @@ export default {
15101516
dynamicScalingVmConfigValue () {
15111517
return this.$store.getters.features.dynamicscalingenabled
15121518
},
1519+
extraConfigEnabled () {
1520+
return this.$store.getters.features.additionalconfigenabled
1521+
},
15131522
isCustomizedDiskIOPS () {
15141523
return this.diskSelected?.iscustomizediops || false
15151524
},
@@ -2323,6 +2332,9 @@ export default {
23232332
if (isUserdataAllowed && values.userdata && values.userdata.length > 0) {
23242333
deployVmData.userdata = this.$toBase64AndURIEncoded(values.userdata)
23252334
}
2335+
if (values.extraconfig && values.extraconfig.length > 0) {
2336+
deployVmData.extraconfig = encodeURIComponent(values.extraconfig)
2337+
}
23262338
// step 2: select template/iso
23272339
if (this.imageType === 'templateid') {
23282340
deployVmData.templateid = values.templateid

0 commit comments

Comments
 (0)