19 KiB
Raw Permalink Blame History

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:

// 查询单个设备的硬件信息
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:

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:

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):
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();
    // ...
}
  1. Processor Information (CIM_Processor via CIM_Realizes):
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();
        // ...
    }
}
  1. Memory Information (CIM_PhysicalMemory):
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();
    // ...
}
  1. Storage Information (CIM_MediaAccessDevice):
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:

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

-- 硬件信息主表
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

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:

<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: 添加"查看硬件"按钮

<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