UNPKG

n8n-nodes-netdevices

Version:
325 lines 11.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.JuniperConnection = void 0; const base_connection_1 = require("../base-connection"); class JuniperConnection extends base_connection_1.BaseConnection { constructor(credentials) { super(credentials); this.inCliMode = false; this.inConfigMode = false; this.inShellMode = false; } async sessionPreparation() { await this.createJuniperShellChannel(); if (this.fastMode) { await this.setBasePrompt(); } else { await this.enterCliMode(); await Promise.all([ this.setTerminalWidth(), this.disablePaging(), ]); await this.setBasePrompt(); } } async createJuniperShellChannel() { return new Promise((resolve, reject) => { this.client.shell((err, channel) => { if (err) { reject(err); return; } this.currentChannel = channel; this.currentChannel.setEncoding(this.encoding); const waitTime = this.fastMode ? 200 : 500; setTimeout(() => { resolve(); }, waitTime); }); }); } async enterCliMode() { await this.writeChannel(this.returnChar); let output = await this.readChannel(3000); const mode = this.determineMode(output); if (mode === 'shell') { this.inShellMode = true; this.inCliMode = false; await this.writeChannel('cli' + this.newline); output = await this.readChannel(3000); if (output.includes('>') || output.includes('#')) { this.inCliMode = true; this.inShellMode = false; } } else if (mode === 'cli') { this.inCliMode = true; this.inShellMode = false; } } determineMode(data) { if (data.match(/root@/) || data.match(/%/) || data.match(/\$/)) { return 'shell'; } if (data.includes('>') || data.includes('#')) { return 'cli'; } return 'cli'; } async setTerminalWidth() { try { await this.writeChannel('set cli screen-width 511' + this.newline); const output = await this.readChannel(2000); if (!output.includes('Screen width set to')) { await this.writeChannel('set cli screen-width 511' + this.newline); await this.readChannel(2000); } } catch (error) { } } async disablePaging() { try { await this.writeChannel('set cli complete-on-space off' + this.newline); await this.readChannel(2000); await this.writeChannel('set cli screen-length 0' + this.newline); await this.readChannel(2000); } catch (error) { } } async setBasePrompt() { await this.writeChannel(this.returnChar); const output = await this.readChannel(3000); const lines = output.trim().split('\n'); const lastLine = lines[lines.length - 1]; this.basePrompt = lastLine.replace(/[>#$%]\s*$/, '').trim(); this.enabledPrompt = this.basePrompt + '#'; this.configPrompt = this.basePrompt + '#'; } async enterConfigMode() { if (!this.inCliMode) { await this.enterCliMode(); } try { await this.writeChannel('configure' + this.newline); const output = await this.readChannel(3000); if (output.includes('Entering configuration mode') || output.includes('[edit]')) { this.inConfigMode = true; } else { throw new Error('Failed to enter configuration mode'); } } catch (error) { throw new Error(`Failed to enter configuration mode: ${error}`); } } async exitConfigMode() { if (!this.inConfigMode) { return; } try { await this.writeChannel('exit configuration-mode' + this.newline); let output = await this.readChannel(3000); if (output.includes('Exit with uncommitted changes')) { await this.writeChannel('yes' + this.newline); output = await this.readChannel(3000); } if (output.includes('>') && !output.includes('[edit]')) { this.inConfigMode = false; } else { throw new Error('Failed to exit configuration mode'); } } catch (error) { throw new Error(`Failed to exit configuration mode: ${error}`); } } async sendCommand(command) { try { if (!this.isConnected || !this.currentChannel) { throw new Error('Not connected to device'); } if (!this.fastMode) { if (!this.inCliMode) { await this.enterCliMode(); } } await this.writeChannel(command + this.newline); const timeout = this.fastMode ? 5000 : 10000; const output = await this.readUntilPrompt(undefined, timeout); const cleanOutput = this.sanitizeOutput(output, command); return { command, output: cleanOutput, success: true }; } catch (error) { return { command, output: '', success: false, error: error instanceof Error ? error.message : 'Unknown error' }; } } async sendConfig(configCommands) { try { if (!this.isConnected || !this.currentChannel) { throw new Error('Not connected to device'); } await this.enterConfigMode(); let allOutput = ''; for (const command of configCommands) { await this.writeChannel(command + this.newline); const output = await this.readChannel(3000); allOutput += output; if (output.includes('error:') || output.includes('syntax error')) { throw new Error(`Configuration error on command "${command}": ${output}`); } } await this.commitConfig(); await this.exitConfigMode(); const cleanOutput = this.sanitizeOutput(allOutput, configCommands.join('; ')); return { command: configCommands.join('; '), output: cleanOutput, success: true }; } catch (error) { if (this.inConfigMode) { try { await this.exitConfigMode(); } catch (exitError) { } } return { command: configCommands.join('; '), output: '', success: false, error: error instanceof Error ? error.message : 'Unknown error' }; } } async commitConfig(comment) { try { if (!this.inConfigMode) { throw new Error('Not in configuration mode'); } let commitCommand = 'commit'; if (comment) { commitCommand += ` comment "${comment}"`; } await this.writeChannel(commitCommand + this.newline); const output = await this.readChannel(10000); if (output.includes('commit complete')) { return { command: commitCommand, output: output, success: true }; } else { throw new Error('Commit failed'); } } catch (error) { return { command: 'commit', output: '', success: false, error: error instanceof Error ? error.message : 'Unknown error' }; } } async getCurrentConfig() { return await this.sendCommand('show configuration'); } async saveConfig() { return await this.sendCommand('show configuration | display set'); } async rebootDevice() { try { await this.writeChannel('request system reboot' + this.newline); let output = await this.readChannel(5000); if (output.includes('Reboot the system?') || output.includes('[yes,no]')) { await this.writeChannel('yes' + this.newline); output += await this.readChannel(5000); } return { command: 'request system reboot', output: output, success: true }; } catch (error) { return { command: 'request system reboot', output: '', success: false, error: error instanceof Error ? error.message : 'Unknown error' }; } } sanitizeOutput(output, command) { const escapedCommand = command.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); let cleanOutput = output.replace(new RegExp(escapedCommand, 'g'), ''); const escapedBasePrompt = this.basePrompt.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); cleanOutput = cleanOutput.replace(new RegExp(escapedBasePrompt + '[>#$%]', 'g'), ''); cleanOutput = cleanOutput.replace(/\[edit\]/g, ''); cleanOutput = cleanOutput.replace(/Entering configuration mode/g, ''); cleanOutput = cleanOutput.replace(/Exiting configuration mode/g, ''); cleanOutput = cleanOutput.replace(/commit complete/g, ''); cleanOutput = cleanOutput.replace(/Screen width set to \d+/g, ''); cleanOutput = cleanOutput.replace(/Disabling complete-on-space/g, ''); cleanOutput = cleanOutput.replace(/Screen length set to \d+/g, ''); cleanOutput = cleanOutput.replace(/^\s+|\s+$/g, ''); cleanOutput = cleanOutput.replace(/\r\n/g, '\n'); cleanOutput = cleanOutput.replace(/\r/g, '\n'); cleanOutput = cleanOutput.replace(/\n\s*\n/g, '\n'); return cleanOutput; } isInCliMode() { return this.inCliMode; } isInConfigMode() { return this.inConfigMode; } isInShellMode() { return this.inShellMode; } async enterShellMode() { if (this.inShellMode) { return; } if (this.inCliMode) { await this.writeChannel('start shell' + this.newline); const output = await this.readChannel(3000); if (output.includes('$') || output.includes('%')) { this.inShellMode = true; this.inCliMode = false; } } } async returnToCliMode() { if (this.inCliMode) { return; } if (this.inShellMode) { await this.writeChannel('exit' + this.newline); const output = await this.readChannel(3000); if (output.includes('>') || output.includes('#')) { this.inCliMode = true; this.inShellMode = false; } } } } exports.JuniperConnection = JuniperConnection; //# sourceMappingURL=juniper-connection.js.map