summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSandeepa Singh <sandeepa.singh@ibm.com>2022-01-10 16:49:36 +0300
committerDixsie Wolmers <dixsiew@gmail.com>2022-02-04 17:21:05 +0300
commit05887b50f1d1b08468b401b357faf13f505ee75f (patch)
tree9a016ca5142e43e3ac7f88ecce045048270fcaa0
parentaee27141f4c002306e9a4bf44dc4f9618a5fae62 (diff)
downloadwebui-vue-05887b50f1d1b08468b401b357faf13f505ee75f.tar.xz
Add Key clear page under Operations section
This page will allow privileged user to clear encrypted keys. - Only admin and CE login user will be able to see the page - The UI will be different for both, admin and CE login user(service) - This page is IBM only Signed-off-by: Sandeepa Singh <sandeepa.singh@ibm.com> Change-Id: Ic6fe3454de815629a6b2250daa99ab21f2b316c3
-rw-r--r--src/components/AppNavigation/AppNavigationMixin.js5
-rw-r--r--src/env/components/AppNavigation/ibm.js69
-rw-r--r--src/env/router/ibm.js9
-rw-r--r--src/env/store/ibm.js3
-rw-r--r--src/locales/en-US.json39
-rw-r--r--src/router/routes.js9
-rw-r--r--src/store/index.js2
-rw-r--r--src/store/modules/Operations/KeyClearStore.js25
-rw-r--r--src/views/Operations/KeyClear/KeyClear.vue106
-rw-r--r--src/views/Operations/KeyClear/index.js2
-rw-r--r--tests/unit/__snapshots__/AppNavigation.spec.js.snap18
11 files changed, 258 insertions, 29 deletions
diff --git a/src/components/AppNavigation/AppNavigationMixin.js b/src/components/AppNavigation/AppNavigationMixin.js
index edeabc52..bbbbb1ee 100644
--- a/src/components/AppNavigation/AppNavigationMixin.js
+++ b/src/components/AppNavigation/AppNavigationMixin.js
@@ -77,6 +77,11 @@ const AppNavigationMixin = {
route: '/operations/kvm',
},
{
+ id: 'key-clear',
+ label: this.$t('appNavigation.keyClear'),
+ route: '/operations/key-clear',
+ },
+ {
id: 'firmware',
label: this.$t('appNavigation.firmware'),
route: '/operations/firmware',
diff --git a/src/env/components/AppNavigation/ibm.js b/src/env/components/AppNavigation/ibm.js
index 32f5c9f4..ed84e17a 100644
--- a/src/env/components/AppNavigation/ibm.js
+++ b/src/env/components/AppNavigation/ibm.js
@@ -70,33 +70,7 @@ const AppNavigationMixin = {
id: 'operations',
label: this.$t('appNavigation.operations'),
icon: 'iconControl',
- children: [
- {
- id: 'factory-reset',
- label: this.$t('appNavigation.factoryReset'),
- route: '/operations/factory-reset',
- },
- {
- id: 'firmware',
- label: this.$t('appNavigation.firmware'),
- route: '/operations/firmware',
- },
- {
- id: 'reboot-bmc',
- label: this.$t('appNavigation.rebootBmc'),
- route: '/operations/reboot-bmc',
- },
- {
- id: 'serial-over-lan',
- label: this.$t('appNavigation.serialOverLan'),
- route: '/operations/serial-over-lan',
- },
- {
- id: 'server-power-operations',
- label: this.$t('appNavigation.serverPowerOperations'),
- route: '/operations/server-power-operations',
- },
- ],
+ children: this.operationsNavigationItems(),
},
{
id: 'settings',
@@ -167,6 +141,47 @@ const AppNavigationMixin = {
],
};
},
+ methods: {
+ operationsNavigationItems() {
+ const username = this.$store.getters['global/username'];
+ let operationNavigationItems = [
+ {
+ id: 'factory-reset',
+ label: this.$t('appNavigation.factoryReset'),
+ route: '/operations/factory-reset',
+ },
+ {
+ id: 'firmware',
+ label: this.$t('appNavigation.firmware'),
+ route: '/operations/firmware',
+ },
+ {
+ id: 'reboot-bmc',
+ label: this.$t('appNavigation.rebootBmc'),
+ route: '/operations/reboot-bmc',
+ },
+ {
+ id: 'serial-over-lan',
+ label: this.$t('appNavigation.serialOverLan'),
+ route: '/operations/serial-over-lan',
+ },
+ {
+ id: 'server-power-operations',
+ label: this.$t('appNavigation.serverPowerOperations'),
+ route: '/operations/server-power-operations',
+ },
+ ];
+ let pageKeyClear = {
+ id: 'key-clear',
+ label: this.$t('appNavigation.keyClear'),
+ route: '/operations/key-clear',
+ };
+ if (username === 'service' || username === 'admin') {
+ operationNavigationItems.splice(2, 0, pageKeyClear);
+ }
+ return operationNavigationItems;
+ },
+ },
};
export default AppNavigationMixin;
diff --git a/src/env/router/ibm.js b/src/env/router/ibm.js
index c6ac61f7..0ccf90ba 100644
--- a/src/env/router/ibm.js
+++ b/src/env/router/ibm.js
@@ -19,6 +19,7 @@ import PowerRestorePolicy from '@/views/Settings/PowerRestorePolicy';
import ProfileSettings from '@/views/ProfileSettings';
import RebootBmc from '@/views/Operations/RebootBmc';
import Policies from '@/views/SecurityAndAccess/Policies';
+import KeyClear from '@/views/Operations/KeyClear';
import Sensors from '@/views/HardwareStatus/Sensors';
import SerialOverLan from '@/views/Operations/SerialOverLan';
import SerialOverLanConsole from '@/views/Operations/SerialOverLan/SerialOverLanConsole';
@@ -223,6 +224,14 @@ const routes = [
},
},
{
+ path: '/operations/key-clear',
+ name: 'key-clear',
+ component: KeyClear,
+ meta: {
+ title: i18n.t('appPageTitle.keyClear'),
+ },
+ },
+ {
path: '/operations/reboot-bmc',
name: 'reboot-bmc',
component: RebootBmc,
diff --git a/src/env/store/ibm.js b/src/env/store/ibm.js
index 787f8975..86fc52d1 100644
--- a/src/env/store/ibm.js
+++ b/src/env/store/ibm.js
@@ -1,8 +1,11 @@
import store from '@/store';
import DumpsStore from '@/store/modules/Logs/DumpsStore';
+import KeyClearStore from '@/store/modules/Operations/KeyClearStore';
store.unregisterModule('virtualMedia');
store.registerModule('dumps', DumpsStore);
+store.registerModule('key-clear', KeyClearStore);
+
export default store;
diff --git a/src/locales/en-US.json b/src/locales/en-US.json
index ddc556df..d8df61c0 100644
--- a/src/locales/en-US.json
+++ b/src/locales/en-US.json
@@ -126,7 +126,8 @@
"serverPowerOperations": "@:appPageTitle.serverPowerOperations",
"certificates": "@:appPageTitle.certificates",
"virtualMedia": "@:appPageTitle.virtualMedia",
- "power": "@:appPageTitle.power"
+ "power": "@:appPageTitle.power",
+ "keyClear": "@:appPageTitle.keyClear"
},
"appPageTitle": {
"changePassword": "Change password",
@@ -154,7 +155,8 @@
"serialOverLan": "Serial over LAN (SOL) console",
"serverPowerOperations": "Server power operations",
"certificates": "Certificates",
- "virtualMedia": "Virtual media"
+ "virtualMedia": "Virtual media",
+ "keyClear": "Key clear"
},
"pageChangePassword": {
"changePassword": "Change password",
@@ -444,6 +446,39 @@
"errorEnableIdentifyLed": "Error enabling Identify LED."
}
},
+ "pageKeyClear": {
+ "description": "Securely clear sensitive data on the system",
+ "alert": {
+ "description": "Due to senstivity of the data that will be cleared, verification through physical presence is required to authorize this operation.",
+ "title": "This operation requires physical presence and system reboot"
+ },
+ "form": {
+ "clearAllSetGenesisIPL": "Clear all and set genesis IPL",
+ "clear": "Clear",
+ "clearAllLabel": "Clear all",
+ "clearAllHeperText":"Clear all the sensitive data that is controlled by the platform firmware",
+ "clearHypervisorSystemKeyLabel":"Clear hypervisor system key",
+ "clearHypervisorSystemKeyHelperText":"This indicates the hypervisor to clear the system key.",
+ "clearOperatingSystemKeysLabel":"Clear operating system keys label",
+ "clearOperatingSystemKeysHelperText":"This indicates OPAL to clear the operating system Secure Boot keys.",
+ "clearSystemSecurityKeyLabel":"Clear system security officer key",
+ "clearSystemSecurityKeyHelperText":"This incicates OPAL/PEF to clear teh system security officer keys.",
+ "keyClearOptionsLabel": "Key clear options",
+ "keyClearNotRequested": "Key clear not requested",
+ "none": "None",
+ "setFactoryDefault": "Set factory default"
+ },
+ "modal":{
+ "clear": "Clear keys",
+ "clearAllMessage": "Any encryption keys contained in the selected data will be lost. System will not be able to decrypt any data that requires these keys.",
+ "clearAllTitle": "Warning: This operation is not reversible"
+
+ },
+ "toast":{
+ "selectedKeyClearedError": "Error clearing keys",
+ "selectedKeyClearedSuccess": "Keys cleared successfully"
+ }
+ },
"pageKvm": {
"openNewTab": "Open in new tab",
"buttonCtrlAltDelete": "Send Ctrl+Alt+Delete",
diff --git a/src/router/routes.js b/src/router/routes.js
index b99aac51..3cbdabce 100644
--- a/src/router/routes.js
+++ b/src/router/routes.js
@@ -21,6 +21,7 @@ import PowerRestorePolicy from '@/views/Settings/PowerRestorePolicy';
import ProfileSettings from '@/views/ProfileSettings';
import RebootBmc from '@/views/Operations/RebootBmc';
import Policies from '@/views/SecurityAndAccess/Policies';
+import KeyClear from '@/views/Operations/KeyClear';
import Sensors from '@/views/HardwareStatus/Sensors';
import SerialOverLan from '@/views/Operations/SerialOverLan';
import SerialOverLanConsole from '@/views/Operations/SerialOverLan/SerialOverLanConsole';
@@ -191,6 +192,14 @@ const routes = [
},
},
{
+ path: '/operations/key-clear',
+ name: 'key-clear',
+ component: KeyClear,
+ meta: {
+ title: i18n.t('appPageTitle.keyClear'),
+ },
+ },
+ {
path: '/operations/kvm',
name: 'kvm',
component: Kvm,
diff --git a/src/store/index.js b/src/store/index.js
index d7c1b22d..ba248c58 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -27,6 +27,7 @@ import AssemblyStore from './modules/HardwareStatus/AssemblyStore';
import PostCodeLogsStore from './modules/Logs/PostCodeLogsStore';
import PoliciesStore from './modules/SecurityAndAccess/PoliciesStore';
import FactoryResetStore from './modules/Operations/FactoryResetStore';
+import KeyClearStore from './modules/Operations/KeyClearStore';
import WebSocketPlugin from './plugins/WebSocketPlugin';
import DateTimeStore from './modules/Settings/DateTimeStore';
@@ -67,6 +68,7 @@ export default new Vuex.Store({
virtualMedia: VirtualMediaStore,
policies: PoliciesStore,
factoryReset: FactoryResetStore,
+ keyClear: KeyClearStore,
},
plugins: [WebSocketPlugin],
});
diff --git a/src/store/modules/Operations/KeyClearStore.js b/src/store/modules/Operations/KeyClearStore.js
new file mode 100644
index 00000000..1dc96e0f
--- /dev/null
+++ b/src/store/modules/Operations/KeyClearStore.js
@@ -0,0 +1,25 @@
+import api from '@/store/api';
+import i18n from '@/i18n';
+
+const KeyClearStore = {
+ namespaced: true,
+ actions: {
+ async clearEncryptionKeys(_, selectedKey) {
+ const selectedKeyForClearing = {
+ Attributes: { hb_key_clear_request: selectedKey },
+ };
+ return await api
+ .patch(
+ '/redfish/v1/Systems/system/Bios/Settings',
+ selectedKeyForClearing
+ )
+ .then(() => i18n.t('pageKeyClear.toast.selectedKeyClearedSuccess'))
+ .catch((error) => {
+ console.log('Key clear', error);
+ throw new Error(i18n.t('pageKeyClear.toast.selectedKeyClearedError'));
+ });
+ },
+ },
+};
+
+export default KeyClearStore;
diff --git a/src/views/Operations/KeyClear/KeyClear.vue b/src/views/Operations/KeyClear/KeyClear.vue
new file mode 100644
index 00000000..2524da10
--- /dev/null
+++ b/src/views/Operations/KeyClear/KeyClear.vue
@@ -0,0 +1,106 @@
+<template>
+ <b-container fluid="xl">
+ <page-title :description="$t('pageKeyClear.description')" />
+ <b-row>
+ <b-col md="8" xl="6">
+ <alert variant="info" class="mb-4">
+ <div class="font-weight-bold">
+ {{ $t('pageKeyClear.alert.title') }}
+ </div>
+ <div>
+ {{ $t('pageKeyClear.alert.description') }}
+ </div>
+ </alert>
+ </b-col>
+ </b-row>
+ <!-- Reset Form -->
+ <b-form id="key-clear" @submit.prevent="onKeyClearSubmit(keyOption)">
+ <b-row>
+ <b-col md="8">
+ <b-form-group :label="$t('pageKeyClear.form.keyClearOptionsLabel')">
+ <b-form-radio-group
+ id="key-clear-options"
+ v-model="keyOption"
+ stacked
+ >
+ <b-form-radio class="mb-1" value="NONE">
+ {{ $t('pageKeyClear.form.none') }}
+ </b-form-radio>
+ <b-form-text id="key-clear-not-requested" class="ml-4 mb-3">
+ {{ $t('pageKeyClear.form.keyClearNotRequested') }}
+ </b-form-text>
+ <b-form-radio class="mb-1" value="ALL">
+ {{ $t('pageKeyClear.form.clearAllLabel') }}
+ </b-form-radio>
+ <b-form-text id="clear-all" class="ml-4 mb-3">
+ {{ $t('pageKeyClear.form.clearAllHeperText') }}
+ </b-form-text>
+ <b-form-radio class="mb-1" value="POWERVM_SYSKEY">
+ {{ $t('pageKeyClear.form.clearHypervisorSystemKeyLabel') }}
+ </b-form-radio>
+ <b-form-text id="clear-hypervisor-key" class="ml-4 mb-3">
+ {{ $t('pageKeyClear.form.clearHypervisorSystemKeyHelperText') }}
+ </b-form-text>
+ <template v-if="username == 'service'">
+ <b-form-radio class="mb-1" value="MFG_ALL">
+ {{ $t('pageKeyClear.form.clearAllSetGenesisIPL') }}
+ </b-form-radio>
+ <b-form-radio class="mb-1" value="MFG">
+ {{ $t('pageKeyClear.form.setFactoryDefault') }}
+ </b-form-radio>
+ </template>
+ </b-form-radio-group>
+ </b-form-group>
+ <b-button
+ type="submit"
+ variant="primary"
+ data-test-id="keyClear-button-submit"
+ >
+ {{ $t('pageKeyClear.form.clear') }}
+ </b-button>
+ </b-col>
+ </b-row>
+ </b-form>
+ </b-container>
+</template>
+
+<script>
+import PageTitle from '@/components/Global/PageTitle';
+import BVToastMixin from '@/components/Mixins/BVToastMixin';
+import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin';
+import Alert from '@/components/Global/Alert';
+
+export default {
+ name: 'KeyClear',
+ components: { PageTitle, Alert },
+ mixins: [LoadingBarMixin, BVToastMixin],
+ data() {
+ return {
+ keyOption: 'NONE',
+ username: this.$store.getters['global/username'],
+ };
+ },
+ created() {
+ this.hideLoader();
+ },
+ methods: {
+ onKeyClearSubmit(valueSelected) {
+ this.$bvModal
+ .msgBoxConfirm(this.$t('pageKeyClear.modal.clearAllMessage'), {
+ title: this.$t('pageKeyClear.modal.clearAllTitle'),
+ okTitle: this.$t('pageKeyClear.modal.clear'),
+ okVariant: 'danger',
+ cancelTitle: this.$t('global.action.cancel'),
+ })
+ .then((clearConfirmed) => {
+ if (clearConfirmed) {
+ this.$store
+ .dispatch('keyClear/clearEncryptionKeys', valueSelected)
+ .then((message) => this.successToast(message))
+ .catch(({ message }) => this.errorToast(message));
+ }
+ });
+ },
+ },
+};
+</script>
diff --git a/src/views/Operations/KeyClear/index.js b/src/views/Operations/KeyClear/index.js
new file mode 100644
index 00000000..56de8c4e
--- /dev/null
+++ b/src/views/Operations/KeyClear/index.js
@@ -0,0 +1,2 @@
+import KeyClear from './KeyClear.vue';
+export default KeyClear;
diff --git a/tests/unit/__snapshots__/AppNavigation.spec.js.snap b/tests/unit/__snapshots__/AppNavigation.spec.js.snap
index 37609d39..98628186 100644
--- a/tests/unit/__snapshots__/AppNavigation.spec.js.snap
+++ b/tests/unit/__snapshots__/AppNavigation.spec.js.snap
@@ -314,6 +314,15 @@ exports[`AppNavigation.vue should render correctly 1`] = `
</a>
<a
class="nav-link"
+ data-test-id="nav-item-key-clear"
+ href="#/operations/key-clear"
+ >
+
+ appNavigation.keyClear
+
+ </a>
+ <a
+ class="nav-link"
data-test-id="nav-item-firmware"
href="#/operations/firmware"
>
@@ -975,6 +984,15 @@ exports[`AppNavigation.vue should render with nav-container open 1`] = `
</a>
<a
class="nav-link"
+ data-test-id="nav-item-key-clear"
+ href="#/operations/key-clear"
+ >
+
+ appNavigation.keyClear
+
+ </a>
+ <a
+ class="nav-link"
data-test-id="nav-item-firmware"
href="#/operations/firmware"
>