summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMateusz Gapski <mateuszx.gapski@intel.com>2020-07-09 10:21:33 +0300
committerDerick Montague <derick.montague@ibm.com>2020-07-22 01:04:15 +0300
commit632de22a066e7a1224d2c490962530389273c717 (patch)
tree6452cd27736c1979f243b8a02d1996bac6c8dc3d
parent2c98b0954ac5c50ea9c77e9ee780e3dee4fcdad8 (diff)
downloadwebui-vue-632de22a066e7a1224d2c490962530389273c717.tar.xz
KVM console
- The kvm console with using novnc library Signed-off-by: Mateusz Gapski <mateuszx.gapski@intel.com> Change-Id: Icfb7643595d8c17231ca3671753d6de971525bd3
-rw-r--r--package-lock.json5
-rw-r--r--package.json1
-rw-r--r--src/components/AppNavigation/AppNavigation.vue3
-rw-r--r--src/locales/en-US.json11
-rw-r--r--src/router/index.js20
-rw-r--r--src/views/Control/Kvm/Kvm.vue56
-rw-r--r--src/views/Control/Kvm/KvmConsole.vue74
-rw-r--r--src/views/Control/Kvm/index.js2
8 files changed, 170 insertions, 2 deletions
diff --git a/package-lock.json b/package-lock.json
index f99d5165..72167091 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1527,6 +1527,11 @@
"fastq": "^1.6.0"
}
},
+ "@novnc/novnc": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@novnc/novnc/-/novnc-1.2.0.tgz",
+ "integrity": "sha512-FaUckOedGhSbwQBXk/KGyxKt9ngskg4wPw6ghbHWXOUEmQscAZr3467lTU5DSfppwHJt5k+lQiHoeYUuY90l2Q=="
+ },
"@nuxt/opencollective": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/@nuxt/opencollective/-/opencollective-0.3.0.tgz",
diff --git a/package.json b/package.json
index 8c90675e..9942f12d 100644
--- a/package.json
+++ b/package.json
@@ -15,6 +15,7 @@
},
"dependencies": {
"@carbon/icons-vue": "10.6.1",
+ "@novnc/novnc": "1.2.0",
"axios": "0.19.0",
"bootstrap": "4.4.1",
"bootstrap-vue": "2.12.0",
diff --git a/src/components/AppNavigation/AppNavigation.vue b/src/components/AppNavigation/AppNavigation.vue
index 37f0f717..2b773a04 100644
--- a/src/components/AppNavigation/AppNavigation.vue
+++ b/src/components/AppNavigation/AppNavigation.vue
@@ -34,6 +34,9 @@
<icon-expand class="icon-expand" />
</b-button>
<b-collapse id="control-menu" tag="ul" class="nav-item__nav">
+ <b-nav-item to="/control/kvm">
+ {{ $t('appNavigation.kvm') }}
+ </b-nav-item>
<b-nav-item to="/control/manage-power-usage">
{{ $t('appNavigation.managePowerUsage') }}
</b-nav-item>
diff --git a/src/locales/en-US.json b/src/locales/en-US.json
index 02600f4c..e6c508b2 100644
--- a/src/locales/en-US.json
+++ b/src/locales/en-US.json
@@ -79,6 +79,7 @@
"firmware": "@:appPageTitle.firmware",
"hardwareStatus": "@:appPageTitle.hardwareStatus",
"health": "Health",
+ "kvm": "@:appPageTitle.kvm",
"ldap": "@:appPageTitle.ldap",
"localUserManagement": "@:appPageTitle.localUserManagement",
"managePowerUsage": "@:appPageTitle.managePowerUsage",
@@ -99,6 +100,7 @@
"eventLogs": "Event logs",
"firmware": "Firmware",
"hardwareStatus": "Hardware status",
+ "kvm": "KVM",
"ldap": "LDAP",
"localUserManagement": "Local user management",
"login": "Login",
@@ -198,6 +200,15 @@
"uuid": "UUID"
}
},
+ "pageKvm": {
+ "openNewTab": "Open in new tab",
+ "subTitle": "Access the KVM console",
+ "buttonCtrlAltDelete": "Send Ctrl+Alt+Delete",
+ "status": "Status",
+ "connected": "Connected",
+ "connecting": "Connecting",
+ "disconnected": "Disconnected"
+ },
"pageLdap": {
"pageDescription": "Configure LDAP settings and manage role groups",
"roleGroups": "Role groups",
diff --git a/src/router/index.js b/src/router/index.js
index 0da37fa8..eace2bb6 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -90,6 +90,14 @@ const routes = [
}
},
{
+ path: '/control/kvm',
+ name: 'kvm',
+ component: () => import('@/views/Control/Kvm'),
+ meta: {
+ title: 'appPageTitle.kvm'
+ }
+ },
+ {
path: '/control/manage-power-usage',
name: 'manage-power-usage',
component: () => import('@/views/Control/ManagePowerUsage'),
@@ -178,13 +186,21 @@ const routes = [
},
children: [
{
- path: '/console/serial-over-lan-console',
- name: 'serial-over-lan',
+ path: 'serial-over-lan-console',
+ name: 'serial-over-lan-console',
component: () =>
import('@/views/Control/SerialOverLan/SerialOverLanConsole'),
meta: {
title: 'appPageTitle.serialOverLan'
}
+ },
+ {
+ path: 'kvm',
+ name: 'kvm-console',
+ component: () => import('@/views/Control/Kvm/KvmConsole'),
+ meta: {
+ title: 'appPageTitle.kvm'
+ }
}
]
}
diff --git a/src/views/Control/Kvm/Kvm.vue b/src/views/Control/Kvm/Kvm.vue
new file mode 100644
index 00000000..195948b0
--- /dev/null
+++ b/src/views/Control/Kvm/Kvm.vue
@@ -0,0 +1,56 @@
+<template>
+ <b-container fluid="xl">
+ <page-title />
+
+ <page-section :section-title="$t('pageKvm.subTitle')">
+ <div>
+ <b-button
+ variant="link"
+ type="button"
+ class="button-launch"
+ @click="openConsoleWindow()"
+ >
+ <icon-launch />
+ {{ $t('pageKvm.openNewTab') }}
+ </b-button>
+ </div>
+ <div class="terminal-container">
+ <kvm-console />
+ </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 KvmConsole from './KvmConsole';
+
+export default {
+ name: 'Kvm',
+ components: { IconLaunch, PageSection, PageTitle, KvmConsole },
+ methods: {
+ openConsoleWindow() {
+ window.open(
+ '#/console/kvm',
+ '_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;
+}
+.button-launch {
+ padding-left: 0px;
+}
+
+.terminal-container {
+ width: 100%;
+}
+</style>
diff --git a/src/views/Control/Kvm/KvmConsole.vue b/src/views/Control/Kvm/KvmConsole.vue
new file mode 100644
index 00000000..080f72e8
--- /dev/null
+++ b/src/views/Control/Kvm/KvmConsole.vue
@@ -0,0 +1,74 @@
+<template>
+ <div>
+ <span class="kvm-status">{{ $t('pageKvm.status') }}: {{ status }}</span>
+ <b-button
+ v-if="isConnected"
+ variant="link"
+ type="button"
+ class="button-launch button-ctrl-alt-delete"
+ @click="sendCtrlAltDel"
+ >
+ {{ $t('pageKvm.buttonCtrlAltDelete') }}
+ </b-button>
+ <div v-show="isConnected" id="terminal" ref="panel"></div>
+ </div>
+</template>
+
+<script>
+import RFB from '@novnc/novnc/core/rfb';
+
+export default {
+ name: 'KvmConsole',
+ data() {
+ return {
+ rfb: null,
+ isConnected: false,
+ status: this.$t('pageKvm.connecting')
+ };
+ },
+ mounted() {
+ this.openTerminal();
+ },
+ methods: {
+ sendCtrlAltDel() {
+ this.rfb.sendCtrlAltDel();
+ },
+ openTerminal() {
+ const token = this.$store.getters['authentication/token'];
+ this.rfb = new RFB(
+ this.$refs.panel,
+ `wss://${window.location.host}/kvm/0`,
+ { wsProtocols: [token] }
+ );
+
+ this.rfb.scaleViewport = true;
+ const that = this;
+ this.rfb.addEventListener('connect', () => {
+ that.isConnected = true;
+ that.status = this.$t('pageKvm.connected');
+ });
+
+ this.rfb.addEventListener('disconnect', () => {
+ that.status = this.$t('pageKvm.disconnected');
+ });
+ }
+ }
+};
+</script>
+
+<style scoped lang="scss">
+@import 'src/assets/styles/helpers';
+#terminal {
+ height: calc(100vh - 42px);
+}
+
+.button-ctrl-alt-delete {
+ float: right;
+}
+
+.kvm-status {
+ padding-top: $spacer / 2;
+ padding-left: $spacer / 4;
+ display: inline-block;
+}
+</style>
diff --git a/src/views/Control/Kvm/index.js b/src/views/Control/Kvm/index.js
new file mode 100644
index 00000000..ac4f9667
--- /dev/null
+++ b/src/views/Control/Kvm/index.js
@@ -0,0 +1,2 @@
+import Kvm from './Kvm.vue';
+export default Kvm;