网络配置

This commit is contained in:
xydkj 2026-04-27 13:33:00 +08:00
parent e125063e0f
commit 68083d86c0
37 changed files with 3334 additions and 1363 deletions

View File

@ -52,6 +52,12 @@
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-jsqlparser</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>

View File

@ -1,6 +1,8 @@
package com.cisd.tms.common.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -9,6 +11,8 @@ public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
return new MybatisPlusInterceptor();
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}

View File

@ -1,24 +1,26 @@
package com.cisd.tms.common.config;
import com.cisd.tms.common.util.TraceIdUtil;
import com.cisd.tms.modules.auth.security.InternalAuthorizationInterceptor;
import com.cisd.tms.security.internal.CachedBodyHttpServletRequest;
import com.cisd.tms.security.internal.InternalApiAuthInterceptor;
import com.cisd.tms.security.internal.InternalApiReplayInterceptor;
import com.cisd.tms.security.internal.CachedBodyHttpServletRequest;
import com.cisd.tms.security.openapi.OpenApiSignAuthInterceptor;
import com.cisd.tms.common.util.TraceIdUtil;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import org.slf4j.MDC;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.io.IOException;
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@ -117,7 +119,7 @@ public class WebMvcConfig implements WebMvcConfigurer {
.allowedOriginPatterns("*")
.allowedMethods("*")
.allowedHeaders("*")
.exposedHeaders("X-Trace-Id")
.exposedHeaders("X-Trace-Id", HttpHeaders.CONTENT_DISPOSITION)
.allowCredentials(true)
.maxAge(3600);
}

View File

