From f34bdd31246e574a0664afce3a0ed99eb0d068be Mon Sep 17 00:00:00 2001 From: bwcx_jzy Date: Mon, 14 Feb 2022 15:09:24 +0800 Subject: [PATCH] pre swarm task list --- .../docker/DockerSwarmInfoController.java | 15 +- .../docker/DockerSwarmServiceController.java | 65 +++++ .../service/docker/DockerInfoService.java | 18 ++ .../io/jpom/DefaultDockerSwarmPluginImpl.java | 55 +++++ .../docker-cli/src/test/java/TestSwarm.java | 46 ++++ web-vue/src/api/docker-swarm.js | 24 ++ web-vue/src/pages/docker/console.vue | 3 - web-vue/src/pages/docker/swarm/console.vue | 59 +++++ web-vue/src/pages/docker/swarm/list.vue | 45 ++-- web-vue/src/pages/docker/swarm/node.vue | 6 +- web-vue/src/pages/docker/swarm/service.vue | 204 ++++++++++++++++ web-vue/src/pages/docker/swarm/task.vue | 224 ++++++++++++++++++ 12 files changed, 727 insertions(+), 37 deletions(-) create mode 100644 modules/server/src/main/java/io/jpom/controller/docker/DockerSwarmServiceController.java create mode 100644 web-vue/src/pages/docker/swarm/console.vue create mode 100644 web-vue/src/pages/docker/swarm/service.vue create mode 100644 web-vue/src/pages/docker/swarm/task.vue diff --git a/modules/server/src/main/java/io/jpom/controller/docker/DockerSwarmInfoController.java b/modules/server/src/main/java/io/jpom/controller/docker/DockerSwarmInfoController.java index 4373414e3..44227a26c 100644 --- a/modules/server/src/main/java/io/jpom/controller/docker/DockerSwarmInfoController.java +++ b/modules/server/src/main/java/io/jpom/controller/docker/DockerSwarmInfoController.java @@ -252,7 +252,7 @@ public class DockerSwarmInfoController extends BaseServerController { String nodeId, String nodeName, String nodeRole) throws Exception { // IPlugin plugin = PluginFactory.getPlugin(DockerSwarmInfoService.DOCKER_PLUGIN_NAME); - Map map = this.getPluginMap(id); + Map map = dockerInfoService.getBySwarmPluginMap(id, getRequest()); map.put("id", nodeId); map.put("name", nodeName); map.put("role", nodeRole); @@ -260,15 +260,6 @@ public class DockerSwarmInfoController extends BaseServerController { return new JsonMessage<>(200, "", listSwarmNodes); } - private Map getPluginMap(String id) { - HttpServletRequest request = getRequest(); - DockerSwarmInfoMode swarmInfoMode1 = dockerSwarmInfoService.getByKey(id, request); - Assert.notNull(swarmInfoMode1, "没有对应的集群"); - // - DockerInfoModel managerSwarmDocker = dockerInfoService.getByKey(swarmInfoMode1.getDockerId(), request); - Assert.notNull(managerSwarmDocker, "对应的 docker 不存在"); - return managerSwarmDocker.toParameter(); - } /** * 修改节点信息 @@ -281,7 +272,7 @@ public class DockerSwarmInfoController extends BaseServerController { public JsonMessage update(@ValidatorItem String id, @ValidatorItem String nodeId, @ValidatorItem String availability, @ValidatorItem String role) throws Exception { // IPlugin plugin = PluginFactory.getPlugin(DockerSwarmInfoService.DOCKER_PLUGIN_NAME); - Map map = this.getPluginMap(id); + Map map = dockerInfoService.getBySwarmPluginMap(id, getRequest()); map.put("nodeId", nodeId); map.put("availability", availability); map.put("role", role); @@ -313,7 +304,7 @@ public class DockerSwarmInfoController extends BaseServerController { plugin.execute("leaveSwarm", parameter, JSONObject.class); } { - Map map = this.getPluginMap(id); + Map map = dockerInfoService.getBySwarmPluginMap(id, getRequest()); map.put("nodeId", nodeId); plugin.execute("removeSwarmNode", map); } diff --git a/modules/server/src/main/java/io/jpom/controller/docker/DockerSwarmServiceController.java b/modules/server/src/main/java/io/jpom/controller/docker/DockerSwarmServiceController.java new file mode 100644 index 000000000..bda2941c3 --- /dev/null +++ b/modules/server/src/main/java/io/jpom/controller/docker/DockerSwarmServiceController.java @@ -0,0 +1,65 @@ +package io.jpom.controller.docker; + +import cn.jiangzeyin.common.JsonMessage; +import cn.jiangzeyin.common.validator.ValidatorItem; +import com.alibaba.fastjson.JSONObject; +import io.jpom.common.BaseServerController; +import io.jpom.plugin.*; +import io.jpom.service.docker.DockerInfoService; +import io.jpom.service.docker.DockerSwarmInfoService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; +import java.util.Map; + +/** + * @author bwcx_jzy + * @since 2022/2/14 + */ +@RestController +@Feature(cls = ClassFeature.DOCKER_SWARM) +@RequestMapping(value = "/docker-swarm-service") +@Slf4j +public class DockerSwarmServiceController extends BaseServerController { + + private final DockerInfoService dockerInfoService; + + public DockerSwarmServiceController(DockerInfoService dockerInfoService) { + this.dockerInfoService = dockerInfoService; + } + + @PostMapping(value = "list", produces = MediaType.APPLICATION_JSON_VALUE) + @Feature(method = MethodFeature.LIST) + public JsonMessage> list( + @ValidatorItem String id, + String serviceId, String serviceName) throws Exception { + // + IPlugin plugin = PluginFactory.getPlugin(DockerSwarmInfoService.DOCKER_PLUGIN_NAME); + Map map = dockerInfoService.getBySwarmPluginMap(id, getRequest()); + map.put("id", serviceId); + map.put("name", serviceName); + List listSwarmNodes = (List) plugin.execute("listServices", map); + return new JsonMessage<>(200, "", listSwarmNodes); + } + + @PostMapping(value = "task-list", produces = MediaType.APPLICATION_JSON_VALUE) + @Feature(method = MethodFeature.LIST) + public JsonMessage> taskList( + @ValidatorItem String id, + String serviceId, String taskId, String taskName, String taskNode, String taskState) throws Exception { + // + IPlugin plugin = PluginFactory.getPlugin(DockerSwarmInfoService.DOCKER_PLUGIN_NAME); + Map map = dockerInfoService.getBySwarmPluginMap(id, getRequest()); + map.put("id", taskId); + map.put("serviceId", serviceId); + map.put("name", taskName); + map.put("node", taskNode); + map.put("state", taskState); + List listSwarmNodes = (List) plugin.execute("listTasks", map); + return new JsonMessage<>(200, "", listSwarmNodes); + } +} diff --git a/modules/server/src/main/java/io/jpom/service/docker/DockerInfoService.java b/modules/server/src/main/java/io/jpom/service/docker/DockerInfoService.java index 32ad02e6e..32f5dbe44 100644 --- a/modules/server/src/main/java/io/jpom/service/docker/DockerInfoService.java +++ b/modules/server/src/main/java/io/jpom/service/docker/DockerInfoService.java @@ -40,7 +40,9 @@ import io.jpom.plugin.PluginFactory; import io.jpom.service.h2db.BaseWorkspaceService; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import org.springframework.util.Assert; +import javax.servlet.http.HttpServletRequest; import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -249,4 +251,20 @@ public class DockerInfoService extends BaseWorkspaceService imp update.setSwarmNodeId(StrUtil.EMPTY); this.update(update); } + + /** + * 获取集群 docker 信息 + * + * @param id 集群ID + * @param request 请求对象 + * @return map + */ + public Map getBySwarmPluginMap(String id, HttpServletRequest request) { + DockerSwarmInfoMode swarmInfoMode1 = dockerSwarmInfoService.getByKey(id, request); + Assert.notNull(swarmInfoMode1, "没有对应的集群"); + // + DockerInfoModel managerSwarmDocker = this.getByKey(swarmInfoMode1.getDockerId(), request); + Assert.notNull(managerSwarmDocker, "对应的 docker 不存在"); + return managerSwarmDocker.toParameter(); + } } diff --git a/modules/sub-plugin/docker-cli/src/main/java/io/jpom/DefaultDockerSwarmPluginImpl.java b/modules/sub-plugin/docker-cli/src/main/java/io/jpom/DefaultDockerSwarmPluginImpl.java index 3a4ab93c6..387666845 100644 --- a/modules/sub-plugin/docker-cli/src/main/java/io/jpom/DefaultDockerSwarmPluginImpl.java +++ b/modules/sub-plugin/docker-cli/src/main/java/io/jpom/DefaultDockerSwarmPluginImpl.java @@ -74,12 +74,67 @@ public class DefaultDockerSwarmPluginImpl implements IDefaultPlugin { case "removeSwarmNode": this.removeSwarmNodeCmd(parameter); return null; + case "listServices": + return this.listServicesCmd(parameter); + case "listTasks": + return this.listTasksCmd(parameter); default: break; } return null; } + private List listTasksCmd(Map parameter) { + DockerClient dockerClient = DockerUtil.build(parameter); + try { + ListTasksCmd listTasksCmd = dockerClient.listTasksCmd(); + String serviceId = (String) parameter.get("serviceId"); + String id = (String) parameter.get("id"); + if (StrUtil.isNotEmpty(serviceId)) { + listTasksCmd.withServiceFilter(serviceId); + } + if (StrUtil.isNotEmpty(id)) { + listTasksCmd.withIdFilter(id); + } + String name = (String) parameter.get("name"); + if (StrUtil.isNotEmpty(name)) { + listTasksCmd.withNameFilter(name); + } + String node = (String) parameter.get("node"); + if (StrUtil.isNotEmpty(node)) { + listTasksCmd.withNodeFilter(node); + } + String state = (String) parameter.get("state"); + if (StrUtil.isNotEmpty(state)) { + TaskState taskState = EnumUtil.fromString(TaskState.class, state); + listTasksCmd.withStateFilter(taskState); + } + List exec = listTasksCmd.exec(); + return exec.stream().map(swarmNode -> (JSONObject) JSONObject.toJSON(swarmNode)).collect(Collectors.toList()); + } finally { + IoUtil.close(dockerClient); + } + } + + public List listServicesCmd(Map parameter) { + DockerClient dockerClient = DockerUtil.build(parameter); + try { + ListServicesCmd listServicesCmd = dockerClient.listServicesCmd(); + String id = (String) parameter.get("id"); + String name = (String) parameter.get("name"); + if (StrUtil.isNotEmpty(id)) { + listServicesCmd.withIdFilter(CollUtil.newArrayList(id)); + } + if (StrUtil.isNotEmpty(name)) { + listServicesCmd.withNameFilter(CollUtil.newArrayList(name)); + } + List exec = listServicesCmd.exec(); + return exec.stream().map(swarmNode -> (JSONObject) JSONObject.toJSON(swarmNode)).collect(Collectors.toList()); + } finally { + IoUtil.close(dockerClient); + } + } + private void removeSwarmNodeCmd(Map parameter) { DockerClient dockerClient = DockerUtil.build(parameter); try { diff --git a/modules/sub-plugin/docker-cli/src/test/java/TestSwarm.java b/modules/sub-plugin/docker-cli/src/test/java/TestSwarm.java index bef9b7ff5..bd002fdbf 100644 --- a/modules/sub-plugin/docker-cli/src/test/java/TestSwarm.java +++ b/modules/sub-plugin/docker-cli/src/test/java/TestSwarm.java @@ -31,6 +31,7 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.serializer.SerializerFeature; import com.github.dockerjava.api.DockerClient; +import com.github.dockerjava.api.async.ResultCallback; import com.github.dockerjava.api.command.*; import com.github.dockerjava.api.model.*; import com.github.dockerjava.core.DefaultDockerClientConfig; @@ -47,6 +48,7 @@ import org.junit.Before; import org.junit.Test; import org.slf4j.LoggerFactory; +import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -205,4 +207,48 @@ public class TestSwarm { joinSwarmCmd.exec(); } + @Test + public void testService() { + DockerClient client = this.client(node1); + ListServicesCmd listServicesCmd = client.listServicesCmd(); + + List exec = listServicesCmd.exec(); + JSONArray toJSON = (JSONArray) JSONObject.toJSON(exec); + System.out.println(toJSON.toString()); + } + + @Test + public void testServiceInspect() { + DockerClient client = this.client(node1); + InspectServiceCmd inspectServiceCmd = client.inspectServiceCmd("esjx0f126tvvicfizymdxymxq"); + + Service exec = inspectServiceCmd.exec(); + + System.out.println(exec); + } + + @Test + public void testServiceLog() throws InterruptedException { + DockerClient client = this.client(node1); + LogSwarmObjectCmd swarmObjectCmd = client.logServiceCmd("esjx0f126tvvicfizymdxymxq"); + swarmObjectCmd.withDetails(true); + swarmObjectCmd.withStderr(true); + swarmObjectCmd.withStdout(true); + swarmObjectCmd.exec(new ResultCallback.Adapter() { + @Override + public void onNext(Frame object) { + String s = new String(object.getPayload(), StandardCharsets.UTF_8); + System.out.print(s); + } + }).awaitCompletion(); + } + + @Test + public void tsetTask() { + DockerClient client = this.client(node1); + ListTasksCmd listTasksCmd = client.listTasksCmd(); + listTasksCmd.withServiceFilter("esjx0f126tvvicfizymdxymxq"); + List exec = listTasksCmd.exec(); + System.out.println(exec); + } } diff --git a/web-vue/src/api/docker-swarm.js b/web-vue/src/api/docker-swarm.js index 1d78c7e9d..0a1a8536b 100644 --- a/web-vue/src/api/docker-swarm.js +++ b/web-vue/src/api/docker-swarm.js @@ -93,3 +93,27 @@ export function dockerSwarmNodeLeave(params) { params: params, }); } + +/** + * 容器集群服务列表 + * @param {JSON} params + */ +export function dockerSwarmServicesList(params) { + return axios({ + url: "/docker-swarm-service/list", + method: "post", + data: params, + }); +} + +/** + * 容器集群服务任务列表 + * @param {JSON} params + */ +export function dockerSwarmServicesTaskList(params) { + return axios({ + url: "/docker-swarm-service/task-list", + method: "post", + data: params, + }); +} diff --git a/web-vue/src/pages/docker/console.vue b/web-vue/src/pages/docker/console.vue index 6f91c8d90..679df857a 100644 --- a/web-vue/src/pages/docker/console.vue +++ b/web-vue/src/pages/docker/console.vue @@ -61,9 +61,6 @@ export default { }; diff --git a/web-vue/src/pages/docker/swarm/list.vue b/web-vue/src/pages/docker/swarm/list.vue index 5a6248a7c..6fcf664d5 100644 --- a/web-vue/src/pages/docker/swarm/list.vue +++ b/web-vue/src/pages/docker/swarm/list.vue @@ -24,12 +24,12 @@ @@ -59,11 +70,12 @@ import { PAGE_DEFAULT_LIMIT, PAGE_DEFAULT_SIZW_OPTIONS, PAGE_DEFAULT_SHOW_TOTAL, PAGE_DEFAULT_LIST_QUERY } from "@/utils/const"; import { editDockerSwarm, dockerSwarmList, unbindSwarm } from "@/api/docker-swarm"; import { parseTime } from "@/utils/time"; -import SwarmNode from "./node.vue"; +import { mapGetters } from "vuex"; +import Console from "./console"; export default { components: { - SwarmNode, + Console, }, props: {}, data() { @@ -73,7 +85,7 @@ export default { list: [], temp: {}, editVisible: false, - nodeVisible: false, + consoleVisible: false, columns: [ { title: "名称", dataIndex: "name", ellipsis: true, scopedSlots: { customRender: "tooltip" } }, { title: "节点地址", dataIndex: "nodeAddr", ellipsis: true, scopedSlots: { customRender: "tooltip" } }, @@ -100,7 +112,7 @@ export default { }, width: 170, }, - { title: "操作", dataIndex: "operation", scopedSlots: { customRender: "operation" }, align: "center", width: 190 }, + { title: "操作", dataIndex: "operation", scopedSlots: { customRender: "operation" }, align: "center", width: 140 }, ], rules: { // id: [{ required: true, message: "Please input ID", trigger: "blur" }], @@ -118,6 +130,7 @@ export default { }; }, computed: { + ...mapGetters(["getCollapsed"]), pagination() { return { total: this.listQuery.total, @@ -154,14 +167,12 @@ export default { this.editVisible = true; this.$refs["editForm"]?.resetFields(); }, - // 节点 - handleNode(record) { + // 服务 + handleConsole(record) { this.temp = record; - this.nodeVisible = true; - this.$nextTick(() => { - this.$refs.swarmNode.refreshData(); - }); + this.consoleVisible = true; }, + // 提交 数据 handleEditOk() { // 检验表单 diff --git a/web-vue/src/pages/docker/swarm/node.vue b/web-vue/src/pages/docker/swarm/node.vue index 67b0375b1..35b95c071 100644 --- a/web-vue/src/pages/docker/swarm/node.vue +++ b/web-vue/src/pages/docker/swarm/node.vue @@ -146,13 +146,9 @@ export default { }, computed: {}, mounted() { - // this.loadData(); + this.loadData(); }, methods: { - refreshData() { - this.list = []; - this.loadData(); - }, // 加载数据 loadData() { this.loading = true; diff --git a/web-vue/src/pages/docker/swarm/service.vue b/web-vue/src/pages/docker/swarm/service.vue new file mode 100644 index 000000000..8829195e4 --- /dev/null +++ b/web-vue/src/pages/docker/swarm/service.vue @@ -0,0 +1,204 @@ + + + diff --git a/web-vue/src/pages/docker/swarm/task.vue b/web-vue/src/pages/docker/swarm/task.vue new file mode 100644 index 000000000..6243f7fce --- /dev/null +++ b/web-vue/src/pages/docker/swarm/task.vue @@ -0,0 +1,224 @@ + + +