mirror of
https://gitee.com/dromara/Jpom.git
synced 2024-12-02 11:58:01 +08:00
fix 节点脚本支持全局共享同步节点、节点管理查看脚本重复问题
This commit is contained in:
parent
5f7caf6684
commit
d5bbe166aa
11
CHANGELOG.md
11
CHANGELOG.md
@ -1,6 +1,15 @@
|
||||
# 🚀 版本日志
|
||||
|
||||
### 2.10.38.9-beta
|
||||
### 2.10.38.10-beta (2023-03-30)
|
||||
|
||||
|
||||
### 🐞 解决BUG、优化功能
|
||||
|
||||
1. 【server】修复 节点脚本支持全局共享同步节点、节点管理查看脚本重复问题(感谢@奇奇)
|
||||
|
||||
------
|
||||
|
||||
### 2.10.38.9-beta (2023-03-30)
|
||||
|
||||
### 🐣 新增功能
|
||||
|
||||
|
@ -31,6 +31,7 @@ import io.jpom.common.forward.NodeForward;
|
||||
import io.jpom.common.forward.NodeUrl;
|
||||
import io.jpom.common.validator.ValidatorItem;
|
||||
import io.jpom.model.data.NodeModel;
|
||||
import io.jpom.model.data.WorkspaceModel;
|
||||
import io.jpom.model.script.ScriptModel;
|
||||
import io.jpom.model.user.UserModel;
|
||||
import io.jpom.permission.ClassFeature;
|
||||
@ -41,6 +42,7 @@ import io.jpom.script.CommandParam;
|
||||
import io.jpom.service.node.script.NodeScriptServer;
|
||||
import io.jpom.service.script.ScriptExecuteLogServer;
|
||||
import io.jpom.service.script.ScriptServer;
|
||||
import io.jpom.service.system.WorkspaceService;
|
||||
import io.jpom.service.user.TriggerTokenLogServer;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.util.Assert;
|
||||
@ -52,10 +54,8 @@ import top.jpom.model.PageResultDto;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author bwcx_jzy
|
||||
@ -70,15 +70,18 @@ public class ScriptController extends BaseServerController {
|
||||
private final NodeScriptServer nodeScriptServer;
|
||||
private final ScriptExecuteLogServer scriptExecuteLogServer;
|
||||
private final TriggerTokenLogServer triggerTokenLogServer;
|
||||
private final WorkspaceService workspaceService;
|
||||
|
||||
public ScriptController(ScriptServer scriptServer,
|
||||
NodeScriptServer nodeScriptServer,
|
||||
ScriptExecuteLogServer scriptExecuteLogServer,
|
||||
TriggerTokenLogServer triggerTokenLogServer) {
|
||||
TriggerTokenLogServer triggerTokenLogServer,
|
||||
WorkspaceService workspaceService) {
|
||||
this.scriptServer = scriptServer;
|
||||
this.nodeScriptServer = nodeScriptServer;
|
||||
this.scriptExecuteLogServer = scriptExecuteLogServer;
|
||||
this.triggerTokenLogServer = triggerTokenLogServer;
|
||||
this.workspaceService = workspaceService;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -100,8 +103,8 @@ public class ScriptController extends BaseServerController {
|
||||
*/
|
||||
@GetMapping(value = "list-all", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Feature(method = MethodFeature.LIST)
|
||||
public JsonMessage<List<ScriptModel>> scriptListAll() {
|
||||
List<ScriptModel> pageResultDto = scriptServer.listByWorkspace(getRequest());
|
||||
public JsonMessage<List<ScriptModel>> scriptListAll(HttpServletRequest request) {
|
||||
List<ScriptModel> pageResultDto = scriptServer.listByWorkspace(request);
|
||||
return JsonMessage.success("success", pageResultDto);
|
||||
}
|
||||
|
||||
@ -142,8 +145,8 @@ public class ScriptController extends BaseServerController {
|
||||
}
|
||||
|
||||
private void syncDelNodeScript(ScriptModel scriptModel, Collection<String> delNode) {
|
||||
for (String s : delNode) {
|
||||
NodeModel byKey = nodeService.getByKey(s, getRequest());
|
||||
for (String nodeId : delNode) {
|
||||
NodeModel byKey = nodeService.getByKey(nodeId);
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("id", scriptModel.getId());
|
||||
JsonMessage<String> request = NodeForward.request(byKey, NodeUrl.Script_Del, jsonObject);
|
||||
@ -160,7 +163,7 @@ public class ScriptController extends BaseServerController {
|
||||
this.syncDelNodeScript(scriptModel, delNode);
|
||||
// 更新
|
||||
for (String newNodeId : newNodeIds) {
|
||||
NodeModel byKey = nodeService.getByKey(newNodeId, request);
|
||||
NodeModel byKey = nodeService.getByKey(newNodeId);
|
||||
Assert.notNull(byKey, "没有找到对应的节点");
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("id", scriptModel.getId());
|
||||
@ -170,7 +173,7 @@ public class ScriptController extends BaseServerController {
|
||||
jsonObject.put("defArgs", scriptModel.getDefArgs());
|
||||
jsonObject.put("description", scriptModel.getDescription());
|
||||
jsonObject.put("name", scriptModel.getName());
|
||||
jsonObject.put("workspaceId", scriptModel.getWorkspaceId());
|
||||
jsonObject.put("workspaceId", byKey.getWorkspaceId());
|
||||
jsonObject.put("global", scriptModel.global());
|
||||
jsonObject.put("nodeId", byKey.getId());
|
||||
JsonMessage<String> jsonMessage = NodeForward.request(byKey, NodeUrl.Script_Save, jsonObject);
|
||||
@ -198,6 +201,42 @@ public class ScriptController extends BaseServerController {
|
||||
return JsonMessage.success("删除成功");
|
||||
}
|
||||
|
||||
@GetMapping(value = "get", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Feature(method = MethodFeature.LIST)
|
||||
public JsonMessage<JSONObject> get(String id, HttpServletRequest request) {
|
||||
String workspaceId = scriptServer.getCheckUserWorkspace(request);
|
||||
ScriptModel server = scriptServer.getByKeyAndGlobal(id, request);
|
||||
Assert.notNull(server, "没有对应的脚本");
|
||||
String nodeIds = server.getNodeIds();
|
||||
List<String> newNodeIds = StrUtil.splitTrim(nodeIds, StrUtil.COMMA);
|
||||
List<JSONObject> nodeList = newNodeIds.stream()
|
||||
.map(s -> {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
NodeModel nodeModel = nodeService.getByKey(s);
|
||||
if (nodeModel == null) {
|
||||
jsonObject.put("nodeName", "未知(数据丢失)");
|
||||
} else {
|
||||
jsonObject.put("nodeName", nodeModel.getName());
|
||||
jsonObject.put("nodeId", nodeModel.getId());
|
||||
jsonObject.put("workspaceId", nodeModel.getWorkspaceId());
|
||||
WorkspaceModel workspaceModel = workspaceService.getByKey(nodeModel.getWorkspaceId());
|
||||
jsonObject.put("workspaceName", Optional.ofNullable(workspaceModel).map(WorkspaceModel::getName).orElse("未知(数据丢失)"));
|
||||
}
|
||||
return jsonObject;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
// 判断是否可以编辑节点
|
||||
boolean prohibitSync = nodeList.stream().anyMatch(jsonObject -> {
|
||||
String workspaceId11 = (String) jsonObject.get("workspaceId");
|
||||
return !StrUtil.equals(workspaceId11, workspaceId);
|
||||
});
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("data", server);
|
||||
jsonObject.put("nodeList", nodeList);
|
||||
jsonObject.put("prohibitSync", prohibitSync);
|
||||
return JsonMessage.success("", jsonObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* 释放脚本关联的节点
|
||||
*
|
||||
|
@ -37,49 +37,57 @@ import org.springframework.util.Assert;
|
||||
@Data
|
||||
public abstract class BaseNodeModel extends BaseWorkspaceModel {
|
||||
|
||||
/**
|
||||
* 节点Id
|
||||
*
|
||||
* @see io.jpom.model.data.NodeModel
|
||||
*/
|
||||
private String nodeId;
|
||||
/**
|
||||
* 节点Id
|
||||
*
|
||||
* @see io.jpom.model.data.NodeModel
|
||||
*/
|
||||
private String nodeId;
|
||||
/**
|
||||
* 节点名称
|
||||
*/
|
||||
private String nodeName;
|
||||
/**
|
||||
* 工作空间名称
|
||||
*/
|
||||
private String workspaceName;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString();
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString();
|
||||
}
|
||||
|
||||
public String fullId() {
|
||||
String workspaceId = this.getWorkspaceId();
|
||||
public String fullId() {
|
||||
String workspaceId = this.getWorkspaceId();
|
||||
|
||||
String nodeId = this.getNodeId();
|
||||
String nodeId = this.getNodeId();
|
||||
|
||||
String dataId = this.dataId();
|
||||
String dataId = this.dataId();
|
||||
|
||||
return BaseNodeModel.fullId(workspaceId, nodeId, dataId);
|
||||
}
|
||||
return BaseNodeModel.fullId(workspaceId, nodeId, dataId);
|
||||
}
|
||||
|
||||
public static String fullId(String workspaceId, String nodeId, String dataId) {
|
||||
public static String fullId(String workspaceId, String nodeId, String dataId) {
|
||||
|
||||
Assert.hasText(workspaceId, "workspaceId");
|
||||
Assert.hasText(workspaceId, "workspaceId");
|
||||
|
||||
Assert.hasText(workspaceId, "nodeId");
|
||||
Assert.hasText(workspaceId, "nodeId");
|
||||
|
||||
Assert.hasText(workspaceId, "dataId");
|
||||
return SecureUtil.sha1(workspaceId + nodeId + dataId);
|
||||
}
|
||||
Assert.hasText(workspaceId, "dataId");
|
||||
return SecureUtil.sha1(workspaceId + nodeId + dataId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取数据ID
|
||||
*
|
||||
* @return 数据ID
|
||||
*/
|
||||
public abstract String dataId();
|
||||
/**
|
||||
* 获取数据ID
|
||||
*
|
||||
* @return 数据ID
|
||||
*/
|
||||
public abstract String dataId();
|
||||
|
||||
/**
|
||||
* 设置数据ID
|
||||
*
|
||||
* @param id 数据ID
|
||||
*/
|
||||
public abstract void dataId(String id);
|
||||
/**
|
||||
* 设置数据ID
|
||||
*
|
||||
* @param id 数据ID
|
||||
*/
|
||||
public abstract void dataId(String id);
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ public abstract class BaseNodeService<T extends BaseNodeModel> extends BaseGloba
|
||||
Assert.notNull(nodeModel, "不存在对应的节点");
|
||||
Assert.state(StrUtil.equals(workspaceId, nodeModel.getWorkspaceId()), "节点的工作空间和操作的工作空间补一致");
|
||||
paramMap.remove("workspaceId");
|
||||
paramMap.remove("nodeId");
|
||||
paramMap.put("nodeId", nodeId);
|
||||
paramMap.put("workspaceId:in", workspaceId + StrUtil.COMMA + ServerConst.WORKSPACE_GLOBAL);
|
||||
|
||||
return super.listPage(paramMap);
|
||||
@ -180,6 +180,9 @@ public abstract class BaseNodeService<T extends BaseNodeModel> extends BaseGloba
|
||||
return StrUtil.equals(nodeModel.getWorkspaceId(), item.getWorkspaceId());
|
||||
})
|
||||
.peek(item -> {
|
||||
item.setNodeName(nodeModel.getName());
|
||||
WorkspaceModel workspaceModel = workspaceService.getByKey(nodeModel.getWorkspaceId());
|
||||
item.setWorkspaceName(Optional.ofNullable(workspaceModel).map(WorkspaceModel::getName).orElse("数据不存在"));
|
||||
cacheIds.remove(item.dataId());
|
||||
// 需要删除相反的工作空间的数据(避免出现一个脚本同步出2条数据的问题)
|
||||
if (StrUtil.equals(item.getWorkspaceId(), ServerConst.WORKSPACE_GLOBAL)) {
|
||||
|
@ -49,3 +49,9 @@ ADD,SERVER_SCRIPT_INFO,createUser,String,50,,创建人,false
|
||||
ADD,BUILD_INFO,statusMsg,TEXT,,,状态信息
|
||||
ADD,BUILDHISTORYLOG,statusMsg,TEXT,,,状态信息
|
||||
ADD,SCRIPT_INFO,createUser,String,50,,创建人,false
|
||||
ADD,SCRIPT_INFO,nodeName,String,50,,节点名称,false
|
||||
ADD,PROJECT_INFO,nodeName,String,50,,节点名称,false
|
||||
ADD,SCRIPT_EXECUTE_LOG,nodeName,String,50,,节点名称,false
|
||||
ADD,SCRIPT_INFO,workspaceName,String,50,,工作空间名称,false
|
||||
ADD,PROJECT_INFO,workspaceName,String,50,,工作空间名称,false
|
||||
ADD,SCRIPT_EXECUTE_LOG,workspaceName,String,50,,工作空间名称,false
|
||||
|
|
@ -11,17 +11,6 @@ export function getScriptList(params) {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* script 服务端中的所有列表
|
||||
*/
|
||||
export function getScriptListAll(params) {
|
||||
return axios({
|
||||
url: "/script/list-all",
|
||||
method: "get",
|
||||
params: params,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存脚本
|
||||
* @param {Json} params
|
||||
@ -101,6 +90,14 @@ export function syncToWorkspace(params) {
|
||||
});
|
||||
}
|
||||
|
||||
export function getScriptItem(params) {
|
||||
return axios({
|
||||
url: "/script/get",
|
||||
method: "get",
|
||||
params: params,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取触发器地址
|
||||
* @param {*} id
|
||||
|
@ -835,7 +835,7 @@ import { getBuildGroupAll, editBuild, getBranchList, buildModeMap, releaseMethod
|
||||
import { getSshListAll } from "@/api/ssh";
|
||||
import { getRepositoryInfo } from "@/api/repository";
|
||||
import { getNodeListAll, getProjectListAll } from "@/api/node";
|
||||
import { getScriptListAll } from "@/api/server-script";
|
||||
// import { getScriptListAll } from "@/api/server-script";
|
||||
import { getDishPatchListAll } from "@/api/dispatch";
|
||||
import { itemGroupBy, CRON_DATA_SOURCE, randomStr } from "@/utils/const";
|
||||
import { mapGetters } from "vuex";
|
||||
@ -930,7 +930,7 @@ export default {
|
||||
dockerSwarmList: [],
|
||||
//集群下 服务下拉数据
|
||||
swarmServiceListOptions: [],
|
||||
scriptList: [],
|
||||
// scriptList: [],
|
||||
groupList: [],
|
||||
temp: {},
|
||||
rules: {
|
||||
@ -1046,7 +1046,7 @@ export default {
|
||||
this.loadNodeProjectList();
|
||||
this.loadSshList();
|
||||
this.loadDockerSwarmListAll();
|
||||
this.loadScriptListList();
|
||||
// this.loadScriptListList();
|
||||
|
||||
this.tempExtraData = {
|
||||
cacheBuild: true,
|
||||
@ -1092,7 +1092,7 @@ export default {
|
||||
this.loadDispatchList();
|
||||
this.loadDockerSwarmListAll();
|
||||
this.loadNodeProjectList();
|
||||
this.loadScriptListList();
|
||||
// this.loadScriptListList();
|
||||
this.loadSshList().then(() => {
|
||||
if (this.tempExtraData.releaseMethodDataId_3) {
|
||||
//
|
||||
@ -1108,14 +1108,14 @@ export default {
|
||||
}
|
||||
});
|
||||
},
|
||||
// 加载脚本列表
|
||||
loadScriptListList() {
|
||||
getScriptListAll().then((res) => {
|
||||
if (res.code === 200) {
|
||||
this.scriptList = res.data;
|
||||
}
|
||||
});
|
||||
},
|
||||
// // 加载脚本列表
|
||||
// loadScriptListList() {
|
||||
// getScriptListAll().then((res) => {
|
||||
// if (res.code === 200) {
|
||||
// this.scriptList = res.data;
|
||||
// }
|
||||
// });
|
||||
// },
|
||||
// 加载节点分发列表
|
||||
loadDispatchList() {
|
||||
this.dispatchList = [];
|
||||
|
@ -36,9 +36,7 @@
|
||||
<a-tooltip slot="tooltip" slot-scope="text" placement="topLeft" :title="text">
|
||||
<span>{{ text }}</span>
|
||||
</a-tooltip>
|
||||
<a-tooltip slot="nodeId" slot-scope="text" placement="topLeft" :title="`${nodeMap[text]} 节点ID: ${text}`">
|
||||
<span>{{ nodeMap[text] }}</span>
|
||||
</a-tooltip>
|
||||
|
||||
<a-tooltip slot="name" @click="handleEdit(record)" slot-scope="text, record" placement="topLeft" :title="text">
|
||||
<!-- <span>{{ text }}</span> -->
|
||||
<a-button type="link" style="padding: 0px" size="small">{{ text }}</a-button>
|
||||
@ -252,7 +250,8 @@ export default {
|
||||
columns: [
|
||||
{ title: "scriptId", dataIndex: "scriptId", ellipsis: true, width: 150, scopedSlots: { customRender: "tooltip" } },
|
||||
{ title: "名称", dataIndex: "name", ellipsis: true, width: 200, scopedSlots: { customRender: "name" } },
|
||||
{ title: "节点名称", dataIndex: "nodeId", ellipsis: true, width: 150, scopedSlots: { customRender: "nodeId" } },
|
||||
{ title: "节点名称", dataIndex: "nodeName", ellipsis: true, width: 150, scopedSlots: { customRender: "tooltip" } },
|
||||
{ title: "工作空间名称", dataIndex: "workspaceName", ellipsis: true, width: 150, scopedSlots: { customRender: "tooltip" } },
|
||||
{ title: "类型", dataIndex: "scriptType", width: 70, align: "center", ellipsis: true, scopedSlots: { customRender: "scriptType" } },
|
||||
{ title: "共享", dataIndex: "workspaceId", ellipsis: true, scopedSlots: { customRender: "global" }, width: "90px" },
|
||||
{ title: "定时执行", dataIndex: "autoExecCron", ellipsis: true, width: 120, scopedSlots: { customRender: "autoExecCron" } },
|
||||
|
@ -129,7 +129,10 @@
|
||||
<a-radio :value="false"> 当前工作空间</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-model-item>
|
||||
<a-form-model-item>
|
||||
<a-form-model-item v-if="temp.prohibitSync" label="禁用分发节点">
|
||||
<a-tag v-for="(item, index) in temp.nodeList" :key="index">节点名称:{{ item.nodeName }} 工作空间:{{ item.workspaceName }}</a-tag>
|
||||
</a-form-model-item>
|
||||
<a-form-model-item v-else>
|
||||
<template slot="label">
|
||||
分发节点
|
||||
<a-tooltip v-show="!temp.id">
|
||||
@ -279,7 +282,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { deleteScript, editScript, getScriptList, syncToWorkspace, unbindScript, getTriggerUrl } from "@/api/server-script";
|
||||
import { deleteScript, editScript, getScriptList, syncToWorkspace, unbindScript, getTriggerUrl, getScriptItem } from "@/api/server-script";
|
||||
import codeEditor from "@/components/codeEditor";
|
||||
import { getNodeListAll } from "@/api/node";
|
||||
import ScriptConsole from "@/pages/script/script-console";
|
||||
@ -316,7 +319,7 @@ export default {
|
||||
columns: [
|
||||
{ title: "id", dataIndex: "id", ellipsis: true, width: 150, scopedSlots: { customRender: "tooltip" } },
|
||||
{ title: "名称", dataIndex: "name", ellipsis: true, width: 150, scopedSlots: { customRender: "tooltip" } },
|
||||
{ title: "共享", dataIndex: "workspaceId", ellipsis: true, scopedSlots: { customRender: "global" }, width: "80px" },
|
||||
{ title: "共享", dataIndex: "workspaceId", ellipsis: true, scopedSlots: { customRender: "global" }, width: "90px" },
|
||||
{ title: "描述", dataIndex: "description", ellipsis: true, width: 300, scopedSlots: { customRender: "tooltip" } },
|
||||
{ title: "定时执行", dataIndex: "autoExecCron", ellipsis: true, width: "100px", scopedSlots: { customRender: "tooltip" } },
|
||||
{
|
||||
@ -406,13 +409,27 @@ export default {
|
||||
},
|
||||
// 修改
|
||||
handleEdit(record) {
|
||||
this.temp = Object.assign({}, record);
|
||||
getScriptItem({
|
||||
id: record.id,
|
||||
}).then((res) => {
|
||||
if (res.code === 200) {
|
||||
const data = res.data.data;
|
||||
this.temp = Object.assign({}, data);
|
||||
|
||||
this.commandParams = record.defArgs ? JSON.parse(record.defArgs) : [];
|
||||
this.commandParams = data?.defArgs ? JSON.parse(data.defArgs) : [];
|
||||
|
||||
this.temp = { ...this.temp, chooseNode: record.nodeIds ? record.nodeIds.split(",") : [], global: record.workspaceId === "GLOBAL", workspaceId: "" };
|
||||
this.editScriptVisible = true;
|
||||
this.getAllNodeList();
|
||||
this.temp = {
|
||||
...this.temp,
|
||||
prohibitSync: res.data.prohibitSync,
|
||||
nodeList: res.data.nodeList,
|
||||
chooseNode: data?.nodeIds ? data.nodeIds.split(",") : [],
|
||||
global: data.workspaceId === "GLOBAL",
|
||||
workspaceId: "",
|
||||
};
|
||||
this.editScriptVisible = true;
|
||||
this.getAllNodeList();
|
||||
}
|
||||
});
|
||||
},
|
||||
// 提交 Script 数据
|
||||
handleEditScriptOk() {
|
||||
@ -436,6 +453,7 @@ export default {
|
||||
}
|
||||
// 提交数据
|
||||
this.temp.nodeIds = this.temp?.chooseNode?.join(",");
|
||||
delete this.temp.nodeList;
|
||||
editScript(this.temp).then((res) => {
|
||||
if (res.code === 200) {
|
||||
// 成功
|
||||
|
Loading…
Reference in New Issue
Block a user