@ -2,23 +2,21 @@ package com.cisd.tms.modules.device.controller;
import com.cisd.tms.common.api.ApiResponse;
import com.cisd.tms.common.enums.ErrorCode;
import com.cisd.tms.common.exception.BizException;
import com.cisd.tms.modules.device.dto.network.*;
import com.cisd.tms.modules.device.entity.PageResult;
import com.cisd.tms.modules.device.service.NetworkConfigService;
import com.cisd.tms.modules.log.annotation.AuditedOperation;
import com.cisd.tms.modules.log.enums.ActionType;
import com.cisd.tms.modules.log.enums.ModuleCode;
import com.cisd.tms.security.internal.ReplayProtected;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@Tag(name = "网络配置管理", description = "提供设备网络信息查询、IPv4/IPv6配置、Bond配置及路由管理等接口")
@RestController
@RequestMapping("/api/v1/device/network-config")
@RequestMapping("/api/v1/device/network")
public class NetworkConfigController {
private final NetworkConfigService networkConfigService;
@ -27,158 +25,88 @@ public class NetworkConfigController {
this.networkConfigService = networkConfigService;
}
@Operation(summary = "获取网络信息", description = "获取当前设备的所有网络连接信息")
@GetMapping("/network-info")
public ApiResponse<List<NetworkInfoResponse>> getNetworkInfo(){
return ApiResponse.success(networkConfigService.getNetworkInfo());
@Operation(summary = "分页查询网卡配置", description = "分页查询设备网卡配置列表,支持按网卡名称、状态等条件筛选")
@PostMapping("/card/Page")
public ApiResponse<PageResult<NetworkTableResponse>> getNetworkTablePage(@RequestBody NetworkTableQueryRequest request) {
PageResult<NetworkTableResponse> pageData = networkConfigService.getNetworkTablePage(request);
return ApiResponse.success(pageData);
}
@Operation(summary = "获取IPv4配置信息", description = "根据设备名称获取指定网络接口的IPv4配置详情")
@GetMapping("/ipv4-info/{deviceName}")
public ApiResponse<Ipv4InfoResponse> getIpv4Info(@PathVariable String deviceName){
return ApiResponse.success(networkConfigService.getIpv4Info(deviceName));
}
@Operation(summary = "设置IPv4配置", description = "为指定网络接口配置IPv4地址、掩码、网关等信息")
@PostMapping("/ipv4-config/set")
@ReplayProtected
@AuditedOperation(module = ModuleCode.NETWORK, action = ActionType.CREATE, summary = "设置IPv4配置")
public ApiResponse<Void> setIpv4Config(@RequestBody Ipv4ConfigRequest req) {
networkConfigService.setIpv4Config(req);
@Operation(summary = "配置网卡", description = "配置指定网卡的 IPv4 或 IPv6 地址、前缀长度、网关和状态")
@PostMapping("/card/configure")
public ApiResponse<Void> configureNetworkCard(@RequestBody @Validated NetworkConfigureRequest request) {
networkConfigService.configureNetworkCard(request);
return ApiResponse.success();
}
@Operation(summary = "获取IPv6配置信息", description = "根据设备名称获取指定网络接口的IPv6配置详情")
@GetMapping("/ipv6-info/{deviceName}")
public ApiResponse<Ipv6InfoResponse> getIpv6Info(@PathVariable String deviceName){
return ApiResponse.success(networkConfigService.getIpv6Info(deviceName));
}
@Operation(summary = "设置IPv6配置", description = "为指定网络接口配置IPv6地址、前缀长度、网关等信息")
@PostMapping("/ipv6-config/set")
@ReplayProtected
@AuditedOperation(module = ModuleCode.NETWORK, action = ActionType.CREATE, summary = "设置IPv6配置")
public ApiResponse<Void> setIpv6Config(@RequestBody Ipv6ConfigRequest req) {
networkConfigService.setIpv6Config(req);
@Operation(summary = "新增网卡配置", description = "新增或配置指定网卡的网络地址信息")
@PostMapping("/card/add")
public ApiResponse<Void> addNetworkCard(@RequestBody @Validated NetworkConfigureRequest req) {
networkConfigService.configureNetworkCard(req);
return ApiResponse.success();
}
@Operation(summary = "获取所有Bond名称", description = "返回当前系统中所有已创建的Bond接口名称")
@GetMapping("/all-bond-name")
public ApiResponse<List<String>> getAllBondName(){
return ApiResponse.success(networkConfigService.getAllBondName());
}
@Operation(summary = "创建Bond", description = "创建一个新的Bond聚合接口需指定名称、模式和从属接口")
@PostMapping("/bond/create")
@ReplayProtected
@AuditedOperation(module = ModuleCode.NETWORK, action = ActionType.CREATE, summary = "创建Bond")
public ApiResponse<Void> createBond(@RequestBody BondCreateRequest req) {
networkConfigService.createBond(req);
@Operation(summary = "删除网卡 IP 配置", description = "删除指定网卡下的某条 IPv4 或 IPv6 地址配置")
@PostMapping("/card/delete")
public ApiResponse<Void> deleteNetworkCardRecord(@RequestBody NetworkDeleteRequest req) {
networkConfigService.deleteNetworkCardRecord(req);
return ApiResponse.success();
}
@Operation(summary = "分页查询 Bond 配置", description = "分页查询 Bond 聚合接口配置列表,包含 Bond 名称、模式、IP、网关和状态")
@PostMapping("/bond/page")
public ApiResponse<PageResult<BondTableResponse>> getBondPage(@RequestBody BondTableRequest req) {
return ApiResponse.success(networkConfigService.getBondPage(req));
}
@Operation(summary = "删除Bond", description = "根据Bond名称删除指定的聚合接口")
@Operation(summary = "删除 Bond", description = "删除指定 Bond 聚合接口及其从属网卡连接配置")
@PostMapping("/bond/delete/{bondName}")
@ReplayProtected
@AuditedOperation(module = ModuleCode.NETWORK, action = ActionType.DELETE, summary = "删除Bond")
public ApiResponse<Void> deleteBond(@PathVariable("bondName") String bondName){
public ApiResponse<Void> deleteBond(@PathVariable String bondName) {
networkConfigService.deleteBond(bondName);
return ApiResponse.success();
}
@Operation(summary = "添加从属接口到Bond", description = "向指定Bond中添加一个或多个从属网络接口")
@PostMapping("/bond-slave/add")
@ReplayProtected
@AuditedOperation(module = ModuleCode.NETWORK, action = ActionType.UPDATE, summary = "添加从属接口到Bond")
public ApiResponse<Void> addSlavesTOBond(@RequestBody BondAddSlavesRequest req) {
networkConfigService.addSlavesTOBond(req);
@Operation(summary = "创建Bond", description = "创建一个新的Bond聚合接口需指定名称、模式和从属接口")
@PostMapping("/bond/create")
@AuditedOperation(module = ModuleCode.NETWORK, action = ActionType.CREATE, summary = "创建Bond")
public ApiResponse<Void> createBond(@Valid @RequestBody BondCreateRequest req) {
networkConfigService.createBond(req);
return ApiResponse.success();
}
@Operation(summary = "从Bond中移除从属接口", description = "从指定Bond中移除一个或多个从属网络接口")
@PostMapping("/bond-slave/remove")
@ReplayProtected
@AuditedOperation(module = ModuleCode.NETWORK, action = ActionType.DELETE, summary = "从Bond中移除从属接口")
public ApiResponse<String> removeSlaveFromBond(@RequestBody BondRemoveSlaveRequest req) {
String resultMessage = networkConfigService.removeSlaveFromBond(req);
return ApiResponse.success(resultMessage);
}
@Operation(summary = "获取Bond的从属接口列表", description = "根据Bond名称返回其所有从属接口名称")
@GetMapping("/bond-slave/{bondName}")
public ApiResponse<List<String>> getBondSlaves(@PathVariable String bondName){
return ApiResponse.success(networkConfigService.getBondSlaves(bondName));
}
@Operation(summary = "获取Bond模式", description = "根据Bond名称查询当前的绑定模式")
@GetMapping("/bond/mode/{bondName}")
public ApiResponse<String> getBondMode(@PathVariable("bondName") String bondName) {
String mode = networkConfigService.getBondMode(bondName);
if (mode == null) {
throw new BizException(ErrorCode.BAD_REQUEST.getCode(), "未找到该连接的 Bond 模式");
}
return ApiResponse.success(mode);
}
@Operation(summary = "设置Bond模式", description = "修改指定Bond的绑定模式")
@PostMapping("/bond/mode/set")
@ReplayProtected
@AuditedOperation(module = ModuleCode.NETWORK, action = ActionType.UPDATE, summary = "设置Bond模式")
public ApiResponse<Void> setBondMode(@RequestBody BondModifyModeRequest req) {
networkConfigService.setBondMode(req);
@Operation(summary = "配置 Bond", description = "修改指定 Bond 的模式、IP 地址、网关、从属物理网卡和激活状态")
@PostMapping("/bond/config")
public ApiResponse<Void> configBond(@Valid @RequestBody BondConfigRequest req) {
networkConfigService.configBond(req);
return ApiResponse.success();
}
@Operation(summary = "获取路由表", description = "返回当前系统的IPv4/IPv6路由表信息")
@GetMapping("/routes/routingTable")
public ApiResponse<List<RouteInfoResponse>> getRoutingTable() {
List<RouteInfoResponse> routes = networkConfigService.getRoutingTable();
return ApiResponse.success(routes);
@Operation(summary = "分页查询路由配置", description = "分页查询静态路由列表,支持 IPv4/IPv6、目标类型和状态筛选")
@PostMapping("/route/page")
public ApiResponse<PageResult<RouteTableResponse>> routePage(@RequestBody RouteTableRequest req) {
return ApiResponse.success(networkConfigService.getRoutePage(req));
}
@Operation(summary = "设置默认路由", description = "配置或修改系统的默认网关路由")
@PostMapping("/routes/default/set")
@ReplayProtected
@AuditedOperation(module = ModuleCode.NETWORK, action = ActionType.UPDATE, summary = "设置默认路由")
public ApiResponse<Void> setDefaultRoute(@RequestBody SetDefaultRouteRequest req) {
networkConfigService.setDefaultRoute(req);
@Operation(summary = "新增路由", description = "新增一条 IPv4 或 IPv6 静态路由配置,可指定目标地址、前缀长度、网口和下一跳")
@PostMapping("/route/add")
public ApiResponse<Void> routeAdd(@Valid @RequestBody RouteCreateRequest req) {
networkConfigService.addRoute(req);
return ApiResponse.success();
}
@Operation(summary = "添加静态路由", description = "新增一条静态路由规则")
@PostMapping("/routes/static/add")
@ReplayProtected
@AuditedOperation(module = ModuleCode.NETWORK, action = ActionType.UPDATE, summary = "添加静态路由")
public ApiResponse<Void> addStaticRoute(@RequestBody AddStaticRouteRequest req) {
networkConfigService.addStaticRoute(req);
@Operation(summary = "修改路由", description = "修改一条已有静态路由,通过删除旧路由并新增新路由实现")
@PostMapping("/route/update")
public ApiResponse<Void> routeUpdate(@Valid @RequestBody RouteUpdateRequest req) {
networkConfigService.updateRoute(req);
return ApiResponse.success();
}
@Operation(summary = "删除默认路由", description = "删除指定的默认路由")
@PostMapping("/routes/default/delete")
@ReplayProtected
@AuditedOperation(module = ModuleCode.NETWORK, action = ActionType.DELETE, summary = "删除默认路由")
public ApiResponse<Void> deleteDefaultRoute(@RequestBody DeleteDefaultRouteRequest req) {
networkConfigService.deleteDefaultRoute(req);
return ApiResponse.success();
}
@Operation(summary = "删除静态路由", description = "删除指定的静态路由")
@PostMapping("/routes/static/delete")
@ReplayProtected
@AuditedOperation(module = ModuleCode.NETWORK, action = ActionType.DELETE, summary = "删除静态路由")
public ApiResponse<Void> deleteStaticRoute(@RequestBody DeleteStaticRouteRequest req) {
networkConfigService.deleteStaticRoute(req);
@Operation(summary = "删除路由", description = "删除指定网口下的一条 IPv4 或 IPv6 静态路由配置")
@PostMapping("/route/delete")
public ApiResponse<Void> routeDelete(@Valid @RequestBody RouteDeleteRequest req) {
networkConfigService.deleteRoute(req);
return ApiResponse.success();
}
}

View File

@ -1,16 +0,0 @@
package com.cisd.tms.modules.device.dto.network;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "添加静态路由请求参数")
public class AddStaticRouteRequest {
@Schema(description = "网络设备名称(如 eth0、bond0", example = "eth0")
private String deviceName;
@Schema(description = "目标网络CIDR", example = "192.168.1.0/24")
private String targetCidr;
@Schema(description = "下一跳地址网关IP", example = "192.168.1.1")
private String nextHop;
}

View File

@ -0,0 +1,77 @@
package com.cisd.tms.modules.device.dto.network;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.util.List;
@Data
@Schema(description = "Bond 配置请求")
public class BondConfigRequest {
/**
* Bond 名称例如 bond0
*/
@Schema(description = "Bond 名称,例如 bond0", example = "bond0", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "Bond名称不能为空")
private String bondName;
/**
* Bond 模式
* 0: balance-rr
* 1: active-backup
* 2: balance-xor
* 4: 802.3ad
*/
@Schema(
description = "Bond 模式0=balance-rr平衡轮询1=active-backup主备2=balance-xor平衡异或4=802.3ad动态链路聚合",
example = "1",
requiredMode = Schema.RequiredMode.REQUIRED
)
@NotNull(message = "Bond类型不能为空")
private Integer mode;
/**
* 地址类型IPv4 / IPv6
*/
@Schema(description = "地址类型IPv4 或 IPv6", example = "IPv4", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "地址类型不能为空")
private String addressType;
/**
* 网络地址
*/
@Schema(description = "网络地址,不包含前缀长度", example = "192.168.10.100", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "网络地址不能为空")
private String ipAddress;
/**
* 前缀长度
*/
@Schema(description = "前缀长度IPv4 范围 0-32IPv6 范围 0-128", example = "24", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "前缀长度不能为空")
private Integer prefixLength;
/**
* 网关地址可为空
*/
@Schema(description = "网关地址,可为空", example = "192.168.10.1")
private String gateway;
/**
* 选择的物理网卡
*/
@Schema(description = "选择加入 Bond 的物理网卡列表", example = "[\"eth0\", \"eth1\"]", requiredMode = Schema.RequiredMode.REQUIRED)
@NotEmpty(message = "请选择至少一个物理网卡")
private List<String> slaveList;
/**
* Active / Inactive
*/
@Schema(description = "Bond 状态Active=激活Inactive=未激活", example = "Active", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "状态不能为空")
private String status;
}

View File

@ -1,32 +1,95 @@
package com.cisd.tms.modules.device.dto.network;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.util.List;
@Data
@Schema(description = "创建Bond请求参数")
public class BondCreateRequest {
/**
* Bond 名称例如 "bond0"
* bond名称例如 bond0
*/
@Schema(description = "Bond 名称", example = "bond0")
@Schema(
description = "Bond名称例如 bond0、bond1",
example = "bond0",
requiredMode = Schema.RequiredMode.REQUIRED
)
@NotBlank(message = "Bond名称不能为空")
private String bondName;
/**
* 模式 (例如: 0, 1, 2, 4)
* 0: balance-rr (轮询)
* 1: active-backup (主备)
* bond模式
* 0: balance-rr
* 1: active-backup
* 2: balance-xor
* 4: 802.3ad (动态链路聚合)
* 4: 802.3ad
*/
@Schema(description = "Bond 模式0: balance-rr 轮询, 1: active-backup 主备, 2: balance-xor, 4: 802.3ad 动态链路聚合"
,example = "1")
@Schema(
description = "Bond模式0=balance-rr平衡轮询1=active-backup主备2=balance-xor平衡异或4=802.3ad动态链路聚合",
example = "1",
allowableValues = {"0", "1", "2", "4"},
requiredMode = Schema.RequiredMode.REQUIRED
)
@NotNull(message = "Bond类型不能为空")
private Integer mode;
/**
* 可选的 IPv4 配置
* 如果前端传了该对象创建 Bond 后会自动配置 IP
* 地址类型IPv4 / IPv6
*/
@Schema(description = "可选的 IPv4 配置,如果提供该对象,创建 Bond 后会自动配置 IP")
private Ipv4ConfigRequest ipv4Config;
@Schema(
description = "地址类型IPv4 或 IPv6",
example = "IPv4",
allowableValues = {"IPv4", "IPv6"},
requiredMode = Schema.RequiredMode.REQUIRED
)
@NotBlank(message = "地址类型不能为空")
private String addressType;
/**
* 网络地址
*/
@Schema(
description = "网络地址,不包含前缀长度",
example = "192.168.10.100",
requiredMode = Schema.RequiredMode.REQUIRED
)
@NotBlank(message = "网络地址不能为空")
private String ipAddress;
/**
* 前缀长度
*/
@Schema(
description = "前缀长度IPv4范围0-32IPv6范围0-128",
example = "24",
requiredMode = Schema.RequiredMode.REQUIRED
)
@NotNull(message = "前缀长度不能为空")
private Integer prefixLength;
/**
* 网关地址可为空
*/
@Schema(
description = "网关地址,可为空",
example = "192.168.10.1"
)
private String gateway;
/**
* 选择的物理网卡例如 eth0eth1
*/
@Schema(
description = "选择加入Bond的物理网卡列表",
example = "[\"eth0\", \"eth1\"]",
requiredMode = Schema.RequiredMode.REQUIRED
)
@NotEmpty(message = "请选择至少一个物理网卡")
private List<String> slaveList;
}

View File

@ -1,15 +0,0 @@
package com.cisd.tms.modules.device.dto.network;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "修改bond模式请求参数")
public class BondModifyModeRequest {
@Schema(description = "Bond 名称", example = "bond0")
private String bondName;
@Schema(description = "Bond 模式0: balance-rr 轮询, 1: active-backup 主备, 2: balance-xor, 4: 802.3ad 动态链路聚合"
,example = "1")
private Integer mode;
}

View File

@ -0,0 +1,37 @@
package com.cisd.tms.modules.device.dto.network;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "Bond分页查询请求参数")
public class BondTableRequest {
/**
* Bond 名称
*/
@Schema(description = "Bond名称支持按Bond名称筛选", example = "bond0")
private String bondName;
/**
* 状态Active / Inactive
*/
@Schema(
description = "Bond状态Active=激活Inactive=未激活",
example = "Active",
allowableValues = {"Active", "Inactive"}
)
private String status;
/**
* 页码
*/
@Schema(description = "页码从1开始", example = "1")
private Integer pageNum = 1;
/**
* 每页条数
*/
@Schema(description = "每页条数", example = "10")
private Integer pageSize = 10;
}

View File

@ -0,0 +1,62 @@
package com.cisd.tms.modules.device.dto.network;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "Bond分页查询响应数据")
public class BondTableResponse {
/**
* bond名称
*/
@Schema(description = "Bond名称", example = "bond0")
private String bondName;
/**
* bond模型
*/
@Schema(
description = "Bond模式",
example = "bond1-主备"
)
private String bondMode;
/**
* 地址类型IPV4 / IPV6
*/
@Schema(
description = "地址类型IPV4 或 IPV6",
example = "IPV4",
allowableValues = {"IPV4", "IPV6", "-"}
)
private String addressType;
/**
* 地址
*/
@Schema(description = "IP地址", example = "192.168.10.100")
private String address;
/**
* 前缀长度
*/
@Schema(description = "前缀长度", example = "24")
private String prefixLength;
/**
* 网关
*/
@Schema(description = "网关地址", example = "192.168.10.1")
private String gateway;
/**
* 状态Active / Inactive
*/
@Schema(
description = "Bond状态Active=激活Inactive=未激活",
example = "Active",
allowableValues = {"Active", "Inactive"}
)
private String status;
}

View File

@ -1,11 +0,0 @@
package com.cisd.tms.modules.device.dto.network;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "删除默认路由请求参数")
public class DeleteDefaultRouteRequest {
@Schema(description = "网络设备名称(如 eth0、bond0", example = "eth0")
private String deviceName;
}

View File

@ -1,18 +0,0 @@
package com.cisd.tms.modules.device.dto.network;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "删除静态路由请求参数")
public class DeleteStaticRouteRequest {
@Schema(description = "网络设备名称", example = "eth0")
private String deviceName;
@Schema(description = "目标网络CIDR", example = "192.168.1.0/24")
private String targetCidr;
@Schema(description = "下一跳地址网关IP", example = "192.168.1.1")
private String nextHop;
}

View File

@ -1,17 +0,0 @@
package com.cisd.tms.modules.device.dto.network;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "IPv4配置请求参数")
public class Ipv4ConfigRequest {
@Schema(description = "网络设备名称", example = "eth0")
private String deviceName;
@Schema(description = "IPv4地址", example = "192.168.1.100")
private String ipv4;
@Schema(description = "子网掩码长度", example = "24")
private String maskLength;
@Schema(description = "默认网关地址", example = "192.168.1.1")
private String gateway;
}

View File

@ -1,18 +0,0 @@
package com.cisd.tms.modules.device.dto.network;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "IPv4配置信息响应")
public class Ipv4InfoResponse {
@Schema(description = "IPv4地址", example = "192.168.1.100")
private String ipv4;
@Schema(description = "子网掩码长度", example = "24")
private String maskLength;
@Schema(description = "默认网关地址", example = "192.168.1.1")
private String gateway;
@Schema(description = "IP获取方式如 static、dhcp", example = "static")
private String method;
}

View File

@ -1,13 +0,0 @@
package com.cisd.tms.modules.device.dto.network;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "单个IPv6地址及掩码")
public class Ipv6AddressItem {
@Schema(description = "IPv6地址", example = "2001:db8::2")
private String ipv6;
@Schema(description = "子网掩码前缀长度", example = "64")
private String maskLength;
}

View File

@ -1,17 +0,0 @@
package com.cisd.tms.modules.device.dto.network;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "IPv6配置请求参数")
public class Ipv6ConfigRequest {
@Schema(description = "网络设备名称(如 eth0、bond0", example = "eth0")
private String deviceName;
@Schema(description = "IPv6地址", example = "2001:db8::1")
private String ipv6;
@Schema(description = "默认网关地址", example = "2001:db8::1")
private String gateway;
@Schema(description = "子网前缀长度(如 64", example = "64")
private String maskLength;
}

View File

@ -1,17 +0,0 @@
package com.cisd.tms.modules.device.dto.network;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Data
@Schema(description = "IPv6配置信息响应")
public class Ipv6InfoResponse {
@Schema(description = "IPv6地址及掩码列表")
private List<Ipv6AddressItem> ipv6List;
@Schema(description = "默认网关地址", example = "2001:db8::1")
private String gateway;
@Schema(description = "IP获取方式如 static、dhcp、auto", example = "static")
private String method;
}

View File

@ -0,0 +1,62 @@
package com.cisd.tms.modules.device.dto.network;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
@Data
@Schema(description = "网卡配置请求参数")
public class NetworkConfigureRequest {
@Schema(
description = "网卡名称,例如 eth0、ens33、bond0",
example = "eth0",
requiredMode = Schema.RequiredMode.REQUIRED
)
@NotBlank(message = "网卡名称不能为空")
private String deviceName;
@Schema(
description = "地址类型IPv4 或 IPv6",
example = "IPv4",
allowableValues = {"IPv4", "IPv6"},
requiredMode = Schema.RequiredMode.REQUIRED
)
@NotBlank(message = "地址类型不能为空")
private String addressType;
@Schema(
description = "网络地址,不包含前缀长度",
example = "192.168.10.100",
requiredMode = Schema.RequiredMode.REQUIRED
)
@NotBlank(message = "网络地址不能为空")
private String ipAddress;
@Schema(
description = "前缀长度IPv4范围0-32IPv6范围0-128",
example = "24",
requiredMode = Schema.RequiredMode.REQUIRED
)
@NotNull(message = "前缀长度不能为空")
private Integer prefixLength;
/**
* 网关地址
*/
@Schema(
description = "网关地址,可为空",
example = "192.168.10.1"
)
private String gateway;
@Schema(
description = "网卡状态Active=激活Inactive=未激活",
example = "Active",
allowableValues = {"Active", "Inactive"},
requiredMode = Schema.RequiredMode.REQUIRED
)
@NotBlank(message = "网卡状态不能为空")
private String status;
}

View File

@ -0,0 +1,44 @@
package com.cisd.tms.modules.device.dto.network;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
@Data
@Schema(description = "删除网卡IP配置请求参数")
public class NetworkDeleteRequest {
@Schema(
description = "网卡名称,例如 eth0、ens33、bond0",
example = "eth0",
requiredMode = Schema.RequiredMode.REQUIRED
)
@NotBlank(message = "网卡名称不能为空")
private String deviceName;
@Schema(
description = "地址类型IPv4 或 IPv6",
example = "IPv4",
allowableValues = {"IPv4", "IPv6"},
requiredMode = Schema.RequiredMode.REQUIRED
)
@NotBlank(message = "地址类型不能为空")
private String addressType;
@Schema(
description = "需要删除的网络地址,不包含前缀长度",
example = "192.168.10.100",
requiredMode = Schema.RequiredMode.REQUIRED
)
@NotBlank(message = "网络地址不能为空")
private String ipAddress;
@Schema(
description = "前缀长度IPv4范围0-32IPv6范围0-128",
example = "24",
requiredMode = Schema.RequiredMode.REQUIRED
)
@NotNull(message = "前缀长度不能为空")
private Integer prefixLength;
}

View File

@ -1,30 +0,0 @@
package com.cisd.tms.modules.device.dto.network;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Data
@Schema(description = "网络接口信息响应参数")
public class NetworkInfoResponse {
@Schema(description = "设备名称", example = "eth0")
private String deviceName;
@Schema(description = "接口类型", example = "ethernet")
private String type;
@Schema(description = "连接状态", example = "connected")
private String state;
@Schema(description = "NetworkManager中的连接名称通常与deviceName相同", example = "eth0")
private String connectionName;
@Schema(description = "IPv4 地址", example = "192.168.1.100")
private String ipv4;
@Schema(description = "IPv6 地址", example = "2001:db8::1")
private List<String> ipv6;
@Schema(description = "MAC 地址", example = "00:11:22:33:44:55")
private String mac;
@Schema(description = "默认网关地址", example = "192.168.1.1")
private String gateway;
}

View File

@ -0,0 +1,37 @@
package com.cisd.tms.modules.device.dto.network;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "网卡配置分页查询请求参数")
public class NetworkTableQueryRequest {
/**
* 网卡名条件可选
*/
@Schema(description = "网卡名称,支持按网卡名筛选", example = "eth0")
private String deviceName;
/**
* 状态条件可选
*/
@Schema(
description = "网卡状态Active=激活Inactive=未激活",
example = "Active",
allowableValues = {"Active", "Inactive"}
)
private String status;
/**
* 当前页码默认 1
*/
@Schema(description = "当前页码从1开始", example = "1")
private Integer pageNum = 1;
/**
* 每页条数默认 10
*/
@Schema(description = "每页条数", example = "10")
private Integer pageSize = 10;
}

