diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/components/AppNavigation/AppNavigationMixin.js | 5 | ||||
-rw-r--r-- | src/env/components/AppNavigation/ibm.js | 69 | ||||
-rw-r--r-- | src/env/router/ibm.js | 9 | ||||
-rw-r--r-- | src/env/store/ibm.js | 3 | ||||
-rw-r--r-- | src/locales/en-US.json | 39 | ||||
-rw-r--r-- | src/router/routes.js | 9 | ||||
-rw-r--r-- | src/store/index.js | 2 | ||||
-rw-r--r-- | src/store/modules/Operations/KeyClearStore.js | 25 | ||||
-rw-r--r-- | src/views/Operations/KeyClear/KeyClear.vue | 106 | ||||
-rw-r--r-- | src/views/Operations/KeyClear/index.js | 2 |
10 files changed, 240 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; |