tracker/sftp 策略配置化.

This commit is contained in:
lijiahangmax
2024-04-16 00:39:51 +08:00
parent 07977124fe
commit 4150ab0666
15 changed files with 221 additions and 28 deletions

View File

@@ -2,6 +2,17 @@
⚡ 注意: 应用不支持跨版本升级, 可以进行多次升级
## v1.0.5
`2024-04-` `release`
* 🔨 优化 定时删除未引用的 `tag`
* 🔨 优化 命令执行日志时间不自增
* 🔨 优化 tracker 监听文件可配置 `app.tracker`
* 🔨 优化 sftp 上传文件重复处理可配置 `app.sftp`
[如何升级](/update/v1.0.5.md)
## v1.0.4
`2024-04-15` `release`
@@ -69,7 +80,7 @@
* 🌈 新增 主机连接日志删除/清理
* 🌈 新增 用户操作日志日志删除/清理
* 🌈 新增 用户操作日志日志删除/清理
* 🔨 优化 用户锁定次数/时间可配置
* 🔨 优化 用户锁定次数/时间可配置 `app.authentication`
[如何升级](/update/v1.0.1.md)

View File

@@ -1,15 +1,12 @@
## 功能排期 ⏳
* tracker 使用配置文件
* 文件重复删除/重命名 可配置
* 定时删除未引用的 tag
* 管理员也需要自行授权资产
* 使用文件执行命令
* 优化文件传输列表进度显示
* 主机身份类型
* 终端断开连接后回车重新连接
* 使用文件执行命令
* 管理员也需要自行授权资产
* 文件夹书签
* 批量上传
* 优化文件传输列表进度显示
* 终端断开连接后回车重新连接
* 站内消息
* 终端背景图片
* 资产授权 UI 改版

View File

@@ -152,6 +152,7 @@ logging:
# 应用配置
app:
# 认证配置
authentication:
# 是否允许多端登录
allow-multi-device: true
@@ -163,6 +164,20 @@ app:
login-failed-lock-count: 5
# 登录失败锁定时间 (分)
login-failed-lock-time: 30
# tracker 配置
tracker:
# 加载偏移量 (行)
offset: 300
# 延迟时间 (ms)
delay: 100
# 文件未找到等待次数
wait-times: 100
# sftp 配置
sftp:
# 上传文件时 文件存在是否备份
upload-present-backup: true
# 备份文件名称
backup-file-name: bk_${fileName}_${timestamp}
# orion framework config
orion:

View File

@@ -0,0 +1,34 @@
package com.orion.ops.module.asset.define.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* 应用 sftp 配置
*
* @author Jiahang Li
* @version 1.0.0
* @since 2024/4/15 22:00
*/
@Data
@Component
@ConfigurationProperties(prefix = "app.sftp")
public class AppSftpConfig {
/**
* 上传文件时 文件存在是否备份
*/
private Boolean uploadPresentBackup;
/**
* 备份文件名称
*/
private String backupFileName;
public AppSftpConfig() {
this.uploadPresentBackup = true;
this.backupFileName = "bk_${fileName}_${timestamp}";
}
}

View File

@@ -0,0 +1,39 @@
package com.orion.ops.module.asset.define.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* 应用 tracker 配置
*
* @author Jiahang Li
* @version 1.0.0
* @since 2024/4/15 22:00
*/
@Data
@Component
@ConfigurationProperties(prefix = "app.tracker")
public class AppTrackerConfig {
/**
* 加载偏移量 (行)
*/
private Integer offset;
/**
* 延迟时间 (ms)
*/
private Integer delay;
/**
* 文件未找到等待次数
*/
private Integer waitTimes;
public AppTrackerConfig() {
this.offset = 300;
this.delay = 100;
this.waitTimes = 100;
}
}

View File

@@ -15,10 +15,4 @@ public interface LogConst {
String SEPARATOR = "|";
int TRACKER_OFFSET_LINE = 200;
int TRACKER_DELAY_MS = 200;
int TRACKER_WAIT_TIMES = 100;
}

View File