View File

@ -0,0 +1,53 @@
package com.cisd.tms.modules.device.dto.network;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "网卡配置分页查询响应数据")
public class NetworkTableResponse {
/**
* 网卡名 eth0eth1
*/
@Schema(description = "网卡名称", example = "eth0")
private String deviceName;
/**
* 地址类型 IPV4IPV6-
*/
@Schema(
description = "地址类型IPV4、IPV6 或 -",
example = "IPV4",
allowableValues = {"IPV4", "IPV6", "-"}
)
private String addressType;
/**
* 地址 172.16.18.1
*/
@Schema(description = "IP地址", example = "172.16.18.1")
private String address;
/**
* 前缀长度 2464
*/
@Schema(description = "前缀长度", example = "24")
private String prefixLength;
/**
* 网关 172.16.18.254
*/
@Schema(description = "网关地址", example = "172.16.18.254")
private String gateway;
/**
* 状态 ActiveInactive
*/
@Schema(
description = "网卡状态Active=激活Inactive=未激活",
example = "Active",
allowableValues = {"Active", "Inactive"}
)
private String status;
}

View File

@ -0,0 +1,81 @@
package com.cisd.tms.modules.device.dto.network;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
@Data
@Schema(description = "新增路由请求参数")
public class RouteCreateRequest {
/**
* HOST / NETWORK
*/
@Schema(
description = "目标类型HOST=主机地址NETWORK=网段地址",
example = "NETWORK",
allowableValues = {"HOST", "NETWORK"},
requiredMode = Schema.RequiredMode.REQUIRED
)
@NotBlank(message = "目标类型不能为空")
private String targetType;
/**
* 目标地址例如
* HOST: 172.2.2.2
* NETWORK: 192.168.10.0
*/
@Schema(
description = "目标地址。HOST时填写主机IPNETWORK时填写网段地址",
example = "192.168.10.0",
requiredMode = Schema.RequiredMode.REQUIRED
)
@NotBlank(message = "目标地址不能为空")
private String targetAddress;
/**
* 前缀长度
* HOST 一般为 32
* NETWORK 例如 2464
*/
@Schema(
description = "前缀长度。IPv4主机路由一般为32IPv6主机路由一般为128网段路由例如IPv4为24、IPv6为64",
example = "24",
requiredMode = Schema.RequiredMode.REQUIRED
)
@NotNull(message = "前缀长度不能为空")
private Integer prefixLength;
/**
* 网口例如 eth0
*/
@Schema(
description = "出接口名称,例如 eth0、ens33、bond0",
example = "eth0",
requiredMode = Schema.RequiredMode.REQUIRED
)
@NotBlank(message = "网口不能为空")
private String interfaceName;
/**
* 下一跳可为空
*/
@Schema(
description = "下一跳网关地址,可为空。为空时表示直连路由",
example = "192.168.10.1"
)
private String nextHop;
/**
* 地址类型IPv4 / IPv6
*/
@Schema(
description = "地址类型IPv4 或 IPv6",
example = "IPv4",
allowableValues = {"IPv4", "IPv6"},
requiredMode = Schema.RequiredMode.REQUIRED
)
@NotBlank(message = "地址类型不能为空")
private String addressType;
}

