mirror of
https://github.com/Jerryplusy/AI-powered-switches.git
synced 2025-10-14 01:39:18 +00:00
Compare commits
3 Commits
16eb9cf6db
...
0b6b9624a6
Author | SHA1 | Date | |
---|---|---|---|
0b6b9624a6 | |||
0f8e7fe4d6 | |||
bccdde74ad |
@ -82,7 +82,7 @@ async def test_endpoint():
|
||||
@router.get("/scan_network", summary="扫描网络中的交换机")
|
||||
async def scan_network(subnet: str = "192.168.1.0/24"):
|
||||
try:
|
||||
devices = scanner.scan_subnet(subnet)
|
||||
devices = await scanner.scan_subnet(subnet)
|
||||
return {
|
||||
"success": True,
|
||||
"devices": devices,
|
||||
@ -94,7 +94,7 @@ async def scan_network(subnet: str = "192.168.1.0/24"):
|
||||
@router.get("/list_devices", summary="列出已发现的交换机")
|
||||
async def list_devices():
|
||||
return {
|
||||
"devices": scanner.load_cached_devices()
|
||||
"devices": await scanner.load_cached_devices()
|
||||
}
|
||||
|
||||
class CommandRequest(BaseModel):
|
||||
@ -125,7 +125,7 @@ async def parse_command(request: CommandRequest):
|
||||
@router.post("/apply_config", response_model=dict)
|
||||
async def apply_config(request: ConfigRequest):
|
||||
"""
|
||||
应用配置到交换机
|
||||
应用配置到交换机(弃用)
|
||||
"""
|
||||
try:
|
||||
configurator = SwitchConfigurator(
|
||||
|
@ -110,6 +110,9 @@ class SwitchConfigurator:
|
||||
|
||||
output = ""
|
||||
for cmd in commands:
|
||||
if cmd.startswith("!"):
|
||||
logger.debug(f"跳过特殊命令: {cmd}")
|
||||
continue
|
||||
logger.info(f"发送命令: {cmd}")
|
||||
writer.write(f"{cmd}\n")
|
||||
await writer.drain()
|
||||
|
@ -42,7 +42,7 @@ class AIService:
|
||||
]
|
||||
|
||||
try:
|
||||
response = self.client.chat.completions.create(
|
||||
response = await self.client.chat.completions.create(
|
||||
model="deepseek-ai/DeepSeek-V3",
|
||||
messages=messages,
|
||||
temperature=0.3,
|
||||
|
@ -9,7 +9,7 @@ class NetworkScanner:
|
||||
self.cache_path = Path(cache_path)
|
||||
self.nm = nmap.PortScanner()
|
||||
|
||||
def scan_subnet(self, subnet: str = "192.168.1.0/24", ports: List[int] = [22, 23, 80]) -> List[Dict]:
|
||||
async def scan_subnet(self, subnet: str = "192.168.1.0/24", ports: List[int] = [22, 23, 80]) -> List[Dict]:
|
||||
"""扫描指定子网的设备,获取设备信息和开放端口"""
|
||||
logger.info(f"Scanning subnet: {subnet}")
|
||||
|
||||
@ -33,16 +33,16 @@ class NetworkScanner:
|
||||
except Exception as e:
|
||||
logger.error(f"Error while scanning subnet: {e}")
|
||||
|
||||
self._save_to_cache(devices)
|
||||
await self._save_to_cache(devices)
|
||||
return devices
|
||||
|
||||
def _save_to_cache(self, devices: List[Dict]):
|
||||
async def _save_to_cache(self, devices: List[Dict]):
|
||||
"""保存扫描结果到本地文件"""
|
||||
with open(self.cache_path, "w") as f:
|
||||
json.dump(devices, f, indent=2)
|
||||
logger.info(f"Saved {len(devices)} devices to cache")
|
||||
|
||||
def load_cached_devices(self) -> List[Dict]:
|
||||
async def load_cached_devices(self) -> List[Dict]:
|
||||
"""从缓存加载设备列表"""
|
||||
if not self.cache_path.exists():
|
||||
return []
|
||||
|
@ -21,6 +21,7 @@
|
||||
"@nestjs/platform-express": "^11.0.1",
|
||||
"@nestjs/swagger": "^11.2.0",
|
||||
"axios": "^1.10.0",
|
||||
"ip": "^2.0.1",
|
||||
"reflect-metadata": "^0.2.2",
|
||||
"rxjs": "^7.8.1",
|
||||
"ssh2": "^1.16.0"
|
||||
@ -34,6 +35,7 @@
|
||||
"@swc/cli": "^0.6.0",
|
||||
"@swc/core": "^1.10.7",
|
||||
"@types/express": "^5.0.0",
|
||||
"@types/ip": "^1.1.3",
|
||||
"@types/jest": "^29.5.14",
|
||||
"@types/node": "^22.16.4",
|
||||
"@types/supertest": "^6.0.2",
|
||||
|
8448
src/nest-backend/pnpm-lock.yaml
generated
8448
src/nest-backend/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,13 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
|
||||
import { RootModule } from './root/root.module';
|
||||
import { HttpMiddleware } from './common/middleware/http.middleware';
|
||||
import { NetworkModule } from './modules/network/network.module';
|
||||
|
||||
@Module({
|
||||
imports: [RootModule],
|
||||
imports: [RootModule, NetworkModule],
|
||||
})
|
||||
export class AppModule {}
|
||||
export class AppModule implements NestModule {
|
||||
configure(consumer: MiddlewareConsumer): any {
|
||||
consumer.apply(HttpMiddleware).forRoutes('api');
|
||||
}
|
||||
}
|
||||
|
@ -1,28 +0,0 @@
|
||||
import {
|
||||
ArgumentsHost,
|
||||
Catch,
|
||||
ExceptionFilter,
|
||||
HttpException,
|
||||
HttpStatus,
|
||||
} from '@nestjs/common';
|
||||
|
||||
@Catch()
|
||||
export class AllExceptionsFilter implements ExceptionFilter {
|
||||
catch(exception: unknown, host: ArgumentsHost) {
|
||||
const ctx = host.switchToHttp();
|
||||
const response = ctx.getResponse();
|
||||
const status =
|
||||
exception instanceof HttpException
|
||||
? exception.getStatus()
|
||||
: HttpStatus.INTERNAL_SERVER_ERROR;
|
||||
|
||||
const message =
|
||||
exception instanceof HttpException ? exception.message : '服务器内部错误';
|
||||
|
||||
response.status(status).json({
|
||||
success: false,
|
||||
data: null,
|
||||
message,
|
||||
});
|
||||
}
|
||||
}
|
@ -19,7 +19,6 @@ export class ResponseInterceptor<T>
|
||||
map((data) => ({
|
||||
success: true,
|
||||
data,
|
||||
message: '操作成功',
|
||||
})),
|
||||
);
|
||||
}
|
||||
|
25
src/nest-backend/src/common/middleware/http.middleware.ts
Normal file
25
src/nest-backend/src/common/middleware/http.middleware.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { Injectable, Logger, NestMiddleware } from '@nestjs/common';
|
||||
import { Request, Response, NextFunction } from 'express';
|
||||
|
||||
@Injectable()
|
||||
export class HttpMiddleware implements NestMiddleware {
|
||||
private readonly logger = new Logger('HTTP');
|
||||
|
||||
use(req: Request, res: Response, next: NextFunction): void {
|
||||
const { method, originalUrl } = req;
|
||||
this.logger.log(`HTTP request for ${method} ${originalUrl}`);
|
||||
const startTime = Date.now();
|
||||
|
||||
res.on('finish', () => {
|
||||
const statusCode = res.statusCode;
|
||||
const contentLength = res.get('content-length') || 0;
|
||||
const duration = Date.now() - startTime;
|
||||
|
||||
this.logger.log(
|
||||
`${method} ${originalUrl} ${statusCode} ${contentLength}B - ${duration}ms`,
|
||||
);
|
||||
});
|
||||
|
||||
next();
|
||||
}
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
export interface ApiResponse<T = any> {
|
||||
success: boolean;
|
||||
data: T;
|
||||
message: string;
|
||||
}
|
||||
|
@ -3,13 +3,11 @@ import { AppModule } from './app.module';
|
||||
import { Logger } from '@nestjs/common';
|
||||
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
|
||||
import { ResponseInterceptor } from './common/interceptors/response.interceptor';
|
||||
import { AllExceptionsFilter } from './common/filters/all-exception.filter';
|
||||
|
||||
async function bootstrap() {
|
||||
const app = await NestFactory.create(AppModule);
|
||||
app.setGlobalPrefix('api');
|
||||
app.useGlobalInterceptors(new ResponseInterceptor());
|
||||
app.useGlobalFilters(new AllExceptionsFilter());
|
||||
const config = new DocumentBuilder()
|
||||
.setTitle('交换机API平台')
|
||||
.setDescription('自动化交换机配置和流量监控接口')
|
||||
|
18
src/nest-backend/src/modules/network/network.controller.ts
Normal file
18
src/nest-backend/src/modules/network/network.controller.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import { Controller, Get, Inject } from '@nestjs/common';
|
||||
import { NetworkService } from './network.service';
|
||||
import { ApiTags, ApiOperation } from '@nestjs/swagger';
|
||||
|
||||
@ApiTags('Network')
|
||||
@Controller('network')
|
||||
export class NetworkController {
|
||||
constructor(
|
||||
@Inject(NetworkService)
|
||||
private readonly networkService: NetworkService,
|
||||
) {}
|
||||
|
||||
@Get('adapters')
|
||||
@ApiOperation({ summary: '获取网络适配器网段' })
|
||||
async getNetworkAdapters() {
|
||||
return this.networkService.getNetworkAdapters();
|
||||
}
|
||||
}
|
10
src/nest-backend/src/modules/network/network.module.ts
Normal file
10
src/nest-backend/src/modules/network/network.module.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { NetworkService } from './network.service';
|
||||
import { NetworkController } from './network.controller';
|
||||
|
||||
@Module({
|
||||
controllers: [NetworkController],
|
||||
providers: [NetworkService],
|
||||
exports: [NetworkService],
|
||||
})
|
||||
export class NetworkModule {}
|
44
src/nest-backend/src/modules/network/network.service.ts
Normal file
44
src/nest-backend/src/modules/network/network.service.ts
Normal file
@ -0,0 +1,44 @@
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import os from 'os';
|
||||
import ip from 'ip';
|
||||
|
||||
@Injectable()
|
||||
export class NetworkService {
|
||||
private readonly logger = new Logger(NetworkService.name);
|
||||
|
||||
/**
|
||||
* 获取网络适配器信息及网段
|
||||
*/
|
||||
async getNetworkAdapters(): Promise<any> {
|
||||
try {
|
||||
this.logger.log('Getting network adapters');
|
||||
const interfaces = os.networkInterfaces();
|
||||
const networks: any[] = [];
|
||||
|
||||
for (const [adapter, addrs] of Object.entries(interfaces)) {
|
||||
if (!addrs) continue;
|
||||
|
||||
for (const addr of addrs) {
|
||||
if (addr.family === 'IPv4' && !addr.internal) {
|
||||
const ipAddress = addr.address;
|
||||
const subnetMask = addr.netmask;
|
||||
const cidr = ip.subnet(ipAddress, subnetMask);
|
||||
const networkCidr = `${cidr.networkAddress}/${cidr.subnetMaskLength}`;
|
||||
|
||||
networks.push({
|
||||
adapter,
|
||||
network: networkCidr,
|
||||
ip: ipAddress,
|
||||
subnet_mask: subnetMask,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { networks };
|
||||
} catch (error) {
|
||||
this.logger.error('获取网络适配器信息失败', error);
|
||||
return { error: `获取网络适配器信息失败: ${error.message}` };
|
||||
}
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@ import { Controller, Get } from '@nestjs/common';
|
||||
@Controller()
|
||||
export class RootController {
|
||||
@Get()
|
||||
getWelcome() {
|
||||
async getWelcome() {
|
||||
return {
|
||||
message: '欢迎使用交换机管理平台 API',
|
||||
};
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
|
||||
import { RootController } from './root.controller';
|
||||
import { HttpMiddleware } from '../common/middleware/http.middleware';
|
||||
|
||||
@Module({
|
||||
controllers: [RootController],
|
||||
|
Loading…
x
Reference in New Issue
Block a user