@@ -5,8 +5,10 @@ import com.orion.ext.tail.delay.DelayTrackerListener;
import com.orion.ext.tail.mode.FileNotFoundMode;
import com.orion.ext.tail.mode.FileOffsetMode;
import com.orion.ops.framework.websocket.core.utils.WebSockets;
import com.orion.ops.module.asset.define.config.AppTrackerConfig;
import com.orion.ops.module.asset.entity.dto.ExecHostLogTailDTO;
import com.orion.ops.module.asset.handler.host.exec.log.constant.LogConst;
import com.orion.spring.SpringHolder;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.socket.WebSocketSession;
@@ -21,6 +23,8 @@ import org.springframework.web.socket.WebSocketSession;
@Slf4j
public class ExecLogTracker implements IExecLogTracker {
private static final AppTrackerConfig TRACKER_CONFIG = SpringHolder.getBean(AppTrackerConfig.class);
private final WebSocketSession session;
private final ExecHostLogTailDTO config;
@@ -50,9 +54,9 @@ public class ExecLogTracker implements IExecLogTracker {
try {
this.tracker = new DelayTrackerListener(absolutePath, this);
tracker.charset(config.getCharset());
tracker.delayMillis(LogConst.TRACKER_DELAY_MS);
tracker.offset(FileOffsetMode.LINE, LogConst.TRACKER_OFFSET_LINE);
tracker.notFoundMode(FileNotFoundMode.WAIT_COUNT, LogConst.TRACKER_WAIT_TIMES);
tracker.delayMillis(TRACKER_CONFIG.getDelay());
tracker.offset(FileOffsetMode.LINE, TRACKER_CONFIG.getOffset());
tracker.notFoundMode(FileNotFoundMode.WAIT_COUNT, TRACKER_CONFIG.getWaitTimes());
// 开始监听文件
tracker.run();
} catch (Exception e) {

View File

@@ -0,0 +1,29 @@
package com.orion.ops.module.asset.handler.host.transfer.model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* sftp 文件备份参数
*
* @author Jiahang Li
* @version 1.0.0
* @since 2024/4/15 23:13
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(name = "SftpFileBackupParams", description = "sftp 文件备份参数")
public class SftpFileBackupParams {
@Schema(description = "文件名称")
private String fileName;
@Schema(description = "时间戳")
private Long timestamp;
}

View File

@@ -1,14 +1,20 @@
package com.orion.ops.module.asset.handler.host.transfer.session;
import com.alibaba.fastjson.JSON;
import com.orion.lang.utils.Booleans;
import com.orion.lang.utils.Strings;
import com.orion.lang.utils.collect.Maps;
import com.orion.lang.utils.io.Streams;
import com.orion.net.host.SessionStore;
import com.orion.net.host.sftp.SftpExecutor;
import com.orion.net.host.sftp.SftpFile;
import com.orion.ops.framework.biz.operator.log.core.model.OperatorLogModel;
import com.orion.ops.framework.biz.operator.log.core.service.OperatorLogFrameworkService;
import com.orion.ops.framework.biz.operator.log.core.utils.OperatorLogs;
import com.orion.ops.module.asset.define.config.AppSftpConfig;
import com.orion.ops.module.asset.entity.dto.HostTerminalConnectDTO;
import com.orion.ops.module.asset.handler.host.terminal.utils.TerminalUtils;
import com.orion.ops.module.asset.handler.host.transfer.model.SftpFileBackupParams;
import com.orion.spring.SpringHolder;
import org.springframework.web.socket.WebSocketSession;
@@ -23,6 +29,8 @@ import java.util.Map;
*/
public abstract class TransferHostSession implements ITransferHostSession {
protected static final AppSftpConfig SFTP_CONFIG = SpringHolder.getBean(AppSftpConfig.class);
protected final HostTerminalConnectDTO connectInfo;
protected final SessionStore sessionStore;
@@ -51,6 +59,27 @@ public abstract class TransferHostSession implements ITransferHostSession {
}
}
/**
* 检查文件是否存在 并且执行响应策略
*
* @param path path
*/
protected void doCheckFilePresent(String path) {
// 重复不备份
if (!Booleans.isTrue(SFTP_CONFIG.getUploadPresentBackup())) {
return;
}
// 检查文件是否存在
SftpFile file = executor.getFile(path);
if (file != null) {
// 文件存在则备份
SftpFileBackupParams backupParams = new SftpFileBackupParams(file.getName(), System.currentTimeMillis());
String target = Strings.format(SFTP_CONFIG.getBackupFileName(), JSON.parseObject(JSON.toJSONString(backupParams)));
// 移动
executor.move(path, target);
}
}
/**
* 保存操作日志
*

View File

@@ -3,7 +3,6 @@ package com.orion.ops.module.asset.handler.host.transfer.session;
import com.orion.lang.exception.argument.InvalidArgumentException;
import com.orion.lang.utils.io.Streams;
import com.orion.net.host.SessionStore;
import com.orion.net.host.sftp.SftpFile;
import com.orion.ops.module.asset.define.operator.HostTerminalOperatorType;
import com.orion.ops.module.asset.entity.dto.HostTerminalConnectDTO;
import com.orion.ops.module.asset.handler.host.transfer.enums.TransferReceiverType;
@@ -40,11 +39,7 @@ public class UploadSession extends TransferHostSession implements IUploadSession
// 检查连接
this.init();
// 检查文件是否存在
SftpFile file = executor.getFile(path);
if (file != null) {
// 文件存在则重命名
executor.move(path, file.getName() + "_bk_" + System.currentTimeMillis());
}
this.doCheckFilePresent(path);
// 打开输出流
this.outputStream = executor.openOutputStream(path);
// 响应结果

View File

@@ -0,0 +1,46 @@
{
"groups": [
{
"name": "app.tracker",
"type": "com.orion.ops.module.asset.define.config.AppTrackerConfig",
"sourceType": "com.orion.ops.module.asset.define.config.AppTrackerConfig"
},
{
"name": "app.sftp",
"type": "com.orion.ops.module.asset.define.config.AppSftpConfig",
"sourceType": "com.orion.ops.module.asset.define.config.AppSftpConfig"
}
],
"properties": [
{
"name": "app.tracker.offset",
"type": "java.lang.Integer",
"description": "加载偏移量 (行)",
"defaultValue": "300"
},
{
"name": "app.tracker.delay",
"type": "java.lang.Integer",
"description": "延迟时间 (ms)",
"defaultValue": "100"
},
{
"name": "app.tracker.wait-times",
"type": "java.lang.Integer",
"description": "文件未找到等待次数",
"defaultValue": "100"
},
{
"name": "app.sftp.upload-present-backup",
"type": "java.lang.Boolean",
"description": "上传文件时 文件存在是否备份.",
"defaultValue": "true"
},
{
"name": "app.sftp.backup-file-name",
"type": "java.lang.String",
"description": "备份文件名称.",
"defaultValue": "bk_${fileName}_${timestamp}"
}
]
}

View File

@@ -1,4 +1,4 @@
package com.orion.ops.module.infra.config;
package com.orion.ops.module.infra.define.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

View File

@@ -16,7 +16,7 @@ import com.orion.ops.framework.common.utils.Valid;
import com.orion.ops.framework.redis.core.utils.RedisStrings;
import com.orion.ops.framework.redis.core.utils.RedisUtils;
import com.orion.ops.framework.security.core.utils.SecurityUtils;
import com.orion.ops.module.infra.config.AppAuthenticationConfig;
import com.orion.ops.module.infra.define.config.AppAuthenticationConfig;
import com.orion.ops.module.infra.convert.SystemUserConvert;
import com.orion.ops.module.infra.dao.SystemUserDAO;
import com.orion.ops.module.infra.dao.SystemUserRoleDAO;

View File

@@ -14,7 +14,7 @@ import com.orion.ops.framework.redis.core.utils.RedisStrings;
import com.orion.ops.framework.redis.core.utils.RedisUtils;
import com.orion.ops.framework.redis.core.utils.barrier.CacheBarriers;
import com.orion.ops.framework.security.core.utils.SecurityUtils;
import com.orion.ops.module.infra.config.AppAuthenticationConfig;
import com.orion.ops.module.infra.define.config.AppAuthenticationConfig;
import com.orion.ops.module.infra.convert.SystemUserConvert;
import com.orion.ops.module.infra.dao.OperatorLogDAO;
import com.orion.ops.module.infra.dao.SystemRoleDAO;

View File

@@ -2,8 +2,8 @@
"groups": [
{
"name": "app.authentication",
"type": "com.orion.ops.module.infra.config.AppAuthenticationConfig",
"sourceType": "com.orion.ops.module.infra.config.AppAuthenticationConfig"
"type": "com.orion.ops.module.infra.define.config.AppAuthenticationConfig",
"sourceType": "com.orion.ops.module.infra.define.config.AppAuthenticationConfig"
}
],
"properties": [