View File

@ -0,0 +1,62 @@
package com.cisd.tms.modules.device.dto.network;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
@Data
@Schema(description = "删除路由请求参数")
public class RouteDeleteRequest {
@Schema(
description = "目标类型HOST=主机地址NETWORK=网段地址",
example = "NETWORK",
allowableValues = {"HOST", "NETWORK"},
requiredMode = Schema.RequiredMode.REQUIRED
)
@NotBlank(message = "目标类型不能为空")
private String targetType;
@Schema(
description = "目标地址。HOST时填写主机IPNETWORK时填写网段地址",
example = "192.168.10.0",
requiredMode = Schema.RequiredMode.REQUIRED
)
@NotBlank(message = "目标地址不能为空")
private String targetAddress;
@Schema(
description = "前缀长度。IPv4主机路由一般为32IPv6主机路由一般为128网段路由例如IPv4为24、IPv6为64",
example = "24",
requiredMode = Schema.RequiredMode.REQUIRED
)
@NotNull(message = "前缀长度不能为空")
private Integer prefixLength;
@Schema(
description = "出接口名称,例如 eth0、ens33、bond0",
example = "eth0",
requiredMode = Schema.RequiredMode.REQUIRED
)
@NotBlank(message = "网口不能为空")
private String interfaceName;
@Schema(
description = "地址类型IPv4 或 IPv6",
example = "IPv4",
allowableValues = {"IPv4", "IPv6"},
requiredMode = Schema.RequiredMode.REQUIRED
)
@NotBlank(message = "地址类型不能为空")
private String addressType;
/**
* 下一跳可为空
*/
@Schema(
description = "下一跳网关地址,可为空。为空时表示直连路由",
example = "192.168.10.1"
)
private String nextHop;
}

