🔨 执行命令.

This commit is contained in:
lijiahang
2024-03-15 19:32:22 +08:00
parent 87bbcfa845
commit 03c334a507
28 changed files with 791 additions and 202 deletions

View File

@@ -5,6 +5,7 @@ import com.orion.ops.framework.biz.operator.log.core.annotation.OperatorLog;
import com.orion.ops.framework.common.validator.group.Page;
import com.orion.ops.framework.log.core.annotation.IgnoreLog;
import com.orion.ops.framework.log.core.enums.IgnoreLogMode;
import com.orion.ops.framework.security.core.utils.SecurityUtils;
import com.orion.ops.framework.web.core.annotation.RestWrapper;
import com.orion.ops.module.asset.define.operator.ExecOperatorType;
import com.orion.ops.module.asset.entity.request.exec.ExecLogQueryRequest;
@@ -73,6 +74,16 @@ public class ExecLogController {
return execLogService.getExecLogStatus(idList);
}
@IgnoreLog(IgnoreLogMode.RET)
@GetMapping("/history")
@Operation(summary = "查询执行历史")
@PreAuthorize("@ss.hasAnyPermission('asset:exec-log:query', 'asset:exec:exec-command')")
public List<ExecLogVO> getExecLogHistory(@Validated(Page.class) ExecLogQueryRequest request) {
request.setSource(ExecSourceEnum.BATCH.name());
request.setUserId(SecurityUtils.getLoginUserId());
return execLogService.getExecHistory(request);
}
@OperatorLog(ExecOperatorType.DELETE_LOG)
@DeleteMapping("/delete")
@Operation(summary = "删除执行日志")

View File

@@ -21,7 +21,6 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
/**
* 执行模板 api
@@ -67,14 +66,6 @@ public class ExecTemplateController {
return execTemplateService.getExecTemplateById(id);
}
@IgnoreLog(IgnoreLogMode.RET)
@GetMapping("/list")
@Operation(summary = "查询全部执行模板")
@PreAuthorize("@ss.hasPermission('asset:exec-template:query')")
public List<ExecTemplateVO> getExecTemplateList() {
return execTemplateService.getExecTemplateListByCache();
}
@IgnoreLog(IgnoreLogMode.RET)
@PostMapping("/query")
@Operation(summary = "分页查询执行模板")

View File

@@ -1,7 +1,6 @@
package com.orion.ops.module.asset.convert;
import com.orion.ops.module.asset.entity.domain.ExecTemplateDO;
import com.orion.ops.module.asset.entity.dto.ExecTemplateCacheDTO;
import com.orion.ops.module.asset.entity.request.exec.ExecTemplateCreateRequest;
import com.orion.ops.module.asset.entity.request.exec.ExecTemplateUpdateRequest;
import com.orion.ops.module.asset.entity.vo.ExecTemplateVO;
@@ -26,8 +25,4 @@ public interface ExecTemplateConvert {
ExecTemplateVO to(ExecTemplateDO domain);
ExecTemplateVO to(ExecTemplateCacheDTO cache);
ExecTemplateCacheDTO toCache(ExecTemplateDO domain);
}

View File

@@ -1,27 +0,0 @@
package com.orion.ops.module.asset.define.cache;
import com.orion.lang.define.cache.key.CacheKeyBuilder;
import com.orion.lang.define.cache.key.CacheKeyDefine;
import com.orion.lang.define.cache.key.struct.RedisCacheStruct;
import com.orion.ops.module.asset.entity.dto.ExecTemplateCacheDTO;
import java.util.concurrent.TimeUnit;
/**
* 执行模板缓存 key
*
* @author Jiahang Li
* @version 1.0.1
* @since 2024-3-7 18:08
*/
public interface ExecTemplateCacheKeyDefine {
CacheKeyDefine EXEC_TEMPLATE = new CacheKeyBuilder()
.key("exec:template:list")
.desc("执行模板列表")
.type(ExecTemplateCacheDTO.class)
.struct(RedisCacheStruct.HASH)
.timeout(1, TimeUnit.DAYS)
.build();
}

