use of io.jpom.model.data.SshModel in project Jpom by dromara.
the class NodeService method update.
/**
* 修改 节点
*
* @param request 请求对象
*/
public void update(HttpServletRequest request, boolean autoReg) {
String type = request.getParameter("type");
boolean create = "add".equalsIgnoreCase(type);
// 创建对象
NodeModel nodeModel = ServletUtil.toBean(request, NodeModel.class, true);
String id = nodeModel.getId();
if (StrUtil.isNotEmpty(id)) {
String checkId = StrUtil.replace(id, StrUtil.DASHED, StrUtil.UNDERLINE);
Validator.validateGeneral(checkId, 2, Const.ID_MAX_LEN, "节点id不能为空并且2-50(英文字母 、数字和下划线)");
}
Assert.hasText(nodeModel.getName(), "节点名称 不能为空");
NodeModel existsNode = super.getByKey(id);
String workspaceId;
if (autoReg) {
if (create) {
Assert.isNull(existsNode, "对应的节点 id 已经存在啦");
// 绑定到默认工作空间
workspaceId = Const.WORKSPACE_DEFAULT_ID;
} else {
Assert.notNull(existsNode, "对应的节点不存在");
workspaceId = existsNode.getWorkspaceId();
}
} else {
workspaceId = this.getCheckUserWorkspace(request);
}
nodeModel.setWorkspaceId(workspaceId);
// nodeModel.setProtocol(StrUtil.emptyToDefault(nodeModel.getProtocol(), "http"));
{
// 节点地址 重复
boolean exists = this.existsByUrl(nodeModel.getUrl(), nodeModel.getWorkspaceId(), id);
Assert.state(!exists, "对应的节点已经存在啦");
}
// 判断 ssh
String sshId = nodeModel.getSshId();
if (StrUtil.isNotEmpty(sshId)) {
SshModel byKey = sshService.getByKey(sshId, request);
Assert.notNull(byKey, "对应的 SSH 不存在");
List<NodeModel> nodeBySshId = this.getNodeBySshId(sshId);
nodeBySshId = ObjectUtil.defaultIfNull(nodeBySshId, Collections.EMPTY_LIST);
Optional<NodeModel> any = nodeBySshId.stream().filter(nodeModel2 -> !StrUtil.equals(id, nodeModel2.getId())).findAny();
Assert.state(!any.isPresent(), "对应的SSH已经被其他节点绑定啦");
}
if (nodeModel.isOpenStatus()) {
//
this.checkLockType(existsNode);
this.testNode(nodeModel);
}
try {
if (autoReg) {
BaseServerController.resetInfo(UserModel.EMPTY);
}
if (create) {
if (autoReg) {
// 自动注册节点默认关闭
nodeModel.setOpenStatus(0);
// 默认锁定 (原因未分配工作空间)
nodeModel.setUnLockType("unassignedWorkspace");
}
this.insert(nodeModel);
// 同步项目
ProjectInfoCacheService projectInfoCacheService = SpringUtil.getBean(ProjectInfoCacheService.class);
projectInfoCacheService.syncNode(nodeModel);
} else {
this.update(nodeModel);
}
} finally {
if (autoReg) {
BaseServerController.removeEmpty();
}
}
}
use of io.jpom.model.data.SshModel in project Jpom by dromara.
the class CommandService method execute.
/**
* 执行命令
*
* @param commandModel 命令模版
* @param commandExecLogModel 执行记录
* @param sshModel ssh
* @param commandParamsLine 参数
* @throws IOException io
*/
private void execute(CommandModel commandModel, CommandExecLogModel commandExecLogModel, SshModel sshModel, String commandParamsLine) throws IOException {
File file = commandExecLogModel.logFile();
try (BufferedOutputStream outputStream = FileUtil.getOutputStream(file)) {
if (sshModel == null) {
this.appendLine(outputStream, "ssh 不存在");
return;
}
String command = commandModel.getCommand();
String[] commands = StrUtil.splitToArray(command, StrUtil.LF);
//
workspaceEnvVarService.formatCommand(commandModel.getWorkspaceId(), commands);
//
Charset charset = sshModel.getCharsetT();
sshService.exec(sshModel, (s, session) -> {
final ChannelExec channel = (ChannelExec) JschUtil.createChannel(session, ChannelType.EXEC);
channel.setCommand(StrUtil.bytes(s + StrUtil.SPACE + commandParamsLine, charset));
channel.setInputStream(null);
channel.setErrStream(outputStream, true);
InputStream in = null;
try {
channel.connect();
in = channel.getInputStream();
IoUtil.readLines(in, charset, (LineHandler) line -> this.appendLine(outputStream, line));
// 更新状态
this.updateStatus(commandExecLogModel.getId(), CommandExecLogModel.Status.DONE);
} catch (Exception e) {
DefaultSystemLog.getLog().error("执行命令错误", e);
// 更新状态
this.updateStatus(commandExecLogModel.getId(), CommandExecLogModel.Status.ERROR);
// 记录错误日志
String stacktraceToString = ExceptionUtil.stacktraceToString(e);
this.appendLine(outputStream, stacktraceToString);
} finally {
IoUtil.close(in);
JschUtil.close(channel);
}
return null;
}, commands);
}
}
use of io.jpom.model.data.SshModel in project Jpom by dromara.
the class SshHandler method logCommands.
/**
* 记录终端执行记录
*
* @param session 回话
* @param command 命令行
* @param refuse 是否拒绝
*/
private void logCommands(WebSocketSession session, String command, boolean refuse) {
List<String> split = StrUtil.splitTrim(command, StrUtil.CR);
// 最后一个是否为回车, 最后一个不是回车表示还未提交,还在缓存去待确认
boolean all = StrUtil.endWith(command, StrUtil.CR);
int size = split.size();
split = CollUtil.sub(split, 0, all ? size : size - 1);
if (CollUtil.isEmpty(split)) {
return;
}
// 获取基础信息
Map<String, Object> attributes = session.getAttributes();
UserModel userInfo = (UserModel) attributes.get("userInfo");
String ip = (String) attributes.get("ip");
String userAgent = (String) attributes.get(HttpHeaders.USER_AGENT);
SshModel sshItem = (SshModel) attributes.get("dataItem");
//
sshTerminalExecuteLogService.batch(userInfo, sshItem, ip, userAgent, refuse, split);
}
use of io.jpom.model.data.SshModel in project Jpom by dromara.
the class SshHandler method afterConnectionEstablishedImpl.
@Override
public void afterConnectionEstablishedImpl(WebSocketSession session) throws Exception {
Map<String, Object> attributes = session.getAttributes();
SshModel sshItem = (SshModel) attributes.get("dataItem");
super.logOpt(this.getClass(), attributes, attributes);
//
HandlerItem handlerItem;
try {
handlerItem = new HandlerItem(session, sshItem);
handlerItem.startRead();
} catch (Exception e) {
// 输出超时日志 @author jzy
DefaultSystemLog.getLog().error("ssh 控制台连接超时", e);
sendBinary(session, "ssh 控制台连接超时");
this.destroy(session);
return;
}
HANDLER_ITEM_CONCURRENT_HASH_MAP.put(session.getId(), handlerItem);
//
Thread.sleep(1000);
}
use of io.jpom.model.data.SshModel in project Jpom by dromara.
the class CommandService method executeItem.
/**
* 准备执行 某一个
*
* @param commandModel 命令模版
* @param commandParams 参数
* @param sshId ssh id
* @param batchId 批次ID
*/
private void executeItem(CommandModel commandModel, List<CommandModel.CommandParam> commandParams, String sshId, String batchId, int triggerExecType) {
SshModel sshModel = sshService.getByKey(sshId, false);
CommandExecLogModel commandExecLogModel = new CommandExecLogModel();
commandExecLogModel.setCommandId(commandModel.getId());
commandExecLogModel.setCommandName(commandModel.getName());
commandExecLogModel.setBatchId(batchId);
commandExecLogModel.setSshId(sshId);
commandExecLogModel.setTriggerExecType(triggerExecType);
if (sshModel != null) {
commandExecLogModel.setSshName(sshModel.getName());
}
commandExecLogModel.setStatus(CommandExecLogModel.Status.ING.getCode());
// 拼接参数
String commandParamsLine;
if (commandParams != null) {
commandExecLogModel.setParams(JSONObject.toJSONString(commandParams));
commandParamsLine = commandParams.stream().map(CommandModel.CommandParam::getValue).collect(Collectors.joining(StrUtil.SPACE));
} else {
commandParamsLine = StrUtil.EMPTY;
}
commandExecLogService.insert(commandExecLogModel);
ThreadUtil.execute(() -> {
try {
this.execute(commandModel, commandExecLogModel, sshModel, commandParamsLine);
} catch (Exception e) {
DefaultSystemLog.getLog().error("命令模版执行链接异常", e);
this.updateStatus(commandExecLogModel.getId(), CommandExecLogModel.Status.SESSION_ERROR);
}
});
}
Aggregations