diff --git a/backend/src/main/java/io/metersphere/controller/TestResourcePoolController.java b/backend/src/main/java/io/metersphere/controller/TestResourcePoolController.java index 763b29fe5b..2ce7bf4ff2 100644 --- a/backend/src/main/java/io/metersphere/controller/TestResourcePoolController.java +++ b/backend/src/main/java/io/metersphere/controller/TestResourcePoolController.java @@ -3,11 +3,14 @@ package io.metersphere.controller; import com.github.pagehelper.Page; import com.github.pagehelper.PageHelper; import io.metersphere.base.domain.TestResourcePool; +import io.metersphere.commons.constants.RoleConstants; import io.metersphere.commons.utils.PageUtils; import io.metersphere.commons.utils.Pager; import io.metersphere.controller.request.resourcepool.QueryResourcePoolRequest; import io.metersphere.dto.TestResourcePoolDTO; import io.metersphere.service.TestResourcePoolService; +import org.apache.shiro.authz.annotation.Logical; +import org.apache.shiro.authz.annotation.RequiresRoles; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; @@ -15,6 +18,7 @@ import java.util.List; @RequestMapping("testresourcepool") @RestController +@RequiresRoles(RoleConstants.ADMIN) public class TestResourcePoolController { @Resource @@ -35,6 +39,11 @@ public class TestResourcePoolController { testResourcePoolService.updateTestResourcePool(testResourcePoolDTO); } + @GetMapping("/update/{poolId}/{status}") + public void updateTestResourcePoolStatus(@PathVariable String poolId, @PathVariable String status) { + testResourcePoolService.updateTestResourcePoolStatus(poolId, status); + } + @PostMapping("list/{goPage}/{pageSize}") public Pager> listResourcePools(@PathVariable int goPage, @PathVariable int pageSize, @RequestBody QueryResourcePoolRequest request) { Page page = PageHelper.startPage(goPage, pageSize, true); @@ -42,6 +51,7 @@ public class TestResourcePoolController { } @GetMapping("list/all/valid") + @RequiresRoles(value = {RoleConstants.TEST_MANAGER, RoleConstants.TEST_USER, RoleConstants.TEST_VIEWER}, logical = Logical.OR) public List listValidResourcePools() { return testResourcePoolService.listValidResourcePools(); } diff --git a/backend/src/main/java/io/metersphere/service/TestResourcePoolService.java b/backend/src/main/java/io/metersphere/service/TestResourcePoolService.java index 20d255fa05..0be3736ad5 100644 --- a/backend/src/main/java/io/metersphere/service/TestResourcePoolService.java +++ b/backend/src/main/java/io/metersphere/service/TestResourcePoolService.java @@ -72,6 +72,36 @@ public class TestResourcePoolService { testResourcePoolMapper.updateByPrimaryKeySelective(testResourcePool); } + + public void updateTestResourcePoolStatus(String poolId, String status) { + TestResourcePool testResourcePool = testResourcePoolMapper.selectByPrimaryKey(poolId); + if (testResourcePool == null) { + MSException.throwException("Resource Pool not found."); + } + testResourcePool.setUpdateTime(System.currentTimeMillis()); + testResourcePool.setStatus(status); + // 禁用资源池 + if (INVALID.name().equals(status)) { + testResourcePoolMapper.updateByPrimaryKeySelective(testResourcePool); + return; + } + TestResourcePoolDTO testResourcePoolDTO = new TestResourcePoolDTO(); + try { + BeanUtils.copyProperties(testResourcePoolDTO, testResourcePool); + TestResourceExample example2 = new TestResourceExample(); + example2.createCriteria().andTestResourcePoolIdEqualTo(poolId); + List testResources = testResourceMapper.selectByExampleWithBLOBs(example2); + testResourcePoolDTO.setResources(testResources); + if (validateTestResourcePool(testResourcePoolDTO)) { + testResourcePoolMapper.updateByPrimaryKeySelective(testResourcePool); + } else { + MSException.throwException("Resource Pool is invalid."); + } + } catch (IllegalAccessException | InvocationTargetException e) { + LogUtil.error(e); + } + } + public List listResourcePools(QueryResourcePoolRequest request) { TestResourcePoolExample example = new TestResourcePoolExample(); TestResourcePoolExample.Criteria criteria = example.createCriteria(); @@ -96,15 +126,14 @@ public class TestResourcePoolService { return testResourcePoolDTOS; } - private void validateTestResourcePool(TestResourcePoolDTO testResourcePool) { + private boolean validateTestResourcePool(TestResourcePoolDTO testResourcePool) { if (StringUtils.equalsIgnoreCase(testResourcePool.getType(), ResourcePoolTypeEnum.K8S.name())) { - validateK8s(testResourcePool); - return; + return validateK8s(testResourcePool); } - validateNodes(testResourcePool); + return validateNodes(testResourcePool); } - private void validateNodes(TestResourcePoolDTO testResourcePool) { + private boolean validateNodes(TestResourcePoolDTO testResourcePool) { if (CollectionUtils.isEmpty(testResourcePool.getResources())) { MSException.throwException(Translator.get("no_nodes_message")); } @@ -121,19 +150,21 @@ public class TestResourcePoolService { MSException.throwException(Translator.get("duplicate_node_ip")); } testResourcePool.setStatus(VALID.name()); + boolean isValid = true; for (TestResource resource : testResourcePool.getResources()) { NodeDTO nodeDTO = JSON.parseObject(resource.getConfiguration(), NodeDTO.class); boolean isValidate = validateNode(nodeDTO); if (!isValidate) { testResourcePool.setStatus(ResourceStatusEnum.INVALID.name()); resource.setStatus(ResourceStatusEnum.INVALID.name()); + isValid = false; } else { resource.setStatus(VALID.name()); } resource.setTestResourcePoolId(testResourcePool.getId()); updateTestResource(resource); - } + return isValid; } private boolean validateNode(NodeDTO node) { @@ -145,7 +176,7 @@ public class TestResourcePoolService { } } - private void validateK8s(TestResourcePoolDTO testResourcePool) { + private boolean validateK8s(TestResourcePoolDTO testResourcePool) { if (CollectionUtils.isEmpty(testResourcePool.getResources()) || testResourcePool.getResources().size() != 1) { throw new RuntimeException(Translator.get("only_one_k8s")); @@ -153,18 +184,21 @@ public class TestResourcePoolService { TestResource testResource = testResourcePool.getResources().get(0); testResource.setTestResourcePoolId(testResourcePool.getId()); + boolean isValid; try { KubernetesProvider provider = new KubernetesProvider(testResource.getConfiguration()); provider.validateCredential(); testResource.setStatus(VALID.name()); testResourcePool.setStatus(VALID.name()); + isValid = true; } catch (Exception e) { testResource.setStatus(ResourceStatusEnum.INVALID.name()); testResourcePool.setStatus(ResourceStatusEnum.INVALID.name()); + isValid = false; } deleteTestResource(testResourcePool.getId()); updateTestResource(testResource); - + return isValid; } private void updateTestResource(TestResource testResource) { @@ -191,7 +225,7 @@ public class TestResourcePoolService { for (TestResourcePoolDTO pool : testResourcePools) { // 手动设置成无效的, 排除 if (INVALID.name().equals(pool.getStatus())) { - continue; + continue; } try { updateTestResourcePool(pool); @@ -205,4 +239,5 @@ public class TestResourcePoolService { example.createCriteria().andStatusEqualTo(ResourceStatusEnum.VALID.name()); return testResourcePoolMapper.selectByExample(example); } + } diff --git a/frontend/src/business/components/settings/system/TestResourcePool.vue b/frontend/src/business/components/settings/system/TestResourcePool.vue index 0ad35e9105..5796ce6faf 100644 --- a/frontend/src/business/components/settings/system/TestResourcePool.vue +++ b/frontend/src/business/components/settings/system/TestResourcePool.vue @@ -413,9 +413,13 @@ this.form = {}; }, changeSwitch(row) { - this.result = this.$post('/testresourcepool/update', row).then(() => { - this.$success(this.$t('test_resource_pool.status_change_success')); - }) + this.result = this.$get('/testresourcepool/update/' + row.id + '/' + row.status) + .then(() => { + this.$success(this.$t('test_resource_pool.status_change_success')); + }).catch(() => { + this.$error(this.$t('test_resource_pool.status_change_failed')); + row.status = 'INVALID'; + }) } } } diff --git a/frontend/src/i18n/en-US.js b/frontend/src/i18n/en-US.js index 499f596490..0580e9c2ce 100644 --- a/frontend/src/i18n/en-US.js +++ b/frontend/src/i18n/en-US.js @@ -314,6 +314,7 @@ export default { 'fill_the_data': 'Please complete the data', 'delete_prompt': 'This operation will permanently delete the resource pool, continue?', 'status_change_success': 'Successfully changed the status!', + 'status_change_failed': 'Failed to change the status!', }, i18n: { 'home': 'Home' diff --git a/frontend/src/i18n/zh-CN.js b/frontend/src/i18n/zh-CN.js index a626cb2cd8..13b1b574de 100644 --- a/frontend/src/i18n/zh-CN.js +++ b/frontend/src/i18n/zh-CN.js @@ -359,6 +359,7 @@ export default { 'fill_the_data': '请完善数据', 'delete_prompt': '此操作将永久删除该资源池, 是否继续?', 'status_change_success': '状态修改成功!', + 'status_change_failed': '状态修改失败!', }, i18n: { 'home': '首页'