diff --git a/src/main/java/com/tongran/agentserver/core/enums/MsgEnum.java b/src/main/java/com/tongran/agentserver/core/enums/MsgEnum.java index 582d567..a08143a 100644 --- a/src/main/java/com/tongran/agentserver/core/enums/MsgEnum.java +++ b/src/main/java/com/tongran/agentserver/core/enums/MsgEnum.java @@ -50,7 +50,15 @@ public enum MsgEnum { 执行命令("EXECUTE_COMMAND"), - 执行命令应答("EXECUTE_COMMAND_RSP"); + 执行命令应答("EXECUTE_COMMAND_RSP"), + + 执行脚本策略("SCRIPT_POLICY"), + + 执行脚本策略应答("SCRIPT_POLICY_RSP"), + + 版本更新("VERSION_UPDATE"), + + 版本更新应答("VERSION_UPDATE_RSP");; private String value; diff --git a/src/main/java/com/tongran/agentserver/server/collect/switchboard/impl/SwitchBoardServiceImpl.java b/src/main/java/com/tongran/agentserver/server/collect/switchboard/impl/SwitchBoardServiceImpl.java index 57f588e..408ebfc 100644 --- a/src/main/java/com/tongran/agentserver/server/collect/switchboard/impl/SwitchBoardServiceImpl.java +++ b/src/main/java/com/tongran/agentserver/server/collect/switchboard/impl/SwitchBoardServiceImpl.java @@ -125,6 +125,7 @@ public class SwitchBoardServiceImpl implements SwitchBoardService { long outBytes = vbs[5].getVariable().toLong(); SwitchBoardVO boardVO = SwitchBoardVO.builder() .name(ifName) + .switchIp(GlobalConfig.SWITCH_IP) .type(ifType) .status(status) .inBytes(inBytes) diff --git a/src/main/java/com/tongran/agentserver/server/collect/vo/SwitchBoardVO.java b/src/main/java/com/tongran/agentserver/server/collect/vo/SwitchBoardVO.java index 783a2d7..58daa46 100644 --- a/src/main/java/com/tongran/agentserver/server/collect/vo/SwitchBoardVO.java +++ b/src/main/java/com/tongran/agentserver/server/collect/vo/SwitchBoardVO.java @@ -19,6 +19,9 @@ public class SwitchBoardVO implements Serializable { @Schema(description = "网口名称") private String name; + @Schema(description = "交换机IP") + private String switchIp; + @Schema(description = "网口类型") private String type; diff --git a/src/main/java/com/tongran/agentserver/server/netty/enpoint/AgentEndpoint.java b/src/main/java/com/tongran/agentserver/server/netty/enpoint/AgentEndpoint.java index d8e9ece..eccdc17 100644 --- a/src/main/java/com/tongran/agentserver/server/netty/enpoint/AgentEndpoint.java +++ b/src/main/java/com/tongran/agentserver/server/netty/enpoint/AgentEndpoint.java @@ -1,9 +1,11 @@ package com.tongran.agentserver.server.netty.enpoint; +import cn.hutool.core.collection.CollectionUtil; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONException; import com.alibaba.fastjson2.JSONObject; import com.tongran.agentserver.core.enums.MsgEnum; +import com.tongran.agentserver.scheduler.*; import com.tongran.agentserver.server.file.AdvancedAsyncDownloader; import com.tongran.agentserver.server.file.AsyncCommandExecutor; import com.tongran.agentserver.server.file.LinuxCommandExecutor; @@ -11,46 +13,53 @@ import com.tongran.agentserver.server.netty.NettyTcpClient; import com.tongran.agentserver.server.netty.annotation.AgentDispatcher; import com.tongran.agentserver.server.netty.basics.AgentHandler; import com.tongran.agentserver.server.netty.model.Message; +import com.tongran.agentserver.server.netty.model.ScriptPolicy; import com.tongran.agentserver.server.netty.model.UpMsgResponse; +import com.tongran.agentserver.utils.AgentUtil; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Component; import javax.annotation.Resource; -import java.util.Arrays; -import java.util.List; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; @Component public class AgentEndpoint { -// @Resource -// private CpuScheduler cpuScheduler; -// -// @Resource -// private DiskScheduler diskScheduler; -// -// @Resource -// private DockerScheduler dockerScheduler; -// -// @Resource -// private MemoryScheduler memoryScheduler; -// -// @Resource -// private NetScheduler netScheduler; -// -// @Resource -// private PointScheduler pointScheduler; -// -// @Resource -// private SwitchBoardScheduler switchBoardScheduler; -// -// @Resource -// private SysScheduler sysScheduler; + @Resource + private CpuScheduler cpuScheduler; + + @Resource + private DiskScheduler diskScheduler; + + @Resource + private DockerScheduler dockerScheduler; + + @Resource + private MemoryScheduler memoryScheduler; + + @Resource + private NetScheduler netScheduler; + + @Resource + private PointScheduler pointScheduler; + + @Resource + private SwitchBoardScheduler switchBoardScheduler; + + @Resource + private SysScheduler sysScheduler; @Resource private NettyTcpClient nettyTcpClient; +// @Resource +// private SpecificTimeTaskService taskService; + @AgentDispatcher(msgId = MsgEnum.更新CPU采集间隔) public class TimeCpuHandler implements AgentHandler { @@ -58,7 +67,7 @@ public class AgentEndpoint { public UpMsgResponse upHandle(String data, String clientId) { JSONObject jsonObject = JSONObject.parseObject(data); long intervalMillis = jsonObject.getLong("intervalMillis"); -// cpuScheduler.updateSchedule(25000, intervalMillis); + cpuScheduler.updateSchedule(25000, intervalMillis); JSONObject json = new JSONObject(); json.put("clientId",clientId); json.put("resCode",1); @@ -72,7 +81,7 @@ public class AgentEndpoint { public UpMsgResponse upHandle(String data, String clientId) { JSONObject jsonObject = JSONObject.parseObject(data); long intervalMillis = jsonObject.getLong("intervalMillis"); -// diskScheduler.updateSchedule(35000, intervalMillis); + diskScheduler.updateSchedule(35000, intervalMillis); JSONObject json = new JSONObject(); json.put("clientId",clientId); json.put("resCode",1); @@ -86,7 +95,7 @@ public class AgentEndpoint { public UpMsgResponse upHandle(String data, String clientId) { JSONObject jsonObject = JSONObject.parseObject(data); long intervalMillis = jsonObject.getLong("intervalMillis"); -// dockerScheduler.updateSchedule(45000, intervalMillis); + dockerScheduler.updateSchedule(45000, intervalMillis); JSONObject json = new JSONObject(); json.put("clientId",clientId); json.put("resCode",1); @@ -100,7 +109,7 @@ public class AgentEndpoint { public UpMsgResponse upHandle(String data, String clientId) { JSONObject jsonObject = JSONObject.parseObject(data); long intervalMillis = jsonObject.getLong("intervalMillis"); -// memoryScheduler.updateSchedule(55000, intervalMillis); + memoryScheduler.updateSchedule(55000, intervalMillis); JSONObject json = new JSONObject(); json.put("clientId",clientId); json.put("resCode",1); @@ -114,7 +123,7 @@ public class AgentEndpoint { public UpMsgResponse upHandle(String data, String clientId) { JSONObject jsonObject = JSONObject.parseObject(data); long intervalMillis = jsonObject.getLong("intervalMillis"); -// netScheduler.updateSchedule(65000, intervalMillis); + netScheduler.updateSchedule(65000, intervalMillis); JSONObject json = new JSONObject(); json.put("clientId",clientId); json.put("resCode",1); @@ -128,7 +137,7 @@ public class AgentEndpoint { public UpMsgResponse upHandle(String data, String clientId) { JSONObject jsonObject = JSONObject.parseObject(data); long intervalMillis = jsonObject.getLong("intervalMillis"); -// pointScheduler.updateSchedule(75000, intervalMillis); + pointScheduler.updateSchedule(75000, intervalMillis); JSONObject json = new JSONObject(); json.put("clientId",clientId); json.put("resCode",1); @@ -142,7 +151,7 @@ public class AgentEndpoint { public UpMsgResponse upHandle(String data, String clientId) { JSONObject jsonObject = JSONObject.parseObject(data); long intervalMillis = jsonObject.getLong("intervalMillis"); -// switchBoardScheduler.updateSchedule(85000, intervalMillis); + switchBoardScheduler.updateSchedule(85000, intervalMillis); JSONObject json = new JSONObject(); json.put("clientId",clientId); json.put("resCode",1); @@ -156,7 +165,7 @@ public class AgentEndpoint { public UpMsgResponse upHandle(String data, String clientId) { JSONObject jsonObject = JSONObject.parseObject(data); long intervalMillis = jsonObject.getLong("intervalMillis"); -// sysScheduler.updateSchedule(40000, intervalMillis); + sysScheduler.updateSchedule(40000, intervalMillis); JSONObject json = new JSONObject(); json.put("clientId",clientId); json.put("resCode",1); @@ -179,7 +188,7 @@ public class AgentEndpoint { if(AdvancedAsyncDownloader.createSingleDirectoryIfNotExists(saveDir)){ String finalSaveDir = saveDir; AdvancedAsyncDownloader.downloadWithProgress(fileUrl, saveDir, null, progress -> { -// System.out.printf("下载进度: %.1f%%\n", progress); + System.out.printf("下载进度: %.1f%%\n", progress); }).thenAccept(filePath -> { JSONObject json = new JSONObject(); json.put("clientId",clientId); @@ -288,5 +297,138 @@ public class AgentEndpoint { } } + @AgentDispatcher(msgId = MsgEnum.执行脚本策略) + public class ScriptPolicyHandler implements AgentHandler { + @Override + public UpMsgResponse upHandle(String data, String clientId) { + ScriptPolicy policy = JSON.parseObject(data, ScriptPolicy.class); + AtomicBoolean isFalse = new AtomicBoolean(false); + if(StringUtils.isNotBlank(policy.getFilePath())){ + if(AdvancedAsyncDownloader.createSingleDirectoryIfNotExists(policy.getFilePath())){ + if(CollectionUtil.isNotEmpty(policy.getFiles())){ + isFalse.set(true); + for (ScriptPolicy.ScriptFile f : policy.getFiles()) { + String finalSaveDir = policy.getFilePath(); + //文件类型:0、平台文件地址;1、外网HTTP(S) + if(f.getFileType() == 0){ + String filePath = policy.getFilePath() + "/" + f.getFileName(); + // 移除Base64 URL前缀(如果存在) + if (f.getFileData().contains(",")) { + f.setFileData(f.getFileData().split(",")[1]); + } + byte[] dataByte = Base64.getDecoder().decode(f.getFileData()); + try (FileOutputStream stream = new FileOutputStream(filePath)) { + stream.write(dataByte); + isFalse.set(false); + System.out.println("文件保存成功: " + filePath); + } catch (IOException e) { + e.printStackTrace(); + } + }else{ + AdvancedAsyncDownloader.downloadWithProgress(f.getFileUrl(), finalSaveDir, null, progress -> { +// System.out.printf("下载进度: %.1f%%\n", progress); + }).thenAccept(filePath -> { + isFalse.set(false); + System.out.println("下载完成: " + filePath); + }).exceptionally(ex -> { + isFalse.set(true); + System.err.println("下载错误: " + ex.getMessage()); + return null; + }); + } + } + } + } + } + //判断文件是否保存成功 + if(!isFalse.get()){ + if(CollectionUtil.isNotEmpty(policy.getCommands())){ + //执行方式:0、立即执行;1、定时执行; + if(policy.getMethod() == 1){ +// SpecificTimeRequest request = SpecificTimeRequest.builder() +// .taskId("") +// .taskName("") +// .taskData(policy.getCommands()) +// .specificDateTime(policy.getPolicyTime()) +// .build(); +// try { +//// taskService.createSpecificTimeTask(request); +// JSONObject json = new JSONObject(); +// json.put("clientId",clientId); +// json.put("resCode",1); +// json.put("result", ""); +// json.put("error",""); +// Message message = Message.builder().clientId(clientId).dataType(MsgEnum.执行脚本策略应答.getValue()).data(json.toString()).build(); +// // 将对象转为 JSON 字符串 +// String msg = "agent-tcp:"+ JSON.toJSONString(message)+"@tong-ran"; +// nettyTcpClient.sendMessage(msg); +// } catch (Exception e) { +// JSONObject json = new JSONObject(); +// json.put("clientId",clientId); +// json.put("resCode",0); +// json.put("result", ""); +// json.put("error","policy save failed"); +// Message message = Message.builder().clientId(clientId).dataType(MsgEnum.执行脚本策略应答.getValue()).data(json.toString()).build(); +// // 将对象转为 JSON 字符串 +// String msg = "agent-tcp:"+ JSON.toJSONString(message)+"@tong-ran"; +// nettyTcpClient.sendMessage(msg); +// } + }else{ + List> list = new ArrayList<>(); + for (String command : policy.getCommands()) { + Map map = new HashMap<>(); + List cmd = Arrays.asList(command.split("\\s+")); + CompletableFuture future = + AsyncCommandExecutor.executeCommandAsync( + cmd, + 60, TimeUnit.SECONDS); + future.thenAccept(result -> { + if (result.isSuccess()) { + System.out.println("脚本执行成功"); + System.out.println("[成功resOut] " + result.getOutput()); + map.put("command",command); + map.put("resOut",result.getOutput()); + } else { + System.out.println("脚本执行失败"); + System.out.println("[失败resOut] " + result.getOutput()); + map.put("command",command); + map.put("resOut",result.getOutput()); + } + }).exceptionally(ex -> { + System.err.println("执行失败: " + ex.getMessage()); + map.put("command",command); + map.put("resOut","Policy execute filed"); + return null; + }); + list.add(map); + } + if(CollectionUtil.isNotEmpty(list)){ + JSONObject json = new JSONObject(); + json.put("clientId",clientId); + json.put("resCode",1); + json.put("result", AgentUtil.toJsonString(list)); + json.put("error",""); + Message message = Message.builder().clientId(clientId).dataType(MsgEnum.执行脚本策略应答.getValue()).data(json.toString()).build(); + // 将对象转为 JSON 字符串 + String msg = "agent-tcp:"+ JSON.toJSONString(message)+"@tong-ran"; + nettyTcpClient.sendMessage(msg); + } + } + } + }else{ + JSONObject json = new JSONObject(); + json.put("clientId",clientId); + json.put("resCode",0); + json.put("result", ""); + json.put("error","File save failed"); + Message message = Message.builder().clientId(clientId).dataType(MsgEnum.执行脚本策略应答.getValue()).data(json.toString()).build(); + // 将对象转为 JSON 字符串 + String msg = "agent-tcp:"+ JSON.toJSONString(message)+"@tong-ran"; + nettyTcpClient.sendMessage(msg); + } + return null; + } + } + } \ No newline at end of file diff --git a/src/main/java/com/tongran/agentserver/server/netty/model/ScriptPolicy.java b/src/main/java/com/tongran/agentserver/server/netty/model/ScriptPolicy.java new file mode 100644 index 0000000..659d56c --- /dev/null +++ b/src/main/java/com/tongran/agentserver/server/netty/model/ScriptPolicy.java @@ -0,0 +1,58 @@ +package com.tongran.agentserver.server.netty.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.time.LocalDateTime; +import java.util.List; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class ScriptPolicy implements Serializable { + + private static final long serialVersionUID = -1267013167162440612L; + + /** + * 文件 + */ + private List files; + + //目标路径地址 + private String filePath; + + //命令 + private List commands; + + //执行方式:0、立即执行;1、定时执行; + private int method; + + //执行方式为1、定时执行时必传-指定时间 + private LocalDateTime policyTime; + + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class ScriptFile{ + + //文件类型:0、平台文件地址;1、外网HTTP(S) + private int fileType; + + //文件类型为1、外网HTTP(S)时必传 + private String fileUrl; + + //文件类型为0、平台文件地址时必传(文件名) + private String fileName; + + //文件类型为0、平台文件地址时必传(文件流) + private String fileData; + + } + +} diff --git a/src/main/java/com/tongran/agentserver/utils/AgentUtil.java b/src/main/java/com/tongran/agentserver/utils/AgentUtil.java index 62cf4e4..d2eaf88 100644 --- a/src/main/java/com/tongran/agentserver/utils/AgentUtil.java +++ b/src/main/java/com/tongran/agentserver/utils/AgentUtil.java @@ -1,10 +1,14 @@ package com.tongran.agentserver.utils; +import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.commons.lang3.StringUtils; import oshi.SystemInfo; import oshi.hardware.Baseboard; import oshi.hardware.HardwareAbstractionLayer; +import java.util.List; +import java.util.Map; + public class AgentUtil { public static String getMotherboardUUID() { @@ -17,4 +21,13 @@ public class AgentUtil { return "client-001"; } + public static String toJsonString(List> list) { + try { + ObjectMapper mapper = new ObjectMapper(); + return mapper.writeValueAsString(list); + } catch (Exception e) { + throw new RuntimeException("JSON转换失败", e); + } + } + }