diff --git a/console-executor.js b/console-executor.js
new file mode 100644
index 00000000..964f43da
--- /dev/null
+++ b/console-executor.js
@@ -0,0 +1,33 @@
+const { spawn } = require('child_process');
+
+exports.openConsole = async (consoleRequest) => {
+ const genericConsoleCommand = 'xfce4-terminal --tab -T "%d" -e "telnet %h %p"';
+ const command = prepareCommand(genericConsoleCommand, consoleRequest);
+ console.log(`Starting console with command: '${command}'`);
+
+ let consoleProcess = spawn(command, [], {
+ shell :true
+ });
+
+ consoleProcess.stdout.on('data', (data) => {
+ console.log(`Console is producing: ${data.toString()}`);
+ });
+}
+
+
+function prepareCommand(consoleCommand, consoleRequest) {
+ const mapping = {
+ h: consoleRequest.host,
+ p: consoleRequest.port,
+ d: consoleRequest.name,
+ i: consoleRequest.project_id,
+ n: consoleRequest.node_id,
+ c: consoleRequest.server_url
+ };
+
+ for(var key in mapping) {
+ const regExp = new RegExp(`%${key}`, 'g');
+ consoleCommand = consoleCommand.replace(regExp, mapping[key]);
+ }
+ return consoleCommand;
+}
\ No newline at end of file
diff --git a/electron-builder.yml b/electron-builder.yml
index 3c465a61..fdaee391 100644
--- a/electron-builder.yml
+++ b/electron-builder.yml
@@ -15,6 +15,7 @@ files:
- sentry.js
- installed-software.js
- local-server.js
+ - console-executor.js
- package.json
extraFiles:
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 223999cc..586395d3 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -168,6 +168,7 @@ import { ListOfSnapshotsComponent } from './components/snapshots/list-of-snapsho
import { DateFilter } from './filters/dateFilter.pipe';
import { NameFilter } from './filters/nameFilter.pipe';
import { CustomAdaptersComponent } from './components/preferences/common/custom-adapters/custom-adapters.component';
+import { ConsoleDeviceActionComponent } from './components/project-map/context-menu/actions/console-device-action/console-device-action.component';
if (environment.production) {
Raven.config('https://b2b1cfd9b043491eb6b566fd8acee358@sentry.io/842726', {
@@ -273,7 +274,8 @@ if (environment.production) {
DateFilter,
NameFilter,
ListOfSnapshotsComponent,
- CustomAdaptersComponent
+ CustomAdaptersComponent,
+ ConsoleDeviceActionComponent
],
imports: [
BrowserModule,
diff --git a/src/app/components/project-map/context-menu/actions/console-device-action/console-device-action.component.html b/src/app/components/project-map/context-menu/actions/console-device-action/console-device-action.component.html
new file mode 100644
index 00000000..4ee59fbf
--- /dev/null
+++ b/src/app/components/project-map/context-menu/actions/console-device-action/console-device-action.component.html
@@ -0,0 +1,4 @@
+
diff --git a/src/app/components/project-map/context-menu/actions/console-device-action/console-device-action.component.spec.ts b/src/app/components/project-map/context-menu/actions/console-device-action/console-device-action.component.spec.ts
new file mode 100644
index 00000000..f254ff09
--- /dev/null
+++ b/src/app/components/project-map/context-menu/actions/console-device-action/console-device-action.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ConsoleDeviceActionComponent } from './console-device-action.component';
+
+describe('ConsoleDeviceActionComponent', () => {
+ let component: ConsoleDeviceActionComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ ConsoleDeviceActionComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(ConsoleDeviceActionComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/components/project-map/context-menu/actions/console-device-action/console-device-action.component.ts b/src/app/components/project-map/context-menu/actions/console-device-action/console-device-action.component.ts
new file mode 100644
index 00000000..46bd67b7
--- /dev/null
+++ b/src/app/components/project-map/context-menu/actions/console-device-action/console-device-action.component.ts
@@ -0,0 +1,43 @@
+import { Component, OnInit, Input } from '@angular/core';
+import { Node } from '../../../../../cartography/models/node';
+import { Server } from '../../../../../models/server';
+import { ElectronService } from 'ngx-electron';
+import { Project } from '../../../../../models/project';
+import { ServerService } from '../../../../../services/server.service';
+
+@Component({
+ selector: 'app-console-device-action',
+ templateUrl: './console-device-action.component.html'
+})
+export class ConsoleDeviceActionComponent implements OnInit {
+ @Input() server: Server;
+ @Input() project: Project;
+ @Input() nodes: Node[];
+
+ constructor(
+ private electronService: ElectronService,
+ private serverService: ServerService
+ ) { }
+
+ ngOnInit() {
+ }
+
+ async console() {
+ for(var node of this.nodes) {
+ const consoleRequest = {
+ type: node.console_type,
+ host: node.console_host,
+ port: node.console,
+ name: node.name,
+ project_id: this.project.project_id,
+ node_id: node.node_id,
+ server_url: this.serverService.getServerUrl(this.server)
+ };
+ await this.openConsole(consoleRequest);
+ }
+ }
+
+ async openConsole(request) {
+ return await this.electronService.remote.require('./console-executor.js').openConsole(request);
+ }
+}
diff --git a/src/app/components/project-map/context-menu/context-menu.component.html b/src/app/components/project-map/context-menu/context-menu.component.html
index 0060c9f1..af129f3c 100644
--- a/src/app/components/project-map/context-menu/context-menu.component.html
+++ b/src/app/components/project-map/context-menu/context-menu.component.html
@@ -3,6 +3,12 @@