网络配置
This commit is contained in:
parent
e125063e0f
commit
68083d86c0
6
pom.xml
6
pom.xml
@ -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>
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
@ -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-32,IPv6 范围 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;
|
||||
}
|
||||
@ -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-32,IPv6范围0-128",
|
||||
example = "24",
|
||||
requiredMode = Schema.RequiredMode.REQUIRED
|
||||
)
|
||||
@NotNull(message = "前缀长度不能为空")
|
||||
private Integer prefixLength;
|
||||
|
||||
/**
|
||||
* 网关地址,可为空
|
||||
*/
|
||||
@Schema(
|
||||
description = "网关地址,可为空",
|
||||
example = "192.168.10.1"
|
||||
)
|
||||
private String gateway;
|
||||
|
||||
/**
|
||||
* 选择的物理网卡,例如 eth0、eth1
|
||||
*/
|
||||
@Schema(
|
||||
description = "选择加入Bond的物理网卡列表",
|
||||
example = "[\"eth0\", \"eth1\"]",
|
||||
requiredMode = Schema.RequiredMode.REQUIRED
|
||||
)
|
||||
@NotEmpty(message = "请选择至少一个物理网卡")
|
||||
private List<String> slaveList;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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-32,IPv6范围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;
|
||||
}
|
||||
@ -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-32,IPv6范围0-128",
|
||||
example = "24",
|
||||
requiredMode = Schema.RequiredMode.REQUIRED
|
||||
)
|
||||
@NotNull(message = "前缀长度不能为空")
|
||||
private Integer prefixLength;
|
||||
}
|
||||
@ -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;
|
||||
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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 {
|
||||
|
||||
/**
|
||||
* 网卡名,如 eth0、eth1
|
||||
*/
|
||||
@Schema(description = "网卡名称", example = "eth0")
|
||||
private String deviceName;
|
||||
|
||||
/**
|
||||
* 地址类型,如 IPV4、IPV6、-
|
||||
*/
|
||||
@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;
|
||||
|
||||
/**
|
||||
* 前缀长度,如 24、64
|
||||
*/
|
||||
@Schema(description = "前缀长度", example = "24")
|
||||
private String prefixLength;
|
||||
|
||||
/**
|
||||
* 网关,如 172.16.18.254
|
||||
*/
|
||||
@Schema(description = "网关地址", example = "172.16.18.254")
|
||||
private String gateway;
|
||||
|
||||
/**
|
||||
* 状态,如 Active、Inactive
|
||||
*/
|
||||
@Schema(
|
||||
description = "网卡状态:Active=激活,Inactive=未激活",
|
||||
example = "Active",
|
||||
allowableValues = {"Active", "Inactive"}
|
||||
)
|
||||
private String status;
|
||||
}
|
||||
@ -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时填写主机IP,NETWORK时填写网段地址",
|
||||
example = "192.168.10.0",
|
||||
requiredMode = Schema.RequiredMode.REQUIRED
|
||||
)
|
||||
@NotBlank(message = "目标地址不能为空")
|
||||
private String targetAddress;
|
||||
|
||||
/**
|
||||
* 前缀长度:
|
||||
* HOST 一般为 32
|
||||
* NETWORK 例如 24、64
|
||||
*/
|
||||
@Schema(
|
||||
description = "前缀长度。IPv4主机路由一般为32,IPv6主机路由一般为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;
|
||||
}
|
||||
@ -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时填写主机IP,NETWORK时填写网段地址",
|
||||
example = "192.168.10.0",
|
||||
requiredMode = Schema.RequiredMode.REQUIRED
|
||||
)
|
||||
@NotBlank(message = "目标地址不能为空")
|
||||
private String targetAddress;
|
||||
|
||||
@Schema(
|
||||
description = "前缀长度。IPv4主机路由一般为32,IPv6主机路由一般为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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -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");
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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());
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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(), "应该截获到异常信息");
|
||||
}
|
||||
}
|
||||
@ -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",
|
||||
|
||||
Loading…
Reference in New Issue
Block a user