View File

@@ -0,0 +1,35 @@
package com.orion.ops.module.asset.entity.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 命令执行参数 schema 对象
*
* @author Jiahang Li
* @version 1.0.0
* @since 2024/3/15 14:50
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(name = "ExecParameterSchemaDTO", description = "命令执行参数 schema 对象")
public class ExecParameterSchemaDTO {
@Schema(description = "参数名称")
private String name;
@Schema(description = "参数描述")
private String desc;
@Schema(description = "默认值")
private Object defaultValue;
@Schema(description = "")
private Object value;
}

View File

@@ -1,43 +0,0 @@
package com.orion.ops.module.asset.entity.dto;
import com.orion.lang.define.cache.key.model.LongCacheIdModel;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* 执行模板 缓存对象
*
* @author Jiahang Li
* @version 1.0.1
* @since 2024-3-7 18:08
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(name = "ExecTemplateCacheDTO", description = "执行模板 缓存对象")
public class ExecTemplateCacheDTO implements LongCacheIdModel, Serializable {
private static final long serialVersionUID = 1L;
@Schema(description = "id")
private Long id;
@Schema(description = "名称")
private String name;
@Schema(description = "命令")
private String command;
@Schema(description = "超时时间秒 0不超时")
private Integer timeout;
@Schema(description = "参数")
private String parameter;
}

View File

