From 666efc4b974b968b921e5fc44d0f2085e005d9c5 Mon Sep 17 00:00:00 2001 From: Henrique Sato Date: Tue, 3 Dec 2024 14:44:18 -0300 Subject: [PATCH 1/6] Simplify validation for creating volume templates via UI (#9828) Co-authored-by: Henrique Sato --- ui/src/config/section/storage.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ui/src/config/section/storage.js b/ui/src/config/section/storage.js index 5a50cb0b1dd..e0fa72dff8a 100644 --- a/ui/src/config/section/storage.js +++ b/ui/src/config/section/storage.js @@ -251,9 +251,7 @@ export default { label: 'label.action.create.template.from.volume', dataView: true, show: (record) => { - return !['Destroy', 'Destroyed', 'Expunging', 'Expunged', 'Migrating', 'Uploading', 'UploadError', 'Creating'].includes(record.state) && - ((record.type === 'ROOT' && record.vmstate === 'Stopped') || - (record.type !== 'ROOT' && !record.virtualmachineid && !['Allocated', 'Uploaded'].includes(record.state))) + return record.state === 'Ready' && (record.vmstate === 'Stopped' || !record.virtualmachineid) }, args: (record, store) => { var fields = ['volumeid', 'name', 'displaytext', 'ostypeid', 'isdynamicallyscalable', 'requireshvm', 'passwordenabled'] From ef1a58d83706cce5a47d5cec58591cb2ed75e617 Mon Sep 17 00:00:00 2001 From: Fabricio Duarte Date: Wed, 4 Dec 2024 04:06:22 -0300 Subject: [PATCH 2/6] Remove user from project before deletion (#10008) Co-authored-by: Suresh Kumar Anaparti --- .../cloud/projects/dao/ProjectAccountDao.java | 2 + .../projects/dao/ProjectAccountDaoImpl.java | 11 ++++ .../cloud/upgrade/DatabaseUpgradeChecker.java | 2 + .../upgrade/dao/Upgrade41910to41920.java | 66 +++++++++++++++++++ .../db/schema-41910to41920-cleanup.sql | 23 +++++++ .../META-INF/db/schema-41910to41920.sql | 20 ++++++ .../com/cloud/user/AccountManagerImpl.java | 10 ++- .../cloud/user/AccountManagerImplTest.java | 10 +++ 8 files changed, 143 insertions(+), 1 deletion(-) create mode 100644 engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade41910to41920.java create mode 100644 engine/schema/src/main/resources/META-INF/db/schema-41910to41920-cleanup.sql create mode 100644 engine/schema/src/main/resources/META-INF/db/schema-41910to41920.sql diff --git a/engine/schema/src/main/java/com/cloud/projects/dao/ProjectAccountDao.java b/engine/schema/src/main/java/com/cloud/projects/dao/ProjectAccountDao.java index 730182a1cb5..f4b2f646002 100644 --- a/engine/schema/src/main/java/com/cloud/projects/dao/ProjectAccountDao.java +++ b/engine/schema/src/main/java/com/cloud/projects/dao/ProjectAccountDao.java @@ -47,6 +47,8 @@ public interface ProjectAccountDao extends GenericDao { void removeAccountFromProjects(long accountId); + void removeUserFromProjects(long userId); + boolean canUserModifyProject(long projectId, long accountId, long userId); List listUsersOrAccountsByRole(long id); diff --git a/engine/schema/src/main/java/com/cloud/projects/dao/ProjectAccountDaoImpl.java b/engine/schema/src/main/java/com/cloud/projects/dao/ProjectAccountDaoImpl.java index d2ba49e9408..9adb1a9e9b3 100644 --- a/engine/schema/src/main/java/com/cloud/projects/dao/ProjectAccountDaoImpl.java +++ b/engine/schema/src/main/java/com/cloud/projects/dao/ProjectAccountDaoImpl.java @@ -194,6 +194,17 @@ public class ProjectAccountDaoImpl extends GenericDaoBase sc = AllFieldsSearch.create(); + sc.setParameters("userId", userId); + + int removedCount = remove(sc); + if (removedCount > 0) { + s_logger.debug(String.format("Removed user [%s] from %s project(s).", userId, removedCount)); + } + } + @Override public boolean canUserModifyProject(long projectId, long accountId, long userId) { SearchCriteria sc = AllFieldsSearch.create(); diff --git a/engine/schema/src/main/java/com/cloud/upgrade/DatabaseUpgradeChecker.java b/engine/schema/src/main/java/com/cloud/upgrade/DatabaseUpgradeChecker.java index b908455c1fe..aecf4cc0590 100644 --- a/engine/schema/src/main/java/com/cloud/upgrade/DatabaseUpgradeChecker.java +++ b/engine/schema/src/main/java/com/cloud/upgrade/DatabaseUpgradeChecker.java @@ -33,6 +33,7 @@ import java.util.List; import javax.inject.Inject; +import com.cloud.upgrade.dao.Upgrade41910to41920; import com.cloud.utils.FileUtil; import org.apache.cloudstack.utils.CloudStackVersion; import org.apache.commons.lang3.StringUtils; @@ -227,6 +228,7 @@ public class DatabaseUpgradeChecker implements SystemIntegrityChecker { .next("4.18.0.0", new Upgrade41800to41810()) .next("4.18.1.0", new Upgrade41810to41900()) .next("4.19.0.0", new Upgrade41900to41910()) + .next("4.19.1.0", new Upgrade41910to41920()) .build(); } diff --git a/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade41910to41920.java b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade41910to41920.java new file mode 100644 index 00000000000..6215021473e --- /dev/null +++ b/engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade41910to41920.java @@ -0,0 +1,66 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package com.cloud.upgrade.dao; + +import com.cloud.utils.exception.CloudRuntimeException; + +import java.io.InputStream; +import java.sql.Connection; + +public class Upgrade41910to41920 implements DbUpgrade { + + @Override + public String[] getUpgradableVersionRange() { + return new String[]{"4.19.1.0", "4.19.2.0"}; + } + + @Override + public String getUpgradedVersion() { + return "4.19.2.0"; + } + + @Override + public boolean supportsRollingUpgrade() { + return false; + } + + @Override + public InputStream[] getPrepareScripts() { + final String scriptFile = "META-INF/db/schema-41910to41920.sql"; + final InputStream script = Thread.currentThread().getContextClassLoader().getResourceAsStream(scriptFile); + if (script == null) { + throw new CloudRuntimeException("Unable to find " + scriptFile); + } + + return new InputStream[]{script}; + } + + @Override + public void performDataMigration(Connection conn) { + } + + @Override + public InputStream[] getCleanupScripts() { + final String scriptFile = "META-INF/db/schema-41910to41920-cleanup.sql"; + final InputStream script = Thread.currentThread().getContextClassLoader().getResourceAsStream(scriptFile); + if (script == null) { + throw new CloudRuntimeException("Unable to find " + scriptFile); + } + + return new InputStream[]{script}; + } +} diff --git a/engine/schema/src/main/resources/META-INF/db/schema-41910to41920-cleanup.sql b/engine/schema/src/main/resources/META-INF/db/schema-41910to41920-cleanup.sql new file mode 100644 index 00000000000..cb317c69b79 --- /dev/null +++ b/engine/schema/src/main/resources/META-INF/db/schema-41910to41920-cleanup.sql @@ -0,0 +1,23 @@ +-- Licensed to the Apache Software Foundation (ASF) under one +-- or more contributor license agreements. See the NOTICE file +-- distributed with this work for additional information +-- regarding copyright ownership. The ASF licenses this file +-- to you under the Apache License, Version 2.0 (the +-- "License"); you may not use this file except in compliance +-- with the License. You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, +-- software distributed under the License is distributed on an +-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +-- KIND, either express or implied. See the License for the +-- specific language governing permissions and limitations +-- under the License. + +--; +-- Schema upgrade cleanup from 4.19.1.0 to 4.19.2.0 +--; + +-- Delete `project_account` entries for users that were removed +DELETE FROM `cloud`.`project_account` WHERE `user_id` IN (SELECT `id` FROM `cloud`.`user` WHERE `removed`); diff --git a/engine/schema/src/main/resources/META-INF/db/schema-41910to41920.sql b/engine/schema/src/main/resources/META-INF/db/schema-41910to41920.sql new file mode 100644 index 00000000000..d4c23eee0ed --- /dev/null +++ b/engine/schema/src/main/resources/META-INF/db/schema-41910to41920.sql @@ -0,0 +1,20 @@ +-- Licensed to the Apache Software Foundation (ASF) under one +-- or more contributor license agreements. See the NOTICE file +-- distributed with this work for additional information +-- regarding copyright ownership. The ASF licenses this file +-- to you under the Apache License, Version 2.0 (the +-- "License"); you may not use this file except in compliance +-- with the License. You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, +-- software distributed under the License is distributed on an +-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +-- KIND, either express or implied. See the License for the +-- specific language governing permissions and limitations +-- under the License. + +--; +-- Schema upgrade from 4.19.1.0 to 4.19.2.0 +--; diff --git a/server/src/main/java/com/cloud/user/AccountManagerImpl.java b/server/src/main/java/com/cloud/user/AccountManagerImpl.java index c7ceb00cb57..412a5b58282 100644 --- a/server/src/main/java/com/cloud/user/AccountManagerImpl.java +++ b/server/src/main/java/com/cloud/user/AccountManagerImpl.java @@ -2087,7 +2087,15 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M // don't allow to delete the user from the account of type Project checkAccountAndAccess(user, account); - return _userDao.remove(deleteUserCmd.getId()); + return Transaction.execute((TransactionCallback) status -> deleteAndCleanupUser(user)); + } + + protected boolean deleteAndCleanupUser(User user) { + long userId = user.getId(); + + _projectAccountDao.removeUserFromProjects(userId); + + return _userDao.remove(userId); } @Override diff --git a/server/src/test/java/com/cloud/user/AccountManagerImplTest.java b/server/src/test/java/com/cloud/user/AccountManagerImplTest.java index f0a5af2bd87..3ecb4f2f1cf 100644 --- a/server/src/test/java/com/cloud/user/AccountManagerImplTest.java +++ b/server/src/test/java/com/cloud/user/AccountManagerImplTest.java @@ -1046,4 +1046,14 @@ public class AccountManagerImplTest extends AccountManagetImplTestBase { Assert.assertEquals(userAccountVOList.size(), userAccounts.size()); Assert.assertEquals(userAccountVOList.get(0), userAccounts.get(0)); } + + @Test + public void deleteAndCleanupUserTestRemovesUserFromProjects() { + long userId = userVoMock.getId(); + Mockito.doNothing().when(_projectAccountDao).removeUserFromProjects(userId); + + accountManagerImpl.deleteAndCleanupUser(userVoMock); + + Mockito.verify(_projectAccountDao).removeUserFromProjects(userId); + } } From b3dc402aa8f83960f410d68f4ccdf12a6ca763bb Mon Sep 17 00:00:00 2001 From: Wei Zhou Date: Wed, 4 Dec 2024 08:11:28 +0100 Subject: [PATCH 3/6] engine/schema: move SQLs to 4.20.0 to 4.20.1 upgrade (#10018) --- .../api/command/admin/management/ListMgmtsCmd.java | 2 +- .../src/main/resources/META-INF/db/schema-41910to42000.sql | 7 ------- .../src/main/resources/META-INF/db/schema-42000to42010.sql | 7 +++++++ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/management/ListMgmtsCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/management/ListMgmtsCmd.java index 6b72deb0775..7b7eae1d0e9 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/management/ListMgmtsCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/management/ListMgmtsCmd.java @@ -42,7 +42,7 @@ public class ListMgmtsCmd extends BaseListCmd { @Parameter(name = ApiConstants.PEERS, type = CommandType.BOOLEAN, description = "Whether to return the management server peers or not. By default, the management server peers will not be returned.", - since = "4.20.0.0") + since = "4.20.1.0") private Boolean peers; ///////////////////////////////////////////////////// diff --git a/engine/schema/src/main/resources/META-INF/db/schema-41910to42000.sql b/engine/schema/src/main/resources/META-INF/db/schema-41910to42000.sql index 97ee1df8b67..c36b71c2f25 100644 --- a/engine/schema/src/main/resources/META-INF/db/schema-41910to42000.sql +++ b/engine/schema/src/main/resources/META-INF/db/schema-41910to42000.sql @@ -425,10 +425,3 @@ INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid, hypervisor_type, hypervi CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.vm_instance', 'delete_protection', 'boolean DEFAULT FALSE COMMENT "delete protection for vm" '); CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.volumes', 'delete_protection', 'boolean DEFAULT FALSE COMMENT "delete protection for volumes" '); - --- Modify index for mshost_peer -DELETE FROM `cloud`.`mshost_peer`; -CALL `cloud`.`IDEMPOTENT_DROP_FOREIGN_KEY`('cloud.mshost_peer','fk_mshost_peer__owner_mshost'); -CALL `cloud`.`IDEMPOTENT_DROP_INDEX`('i_mshost_peer__owner_peer_runid','mshost_peer'); -CALL `cloud`.`IDEMPOTENT_ADD_UNIQUE_KEY`('cloud.mshost_peer', 'i_mshost_peer__owner_peer', '(owner_mshost, peer_mshost)'); -CALL `cloud`.`IDEMPOTENT_ADD_FOREIGN_KEY`('cloud.mshost_peer', 'fk_mshost_peer__owner_mshost', '(owner_mshost)', '`mshost`(`id`)'); diff --git a/engine/schema/src/main/resources/META-INF/db/schema-42000to42010.sql b/engine/schema/src/main/resources/META-INF/db/schema-42000to42010.sql index 31c4928d81b..570627a8da5 100644 --- a/engine/schema/src/main/resources/META-INF/db/schema-42000to42010.sql +++ b/engine/schema/src/main/resources/META-INF/db/schema-42000to42010.sql @@ -22,3 +22,10 @@ -- Add column api_key_access to user and account tables CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.user', 'api_key_access', 'boolean DEFAULT NULL COMMENT "is api key access allowed for the user" AFTER `secret_key`'); CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.account', 'api_key_access', 'boolean DEFAULT NULL COMMENT "is api key access allowed for the account" '); + +-- Modify index for mshost_peer +DELETE FROM `cloud`.`mshost_peer`; +CALL `cloud`.`IDEMPOTENT_DROP_FOREIGN_KEY`('cloud.mshost_peer','fk_mshost_peer__owner_mshost'); +CALL `cloud`.`IDEMPOTENT_DROP_INDEX`('i_mshost_peer__owner_peer_runid','mshost_peer'); +CALL `cloud`.`IDEMPOTENT_ADD_UNIQUE_KEY`('cloud.mshost_peer', 'i_mshost_peer__owner_peer', '(owner_mshost, peer_mshost)'); +CALL `cloud`.`IDEMPOTENT_ADD_FOREIGN_KEY`('cloud.mshost_peer', 'fk_mshost_peer__owner_mshost', '(owner_mshost)', '`mshost`(`id`)'); From a2ea719bcedd79678fcb5d9d1452f0f06b3c3b73 Mon Sep 17 00:00:00 2001 From: dahn Date: Wed, 4 Dec 2024 09:50:23 +0100 Subject: [PATCH 4/6] cloudstack-migrate-databases: sql AND added (#10033) --- .../java/com/cloud/utils/crypt/EncryptionSecretKeyChanger.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/db/src/main/java/com/cloud/utils/crypt/EncryptionSecretKeyChanger.java b/framework/db/src/main/java/com/cloud/utils/crypt/EncryptionSecretKeyChanger.java index 961c537d0da..e96b0a00894 100644 --- a/framework/db/src/main/java/com/cloud/utils/crypt/EncryptionSecretKeyChanger.java +++ b/framework/db/src/main/java/com/cloud/utils/crypt/EncryptionSecretKeyChanger.java @@ -656,7 +656,7 @@ public class EncryptionSecretKeyChanger { String sqlTemplateDeployAsIsDetails = "SELECT template_deploy_as_is_details.value " + "FROM template_deploy_as_is_details JOIN vm_instance " + "WHERE template_deploy_as_is_details.template_id = vm_instance.vm_template_id " + - "vm_instance.id = %s AND template_deploy_as_is_details.name = '%s' LIMIT 1"; + "AND vm_instance.id = %s AND template_deploy_as_is_details.name = '%s' LIMIT 1"; try (PreparedStatement selectPstmt = conn.prepareStatement("SELECT id, vm_id, name, value FROM user_vm_deploy_as_is_details"); ResultSet rs = selectPstmt.executeQuery(); PreparedStatement updatePstmt = conn.prepareStatement("UPDATE user_vm_deploy_as_is_details SET value=? WHERE id=?") From 52584d93dc785452cc87013103bd2b09372763b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bernardo=20De=20Marco=20Gon=C3=A7alves?= Date: Wed, 4 Dec 2024 07:17:27 -0300 Subject: [PATCH 5/6] Prevent password updates for SAML and LDAP users (#9999) --- .../com/cloud/user/AccountManagerImpl.java | 8 +++++ .../cloud/user/AccountManagerImplTest.java | 30 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/server/src/main/java/com/cloud/user/AccountManagerImpl.java b/server/src/main/java/com/cloud/user/AccountManagerImpl.java index 412a5b58282..c21d8b830dd 100644 --- a/server/src/main/java/com/cloud/user/AccountManagerImpl.java +++ b/server/src/main/java/com/cloud/user/AccountManagerImpl.java @@ -1459,6 +1459,8 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M *
    *
  • If 'password' is blank, we throw an {@link InvalidParameterValueException}; *
  • If 'current password' is not provided and user is not an Admin, we throw an {@link InvalidParameterValueException}; + *
  • If the user whose password is being changed has a source equal to {@link User.Source#SAML2}, {@link User.Source#SAML2DISABLED} or {@link User.Source#LDAP}, + * we throw an {@link InvalidParameterValueException}; *
  • If a normal user is calling this method, we use {@link #validateCurrentPassword(UserVO, String)} to check if the provided old password matches the database one; *
* @@ -1473,6 +1475,12 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M throw new InvalidParameterValueException("Password cannot be empty or blank."); } + User.Source userSource = user.getSource(); + if (userSource == User.Source.SAML2 || userSource == User.Source.SAML2DISABLED || userSource == User.Source.LDAP) { + s_logger.warn(String.format("Unable to update the password for user [%d], as its source is [%s].", user.getId(), user.getSource().toString())); + throw new InvalidParameterValueException("CloudStack does not support updating passwords for SAML or LDAP users. Please contact your cloud administrator for assistance."); + } + passwordPolicy.verifyIfPasswordCompliesWithPasswordPolicies(newPassword, user.getUsername(), getAccount(user.getAccountId()).getDomainId()); Account callingAccount = getCurrentCallingAccount(); diff --git a/server/src/test/java/com/cloud/user/AccountManagerImplTest.java b/server/src/test/java/com/cloud/user/AccountManagerImplTest.java index 3ecb4f2f1cf..a98d187b5a9 100644 --- a/server/src/test/java/com/cloud/user/AccountManagerImplTest.java +++ b/server/src/test/java/com/cloud/user/AccountManagerImplTest.java @@ -745,6 +745,36 @@ public class AccountManagerImplTest extends AccountManagetImplTestBase { accountManagerImpl.validateUserPasswordAndUpdateIfNeeded(newPassword, userVoMock, currentPassword); } + @Test(expected = InvalidParameterValueException.class) + public void validateUserPasswordAndUpdateIfNeededTestSaml2UserShouldNotBeAllowedToUpdateTheirPassword() { + String newPassword = "newPassword"; + String currentPassword = "theCurrentPassword"; + + Mockito.when(userVoMock.getSource()).thenReturn(User.Source.SAML2); + + accountManagerImpl.validateUserPasswordAndUpdateIfNeeded(newPassword, userVoMock, currentPassword); + } + + @Test(expected = InvalidParameterValueException.class) + public void validateUserPasswordAndUpdateIfNeededTestSaml2DisabledUserShouldNotBeAllowedToUpdateTheirPassword() { + String newPassword = "newPassword"; + String currentPassword = "theCurrentPassword"; + + Mockito.when(userVoMock.getSource()).thenReturn(User.Source.SAML2DISABLED); + + accountManagerImpl.validateUserPasswordAndUpdateIfNeeded(newPassword, userVoMock, currentPassword); + } + + @Test(expected = InvalidParameterValueException.class) + public void validateUserPasswordAndUpdateIfNeededTestLdapUserShouldNotBeAllowedToUpdateTheirPassword() { + String newPassword = "newPassword"; + String currentPassword = "theCurrentPassword"; + + Mockito.when(userVoMock.getSource()).thenReturn(User.Source.LDAP); + + accountManagerImpl.validateUserPasswordAndUpdateIfNeeded(newPassword, userVoMock, currentPassword); + } + private String configureUserMockAuthenticators(String newPassword) { accountManagerImpl._userPasswordEncoders = new ArrayList<>(); UserAuthenticator authenticatorMock1 = Mockito.mock(UserAuthenticator.class); From 9960e400309a74520c94a6ca9c8f02147bbce14c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bernardo=20De=20Marco=20Gon=C3=A7alves?= Date: Wed, 4 Dec 2024 09:04:50 -0300 Subject: [PATCH 6/6] UI: Fix userdata and load balancer selection (#10016) --- ui/src/views/compute/DeployVM.vue | 12 +++++------- .../views/compute/wizard/LoadBalancerSelection.vue | 9 +++++++++ ui/src/views/compute/wizard/UserDataSelection.vue | 10 +++++----- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/ui/src/views/compute/DeployVM.vue b/ui/src/views/compute/DeployVM.vue index 3c4742d64b2..cb9f4a6dce7 100644 --- a/ui/src/views/compute/DeployVM.vue +++ b/ui/src/views/compute/DeployVM.vue @@ -1940,18 +1940,16 @@ export default { this.form.userdataid = undefined return } + this.form.userdataid = id this.userDataParams = [] api('listUserData', { id: id }).then(json => { const resp = json?.listuserdataresponse?.userdata || [] if (resp[0]) { - var params = resp[0].params - if (params) { - var dataParams = params.split(',') - } - var that = this - dataParams.forEach(function (val, index) { - that.userDataParams.push({ + const params = resp[0].params + const dataParams = params ? params.split(',') : [] + dataParams.forEach((val, index) => { + this.userDataParams.push({ id: index, key: val }) diff --git a/ui/src/views/compute/wizard/LoadBalancerSelection.vue b/ui/src/views/compute/wizard/LoadBalancerSelection.vue index e2ffb991e98..3ba66241d56 100644 --- a/ui/src/views/compute/wizard/LoadBalancerSelection.vue +++ b/ui/src/views/compute/wizard/LoadBalancerSelection.vue @@ -30,6 +30,7 @@ :rowKey="record => record.id" :pagination="false" :rowSelection="rowSelection" + :customRow="onClickRow" size="middle" :scroll="{ y: 225 }">