660 lines
19 KiB
Markdown
660 lines
19 KiB
Markdown
# Design Document: AMT Hardware Information Query
|
||
|
||
## Overview
|
||
|
||
本设计文档描述了如何实现通过 Intel AMT 技术远程查询设备硬件配置信息的功能。系统将使用 Intel AMT SDK 的 WS-Management 接口查询 CIM (Common Information Model) 类,获取 CPU、内存、存储设备等硬件信息,并通过 RESTful API 提供给前端展示。
|
||
|
||
## Architecture
|
||
|
||
### System Architecture
|
||
|
||
```
|
||
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
|
||
│ │ │ │ │ │
|
||
│ Vue Frontend │◄───────►│ C# Backend │◄───────►│ AMT Device │
|
||
│ │ HTTP │ (ASP.NET Core) │ WSMAN │ (CIM Classes) │
|
||
│ │ │ │ │ │
|
||
└─────────────────┘ └──────────────────┘ └─────────────────┘
|
||
│
|
||
▼
|
||
┌──────────────────┐
|
||
│ │
|
||
│ MySQL Database │
|
||
│ (Cache) │
|
||
│ │
|
||
└──────────────────┘
|
||
```
|
||
|
||
### Component Diagram
|
||
|
||
```
|
||
Backend Components:
|
||
┌────────────────────────────────────────────────────────────┐
|
||
│ │
|
||
│ ┌──────────────────┐ │
|
||
│ │ HardwareInfo │ │
|
||
│ │ Controller │ │
|
||
│ └────────┬─────────┘ │
|
||
│ │ │
|
||
│ ▼ │
|
||
│ ┌──────────────────┐ ┌──────────────────┐ │
|
||
│ │ HardwareInfo │────────►│ AMT Connection │ │
|
||
│ │ Service │ │ Service │ │
|
||
│ └────────┬─────────┘ └──────────────────┘ │
|
||
│ │ │
|
||
│ ▼ │
|
||
│ ┌──────────────────┐ │
|
||
│ │ Hardware Info │ │
|
||
│ │ Repository │ │
|
||
│ └──────────────────┘ │
|
||
│ │
|
||
└────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
## Components and Interfaces
|
||
|
||
### 1. Backend Components
|
||
|
||
#### 1.1 HardwareInfoController
|
||
|
||
**Responsibility**: 处理硬件信息查询的 HTTP 请求
|
||
|
||
**Endpoints**:
|
||
```csharp
|
||
// 查询单个设备的硬件信息
|
||
GET /api/hardware-info/{deviceId}
|
||
Query Parameters:
|
||
- refresh: bool (是否强制刷新,默认 false)
|
||
|
||
Response:
|
||
{
|
||
"deviceId": 1,
|
||
"ipAddress": "192.168.8.111",
|
||
"lastUpdated": "2024-01-19T10:30:00Z",
|
||
"systemInfo": {
|
||
"manufacturer": "Dell Inc.",
|
||
"model": "OptiPlex 7090",
|
||
"serialNumber": "ABC123456"
|
||
},
|
||
"processor": {
|
||
"model": "Intel Core i7-10700",
|
||
"cores": 8,
|
||
"threads": 16,
|
||
"maxClockSpeed": 2900,
|
||
"currentClockSpeed": 2900
|
||
},
|
||
"memory": {
|
||
"totalCapacity": 17179869184, // bytes
|
||
"totalCapacityGB": 16,
|
||
"modules": [
|
||
{
|
||
"slot": "DIMM_A1",
|
||
"capacity": 8589934592,
|
||
"capacityGB": 8,
|
||
"speed": 2933,
|
||
"type": "DDR4",
|
||
"manufacturer": "Samsung",
|
||
"partNumber": "M378A1K43CB2-CVF"
|
||
},
|
||
{
|
||
"slot": "DIMM_A2",
|
||
"capacity": 8589934592,
|
||
"capacityGB": 8,
|
||
"speed": 2933,
|
||
"type": "DDR4",
|
||
"manufacturer": "Samsung",
|
||
"partNumber": "M378A1K43CB2-CVF"
|
||
}
|
||
]
|
||
},
|
||
"storage": {
|
||
"devices": [
|
||
{
|
||
"deviceId": "0",
|
||
"model": "Samsung SSD 970 EVO Plus 500GB",
|
||
"capacity": 500107862016,
|
||
"capacityGB": 465,
|
||
"interfaceType": "NVMe"
|
||
}
|
||
]
|
||
}
|
||
}
|
||
|
||
// 批量查询多个设备的硬件信息
|
||
POST /api/hardware-info/batch
|
||
Request Body:
|
||
{
|
||
"deviceIds": [1, 2, 3],
|
||
"refresh": false
|
||
}
|
||
|
||
Response:
|
||
{
|
||
"results": [
|
||
{
|
||
"deviceId": 1,
|
||
"success": true,
|
||
"data": { /* hardware info */ }
|
||
},
|
||
{
|
||
"deviceId": 2,
|
||
"success": false,
|
||
"error": "Connection timeout"
|
||
}
|
||
]
|
||
}
|
||
|
||
// 导出硬件信息为 CSV
|
||
GET /api/hardware-info/export
|
||
Query Parameters:
|
||
- deviceIds: string (逗号分隔的设备 ID)
|
||
- format: string (csv 或 json)
|
||
|
||
Response: File download
|
||
```
|
||
|
||
#### 1.2 HardwareInfoService
|
||
|
||
**Responsibility**: 业务逻辑层,协调硬件信息查询和缓存
|
||
|
||
**Methods**:
|
||
```csharp
|
||
public interface IHardwareInfoService
|
||
{
|
||
Task<HardwareInfo> GetHardwareInfoAsync(int deviceId, bool forceRefresh = false);
|
||
Task<List<BatchHardwareInfoResult>> GetBatchHardwareInfoAsync(List<int> deviceIds, bool forceRefresh = false);
|
||
Task<HardwareInfo> QueryHardwareInfoFromDeviceAsync(string ipAddress, string username, string password);
|
||
Task<byte[]> ExportHardwareInfoAsync(List<int> deviceIds, ExportFormat format);
|
||
}
|
||
```
|
||
|
||
**Implementation Details**:
|
||
- 检查缓存是否存在且未过期(24小时)
|
||
- 如果缓存有效且不强制刷新,返回缓存数据
|
||
- 否则,调用 AMT 设备查询硬件信息
|
||
- 将查询结果保存到数据库
|
||
- 处理查询失败的情况,返回部分可用信息
|
||
|
||
#### 1.3 AmtHardwareQueryService
|
||
|
||
**Responsibility**: 使用 Intel AMT SDK 查询硬件信息
|
||
|
||
**Methods**:
|
||
```csharp
|
||
public interface IAmtHardwareQueryService
|
||
{
|
||
Task<SystemInfo> QuerySystemInfoAsync(IWsmanConnection connection);
|
||
Task<ProcessorInfo> QueryProcessorInfoAsync(IWsmanConnection connection);
|
||
Task<MemoryInfo> QueryMemoryInfoAsync(IWsmanConnection connection);
|
||
Task<StorageInfo> QueryStorageInfoAsync(IWsmanConnection connection);
|
||
}
|
||
```
|
||
|
||
**CIM Query Details**:
|
||
|
||
1. **System Information** (CIM_ComputerSystem):
|
||
```csharp
|
||
var query = connection.ExecQuery("SELECT * FROM CIM_ComputerSystem WHERE Name='ManagedSystem'");
|
||
foreach (IWsmanItem item in query)
|
||
{
|
||
var manufacturer = item.Object.GetProperty("Manufacturer").ToString();
|
||
var model = item.Object.GetProperty("Model").ToString();
|
||
// ...
|
||
}
|
||
```
|
||
|
||
2. **Processor Information** (CIM_Processor via CIM_Realizes):
|
||
```csharp
|
||
var query = connection.ExecQuery("SELECT * FROM CIM_Realizes");
|
||
foreach (IWsmanItem item in query)
|
||
{
|
||
if (item.Object.GetProperty("Dependent").IsA("CIM_Processor"))
|
||
{
|
||
var cpuObj = item.Object.GetProperty("Dependent").Ref.Get();
|
||
var family = cpuObj.GetProperty("Family").ToString();
|
||
var maxClockSpeed = cpuObj.GetProperty("MaxClockSpeed").ToString();
|
||
var currentClockSpeed = cpuObj.GetProperty("CurrentClockSpeed").ToString();
|
||
// ...
|
||
}
|
||
}
|
||
```
|
||
|
||
3. **Memory Information** (CIM_PhysicalMemory):
|
||
```csharp
|
||
var query = connection.ExecQuery("SELECT * FROM CIM_PhysicalMemory");
|
||
foreach (IWsmanItem item in query)
|
||
{
|
||
var tag = item.Object.GetProperty("Tag").ToString();
|
||
var bankLabel = item.Object.GetProperty("BankLabel").ToString();
|
||
var capacity = item.Object.GetProperty("Capacity").ToString();
|
||
var speed = item.Object.GetProperty("Speed").ToString();
|
||
var memoryType = item.Object.GetProperty("MemoryType").ToString();
|
||
var manufacturer = item.Object.GetProperty("Manufacturer").ToString();
|
||
var partNumber = item.Object.GetProperty("PartNumber").ToString();
|
||
// ...
|
||
}
|
||
```
|
||
|
||
4. **Storage Information** (CIM_MediaAccessDevice):
|
||
```csharp
|
||
var query = connection.ExecQuery("SELECT * FROM CIM_MediaAccessDevice");
|
||
foreach (IWsmanItem item in query)
|
||
{
|
||
var deviceId = item.Object.GetProperty("DeviceID").ToString();
|
||
var caption = item.Object.GetProperty("Caption").ToString();
|
||
var capacity = item.Object.GetProperty("MaxMediaSize").ToString();
|
||
// ...
|
||
}
|
||
```
|
||
|
||
#### 1.4 HardwareInfoRepository
|
||
|
||
**Responsibility**: 数据访问层,管理硬件信息的持久化
|
||
|
||
**Methods**:
|
||
```csharp
|
||
public interface IHardwareInfoRepository
|
||
{
|
||
Task<HardwareInfo?> GetByDeviceIdAsync(int deviceId);
|
||
Task SaveAsync(HardwareInfo hardwareInfo);
|
||
Task<List<HardwareInfo>> GetByDeviceIdsAsync(List<int> deviceIds);
|
||
Task DeleteByDeviceIdAsync(int deviceId);
|
||
}
|
||
```
|
||
|
||
### 2. Data Models
|
||
|
||
#### 2.1 Database Schema
|
||
|
||
```sql
|
||
-- 硬件信息主表
|
||
CREATE TABLE HardwareInfo (
|
||
Id INT PRIMARY KEY AUTO_INCREMENT,
|
||
DeviceId INT NOT NULL,
|
||
LastUpdated DATETIME NOT NULL,
|
||
SystemManufacturer VARCHAR(200),
|
||
SystemModel VARCHAR(200),
|
||
SystemSerialNumber VARCHAR(200),
|
||
ProcessorModel VARCHAR(500),
|
||
ProcessorCores INT,
|
||
ProcessorThreads INT,
|
||
ProcessorMaxClockSpeed INT,
|
||
ProcessorCurrentClockSpeed INT,
|
||
TotalMemoryBytes BIGINT,
|
||
CreatedAt DATETIME NOT NULL,
|
||
UpdatedAt DATETIME NOT NULL,
|
||
FOREIGN KEY (DeviceId) REFERENCES AmtDevices(Id) ON DELETE CASCADE,
|
||
INDEX idx_device_id (DeviceId),
|
||
INDEX idx_last_updated (LastUpdated)
|
||
);
|
||
|
||
-- 内存模块表
|
||
CREATE TABLE MemoryModules (
|
||
Id INT PRIMARY KEY AUTO_INCREMENT,
|
||
HardwareInfoId INT NOT NULL,
|
||
SlotLocation VARCHAR(100),
|
||
CapacityBytes BIGINT,
|
||
SpeedMHz INT,
|
||
MemoryType VARCHAR(50),
|
||
Manufacturer VARCHAR(200),
|
||
PartNumber VARCHAR(200),
|
||
SerialNumber VARCHAR(200),
|
||
FOREIGN KEY (HardwareInfoId) REFERENCES HardwareInfo(Id) ON DELETE CASCADE
|
||
);
|
||
|
||
-- 存储设备表
|
||
CREATE TABLE StorageDevices (
|
||
Id INT PRIMARY KEY AUTO_INCREMENT,
|
||
HardwareInfoId INT NOT NULL,
|
||
DeviceId VARCHAR(100),
|
||
Model VARCHAR(500),
|
||
CapacityBytes BIGINT,
|
||
InterfaceType VARCHAR(50),
|
||
FOREIGN KEY (HardwareInfoId) REFERENCES HardwareInfo(Id) ON DELETE CASCADE
|
||
);
|
||
```
|
||
|
||
#### 2.2 C# Models
|
||
|
||
```csharp
|
||
public class HardwareInfo
|
||
{
|
||
public int Id { get; set; }
|
||
public int DeviceId { get; set; }
|
||
public DateTime LastUpdated { get; set; }
|
||
|
||
public SystemInfo SystemInfo { get; set; }
|
||
public ProcessorInfo Processor { get; set; }
|
||
public MemoryInfo Memory { get; set; }
|
||
public StorageInfo Storage { get; set; }
|
||
|
||
public DateTime CreatedAt { get; set; }
|
||
public DateTime UpdatedAt { get; set; }
|
||
|
||
// Navigation property
|
||
public AmtDevice Device { get; set; }
|
||
}
|
||
|
||
public class SystemInfo
|
||
{
|
||
public string Manufacturer { get; set; }
|
||
public string Model { get; set; }
|
||
public string SerialNumber { get; set; }
|
||
}
|
||
|
||
public class ProcessorInfo
|
||
{
|
||
public string Model { get; set; }
|
||
public int Cores { get; set; }
|
||
public int Threads { get; set; }
|
||
public int MaxClockSpeed { get; set; } // MHz
|
||
public int CurrentClockSpeed { get; set; } // MHz
|
||
}
|
||
|
||
public class MemoryInfo
|
||
{
|
||
public long TotalCapacity { get; set; } // bytes
|
||
public int TotalCapacityGB { get; set; }
|
||
public List<MemoryModule> Modules { get; set; }
|
||
}
|
||
|
||
public class MemoryModule
|
||
{
|
||
public int Id { get; set; }
|
||
public int HardwareInfoId { get; set; }
|
||
public string Slot { get; set; }
|
||
public long Capacity { get; set; } // bytes
|
||
public int CapacityGB { get; set; }
|
||
public int Speed { get; set; } // MHz
|
||
public string Type { get; set; } // DDR3, DDR4, etc.
|
||
public string Manufacturer { get; set; }
|
||
public string PartNumber { get; set; }
|
||
public string SerialNumber { get; set; }
|
||
}
|
||
|
||
public class StorageInfo
|
||
{
|
||
public List<StorageDevice> Devices { get; set; }
|
||
}
|
||
|
||
public class StorageDevice
|
||
{
|
||
public int Id { get; set; }
|
||
public int HardwareInfoId { get; set; }
|
||
public string DeviceId { get; set; }
|
||
public string Model { get; set; }
|
||
public long Capacity { get; set; } // bytes
|
||
public int CapacityGB { get; set; }
|
||
public string InterfaceType { get; set; } // SATA, NVMe, etc.
|
||
}
|
||
```
|
||
|
||
### 3. Frontend Components
|
||
|
||
#### 3.1 HardwareInfoModal.vue
|
||
|
||
**Responsibility**: 显示单个设备的硬件信息弹窗
|
||
|
||
**Features**:
|
||
- 分组显示系统信息、CPU、内存、存储
|
||
- 显示最后更新时间
|
||
- 提供刷新按钮
|
||
- 提供导出按钮
|
||
- 加载状态和错误处理
|
||
|
||
**Template Structure**:
|
||
```vue
|
||
<template>
|
||
<div class="hardware-info-modal">
|
||
<div class="modal-header">
|
||
<h2>硬件配置信息 - {{ deviceIp }}</h2>
|
||
<button @click="refresh">刷新</button>
|
||
<button @click="exportInfo">导出</button>
|
||
</div>
|
||
|
||
<div class="modal-body">
|
||
<!-- System Info Section -->
|
||
<section class="info-section">
|
||
<h3>系统信息</h3>
|
||
<div class="info-grid">
|
||
<div class="info-item">
|
||
<label>制造商:</label>
|
||
<span>{{ hardwareInfo.systemInfo.manufacturer }}</span>
|
||
</div>
|
||
<!-- ... -->
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Processor Section -->
|
||
<section class="info-section">
|
||
<h3>处理器</h3>
|
||
<!-- ... -->
|
||
</section>
|
||
|
||
<!-- Memory Section -->
|
||
<section class="info-section">
|
||
<h3>内存</h3>
|
||
<div class="memory-summary">
|
||
总容量: {{ hardwareInfo.memory.totalCapacityGB }} GB
|
||
</div>
|
||
<table class="memory-table">
|
||
<thead>
|
||
<tr>
|
||
<th>插槽</th>
|
||
<th>容量</th>
|
||
<th>速度</th>
|
||
<th>类型</th>
|
||
<th>制造商</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr v-for="module in hardwareInfo.memory.modules" :key="module.slot">
|
||
<!-- ... -->
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</section>
|
||
|
||
<!-- Storage Section -->
|
||
<section class="info-section">
|
||
<h3>存储设备</h3>
|
||
<!-- ... -->
|
||
</section>
|
||
</div>
|
||
|
||
<div class="modal-footer">
|
||
<span class="last-updated">
|
||
最后更新: {{ formatDate(hardwareInfo.lastUpdated) }}
|
||
</span>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
```
|
||
|
||
#### 3.2 DeviceList.vue (Updated)
|
||
|
||
**Changes**: 添加"查看硬件"按钮
|
||
|
||
```vue
|
||
<template>
|
||
<tr v-for="device in devices" :key="device.id">
|
||
<!-- existing columns -->
|
||
<td>
|
||
<button @click="viewHardwareInfo(device.id)">查看硬件</button>
|
||
<button @click="deleteDevice(device.id)">删除</button>
|
||
</td>
|
||
</tr>
|
||
</template>
|
||
```
|
||
|
||
#### 3.3 BatchHardwareExport.vue
|
||
|
||
**Responsibility**: 批量导出硬件信息
|
||
|
||
**Features**:
|
||
- 选择多个设备
|
||
- 选择导出格式(CSV/JSON)
|
||
- 显示导出进度
|
||
- 下载文件
|
||
|
||
## Error Handling
|
||
|
||
### Error Scenarios and Handling
|
||
|
||
1. **设备连接失败**
|
||
- Retry: 重试 1 次
|
||
- Fallback: 返回错误信息,标记为不可用
|
||
- User Message: "无法连接到设备,请检查设备是否在线"
|
||
|
||
2. **CIM 类不支持**
|
||
- Retry: 不重试
|
||
- Fallback: 跳过该组件,继续查询其他组件
|
||
- User Message: 显示"不支持"或"信息不可用"
|
||
|
||
3. **查询超时**
|
||
- Timeout: 30 秒
|
||
- Retry: 不重试
|
||
- Fallback: 返回已获取的部分信息
|
||
- User Message: "查询超时,部分信息可能不完整"
|
||
|
||
4. **数据解析错误**
|
||
- Retry: 不重试
|
||
- Fallback: 使用默认值或跳过该字段
|
||
- Logging: 记录详细错误日志
|
||
- User Message: "部分信息解析失败"
|
||
|
||
5. **数据库保存失败**
|
||
- Retry: 重试 2 次
|
||
- Fallback: 返回查询结果但不缓存
|
||
- Logging: 记录错误
|
||
- User Message: "信息已获取但缓存失败"
|
||
|
||
## Testing Strategy
|
||
|
||
### Unit Tests
|
||
|
||
1. **AmtHardwareQueryService Tests**
|
||
- Test CIM query construction
|
||
- Test data parsing from CIM objects
|
||
- Test error handling for missing properties
|
||
- Test handling of null values
|
||
|
||
2. **HardwareInfoService Tests**
|
||
- Test cache hit/miss logic
|
||
- Test force refresh behavior
|
||
- Test batch query coordination
|
||
- Test error aggregation
|
||
|
||
3. **HardwareInfoRepository Tests**
|
||
- Test CRUD operations
|
||
- Test foreign key constraints
|
||
- Test cascade deletes
|
||
|
||
### Integration Tests
|
||
|
||
1. **End-to-End Hardware Query**
|
||
- Test complete flow from API to AMT device
|
||
- Test with real AMT device (if available)
|
||
- Test with mock AMT responses
|
||
|
||
2. **Batch Query Performance**
|
||
- Test querying 10+ devices simultaneously
|
||
- Verify no resource leaks
|
||
- Verify proper error isolation
|
||
|
||
### Manual Testing Checklist
|
||
|
||
- [ ] Query hardware info from HTTP device (192.168.8.111)
|
||
- [ ] Query hardware info from HTTPS device (192.168.8.112)
|
||
- [ ] Verify cache works correctly
|
||
- [ ] Test force refresh
|
||
- [ ] Test batch query with mixed success/failure
|
||
- [ ] Test export to CSV
|
||
- [ ] Test export to JSON
|
||
- [ ] Verify UI displays all information correctly
|
||
- [ ] Test with device that doesn't support all CIM classes
|
||
- [ ] Test error messages are user-friendly
|
||
|
||
## Performance Considerations
|
||
|
||
1. **Query Optimization**
|
||
- Query all CIM classes in parallel using Task.WhenAll
|
||
- Set reasonable timeout (30 seconds per device)
|
||
- Use connection pooling for database
|
||
|
||
2. **Caching Strategy**
|
||
- Cache hardware info for 24 hours
|
||
- Invalidate cache on force refresh
|
||
- Use database indexes on DeviceId and LastUpdated
|
||
|
||
3. **Batch Query**
|
||
- Limit concurrent queries to 10 devices at a time
|
||
- Use SemaphoreSlim to control concurrency
|
||
- Return results as they complete (streaming)
|
||
|
||
4. **Memory Management**
|
||
- Dispose WsmanConnection properly
|
||
- Use streaming for large exports
|
||
- Limit result set size
|
||
|
||
## Security Considerations
|
||
|
||
1. **Authentication**
|
||
- Reuse existing AMT credentials from database
|
||
- Decrypt passwords only when needed
|
||
- Never log passwords
|
||
|
||
2. **Authorization**
|
||
- Verify user has permission to view device info
|
||
- Implement role-based access control
|
||
|
||
3. **Data Protection**
|
||
- Sanitize serial numbers if needed
|
||
- Consider masking sensitive hardware info
|
||
|
||
4. **Input Validation**
|
||
- Validate device IDs
|
||
- Validate export format parameters
|
||
- Prevent SQL injection in queries
|
||
|
||
## Deployment Considerations
|
||
|
||
1. **Database Migration**
|
||
- Create migration for new tables
|
||
- Add foreign key constraints
|
||
- Create indexes
|
||
|
||
2. **Configuration**
|
||
- Add cache expiration setting to appsettings.json
|
||
- Add query timeout setting
|
||
- Add batch query concurrency limit
|
||
|
||
3. **Monitoring**
|
||
- Log query success/failure rates
|
||
- Monitor query duration
|
||
- Alert on high failure rates
|
||
|
||
## Future Enhancements
|
||
|
||
1. **Additional Hardware Info**
|
||
- Network adapters (CIM_NetworkAdapter)
|
||
- BIOS information (CIM_BIOSElement)
|
||
- Chassis information (CIM_Chassis)
|
||
- Fan and temperature sensors
|
||
|
||
2. **Hardware Change Detection**
|
||
- Compare current vs. cached hardware info
|
||
- Alert on hardware changes
|
||
- Track hardware change history
|
||
|
||
3. **Hardware Inventory Reports**
|
||
- Generate PDF reports
|
||
- Schedule automatic inventory scans
|
||
- Hardware lifecycle management
|
||
|
||
4. **Performance Metrics**
|
||
- Track query performance over time
|
||
- Identify slow devices
|
||
- Optimize query patterns
|
||
|