View File

@ -1,18 +0,0 @@
package com.cisd.tms.modules.device.dto.network;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "路由信息响应")
public class RouteInfoResponse {
@Schema(description = "目标网络或主机CIDR格式或主机地址", example = "0.0.0.0/0")
private String destination;
@Schema(description = "下一跳地址(网关)", example = "192.168.1.1")
private String nextHop;
@Schema(description = "出口网络接口名称", example = "eth0")
private String interfaceName;
}

View File

@ -0,0 +1,38 @@
package com.cisd.tms.modules.device.dto.network;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "路由分页查询请求参数")
public class RouteTableRequest {
/**
* 目标类型
* HOST主机地址
* NETWORK网段地址
*/
@Schema(
description = "目标类型HOST=主机地址NETWORK=网段地址",
example = "NETWORK",
allowableValues = {"HOST", "NETWORK"}
)
private String targetType;
/**
* 网卡状态
* Active / Inactive
*/
@Schema(
description = "网卡状态Active=激活Inactive=未激活",
example = "Active",
allowableValues = {"Active", "Inactive"}
)
private String status;
@Schema(description = "当前页码从1开始", example = "1")
private Integer pageNum = 1;
@Schema(description = "每页条数", example = "10")
private Integer pageSize = 10;
}

View File

@ -0,0 +1,61 @@
package com.cisd.tms.modules.device.dto.network;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "路由分页查询响应数据")
public class RouteTableResponse {
/**
* 目标类型主机地址 / 网段地址
*/
@Schema(
description = "目标类型HOST=主机地址NETWORK=网段地址",
example = "NETWORK",
allowableValues = {"HOST", "NETWORK"}
)
private String targetType;
/**
* 目标地址
*/
@Schema(description = "目标地址", example = "192.168.10.0")
private String targetAddress;
/**
* 前缀长度
*/
@Schema(description = "前缀长度", example = "24")
private String prefixLength;
/**
* 网口
*/
@Schema(description = "出接口名称", example = "eth0")
private String interfaceName;
/**
* 下一跳可为空
*/
@Schema(description = "下一跳网关地址,可为空。为空时表示直连路由", example = "192.168.10.1")
private String nextHop;
/**
* 状态Active / Inactive
*/
@Schema(
description = "网口状态Active=激活Inactive=未激活",
example = "Active",
allowableValues = {"Active", "Inactive"}
)
private String status;
@Schema(
description = "网口状态Active=激活Inactive=未激活",
example = "Active",
allowableValues = {"Active", "Inactive"}
)
private String addressType;
}

