mirror of
				https://github.com/apache/cloudstack.git
				synced 2025-10-26 08:42:29 +01:00 
			
		
		
		
	AutoScaling: support Managed User Data (#7769)
This commit is contained in:
		
							parent
							
								
									405ef82aef
								
							
						
					
					
						commit
						78bdde9e98
					
				| @ -35,6 +35,10 @@ public interface AutoScaleVmProfile extends ControlledEntity, InternalIdentity, | |||||||
| 
 | 
 | ||||||
|     String getUserData(); |     String getUserData(); | ||||||
| 
 | 
 | ||||||
|  |     Long getUserDataId(); | ||||||
|  | 
 | ||||||
|  |     String getUserDataDetails(); | ||||||
|  | 
 | ||||||
|     public String getUuid(); |     public String getUuid(); | ||||||
| 
 | 
 | ||||||
|     public Long getZoneId(); |     public Long getZoneId(); | ||||||
|  | |||||||
| @ -21,8 +21,10 @@ import java.lang.reflect.Field; | |||||||
| import java.text.DateFormat; | import java.text.DateFormat; | ||||||
| import java.text.SimpleDateFormat; | import java.text.SimpleDateFormat; | ||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
|  | import java.util.Collection; | ||||||
| import java.util.Date; | import java.util.Date; | ||||||
| import java.util.HashMap; | import java.util.HashMap; | ||||||
|  | import java.util.Iterator; | ||||||
| import java.util.List; | import java.util.List; | ||||||
| import java.util.Map; | import java.util.Map; | ||||||
| import java.util.regex.Pattern; | import java.util.regex.Pattern; | ||||||
| @ -42,6 +44,7 @@ import org.apache.cloudstack.network.lb.InternalLoadBalancerVMService; | |||||||
| import org.apache.cloudstack.query.QueryService; | import org.apache.cloudstack.query.QueryService; | ||||||
| import org.apache.cloudstack.storage.ImageStoreService; | import org.apache.cloudstack.storage.ImageStoreService; | ||||||
| import org.apache.cloudstack.usage.UsageService; | import org.apache.cloudstack.usage.UsageService; | ||||||
|  | import org.apache.commons.collections.MapUtils; | ||||||
| import org.apache.log4j.Logger; | import org.apache.log4j.Logger; | ||||||
| 
 | 
 | ||||||
| import com.cloud.configuration.ConfigurationService; | import com.cloud.configuration.ConfigurationService; | ||||||
| @ -456,4 +459,18 @@ public abstract class BaseCmd { | |||||||
|         return ApiCommandResourceType.None; |         return ApiCommandResourceType.None; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public Map<String, String> convertDetailsToMap(Map details) { | ||||||
|  |         Map<String, String> detailsMap = new HashMap<String, String>(); | ||||||
|  |         if (MapUtils.isNotEmpty(details)) { | ||||||
|  |             Collection parameterCollection = details.values(); | ||||||
|  |             Iterator iter = parameterCollection.iterator(); | ||||||
|  |             while (iter.hasNext()) { | ||||||
|  |                 HashMap<String, String> value = (HashMap<String, String>)iter.next(); | ||||||
|  |                 for (Map.Entry<String,String> entry: value.entrySet()) { | ||||||
|  |                     detailsMap.put(entry.getKey(),entry.getValue()); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return detailsMap; | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -35,6 +35,7 @@ import org.apache.cloudstack.api.response.DomainResponse; | |||||||
| import org.apache.cloudstack.api.response.ProjectResponse; | import org.apache.cloudstack.api.response.ProjectResponse; | ||||||
| import org.apache.cloudstack.api.response.ServiceOfferingResponse; | import org.apache.cloudstack.api.response.ServiceOfferingResponse; | ||||||
| import org.apache.cloudstack.api.response.TemplateResponse; | import org.apache.cloudstack.api.response.TemplateResponse; | ||||||
|  | import org.apache.cloudstack.api.response.UserDataResponse; | ||||||
| import org.apache.cloudstack.api.response.UserResponse; | import org.apache.cloudstack.api.response.UserResponse; | ||||||
| import org.apache.cloudstack.api.response.ZoneResponse; | import org.apache.cloudstack.api.response.ZoneResponse; | ||||||
| import org.apache.cloudstack.context.CallContext; | import org.apache.cloudstack.context.CallContext; | ||||||
| @ -107,6 +108,12 @@ public class CreateAutoScaleVmProfileCmd extends BaseAsyncCreateCmd { | |||||||
|             since = "4.18.0") |             since = "4.18.0") | ||||||
|     private String userData; |     private String userData; | ||||||
| 
 | 
 | ||||||
|  |     @Parameter(name = ApiConstants.USER_DATA_ID, type = CommandType.UUID, entityType = UserDataResponse.class, description = "the ID of the Userdata", since = "4.18.1") | ||||||
|  |     private Long userDataId; | ||||||
|  | 
 | ||||||
|  |     @Parameter(name = ApiConstants.USER_DATA_DETAILS, type = CommandType.MAP, description = "used to specify the parameters values for the variables in userdata.", since = "4.18.1") | ||||||
|  |     private Map userDataDetails; | ||||||
|  | 
 | ||||||
|     @Parameter(name = ApiConstants.AUTOSCALE_USER_ID, |     @Parameter(name = ApiConstants.AUTOSCALE_USER_ID, | ||||||
|                type = CommandType.UUID, |                type = CommandType.UUID, | ||||||
|                entityType = UserResponse.class, |                entityType = UserResponse.class, | ||||||
| @ -163,6 +170,14 @@ public class CreateAutoScaleVmProfileCmd extends BaseAsyncCreateCmd { | |||||||
|         return userData; |         return userData; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public Long getUserDataId() { | ||||||
|  |         return userDataId; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public Map<String, String> getUserDataDetails() { | ||||||
|  |         return convertDetailsToMap(userDataDetails); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     public Long getAutoscaleUserId() { |     public Long getAutoscaleUserId() { | ||||||
|         return autoscaleUserId; |         return autoscaleUserId; | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -35,6 +35,7 @@ import org.apache.cloudstack.api.ServerApiException; | |||||||
| import org.apache.cloudstack.api.response.AutoScaleVmProfileResponse; | import org.apache.cloudstack.api.response.AutoScaleVmProfileResponse; | ||||||
| import org.apache.cloudstack.api.response.ServiceOfferingResponse; | import org.apache.cloudstack.api.response.ServiceOfferingResponse; | ||||||
| import org.apache.cloudstack.api.response.TemplateResponse; | import org.apache.cloudstack.api.response.TemplateResponse; | ||||||
|  | import org.apache.cloudstack.api.response.UserDataResponse; | ||||||
| import org.apache.cloudstack.api.response.UserResponse; | import org.apache.cloudstack.api.response.UserResponse; | ||||||
| import org.apache.cloudstack.context.CallContext; | import org.apache.cloudstack.context.CallContext; | ||||||
| 
 | 
 | ||||||
| @ -102,6 +103,14 @@ public class UpdateAutoScaleVmProfileCmd extends BaseAsyncCustomIdCmd { | |||||||
|             since = "4.18.0") |             since = "4.18.0") | ||||||
|     private String userData; |     private String userData; | ||||||
| 
 | 
 | ||||||
|  |     @Parameter(name = ApiConstants.USER_DATA_ID, type = CommandType.UUID, entityType = UserDataResponse.class, description = "the ID of the userdata", | ||||||
|  |             since = "4.18.1") | ||||||
|  |     private Long userDataId; | ||||||
|  | 
 | ||||||
|  |     @Parameter(name = ApiConstants.USER_DATA_DETAILS, type = CommandType.MAP, description = "used to specify the parameters values for the variables in userdata.", | ||||||
|  |             since = "4.18.1") | ||||||
|  |     private Map userDataDetails; | ||||||
|  | 
 | ||||||
|     @Parameter(name = ApiConstants.AUTOSCALE_USER_ID, |     @Parameter(name = ApiConstants.AUTOSCALE_USER_ID, | ||||||
|                type = CommandType.UUID, |                type = CommandType.UUID, | ||||||
|                entityType = UserResponse.class, |                entityType = UserResponse.class, | ||||||
| @ -156,6 +165,14 @@ public class UpdateAutoScaleVmProfileCmd extends BaseAsyncCustomIdCmd { | |||||||
|         return userData; |         return userData; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public Long getUserDataId() { | ||||||
|  |         return userDataId; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public Map<String, String> getUserDataDetails() { | ||||||
|  |         return convertDetailsToMap(userDataDetails); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     public Long getAutoscaleUserId() { |     public Long getAutoscaleUserId() { | ||||||
|         return autoscaleUserId; |         return autoscaleUserId; | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -309,17 +309,8 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd implements SecurityG | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public Map<String, String> getDetails() { |     public Map<String, String> getDetails() { | ||||||
|         Map<String, String> customparameterMap = new HashMap<String, String>(); |         Map<String, String> customparameterMap = convertDetailsToMap(details); | ||||||
|         if (details != null && details.size() != 0) { | 
 | ||||||
|             Collection parameterCollection = details.values(); |  | ||||||
|             Iterator iter = parameterCollection.iterator(); |  | ||||||
|             while (iter.hasNext()) { |  | ||||||
|                 HashMap<String, String> value = (HashMap<String, String>)iter.next(); |  | ||||||
|                 for (Map.Entry<String,String> entry: value.entrySet()) { |  | ||||||
|                     customparameterMap.put(entry.getKey(),entry.getValue()); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         if (getBootType() != null) { |         if (getBootType() != null) { | ||||||
|             customparameterMap.put(getBootType().toString(), getBootMode().toString()); |             customparameterMap.put(getBootType().toString(), getBootMode().toString()); | ||||||
|         } |         } | ||||||
| @ -450,18 +441,7 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd implements SecurityG | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public Map<String, String> getUserdataDetails() { |     public Map<String, String> getUserdataDetails() { | ||||||
|         Map<String, String> userdataDetailsMap = new HashMap<String, String>(); |         return convertDetailsToMap(userdataDetails); | ||||||
|         if (userdataDetails != null && userdataDetails.size() != 0) { |  | ||||||
|             Collection parameterCollection = userdataDetails.values(); |  | ||||||
|             Iterator iter = parameterCollection.iterator(); |  | ||||||
|             while (iter.hasNext()) { |  | ||||||
|                 HashMap<String, String> value = (HashMap<String, String>)iter.next(); |  | ||||||
|                 for (Map.Entry<String,String> entry: value.entrySet()) { |  | ||||||
|                     userdataDetailsMap.put(entry.getKey(),entry.getValue()); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         return userdataDetailsMap; |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public Long getZoneId() { |     public Long getZoneId() { | ||||||
|  | |||||||
| @ -39,9 +39,6 @@ import org.apache.cloudstack.api.response.UserVmResponse; | |||||||
| import org.apache.cloudstack.context.CallContext; | import org.apache.cloudstack.context.CallContext; | ||||||
| import org.apache.log4j.Logger; | import org.apache.log4j.Logger; | ||||||
| 
 | 
 | ||||||
| import java.util.Collection; |  | ||||||
| import java.util.HashMap; |  | ||||||
| import java.util.Iterator; |  | ||||||
| import java.util.Map; | import java.util.Map; | ||||||
| 
 | 
 | ||||||
| @APICommand(name = "resetUserDataForVirtualMachine", responseObject = UserVmResponse.class, description = "Resets the UserData for virtual machine. " + | @APICommand(name = "resetUserDataForVirtualMachine", responseObject = UserVmResponse.class, description = "Resets the UserData for virtual machine. " + | ||||||
| @ -117,18 +114,7 @@ public class ResetVMUserDataCmd extends BaseCmd implements UserCmd { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public Map<String, String> getUserdataDetails() { |     public Map<String, String> getUserdataDetails() { | ||||||
|         Map<String, String> userdataDetailsMap = new HashMap<String, String>(); |         return convertDetailsToMap(userdataDetails); | ||||||
|         if (userdataDetails != null && userdataDetails.size() != 0) { |  | ||||||
|             Collection parameterCollection = userdataDetails.values(); |  | ||||||
|             Iterator iter = parameterCollection.iterator(); |  | ||||||
|             while (iter.hasNext()) { |  | ||||||
|                 HashMap<String, String> value = (HashMap<String, String>)iter.next(); |  | ||||||
|                 for (Map.Entry<String,String> entry: value.entrySet()) { |  | ||||||
|                     userdataDetailsMap.put(entry.getKey(),entry.getValue()); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         return userdataDetailsMap; |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|  | |||||||
| @ -16,9 +16,6 @@ | |||||||
| // under the License. | // under the License. | ||||||
| package org.apache.cloudstack.api.command.user.vm; | package org.apache.cloudstack.api.command.user.vm; | ||||||
| 
 | 
 | ||||||
| import java.util.Collection; |  | ||||||
| import java.util.HashMap; |  | ||||||
| import java.util.Iterator; |  | ||||||
| import java.util.List; | import java.util.List; | ||||||
| import java.util.Map; | import java.util.Map; | ||||||
| 
 | 
 | ||||||
| @ -99,17 +96,7 @@ public class ScaleVMCmd extends BaseAsyncCmd implements UserCmd { | |||||||
|     //it is because details.values() cannot be cast to a map. |     //it is because details.values() cannot be cast to a map. | ||||||
|     //it gives a exception |     //it gives a exception | ||||||
|     public Map<String, String> getDetails() { |     public Map<String, String> getDetails() { | ||||||
|         Map<String, String> customparameterMap = new HashMap<String, String>(); |         Map<String, String> customparameterMap = convertDetailsToMap(details); | ||||||
|         if (details != null && details.size() != 0) { |  | ||||||
|             Collection parameterCollection = details.values(); |  | ||||||
|             Iterator iter = parameterCollection.iterator(); |  | ||||||
|             while (iter.hasNext()) { |  | ||||||
|                 HashMap<String, String> value = (HashMap<String, String>)iter.next(); |  | ||||||
|                 for (String key : value.keySet()) { |  | ||||||
|                     customparameterMap.put(key, value.get(key)); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         if (shrinkOk != null) customparameterMap.put(ApiConstants.SHRINK_OK, String.valueOf(isShrinkOk())); |         if (shrinkOk != null) customparameterMap.put(ApiConstants.SHRINK_OK, String.valueOf(isShrinkOk())); | ||||||
|         if (autoMigrate != null) customparameterMap.put(ApiConstants.AUTO_MIGRATE, String.valueOf(getAutoMigrate())); |         if (autoMigrate != null) customparameterMap.put(ApiConstants.AUTO_MIGRATE, String.valueOf(getAutoMigrate())); | ||||||
|  | |||||||
| @ -18,7 +18,6 @@ package org.apache.cloudstack.api.command.user.vm; | |||||||
| 
 | 
 | ||||||
| import java.util.Collection; | import java.util.Collection; | ||||||
| import java.util.HashMap; | import java.util.HashMap; | ||||||
| import java.util.Iterator; |  | ||||||
| import java.util.List; | import java.util.List; | ||||||
| import java.util.Map; | import java.util.Map; | ||||||
| 
 | 
 | ||||||
| @ -176,18 +175,7 @@ public class UpdateVMCmd extends BaseCustomIdCmd implements SecurityGroupAction, | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public Map<String, String> getUserdataDetails() { |     public Map<String, String> getUserdataDetails() { | ||||||
|         Map<String, String> userdataDetailsMap = new HashMap<String, String>(); |         return convertDetailsToMap(userdataDetails); | ||||||
|         if (userdataDetails != null && userdataDetails.size() != 0) { |  | ||||||
|             Collection parameterCollection = userdataDetails.values(); |  | ||||||
|             Iterator iter = parameterCollection.iterator(); |  | ||||||
|             while (iter.hasNext()) { |  | ||||||
|                 HashMap<String, String> value = (HashMap<String, String>)iter.next(); |  | ||||||
|                 for (Map.Entry<String,String> entry: value.entrySet()) { |  | ||||||
|                     userdataDetailsMap.put(entry.getKey(),entry.getValue()); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         return userdataDetailsMap; |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public Boolean getDisplayVm() { |     public Boolean getDisplayVm() { | ||||||
|  | |||||||
| @ -16,9 +16,6 @@ | |||||||
| // under the License. | // under the License. | ||||||
| package org.apache.cloudstack.api.command.user.vm; | package org.apache.cloudstack.api.command.user.vm; | ||||||
| 
 | 
 | ||||||
| import java.util.Collection; |  | ||||||
| import java.util.HashMap; |  | ||||||
| import java.util.Iterator; |  | ||||||
| import java.util.Map; | import java.util.Map; | ||||||
| 
 | 
 | ||||||
| import org.apache.log4j.Logger; | import org.apache.log4j.Logger; | ||||||
| @ -95,17 +92,7 @@ public class UpgradeVMCmd extends BaseCmd implements UserCmd { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public Map<String, String> getDetails() { |     public Map<String, String> getDetails() { | ||||||
|         Map<String, String> customparameterMap = new HashMap<String, String>(); |         Map<String, String> customparameterMap = convertDetailsToMap(details); | ||||||
|         if (details != null && details.size() != 0) { |  | ||||||
|             Collection parameterCollection = details.values(); |  | ||||||
|             Iterator iter = parameterCollection.iterator(); |  | ||||||
|             while (iter.hasNext()) { |  | ||||||
|                 HashMap<String, String> value = (HashMap<String, String>)iter.next(); |  | ||||||
|                 for (String key : value.keySet()) { |  | ||||||
|                     customparameterMap.put(key, value.get(key)); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         if (shrinkOk != null) customparameterMap.put(ApiConstants.SHRINK_OK, String.valueOf(isShrinkOk())); |         if (shrinkOk != null) customparameterMap.put(ApiConstants.SHRINK_OK, String.valueOf(isShrinkOk())); | ||||||
|         if (autoMigrate != null) customparameterMap.put(ApiConstants.AUTO_MIGRATE, String.valueOf(getAutoMigrate())); |         if (autoMigrate != null) customparameterMap.put(ApiConstants.AUTO_MIGRATE, String.valueOf(getAutoMigrate())); | ||||||
|  | |||||||
| @ -72,6 +72,18 @@ public class AutoScaleVmProfileResponse extends BaseResponse implements Controll | |||||||
|     @Param(description = "Base 64 encoded VM user data") |     @Param(description = "Base 64 encoded VM user data") | ||||||
|     private String userData; |     private String userData; | ||||||
| 
 | 
 | ||||||
|  |     @SerializedName(ApiConstants.USER_DATA_ID) @Param(description="the id of userdata used for the VM", since = "4.18.1") | ||||||
|  |     private String userDataId; | ||||||
|  | 
 | ||||||
|  |     @SerializedName(ApiConstants.USER_DATA_NAME) @Param(description="the name of userdata used for the VM", since = "4.18.1") | ||||||
|  |     private String userDataName; | ||||||
|  | 
 | ||||||
|  |     @SerializedName(ApiConstants.USER_DATA_POLICY) @Param(description="the userdata override policy with the userdata provided while deploying VM", since = "4.18.1") | ||||||
|  |     private String userDataPolicy; | ||||||
|  | 
 | ||||||
|  |     @SerializedName(ApiConstants.USER_DATA_DETAILS) @Param(description="list of variables and values for the variables declared in userdata", since = "4.18.1") | ||||||
|  |     private String userDataDetails; | ||||||
|  | 
 | ||||||
|     @SerializedName(ApiConstants.AUTOSCALE_USER_ID) |     @SerializedName(ApiConstants.AUTOSCALE_USER_ID) | ||||||
|     @Param(description = "the ID of the user used to launch and destroy the VMs") |     @Param(description = "the ID of the user used to launch and destroy the VMs") | ||||||
|     private String autoscaleUserId; |     private String autoscaleUserId; | ||||||
| @ -153,6 +165,22 @@ public class AutoScaleVmProfileResponse extends BaseResponse implements Controll | |||||||
|         this.userData = userData; |         this.userData = userData; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public void setUserDataId(String userDataId) { | ||||||
|  |         this.userDataId = userDataId; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setUserDataName(String userDataName) { | ||||||
|  |         this.userDataName = userDataName; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setUserDataPolicy(String userDataPolicy) { | ||||||
|  |         this.userDataPolicy = userDataPolicy; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setUserDataDetails(String userDataDetails) { | ||||||
|  |         this.userDataDetails = userDataDetails; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     @Override |     @Override | ||||||
|     public void setAccountName(String accountName) { |     public void setAccountName(String accountName) { | ||||||
|         this.accountName = accountName; |         this.accountName = accountName; | ||||||
| @ -193,4 +221,24 @@ public class AutoScaleVmProfileResponse extends BaseResponse implements Controll | |||||||
|     public void setForDisplay(Boolean forDisplay) { |     public void setForDisplay(Boolean forDisplay) { | ||||||
|         this.forDisplay = forDisplay; |         this.forDisplay = forDisplay; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     public String getUserData() { | ||||||
|  |         return userData; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getUserDataId() { | ||||||
|  |         return userDataId; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getUserDataName() { | ||||||
|  |         return userDataName; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getUserDataPolicy() { | ||||||
|  |         return userDataPolicy; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public String getUserDataDetails() { | ||||||
|  |         return userDataDetails; | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -88,6 +88,12 @@ public class AutoScaleVmProfileVO implements AutoScaleVmProfile, Identity, Inter | |||||||
|     @Basic(fetch = FetchType.LAZY) |     @Basic(fetch = FetchType.LAZY) | ||||||
|     private String userData; |     private String userData; | ||||||
| 
 | 
 | ||||||
|  |     @Column(name = "user_data_id", nullable = true) | ||||||
|  |     private Long userDataId = null; | ||||||
|  | 
 | ||||||
|  |     @Column(name = "user_data_details", updatable = true, length = 4096) | ||||||
|  |     private String userDataDetails; | ||||||
|  | 
 | ||||||
|     @Column(name = GenericDao.REMOVED_COLUMN) |     @Column(name = GenericDao.REMOVED_COLUMN) | ||||||
|     protected Date removed; |     protected Date removed; | ||||||
| 
 | 
 | ||||||
| @ -228,6 +234,24 @@ public class AutoScaleVmProfileVO implements AutoScaleVmProfile, Identity, Inter | |||||||
|         return userData; |         return userData; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     @Override | ||||||
|  |     public Long getUserDataId() { | ||||||
|  |         return userDataId; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setUserDataId(Long userDataId) { | ||||||
|  |         this.userDataId = userDataId; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public String getUserDataDetails() { | ||||||
|  |         return userDataDetails; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setUserDataDetails(String userDataDetails) { | ||||||
|  |         this.userDataDetails = userDataDetails; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     @Override |     @Override | ||||||
|     public String getUuid() { |     public String getUuid() { | ||||||
|         return uuid; |         return uuid; | ||||||
|  | |||||||
| @ -63,6 +63,7 @@ public class Upgrade41800to41810 implements DbUpgrade, DbUpgradeSystemVmTemplate | |||||||
|         fixForeignKeyNames(conn); |         fixForeignKeyNames(conn); | ||||||
|         updateGuestOsMappings(conn); |         updateGuestOsMappings(conn); | ||||||
|         copyGuestOsMappingsToVMware80u1(); |         copyGuestOsMappingsToVMware80u1(); | ||||||
|  |         addForeignKeyToAutoscaleVmprofiles(conn); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
| @ -225,4 +226,8 @@ public class Upgrade41800to41810 implements DbUpgrade, DbUpgradeSystemVmTemplate | |||||||
|         DbUpgradeUtils.dropKeysIfExist(conn, "cloud.volumes", keys, false); |         DbUpgradeUtils.dropKeysIfExist(conn, "cloud.volumes", keys, false); | ||||||
|         DbUpgradeUtils.addForeignKey(conn, "volumes", "passphrase_id","passphrase", "id"); |         DbUpgradeUtils.addForeignKey(conn, "volumes", "passphrase_id","passphrase", "id"); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     private void addForeignKeyToAutoscaleVmprofiles(Connection conn) { | ||||||
|  |         DbUpgradeUtils.addForeignKey(conn, "autoscale_vmprofiles", "user_data_id", "user_data", "id"); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -35,6 +35,10 @@ CALL ADD_GUEST_OS_AND_HYPERVISOR_MAPPING (6, 'Windows Server 2022 (64-bit)', 'VM | |||||||
| CALL ADD_GUEST_OS_AND_HYPERVISOR_MAPPING (6, 'Windows Server 2022 (64-bit)', 'VMware', '8.0.0.1', 'windows2019srvNext_64Guest'); | CALL ADD_GUEST_OS_AND_HYPERVISOR_MAPPING (6, 'Windows Server 2022 (64-bit)', 'VMware', '8.0.0.1', 'windows2019srvNext_64Guest'); | ||||||
| CALL ADD_GUEST_OS_AND_HYPERVISOR_MAPPING (6, 'Windows Server 2022 (64-bit)', 'Xenserver', '8.2.0', 'Windows Server 2022 (64-bit)'); | CALL ADD_GUEST_OS_AND_HYPERVISOR_MAPPING (6, 'Windows Server 2022 (64-bit)', 'Xenserver', '8.2.0', 'Windows Server 2022 (64-bit)'); | ||||||
| 
 | 
 | ||||||
|  | -- Support userdata ids and details in VM AutoScaling | ||||||
|  | CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.autoscale_vmprofiles', 'user_data_id', 'bigint unsigned DEFAULT NULL COMMENT "id of the user data" AFTER `user_data`'); | ||||||
|  | CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.autoscale_vmprofiles', 'user_data_details', 'mediumtext DEFAULT NULL COMMENT "value of the comma-separated list of parameters" AFTER `user_data_id`'); | ||||||
|  | 
 | ||||||
| -- Don't enable CPU cap for default system offerings, fixes regression from https://github.com/apache/cloudstack/pull/6420 | -- Don't enable CPU cap for default system offerings, fixes regression from https://github.com/apache/cloudstack/pull/6420 | ||||||
| UPDATE `cloud`.`service_offering` so | UPDATE `cloud`.`service_offering` so | ||||||
| SET so.limit_cpu_use = 0 | SET so.limit_cpu_use = 0 | ||||||
|  | |||||||
| @ -26,6 +26,18 @@ import org.junit.Test; | |||||||
| 
 | 
 | ||||||
| public class AutoScaleVmProfileVOTest { | public class AutoScaleVmProfileVOTest { | ||||||
| 
 | 
 | ||||||
|  |     static long zoneId = 1L; | ||||||
|  |     static long domainId = 2L; | ||||||
|  |     static long accountId = 3L; | ||||||
|  |     static long serviceOfferingId = 4L; | ||||||
|  |     static long templateId  = 5L; | ||||||
|  |     static String userdata = "userdata"; | ||||||
|  |     static long userdataId = 6L; | ||||||
|  |     static String userdataDetails = "userdataDetails"; | ||||||
|  |     static String userdataNew = "userdataNew"; | ||||||
|  | 
 | ||||||
|  |     static long autoScaleUserId = 7L; | ||||||
|  | 
 | ||||||
|     @Test |     @Test | ||||||
|     public void testCounterParamsForUpdate() { |     public void testCounterParamsForUpdate() { | ||||||
|         AutoScaleVmProfileVO profile = new AutoScaleVmProfileVO(); |         AutoScaleVmProfileVO profile = new AutoScaleVmProfileVO(); | ||||||
| @ -62,4 +74,23 @@ public class AutoScaleVmProfileVOTest { | |||||||
|         Assert.assertEquals("rootdisksize", otherDeployParamsList.get(1).first()); |         Assert.assertEquals("rootdisksize", otherDeployParamsList.get(1).first()); | ||||||
|         Assert.assertEquals("10", otherDeployParamsList.get(1).second()); |         Assert.assertEquals("10", otherDeployParamsList.get(1).second()); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void testProperties() { | ||||||
|  |         AutoScaleVmProfileVO profile = new AutoScaleVmProfileVO(zoneId, domainId, accountId, serviceOfferingId, templateId, null, null, userdata, null, autoScaleUserId); | ||||||
|  |         Assert.assertEquals(new Long(zoneId), profile.getZoneId()); | ||||||
|  |         Assert.assertEquals(domainId, profile.getDomainId()); | ||||||
|  |         Assert.assertEquals(accountId, profile.getAccountId()); | ||||||
|  |         Assert.assertEquals(new Long(serviceOfferingId), profile.getServiceOfferingId()); | ||||||
|  |         Assert.assertEquals(new Long(templateId), profile.getTemplateId()); | ||||||
|  |         Assert.assertEquals(userdata, profile.getUserData()); | ||||||
|  |         Assert.assertEquals(new Long(autoScaleUserId), profile.getAutoScaleUserId()); | ||||||
|  | 
 | ||||||
|  |         profile.setUserData(userdataNew); | ||||||
|  |         profile.setUserDataId(userdataId); | ||||||
|  |         profile.setUserDataDetails(userdataDetails); | ||||||
|  |         Assert.assertEquals(userdataNew, profile.getUserData()); | ||||||
|  |         Assert.assertEquals(new Long(userdataId), profile.getUserDataId()); | ||||||
|  |         Assert.assertEquals(userdataDetails, profile.getUserDataDetails()); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -21,6 +21,7 @@ import java.util.Map; | |||||||
| 
 | 
 | ||||||
| import javax.inject.Inject; | import javax.inject.Inject; | ||||||
| 
 | 
 | ||||||
|  | import org.apache.cloudstack.api.ApiConstants; | ||||||
| import org.apache.cloudstack.api.ApiErrorCode; | import org.apache.cloudstack.api.ApiErrorCode; | ||||||
| import org.apache.cloudstack.api.BaseAsyncCmd; | import org.apache.cloudstack.api.BaseAsyncCmd; | ||||||
| import org.apache.cloudstack.api.BaseAsyncCreateCmd; | import org.apache.cloudstack.api.BaseAsyncCreateCmd; | ||||||
| @ -101,6 +102,11 @@ public class ApiAsyncJobDispatcher extends AdapterBase implements AsyncJobDispat | |||||||
|                 ctx.putContextParameters((Map<Object, Object>) gson.fromJson(contextDetails, objectMapType)); |                 ctx.putContextParameters((Map<Object, Object>) gson.fromJson(contextDetails, objectMapType)); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  |             String httpmethod = params.get(ApiConstants.HTTPMETHOD); | ||||||
|  |             if (httpmethod != null) { | ||||||
|  |                 cmdObj.setHttpMethod(httpmethod); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|             try { |             try { | ||||||
|                 // dispatch could ultimately queue the job |                 // dispatch could ultimately queue the job | ||||||
|                 _dispatcher.dispatch(cmdObj, params, true); |                 _dispatcher.dispatch(cmdObj, params, true); | ||||||
|  | |||||||
| @ -365,6 +365,7 @@ import com.cloud.user.User; | |||||||
| import com.cloud.user.UserAccount; | import com.cloud.user.UserAccount; | ||||||
| import com.cloud.user.UserData; | import com.cloud.user.UserData; | ||||||
| import com.cloud.user.UserStatisticsVO; | import com.cloud.user.UserStatisticsVO; | ||||||
|  | import com.cloud.user.dao.UserDataDao; | ||||||
| import com.cloud.user.dao.UserStatisticsDao; | import com.cloud.user.dao.UserStatisticsDao; | ||||||
| import com.cloud.uservm.UserVm; | import com.cloud.uservm.UserVm; | ||||||
| import com.cloud.utils.Pair; | import com.cloud.utils.Pair; | ||||||
| @ -455,6 +456,8 @@ public class ApiResponseHelper implements ResponseGenerator { | |||||||
|     UserVmJoinDao userVmJoinDao; |     UserVmJoinDao userVmJoinDao; | ||||||
|     @Inject |     @Inject | ||||||
|     NetworkServiceMapDao ntwkSrvcDao; |     NetworkServiceMapDao ntwkSrvcDao; | ||||||
|  |     @Inject | ||||||
|  |     UserDataDao userDataDao; | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|     public UserResponse createUserResponse(User user) { |     public UserResponse createUserResponse(User user) { | ||||||
| @ -3393,9 +3396,20 @@ public class ApiResponseHelper implements ResponseGenerator { | |||||||
|             VMTemplateVO template = ApiDBUtils.findTemplateById(profile.getTemplateId()); |             VMTemplateVO template = ApiDBUtils.findTemplateById(profile.getTemplateId()); | ||||||
|             if (template != null) { |             if (template != null) { | ||||||
|                 response.setTemplateId(template.getUuid()); |                 response.setTemplateId(template.getUuid()); | ||||||
|  |                 if (template.getUserDataOverridePolicy() != null) { | ||||||
|  |                     response.setUserDataPolicy(template.getUserDataOverridePolicy().toString()); | ||||||
|  |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         response.setUserData(profile.getUserData()); |         response.setUserData(profile.getUserData()); | ||||||
|  |         if (profile.getUserDataId() != null) { | ||||||
|  |             UserData userData = userDataDao.findById(profile.getUserDataId()); | ||||||
|  |             if (userData != null) { | ||||||
|  |                 response.setUserDataId(userData.getUuid()); | ||||||
|  |                 response.setUserDataName(userData.getName()); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         response.setUserDataDetails(profile.getUserDataDetails()); | ||||||
|         response.setOtherDeployParams(profile.getOtherDeployParamsList()); |         response.setOtherDeployParams(profile.getOtherDeployParamsList()); | ||||||
|         response.setCounterParams(profile.getCounterParams()); |         response.setCounterParams(profile.getCounterParams()); | ||||||
|         response.setExpungeVmGracePeriod(profile.getExpungeVmGracePeriod()); |         response.setExpungeVmGracePeriod(profile.getExpungeVmGracePeriod()); | ||||||
|  | |||||||
| @ -740,6 +740,9 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer | |||||||
|             params.put("ctxStartEventId", String.valueOf(startEventId)); |             params.put("ctxStartEventId", String.valueOf(startEventId)); | ||||||
|             params.put("cmdEventType", asyncCmd.getEventType().toString()); |             params.put("cmdEventType", asyncCmd.getEventType().toString()); | ||||||
|             params.put("ctxDetails", ApiGsonHelper.getBuilder().create().toJson(ctx.getContextParameters())); |             params.put("ctxDetails", ApiGsonHelper.getBuilder().create().toJson(ctx.getContextParameters())); | ||||||
|  |             if (asyncCmd.getHttpMethod() != null) { | ||||||
|  |                 params.put(ApiConstants.HTTPMETHOD, asyncCmd.getHttpMethod().toString()); | ||||||
|  |             } | ||||||
| 
 | 
 | ||||||
|             Long instanceId = (objectId == null) ? asyncCmd.getApiResourceId() : objectId; |             Long instanceId = (objectId == null) ? asyncCmd.getApiResourceId() : objectId; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -532,7 +532,6 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScaleManage | |||||||
|         long zoneId = cmd.getZoneId(); |         long zoneId = cmd.getZoneId(); | ||||||
|         long serviceOfferingId = cmd.getServiceOfferingId(); |         long serviceOfferingId = cmd.getServiceOfferingId(); | ||||||
|         Long autoscaleUserId = cmd.getAutoscaleUserId(); |         Long autoscaleUserId = cmd.getAutoscaleUserId(); | ||||||
|         String userData = cmd.getUserData(); |  | ||||||
| 
 | 
 | ||||||
|         DataCenter zone = entityMgr.findById(DataCenter.class, zoneId); |         DataCenter zone = entityMgr.findById(DataCenter.class, zoneId); | ||||||
| 
 | 
 | ||||||
| @ -545,6 +544,11 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScaleManage | |||||||
|             throw new InvalidParameterValueException("Unable to find service offering by id"); |             throw new InvalidParameterValueException("Unable to find service offering by id"); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         VirtualMachineTemplate template = entityMgr.findById(VirtualMachineTemplate.class, cmd.getTemplateId()); | ||||||
|  |         if (template == null) { | ||||||
|  |             throw new InvalidParameterValueException("Unable to find template by id " + cmd.getTemplateId()); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         // validations |         // validations | ||||||
|         HashMap<String, String> deployParams = cmd.getDeployParamMap(); |         HashMap<String, String> deployParams = cmd.getDeployParamMap(); | ||||||
|         /* |         /* | ||||||
| @ -562,9 +566,23 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScaleManage | |||||||
|             profileVO.setDisplay(cmd.getDisplay()); |             profileVO.setDisplay(cmd.getDisplay()); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         String userData = cmd.getUserData(); | ||||||
|  |         Long userDataId = cmd.getUserDataId(); | ||||||
|  |         String userDataDetails = null; | ||||||
|  |         if (MapUtils.isNotEmpty(cmd.getUserDataDetails())) { | ||||||
|  |             userDataDetails = cmd.getUserDataDetails().toString(); | ||||||
|  |         } | ||||||
|  |         userData = userVmMgr.finalizeUserData(userData, userDataId, template); | ||||||
|  |         userData = userVmMgr.validateUserData(userData, cmd.getHttpMethod()); | ||||||
|         if (userData != null) { |         if (userData != null) { | ||||||
|             profileVO.setUserData(userData); |             profileVO.setUserData(userData); | ||||||
|         } |         } | ||||||
|  |         if (userDataId != null) { | ||||||
|  |             profileVO.setUserDataId(userDataId); | ||||||
|  |         } | ||||||
|  |         if (userDataDetails != null) { | ||||||
|  |             profileVO.setUserDataDetails(userDataDetails); | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         profileVO = checkValidityAndPersist(profileVO, true); |         profileVO = checkValidityAndPersist(profileVO, true); | ||||||
|         s_logger.info("Successfully create AutoScale Vm Profile with Id: " + profileVO.getId()); |         s_logger.info("Successfully create AutoScale Vm Profile with Id: " + profileVO.getId()); | ||||||
| @ -582,12 +600,19 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScaleManage | |||||||
|         Map<String, HashMap<String, String>> otherDeployParams = cmd.getOtherDeployParams(); |         Map<String, HashMap<String, String>> otherDeployParams = cmd.getOtherDeployParams(); | ||||||
|         Map counterParamList = cmd.getCounterParamList(); |         Map counterParamList = cmd.getCounterParamList(); | ||||||
|         String userData = cmd.getUserData(); |         String userData = cmd.getUserData(); | ||||||
|  |         Long userDataId = cmd.getUserDataId(); | ||||||
|  |         String userDataDetails = null; | ||||||
|  |         if (MapUtils.isNotEmpty(cmd.getUserDataDetails())) { | ||||||
|  |             userDataDetails = cmd.getUserDataDetails().toString(); | ||||||
|  |         } | ||||||
|  |         boolean userdataUpdate = userData != null || userDataId != null || MapUtils.isNotEmpty(cmd.getUserDataDetails()); | ||||||
| 
 | 
 | ||||||
|         Integer expungeVmGracePeriod = cmd.getExpungeVmGracePeriod(); |         Integer expungeVmGracePeriod = cmd.getExpungeVmGracePeriod(); | ||||||
| 
 | 
 | ||||||
|         AutoScaleVmProfileVO vmProfile = getEntityInDatabase(CallContext.current().getCallingAccount(), "Auto Scale Vm Profile", profileId, autoScaleVmProfileDao); |         AutoScaleVmProfileVO vmProfile = getEntityInDatabase(CallContext.current().getCallingAccount(), "Auto Scale Vm Profile", profileId, autoScaleVmProfileDao); | ||||||
| 
 | 
 | ||||||
|         boolean physicalParameterUpdate = (templateId != null || autoscaleUserId != null || counterParamList != null || otherDeployParams != null || expungeVmGracePeriod != null || userData != null); |         boolean physicalParameterUpdate = (templateId != null || autoscaleUserId != null || counterParamList != null | ||||||
|  |                 || otherDeployParams != null || expungeVmGracePeriod != null || userdataUpdate); | ||||||
| 
 | 
 | ||||||
|         if (serviceOfferingId != null) { |         if (serviceOfferingId != null) { | ||||||
|             vmProfile.setServiceOfferingId(serviceOfferingId); |             vmProfile.setServiceOfferingId(serviceOfferingId); | ||||||
| @ -609,10 +634,6 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScaleManage | |||||||
|             vmProfile.setCounterParamsForUpdate(counterParamList); |             vmProfile.setCounterParamsForUpdate(counterParamList); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if (userData != null) { |  | ||||||
|             vmProfile.setUserData(userData); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (expungeVmGracePeriod != null) { |         if (expungeVmGracePeriod != null) { | ||||||
|             vmProfile.setExpungeVmGracePeriod(expungeVmGracePeriod); |             vmProfile.setExpungeVmGracePeriod(expungeVmGracePeriod); | ||||||
|         } |         } | ||||||
| @ -625,6 +646,18 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScaleManage | |||||||
|             vmProfile.setDisplay(cmd.getDisplay()); |             vmProfile.setDisplay(cmd.getDisplay()); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         if (userdataUpdate) { | ||||||
|  |             if (templateId == null) { | ||||||
|  |                 templateId = vmProfile.getTemplateId(); | ||||||
|  |             } | ||||||
|  |             VirtualMachineTemplate template = entityMgr.findByIdIncludingRemoved(VirtualMachineTemplate.class, templateId); | ||||||
|  |             userData = userVmMgr.finalizeUserData(userData, userDataId, template); | ||||||
|  |             userData = userVmMgr.validateUserData(userData, cmd.getHttpMethod()); | ||||||
|  |             vmProfile.setUserDataId(userDataId); | ||||||
|  |             vmProfile.setUserData(userData); | ||||||
|  |             vmProfile.setUserDataDetails(userDataDetails); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         List<AutoScaleVmGroupVO> vmGroupList = autoScaleVmGroupDao.listByAll(null, profileId); |         List<AutoScaleVmGroupVO> vmGroupList = autoScaleVmGroupDao.listByAll(null, profileId); | ||||||
|         for (AutoScaleVmGroupVO vmGroupVO : vmGroupList) { |         for (AutoScaleVmGroupVO vmGroupVO : vmGroupList) { | ||||||
|             if (physicalParameterUpdate && !vmGroupVO.getState().equals(AutoScaleVmGroup.State.DISABLED)) { |             if (physicalParameterUpdate && !vmGroupVO.getState().equals(AutoScaleVmGroup.State.DISABLED)) { | ||||||
| @ -1740,6 +1773,8 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScaleManage | |||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             String userData = profileVo.getUserData(); |             String userData = profileVo.getUserData(); | ||||||
|  |             Long userDataId = profileVo.getUserDataId(); | ||||||
|  |             String userDataDetails = profileVo.getUserDataDetails(); | ||||||
| 
 | 
 | ||||||
|             UserVm vm = null; |             UserVm vm = null; | ||||||
|             IpAddresses addrs = new IpAddresses(null, null); |             IpAddresses addrs = new IpAddresses(null, null); | ||||||
| @ -1763,20 +1798,20 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScaleManage | |||||||
|             if (zone.getNetworkType() == NetworkType.Basic) { |             if (zone.getNetworkType() == NetworkType.Basic) { | ||||||
|                 vm = userVmService.createBasicSecurityGroupVirtualMachine(zone, serviceOffering, template, null, owner, vmHostName, |                 vm = userVmService.createBasicSecurityGroupVirtualMachine(zone, serviceOffering, template, null, owner, vmHostName, | ||||||
|                         vmHostName, diskOfferingId, dataDiskSize, null, |                         vmHostName, diskOfferingId, dataDiskSize, null, | ||||||
|                         hypervisorType, HTTPMethod.GET, userData, null, null, sshKeyPairs, |                         hypervisorType, HTTPMethod.GET, userData, userDataId, userDataDetails, sshKeyPairs, | ||||||
|                         null, null, true, null, affinityGroupIdList, customParameters, null, null, null, |                         null, null, true, null, affinityGroupIdList, customParameters, null, null, null, | ||||||
|                         null, true, overrideDiskOfferingId); |                         null, true, overrideDiskOfferingId); | ||||||
|             } else { |             } else { | ||||||
|                 if (zone.isSecurityGroupEnabled()) { |                 if (zone.isSecurityGroupEnabled()) { | ||||||
|                     vm = userVmService.createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, template, networkIds, null, |                     vm = userVmService.createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, template, networkIds, null, | ||||||
|                             owner, vmHostName,vmHostName, diskOfferingId, dataDiskSize, null, |                             owner, vmHostName,vmHostName, diskOfferingId, dataDiskSize, null, | ||||||
|                             hypervisorType, HTTPMethod.GET, userData, null, null, sshKeyPairs, |                             hypervisorType, HTTPMethod.GET, userData, userDataId, userDataDetails, sshKeyPairs, | ||||||
|                             null, null, true, null, affinityGroupIdList, customParameters, null, null, null, |                             null, null, true, null, affinityGroupIdList, customParameters, null, null, null, | ||||||
|                             null, true, overrideDiskOfferingId, null); |                             null, true, overrideDiskOfferingId, null); | ||||||
|                 } else { |                 } else { | ||||||
|                     vm = userVmService.createAdvancedVirtualMachine(zone, serviceOffering, template, networkIds, owner, vmHostName, vmHostName, |                     vm = userVmService.createAdvancedVirtualMachine(zone, serviceOffering, template, networkIds, owner, vmHostName, vmHostName, | ||||||
|                             diskOfferingId, dataDiskSize, null, |                             diskOfferingId, dataDiskSize, null, | ||||||
|                             hypervisorType, HTTPMethod.GET, userData, null, null, sshKeyPairs, |                             hypervisorType, HTTPMethod.GET, userData, userDataId, userDataDetails, sshKeyPairs, | ||||||
|                             null, addrs, true, null, affinityGroupIdList, customParameters, null, null, null, |                             null, addrs, true, null, affinityGroupIdList, customParameters, null, null, null, | ||||||
|                             null, true, null, overrideDiskOfferingId); |                             null, true, null, overrideDiskOfferingId); | ||||||
|                 } |                 } | ||||||
|  | |||||||
| @ -92,6 +92,10 @@ public interface UserVmManager extends UserVmService { | |||||||
| 
 | 
 | ||||||
|     void removeInstanceFromInstanceGroup(long vmId); |     void removeInstanceFromInstanceGroup(long vmId); | ||||||
| 
 | 
 | ||||||
|  |     String finalizeUserData(String userData, Long userDataId, VirtualMachineTemplate template); | ||||||
|  | 
 | ||||||
|  |     String validateUserData(String userData, HTTPMethod httpmethod); | ||||||
|  | 
 | ||||||
|     boolean isVMUsingLocalStorage(VMInstanceVO vm); |     boolean isVMUsingLocalStorage(VMInstanceVO vm); | ||||||
| 
 | 
 | ||||||
|     boolean expunge(UserVmVO vm); |     boolean expunge(UserVmVO vm); | ||||||
|  | |||||||
| @ -4769,7 +4769,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     protected String validateUserData(String userData, HTTPMethod httpmethod) { |     @Override | ||||||
|  |     public String validateUserData(String userData, HTTPMethod httpmethod) { | ||||||
|         byte[] decodedUserData = null; |         byte[] decodedUserData = null; | ||||||
|         if (userData != null) { |         if (userData != null) { | ||||||
| 
 | 
 | ||||||
| @ -5703,7 +5704,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir | |||||||
|         return userVm.getHypervisorType(); |         return userVm.getHypervisorType(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     protected String finalizeUserData(String userData, Long userDataId, VirtualMachineTemplate template) { |     @Override | ||||||
|  |     public String finalizeUserData(String userData, Long userDataId, VirtualMachineTemplate template) { | ||||||
|         if (StringUtils.isEmpty(userData) && userDataId == null && (template == null || template.getUserDataId() == null)) { |         if (StringUtils.isEmpty(userData) && userDataId == null && (template == null || template.getUserDataId() == null)) { | ||||||
|             return null; |             return null; | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -32,6 +32,7 @@ import java.util.UUID; | |||||||
| 
 | 
 | ||||||
| import org.apache.cloudstack.annotation.dao.AnnotationDao; | import org.apache.cloudstack.annotation.dao.AnnotationDao; | ||||||
| import org.apache.cloudstack.api.response.AutoScaleVmGroupResponse; | import org.apache.cloudstack.api.response.AutoScaleVmGroupResponse; | ||||||
|  | import org.apache.cloudstack.api.response.AutoScaleVmProfileResponse; | ||||||
| import org.apache.cloudstack.api.response.DirectDownloadCertificateResponse; | import org.apache.cloudstack.api.response.DirectDownloadCertificateResponse; | ||||||
| import org.apache.cloudstack.api.response.NicSecondaryIpResponse; | import org.apache.cloudstack.api.response.NicSecondaryIpResponse; | ||||||
| import org.apache.cloudstack.api.response.UsageRecordResponse; | import org.apache.cloudstack.api.response.UsageRecordResponse; | ||||||
| @ -52,17 +53,22 @@ import org.powermock.modules.junit4.PowerMockRunner; | |||||||
| import com.cloud.domain.DomainVO; | import com.cloud.domain.DomainVO; | ||||||
| import com.cloud.network.as.AutoScaleVmGroup; | import com.cloud.network.as.AutoScaleVmGroup; | ||||||
| import com.cloud.network.as.AutoScaleVmGroupVO; | import com.cloud.network.as.AutoScaleVmGroupVO; | ||||||
|  | import com.cloud.network.as.AutoScaleVmProfileVO; | ||||||
| import com.cloud.network.as.dao.AutoScaleVmGroupVmMapDao; | import com.cloud.network.as.dao.AutoScaleVmGroupVmMapDao; | ||||||
| import com.cloud.network.dao.IPAddressVO; | import com.cloud.network.dao.IPAddressVO; | ||||||
| import com.cloud.network.dao.LoadBalancerVO; | import com.cloud.network.dao.LoadBalancerVO; | ||||||
| import com.cloud.network.dao.NetworkServiceMapDao; | import com.cloud.network.dao.NetworkServiceMapDao; | ||||||
| import com.cloud.network.dao.NetworkVO; | import com.cloud.network.dao.NetworkVO; | ||||||
|  | import com.cloud.storage.VMTemplateVO; | ||||||
| import com.cloud.usage.UsageVO; | import com.cloud.usage.UsageVO; | ||||||
| import com.cloud.user.Account; | import com.cloud.user.Account; | ||||||
| import com.cloud.user.AccountManager; | import com.cloud.user.AccountManager; | ||||||
| import com.cloud.user.AccountVO; | import com.cloud.user.AccountVO; | ||||||
| import com.cloud.user.User; | import com.cloud.user.User; | ||||||
|  | import com.cloud.user.UserData; | ||||||
|  | import com.cloud.user.UserDataVO; | ||||||
| import com.cloud.user.UserVO; | import com.cloud.user.UserVO; | ||||||
|  | import com.cloud.user.dao.UserDataDao; | ||||||
| import com.cloud.utils.net.Ip; | import com.cloud.utils.net.Ip; | ||||||
| import com.cloud.vm.NicSecondaryIp; | import com.cloud.vm.NicSecondaryIp; | ||||||
| 
 | 
 | ||||||
| @ -86,12 +92,27 @@ public class ApiResponseHelperTest { | |||||||
|     @Mock |     @Mock | ||||||
|     AutoScaleVmGroupVmMapDao autoScaleVmGroupVmMapDaoMock; |     AutoScaleVmGroupVmMapDao autoScaleVmGroupVmMapDaoMock; | ||||||
| 
 | 
 | ||||||
|  |     @Mock | ||||||
|  |     UserDataDao userDataDaoMock; | ||||||
|  | 
 | ||||||
|     @Spy |     @Spy | ||||||
|     @InjectMocks |     @InjectMocks | ||||||
|     ApiResponseHelper apiResponseHelper = new ApiResponseHelper(); |     ApiResponseHelper apiResponseHelper = new ApiResponseHelper(); | ||||||
| 
 | 
 | ||||||
|     SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss ZZZ"); |     SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss ZZZ"); | ||||||
| 
 | 
 | ||||||
|  |     static long zoneId = 1L; | ||||||
|  |     static long domainId = 2L; | ||||||
|  |     static long accountId = 3L; | ||||||
|  |     static long serviceOfferingId = 4L; | ||||||
|  |     static long templateId  = 5L; | ||||||
|  |     static String userdata = "userdata"; | ||||||
|  |     static long userdataId = 6L; | ||||||
|  |     static String userdataDetails = "userdataDetails"; | ||||||
|  |     static String userdataNew = "userdataNew"; | ||||||
|  | 
 | ||||||
|  |     static long autoScaleUserId = 7L; | ||||||
|  | 
 | ||||||
|     @Before |     @Before | ||||||
|     public void injectMocks() throws SecurityException, NoSuchFieldException, |     public void injectMocks() throws SecurityException, NoSuchFieldException, | ||||||
|             IllegalArgumentException, IllegalAccessException { |             IllegalArgumentException, IllegalAccessException { | ||||||
| @ -297,4 +318,55 @@ public class ApiResponseHelperTest { | |||||||
|         assertEquals("8080", response.getPublicPort()); |         assertEquals("8080", response.getPublicPort()); | ||||||
|         assertEquals("8081", response.getPrivatePort()); |         assertEquals("8081", response.getPrivatePort()); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     @PrepareForTest(ApiDBUtils.class) | ||||||
|  |     public void testAutoScaleVmProfileResponse() { | ||||||
|  |         AutoScaleVmProfileVO vmProfile = new AutoScaleVmProfileVO(zoneId, domainId, accountId, serviceOfferingId, templateId, null, null, userdata, null, autoScaleUserId); | ||||||
|  |         vmProfile.setUserDataId(userdataId); | ||||||
|  |         vmProfile.setUserDataDetails(userdataDetails); | ||||||
|  | 
 | ||||||
|  |         PowerMockito.mockStatic(ApiDBUtils.class); | ||||||
|  |         when(ApiDBUtils.findAccountById(anyLong())).thenReturn(new AccountVO()); | ||||||
|  |         when(ApiDBUtils.findDomainById(anyLong())).thenReturn(new DomainVO()); | ||||||
|  | 
 | ||||||
|  |         UserData.UserDataOverridePolicy templatePolicy = UserData.UserDataOverridePolicy.APPEND; | ||||||
|  |         VMTemplateVO templateVO = Mockito.mock(VMTemplateVO.class); | ||||||
|  |         when(ApiDBUtils.findTemplateById(anyLong())).thenReturn(templateVO); | ||||||
|  |         when(templateVO.getUserDataOverridePolicy()).thenReturn(templatePolicy); | ||||||
|  | 
 | ||||||
|  |         UserDataVO userDataVO =  Mockito.mock(UserDataVO.class); | ||||||
|  |         String userDataUuid = "userDataUuid"; | ||||||
|  |         String userDataName = "userDataName"; | ||||||
|  |         when(userDataDaoMock.findById(anyLong())).thenReturn(userDataVO); | ||||||
|  |         when(userDataVO.getUuid()).thenReturn(userDataUuid); | ||||||
|  |         when(userDataVO.getName()).thenReturn(userDataName); | ||||||
|  | 
 | ||||||
|  |         AutoScaleVmProfileResponse response = apiResponseHelper.createAutoScaleVmProfileResponse(vmProfile); | ||||||
|  |         assertEquals(templatePolicy.toString(), response.getUserDataPolicy()); | ||||||
|  |         assertEquals(userdata, response.getUserData()); | ||||||
|  |         assertEquals(userDataUuid, response.getUserDataId()); | ||||||
|  |         assertEquals(userDataName, response.getUserDataName()); | ||||||
|  |         assertEquals(userdataDetails, response.getUserDataDetails()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     @PrepareForTest(ApiDBUtils.class) | ||||||
|  |     public void testAutoScaleVmProfileResponseWithoutUserData() { | ||||||
|  |         AutoScaleVmProfileVO vmProfile = new AutoScaleVmProfileVO(zoneId, domainId, accountId, serviceOfferingId, templateId, null, null, null, null, autoScaleUserId); | ||||||
|  | 
 | ||||||
|  |         PowerMockito.mockStatic(ApiDBUtils.class); | ||||||
|  |         when(ApiDBUtils.findAccountById(anyLong())).thenReturn(new AccountVO()); | ||||||
|  |         when(ApiDBUtils.findDomainById(anyLong())).thenReturn(new DomainVO()); | ||||||
|  | 
 | ||||||
|  |         VMTemplateVO templateVO = Mockito.mock(VMTemplateVO.class); | ||||||
|  |         when(ApiDBUtils.findTemplateById(anyLong())).thenReturn(templateVO); | ||||||
|  | 
 | ||||||
|  |         AutoScaleVmProfileResponse response = apiResponseHelper.createAutoScaleVmProfileResponse(vmProfile); | ||||||
|  |         assertNull(response.getUserDataPolicy()); | ||||||
|  |         assertNull(response.getUserData()); | ||||||
|  |         assertNull(response.getUserDataId()); | ||||||
|  |         assertNull(response.getUserDataName()); | ||||||
|  |         assertNull(response.getUserDataDetails()); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -47,6 +47,7 @@ import org.apache.cloudstack.affinity.dao.AffinityGroupDao; | |||||||
| import org.apache.cloudstack.annotation.AnnotationService; | import org.apache.cloudstack.annotation.AnnotationService; | ||||||
| import org.apache.cloudstack.annotation.dao.AnnotationDao; | import org.apache.cloudstack.annotation.dao.AnnotationDao; | ||||||
| import org.apache.cloudstack.api.ApiConstants; | import org.apache.cloudstack.api.ApiConstants; | ||||||
|  | import org.apache.cloudstack.api.BaseCmd; | ||||||
| import org.apache.cloudstack.api.command.admin.autoscale.CreateCounterCmd; | import org.apache.cloudstack.api.command.admin.autoscale.CreateCounterCmd; | ||||||
| import org.apache.cloudstack.api.command.user.autoscale.CreateAutoScalePolicyCmd; | import org.apache.cloudstack.api.command.user.autoscale.CreateAutoScalePolicyCmd; | ||||||
| import org.apache.cloudstack.api.command.user.autoscale.CreateAutoScaleVmGroupCmd; | import org.apache.cloudstack.api.command.user.autoscale.CreateAutoScaleVmGroupCmd; | ||||||
| @ -340,6 +341,10 @@ public class AutoScaleManagerImplTest { | |||||||
|     private static final Long scaleDownCounterId = 38L; |     private static final Long scaleDownCounterId = 38L; | ||||||
|     private static final Long nextVmSeq = 39L; |     private static final Long nextVmSeq = 39L; | ||||||
|     private static final Long networkOfferingId = 40L; |     private static final Long networkOfferingId = 40L; | ||||||
|  |     private static final String userData = "VGVzdFVzZXJEYXRh";  //TestUserData | ||||||
|  |     private static final Long userDataId = 41L; | ||||||
|  |     private static final Map<String, HashMap<String, String>> userDataDetails = new HashMap<>(); | ||||||
|  |     private static final String userDataFinal = "VGVzdFVzZXJEYXRhRmluYWw=";  //TestUserDataFinal | ||||||
| 
 | 
 | ||||||
|     @Mock |     @Mock | ||||||
|     DataCenterVO zoneMock; |     DataCenterVO zoneMock; | ||||||
| @ -404,6 +409,10 @@ public class AutoScaleManagerImplTest { | |||||||
|         Mockito.doNothing().when(accountManager).checkAccess(Mockito.any(Account.class), Mockito.isNull(), Mockito.anyBoolean(), Mockito.any()); |         Mockito.doNothing().when(accountManager).checkAccess(Mockito.any(Account.class), Mockito.isNull(), Mockito.anyBoolean(), Mockito.any()); | ||||||
| 
 | 
 | ||||||
|         when(asPolicyDao.persist(any(AutoScalePolicyVO.class))).thenReturn(asScaleUpPolicyMock); |         when(asPolicyDao.persist(any(AutoScalePolicyVO.class))).thenReturn(asScaleUpPolicyMock); | ||||||
|  | 
 | ||||||
|  |         userDataDetails.put("0", new HashMap<>() {{ put("key1", "value1"); put("key2", "value2"); }}); | ||||||
|  |         Mockito.doReturn(userDataFinal).when(userVmMgr).finalizeUserData(any(), any(), any()); | ||||||
|  |         Mockito.doReturn(userDataFinal).when(userVmMgr).validateUserData(eq(userDataFinal), nullable(BaseCmd.HTTPMethod.class)); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @After |     @After | ||||||
| @ -748,10 +757,48 @@ public class AutoScaleManagerImplTest { | |||||||
|         ReflectionTestUtils.setField(cmd, "otherDeployParams", otherDeployParams); |         ReflectionTestUtils.setField(cmd, "otherDeployParams", otherDeployParams); | ||||||
|         ReflectionTestUtils.setField(cmd, "counterParamList", counterParamList); |         ReflectionTestUtils.setField(cmd, "counterParamList", counterParamList); | ||||||
| 
 | 
 | ||||||
|  |         ReflectionTestUtils.setField(cmd, "userData", userData); | ||||||
|  |         ReflectionTestUtils.setField(cmd, "userDataId", userDataId); | ||||||
|  |         ReflectionTestUtils.setField(cmd, "userDataDetails", userDataDetails); | ||||||
|  | 
 | ||||||
|         AutoScaleVmProfile vmProfile = autoScaleManagerImplSpy.createAutoScaleVmProfile(cmd); |         AutoScaleVmProfile vmProfile = autoScaleManagerImplSpy.createAutoScaleVmProfile(cmd); | ||||||
| 
 | 
 | ||||||
|         Assert.assertEquals(asVmProfileMock, vmProfile); |         Assert.assertEquals(asVmProfileMock, vmProfile); | ||||||
|         Mockito.verify(autoScaleVmProfileDao).persist(Mockito.any()); |         Mockito.verify(autoScaleVmProfileDao).persist(Mockito.any()); | ||||||
|  | 
 | ||||||
|  |         Mockito.verify(userVmMgr).finalizeUserData(any(), any(), any()); | ||||||
|  |         Mockito.verify(userVmMgr).validateUserData(eq(userDataFinal), nullable(BaseCmd.HTTPMethod.class)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test(expected = InvalidParameterValueException.class) | ||||||
|  |     @PrepareForTest(ComponentContext.class) | ||||||
|  |     public void testCreateAutoScaleVmProfileFail() { | ||||||
|  |         when(entityManager.findById(DataCenter.class, zoneId)).thenReturn(zoneMock); | ||||||
|  |         when(entityManager.findById(ServiceOffering.class, serviceOfferingId)).thenReturn(serviceOfferingMock); | ||||||
|  |         when(entityManager.findByIdIncludingRemoved(ServiceOffering.class, serviceOfferingId)).thenReturn(serviceOfferingMock); | ||||||
|  |         when(entityManager.findById(VirtualMachineTemplate.class, templateId)).thenReturn(templateMock); | ||||||
|  |         when(serviceOfferingMock.isDynamic()).thenReturn(false); | ||||||
|  |         Mockito.doThrow(InvalidParameterValueException.class).when(userVmMgr).finalizeUserData(any(), any(), any()); | ||||||
|  | 
 | ||||||
|  |         DispatchChain dispatchChainMock = Mockito.mock(DispatchChain.class); | ||||||
|  |         when(dispatchChainFactory.getStandardDispatchChain()).thenReturn(dispatchChainMock); | ||||||
|  |         Mockito.doNothing().when(dispatchChainMock).dispatch(any()); | ||||||
|  |         PowerMockito.mockStatic(ComponentContext.class); | ||||||
|  |         when(ComponentContext.inject(DeployVMCmd.class)).thenReturn(Mockito.mock(DeployVMCmd.class)); | ||||||
|  | 
 | ||||||
|  |         CreateAutoScaleVmProfileCmd cmd = new CreateAutoScaleVmProfileCmd(); | ||||||
|  | 
 | ||||||
|  |         ReflectionTestUtils.setField(cmd, "zoneId", zoneId); | ||||||
|  |         ReflectionTestUtils.setField(cmd, "serviceOfferingId", serviceOfferingId); | ||||||
|  |         ReflectionTestUtils.setField(cmd, "templateId", templateId); | ||||||
|  |         ReflectionTestUtils.setField(cmd, "expungeVmGracePeriod", expungeVmGracePeriod); | ||||||
|  |         ReflectionTestUtils.setField(cmd, "otherDeployParams", otherDeployParams); | ||||||
|  |         ReflectionTestUtils.setField(cmd, "counterParamList", counterParamList); | ||||||
|  | 
 | ||||||
|  |         ReflectionTestUtils.setField(cmd, "userData", userData); | ||||||
|  |         ReflectionTestUtils.setField(cmd, "userDataId", userDataId); | ||||||
|  | 
 | ||||||
|  |         AutoScaleVmProfile vmProfile = autoScaleManagerImplSpy.createAutoScaleVmProfile(cmd); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Test |     @Test | ||||||
| @ -774,10 +821,17 @@ public class AutoScaleManagerImplTest { | |||||||
|         ReflectionTestUtils.setField(cmd, "serviceOfferingId", serviceOfferingId); |         ReflectionTestUtils.setField(cmd, "serviceOfferingId", serviceOfferingId); | ||||||
|         ReflectionTestUtils.setField(cmd, "templateId", templateId); |         ReflectionTestUtils.setField(cmd, "templateId", templateId); | ||||||
| 
 | 
 | ||||||
|  |         ReflectionTestUtils.setField(cmd, "userData", userData); | ||||||
|  |         ReflectionTestUtils.setField(cmd, "userDataId", userDataId); | ||||||
|  |         ReflectionTestUtils.setField(cmd, "userDataDetails", userDataDetails); | ||||||
|  | 
 | ||||||
|         AutoScaleVmProfile vmProfile = autoScaleManagerImplSpy.updateAutoScaleVmProfile(cmd); |         AutoScaleVmProfile vmProfile = autoScaleManagerImplSpy.updateAutoScaleVmProfile(cmd); | ||||||
| 
 | 
 | ||||||
|         Assert.assertEquals(asVmProfileMock, vmProfile); |         Assert.assertEquals(asVmProfileMock, vmProfile); | ||||||
|         Mockito.verify(autoScaleVmProfileDao).persist(Mockito.any()); |         Mockito.verify(autoScaleVmProfileDao).persist(Mockito.any()); | ||||||
|  | 
 | ||||||
|  |         Mockito.verify(userVmMgr).finalizeUserData(any(), any(), any()); | ||||||
|  |         Mockito.verify(userVmMgr).validateUserData(eq(userDataFinal), nullable(BaseCmd.HTTPMethod.class)); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Test |     @Test | ||||||
| @ -1208,6 +1262,9 @@ public class AutoScaleManagerImplTest { | |||||||
|         when(asVmProfileMock.getAccountId()).thenReturn(accountId); |         when(asVmProfileMock.getAccountId()).thenReturn(accountId); | ||||||
|         when(asVmProfileMock.getZoneId()).thenReturn(zoneId); |         when(asVmProfileMock.getZoneId()).thenReturn(zoneId); | ||||||
|         when(asVmProfileMock.getOtherDeployParams()).thenReturn(""); |         when(asVmProfileMock.getOtherDeployParams()).thenReturn(""); | ||||||
|  |         when(asVmProfileMock.getUserData()).thenReturn(userData); | ||||||
|  |         when(asVmProfileMock.getUserDataId()).thenReturn(userDataId); | ||||||
|  |         when(asVmProfileMock.getUserDataDetails()).thenReturn(userDataDetails.toString()); | ||||||
| 
 | 
 | ||||||
|         when(accountService.getActiveAccountById(accountId)).thenReturn(account); |         when(accountService.getActiveAccountById(accountId)).thenReturn(account); | ||||||
|         when(entityManager.findById(DataCenter.class, zoneId)).thenReturn(zoneMock); |         when(entityManager.findById(DataCenter.class, zoneId)).thenReturn(zoneMock); | ||||||
| @ -1224,7 +1281,7 @@ public class AutoScaleManagerImplTest { | |||||||
|         when(userVmMock.getId()).thenReturn(virtualMachineId); |         when(userVmMock.getId()).thenReturn(virtualMachineId); | ||||||
|         when(zoneMock.getNetworkType()).thenReturn(DataCenter.NetworkType.Basic); |         when(zoneMock.getNetworkType()).thenReturn(DataCenter.NetworkType.Basic); | ||||||
|         when(userVmService.createBasicSecurityGroupVirtualMachine(any(), any(), any(), any(), any(), any(), any(), |         when(userVmService.createBasicSecurityGroupVirtualMachine(any(), any(), any(), any(), any(), any(), any(), | ||||||
|                 any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), eq(true), any(), any(), any(), |                 any(), any(), any(), any(), any(), eq(userData), eq(userDataId), eq(userDataDetails.toString()), any(), any(), any(), eq(true), any(), any(), any(), | ||||||
|                 any(), any(), any(), any(), eq(true), any())).thenReturn(userVmMock); |                 any(), any(), any(), any(), eq(true), any())).thenReturn(userVmMock); | ||||||
| 
 | 
 | ||||||
|         long result = autoScaleManagerImplSpy.createNewVM(asVmGroupMock); |         long result = autoScaleManagerImplSpy.createNewVM(asVmGroupMock); | ||||||
| @ -1235,7 +1292,7 @@ public class AutoScaleManagerImplTest { | |||||||
|                 "-" + asVmGroupMock.getNextVmSeq() + "-[a-z]{6}"; |                 "-" + asVmGroupMock.getNextVmSeq() + "-[a-z]{6}"; | ||||||
|         Mockito.verify(userVmService).createBasicSecurityGroupVirtualMachine(any(), any(), any(), any(), any(), |         Mockito.verify(userVmService).createBasicSecurityGroupVirtualMachine(any(), any(), any(), any(), any(), | ||||||
|                 matches(vmHostNamePattern), matches(vmHostNamePattern), |                 matches(vmHostNamePattern), matches(vmHostNamePattern), | ||||||
|                 any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), eq(true), any(), any(), any(), |                 any(), any(), any(), any(), any(), eq(userData), eq(userDataId), eq(userDataDetails.toString()), any(), any(), any(), eq(true), any(), any(), any(), | ||||||
|                 any(), any(), any(), any(), eq(true), any()); |                 any(), any(), any(), any(), eq(true), any()); | ||||||
|         Mockito.verify(asVmGroupMock).setNextVmSeq(nextVmSeq + 1); |         Mockito.verify(asVmGroupMock).setNextVmSeq(nextVmSeq + 1); | ||||||
|     } |     } | ||||||
| @ -1253,6 +1310,9 @@ public class AutoScaleManagerImplTest { | |||||||
|         when(asVmProfileMock.getAccountId()).thenReturn(accountId); |         when(asVmProfileMock.getAccountId()).thenReturn(accountId); | ||||||
|         when(asVmProfileMock.getZoneId()).thenReturn(zoneId); |         when(asVmProfileMock.getZoneId()).thenReturn(zoneId); | ||||||
|         when(asVmProfileMock.getOtherDeployParams()).thenReturn(""); |         when(asVmProfileMock.getOtherDeployParams()).thenReturn(""); | ||||||
|  |         when(asVmProfileMock.getUserData()).thenReturn(userData); | ||||||
|  |         when(asVmProfileMock.getUserDataId()).thenReturn(userDataId); | ||||||
|  |         when(asVmProfileMock.getUserDataDetails()).thenReturn(userDataDetails.toString()); | ||||||
| 
 | 
 | ||||||
|         when(accountService.getActiveAccountById(accountId)).thenReturn(account); |         when(accountService.getActiveAccountById(accountId)).thenReturn(account); | ||||||
|         when(entityManager.findById(DataCenter.class, zoneId)).thenReturn(zoneMock); |         when(entityManager.findById(DataCenter.class, zoneId)).thenReturn(zoneMock); | ||||||
| @ -1270,7 +1330,7 @@ public class AutoScaleManagerImplTest { | |||||||
|         when(zoneMock.getNetworkType()).thenReturn(DataCenter.NetworkType.Advanced); |         when(zoneMock.getNetworkType()).thenReturn(DataCenter.NetworkType.Advanced); | ||||||
|         when(zoneMock.isSecurityGroupEnabled()).thenReturn(true); |         when(zoneMock.isSecurityGroupEnabled()).thenReturn(true); | ||||||
|         when(userVmService.createAdvancedSecurityGroupVirtualMachine(any(), any(), any(), any(), any(), any(), any(), |         when(userVmService.createAdvancedSecurityGroupVirtualMachine(any(), any(), any(), any(), any(), any(), any(), | ||||||
|                 any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), |                 any(), any(), any(), any(), any(), any(), eq(userData), eq(userDataId), eq(userDataDetails.toString()), any(), any(), any(), any(), any(), any(), | ||||||
|                 any(), any(), any(), any(), any(), eq(true), any(), any())).thenReturn(userVmMock); |                 any(), any(), any(), any(), any(), eq(true), any(), any())).thenReturn(userVmMock); | ||||||
| 
 | 
 | ||||||
|         long result = autoScaleManagerImplSpy.createNewVM(asVmGroupMock); |         long result = autoScaleManagerImplSpy.createNewVM(asVmGroupMock); | ||||||
| @ -1281,7 +1341,7 @@ public class AutoScaleManagerImplTest { | |||||||
|                 "-" + asVmGroupMock.getNextVmSeq() + "-[a-z]{6}"; |                 "-" + asVmGroupMock.getNextVmSeq() + "-[a-z]{6}"; | ||||||
|         Mockito.verify(userVmService).createAdvancedSecurityGroupVirtualMachine(any(), any(), any(), any(), any(), any(), |         Mockito.verify(userVmService).createAdvancedSecurityGroupVirtualMachine(any(), any(), any(), any(), any(), any(), | ||||||
|                 matches(vmHostNamePattern), matches(vmHostNamePattern), |                 matches(vmHostNamePattern), matches(vmHostNamePattern), | ||||||
|                 any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), |                 any(), any(), any(), any(), any(), eq(userData), eq(userDataId), eq(userDataDetails.toString()), any(), any(), any(), any(), any(), any(), | ||||||
|                 any(), any(), any(), any(), any(), eq(true), any(), any()); |                 any(), any(), any(), any(), any(), eq(true), any(), any()); | ||||||
|         Mockito.verify(asVmGroupMock).setNextVmSeq(nextVmSeq + 2); |         Mockito.verify(asVmGroupMock).setNextVmSeq(nextVmSeq + 2); | ||||||
|     } |     } | ||||||
| @ -1299,6 +1359,9 @@ public class AutoScaleManagerImplTest { | |||||||
|         when(asVmProfileMock.getAccountId()).thenReturn(accountId); |         when(asVmProfileMock.getAccountId()).thenReturn(accountId); | ||||||
|         when(asVmProfileMock.getZoneId()).thenReturn(zoneId); |         when(asVmProfileMock.getZoneId()).thenReturn(zoneId); | ||||||
|         when(asVmProfileMock.getOtherDeployParams()).thenReturn(""); |         when(asVmProfileMock.getOtherDeployParams()).thenReturn(""); | ||||||
|  |         when(asVmProfileMock.getUserData()).thenReturn(userData); | ||||||
|  |         when(asVmProfileMock.getUserDataId()).thenReturn(userDataId); | ||||||
|  |         when(asVmProfileMock.getUserDataDetails()).thenReturn(userDataDetails.toString()); | ||||||
| 
 | 
 | ||||||
|         when(accountService.getActiveAccountById(accountId)).thenReturn(account); |         when(accountService.getActiveAccountById(accountId)).thenReturn(account); | ||||||
|         when(entityManager.findById(DataCenter.class, zoneId)).thenReturn(zoneMock); |         when(entityManager.findById(DataCenter.class, zoneId)).thenReturn(zoneMock); | ||||||
| @ -1316,7 +1379,7 @@ public class AutoScaleManagerImplTest { | |||||||
|         when(zoneMock.getNetworkType()).thenReturn(DataCenter.NetworkType.Advanced); |         when(zoneMock.getNetworkType()).thenReturn(DataCenter.NetworkType.Advanced); | ||||||
|         when(zoneMock.isSecurityGroupEnabled()).thenReturn(false); |         when(zoneMock.isSecurityGroupEnabled()).thenReturn(false); | ||||||
|         when(userVmService.createAdvancedVirtualMachine(any(), any(), any(), any(), any(), any(), any(), |         when(userVmService.createAdvancedVirtualMachine(any(), any(), any(), any(), any(), any(), any(), | ||||||
|                 any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), eq(true), any(), any(), any(), |                 any(), any(), any(), any(), any(), eq(userData), eq(userDataId), eq(userDataDetails.toString()), any(), any(), any(), eq(true), any(), any(), any(), | ||||||
|                 any(), any(), any(), any(), eq(true), any(), any())).thenReturn(userVmMock); |                 any(), any(), any(), any(), eq(true), any(), any())).thenReturn(userVmMock); | ||||||
| 
 | 
 | ||||||
|         long result = autoScaleManagerImplSpy.createNewVM(asVmGroupMock); |         long result = autoScaleManagerImplSpy.createNewVM(asVmGroupMock); | ||||||
| @ -1327,7 +1390,7 @@ public class AutoScaleManagerImplTest { | |||||||
|                 "-" + asVmGroupMock.getNextVmSeq() + "-[a-z]{6}"; |                 "-" + asVmGroupMock.getNextVmSeq() + "-[a-z]{6}"; | ||||||
|         Mockito.verify(userVmService).createAdvancedVirtualMachine(any(), any(), any(), any(), any(), |         Mockito.verify(userVmService).createAdvancedVirtualMachine(any(), any(), any(), any(), any(), | ||||||
|                 matches(vmHostNamePattern), matches(vmHostNamePattern), |                 matches(vmHostNamePattern), matches(vmHostNamePattern), | ||||||
|                 any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), eq(true), any(), any(), any(), |                 any(), any(), any(), any(), any(), eq(userData), eq(userDataId), eq(userDataDetails.toString()), any(), any(), any(), eq(true), any(), any(), any(), | ||||||
|                 any(), any(), any(), any(), eq(true), any(), any()); |                 any(), any(), any(), any(), eq(true), any(), any()); | ||||||
|         Mockito.verify(asVmGroupMock).setNextVmSeq(nextVmSeq + 3); |         Mockito.verify(asVmGroupMock).setNextVmSeq(nextVmSeq + 3); | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -38,6 +38,7 @@ from marvin.lib.base import (Account, | |||||||
|                              Domain, |                              Domain, | ||||||
|                              Project, |                              Project, | ||||||
|                              ServiceOffering, |                              ServiceOffering, | ||||||
|  |                              Template, | ||||||
|                              VirtualMachine, |                              VirtualMachine, | ||||||
|                              Volume, |                              Volume, | ||||||
|                              Zone, |                              Zone, | ||||||
| @ -47,6 +48,7 @@ from marvin.lib.base import (Account, | |||||||
|                              LoadBalancerRule, |                              LoadBalancerRule, | ||||||
|                              VPC, |                              VPC, | ||||||
|                              VpcOffering, |                              VpcOffering, | ||||||
|  |                              UserData, | ||||||
|                              SSHKeyPair) |                              SSHKeyPair) | ||||||
| 
 | 
 | ||||||
| from marvin.lib.common import (get_domain, | from marvin.lib.common import (get_domain, | ||||||
| @ -198,6 +200,37 @@ class TestVmAutoScaling(cloudstackTestCase): | |||||||
|             name="keypair2" |             name="keypair2" | ||||||
|         ) |         ) | ||||||
| 
 | 
 | ||||||
|  |         # 8-2. Register userdata | ||||||
|  |         cls.apiUserdata = UserData.register( | ||||||
|  |             cls.apiclient, | ||||||
|  |             name="ApiUserdata", | ||||||
|  |             userdata="QVBJdXNlcmRhdGE=", #APIuserdata | ||||||
|  |             account=cls.regular_user.name, | ||||||
|  |             domainid=cls.regular_user.domainid | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  |         # 8-3. Register userdata for template | ||||||
|  |         cls.templateUserdata = UserData.register( | ||||||
|  |             cls.apiclient, | ||||||
|  |             name="TemplateUserdata", | ||||||
|  |             userdata="IyMgdGVtcGxhdGU6IGppbmphCiNjbG91ZC1jb25maWcKcnVuY21kOgogICAgLSBlY2hvICdrZXkge3sgZHMubWV0YV9kYXRhLmtleTEgfX0nID4+IC9yb290L2luc3RhbmNlX21ldGFkYXRhCgo=", | ||||||
|  |             #    ## template: jinja | ||||||
|  |             #    #cloud-config | ||||||
|  |             #    runcmd: | ||||||
|  |             #        - echo 'key {{ ds.meta_data.key1 }}' >> /root/instance_metadata | ||||||
|  |             # | ||||||
|  |             account=cls.regular_user.name, | ||||||
|  |             domainid=cls.regular_user.domainid | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  |         # 8-3. Link userdata to template | ||||||
|  |         cls.template = Template.linkUserDataToTemplate( | ||||||
|  |             cls.apiclient, | ||||||
|  |             templateid=cls.template.id, | ||||||
|  |             userdataid=cls.templateUserdata.userdata.id, | ||||||
|  |             userdatapolicy="append" | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|         # 9. Get counters for cpu and memory |         # 9. Get counters for cpu and memory | ||||||
|         counters = Autoscale.listCounters( |         counters = Autoscale.listCounters( | ||||||
|             cls.regular_user_apiclient, |             cls.regular_user_apiclient, | ||||||
| @ -294,6 +327,7 @@ class TestVmAutoScaling(cloudstackTestCase): | |||||||
|             serviceofferingid=cls.service_offering.id, |             serviceofferingid=cls.service_offering.id, | ||||||
|             zoneid=cls.zone.id, |             zoneid=cls.zone.id, | ||||||
|             templateid=cls.template.id, |             templateid=cls.template.id, | ||||||
|  |             userdata="VGVzdFVzZXJEYXRh", #TestUserData | ||||||
|             expungevmgraceperiod=DEFAULT_EXPUNGE_VM_GRACE_PERIOD, |             expungevmgraceperiod=DEFAULT_EXPUNGE_VM_GRACE_PERIOD, | ||||||
|             otherdeployparams=cls.otherdeployparams |             otherdeployparams=cls.otherdeployparams | ||||||
|         ) |         ) | ||||||
| @ -349,6 +383,10 @@ class TestVmAutoScaling(cloudstackTestCase): | |||||||
| 
 | 
 | ||||||
|     @classmethod |     @classmethod | ||||||
|     def tearDownClass(cls): |     def tearDownClass(cls): | ||||||
|  |         cls.template = Template.linkUserDataToTemplate( | ||||||
|  |             cls.apiclient, | ||||||
|  |             templateid=cls.template.id | ||||||
|  |         ) | ||||||
|         Configurations.update(cls.apiclient, |         Configurations.update(cls.apiclient, | ||||||
|                               CONFIG_NAME_DISK_CONTROLLER, |                               CONFIG_NAME_DISK_CONTROLLER, | ||||||
|                               cls.initial_vmware_root_disk_controller) |                               cls.initial_vmware_root_disk_controller) | ||||||
| @ -390,6 +428,7 @@ class TestVmAutoScaling(cloudstackTestCase): | |||||||
|             self.regular_user_apiclient, |             self.regular_user_apiclient, | ||||||
|             autoscalevmgroupid=autoscalevmgroupid, |             autoscalevmgroupid=autoscalevmgroupid, | ||||||
|             projectid=projectid, |             projectid=projectid, | ||||||
|  |             userdata=True, | ||||||
|             listall=True |             listall=True | ||||||
|         ) |         ) | ||||||
|         self.assertEqual( |         self.assertEqual( | ||||||
| @ -505,6 +544,31 @@ class TestVmAutoScaling(cloudstackTestCase): | |||||||
|         else: |         else: | ||||||
|             self.assertEquals(affinitygroupids, '') |             self.assertEquals(affinitygroupids, '') | ||||||
| 
 | 
 | ||||||
|  |         userdata = None | ||||||
|  |         userdatadetails = None | ||||||
|  |         userdataid = None | ||||||
|  |         if vm.userdata: | ||||||
|  |             userdata = vm.userdata | ||||||
|  |         if vm.userdatadetails: | ||||||
|  |             userdatadetails = vm.userdatadetails | ||||||
|  |         if vm.userdataid: | ||||||
|  |             userdataid = vm.userdataid | ||||||
|  | 
 | ||||||
|  |         if vmprofile.userdataid: | ||||||
|  |             self.assertEquals(userdataid, vmprofile.userdataid) | ||||||
|  |         else: | ||||||
|  |             self.assertIsNone(userdataid) | ||||||
|  | 
 | ||||||
|  |         if vmprofile.userdatadetails: | ||||||
|  |             self.assertEquals(userdatadetails, vmprofile.userdatadetails) | ||||||
|  |         else: | ||||||
|  |             self.assertIsNone(userdatadetails) | ||||||
|  | 
 | ||||||
|  |         if vmprofile.userdata: | ||||||
|  |             self.assertEquals(userdata, vmprofile.userdata) | ||||||
|  |         else: | ||||||
|  |             self.assertIsNone(userdata) | ||||||
|  | 
 | ||||||
|     def wait_for_vm_start(self, vm=None, project_id=None): |     def wait_for_vm_start(self, vm=None, project_id=None): | ||||||
|         """ Wait until vm is Running """ |         """ Wait until vm is Running """ | ||||||
|         def check_user_vm_state(): |         def check_user_vm_state(): | ||||||
| @ -512,6 +576,7 @@ class TestVmAutoScaling(cloudstackTestCase): | |||||||
|                 self.apiclient, |                 self.apiclient, | ||||||
|                 id=vm.id, |                 id=vm.id, | ||||||
|                 projectid=project_id, |                 projectid=project_id, | ||||||
|  |                 userdata=True, | ||||||
|                 listall=True |                 listall=True | ||||||
|             ) |             ) | ||||||
|             if isinstance(vms, list): |             if isinstance(vms, list): | ||||||
| @ -576,6 +641,8 @@ class TestVmAutoScaling(cloudstackTestCase): | |||||||
|             Autoscale.updateAutoscaleVMProfile( |             Autoscale.updateAutoscaleVMProfile( | ||||||
|                 self.regular_user_apiclient, |                 self.regular_user_apiclient, | ||||||
|                 id = self.autoscaling_vmprofile.id, |                 id = self.autoscaling_vmprofile.id, | ||||||
|  |                 userdataid=self.apiUserdata.userdata.id, | ||||||
|  |                 userdatadetails=[{"key1": "value2"}], | ||||||
|                 serviceofferingid = self.service_offering_new.id, |                 serviceofferingid = self.service_offering_new.id, | ||||||
|                 expungevmgraceperiod = DEFAULT_EXPUNGE_VM_GRACE_PERIOD + 1, |                 expungevmgraceperiod = DEFAULT_EXPUNGE_VM_GRACE_PERIOD + 1, | ||||||
|                 otherdeployparams = otherdeployparams_new |                 otherdeployparams = otherdeployparams_new | ||||||
| @ -712,6 +779,7 @@ class TestVmAutoScaling(cloudstackTestCase): | |||||||
|         vms = VirtualMachine.list( |         vms = VirtualMachine.list( | ||||||
|             self.regular_user_apiclient, |             self.regular_user_apiclient, | ||||||
|             autoscalevmgroupid=self.autoscaling_vmgroup.id, |             autoscalevmgroupid=self.autoscaling_vmgroup.id, | ||||||
|  |             userdata=True, | ||||||
|             listall=True |             listall=True | ||||||
|         ) |         ) | ||||||
|         self.assertEqual( |         self.assertEqual( | ||||||
| @ -889,6 +957,7 @@ class TestVmAutoScaling(cloudstackTestCase): | |||||||
|             self.regular_user_apiclient, |             self.regular_user_apiclient, | ||||||
|             autoscalevmgroupid=autoscaling_vmgroup_project.id, |             autoscalevmgroupid=autoscaling_vmgroup_project.id, | ||||||
|             projectid=project.id, |             projectid=project.id, | ||||||
|  |             userdata=True, | ||||||
|             listall=True |             listall=True | ||||||
|         ) |         ) | ||||||
|         self.assertEqual( |         self.assertEqual( | ||||||
|  | |||||||
| @ -1625,6 +1625,7 @@ | |||||||
| "label.reset.config.value": "Reset to default value", | "label.reset.config.value": "Reset to default value", | ||||||
| "label.reset.ssh.key.pair": "Reset SSH key pair", | "label.reset.ssh.key.pair": "Reset SSH key pair", | ||||||
| "label.reset.to.default": "Reset to default", | "label.reset.to.default": "Reset to default", | ||||||
|  | "label.reset.userdata.on.autoscale.vm.group": "Reset Userdata on AutoScale VM Group", | ||||||
| "label.reset.userdata.on.vm": "Reset Userdata on VM", | "label.reset.userdata.on.vm": "Reset Userdata on VM", | ||||||
| "label.reset.vpn.connection": "Reset VPN connection", | "label.reset.vpn.connection": "Reset VPN connection", | ||||||
| "label.resource": "Resource", | "label.resource": "Resource", | ||||||
|  | |||||||
| @ -69,6 +69,47 @@ | |||||||
|           {{ getServiceOfferingName(serviceofferingid) }} |           {{ getServiceOfferingName(serviceofferingid) }} | ||||||
|         </div> |         </div> | ||||||
|       </div> |       </div> | ||||||
|  |       <div class="form" v-if="userdataid"> | ||||||
|  |         <div class="form__item"> | ||||||
|  |           <div class="form__label"> | ||||||
|  |             <tooltip-label :title="$t('label.userdataid')"/> | ||||||
|  |           </div> | ||||||
|  |           {{ userdataid }} | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |       <div class="form" v-if="userdataname"> | ||||||
|  |         <div class="form__item"> | ||||||
|  |           <div class="form__label"> | ||||||
|  |             <tooltip-label :title="$t('label.userdataname')"/> | ||||||
|  |           </div> | ||||||
|  |           {{ userdataname }} | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |       <div class="form" v-if="userdatadetails"> | ||||||
|  |         <div class="form__item"> | ||||||
|  |           <div class="form__label"> | ||||||
|  |             <tooltip-label :title="$t('label.userdatadetails')"/> | ||||||
|  |           </div> | ||||||
|  |           {{ userdatadetails }} | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |       <div class="form" v-if="userdatapolicy"> | ||||||
|  |         <div class="form__item"> | ||||||
|  |           <div class="form__label"> | ||||||
|  |             <tooltip-label :title="$t('label.userdatapolicy')"/> | ||||||
|  |           </div> | ||||||
|  |           {{ userdatapolicy }} | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|  |       <div class="form"> | ||||||
|  |         <div class="form__item"> | ||||||
|  |           <div class="form__label"> | ||||||
|  |             <tooltip-label :title="$t('label.userdata')" :tooltip="createAutoScaleVmProfileApiParams.userdata.description"/> | ||||||
|  |           </div> | ||||||
|  |           <a-textarea v-model:value="userdata" rows="5" :disabled="true"> | ||||||
|  |           </a-textarea> | ||||||
|  |         </div> | ||||||
|  |       </div> | ||||||
|       <div class="form"> |       <div class="form"> | ||||||
|         <div class="form__item"> |         <div class="form__item"> | ||||||
|           <a-button ref="submit" :disabled="!('updateAutoScaleVmProfile' in $store.getters.apis) || resource.state !== 'DISABLED'" type="primary" @click="editProfileModalVisible = true"> |           <a-button ref="submit" :disabled="!('updateAutoScaleVmProfile' in $store.getters.apis) || resource.state !== 'DISABLED'" type="primary" @click="editProfileModalVisible = true"> | ||||||
| @ -76,6 +117,12 @@ | |||||||
|             {{ $t('label.edit.autoscale.vmprofile') }} |             {{ $t('label.edit.autoscale.vmprofile') }} | ||||||
|           </a-button> |           </a-button> | ||||||
|         </div> |         </div> | ||||||
|  |         <div class="form__item"> | ||||||
|  |           <a-button ref="submit" :disabled="!('updateAutoScaleVmProfile' in $store.getters.apis) || resource.state !== 'DISABLED'" type="primary" @click="showUpdateUserDataForm = true"> | ||||||
|  |             <template #icon><solution-outlined /></template> | ||||||
|  |             {{ $t('label.reset.userdata.on.autoscale.vm.group') }} | ||||||
|  |           </a-button> | ||||||
|  |         </div> | ||||||
|       </div> |       </div> | ||||||
| 
 | 
 | ||||||
|       <a-divider/> |       <a-divider/> | ||||||
| @ -224,20 +271,26 @@ | |||||||
|           </a-select> |           </a-select> | ||||||
|         </div> |         </div> | ||||||
|       </div> |       </div> | ||||||
|       <div class="form"> |  | ||||||
|         <div class="form__item"> |  | ||||||
|           <div class="form__label"> |  | ||||||
|             <tooltip-label :title="$t('label.userdata')" :tooltip="createAutoScaleVmProfileApiParams.userdata.description"/> |  | ||||||
|           </div> |  | ||||||
|           <a-textarea v-model:value="userdata"> |  | ||||||
|           </a-textarea> |  | ||||||
|         </div> |  | ||||||
|       </div> |  | ||||||
|       <div :span="24" class="action-button"> |       <div :span="24" class="action-button"> | ||||||
|         <a-button :loading="loading" @click="closeModal">{{ $t('label.cancel') }}</a-button> |         <a-button :loading="loading" @click="closeModal">{{ $t('label.cancel') }}</a-button> | ||||||
|         <a-button :loading="loading" ref="submit" type="primary" @click="updateAutoScaleVmProfile">{{ $t('label.ok') }}</a-button> |         <a-button :loading="loading" ref="submit" type="primary" @click="updateAutoScaleVmProfile">{{ $t('label.ok') }}</a-button> | ||||||
|       </div> |       </div> | ||||||
|     </a-modal> |     </a-modal> | ||||||
|  | 
 | ||||||
|  |     <a-modal | ||||||
|  |       :visible="showUpdateUserDataForm" | ||||||
|  |       :title="$t('label.reset.userdata.on.autoscale.vm.group')" | ||||||
|  |       :closable="true" | ||||||
|  |       :maskClosable="false" | ||||||
|  |       :footer="null" | ||||||
|  |       @cancel="showUpdateUserDataForm = false" | ||||||
|  |       centered | ||||||
|  |       width="auto"> | ||||||
|  |       <reset-user-data | ||||||
|  |         :resource="{ ...resource, ...{ resetUserDataApiName: 'updateAutoScaleVmProfile', resetUserDataResourceId: this.resource.vmprofileid, templateid: this.templateid}}" | ||||||
|  |         @close-action="showUpdateUserDataForm = false" | ||||||
|  |       /> | ||||||
|  |     </a-modal> | ||||||
|   </div> |   </div> | ||||||
| </template> | </template> | ||||||
| 
 | 
 | ||||||
| @ -247,10 +300,12 @@ import { isAdmin, isAdminOrDomainAdmin } from '@/role' | |||||||
| import Status from '@/components/widgets/Status' | import Status from '@/components/widgets/Status' | ||||||
| import TooltipButton from '@/components/widgets/TooltipButton' | import TooltipButton from '@/components/widgets/TooltipButton' | ||||||
| import TooltipLabel from '@/components/widgets/TooltipLabel' | import TooltipLabel from '@/components/widgets/TooltipLabel' | ||||||
|  | import ResetUserData from '@views/compute/ResetUserData' | ||||||
| 
 | 
 | ||||||
| export default { | export default { | ||||||
|   name: 'conditionsTab', |   name: 'conditionsTab', | ||||||
|   components: { |   components: { | ||||||
|  |     ResetUserData, | ||||||
|     Status, |     Status, | ||||||
|     TooltipButton, |     TooltipButton, | ||||||
|     TooltipLabel |     TooltipLabel | ||||||
| @ -266,12 +321,17 @@ export default { | |||||||
|       filterColumns: ['Action'], |       filterColumns: ['Action'], | ||||||
|       loading: true, |       loading: true, | ||||||
|       editProfileModalVisible: false, |       editProfileModalVisible: false, | ||||||
|  |       showUpdateUserDataForm: false, | ||||||
|       profileid: null, |       profileid: null, | ||||||
|       autoscaleuserid: null, |       autoscaleuserid: null, | ||||||
|       expungevmgraceperiod: null, |       expungevmgraceperiod: null, | ||||||
|       templateid: null, |       templateid: null, | ||||||
|       serviceofferingid: null, |       serviceofferingid: null, | ||||||
|       userdata: null, |       userdata: null, | ||||||
|  |       userdataid: null, | ||||||
|  |       userdataname: null, | ||||||
|  |       userdatadetails: null, | ||||||
|  |       userdatapolicy: null, | ||||||
|       usersList: [], |       usersList: [], | ||||||
|       templatesList: [], |       templatesList: [], | ||||||
|       serviceOfferingsList: [], |       serviceOfferingsList: [], | ||||||
| @ -384,6 +444,11 @@ export default { | |||||||
|         this.serviceofferingid = response.listautoscalevmprofilesresponse?.autoscalevmprofile?.[0]?.serviceofferingid |         this.serviceofferingid = response.listautoscalevmprofilesresponse?.autoscalevmprofile?.[0]?.serviceofferingid | ||||||
|         this.templateid = response.listautoscalevmprofilesresponse?.autoscalevmprofile?.[0]?.templateid |         this.templateid = response.listautoscalevmprofilesresponse?.autoscalevmprofile?.[0]?.templateid | ||||||
|         this.userdata = this.decodeUserData(decodeURIComponent(response.listautoscalevmprofilesresponse?.autoscalevmprofile?.[0]?.userdata || '')) |         this.userdata = this.decodeUserData(decodeURIComponent(response.listautoscalevmprofilesresponse?.autoscalevmprofile?.[0]?.userdata || '')) | ||||||
|  |         this.userdataid = response.listautoscalevmprofilesresponse?.autoscalevmprofile?.[0]?.userdataid | ||||||
|  |         this.userdataname = response.listautoscalevmprofilesresponse?.autoscalevmprofile?.[0]?.userdataname | ||||||
|  |         this.userdatadetails = response.listautoscalevmprofilesresponse?.autoscalevmprofile?.[0]?.userdatadetails | ||||||
|  |         this.userdatapolicy = response.listautoscalevmprofilesresponse?.autoscalevmprofile?.[0]?.userdatapolicy | ||||||
|  | 
 | ||||||
|         const counterparam = response.listautoscalevmprofilesresponse?.autoscalevmprofile?.[0]?.counterparam || {} |         const counterparam = response.listautoscalevmprofilesresponse?.autoscalevmprofile?.[0]?.counterparam || {} | ||||||
|         const otherdeployparams = response.listautoscalevmprofilesresponse?.autoscalevmprofile?.[0]?.otherdeployparams || {} |         const otherdeployparams = response.listautoscalevmprofilesresponse?.autoscalevmprofile?.[0]?.otherdeployparams || {} | ||||||
|         this.finalizeParams(counterparam, otherdeployparams) |         this.finalizeParams(counterparam, otherdeployparams) | ||||||
| @ -518,13 +583,10 @@ export default { | |||||||
|       if (this.autoscaleuserid) { |       if (this.autoscaleuserid) { | ||||||
|         params.autoscaleuserid = this.autoscaleuserid |         params.autoscaleuserid = this.autoscaleuserid | ||||||
|       } |       } | ||||||
|       if (this.userdata && this.userdata.length > 0) { |  | ||||||
|         params.userdata = this.$toBase64AndURIEncoded(this.userdata) |  | ||||||
|       } |  | ||||||
| 
 | 
 | ||||||
|       const httpMethod = params.userdata ? 'POST' : 'GET' |       const httpMethod = 'GET' | ||||||
|       const args = httpMethod === 'POST' ? {} : params |       const args = params | ||||||
|       const data = httpMethod === 'POST' ? params : {} |       const data = {} | ||||||
| 
 | 
 | ||||||
|       api('updateAutoScaleVmProfile', args, httpMethod, data).then(response => { |       api('updateAutoScaleVmProfile', args, httpMethod, data).then(response => { | ||||||
|         this.$pollJob({ |         this.$pollJob({ | ||||||
|  | |||||||
| @ -407,7 +407,7 @@ | |||||||
| 
 | 
 | ||||||
|                         <span v-if="property.type && property.type==='boolean'"> |                         <span v-if="property.type && property.type==='boolean'"> | ||||||
|                           <a-switch |                           <a-switch | ||||||
|                             v-model:cheked="form['properties.' + escapePropertyKey(property.key)]" |                             v-model:checked="form['properties.' + escapePropertyKey(property.key)]" | ||||||
|                             :placeholder="property.description" |                             :placeholder="property.description" | ||||||
|                           /> |                           /> | ||||||
|                         </span> |                         </span> | ||||||
| @ -760,15 +760,102 @@ | |||||||
|                         @select-affinity-group-item="($event) => updateAffinityGroups($event)" |                         @select-affinity-group-item="($event) => updateAffinityGroups($event)" | ||||||
|                         @handle-search-filter="($event) => handleSearchFilter('affinityGroups', $event)"/> |                         @handle-search-filter="($event) => handleSearchFilter('affinityGroups', $event)"/> | ||||||
|                     </a-form-item> |                     </a-form-item> | ||||||
|                     <a-form-item name="userdata" ref="userdata"> |                     <a-form-item> | ||||||
|                       <template #label> |                       <template #label> | ||||||
|                         <tooltip-label :title="$t('label.userdata')" :tooltip="createAutoScaleVmProfileApiParams.userdata.description"/> |                         <tooltip-label :title="$t('label.userdata')" :tooltip="createAutoScaleVmProfileApiParams.userdata.description"/> | ||||||
|                       </template> |                       </template> | ||||||
|  |                       <a-card> | ||||||
|  |                         <div v-if="this.template && this.template.userdataid"> | ||||||
|  |                           <a-text type="primary"> | ||||||
|  |                             Userdata "{{ $t(this.template.userdataname) }}" is linked with template "{{ $t(this.template.name) }}" with override policy "{{ $t(this.template.userdatapolicy) }}" | ||||||
|  |                           </a-text><br/><br/> | ||||||
|  |                           <div v-if="templateUserDataParams.length > 0 && !doUserdataOverride"> | ||||||
|  |                             <a-text type="primary" v-if="this.template && this.template.userdataid && templateUserDataParams.length > 0"> | ||||||
|  |                               Enter the values for the variables in userdata | ||||||
|  |                             </a-text> | ||||||
|  |                             <a-input-group> | ||||||
|  |                               <a-table | ||||||
|  |                                 size="small" | ||||||
|  |                                 style="overflow-y: auto" | ||||||
|  |                                 :columns="userDataParamCols" | ||||||
|  |                                 :dataSource="templateUserDataParams" | ||||||
|  |                                 :pagination="false" | ||||||
|  |                                 :rowKey="record => record.key"> | ||||||
|  |                                 <template #value="{ record }"> | ||||||
|  |                                   <a-input v-model:value="templateUserDataValues[record.key]" /> | ||||||
|  |                                 </template> | ||||||
|  |                               </a-table> | ||||||
|  |                             </a-input-group> | ||||||
|  |                           </div> | ||||||
|  |                         </div><br/><br/> | ||||||
|  |                         <div v-if="userdataDefaultOverridePolicy === 'ALLOWOVERRIDE' || userdataDefaultOverridePolicy === 'APPEND' || !userdataDefaultOverridePolicy"> | ||||||
|  |                           <span v-if="userdataDefaultOverridePolicy === 'ALLOWOVERRIDE'" > | ||||||
|  |                             {{ $t('label.userdata.do.override') }} | ||||||
|  |                             <a-switch v-model:checked="doUserdataOverride" style="margin-left: 10px"/> | ||||||
|  |                           </span> | ||||||
|  |                           <span v-if="userdataDefaultOverridePolicy === 'APPEND'"> | ||||||
|  |                             {{ $t('label.userdata.do.append') }} | ||||||
|  |                             <a-switch v-model:checked="doUserdataAppend" style="margin-left: 10px"/> | ||||||
|  |                           </span> | ||||||
|  |                           <a-step | ||||||
|  |                             :status="zoneSelected ? 'process' : 'wait'"> | ||||||
|  |                             <template #description> | ||||||
|  |                               <div v-if="doUserdataOverride || doUserdataAppend || !userdataDefaultOverridePolicy" style="margin-top: 15px"> | ||||||
|  |                                 <a-card | ||||||
|  |                                   :tabList="userdataTabList" | ||||||
|  |                                   :activeTabKey="userdataTabKey" | ||||||
|  |                                   @tabChange="key => onUserdataTabChange(key, 'userdataTabKey')"> | ||||||
|  |                                   <div v-if="userdataTabKey === 'userdataregistered'"> | ||||||
|  |                                     <a-step | ||||||
|  |                                       v-if="isUserAllowedToListUserDatas" | ||||||
|  |                                       :status="zoneSelected ? 'process' : 'wait'"> | ||||||
|  |                                       <template #description> | ||||||
|  |                                         <div v-if="zoneSelected"> | ||||||
|  |                                           <user-data-selection | ||||||
|  |                                             :items="options.userDatas" | ||||||
|  |                                             :row-count="rowCount.userDatas" | ||||||
|  |                                             :zoneId="zoneId" | ||||||
|  |                                             :disabled="template.userdatapolicy === 'DENYOVERRIDE'" | ||||||
|  |                                             :loading="loading.userDatas" | ||||||
|  |                                             :preFillContent="dataPreFill" | ||||||
|  |                                             @select-user-data-item="($event) => updateUserData($event)" | ||||||
|  |                                             @handle-search-filter="($event) => handleSearchFilter('userData', $event)" | ||||||
|  |                                           /> | ||||||
|  |                                           <div v-if="userDataParams.length > 0"> | ||||||
|  |                                             <a-input-group> | ||||||
|  |                                               <a-table | ||||||
|  |                                                 size="small" | ||||||
|  |                                                 style="overflow-y: auto" | ||||||
|  |                                                 :columns="userDataParamCols" | ||||||
|  |                                                 :dataSource="userDataParams" | ||||||
|  |                                                 :pagination="false" | ||||||
|  |                                                 :rowKey="record => record.key"> | ||||||
|  |                                                 <template #value="{ record }"> | ||||||
|  |                                                   <a-input v-model:value="userDataValues[record.key]" /> | ||||||
|  |                                                 </template> | ||||||
|  |                                               </a-table> | ||||||
|  |                                             </a-input-group> | ||||||
|  |                                           </div> | ||||||
|  |                                         </div> | ||||||
|  |                                       </template> | ||||||
|  |                                     </a-step> | ||||||
|  |                                   </div> | ||||||
|  |                                   <div v-else> | ||||||
|  |                                     <a-form-item name="userdata" ref="userdata" > | ||||||
|                                       <a-textarea |                                       <a-textarea | ||||||
|  |                                         placeholder="Userdata" | ||||||
|                                         v-model:value="form.userdata"> |                                         v-model:value="form.userdata"> | ||||||
|                                       </a-textarea> |                                       </a-textarea> | ||||||
|                                     </a-form-item> |                                     </a-form-item> | ||||||
|                                   </div> |                                   </div> | ||||||
|  |                                 </a-card> | ||||||
|  |                               </div> | ||||||
|  |                             </template> | ||||||
|  |                           </a-step> | ||||||
|  |                         </div> | ||||||
|  |                       </a-card> | ||||||
|  |                     </a-form-item> | ||||||
|  |                   </div> | ||||||
|                 </template> |                 </template> | ||||||
|               </a-step> |               </a-step> | ||||||
|               <a-step |               <a-step | ||||||
| @ -952,6 +1039,7 @@ import NetworkSelection from '@views/compute/wizard/NetworkSelection' | |||||||
| import NetworkConfiguration from '@views/compute/wizard/NetworkConfiguration' | import NetworkConfiguration from '@views/compute/wizard/NetworkConfiguration' | ||||||
| import LoadBalancerSelection from '@views/compute/wizard/LoadBalancerSelection' | import LoadBalancerSelection from '@views/compute/wizard/LoadBalancerSelection' | ||||||
| import SshKeyPairSelection from '@views/compute/wizard/SshKeyPairSelection' | import SshKeyPairSelection from '@views/compute/wizard/SshKeyPairSelection' | ||||||
|  | import UserDataSelection from '@views/compute/wizard/UserDataSelection' | ||||||
| import SecurityGroupSelection from '@views/compute/wizard/SecurityGroupSelection' | import SecurityGroupSelection from '@views/compute/wizard/SecurityGroupSelection' | ||||||
| import TooltipLabel from '@/components/widgets/TooltipLabel' | import TooltipLabel from '@/components/widgets/TooltipLabel' | ||||||
| import InstanceNicsNetworkSelectListView from '@/components/view/InstanceNicsNetworkSelectListView.vue' | import InstanceNicsNetworkSelectListView from '@/components/view/InstanceNicsNetworkSelectListView.vue' | ||||||
| @ -964,6 +1052,7 @@ export default { | |||||||
|   name: 'Wizard', |   name: 'Wizard', | ||||||
|   components: { |   components: { | ||||||
|     SshKeyPairSelection, |     SshKeyPairSelection, | ||||||
|  |     UserDataSelection, | ||||||
|     NetworkConfiguration, |     NetworkConfiguration, | ||||||
|     NetworkSelection, |     NetworkSelection, | ||||||
|     LoadBalancerSelection, |     LoadBalancerSelection, | ||||||
| @ -1010,6 +1099,10 @@ export default { | |||||||
|       zoneSelected: false, |       zoneSelected: false, | ||||||
|       dynamicscalingenabled: true, |       dynamicscalingenabled: true, | ||||||
|       templateKey: 0, |       templateKey: 0, | ||||||
|  |       showRegisteredUserdata: true, | ||||||
|  |       doUserdataOverride: false, | ||||||
|  |       doUserdataAppend: false, | ||||||
|  |       userdataDefaultOverridePolicy: 'ALLOWOVERRIDE', | ||||||
|       vm: { |       vm: { | ||||||
|         name: null, |         name: null, | ||||||
|         zoneid: null, |         zoneid: null, | ||||||
| @ -1034,6 +1127,7 @@ export default { | |||||||
|         affinityGroups: [], |         affinityGroups: [], | ||||||
|         networks: [], |         networks: [], | ||||||
|         sshKeyPairs: [], |         sshKeyPairs: [], | ||||||
|  |         UserDatas: [], | ||||||
|         loadbalancers: [] |         loadbalancers: [] | ||||||
|       }, |       }, | ||||||
|       rowCount: {}, |       rowCount: {}, | ||||||
| @ -1045,6 +1139,7 @@ export default { | |||||||
|         affinityGroups: false, |         affinityGroups: false, | ||||||
|         networks: false, |         networks: false, | ||||||
|         sshKeyPairs: false, |         sshKeyPairs: false, | ||||||
|  |         userDatas: false, | ||||||
|         loadbalancers: false, |         loadbalancers: false, | ||||||
|         zones: false |         zones: false | ||||||
|       }, |       }, | ||||||
| @ -1123,6 +1218,32 @@ export default { | |||||||
|       zone: {}, |       zone: {}, | ||||||
|       sshKeyPairs: [], |       sshKeyPairs: [], | ||||||
|       sshKeyPair: {}, |       sshKeyPair: {}, | ||||||
|  |       userData: {}, | ||||||
|  |       userDataParams: [], | ||||||
|  |       userDataParamCols: [ | ||||||
|  |         { | ||||||
|  |           title: this.$t('label.key'), | ||||||
|  |           dataIndex: 'key' | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           title: this.$t('label.value'), | ||||||
|  |           dataIndex: 'value', | ||||||
|  |           slots: { customRender: 'value' } | ||||||
|  |         } | ||||||
|  |       ], | ||||||
|  |       userDataValues: {}, | ||||||
|  |       templateUserDataCols: [ | ||||||
|  |         { | ||||||
|  |           title: this.$t('label.userdata'), | ||||||
|  |           dataIndex: 'userdata' | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           title: this.$t('label.userdatapolicy'), | ||||||
|  |           dataIndex: 'userdataoverridepolicy' | ||||||
|  |         } | ||||||
|  |       ], | ||||||
|  |       templateUserDataParams: [], | ||||||
|  |       templateUserDataValues: {}, | ||||||
|       overrideDiskOffering: {}, |       overrideDiskOffering: {}, | ||||||
|       templateFilter: [ |       templateFilter: [ | ||||||
|         'featured', |         'featured', | ||||||
| @ -1134,6 +1255,7 @@ export default { | |||||||
|       defaultNetworkId: '', |       defaultNetworkId: '', | ||||||
|       dataNetworkCreated: [], |       dataNetworkCreated: [], | ||||||
|       tabKey: 'templateid', |       tabKey: 'templateid', | ||||||
|  |       userdataTabKey: 'userdataregistered', | ||||||
|       dataPreFill: {}, |       dataPreFill: {}, | ||||||
|       showDetails: false, |       showDetails: false, | ||||||
|       showRootDiskSizeChanger: false, |       showRootDiskSizeChanger: false, | ||||||
| @ -1224,6 +1346,15 @@ export default { | |||||||
|             listall: false |             listall: false | ||||||
|           } |           } | ||||||
|         }, |         }, | ||||||
|  |         userDatas: { | ||||||
|  |           list: 'listUserData', | ||||||
|  |           options: { | ||||||
|  |             page: 1, | ||||||
|  |             pageSize: 10, | ||||||
|  |             keyword: undefined, | ||||||
|  |             listall: false | ||||||
|  |           } | ||||||
|  |         }, | ||||||
|         networks: { |         networks: { | ||||||
|           list: 'listNetworks', |           list: 'listNetworks', | ||||||
|           options: { |           options: { | ||||||
| @ -1285,12 +1416,27 @@ export default { | |||||||
|       }] |       }] | ||||||
|       return tabList |       return tabList | ||||||
|     }, |     }, | ||||||
|  |     userdataTabList () { | ||||||
|  |       let tabList = [] | ||||||
|  |       tabList = [{ | ||||||
|  |         key: 'userdataregistered', | ||||||
|  |         tab: this.$t('label.userdata.registered') | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         key: 'userdatatext', | ||||||
|  |         tab: this.$t('label.userdata.text') | ||||||
|  |       }] | ||||||
|  |       return tabList | ||||||
|  |     }, | ||||||
|     showSecurityGroupSection () { |     showSecurityGroupSection () { | ||||||
|       return (this.networks.length > 0 && this.zone.securitygroupsenabled) || (this.zone && this.zone.networktype === 'Basic') |       return (this.networks.length > 0 && this.zone.securitygroupsenabled) || (this.zone && this.zone.networktype === 'Basic') | ||||||
|     }, |     }, | ||||||
|     isUserAllowedToListSshKeys () { |     isUserAllowedToListSshKeys () { | ||||||
|       return Boolean('listSSHKeyPairs' in this.$store.getters.apis) |       return Boolean('listSSHKeyPairs' in this.$store.getters.apis) | ||||||
|     }, |     }, | ||||||
|  |     isUserAllowedToListUserDatas () { | ||||||
|  |       return Boolean('listUserData' in this.$store.getters.apis) | ||||||
|  |     }, | ||||||
|     dynamicScalingVmConfigValue () { |     dynamicScalingVmConfigValue () { | ||||||
|       return this.options.dynamicScalingVmConfig?.[0]?.value === 'true' |       return this.options.dynamicScalingVmConfig?.[0]?.value === 'true' | ||||||
|     }, |     }, | ||||||
| @ -1421,6 +1567,8 @@ export default { | |||||||
|   template (oldValue, newValue) { |   template (oldValue, newValue) { | ||||||
|     if (oldValue && newValue && oldValue.id !== newValue.id) { |     if (oldValue && newValue && oldValue.id !== newValue.id) { | ||||||
|       this.dynamicscalingenabled = this.isDynamicallyScalable() |       this.dynamicscalingenabled = this.isDynamicallyScalable() | ||||||
|  |       this.doUserdataOverride = false | ||||||
|  |       this.doUserdataAppend = false | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   beforeCreate () { |   beforeCreate () { | ||||||
| @ -1853,6 +2001,8 @@ export default { | |||||||
|         if (template) { |         if (template) { | ||||||
|           var size = template.size / (1024 * 1024 * 1024) || 0 // bytes to GB |           var size = template.size / (1024 * 1024 * 1024) || 0 // bytes to GB | ||||||
|           this.dataPreFill.minrootdisksize = Math.ceil(size) |           this.dataPreFill.minrootdisksize = Math.ceil(size) | ||||||
|  |           this.updateTemplateLinkedUserData(this.template.userdataid) | ||||||
|  |           this.userdataDefaultOverridePolicy = this.template.userdatapolicy | ||||||
|         } |         } | ||||||
|       } else if (['cpuspeed', 'cpunumber', 'memory'].includes(name)) { |       } else if (['cpuspeed', 'cpunumber', 'memory'].includes(name)) { | ||||||
|         this.vm[name] = value |         this.vm[name] = value | ||||||
| @ -2017,6 +2167,56 @@ export default { | |||||||
|       this.form.keypairs = names |       this.form.keypairs = names | ||||||
|       this.sshKeyPairs = names.map((sshKeyPair) => { return sshKeyPair.name }) |       this.sshKeyPairs = names.map((sshKeyPair) => { return sshKeyPair.name }) | ||||||
|     }, |     }, | ||||||
|  |     updateUserData (id) { | ||||||
|  |       if (id === '0') { | ||||||
|  |         this.form.userdataid = undefined | ||||||
|  |         return | ||||||
|  |       } | ||||||
|  |       this.form.userdataid = id | ||||||
|  |       this.userDataParams = [] | ||||||
|  |       api('listUserData', { id: id }).then(json => { | ||||||
|  |         const resp = json?.listuserdataresponse?.userdata || [] | ||||||
|  |         if (resp) { | ||||||
|  |           var params = resp[0].params | ||||||
|  |           if (params) { | ||||||
|  |             var dataParams = params.split(',') | ||||||
|  |           } | ||||||
|  |           var that = this | ||||||
|  |           dataParams.forEach(function (val, index) { | ||||||
|  |             that.userDataParams.push({ | ||||||
|  |               id: index, | ||||||
|  |               key: val | ||||||
|  |             }) | ||||||
|  |           }) | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |     updateTemplateLinkedUserData (id) { | ||||||
|  |       if (id === '0') { | ||||||
|  |         return | ||||||
|  |       } | ||||||
|  |       this.templateUserDataParams = [] | ||||||
|  | 
 | ||||||
|  |       api('listUserData', { id: id }).then(json => { | ||||||
|  |         const resp = json?.listuserdataresponse?.userdata || [] | ||||||
|  |         if (resp) { | ||||||
|  |           var params = resp[0].params | ||||||
|  |           if (params) { | ||||||
|  |             var dataParams = params.split(',') | ||||||
|  |           } | ||||||
|  |           var that = this | ||||||
|  |           that.templateUserDataParams = [] | ||||||
|  |           if (dataParams) { | ||||||
|  |             dataParams.forEach(function (val, index) { | ||||||
|  |               that.templateUserDataParams.push({ | ||||||
|  |                 id: index, | ||||||
|  |                 key: val | ||||||
|  |               }) | ||||||
|  |             }) | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|     updateAffinityGroups (ids) { |     updateAffinityGroups (ids) { | ||||||
|       this.form.affinitygroupids = ids |       this.form.affinitygroupids = ids | ||||||
|     }, |     }, | ||||||
| @ -2035,17 +2235,21 @@ export default { | |||||||
|         }, 1000) |         }, 1000) | ||||||
|       }) |       }) | ||||||
|     }, |     }, | ||||||
|     createVmProfile (createVmGroupData) { |     createVmProfile (createVmGroupData, createVmGroupUserDataDetails) { | ||||||
|       this.addStep('message.creating.autoscale.vmprofile', 'createVmProfile') |       this.addStep('message.creating.autoscale.vmprofile', 'createVmProfile') | ||||||
| 
 | 
 | ||||||
|       return new Promise((resolve, reject) => { |       return new Promise((resolve, reject) => { | ||||||
|         const params = { |         const params = { | ||||||
|  |           ...createVmGroupUserDataDetails, | ||||||
|  |           ...{ | ||||||
|             expungevmgraceperiod: createVmGroupData.expungevmgraceperiod, |             expungevmgraceperiod: createVmGroupData.expungevmgraceperiod, | ||||||
|             serviceofferingid: createVmGroupData.serviceofferingid, |             serviceofferingid: createVmGroupData.serviceofferingid, | ||||||
|             templateid: createVmGroupData.templateid, |             templateid: createVmGroupData.templateid, | ||||||
|             userdata: createVmGroupData.userdata, |             userdata: createVmGroupData.userdata, | ||||||
|  |             userdataid: createVmGroupData.userdataid, | ||||||
|             zoneid: createVmGroupData.zoneid |             zoneid: createVmGroupData.zoneid | ||||||
|           } |           } | ||||||
|  |         } | ||||||
|         if (createVmGroupData.autoscaleuserid) { |         if (createVmGroupData.autoscaleuserid) { | ||||||
|           params.autoscaleuserid = createVmGroupData.autoscaleuserid |           params.autoscaleuserid = createVmGroupData.autoscaleuserid | ||||||
|         } |         } | ||||||
| @ -2425,9 +2629,13 @@ export default { | |||||||
|         // advanced settings |         // advanced settings | ||||||
|         createVmGroupData.keypairs = this.sshKeyPairs.join(',') |         createVmGroupData.keypairs = this.sshKeyPairs.join(',') | ||||||
|         createVmGroupData.affinitygroupids = (values.affinitygroupids || []).join(',') |         createVmGroupData.affinitygroupids = (values.affinitygroupids || []).join(',') | ||||||
|         if (values.userdata && values.userdata.length > 0) { |         const isUserdataAllowed = !this.userdataDefaultOverridePolicy || (this.userdataDefaultOverridePolicy === 'ALLOWOVERRIDE' && this.doUserdataOverride) || (this.userdataDefaultOverridePolicy === 'APPEND' && this.doUserdataAppend) | ||||||
|  |         if (isUserdataAllowed && values.userdata && values.userdata.length > 0) { | ||||||
|           createVmGroupData.userdata = this.$toBase64AndURIEncoded(values.userdata) |           createVmGroupData.userdata = this.$toBase64AndURIEncoded(values.userdata) | ||||||
|         } |         } | ||||||
|  |         if (isUserdataAllowed) { | ||||||
|  |           createVmGroupData.userdataid = values.userdataid | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         // vm profile details |         // vm profile details | ||||||
|         createVmGroupData.autoscaleuserid = values.autoscaleuserid |         createVmGroupData.autoscaleuserid = values.autoscaleuserid | ||||||
| @ -2436,11 +2644,26 @@ export default { | |||||||
|         createVmGroupData = Object.fromEntries( |         createVmGroupData = Object.fromEntries( | ||||||
|           Object.entries(createVmGroupData).filter(([key, value]) => value !== undefined)) |           Object.entries(createVmGroupData).filter(([key, value]) => value !== undefined)) | ||||||
| 
 | 
 | ||||||
|  |         const createVmGroupUserDataDetails = {} | ||||||
|  |         var idx = 0 | ||||||
|  |         if (this.templateUserDataValues) { | ||||||
|  |           for (const [key, value] of Object.entries(this.templateUserDataValues)) { | ||||||
|  |             createVmGroupUserDataDetails['userdatadetails[' + idx + '].' + `${key}`] = value | ||||||
|  |             idx++ | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |         if (isUserdataAllowed && this.userDataValues) { | ||||||
|  |           for (const [key, value] of Object.entries(this.userDataValues)) { | ||||||
|  |             createVmGroupUserDataDetails['userdatadetails[' + idx + '].' + `${key}`] = value | ||||||
|  |             idx++ | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         this.processStatusModalVisible = true |         this.processStatusModalVisible = true | ||||||
|         this.processStatus = null |         this.processStatus = null | ||||||
| 
 | 
 | ||||||
|         // create autoscale vm profile |         // create autoscale vm profile | ||||||
|         const vmprofile = await this.createVmProfile(createVmGroupData) |         const vmprofile = await this.createVmProfile(createVmGroupData, createVmGroupUserDataDetails) | ||||||
| 
 | 
 | ||||||
|         // create scaleup conditions and policy |         // create scaleup conditions and policy | ||||||
|         const scaleUpPolicyIds = [] |         const scaleUpPolicyIds = [] | ||||||
| @ -2547,7 +2770,7 @@ export default { | |||||||
|       return new Promise((resolve) => { |       return new Promise((resolve) => { | ||||||
|         this.loading.zones = true |         this.loading.zones = true | ||||||
|         const param = this.params.zones |         const param = this.params.zones | ||||||
|         const args = { listall: true, showicon: true } |         const args = { showicon: true } | ||||||
|         if (zoneId) args.id = zoneId |         if (zoneId) args.id = zoneId | ||||||
|         api(param.list, args).then(json => { |         api(param.list, args).then(json => { | ||||||
|           const zoneResponse = (json.listzonesresponse.zone || []).filter(item => item.securitygroupsenabled === false) |           const zoneResponse = (json.listzonesresponse.zone || []).filter(item => item.securitygroupsenabled === false) | ||||||
| @ -2579,7 +2802,7 @@ export default { | |||||||
|       param.loading = true |       param.loading = true | ||||||
|       param.opts = [] |       param.opts = [] | ||||||
|       const options = param.options || {} |       const options = param.options || {} | ||||||
|       if (!('listall' in options)) { |       if (!('listall' in options) && !['zones', 'pods', 'clusters', 'hosts', 'dynamicScalingVmConfig', 'hypervisors'].includes(name)) { | ||||||
|         options.listall = true |         options.listall = true | ||||||
|       } |       } | ||||||
|       api(param.list, options).then((response) => { |       api(param.list, options).then((response) => { | ||||||
| @ -2703,6 +2926,10 @@ export default { | |||||||
|       this.params[name].options = { ...this.params[name].options, ...options } |       this.params[name].options = { ...this.params[name].options, ...options } | ||||||
|       this.fetchOptions(this.params[name], name) |       this.fetchOptions(this.params[name], name) | ||||||
|     }, |     }, | ||||||
|  |     onUserdataTabChange (key, type) { | ||||||
|  |       this[type] = key | ||||||
|  |       this.userDataParams = [] | ||||||
|  |     }, | ||||||
|     fetchTemplateNics (template) { |     fetchTemplateNics (template) { | ||||||
|       var nics = [] |       var nics = [] | ||||||
|       this.nicToNetworkSelection = [] |       this.nicToNetworkSelection = [] | ||||||
|  | |||||||
| @ -335,7 +335,6 @@ export default { | |||||||
|       this.loadingData = true |       this.loadingData = true | ||||||
|       console.log(values) |       console.log(values) | ||||||
|       const params = { |       const params = { | ||||||
|         id: this.resource.id |  | ||||||
|       } |       } | ||||||
|       if (values.userdata && values.userdata.length > 0) { |       if (values.userdata && values.userdata.length > 0) { | ||||||
|         params.userdata = this.$toBase64AndURIEncoded(values.userdata) |         params.userdata = this.$toBase64AndURIEncoded(values.userdata) | ||||||
| @ -356,7 +355,14 @@ export default { | |||||||
|           idx++ |           idx++ | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|       api('resetUserDataForVirtualMachine', params).then(json => { |       params.id = this.resource.resetUserDataResourceId ? this.resource.resetUserDataResourceId : this.resource.id | ||||||
|  | 
 | ||||||
|  |       const resetUserDataApiName = this.resource.resetUserDataApiName ? this.resource.resetUserDataApiName : 'resetUserDataForVirtualMachine' | ||||||
|  |       const httpMethod = params.userdata ? 'POST' : 'GET' | ||||||
|  |       const args = httpMethod === 'POST' ? {} : params | ||||||
|  |       const data = httpMethod === 'POST' ? params : {} | ||||||
|  | 
 | ||||||
|  |       api(resetUserDataApiName, args, httpMethod, data).then(json => { | ||||||
|         this.$message.success({ |         this.$message.success({ | ||||||
|           content: `${this.$t('label.action.userdata.reset')} - ${this.$t('label.success')}`, |           content: `${this.$t('label.action.userdata.reset')} - ${this.$t('label.success')}`, | ||||||
|           duration: 2 |           duration: 2 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user