n8n-nodes-customssh
Version:
n8n community node for advanced SSH connections with configurable ciphers and network device support
162 lines (161 loc) • 7.26 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ConfigManager = void 0;
const SshCommandExecutor_1 = require("./SshCommandExecutor");
const LoggingUtils_1 = require("../utils/LoggingUtils");
/**
* Service for managing device configurations
*/
class ConfigManager {
/**
* Get configuration from network device
*/
static async getDeviceConfig(host, port, username, password, configType, cipher, options) {
// Get device-specific command
let command = '';
switch (options.deviceType) {
case 'cisco':
command = configType === 'running' ? 'show running-config' : 'show startup-config';
break;
case 'aruba':
command = configType === 'running' ? 'show running-config' : 'show config startup';
break;
case 'aruba-os':
// Aruba OS uses different commands for configurations
command = configType === 'running' ? 'show running-config' : 'show config';
break;
case 'juniper':
command = 'show configuration';
break;
default:
command = 'show running-config';
}
LoggingUtils_1.LoggingUtils.log(`Retrieving ${configType} configuration from ${host} using command: ${command}`, options.verboseLogging || false);
// Execute command
const result = await SshCommandExecutor_1.SshCommandExecutor.executeSshCommand(host, port, username, password, command, [cipher], options);
if (!result.success || !result.output) {
throw new Error(`Failed to retrieve configuration: ${result.error || 'Unknown error'}`);
}
return result.output;
}
/**
* Apply configuration to network device
*/
static async applyDeviceConfig(host, port, username, password, configText, applyMethod, saveAfterApply, cipher, options) {
var _a;
// Process config text into lines
const configLines = configText
.split('\n')
.map((line) => line.trim())
.filter((line) => line.length > 0 &&
!line.startsWith('!') &&
!line.startsWith('#') &&
!line.match(/^version \d+\.\d+/));
LoggingUtils_1.LoggingUtils.log(`Applying configuration to ${host}: ${configLines.length} lines`, options.verboseLogging || false);
const errors = [];
let enterConfigSuccess = true;
// Step 1: Enter config mode
try {
let configCommand = '';
switch (options.deviceType) {
case 'juniper':
configCommand = 'configure';
break;
case 'aruba-os':
configCommand = 'config';
break;
default:
configCommand = 'configure terminal';
}
// Enter configuration mode
const configResult = await SshCommandExecutor_1.SshCommandExecutor.executeSshCommand(host, port, username, password, configCommand, [cipher], options);
if (!configResult.success) {
throw new Error(`Failed to enter configuration mode: ${configResult.error}`);
}
}
catch (error) {
enterConfigSuccess = false;
errors.push(`Failed to enter configuration mode: ${error.message}`);
}
if (!enterConfigSuccess) {
return {
success: false,
linesApplied: 0,
errors,
};
}
// Step 2: Apply configuration commands
let commands = configLines.map((line) => ({
command: line,
waitTime: 500, // Shorter wait time between config lines
}));
// Handle Aruba OS specific configuration restore
if (options.deviceType === 'aruba-os') {
// Set specific save command for Aruba OS
options.deviceSpecific.saveCommand = 'write memory';
// For Aruba OS, we might need different configuration commands
if (applyMethod === 'replace') {
options.deviceSpecific.configReplaceMode = true;
options.deviceSpecific.configModeCommand = 'config';
options.deviceSpecific.configExitCommand = 'end';
}
// Add pagination handling for configuration commands
const noPaginationCommand = {
command: 'no page',
waitTime: 1000,
};
// Add this command at the beginning to prevent pagination issues
commands.unshift(noPaginationCommand);
// Increase wait times for Aruba OS config commands
commands = commands.map((cmd) => ({
...cmd,
waitTime: Math.max(cmd.waitTime, 1500), // At least 1.5s for config commands
}));
}
const configApplyResult = await SshCommandExecutor_1.SshCommandExecutor.executeMultipleSshCommands(host, port, username, password, commands, [cipher], options);
// Check for errors in results
if (configApplyResult.results) {
configApplyResult.results.forEach((result, index) => {
if (result.output &&
(result.output.toLowerCase().includes('error') ||
result.output.toLowerCase().includes('invalid') ||
result.output.toLowerCase().includes('failed'))) {
errors.push(`Error on line "${commands[index].command}": ${result.output.trim()}`);
}
});
}
// Step 3: Exit config mode and save if requested
let exitCommand = '';
let saveCommand = '';
switch (options.deviceType) {
case 'juniper':
// For Juniper, we commit and exit in one command
exitCommand = saveAfterApply ? 'commit and-quit' : 'quit';
break;
case 'aruba-os':
// For Aruba OS, use end to exit config mode
exitCommand = 'end';
// Use write memory to save
saveCommand = saveAfterApply ? ((_a = options.deviceSpecific) === null || _a === void 0 ? void 0 : _a.saveCommand) || 'write memory' : '';
break;
case 'cisco':
default:
// For Cisco and others, exit config mode first
exitCommand = 'end';
// Then issue save command if needed
saveCommand = saveAfterApply ? 'write memory' : '';
}
// Exit config mode
await SshCommandExecutor_1.SshCommandExecutor.executeSshCommand(host, port, username, password, exitCommand, [cipher], options);
// Save if requested
if (saveAfterApply && saveCommand) {
await SshCommandExecutor_1.SshCommandExecutor.executeSshCommand(host, port, username, password, saveCommand, [cipher], options);
}
return {
success: errors.length === 0,
linesApplied: configLines.length,
errors: errors,
};
}
}
exports.ConfigManager = ConfigManager;