summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--package-lock.json15
-rw-r--r--package.json5
-rw-r--r--src/components/AppNavigation/AppNavigation.vue3
-rw-r--r--src/layouts/ConsoleLayout.vue9
-rw-r--r--src/locales/en-US.json7
-rw-r--r--src/router/index.js27
-rw-r--r--src/views/Control/SerialOverLan/SerialOverLan.vue55
-rw-r--r--src/views/Control/SerialOverLan/SerialOverLanConsole.vue74
-rw-r--r--src/views/Control/SerialOverLan/index.js2
9 files changed, 196 insertions, 1 deletions
diff --git a/package-lock.json b/package-lock.json
index 933f86cc..f99d5165 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -18595,6 +18595,21 @@
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
"dev": true
},
+ "xterm": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/xterm/-/xterm-4.6.0.tgz",
+ "integrity": "sha512-98211RIDrAECqpsxs6gbilwMcxLtxSDIvtzZUIqP1xIByXtuccJ4pmMhHGJATZeEGe/reARPMqwPINK8T7jGZg=="
+ },
+ "xterm-addon-attach": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/xterm-addon-attach/-/xterm-addon-attach-0.6.0.tgz",
+ "integrity": "sha512-Mo8r3HTjI/EZfczVCwRU6jh438B4WLXxdFO86OB7bx0jGhwh2GdF4ifx/rP+OB+Cb2vmLhhVIZ00/7x3YSP3dg=="
+ },
+ "xterm-addon-fit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/xterm-addon-fit/-/xterm-addon-fit-0.4.0.tgz",
+ "integrity": "sha512-p4BESuV/g2L6pZzFHpeNLLnep9mp/DkF3qrPglMiucSFtD8iJxtMufEoEJbN8LZwB4i+8PFpFvVuFrGOSpW05w=="
+ },
"y18n": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
diff --git a/package.json b/package.json
index 5482f548..8c90675e 100644
--- a/package.json
+++ b/package.json
@@ -25,7 +25,10 @@
"vue-i18n": "8.15.3",
"vue-router": "3.1.3",
"vuelidate": "0.7.5",
- "vuex": "3.0.1"
+ "vuex": "3.0.1",
+ "xterm": "4.6.0",
+ "xterm-addon-attach": "0.6.0",
+ "xterm-addon-fit": "0.4.0"
},
"devDependencies": {
"@kazupon/vue-i18n-loader": "0.3.0",
diff --git a/src/components/AppNavigation/AppNavigation.vue b/src/components/AppNavigation/AppNavigation.vue
index 9c5295ad..1dfba11e 100644
--- a/src/components/AppNavigation/AppNavigation.vue
+++ b/src/components/AppNavigation/AppNavigation.vue
@@ -40,6 +40,9 @@
<b-nav-item to="/control/reboot-bmc">
{{ $t('appNavigation.rebootBmc') }}
</b-nav-item>
+ <b-nav-item to="/control/serial-over-lan">
+ {{ $t('appNavigation.serialOverLan') }}
+ </b-nav-item>
<b-nav-item to="/control/server-led">
{{ $t('appNavigation.serverLed') }}
</b-nav-item>
diff --git a/src/layouts/ConsoleLayout.vue b/src/layouts/ConsoleLayout.vue
new file mode 100644
index 00000000..99f8d9f5
--- /dev/null
+++ b/src/layouts/ConsoleLayout.vue
@@ -0,0 +1,9 @@
+<template>
+ <router-view />
+</template>
+
+<script>
+export default {
+ name: 'Console'
+};
+</script>
diff --git a/src/locales/en-US.json b/src/locales/en-US.json
index f2390589..f0494c76 100644
--- a/src/locales/en-US.json
+++ b/src/locales/en-US.json
@@ -85,6 +85,7 @@
"primaryNavigation": "Primary navigation",
"rebootBmc": "@:appPageTitle.rebootBmc",
"sensors": "@:appPageTitle.sensors",
+ "serialOverLan": "@:appPageTitle.serialOverLan",
"serverLed": "@:appPageTitle.serverLed",
"serverPowerOperations": "@:appPageTitle.serverPowerOperations",
"snmpSettings": "@:appPageTitle.snmpSettings",
@@ -103,6 +104,7 @@
"profileSettings":"Profile settings",
"rebootBmc": "Reboot BMC",
"sensors": "Sensors",
+ "serialOverLan": "Serial over LAN console",
"serverLed": "Server LED",
"serverPowerOperations": "Server power operations",
"snmpSettings": "SNMP settings",
@@ -388,6 +390,11 @@
"upperCritical": "Upper critical"
}
},
+ "pageSerialoverLAN": {
+ "openNewTab": "Open in new tab",
+ "subTitle": "Access the Serial over LAN console",
+ "subTitleDesc": "The Serial over LAN (SoL) console redirects the output of the server's serial port to a browser window on your workstation."
+ },
"pageServerLed": {
"serverLedSubTitle": "Server indicator LED",
"serverLedTitle": "LED light control",
diff --git a/src/router/index.js b/src/router/index.js
index 73f31861..a3d28063 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -3,6 +3,7 @@ import VueRouter from 'vue-router';
import store from '../store/index';
import AppLayout from '../layouts/AppLayout.vue';
import LoginLayout from '@/layouts/LoginLayout';
+import ConsoleLayout from '@/layouts/ConsoleLayout.vue';
Vue.use(VueRouter);
@@ -113,6 +114,14 @@ const routes = [
}
},
{
+ path: '/control/serial-over-lan',
+ name: 'serial-over-lan',
+ component: () => import('@/views/Control/SerialOverLan'),
+ meta: {
+ title: 'appPageTitle.serialOverLan'
+ }
+ },
+ {
path: '/control/server-power-operations',
name: 'server-power-operations',
component: () => import('@/views/Control/ServerPowerOperations'),
@@ -143,6 +152,24 @@ const routes = [
}
}
]
+ },
+ {
+ path: '/console',
+ component: ConsoleLayout,
+ meta: {
+ requiresAuth: true
+ },
+ children: [
+ {
+ path: '/console/serial-over-lan-console',
+ name: 'serial-over-lan',
+ component: () =>
+ import('@/views/Control/SerialOverLan/SerialOverLanConsole'),
+ meta: {
+ title: 'appPageTitle.serialOverLan'
+ }
+ }
+ ]
}
];
diff --git a/src/views/Control/SerialOverLan/SerialOverLan.vue b/src/views/Control/SerialOverLan/SerialOverLan.vue
new file mode 100644
index 00000000..61f91e0e
--- /dev/null
+++ b/src/views/Control/SerialOverLan/SerialOverLan.vue
@@ -0,0 +1,55 @@
+<template>
+ <b-container fluid="xl">
+ <page-title />
+
+ <page-section :section-title="$t('pageSerialoverLAN.subTitle')">
+ <p>{{ $t('pageSerialoverLAN.subTitleDesc') }}</p>
+
+ <div class="terminal-container">
+ <serial-over-lan-console />
+ </div>
+ <div class="text-right">
+ <b-button
+ variant="link"
+ type="button"
+ class="button-launch"
+ @click="openConsoleWindow()"
+ >
+ <icon-launch />
+
+ {{ $t('pageSerialoverLAN.openNewTab') }}
+ </b-button>
+ </div>
+ </page-section>
+ </b-container>
+</template>
+
+<script>
+import IconLaunch from '@carbon/icons-vue/es/launch/32';
+import PageTitle from '@/components/Global/PageTitle';
+import PageSection from '@/components/Global/PageSection';
+import SerialOverLanConsole from './SerialOverLanConsole';
+
+export default {
+ name: 'SerialOverLan',
+ components: { IconLaunch, PageSection, PageTitle, SerialOverLanConsole },
+ methods: {
+ openConsoleWindow() {
+ window.open(
+ '#/console/serial-over-lan-console',
+ '_blank',
+ 'directories=no,titlebar=no,toolbar=no,location=no,status=no,menubar=no,scrollbars=no,resizable=yes,width=600,height=550'
+ );
+ }
+ }
+};
+</script>
+
+<style scoped>
+.button-launch > svg {
+ height: 25px;
+}
+.terminal-container {
+ width: 100%;
+}
+</style>
diff --git a/src/views/Control/SerialOverLan/SerialOverLanConsole.vue b/src/views/Control/SerialOverLan/SerialOverLanConsole.vue
new file mode 100644
index 00000000..69ccf8df
--- /dev/null
+++ b/src/views/Control/SerialOverLan/SerialOverLanConsole.vue
@@ -0,0 +1,74 @@
+<template>
+ <div id="terminal" ref="panel"></div>
+</template>
+
+<script>
+import { AttachAddon } from 'xterm-addon-attach';
+import { FitAddon } from 'xterm-addon-fit';
+import { Terminal } from 'xterm';
+
+export default {
+ name: 'SerialOverLanConsole',
+ mounted() {
+ this.openTerminal();
+ },
+ methods: {
+ openTerminal() {
+ const token = this.$store.getters['authentication/token'];
+
+ const ws = new WebSocket(`wss://${window.location.host}/console0`, [
+ token
+ ]);
+
+ // Refer https://github.com/xtermjs/xterm.js/ for xterm implementation and addons.
+
+ const term = new Terminal({
+ fontSize: 15,
+ fontFamily:
+ 'SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace'
+ });
+
+ const attachAddon = new AttachAddon(ws);
+ term.loadAddon(attachAddon);
+
+ const fitAddon = new FitAddon();
+ term.loadAddon(fitAddon);
+
+ const SOL_THEME = {
+ background: '#19273c',
+ cursor: 'rgba(83, 146, 255, .5)',
+ scrollbar: 'rgba(83, 146, 255, .5)'
+ };
+ term.setOption('theme', SOL_THEME);
+
+ term.open(this.$refs.panel);
+ fitAddon.fit();
+
+ try {
+ ws.onopen = function() {
+ console.log('websocket console0/ opened');
+ };
+ ws.onclose = function(event) {
+ console.log(
+ 'websocket console0/ closed. code: ' +
+ event.code +
+ ' reason: ' +
+ event.reason
+ );
+ };
+ } catch (error) {
+ console.log(error);
+ }
+ }
+ }
+};
+</script>
+
+<style scoped>
+@import '~xterm/css/xterm.css';
+
+#terminal {
+ height: 25em;
+ overflow: hidden;
+}
+</style>
diff --git a/src/views/Control/SerialOverLan/index.js b/src/views/Control/SerialOverLan/index.js
new file mode 100644
index 00000000..7c8bc7c0
--- /dev/null
+++ b/src/views/Control/SerialOverLan/index.js
@@ -0,0 +1,2 @@
+import SerialOverLan from './SerialOverLan.vue';
+export default SerialOverLan;