@@ -34,10 +34,6 @@ public class ExecCommandRequest {
@Schema(description = "执行命令")
private String command;
@NotBlank
@Schema(description = "执行参数")
private String parameter;
@NotBlank
@Schema(description = "参数 schema")
private String parameterSchema;

View File

@@ -8,6 +8,7 @@ import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* 批量执行日志 视图响应对象
@@ -55,4 +56,7 @@ public class ExecLogVO implements Serializable {
@Schema(description = "执行完成时间")
private Date finishTime;
@Schema(description = "执行主机id")
private List<Long> hostIdList;
}

View File

@@ -24,6 +24,14 @@ public interface ExecLogService {
*/
DataGrid<ExecLogVO> getExecLogPage(ExecLogQueryRequest request);
/**
* 获取执行历史
*
* @param request request
* @return history
*/
List<ExecLogVO> getExecHistory(ExecLogQueryRequest request);
/**
* 获取执行日志状态
*

View File

@@ -6,8 +6,6 @@ import com.orion.ops.module.asset.entity.request.exec.ExecTemplateQueryRequest;
import com.orion.ops.module.asset.entity.request.exec.ExecTemplateUpdateRequest;
import com.orion.ops.module.asset.entity.vo.ExecTemplateVO;
import java.util.List;
/**
* 执行模板 服务类
*
@@ -41,13 +39,6 @@ public interface ExecTemplateService {
*/
ExecTemplateVO getExecTemplateById(Long id);
/**
* 通过缓存查询执行模板
*
* @return rows
*/
List<ExecTemplateVO> getExecTemplateListByCache();
/**
* 分页查询执行模板
*

View File

@@ -28,6 +28,7 @@ import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
@@ -64,6 +65,41 @@ public class ExecLogServiceImpl implements ExecLogService {
.dataGrid(ExecLogConvert.MAPPER::to);
}
@Override
public List<ExecLogVO> getExecHistory(ExecLogQueryRequest request) {
// 查询执行记录
List<ExecLogVO> logs = execLogDAO.of()
.createWrapper()
.eq(ExecLogDO::getSource, request.getSource())
.eq(ExecLogDO::getUserId, request.getUserId())
.groupBy(ExecLogDO::getDescription)
.orderByDesc(ExecLogDO::getId)
.then()
.limit(request)
.list(ExecLogConvert.MAPPER::to);
if (logs.isEmpty()) {
return logs;
}
List<Long> logIdList = logs.stream()
.map(ExecLogVO::getId)
.collect(Collectors.toList());
// 设置执行主机id
Map<Long, List<Long>> hostIdRel = execHostLogDAO.of()
.createWrapper()
.in(ExecHostLogDO::getLogId, logIdList)
.then()
.stream()
.collect(Collectors.groupingBy(
ExecHostLogDO::getLogId,
Collectors.mapping(
ExecHostLogDO::getHostId,
Collectors.toList()
)
));
logs.forEach(s -> s.setHostIdList(hostIdRel.get(s.getId())));
return logs;
}
@Override
public ExecLogStatusVO getExecLogStatus(List<Long> idList) {
// 查询执行状态

View File

@@ -1,10 +1,11 @@
package com.orion.ops.module.asset.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.orion.lang.function.Functions;
import com.orion.lang.id.UUIds;
import com.orion.lang.utils.Strings;
import com.orion.lang.utils.collect.Lists;
import com.orion.lang.utils.collect.Maps;
import com.orion.lang.utils.json.matcher.NoMatchStrategy;
import com.orion.lang.utils.json.matcher.ReplacementFormatter;
@@ -23,6 +24,7 @@ import com.orion.ops.module.asset.dao.HostDAO;
import com.orion.ops.module.asset.entity.domain.ExecHostLogDO;
import com.orion.ops.module.asset.entity.domain.ExecLogDO;
import com.orion.ops.module.asset.entity.domain.HostDO;
import com.orion.ops.module.asset.entity.dto.ExecParameterSchemaDTO;
import com.orion.ops.module.asset.entity.request.exec.ExecCommandRequest;
import com.orion.ops.module.asset.entity.vo.ExecCommandHostVO;
import com.orion.ops.module.asset.entity.vo.ExecCommandVO;
@@ -109,7 +111,7 @@ public class ExecServiceImpl implements ExecService {
execLogDAO.insert(execLog);
Long execId = execLog.getId();
// 获取内置参数
Map<String, Object> builtinsParams = this.getBaseBuiltinsParams(user, execId, request.getParameter());
Map<String, Object> builtinsParams = this.getBaseBuiltinsParams(user, execId, request.getParameterSchema());
// 设置主机日志
List<ExecHostLogDO> execHostLogs = hosts.stream()
.map(s -> {
@@ -159,7 +161,6 @@ public class ExecServiceImpl implements ExecService {
.description(execLog.getDescription())
.timeout(execLog.getTimeout())
.command(execLog.getCommand())
.parameter(hostLogs.get(0).getParameter())
.parameterSchema(execLog.getParameterSchema())
.hostIdList(hostIdList)
.build();
@@ -298,19 +299,37 @@ public class ExecServiceImpl implements ExecService {
}
/**
* 获取基础内置参数
* 提取参数
*
* @param user user
* @param execId execId
* @param parameterSchema parameterSchema
* @return params
*/
private Map<String, Object> getBaseBuiltinsParams(LoginUser user, Long execId, String inputParam) {
private Map<String, Object> extraSchemaParams(String parameterSchema) {
List<ExecParameterSchemaDTO> schemaList = JSON.parseArray(parameterSchema, ExecParameterSchemaDTO.class);
if (Lists.isEmpty(schemaList)) {
return Maps.newMap();
}
// 解析参数
return schemaList.stream()
.collect(Collectors.toMap(ExecParameterSchemaDTO::getName,
ExecParameterSchemaDTO::getValue,
Functions.right()));
}
/**
* 获取基础内置参数
*
* @param user user
* @param execId execId
* @param parameterSchema parameterSchema
* @return params
*/
private Map<String, Object> getBaseBuiltinsParams(LoginUser user, Long execId, String parameterSchema) {
String uuid = UUIds.random();
Date date = new Date();
// 输入参数
JSONObject inputParams = JSON.parseObject(inputParam);
// 内置参数
Map<String, Object> params = Maps.newMap(inputParams);
Map<String, Object> params = this.extraSchemaParams(parameterSchema);
// 添加内置参数
params.put("userId", user.getId());
params.put("username", user.getId());
params.put("execId", execId);

View File

@@ -5,13 +5,9 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.orion.lang.define.wrapper.DataGrid;
import com.orion.ops.framework.common.constant.ErrorMessage;
import com.orion.ops.framework.common.utils.Valid;
import com.orion.ops.framework.redis.core.utils.RedisMaps;
import com.orion.ops.framework.redis.core.utils.barrier.CacheBarriers;
import com.orion.ops.module.asset.convert.ExecTemplateConvert;
import com.orion.ops.module.asset.dao.ExecTemplateDAO;
import com.orion.ops.module.asset.define.cache.ExecTemplateCacheKeyDefine;
import com.orion.ops.module.asset.entity.domain.ExecTemplateDO;
import com.orion.ops.module.asset.entity.dto.ExecTemplateCacheDTO;
import com.orion.ops.module.asset.entity.request.exec.ExecTemplateCreateRequest;
import com.orion.ops.module.asset.entity.request.exec.ExecTemplateQueryRequest;
import com.orion.ops.module.asset.entity.request.exec.ExecTemplateUpdateRequest;
@@ -21,9 +17,6 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
/**
* 执行模板 服务实现类
@@ -50,8 +43,6 @@ public class ExecTemplateServiceImpl implements ExecTemplateService {
int effect = execTemplateDAO.insert(record);
Long id = record.getId();
log.info("ExecTemplateService-createExecTemplate id: {}, effect: {}", id, effect);
// 删除缓存
RedisMaps.delete(ExecTemplateCacheKeyDefine.EXEC_TEMPLATE);
return id;
}
@@ -69,8 +60,6 @@ public class ExecTemplateServiceImpl implements ExecTemplateService {
// 更新
int effect = execTemplateDAO.updateById(updateRecord);
log.info("ExecTemplateService-updateExecTemplateById effect: {}", effect);
// 删除缓存
RedisMaps.delete(ExecTemplateCacheKeyDefine.EXEC_TEMPLATE);
return effect;
}
@@ -83,27 +72,6 @@ public class ExecTemplateServiceImpl implements ExecTemplateService {
return ExecTemplateConvert.MAPPER.to(record);
}
@Override
public List<ExecTemplateVO> getExecTemplateListByCache() {
// 查询缓存
List<ExecTemplateCacheDTO> list = RedisMaps.valuesJson(ExecTemplateCacheKeyDefine.EXEC_TEMPLATE);
if (list.isEmpty()) {
// 查询数据库
list = execTemplateDAO.of().list(ExecTemplateConvert.MAPPER::toCache);
// 设置屏障 防止穿透
CacheBarriers.checkBarrier(list, ExecTemplateCacheDTO::new);
// 设置缓存
RedisMaps.putAllJson(ExecTemplateCacheKeyDefine.EXEC_TEMPLATE, s -> s.getId().toString(), list);
}
// 删除屏障
CacheBarriers.removeBarrier(list);
// 转换
return list.stream()
.map(ExecTemplateConvert.MAPPER::to)
.sorted(Comparator.comparing(ExecTemplateVO::getId).reversed())
.collect(Collectors.toList());
}
@Override
public DataGrid<ExecTemplateVO> getExecTemplatePage(ExecTemplateQueryRequest request) {
// 条件
@@ -123,8 +91,6 @@ public class ExecTemplateServiceImpl implements ExecTemplateService {
// 删除
int effect = execTemplateDAO.deleteById(id);
log.info("ExecTemplateService-deleteExecTemplateById id: {}, effect: {}", id, effect);
// 删除缓存
RedisMaps.delete(ExecTemplateCacheKeyDefine.EXEC_TEMPLATE, id);
return effect;
}