BREAKING CHANGE(snmp): refactor: update SNMP type definitions and interface names for consistency
This commit is contained in:
parent
70c16fa0a6
commit
ecfd171f97
@ -1,5 +1,11 @@
|
||||
# Changelog
|
||||
|
||||
## 2025-03-25 - 2.0.0 - BREAKING CHANGE(snmp)
|
||||
refactor: update SNMP type definitions and interface names for consistency
|
||||
|
||||
- Renamed SnmpConfig to ISnmpConfig, OIDSet to IOidSet, UpsStatus to IUpsStatus, and UpsModel to TUpsModel in ts/snmp/types.ts.
|
||||
- Updated internal references in ts/daemon.ts, ts/snmp/index.ts, ts/snmp/manager.ts, ts/snmp/oid-sets.ts, ts/snmp/packet-creator.ts, and ts/snmp/packet-parser.ts to use the new interface names.
|
||||
|
||||
## 2025-03-25 - 1.10.1 - fix(systemd/readme)
|
||||
Improve README documentation and fix UPS status retrieval in systemd service
|
||||
|
||||
|
@ -3,6 +3,6 @@
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@serve.zone/nupst',
|
||||
version: '1.10.1',
|
||||
version: '2.0.0',
|
||||
description: 'Node.js UPS Shutdown Tool for SNMP-enabled UPS devices'
|
||||
}
|
||||
|
16
ts/daemon.ts
16
ts/daemon.ts
@ -1,13 +1,13 @@
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import { NupstSnmp, type SnmpConfig } from './snmp.js';
|
||||
import { NupstSnmp, type ISnmpConfig } from './snmp.js';
|
||||
|
||||
/**
|
||||
* Configuration interface for the daemon
|
||||
*/
|
||||
export interface NupstConfig {
|
||||
export interface INupstConfig {
|
||||
/** SNMP configuration settings */
|
||||
snmp: SnmpConfig;
|
||||
snmp: ISnmpConfig;
|
||||
/** Threshold settings for initiating shutdown */
|
||||
thresholds: {
|
||||
/** Shutdown when battery below this percentage */
|
||||
@ -28,7 +28,7 @@ export class NupstDaemon {
|
||||
private readonly CONFIG_PATH = '/etc/nupst/config.json';
|
||||
|
||||
/** Default configuration */
|
||||
private readonly DEFAULT_CONFIG: NupstConfig = {
|
||||
private readonly DEFAULT_CONFIG: INupstConfig = {
|
||||
snmp: {
|
||||
host: '127.0.0.1',
|
||||
port: 161,
|
||||
@ -52,7 +52,7 @@ export class NupstDaemon {
|
||||
checkInterval: 30000, // Check every 30 seconds
|
||||
};
|
||||
|
||||
private config: NupstConfig;
|
||||
private config: INupstConfig;
|
||||
private snmp: NupstSnmp;
|
||||
private isRunning: boolean = false;
|
||||
|
||||
@ -68,7 +68,7 @@ export class NupstDaemon {
|
||||
* Load configuration from file
|
||||
* @throws Error if configuration file doesn't exist
|
||||
*/
|
||||
public async loadConfig(): Promise<NupstConfig> {
|
||||
public async loadConfig(): Promise<INupstConfig> {
|
||||
try {
|
||||
// Check if config file exists
|
||||
const configExists = fs.existsSync(this.CONFIG_PATH);
|
||||
@ -95,7 +95,7 @@ export class NupstDaemon {
|
||||
/**
|
||||
* Save configuration to file
|
||||
*/
|
||||
public async saveConfig(config: NupstConfig): Promise<void> {
|
||||
public async saveConfig(config: INupstConfig): Promise<void> {
|
||||
try {
|
||||
const configDir = path.dirname(this.CONFIG_PATH);
|
||||
if (!fs.existsSync(configDir)) {
|
||||
@ -125,7 +125,7 @@ export class NupstDaemon {
|
||||
/**
|
||||
* Get the current configuration
|
||||
*/
|
||||
public getConfig(): NupstConfig {
|
||||
public getConfig(): INupstConfig {
|
||||
return this.config;
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
// Re-export all public types
|
||||
export type { UpsStatus, OIDSet, UpsModel, SnmpConfig } from './types.js';
|
||||
export type { IUpsStatus, IOidSet, TUpsModel, ISnmpConfig } from './types.js';
|
||||
|
||||
// Re-export the SNMP manager class
|
||||
export { NupstSnmp } from './manager.js';
|
@ -1,7 +1,7 @@
|
||||
import { exec } from 'child_process';
|
||||
import { promisify } from 'util';
|
||||
import * as dgram from 'dgram';
|
||||
import type { OIDSet, SnmpConfig, UpsModel, UpsStatus } from './types.js';
|
||||
import type { IOidSet, ISnmpConfig, TUpsModel, IUpsStatus } from './types.js';
|
||||
import { UpsOidSets } from './oid-sets.js';
|
||||
import { SnmpPacketCreator } from './packet-creator.js';
|
||||
import { SnmpPacketParser } from './packet-parser.js';
|
||||
@ -14,12 +14,12 @@ const execAsync = promisify(exec);
|
||||
*/
|
||||
export class NupstSnmp {
|
||||
// Active OID set
|
||||
private activeOIDs: OIDSet;
|
||||
private activeOIDs: IOidSet;
|
||||
// Reference to the parent Nupst instance
|
||||
private nupst: any; // Type 'any' to avoid circular dependency
|
||||
|
||||
// Default SNMP configuration
|
||||
private readonly DEFAULT_CONFIG: SnmpConfig = {
|
||||
private readonly DEFAULT_CONFIG: ISnmpConfig = {
|
||||
host: '127.0.0.1', // Default to localhost
|
||||
port: 161, // Default SNMP port
|
||||
community: 'public', // Default community string for v1/v2c
|
||||
@ -64,7 +64,7 @@ export class NupstSnmp {
|
||||
* Set active OID set based on UPS model
|
||||
* @param config SNMP configuration
|
||||
*/
|
||||
private setActiveOIDs(config: SnmpConfig): void {
|
||||
private setActiveOIDs(config: ISnmpConfig): void {
|
||||
// If custom OIDs are provided, use them
|
||||
if (config.upsModel === 'custom' && config.customOIDs) {
|
||||
this.activeOIDs = config.customOIDs;
|
||||
@ -206,7 +206,7 @@ export class NupstSnmp {
|
||||
* @param config SNMP configuration
|
||||
* @returns Promise resolving to the UPS status
|
||||
*/
|
||||
public async getUpsStatus(config = this.DEFAULT_CONFIG): Promise<UpsStatus> {
|
||||
public async getUpsStatus(config = this.DEFAULT_CONFIG): Promise<IUpsStatus> {
|
||||
try {
|
||||
// Set active OID set based on UPS model in config
|
||||
this.setActiveOIDs(config);
|
||||
@ -408,12 +408,12 @@ export class NupstSnmp {
|
||||
* @param config SNMP configuration
|
||||
* @returns Promise resolving to the discovered engine ID
|
||||
*/
|
||||
public async discoverEngineId(config: SnmpConfig): Promise<Buffer> {
|
||||
public async discoverEngineId(config: ISnmpConfig): Promise<Buffer> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const socket = dgram.createSocket('udp4');
|
||||
|
||||
// Create a proper discovery message (SNMPv3 with noAuthNoPriv)
|
||||
const discoveryConfig: SnmpConfig = {
|
||||
const discoveryConfig: ISnmpConfig = {
|
||||
...config,
|
||||
securityLevel: 'noAuthNoPriv',
|
||||
username: '', // Empty username for discovery
|
||||
|
@ -1,4 +1,4 @@
|
||||
import type { OIDSet, UpsModel } from './types.js';
|
||||
import type { IOidSet, TUpsModel } from './types.js';
|
||||
|
||||
/**
|
||||
* OID sets for different UPS models
|
||||
@ -8,7 +8,7 @@ export class UpsOidSets {
|
||||
/**
|
||||
* OID sets for different UPS models
|
||||
*/
|
||||
private static readonly UPS_OID_SETS: Record<UpsModel, OIDSet> = {
|
||||
private static readonly UPS_OID_SETS: Record<TUpsModel, IOidSet> = {
|
||||
// Cyberpower OIDs for RMCARD205 (based on CyberPower_MIB_v2.11)
|
||||
cyberpower: {
|
||||
POWER_STATUS: '1.3.6.1.4.1.3808.1.1.1.4.1.1.0', // upsBaseOutputStatus (2=online, 3=on battery)
|
||||
@ -57,7 +57,7 @@ export class UpsOidSets {
|
||||
* @param model UPS model name
|
||||
* @returns OID set for the model
|
||||
*/
|
||||
public static getOidSet(model: UpsModel): OIDSet {
|
||||
public static getOidSet(model: TUpsModel): IOidSet {
|
||||
return this.UPS_OID_SETS[model];
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import * as crypto from 'crypto';
|
||||
import type { SnmpConfig, SnmpV3SecurityParams } from './types.js';
|
||||
import type { ISnmpConfig, ISnmpV3SecurityParams } from './types.js';
|
||||
import { SnmpEncoder } from './encoder.js';
|
||||
|
||||
/**
|
||||
@ -118,7 +118,7 @@ export class SnmpPacketCreator {
|
||||
*/
|
||||
public static createSnmpV3GetRequest(
|
||||
oid: string,
|
||||
config: SnmpConfig,
|
||||
config: ISnmpConfig,
|
||||
engineID: Buffer,
|
||||
engineBoots: number,
|
||||
engineTime: number,
|
||||
@ -145,7 +145,7 @@ export class SnmpPacketCreator {
|
||||
}
|
||||
|
||||
// Create security parameters
|
||||
const securityParams: SnmpV3SecurityParams = {
|
||||
const securityParams: ISnmpV3SecurityParams = {
|
||||
msgAuthoritativeEngineID: engineID,
|
||||
msgAuthoritativeEngineBoots: engineBoots,
|
||||
msgAuthoritativeEngineTime: engineTime,
|
||||
@ -366,7 +366,7 @@ export class SnmpPacketCreator {
|
||||
* @param config SNMP configuration
|
||||
* @returns Encrypted data
|
||||
*/
|
||||
private static simulateEncryption(data: Buffer, config: SnmpConfig): Buffer {
|
||||
private static simulateEncryption(data: Buffer, config: ISnmpConfig): Buffer {
|
||||
// This is a placeholder - in a real implementation, you would:
|
||||
// 1. Generate an initialization vector (IV)
|
||||
// 2. Use the privacy key derived from the privKey
|
||||
@ -427,7 +427,7 @@ export class SnmpPacketCreator {
|
||||
* @param authParamsBuf Authentication parameters buffer
|
||||
* @returns Authenticated message
|
||||
*/
|
||||
private static addAuthentication(message: Buffer, config: SnmpConfig, authParamsBuf: Buffer): Buffer {
|
||||
private static addAuthentication(message: Buffer, config: ISnmpConfig, authParamsBuf: Buffer): Buffer {
|
||||
// In a real implementation, this would:
|
||||
// 1. Zero out the authentication parameters field
|
||||
// 2. Calculate HMAC-MD5 or HMAC-SHA1 over the entire message
|
||||
@ -548,7 +548,7 @@ export class SnmpPacketCreator {
|
||||
* @param requestID Request ID
|
||||
* @returns Discovery message
|
||||
*/
|
||||
public static createDiscoveryMessage(config: SnmpConfig, requestID: number): Buffer {
|
||||
public static createDiscoveryMessage(config: ISnmpConfig, requestID: number): Buffer {
|
||||
// Basic SNMPv3 header for discovery
|
||||
const msgIdBuf = Buffer.concat([
|
||||
Buffer.from([0x02, 0x04]), // ASN.1 Integer, length 4
|
||||
|
@ -1,4 +1,4 @@
|
||||
import type { SnmpConfig } from './types.js';
|
||||
import type { ISnmpConfig } from './types.js';
|
||||
import { SnmpEncoder } from './encoder.js';
|
||||
|
||||
/**
|
||||
@ -13,7 +13,7 @@ export class SnmpPacketParser {
|
||||
* @param debug Whether to enable debug output
|
||||
* @returns Parsed value or null if parsing failed
|
||||
*/
|
||||
public static parseSnmpResponse(buffer: Buffer, config: SnmpConfig, debug: boolean = false): any {
|
||||
public static parseSnmpResponse(buffer: Buffer, config: ISnmpConfig, debug: boolean = false): any {
|
||||
// Check if we have a response packet
|
||||
if (buffer[0] !== 0x30) {
|
||||
throw new Error('Invalid SNMP response format');
|
||||
|
@ -5,7 +5,7 @@
|
||||
/**
|
||||
* UPS status interface
|
||||
*/
|
||||
export interface UpsStatus {
|
||||
export interface IUpsStatus {
|
||||
/** Current power status */
|
||||
powerStatus: 'online' | 'onBattery' | 'unknown';
|
||||
/** Battery capacity percentage */
|
||||
@ -19,7 +19,7 @@ export interface UpsStatus {
|
||||
/**
|
||||
* SNMP OID Sets for different UPS brands
|
||||
*/
|
||||
export interface OIDSet {
|
||||
export interface IOidSet {
|
||||
/** OID for power status */
|
||||
POWER_STATUS: string;
|
||||
/** OID for battery capacity */
|
||||
@ -31,12 +31,12 @@ export interface OIDSet {
|
||||
/**
|
||||
* Supported UPS model types
|
||||
*/
|
||||
export type UpsModel = 'cyberpower' | 'apc' | 'eaton' | 'tripplite' | 'liebert' | 'custom';
|
||||
export type TUpsModel = 'cyberpower' | 'apc' | 'eaton' | 'tripplite' | 'liebert' | 'custom';
|
||||
|
||||
/**
|
||||
* SNMP Configuration interface
|
||||
*/
|
||||
export interface SnmpConfig {
|
||||
export interface ISnmpConfig {
|
||||
/** SNMP server host */
|
||||
host: string;
|
||||
/** SNMP server port (default 161) */
|
||||
@ -66,15 +66,15 @@ export interface SnmpConfig {
|
||||
|
||||
// UPS model and custom OIDs
|
||||
/** UPS model for OID selection */
|
||||
upsModel?: UpsModel;
|
||||
upsModel?: TUpsModel;
|
||||
/** Custom OIDs when using custom UPS model */
|
||||
customOIDs?: OIDSet;
|
||||
customOIDs?: IOidSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* SNMPv3 security parameters
|
||||
*/
|
||||
export interface SnmpV3SecurityParams {
|
||||
export interface ISnmpV3SecurityParams {
|
||||
/** Engine ID for the SNMP server */
|
||||
msgAuthoritativeEngineID: Buffer;
|
||||
/** Engine boots counter */
|
||||
|
Loading…
x
Reference in New Issue
Block a user