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();
|
||||
|
||||
Long getUserDataId();
|
||||
|
||||
String getUserDataDetails();
|
||||
|
||||
public String getUuid();
|
||||
|
||||
public Long getZoneId();
|
||||
|
||||
@ -21,8 +21,10 @@ import java.lang.reflect.Field;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
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.storage.ImageStoreService;
|
||||
import org.apache.cloudstack.usage.UsageService;
|
||||
import org.apache.commons.collections.MapUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.configuration.ConfigurationService;
|
||||
@ -456,4 +459,18 @@ public abstract class BaseCmd {
|
||||
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.ServiceOfferingResponse;
|
||||
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.ZoneResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
@ -107,6 +108,12 @@ public class CreateAutoScaleVmProfileCmd extends BaseAsyncCreateCmd {
|
||||
since = "4.18.0")
|
||||
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,
|
||||
type = CommandType.UUID,
|
||||
entityType = UserResponse.class,
|
||||
@ -163,6 +170,14 @@ public class CreateAutoScaleVmProfileCmd extends BaseAsyncCreateCmd {
|
||||
return userData;
|
||||
}
|
||||
|
||||
public Long getUserDataId() {
|
||||
return userDataId;
|
||||
}
|
||||
|
||||
public Map<String, String> getUserDataDetails() {
|
||||
return convertDetailsToMap(userDataDetails);
|
||||
}
|
||||
|
||||
public Long getAutoscaleUserId() {
|
||||
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.ServiceOfferingResponse;
|
||||
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.context.CallContext;
|
||||
|
||||
@ -102,6 +103,14 @@ public class UpdateAutoScaleVmProfileCmd extends BaseAsyncCustomIdCmd {
|
||||
since = "4.18.0")
|
||||
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,
|
||||
type = CommandType.UUID,
|
||||
entityType = UserResponse.class,
|
||||
@ -156,6 +165,14 @@ public class UpdateAutoScaleVmProfileCmd extends BaseAsyncCustomIdCmd {
|
||||
return userData;
|
||||
}
|
||||
|
||||
public Long getUserDataId() {
|
||||
return userDataId;
|
||||
}
|
||||
|
||||
public Map<String, String> getUserDataDetails() {
|
||||
return convertDetailsToMap(userDataDetails);
|
||||
}
|
||||
|
||||
public Long getAutoscaleUserId() {
|
||||
return autoscaleUserId;
|
||||
}
|
||||
|
||||
@ -309,17 +309,8 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd implements SecurityG
|
||||
}
|
||||
|
||||
public Map<String, String> getDetails() {
|
||||
Map<String, String> customparameterMap = new HashMap<String, String>();
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
Map<String, String> customparameterMap = convertDetailsToMap(details);
|
||||
|
||||
if (getBootType() != null) {
|
||||
customparameterMap.put(getBootType().toString(), getBootMode().toString());
|
||||
}
|
||||
@ -450,18 +441,7 @@ public class DeployVMCmd extends BaseAsyncCreateCustomIdCmd implements SecurityG
|
||||
}
|
||||
|
||||
public Map<String, String> getUserdataDetails() {
|
||||
Map<String, String> userdataDetailsMap = new HashMap<String, String>();
|
||||
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;
|
||||
return convertDetailsToMap(userdataDetails);
|
||||
}
|
||||
|
||||
public Long getZoneId() {
|
||||
|
||||
@ -39,9 +39,6 @@ import org.apache.cloudstack.api.response.UserVmResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
@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() {
|
||||
Map<String, String> userdataDetailsMap = new HashMap<String, String>();
|
||||
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;
|
||||
return convertDetailsToMap(userdataDetails);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -16,9 +16,6 @@
|
||||
// under the License.
|
||||
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.Map;
|
||||
|
||||
@ -99,17 +96,7 @@ public class ScaleVMCmd extends BaseAsyncCmd implements UserCmd {
|
||||
//it is because details.values() cannot be cast to a map.
|
||||
//it gives a exception
|
||||
public Map<String, String> getDetails() {
|
||||
Map<String, String> customparameterMap = new HashMap<String, String>();
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
Map<String, String> customparameterMap = convertDetailsToMap(details);
|
||||
|
||||
if (shrinkOk != null) customparameterMap.put(ApiConstants.SHRINK_OK, String.valueOf(isShrinkOk()));
|
||||
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.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@ -176,18 +175,7 @@ public class UpdateVMCmd extends BaseCustomIdCmd implements SecurityGroupAction,
|
||||
}
|
||||
|
||||
public Map<String, String> getUserdataDetails() {
|
||||
Map<String, String> userdataDetailsMap = new HashMap<String, String>();
|
||||
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;
|
||||
return convertDetailsToMap(userdataDetails);
|
||||
}
|
||||
|
||||
public Boolean getDisplayVm() {
|
||||
|
||||
@ -16,9 +16,6 @@
|
||||
// under the License.
|
||||
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 org.apache.log4j.Logger;
|
||||
@ -95,17 +92,7 @@ public class UpgradeVMCmd extends BaseCmd implements UserCmd {
|
||||
}
|
||||
|
||||
public Map<String, String> getDetails() {
|
||||
Map<String, String> customparameterMap = new HashMap<String, String>();
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
Map<String, String> customparameterMap = convertDetailsToMap(details);
|
||||
|
||||
if (shrinkOk != null) customparameterMap.put(ApiConstants.SHRINK_OK, String.valueOf(isShrinkOk()));
|
||||
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")
|
||||
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)
|
||||
@Param(description = "the ID of the user used to launch and destroy the VMs")
|
||||
private String autoscaleUserId;
|
||||
@ -153,6 +165,22 @@ public class AutoScaleVmProfileResponse extends BaseResponse implements Controll
|
||||
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
|
||||
public void setAccountName(String accountName) {
|
||||
this.accountName = accountName;
|
||||
@ -193,4 +221,24 @@ public class AutoScaleVmProfileResponse extends BaseResponse implements Controll
|
||||
public void setForDisplay(Boolean 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)
|
||||
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)
|
||||
protected Date removed;
|
||||
|
||||
@ -228,6 +234,24 @@ public class AutoScaleVmProfileVO implements AutoScaleVmProfile, Identity, Inter
|
||||
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
|
||||
public String getUuid() {
|
||||
return uuid;
|
||||
|
||||
@ -63,6 +63,7 @@ public class Upgrade41800to41810 implements DbUpgrade, DbUpgradeSystemVmTemplate
|
||||
fixForeignKeyNames(conn);
|
||||
updateGuestOsMappings(conn);
|
||||
copyGuestOsMappingsToVMware80u1();
|
||||
addForeignKeyToAutoscaleVmprofiles(conn);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -225,4 +226,8 @@ public class Upgrade41800to41810 implements DbUpgrade, DbUpgradeSystemVmTemplate
|
||||
DbUpgradeUtils.dropKeysIfExist(conn, "cloud.volumes", keys, false);
|
||||
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)', '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
|
||||
UPDATE `cloud`.`service_offering` so
|
||||
SET so.limit_cpu_use = 0
|
||||
|
||||
@ -26,6 +26,18 @@ import org.junit.Test;
|
||||
|
||||
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
|
||||
public void testCounterParamsForUpdate() {
|
||||
AutoScaleVmProfileVO profile = new AutoScaleVmProfileVO();
|
||||
@ -62,4 +74,23 @@ public class AutoScaleVmProfileVOTest {
|
||||
Assert.assertEquals("rootdisksize", otherDeployParamsList.get(1).first());
|
||||
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 org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseAsyncCmd;
|
||||
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));
|
||||
}
|
||||
|
||||
String httpmethod = params.get(ApiConstants.HTTPMETHOD);
|
||||
if (httpmethod != null) {
|
||||
cmdObj.setHttpMethod(httpmethod);
|
||||
}
|
||||
|
||||
try {
|
||||
// dispatch could ultimately queue the job
|
||||
_dispatcher.dispatch(cmdObj, params, true);
|
||||
|
||||
@ -365,6 +365,7 @@ import com.cloud.user.User;
|
||||
import com.cloud.user.UserAccount;
|
||||
import com.cloud.user.UserData;
|
||||
import com.cloud.user.UserStatisticsVO;
|
||||
import com.cloud.user.dao.UserDataDao;
|
||||
import com.cloud.user.dao.UserStatisticsDao;
|
||||
import com.cloud.uservm.UserVm;
|
||||
import com.cloud.utils.Pair;
|
||||
@ -455,6 +456,8 @@ public class ApiResponseHelper implements ResponseGenerator {
|
||||
UserVmJoinDao userVmJoinDao;
|
||||
@Inject
|
||||
NetworkServiceMapDao ntwkSrvcDao;
|
||||
@Inject
|
||||
UserDataDao userDataDao;
|
||||
|
||||
@Override
|
||||
public UserResponse createUserResponse(User user) {
|
||||
@ -3393,9 +3396,20 @@ public class ApiResponseHelper implements ResponseGenerator {
|
||||
VMTemplateVO template = ApiDBUtils.findTemplateById(profile.getTemplateId());
|
||||
if (template != null) {
|
||||
response.setTemplateId(template.getUuid());
|
||||
if (template.getUserDataOverridePolicy() != null) {
|
||||
response.setUserDataPolicy(template.getUserDataOverridePolicy().toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
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.setCounterParams(profile.getCounterParams());
|
||||
response.setExpungeVmGracePeriod(profile.getExpungeVmGracePeriod());
|
||||
|
||||
@ -740,6 +740,9 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
|
||||
params.put("ctxStartEventId", String.valueOf(startEventId));
|
||||
params.put("cmdEventType", asyncCmd.getEventType().toString());
|
||||
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;
|
||||
|
||||
|
||||
@ -532,7 +532,6 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScaleManage
|
||||
long zoneId = cmd.getZoneId();
|
||||
long serviceOfferingId = cmd.getServiceOfferingId();
|
||||
Long autoscaleUserId = cmd.getAutoscaleUserId();
|
||||
String userData = cmd.getUserData();
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
VirtualMachineTemplate template = entityMgr.findById(VirtualMachineTemplate.class, cmd.getTemplateId());
|
||||
if (template == null) {
|
||||
throw new InvalidParameterValueException("Unable to find template by id " + cmd.getTemplateId());
|
||||
}
|
||||
|
||||
// validations
|
||||
HashMap<String, String> deployParams = cmd.getDeployParamMap();
|
||||
/*
|
||||
@ -562,9 +566,23 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScaleManage
|
||||
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) {
|
||||
profileVO.setUserData(userData);
|
||||
}
|
||||
if (userDataId != null) {
|
||||
profileVO.setUserDataId(userDataId);
|
||||
}
|
||||
if (userDataDetails != null) {
|
||||
profileVO.setUserDataDetails(userDataDetails);
|
||||
}
|
||||
|
||||
profileVO = checkValidityAndPersist(profileVO, true);
|
||||
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 counterParamList = cmd.getCounterParamList();
|
||||
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();
|
||||
|
||||
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) {
|
||||
vmProfile.setServiceOfferingId(serviceOfferingId);
|
||||
@ -609,10 +634,6 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScaleManage
|
||||
vmProfile.setCounterParamsForUpdate(counterParamList);
|
||||
}
|
||||
|
||||
if (userData != null) {
|
||||
vmProfile.setUserData(userData);
|
||||
}
|
||||
|
||||
if (expungeVmGracePeriod != null) {
|
||||
vmProfile.setExpungeVmGracePeriod(expungeVmGracePeriod);
|
||||
}
|
||||
@ -625,6 +646,18 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScaleManage
|
||||
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);
|
||||
for (AutoScaleVmGroupVO vmGroupVO : vmGroupList) {
|
||||
if (physicalParameterUpdate && !vmGroupVO.getState().equals(AutoScaleVmGroup.State.DISABLED)) {
|
||||
@ -1740,6 +1773,8 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScaleManage
|
||||
}
|
||||
|
||||
String userData = profileVo.getUserData();
|
||||
Long userDataId = profileVo.getUserDataId();
|
||||
String userDataDetails = profileVo.getUserDataDetails();
|
||||
|
||||
UserVm vm = null;
|
||||
IpAddresses addrs = new IpAddresses(null, null);
|
||||
@ -1763,20 +1798,20 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScaleManage
|
||||
if (zone.getNetworkType() == NetworkType.Basic) {
|
||||
vm = userVmService.createBasicSecurityGroupVirtualMachine(zone, serviceOffering, template, 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, true, overrideDiskOfferingId);
|
||||
} else {
|
||||
if (zone.isSecurityGroupEnabled()) {
|
||||
vm = userVmService.createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, template, networkIds, 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, true, overrideDiskOfferingId, null);
|
||||
} else {
|
||||
vm = userVmService.createAdvancedVirtualMachine(zone, serviceOffering, template, networkIds, owner, vmHostName, vmHostName,
|
||||
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, true, null, overrideDiskOfferingId);
|
||||
}
|
||||
|
||||
@ -92,6 +92,10 @@ public interface UserVmManager extends UserVmService {
|
||||
|
||||
void removeInstanceFromInstanceGroup(long vmId);
|
||||
|
||||
String finalizeUserData(String userData, Long userDataId, VirtualMachineTemplate template);
|
||||
|
||||
String validateUserData(String userData, HTTPMethod httpmethod);
|
||||
|
||||
boolean isVMUsingLocalStorage(VMInstanceVO 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;
|
||||
if (userData != null) {
|
||||
|
||||
@ -5703,7 +5704,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
||||
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)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -32,6 +32,7 @@ import java.util.UUID;
|
||||
|
||||
import org.apache.cloudstack.annotation.dao.AnnotationDao;
|
||||
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.NicSecondaryIpResponse;
|
||||
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.network.as.AutoScaleVmGroup;
|
||||
import com.cloud.network.as.AutoScaleVmGroupVO;
|
||||
import com.cloud.network.as.AutoScaleVmProfileVO;
|
||||
import com.cloud.network.as.dao.AutoScaleVmGroupVmMapDao;
|
||||
import com.cloud.network.dao.IPAddressVO;
|
||||
import com.cloud.network.dao.LoadBalancerVO;
|
||||
import com.cloud.network.dao.NetworkServiceMapDao;
|
||||
import com.cloud.network.dao.NetworkVO;
|
||||
import com.cloud.storage.VMTemplateVO;
|
||||
import com.cloud.usage.UsageVO;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountManager;
|
||||
import com.cloud.user.AccountVO;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.user.UserData;
|
||||
import com.cloud.user.UserDataVO;
|
||||
import com.cloud.user.UserVO;
|
||||
import com.cloud.user.dao.UserDataDao;
|
||||
import com.cloud.utils.net.Ip;
|
||||
import com.cloud.vm.NicSecondaryIp;
|
||||
|
||||
@ -86,12 +92,27 @@ public class ApiResponseHelperTest {
|
||||
@Mock
|
||||
AutoScaleVmGroupVmMapDao autoScaleVmGroupVmMapDaoMock;
|
||||
|
||||
@Mock
|
||||
UserDataDao userDataDaoMock;
|
||||
|
||||
@Spy
|
||||
@InjectMocks
|
||||
ApiResponseHelper apiResponseHelper = new ApiResponseHelper();
|
||||
|
||||
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
|
||||
public void injectMocks() throws SecurityException, NoSuchFieldException,
|
||||
IllegalArgumentException, IllegalAccessException {
|
||||
@ -297,4 +318,55 @@ public class ApiResponseHelperTest {
|
||||
assertEquals("8080", response.getPublicPort());
|
||||
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.dao.AnnotationDao;
|
||||
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.user.autoscale.CreateAutoScalePolicyCmd;
|
||||
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 nextVmSeq = 39L;
|
||||
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
|
||||
DataCenterVO zoneMock;
|
||||
@ -404,6 +409,10 @@ public class AutoScaleManagerImplTest {
|
||||
Mockito.doNothing().when(accountManager).checkAccess(Mockito.any(Account.class), Mockito.isNull(), Mockito.anyBoolean(), Mockito.any());
|
||||
|
||||
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
|
||||
@ -748,10 +757,48 @@ public class AutoScaleManagerImplTest {
|
||||
ReflectionTestUtils.setField(cmd, "otherDeployParams", otherDeployParams);
|
||||
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);
|
||||
|
||||
Assert.assertEquals(asVmProfileMock, vmProfile);
|
||||
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
|
||||
@ -774,10 +821,17 @@ public class AutoScaleManagerImplTest {
|
||||
ReflectionTestUtils.setField(cmd, "serviceOfferingId", serviceOfferingId);
|
||||
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);
|
||||
|
||||
Assert.assertEquals(asVmProfileMock, vmProfile);
|
||||
Mockito.verify(autoScaleVmProfileDao).persist(Mockito.any());
|
||||
|
||||
Mockito.verify(userVmMgr).finalizeUserData(any(), any(), any());
|
||||
Mockito.verify(userVmMgr).validateUserData(eq(userDataFinal), nullable(BaseCmd.HTTPMethod.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -1208,6 +1262,9 @@ public class AutoScaleManagerImplTest {
|
||||
when(asVmProfileMock.getAccountId()).thenReturn(accountId);
|
||||
when(asVmProfileMock.getZoneId()).thenReturn(zoneId);
|
||||
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(entityManager.findById(DataCenter.class, zoneId)).thenReturn(zoneMock);
|
||||
@ -1224,7 +1281,7 @@ public class AutoScaleManagerImplTest {
|
||||
when(userVmMock.getId()).thenReturn(virtualMachineId);
|
||||
when(zoneMock.getNetworkType()).thenReturn(DataCenter.NetworkType.Basic);
|
||||
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);
|
||||
|
||||
long result = autoScaleManagerImplSpy.createNewVM(asVmGroupMock);
|
||||
@ -1235,7 +1292,7 @@ public class AutoScaleManagerImplTest {
|
||||
"-" + asVmGroupMock.getNextVmSeq() + "-[a-z]{6}";
|
||||
Mockito.verify(userVmService).createBasicSecurityGroupVirtualMachine(any(), any(), any(), any(), any(),
|
||||
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());
|
||||
Mockito.verify(asVmGroupMock).setNextVmSeq(nextVmSeq + 1);
|
||||
}
|
||||
@ -1253,6 +1310,9 @@ public class AutoScaleManagerImplTest {
|
||||
when(asVmProfileMock.getAccountId()).thenReturn(accountId);
|
||||
when(asVmProfileMock.getZoneId()).thenReturn(zoneId);
|
||||
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(entityManager.findById(DataCenter.class, zoneId)).thenReturn(zoneMock);
|
||||
@ -1270,7 +1330,7 @@ public class AutoScaleManagerImplTest {
|
||||
when(zoneMock.getNetworkType()).thenReturn(DataCenter.NetworkType.Advanced);
|
||||
when(zoneMock.isSecurityGroupEnabled()).thenReturn(true);
|
||||
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);
|
||||
|
||||
long result = autoScaleManagerImplSpy.createNewVM(asVmGroupMock);
|
||||
@ -1281,7 +1341,7 @@ public class AutoScaleManagerImplTest {
|
||||
"-" + asVmGroupMock.getNextVmSeq() + "-[a-z]{6}";
|
||||
Mockito.verify(userVmService).createAdvancedSecurityGroupVirtualMachine(any(), any(), any(), any(), any(), any(),
|
||||
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());
|
||||
Mockito.verify(asVmGroupMock).setNextVmSeq(nextVmSeq + 2);
|
||||
}
|
||||
@ -1299,6 +1359,9 @@ public class AutoScaleManagerImplTest {
|
||||
when(asVmProfileMock.getAccountId()).thenReturn(accountId);
|
||||
when(asVmProfileMock.getZoneId()).thenReturn(zoneId);
|
||||
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(entityManager.findById(DataCenter.class, zoneId)).thenReturn(zoneMock);
|
||||
@ -1316,7 +1379,7 @@ public class AutoScaleManagerImplTest {
|
||||
when(zoneMock.getNetworkType()).thenReturn(DataCenter.NetworkType.Advanced);
|
||||
when(zoneMock.isSecurityGroupEnabled()).thenReturn(false);
|
||||
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);
|
||||
|
||||
long result = autoScaleManagerImplSpy.createNewVM(asVmGroupMock);
|
||||
@ -1327,7 +1390,7 @@ public class AutoScaleManagerImplTest {
|
||||
"-" + asVmGroupMock.getNextVmSeq() + "-[a-z]{6}";
|
||||
Mockito.verify(userVmService).createAdvancedVirtualMachine(any(), any(), any(), any(), any(),
|
||||
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());
|
||||
Mockito.verify(asVmGroupMock).setNextVmSeq(nextVmSeq + 3);
|
||||
}
|
||||
|
||||
@ -38,6 +38,7 @@ from marvin.lib.base import (Account,
|
||||
Domain,
|
||||
Project,
|
||||
ServiceOffering,
|
||||
Template,
|
||||
VirtualMachine,
|
||||
Volume,
|
||||
Zone,
|
||||
@ -47,6 +48,7 @@ from marvin.lib.base import (Account,
|
||||
LoadBalancerRule,
|
||||
VPC,
|
||||
VpcOffering,
|
||||
UserData,
|
||||
SSHKeyPair)
|
||||
|
||||
from marvin.lib.common import (get_domain,
|
||||
@ -198,6 +200,37 @@ class TestVmAutoScaling(cloudstackTestCase):
|
||||
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
|
||||
counters = Autoscale.listCounters(
|
||||
cls.regular_user_apiclient,
|
||||
@ -294,6 +327,7 @@ class TestVmAutoScaling(cloudstackTestCase):
|
||||
serviceofferingid=cls.service_offering.id,
|
||||
zoneid=cls.zone.id,
|
||||
templateid=cls.template.id,
|
||||
userdata="VGVzdFVzZXJEYXRh", #TestUserData
|
||||
expungevmgraceperiod=DEFAULT_EXPUNGE_VM_GRACE_PERIOD,
|
||||
otherdeployparams=cls.otherdeployparams
|
||||
)
|
||||
@ -349,6 +383,10 @@ class TestVmAutoScaling(cloudstackTestCase):
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
cls.template = Template.linkUserDataToTemplate(
|
||||
cls.apiclient,
|
||||
templateid=cls.template.id
|
||||
)
|
||||
Configurations.update(cls.apiclient,
|
||||
CONFIG_NAME_DISK_CONTROLLER,
|
||||
cls.initial_vmware_root_disk_controller)
|
||||
@ -390,6 +428,7 @@ class TestVmAutoScaling(cloudstackTestCase):
|
||||
self.regular_user_apiclient,
|
||||
autoscalevmgroupid=autoscalevmgroupid,
|
||||
projectid=projectid,
|
||||
userdata=True,
|
||||
listall=True
|
||||
)
|
||||
self.assertEqual(
|
||||
@ -505,6 +544,31 @@ class TestVmAutoScaling(cloudstackTestCase):
|
||||
else:
|
||||
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):
|
||||
""" Wait until vm is Running """
|
||||
def check_user_vm_state():
|
||||
@ -512,6 +576,7 @@ class TestVmAutoScaling(cloudstackTestCase):
|
||||
self.apiclient,
|
||||
id=vm.id,
|
||||
projectid=project_id,
|
||||
userdata=True,
|
||||
listall=True
|
||||
)
|
||||
if isinstance(vms, list):
|
||||
@ -576,6 +641,8 @@ class TestVmAutoScaling(cloudstackTestCase):
|
||||
Autoscale.updateAutoscaleVMProfile(
|
||||
self.regular_user_apiclient,
|
||||
id = self.autoscaling_vmprofile.id,
|
||||
userdataid=self.apiUserdata.userdata.id,
|
||||
userdatadetails=[{"key1": "value2"}],
|
||||
serviceofferingid = self.service_offering_new.id,
|
||||
expungevmgraceperiod = DEFAULT_EXPUNGE_VM_GRACE_PERIOD + 1,
|
||||
otherdeployparams = otherdeployparams_new
|
||||
@ -712,6 +779,7 @@ class TestVmAutoScaling(cloudstackTestCase):
|
||||
vms = VirtualMachine.list(
|
||||
self.regular_user_apiclient,
|
||||
autoscalevmgroupid=self.autoscaling_vmgroup.id,
|
||||
userdata=True,
|
||||
listall=True
|
||||
)
|
||||
self.assertEqual(
|
||||
@ -889,6 +957,7 @@ class TestVmAutoScaling(cloudstackTestCase):
|
||||
self.regular_user_apiclient,
|
||||
autoscalevmgroupid=autoscaling_vmgroup_project.id,
|
||||
projectid=project.id,
|
||||
userdata=True,
|
||||
listall=True
|
||||
)
|
||||
self.assertEqual(
|
||||
|
||||
@ -1625,6 +1625,7 @@
|
||||
"label.reset.config.value": "Reset to default value",
|
||||
"label.reset.ssh.key.pair": "Reset SSH key pair",
|
||||
"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.vpn.connection": "Reset VPN connection",
|
||||
"label.resource": "Resource",
|
||||
|
||||
@ -69,6 +69,47 @@
|
||||
{{ getServiceOfferingName(serviceofferingid) }}
|
||||
</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__item">
|
||||
<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') }}
|
||||
</a-button>
|
||||
</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>
|
||||
|
||||
<a-divider/>
|
||||
@ -224,20 +271,26 @@
|
||||
</a-select>
|
||||
</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">
|
||||
<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>
|
||||
</div>
|
||||
</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>
|
||||
</template>
|
||||
|
||||
@ -247,10 +300,12 @@ import { isAdmin, isAdminOrDomainAdmin } from '@/role'
|
||||
import Status from '@/components/widgets/Status'
|
||||
import TooltipButton from '@/components/widgets/TooltipButton'
|
||||
import TooltipLabel from '@/components/widgets/TooltipLabel'
|
||||
import ResetUserData from '@views/compute/ResetUserData'
|
||||
|
||||
export default {
|
||||
name: 'conditionsTab',
|
||||
components: {
|
||||
ResetUserData,
|
||||
Status,
|
||||
TooltipButton,
|
||||
TooltipLabel
|
||||
@ -266,12 +321,17 @@ export default {
|
||||
filterColumns: ['Action'],
|
||||
loading: true,
|
||||
editProfileModalVisible: false,
|
||||
showUpdateUserDataForm: false,
|
||||
profileid: null,
|
||||
autoscaleuserid: null,
|
||||
expungevmgraceperiod: null,
|
||||
templateid: null,
|
||||
serviceofferingid: null,
|
||||
userdata: null,
|
||||
userdataid: null,
|
||||
userdataname: null,
|
||||
userdatadetails: null,
|
||||
userdatapolicy: null,
|
||||
usersList: [],
|
||||
templatesList: [],
|
||||
serviceOfferingsList: [],
|
||||
@ -384,6 +444,11 @@ export default {
|
||||
this.serviceofferingid = response.listautoscalevmprofilesresponse?.autoscalevmprofile?.[0]?.serviceofferingid
|
||||
this.templateid = response.listautoscalevmprofilesresponse?.autoscalevmprofile?.[0]?.templateid
|
||||
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 otherdeployparams = response.listautoscalevmprofilesresponse?.autoscalevmprofile?.[0]?.otherdeployparams || {}
|
||||
this.finalizeParams(counterparam, otherdeployparams)
|
||||
@ -518,13 +583,10 @@ export default {
|
||||
if (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 args = httpMethod === 'POST' ? {} : params
|
||||
const data = httpMethod === 'POST' ? params : {}
|
||||
const httpMethod = 'GET'
|
||||
const args = params
|
||||
const data = {}
|
||||
|
||||
api('updateAutoScaleVmProfile', args, httpMethod, data).then(response => {
|
||||
this.$pollJob({
|
||||
|
||||
@ -407,7 +407,7 @@
|
||||
|
||||
<span v-if="property.type && property.type==='boolean'">
|
||||
<a-switch
|
||||
v-model:cheked="form['properties.' + escapePropertyKey(property.key)]"
|
||||
v-model:checked="form['properties.' + escapePropertyKey(property.key)]"
|
||||
:placeholder="property.description"
|
||||
/>
|
||||
</span>
|
||||
@ -760,13 +760,100 @@
|
||||
@select-affinity-group-item="($event) => updateAffinityGroups($event)"
|
||||
@handle-search-filter="($event) => handleSearchFilter('affinityGroups', $event)"/>
|
||||
</a-form-item>
|
||||
<a-form-item name="userdata" ref="userdata">
|
||||
<a-form-item>
|
||||
<template #label>
|
||||
<tooltip-label :title="$t('label.userdata')" :tooltip="createAutoScaleVmProfileApiParams.userdata.description"/>
|
||||
</template>
|
||||
<a-textarea
|
||||
v-model:value="form.userdata">
|
||||
</a-textarea>
|
||||
<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
|
||||
placeholder="Userdata"
|
||||
v-model:value="form.userdata">
|
||||
</a-textarea>
|
||||
</a-form-item>
|
||||
</div>
|
||||
</a-card>
|
||||
</div>
|
||||
</template>
|
||||
</a-step>
|
||||
</div>
|
||||
</a-card>
|
||||
</a-form-item>
|
||||
</div>
|
||||
</template>
|
||||
@ -952,6 +1039,7 @@ import NetworkSelection from '@views/compute/wizard/NetworkSelection'
|
||||
import NetworkConfiguration from '@views/compute/wizard/NetworkConfiguration'
|
||||
import LoadBalancerSelection from '@views/compute/wizard/LoadBalancerSelection'
|
||||
import SshKeyPairSelection from '@views/compute/wizard/SshKeyPairSelection'
|
||||
import UserDataSelection from '@views/compute/wizard/UserDataSelection'
|
||||
import SecurityGroupSelection from '@views/compute/wizard/SecurityGroupSelection'
|
||||
import TooltipLabel from '@/components/widgets/TooltipLabel'
|
||||
import InstanceNicsNetworkSelectListView from '@/components/view/InstanceNicsNetworkSelectListView.vue'
|
||||
@ -964,6 +1052,7 @@ export default {
|
||||
name: 'Wizard',
|
||||
components: {
|
||||
SshKeyPairSelection,
|
||||
UserDataSelection,
|
||||
NetworkConfiguration,
|
||||
NetworkSelection,
|
||||
LoadBalancerSelection,
|
||||
@ -1010,6 +1099,10 @@ export default {
|
||||
zoneSelected: false,
|
||||
dynamicscalingenabled: true,
|
||||
templateKey: 0,
|
||||
showRegisteredUserdata: true,
|
||||
doUserdataOverride: false,
|
||||
doUserdataAppend: false,
|
||||
userdataDefaultOverridePolicy: 'ALLOWOVERRIDE',
|
||||
vm: {
|
||||
name: null,
|
||||
zoneid: null,
|
||||
@ -1034,6 +1127,7 @@ export default {
|
||||
affinityGroups: [],
|
||||
networks: [],
|
||||
sshKeyPairs: [],
|
||||
UserDatas: [],
|
||||
loadbalancers: []
|
||||
},
|
||||
rowCount: {},
|
||||
@ -1045,6 +1139,7 @@ export default {
|
||||
affinityGroups: false,
|
||||
networks: false,
|
||||
sshKeyPairs: false,
|
||||
userDatas: false,
|
||||
loadbalancers: false,
|
||||
zones: false
|
||||
},
|
||||
@ -1123,6 +1218,32 @@ export default {
|
||||
zone: {},
|
||||
sshKeyPairs: [],
|
||||
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: {},
|
||||
templateFilter: [
|
||||
'featured',
|
||||
@ -1134,6 +1255,7 @@ export default {
|
||||
defaultNetworkId: '',
|
||||
dataNetworkCreated: [],
|
||||
tabKey: 'templateid',
|
||||
userdataTabKey: 'userdataregistered',
|
||||
dataPreFill: {},
|
||||
showDetails: false,
|
||||
showRootDiskSizeChanger: false,
|
||||
@ -1224,6 +1346,15 @@ export default {
|
||||
listall: false
|
||||
}
|
||||
},
|
||||
userDatas: {
|
||||
list: 'listUserData',
|
||||
options: {
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
keyword: undefined,
|
||||
listall: false
|
||||
}
|
||||
},
|
||||
networks: {
|
||||
list: 'listNetworks',
|
||||
options: {
|
||||
@ -1285,12 +1416,27 @@ export default {
|
||||
}]
|
||||
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 () {
|
||||
return (this.networks.length > 0 && this.zone.securitygroupsenabled) || (this.zone && this.zone.networktype === 'Basic')
|
||||
},
|
||||
isUserAllowedToListSshKeys () {
|
||||
return Boolean('listSSHKeyPairs' in this.$store.getters.apis)
|
||||
},
|
||||
isUserAllowedToListUserDatas () {
|
||||
return Boolean('listUserData' in this.$store.getters.apis)
|
||||
},
|
||||
dynamicScalingVmConfigValue () {
|
||||
return this.options.dynamicScalingVmConfig?.[0]?.value === 'true'
|
||||
},
|
||||
@ -1421,6 +1567,8 @@ export default {
|
||||
template (oldValue, newValue) {
|
||||
if (oldValue && newValue && oldValue.id !== newValue.id) {
|
||||
this.dynamicscalingenabled = this.isDynamicallyScalable()
|
||||
this.doUserdataOverride = false
|
||||
this.doUserdataAppend = false
|
||||
}
|
||||
},
|
||||
beforeCreate () {
|
||||
@ -1853,6 +2001,8 @@ export default {
|
||||
if (template) {
|
||||
var size = template.size / (1024 * 1024 * 1024) || 0 // bytes to GB
|
||||
this.dataPreFill.minrootdisksize = Math.ceil(size)
|
||||
this.updateTemplateLinkedUserData(this.template.userdataid)
|
||||
this.userdataDefaultOverridePolicy = this.template.userdatapolicy
|
||||
}
|
||||
} else if (['cpuspeed', 'cpunumber', 'memory'].includes(name)) {
|
||||
this.vm[name] = value
|
||||
@ -2017,6 +2167,56 @@ export default {
|
||||
this.form.keypairs = names
|
||||
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) {
|
||||
this.form.affinitygroupids = ids
|
||||
},
|
||||
@ -2035,16 +2235,20 @@ export default {
|
||||
}, 1000)
|
||||
})
|
||||
},
|
||||
createVmProfile (createVmGroupData) {
|
||||
createVmProfile (createVmGroupData, createVmGroupUserDataDetails) {
|
||||
this.addStep('message.creating.autoscale.vmprofile', 'createVmProfile')
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const params = {
|
||||
expungevmgraceperiod: createVmGroupData.expungevmgraceperiod,
|
||||
serviceofferingid: createVmGroupData.serviceofferingid,
|
||||
templateid: createVmGroupData.templateid,
|
||||
userdata: createVmGroupData.userdata,
|
||||
zoneid: createVmGroupData.zoneid
|
||||
...createVmGroupUserDataDetails,
|
||||
...{
|
||||
expungevmgraceperiod: createVmGroupData.expungevmgraceperiod,
|
||||
serviceofferingid: createVmGroupData.serviceofferingid,
|
||||
templateid: createVmGroupData.templateid,
|
||||
userdata: createVmGroupData.userdata,
|
||||
userdataid: createVmGroupData.userdataid,
|
||||
zoneid: createVmGroupData.zoneid
|
||||
}
|
||||
}
|
||||
if (createVmGroupData.autoscaleuserid) {
|
||||
params.autoscaleuserid = createVmGroupData.autoscaleuserid
|
||||
@ -2425,9 +2629,13 @@ export default {
|
||||
// advanced settings
|
||||
createVmGroupData.keypairs = this.sshKeyPairs.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)
|
||||
}
|
||||
if (isUserdataAllowed) {
|
||||
createVmGroupData.userdataid = values.userdataid
|
||||
}
|
||||
|
||||
// vm profile details
|
||||
createVmGroupData.autoscaleuserid = values.autoscaleuserid
|
||||
@ -2436,11 +2644,26 @@ export default {
|
||||
createVmGroupData = Object.fromEntries(
|
||||
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.processStatus = null
|
||||
|
||||
// create autoscale vm profile
|
||||
const vmprofile = await this.createVmProfile(createVmGroupData)
|
||||
const vmprofile = await this.createVmProfile(createVmGroupData, createVmGroupUserDataDetails)
|
||||
|
||||
// create scaleup conditions and policy
|
||||
const scaleUpPolicyIds = []
|
||||
@ -2547,7 +2770,7 @@ export default {
|
||||
return new Promise((resolve) => {
|
||||
this.loading.zones = true
|
||||
const param = this.params.zones
|
||||
const args = { listall: true, showicon: true }
|
||||
const args = { showicon: true }
|
||||
if (zoneId) args.id = zoneId
|
||||
api(param.list, args).then(json => {
|
||||
const zoneResponse = (json.listzonesresponse.zone || []).filter(item => item.securitygroupsenabled === false)
|
||||
@ -2579,7 +2802,7 @@ export default {
|
||||
param.loading = true
|
||||
param.opts = []
|
||||
const options = param.options || {}
|
||||
if (!('listall' in options)) {
|
||||
if (!('listall' in options) && !['zones', 'pods', 'clusters', 'hosts', 'dynamicScalingVmConfig', 'hypervisors'].includes(name)) {
|
||||
options.listall = true
|
||||
}
|
||||
api(param.list, options).then((response) => {
|
||||
@ -2703,6 +2926,10 @@ export default {
|
||||
this.params[name].options = { ...this.params[name].options, ...options }
|
||||
this.fetchOptions(this.params[name], name)
|
||||
},
|
||||
onUserdataTabChange (key, type) {
|
||||
this[type] = key
|
||||
this.userDataParams = []
|
||||
},
|
||||
fetchTemplateNics (template) {
|
||||
var nics = []
|
||||
this.nicToNetworkSelection = []
|
||||
|
||||
@ -335,7 +335,6 @@ export default {
|
||||
this.loadingData = true
|
||||
console.log(values)
|
||||
const params = {
|
||||
id: this.resource.id
|
||||
}
|
||||
if (values.userdata && values.userdata.length > 0) {
|
||||
params.userdata = this.$toBase64AndURIEncoded(values.userdata)
|
||||
@ -356,7 +355,14 @@ export default {
|
||||
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({
|
||||
content: `${this.$t('label.action.userdata.reset')} - ${this.$t('label.success')}`,
|
||||
duration: 2
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user