119 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			119 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| import { BaseMigration } from './base-migration.ts';
 | |
| import { logger } from '../logger.ts';
 | |
| 
 | |
| /**
 | |
|  * Migration from v3 (upsList) to v4 (upsDevices)
 | |
|  *
 | |
|  * Transforms v3 format with flat SNMP config:
 | |
|  * {
 | |
|  *   upsList: [
 | |
|  *     {
 | |
|  *       id: "ups-1",
 | |
|  *       name: "UPS 1",
 | |
|  *       host: "192.168.1.1",
 | |
|  *       port: 161,
 | |
|  *       community: "public",
 | |
|  *       version: "1"  // string
 | |
|  *     }
 | |
|  *   ]
 | |
|  * }
 | |
|  *
 | |
|  * To v4 format with nested SNMP config:
 | |
|  * {
 | |
|  *   version: "4.0",
 | |
|  *   upsDevices: [
 | |
|  *     {
 | |
|  *       id: "ups-1",
 | |
|  *       name: "UPS 1",
 | |
|  *       snmp: {
 | |
|  *         host: "192.168.1.1",
 | |
|  *         port: 161,
 | |
|  *         community: "public",
 | |
|  *         version: 1,  // number
 | |
|  *         timeout: 5000
 | |
|  *       },
 | |
|  *       thresholds: { battery: 60, runtime: 20 },
 | |
|  *       groups: []
 | |
|  *     }
 | |
|  *   ]
 | |
|  * }
 | |
|  */
 | |
| export class MigrationV3ToV4 extends BaseMigration {
 | |
|   readonly fromVersion = '3.x';
 | |
|   readonly toVersion = '4.0';
 | |
| 
 | |
|   async shouldRun(config: any): Promise<boolean> {
 | |
|     // V3 format has upsList OR has upsDevices with flat structure (host at top level)
 | |
|     if (config.upsList && !config.upsDevices) {
 | |
|       return true; // Classic v3 with upsList
 | |
|     }
 | |
| 
 | |
|     // Check if upsDevices exists but has flat structure (v3 format)
 | |
|     if (config.upsDevices && config.upsDevices.length > 0) {
 | |
|       const firstDevice = config.upsDevices[0];
 | |
|       // V3 has host at top level, v4 has it nested in snmp object
 | |
|       return !!firstDevice.host && !firstDevice.snmp;
 | |
|     }
 | |
| 
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   async migrate(config: any): Promise<any> {
 | |
|     logger.info(`${this.getName()}: Migrating v3 config to v4 format...`);
 | |
|     logger.dim(`  - Restructuring UPS devices (flat → nested snmp config)`);
 | |
| 
 | |
|     // Get devices from either upsList or upsDevices (for partially migrated configs)
 | |
|     const sourceDevices = config.upsList || config.upsDevices;
 | |
| 
 | |
|     // Transform each UPS device from v3 flat structure to v4 nested structure
 | |
|     const transformedDevices = sourceDevices.map((device: any) => {
 | |
|       // Build SNMP config object
 | |
|       const snmpConfig: any = {
 | |
|         host: device.host,
 | |
|         port: device.port || 161,
 | |
|         version: typeof device.version === 'string' ? parseInt(device.version, 10) : device.version,
 | |
|         timeout: device.timeout || 5000,
 | |
|       };
 | |
| 
 | |
|       // Add SNMPv1/v2c fields
 | |
|       if (device.community) {
 | |
|         snmpConfig.community = device.community;
 | |
|       }
 | |
| 
 | |
|       // Add SNMPv3 fields
 | |
|       if (device.securityLevel) snmpConfig.securityLevel = device.securityLevel;
 | |
|       if (device.username) snmpConfig.username = device.username;
 | |
|       if (device.authProtocol) snmpConfig.authProtocol = device.authProtocol;
 | |
|       if (device.authKey) snmpConfig.authKey = device.authKey;
 | |
|       if (device.privProtocol) snmpConfig.privProtocol = device.privProtocol;
 | |
|       if (device.privKey) snmpConfig.privKey = device.privKey;
 | |
| 
 | |
|       // Add UPS model if present
 | |
|       if (device.upsModel) snmpConfig.upsModel = device.upsModel;
 | |
|       if (device.customOIDs) snmpConfig.customOIDs = device.customOIDs;
 | |
| 
 | |
|       // Return v4 format with nested structure
 | |
|       return {
 | |
|         id: device.id,
 | |
|         name: device.name,
 | |
|         snmp: snmpConfig,
 | |
|         thresholds: device.thresholds || {
 | |
|           battery: 60,
 | |
|           runtime: 20,
 | |
|         },
 | |
|         groups: device.groups || [],
 | |
|       };
 | |
|     });
 | |
| 
 | |
|     const migrated = {
 | |
|       version: this.toVersion,
 | |
|       upsDevices: transformedDevices,
 | |
|       groups: config.groups || [],
 | |
|       checkInterval: config.checkInterval || 30000,
 | |
|     };
 | |
| 
 | |
|     logger.success(`${this.getName()}: Migration complete (${transformedDevices.length} devices transformed)`);
 | |
|     return migrated;
 | |
|   }
 | |
| }
 |