diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/components/AppNavigation/AppNavigation.vue | 3 | ||||
-rw-r--r-- | src/layouts/ConsoleLayout.vue | 9 | ||||
-rw-r--r-- | src/locales/en-US.json | 7 | ||||
-rw-r--r-- | src/router/index.js | 27 | ||||
-rw-r--r-- | src/views/Control/SerialOverLan/SerialOverLan.vue | 55 | ||||
-rw-r--r-- | src/views/Control/SerialOverLan/SerialOverLanConsole.vue | 74 | ||||
-rw-r--r-- | src/views/Control/SerialOverLan/index.js | 2 |
7 files changed, 177 insertions, 0 deletions
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; |