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 41e91070..8800de06 100644
--- a/electron-builder.yml
+++ b/electron-builder.yml
@@ -16,6 +16,7 @@ files:
- sentry.js
- installed-software.js
- local-server.js
+ - console-executor.js
- package.json
extraFiles:
diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts
index 683f4f88..9da6cfde 100644
--- a/src/app/app-routing.module.ts
+++ b/src/app/app-routing.module.ts
@@ -51,6 +51,7 @@ import { CopyIosTemplateComponent } from './components/preferences/dynamips/copy
import { CopyDockerTemplateComponent } from './components/preferences/docker/copy-docker-template/copy-docker-template.component';
import { CopyIouTemplateComponent } from './components/preferences/ios-on-unix/copy-iou-template/copy-iou-template.component';
import { ListOfSnapshotsComponent } from './components/snapshots/list-of-snapshots/list-of-snapshots.component';
+import { ConsoleComponent } from './components/settings/console/console.component';
const routes: Routes = [
{
@@ -62,6 +63,7 @@ const routes: Routes = [
{ path: 'bundled', component: BundledServerFinderComponent },
{ path: 'server/:server_id/projects', component: ProjectsComponent },
{ path: 'settings', component: SettingsComponent },
+ { path: 'settings/console', component: ConsoleComponent },
{ path: 'installed-software', component: InstalledSoftwareComponent },
{ path: 'server/:server_id/project/:project_id/snapshots', component: ListOfSnapshotsComponent },
{ path: 'server/:server_id/preferences', component: PreferencesComponent },
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index eab5be9e..b8f48dd8 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -168,6 +168,9 @@ 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';
+import { ConsoleComponent } from './components/settings/console/console.component';
import { NodesMenuComponent } from './components/project-map/nodes-menu/nodes-menu.component';
import { PacketFiltersActionComponent } from './components/project-map/context-menu/actions/packet-filters-action/packet-filters-action.component';
import { PacketFiltersDialogComponent } from './components/project-map/packet-capturing/packet-filters/packet-filters.component';
@@ -291,6 +294,8 @@ if (environment.production) {
NameFilter,
ListOfSnapshotsComponent,
CustomAdaptersComponent,
+ ConsoleDeviceActionComponent,
+ ConsoleComponent,
NodesMenuComponent
],
imports: [
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 8d778210..47ddcf68 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 @@