View File

@ -0,0 +1,27 @@
package com.cisd.tms.modules.device.dto.network;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
@Data
@Schema(description = "修改路由请求参数")
public class RouteUpdateRequest {
@Schema(
description = "旧路由信息,用于定位需要被修改的原始路由",
requiredMode = Schema.RequiredMode.REQUIRED
)
@Valid
@NotNull(message = "旧路由信息不能为空")
private RouteCreateRequest oldRoute;
@Schema(
description = "新路由信息,用于替换旧路由",
requiredMode = Schema.RequiredMode.REQUIRED
)
@Valid
@NotNull(message = "新路由信息不能为空")
private RouteCreateRequest newRoute;
}

View File

@ -1,15 +0,0 @@
package com.cisd.tms.modules.device.dto.network;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "设置默认路由请求参数")
public class SetDefaultRouteRequest {
@Schema(description = "网络设备名称(如 eth0、bond0", example = "eth0")
private String deviceName;
@Schema(description = "默认网关IP地址", example = "192.168.1.1")
private String gatewayIp;
}

View File

@ -0,0 +1,18 @@
package com.cisd.tms.modules.device.entity;
import lombok.Data;
import java.util.List;
@Data
public class PageResult<T> {
private long total;
private List<T> records;
public PageResult(long total, List<T> records) {
this.total = total;
this.records = records;
}
}

