n8n-nodes-netdevices
Version:
n8n node to interact with network devices (Cisco, MikroTik, Arista, Extreme Networks, Dell, Juniper, HP, Aruba, Ubiquiti, Palo Alto, Fortinet - ISP, data center, campus, and edge)
234 lines • 8.35 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.VersaFlexVNFConnection = void 0;
const base_connection_1 = require("../base-connection");
const no_enable_1 = require("../no-enable");
class VersaFlexVNFConnectionBase extends base_connection_1.BaseConnection {
constructor() {
super(...arguments);
this.inConfigMode = false;
}
async sessionPreparation() {
await this.createShellChannel();
await this.enterCliMode();
await this.setBasePrompt();
await Promise.all([
this.setTerminalWidth(),
this.disablePaging(),
]);
}
async setTerminalWidth() {
try {
await this.writeChannel('set screen width 511' + this.newline);
await this.readChannel(2000);
}
catch (error) {
}
}
async disablePaging() {
try {
await this.writeChannel('set screen length 0' + this.newline);
await this.readChannel(2000);
}
catch (error) {
}
}
async enterCliMode() {
let attempts = 0;
const maxAttempts = 50;
while (attempts < maxAttempts) {
await this.writeChannel(this.returnChar);
await new Promise(resolve => setTimeout(resolve, 100));
const output = await this.readChannel(1000);
if (output.includes('admin@') || /\$\s*$/.test(output.trim())) {
await this.writeChannel('cli' + this.newline);
await new Promise(resolve => setTimeout(resolve, 300));
await this.readChannel(500);
break;
}
else if (output.includes('>') || output.includes('%')) {
break;
}
attempts++;
}
}
async checkConfigMode() {
await this.writeChannel(this.returnChar);
const output = await this.readChannel(2000);
return output.includes(']');
}
async enterConfigMode() {
if (await this.checkConfigMode()) {
this.inConfigMode = true;
return;
}
try {
await this.writeChannel('configure' + this.newline);
const output = await this.readUntilPrompt(undefined, 3000);
if (!output.includes(']')) {
throw new Error('Failed to enter configuration mode');
}
this.inConfigMode = true;
}
catch (error) {
throw new Error(`Failed to enter configuration mode: ${error}`);
}
}
async exitConfigMode() {
if (!(await this.checkConfigMode())) {
this.inConfigMode = false;
return;
}
try {
await this.writeChannel('exit configuration-mode' + this.newline);
let output = await this.readChannel(3000);
if (output.includes('uncommitted changes')) {
await this.writeChannel('yes' + this.newline);
output = await this.readUntilPrompt(undefined, 3000);
}
if (await this.checkConfigMode()) {
throw new Error('Failed to exit configuration mode');
}
this.inConfigMode = false;
}
catch (error) {
throw new Error(`Failed to exit configuration mode: ${error}`);
}
}
async commit(options = {}) {
const { check = false, confirm = false, confirmDelay, comment = '', andQuit = false, timeout = 120000, } = options;
if (check && (confirm || confirmDelay || comment)) {
throw new Error('Invalid arguments: cannot use check with confirm, confirmDelay, or comment');
}
if (confirmDelay && !confirm) {
throw new Error('Invalid arguments: confirmDelay requires confirm to be true');
}
let commandString = 'commit';
let commitMarker = 'Commit complete.';
if (check) {
commandString = 'commit check';
commitMarker = 'Validation complete';
}
else if (confirm) {
if (confirmDelay) {
commandString = `commit confirmed ${confirmDelay}`;
}
else {
commandString = 'commit confirmed';
}
commitMarker = 'commit confirmed will be automatically rolled back in';
}
if (comment) {
if (comment.includes('"')) {
throw new Error('Invalid comment: contains double quote');
}
commandString += ` comment "${comment}"`;
}
if (andQuit) {
commandString += ' and-quit';
}
try {
await this.enterConfigMode();
await this.writeChannel(commandString + this.newline);
let output;
if (andQuit) {
output = await this.readUntilPrompt(this.basePrompt, timeout);
}
else {
output = await this.readUntilPrompt(undefined, timeout);
}
if (!output.includes(commitMarker)) {
throw new Error(`Commit failed with the following errors:\n\n${output}`);
}
return this.stripFlexVNFContext(output);
}
catch (error) {
throw new Error(`Failed to commit configuration: ${error}`);
}
}
async sendConfig(configCommands) {
try {
await this.enterConfigMode();
let allOutput = '';
let hasError = false;
let errorMessage = '';
for (const command of configCommands) {
try {
await this.writeChannel(command + this.newline);
const output = await this.readUntilPrompt(undefined, this.timeout);
allOutput += output;
const errorPatterns = [
/invalid command/i,
/syntax error/i,
/unknown command/i,
/error:/i,
/failed/i,
];
if (errorPatterns.some(pattern => pattern.test(output))) {
hasError = true;
errorMessage = `Error in command: ${command}`;
break;
}
}
catch (cmdError) {
hasError = true;
errorMessage = cmdError instanceof Error ? cmdError.message : 'Unknown error';
break;
}
}
const cleanedOutput = this.stripFlexVNFContext(allOutput);
return {
command: configCommands.join('\n'),
output: cleanedOutput,
success: !hasError,
error: hasError ? errorMessage : undefined,
};
}
catch (error) {
return {
command: configCommands.join('\n'),
output: '',
success: false,
error: error instanceof Error ? error.message : 'Unknown error',
};
}
}
stripFlexVNFContext(output) {
const stringsToStrip = [
/admin@[\w-]+\S*/g,
/\[edit.*\]/g,
/\[edit\]/g,
/\[ok\]/g,
/\{master:.*\}/g,
/\{backup:.*\}/g,
/\{line.*\}/g,
/\{primary.*\}/g,
/\{secondary.*\}/g,
];
let result = output;
for (const pattern of stringsToStrip) {
result = result.replace(pattern, '');
}
result = result
.split('\n')
.map(line => line.trim())
.filter(line => line.length > 0)
.join('\n');
return result;
}
async saveConfig() {
try {
const output = await this.commit({ comment: 'Configuration saved via n8n' });
return {
command: 'commit',
output: output,
success: true,
};
}
catch (error) {
throw new Error(`Failed to save configuration: ${error}`);
}
}
}
exports.VersaFlexVNFConnection = (0, no_enable_1.NoEnable)(VersaFlexVNFConnectionBase);
//# sourceMappingURL=versa-connection.js.map