mirror of
				https://github.com/apache/cloudstack.git
				synced 2025-10-26 08:42:29 +01:00 
			
		
		
		
	UI support for extraconfig in deploy and update instance (#11719)
This commit is contained in:
		
							parent
							
								
									30cb8c7a82
								
							
						
					
					
						commit
						70af55e848
					
				| @ -26,6 +26,7 @@ public class ApiConstants { | ||||
|     public static final String ACTIVATION_RULE = "activationrule"; | ||||
|     public static final String ACTIVITY = "activity"; | ||||
|     public static final String ADAPTER_TYPE = "adaptertype"; | ||||
|     public static final String ADDITONAL_CONFIG_ENABLED = "additionalconfigenabled"; | ||||
|     public static final String ADDRESS = "address"; | ||||
|     public static final String ALGORITHM = "algorithm"; | ||||
|     public static final String ALIAS = "alias"; | ||||
|  | ||||
| @ -73,6 +73,7 @@ public class ListCapabilitiesCmd extends BaseCmd { | ||||
|         response.setSharedFsVmMinCpuCount((Integer)capabilities.get(ApiConstants.SHAREDFSVM_MIN_CPU_COUNT)); | ||||
|         response.setSharedFsVmMinRamSize((Integer)capabilities.get(ApiConstants.SHAREDFSVM_MIN_RAM_SIZE)); | ||||
|         response.setDynamicScalingEnabled((Boolean) capabilities.get(ApiConstants.DYNAMIC_SCALING_ENABLED)); | ||||
|         response.setAdditionalConfigEnabled((Boolean) capabilities.get(ApiConstants.ADDITONAL_CONFIG_ENABLED)); | ||||
|         response.setObjectName("capability"); | ||||
|         response.setResponseName(getCommandName()); | ||||
|         this.setResponseObject(response); | ||||
|  | ||||
| @ -140,6 +140,10 @@ public class CapabilitiesResponse extends BaseResponse { | ||||
|     @Param(description = "true if dynamically scaling for instances is enabled", since = "4.21.0") | ||||
|     private Boolean dynamicScalingEnabled; | ||||
| 
 | ||||
|     @SerializedName(ApiConstants.ADDITONAL_CONFIG_ENABLED) | ||||
|     @Param(description = "true if additional configurations or extraconfig can be passed to Instances", since = "4.20.2") | ||||
|     private Boolean additionalConfigEnabled; | ||||
| 
 | ||||
|     public void setSecurityGroupsEnabled(boolean securityGroupsEnabled) { | ||||
|         this.securityGroupsEnabled = securityGroupsEnabled; | ||||
|     } | ||||
| @ -255,4 +259,8 @@ public class CapabilitiesResponse extends BaseResponse { | ||||
|     public void setDynamicScalingEnabled(Boolean dynamicScalingEnabled) { | ||||
|         this.dynamicScalingEnabled = dynamicScalingEnabled; | ||||
|     } | ||||
| 
 | ||||
|     public void setAdditionalConfigEnabled(Boolean additionalConfigEnabled) { | ||||
|         this.additionalConfigEnabled = additionalConfigEnabled; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -4535,6 +4535,8 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe | ||||
|         } | ||||
|         capabilities.put(ApiConstants.SHAREDFSVM_MIN_CPU_COUNT, fsVmMinCpu); | ||||
|         capabilities.put(ApiConstants.SHAREDFSVM_MIN_RAM_SIZE, fsVmMinRam); | ||||
|         capabilities.put(ApiConstants.ADDITONAL_CONFIG_ENABLED, UserVmManager.EnableAdditionalVmConfig.valueIn(caller.getId())); | ||||
| 
 | ||||
| 
 | ||||
|         return capabilities; | ||||
|     } | ||||
|  | ||||
| @ -83,6 +83,15 @@ public interface UserVmManager extends UserVmService { | ||||
|             "If set to true, tags specified in `resource.limit.host.tags` are also included in vm.strict.host.tags.", | ||||
|             true); | ||||
| 
 | ||||
|     ConfigKey<Boolean> EnableAdditionalVmConfig = new ConfigKey<>( | ||||
|             "Advanced", | ||||
|             Boolean.class, | ||||
|             "enable.additional.vm.configuration", | ||||
|             "false", | ||||
|             "allow additional arbitrary configuration to vm", | ||||
|             true, | ||||
|             ConfigKey.Scope.Account); | ||||
| 
 | ||||
|     static final int MAX_USER_DATA_LENGTH_BYTES = 2048; | ||||
| 
 | ||||
|     public  static  final String CKS_NODE = "cksnode"; | ||||
|  | ||||
| @ -670,9 +670,6 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir | ||||
|     private static final ConfigKey<Boolean> AllowDeployVmIfGivenHostFails = new ConfigKey<Boolean>("Advanced", Boolean.class, "allow.deploy.vm.if.deploy.on.given.host.fails", "false", | ||||
|             "allow vm to deploy on different host if vm fails to deploy on the given host ", true); | ||||
| 
 | ||||
|     private static final ConfigKey<Boolean> EnableAdditionalVmConfig = new ConfigKey<>("Advanced", Boolean.class, | ||||
|             "enable.additional.vm.configuration", "false", "allow additional arbitrary configuration to vm", true, ConfigKey.Scope.Account); | ||||
| 
 | ||||
|     private static final ConfigKey<String> KvmAdditionalConfigAllowList = new ConfigKey<>(String.class, | ||||
|     "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); | ||||
| 
 | ||||
| @ -6280,7 +6277,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir | ||||
|     protected void persistExtraConfigVmware(String decodedUrl, UserVm vm) { | ||||
|         boolean isValidConfig = isValidKeyValuePair(decodedUrl); | ||||
|         if (isValidConfig) { | ||||
|             String[] extraConfigs = decodedUrl.split("\\r?\\n"); | ||||
|             String[] extraConfigs = decodedUrl.split("\\r?\\n+"); | ||||
|             for (String cfg : extraConfigs) { | ||||
|                 // Validate cfg against unsupported operations set by admin here | ||||
|                 String[] allowedKeyList = VmwareAdditionalConfigAllowList.value().split(","); | ||||
| @ -6308,7 +6305,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir | ||||
|     protected void persistExtraConfigXenServer(String decodedUrl, UserVm vm) { | ||||
|         boolean isValidConfig = isValidKeyValuePair(decodedUrl); | ||||
|         if (isValidConfig) { | ||||
|             String[] extraConfigs = decodedUrl.split("\\r?\\n"); | ||||
|             String[] extraConfigs = decodedUrl.split("\\r?\\n+"); | ||||
|             int i = 1; | ||||
|             String extraConfigKey = ApiConstants.EXTRA_CONFIG + "-"; | ||||
|             for (String cfg : extraConfigs) { | ||||
| @ -6388,8 +6385,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir | ||||
|         // validate config against denied cfg commands | ||||
|         validateKvmExtraConfig(decodedUrl, vm.getAccountId()); | ||||
|         String[] extraConfigs = decodedUrl.split("\n\n"); | ||||
|         int i = 1; | ||||
|         for (String cfg : extraConfigs) { | ||||
|             int i = 1; | ||||
|             String[] cfgParts = cfg.split("\n"); | ||||
|             String extraConfigKey = ApiConstants.EXTRA_CONFIG; | ||||
|             String extraConfigValue; | ||||
|  | ||||
| @ -975,6 +975,8 @@ | ||||
| "label.externalid": "External Id", | ||||
| "label.externalloadbalanceripaddress": "External load balancer IP address.", | ||||
| "label.extra": "Extra arguments", | ||||
| "label.extraconfig": "Additional Configuration", | ||||
| "label.extraconfig.tooltip": "Additional configuration parameters (extraconfig) to pass to the instance in plain text", | ||||
| "label.f5": "F5", | ||||
| "label.f5.ip.loadbalancer": "F5 BIG-IP load balancer.", | ||||
| "label.failed": "Failed", | ||||
|  | ||||
| @ -724,6 +724,12 @@ | ||||
|                         </div> | ||||
|                       </a-card> | ||||
|                     </a-form-item> | ||||
|                     <a-form-item v-if="extraConfigEnabled" name="extraconfig" ref="extraconfig"> | ||||
|                       <template #label> | ||||
|                         <tooltip-label :title="$t('label.extraconfig')" :tooltip="$t('label.extraconfig.tooltip')"/> | ||||
|                       </template> | ||||
|                       <a-textarea v-model:value="form.extraconfig"/> | ||||
|                     </a-form-item> | ||||
|                     <a-form-item :label="$t('label.affinity.groups')"> | ||||
|                       <affinity-group-selection | ||||
|                         :items="options.affinityGroups" | ||||
| @ -1418,6 +1424,9 @@ export default { | ||||
|     dynamicScalingVmConfigValue () { | ||||
|       return this.$store.getters.features.dynamicscalingenabled | ||||
|     }, | ||||
|     extraConfigEnabled () { | ||||
|       return this.$store.getters.features.additionalconfigenabled | ||||
|     }, | ||||
|     isCustomizedDiskIOPS () { | ||||
|       return this.diskSelected?.iscustomizediops || false | ||||
|     }, | ||||
| @ -2054,6 +2063,9 @@ export default { | ||||
|         if (isUserdataAllowed && values.userdata && values.userdata.length > 0) { | ||||
|           deployVmData.userdata = this.$toBase64AndURIEncoded(values.userdata) | ||||
|         } | ||||
|         if (values.extraconfig && values.extraconfig.length > 0) { | ||||
|           deployVmData.extraconfig = encodeURIComponent(values.extraconfig) | ||||
|         } | ||||
|         // step 2: select template/iso | ||||
|         if (this.tabKey === 'templateid') { | ||||
|           deployVmData.templateid = values.templateid | ||||
|  | ||||
| @ -91,6 +91,12 @@ | ||||
|         <a-textarea v-model:value="form.userdata"> | ||||
|         </a-textarea> | ||||
|       </a-form-item> | ||||
|       <a-form-item v-if="extraConfigEnabled"> | ||||
|         <template #label> | ||||
|           <tooltip-label :title="$t('label.extraconfig')" :tooltip="$t('label.extraconfig.tooltip')"/> | ||||
|         </template> | ||||
|         <a-textarea v-model:value="form.extraconfig"/> | ||||
|       </a-form-item> | ||||
|       <a-form-item ref="securitygroupids" name="securitygroupids" :label="$t('label.security.groups')" v-if="securityGroupsEnabled"> | ||||
|         <a-select | ||||
|           mode="multiple" | ||||
| @ -167,6 +173,19 @@ export default { | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   computed: { | ||||
|     extraConfigEnabled () { | ||||
|       return this.$store.getters.features.additionalconfigenabled | ||||
|     }, | ||||
|     combinedExtraConfig () { | ||||
|       if (!this.extraConfigEnabled || !this.resource.details) return '' | ||||
|       const configs = Object.keys(this.resource.details) | ||||
|         .filter(key => key.startsWith('extraconfig-')) | ||||
|         .map(key => this.resource.details[key] || '') | ||||
|         .filter(val => val.trim()) | ||||
|       return configs.join('\n\n') | ||||
|     } | ||||
|   }, | ||||
|   beforeCreate () { | ||||
|     this.apiParams = this.$getApiParams('updateVirtualMachine') | ||||
|   }, | ||||
| @ -185,7 +204,8 @@ export default { | ||||
|         deleteprotection: this.resource.deleteprotection, | ||||
|         group: this.resource.group, | ||||
|         userdata: '', | ||||
|         haenable: this.resource.haenable | ||||
|         haenable: this.resource.haenable, | ||||
|         extraconfig: this.combinedExtraConfig | ||||
|       }) | ||||
|       this.rules = reactive({}) | ||||
|     }, | ||||
| @ -342,6 +362,9 @@ export default { | ||||
|         if (values.userdata && values.userdata.length > 0) { | ||||
|           params.userdata = this.$toBase64AndURIEncoded(values.userdata) | ||||
|         } | ||||
|         if (values.extraconfig && values.extraconfig.length > 0) { | ||||
|           params.extraconfig = encodeURIComponent(values.extraconfig) | ||||
|         } | ||||
|         this.loading = true | ||||
| 
 | ||||
|         api('updateVirtualMachine', {}, 'POST', params).then(json => { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user