View File

@ -4,6 +4,10 @@ import com.cisd.tms.common.enums.ErrorCode;
import com.cisd.tms.common.exception.BizException;
import com.cisd.tms.modules.device.dto.TimeConfigRequest;
import com.cisd.tms.modules.device.service.TimeConfigService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
@ -12,15 +16,12 @@ import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.time.format.ResolverStyle;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
@ -40,6 +41,10 @@ public class TimeConfigServiceImpl implements TimeConfigService {
throw new IllegalArgumentException("Invalid or empty timezone format");
}
if (!ZoneId.getAvailableZoneIds().contains(timezone)) {
throw new IllegalArgumentException( "Invalid timezone");
}
String datetime = request.getDatetime();
if (datetime == null) {
throw new IllegalArgumentException("Invalid or empty datetime format. Expected: YYYY-MM-DD HH:MM");

View File

@ -2,7 +2,6 @@ package com.cisd.tms.modules.log.repository.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cisd.tms.modules.log.dto.BackupRecordPageRequest;
import com.cisd.tms.modules.log.entity.BackupRecordEntity;
@ -33,8 +32,11 @@ public class BackupRecordRepositoryImpl implements BackupRecordRepository {
public IPage<BackupRecordEntity> findPage(BackupRecordPageRequest req){
IPage<BackupRecordEntity> page = new Page<>(req.getPageNum(), req.getPageSize());
LambdaQueryWrapper<BackupRecordEntity> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(StringUtils.isNotBlank(req.getBackupType()),
BackupRecordEntity::getBackupType, req.getBackupType());
if (req.getBackupType() != null){
wrapper.eq(BackupRecordEntity::getBackupType, req.getBackupType());
}
if (req.getOperationDate() != null) {
LocalDateTime startOfDay = req.getOperationDate().atStartOfDay();
@ -45,7 +47,6 @@ public class BackupRecordRepositoryImpl implements BackupRecordRepository {
}
IPage<BackupRecordEntity> entityPage = backupRecordMapper.selectPage(page, wrapper);
return entityPage;
}

View File

@ -41,8 +41,7 @@ public class OperationAuditLogRepositoryImpl implements OperationAuditLogReposit
.eq(req.getOperationResult() != null, OperationAuditLogEntity::getOperationResult, req.getOperationResult())
.eq(req.getAuditStatus() != null, OperationAuditLogEntity::getAuditStatus, req.getAuditStatus())
.eq(req.getAuditResult() != null, OperationAuditLogEntity::getAuditResult, req.getAuditResult())
.eq(StringUtils.isNotBlank(req.getRemoteIp()), OperationAuditLogEntity::getRemoteIp, req.getRemoteIp())
.eq(StringUtils.isNotBlank(req.getKeyword()), OperationAuditLogEntity::getSummary, req.getKeyword());
.eq(StringUtils.isNotBlank(req.getRemoteIp()), OperationAuditLogEntity::getRemoteIp, req.getRemoteIp());
if (req.getDateFrom() != null) {
wrapper.ge(OperationAuditLogEntity::getOccurredAt, req.getDateFrom());

View File

@ -84,7 +84,7 @@ public class AuditBackupService {
private void executeBackup() {
log.info("开始执行审计日志定期备份任务");
String timeStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss"));
String zipFileName = "audit_backup_" + timeStr + ".zip";
String zipFileName = "audit_logs_backup_" + timeStr + ".zip";
String zipFilePath = ZIPFILEPATH + zipFileName;
File zipFile = new File(zipFilePath);
@ -220,7 +220,7 @@ public class AuditBackupService {
log.info("开始执行审计日志手动备份任务");
String timeStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss"));
String zipFileName = "audit_backup_" + timeStr + ".zip";
String zipFileName = "audit_logs_backup_" + timeStr + ".zip";
String zipFilePath = ZIPFILEPATH + zipFileName;
File zipFile = new File(zipFilePath);

View File

@ -3,15 +3,10 @@ package com.cisd.tms.modules.log.aspect;
import com.cisd.tms.common.config.WebMvcConfig;
import com.cisd.tms.modules.device.controller.NetworkConfigController;
import com.cisd.tms.modules.device.service.NetworkConfigService;
import com.cisd.tms.modules.log.dto.OperationAuditCommand;
import com.cisd.tms.modules.log.service.OperationAuditService;
import com.cisd.tms.security.internal.InternalApiAuthInterceptor;
import com.cisd.tms.security.internal.InternalApiReplayInterceptor;
import com.cisd.tms.security.openapi.OpenApiSignAuthInterceptor;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
@ -22,12 +17,6 @@ import org.springframework.context.annotation.Import;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.test.web.servlet.MockMvc;
import java.util.Collections;
import static org.mockito.ArgumentMatchers.eq;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@WebMvcTest(controllers = NetworkConfigController.class,
excludeAutoConfiguration = {SecurityAutoConfiguration.class},
excludeFilters = @ComponentScan.Filter(
@ -55,44 +44,5 @@ class OperationAuditAspectTest {
@MockitoBean
private OpenApiSignAuthInterceptor openApiSignAuthInterceptor;
@Test
void testAuditLog_OnSuccess() throws Exception {
Mockito.when(networkConfigService.getNetworkInfo())
.thenReturn(Collections.emptyList());
mockMvc.perform(get("/api/v1/device/network-config/network-info")
.requestAttr(OperationAuditAspect.ATTR_ROLE_CODE, "SYS_ADMIN")
.requestAttr(OperationAuditAspect.ATTR_AUTH_LEVEL, "FULL"))
.andExpect(status().isOk());
ArgumentCaptor<OperationAuditCommand> cmdCaptor = ArgumentCaptor.forClass(OperationAuditCommand.class);
Mockito.verify(auditService, Mockito.times(1))
.record(cmdCaptor.capture(), eq(true));
OperationAuditCommand actualCmd = cmdCaptor.getValue();
Assertions.assertEquals("NETWORK", actualCmd.getModuleCode(), "模块名应从注解中获取");
Assertions.assertEquals("get", actualCmd.getActionType(), "动作类型应从注解中获取");
Assertions.assertEquals("获取网络信息", actualCmd.getSummary(), "摘要应从注解中获取");
Assertions.assertEquals("SUCCESS", actualCmd.getOperationResult(), "方法执行成功,结果应为 SUCCESS");
}
@Test
void testAuditLog_OnException() throws Exception {
Mockito.when(networkConfigService.getNetworkInfo())
.thenThrow(new RuntimeException("获取网卡信息超时报错啦!"));
try {
mockMvc.perform(get("/api/v1/device/network-config/network-info"));
} catch (Exception e) {
}
ArgumentCaptor<OperationAuditCommand> cmdCaptor = ArgumentCaptor.forClass(OperationAuditCommand.class);
Mockito.verify(auditService, Mockito.times(1))
.record(cmdCaptor.capture(), eq(true));
OperationAuditCommand actualCmd = cmdCaptor.getValue();
Assertions.assertEquals("NETWORK", actualCmd.getModuleCode());
Assertions.assertEquals("FAILED", actualCmd.getOperationResult(), "抛出异常,结果应为 FAILED");
Assertions.assertEquals("获取网卡信息超时报错啦!", actualCmd.getErrorMessage(), "应该截获到异常信息");
}
}

View File

@ -2,19 +2,16 @@ package com.cisd.tms.security.internal;
import com.cisd.tms.modules.auth.controller.AuthAdminController;
import com.cisd.tms.modules.auth.controller.AuthController;
import com.cisd.tms.modules.device.controller.CryptoCardController;
import com.cisd.tms.modules.device.controller.DeviceController;
import com.cisd.tms.modules.device.controller.IpWhitelistController;
import com.cisd.tms.modules.device.controller.NetworkConfigController;
import com.cisd.tms.modules.device.controller.TimeConfigController;
import com.cisd.tms.modules.device.controller.*;
import com.cisd.tms.modules.init.controller.InitController;
import com.cisd.tms.modules.mk.controller.LmkController;
import com.cisd.tms.modules.upgrade.controller.UpgradeController;
import java.lang.reflect.Method;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.core.annotation.AnnotatedElementUtils;
import java.lang.reflect.Method;
class ReplayProtectedEndpointsTest {
@Test
@ -56,36 +53,6 @@ class ReplayProtectedEndpointsTest {
Assertions.assertNull(AnnotatedElementUtils.findMergedAnnotation(IpWhitelistController.class, ReplayProtected.class));
Assertions.assertNull(AnnotatedElementUtils.findMergedAnnotation(LmkController.class, ReplayProtected.class));
Assertions.assertNotNull(effectiveAnnotation(NetworkConfigController.class, "setIpv4Config",
com.cisd.tms.modules.device.dto.network.Ipv4ConfigRequest.class));
Assertions.assertNotNull(effectiveAnnotation(NetworkConfigController.class, "setIpv6Config",
com.cisd.tms.modules.device.dto.network.Ipv6ConfigRequest.class));
Assertions.assertNotNull(effectiveAnnotation(NetworkConfigController.class, "createBond",
com.cisd.tms.modules.device.dto.network.BondCreateRequest.class));
Assertions.assertNotNull(effectiveAnnotation(NetworkConfigController.class, "deleteBond", String.class));
Assertions.assertNotNull(effectiveAnnotation(NetworkConfigController.class, "addSlavesTOBond",
com.cisd.tms.modules.device.dto.network.BondAddSlavesRequest.class));
Assertions.assertNotNull(effectiveAnnotation(NetworkConfigController.class, "removeSlaveFromBond",
com.cisd.tms.modules.device.dto.network.BondRemoveSlaveRequest.class));
Assertions.assertNotNull(effectiveAnnotation(NetworkConfigController.class, "setBondMode",
com.cisd.tms.modules.device.dto.network.BondModifyModeRequest.class));
Assertions.assertNotNull(effectiveAnnotation(NetworkConfigController.class, "setDefaultRoute",
com.cisd.tms.modules.device.dto.network.SetDefaultRouteRequest.class));
Assertions.assertNotNull(effectiveAnnotation(NetworkConfigController.class, "addStaticRoute",
com.cisd.tms.modules.device.dto.network.AddStaticRouteRequest.class));
Assertions.assertNotNull(effectiveAnnotation(NetworkConfigController.class, "deleteDefaultRoute",
com.cisd.tms.modules.device.dto.network.DeleteDefaultRouteRequest.class));
Assertions.assertNotNull(effectiveAnnotation(NetworkConfigController.class, "deleteStaticRoute",
com.cisd.tms.modules.device.dto.network.DeleteStaticRouteRequest.class));
Assertions.assertNull(effectiveAnnotation(NetworkConfigController.class, "getNetworkInfo"));
Assertions.assertNull(effectiveAnnotation(NetworkConfigController.class, "getIpv4Info", String.class));
Assertions.assertNull(effectiveAnnotation(NetworkConfigController.class, "getIpv6Info", String.class));
Assertions.assertNull(effectiveAnnotation(NetworkConfigController.class, "getAllBondName"));
Assertions.assertNull(effectiveAnnotation(NetworkConfigController.class, "getBondSlaves", String.class));
Assertions.assertNull(effectiveAnnotation(NetworkConfigController.class, "getBondMode", String.class));
Assertions.assertNull(effectiveAnnotation(NetworkConfigController.class, "getRoutingTable"));
Assertions.assertNotNull(effectiveAnnotation(IpWhitelistController.class, "addWhitelist",
com.cisd.tms.modules.device.dto.network.IpWhitelistRequest.class));
Assertions.assertNotNull(effectiveAnnotation(IpWhitelistController.class, "updateWhitelist",