summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYoshie Muranaka <yoshiemuranaka@gmail.com>2020-12-08 00:04:11 +0300
committerDerick Montague <derick.montague@ibm.com>2021-01-05 22:54:01 +0300
commitf415a0898b6f1f5cee8aa43259e8aedf07d395aa (patch)
treec4cb17fba51d9d4c6caa266081f07b95778abf9d
parent22d4d527af48d87ca70a8766bacc5b1ec0cfe9b7 (diff)
downloadwebui-vue-f415a0898b6f1f5cee8aa43259e8aedf07d395aa.tar.xz
Add DumpsStore API calls
Ties in API requests to the Dumps page and adds ability to: - Create new System or BMC dump - Delete single or multiple BMC dumps. Uses ClearLog service to delete all and DELETE request for single dump deletion Signed-off-by: Yoshie Muranaka <yoshiemuranaka@gmail.com> Change-Id: Iae928fa3b8fab00e549c33c0ab914a4b04de0f40
-rw-r--r--src/assets/styles/bmc/custom/_forms.scss2
-rw-r--r--src/env/components/Dumps/Dumps.vue46
-rw-r--r--src/env/components/Dumps/DumpsForm.vue38
-rw-r--r--src/env/components/Dumps/DumpsModalConfirmation.vue75
-rw-r--r--src/env/store/Dumps/DumpsStore.js91
-rw-r--r--src/locales/en-US.json25
6 files changed, 259 insertions, 18 deletions
diff --git a/src/assets/styles/bmc/custom/_forms.scss b/src/assets/styles/bmc/custom/_forms.scss
index cea5ef50..428a40c2 100644
--- a/src/assets/styles/bmc/custom/_forms.scss
+++ b/src/assets/styles/bmc/custom/_forms.scss
@@ -51,7 +51,7 @@
.custom-select,
.custom-control-label,
.form-control {
- color: theme-color("dark");
+ color: theme-color("dark") !important;
font-size: 1rem;
}
diff --git a/src/env/components/Dumps/Dumps.vue b/src/env/components/Dumps/Dumps.vue
index eba90b7a..3bf5579a 100644
--- a/src/env/components/Dumps/Dumps.vue
+++ b/src/env/components/Dumps/Dumps.vue
@@ -3,14 +3,14 @@
<page-title />
<b-row>
<b-col sm="6" lg="5" xl="4">
- <page-section :section-title="$t('pageDumps.newDump')">
+ <page-section :section-title="$t('pageDumps.initiateDump')">
<dumps-form />
</page-section>
</b-col>
</b-row>
<b-row>
<b-col xl="10">
- <page-section :section-title="$t('pageDumps.dumpHistory')">
+ <page-section :section-title="$t('pageDumps.dumpsAvailableOnBmc')">
<b-row class="align-items-start">
<b-col sm="8" xl="6" class="d-sm-flex align-items-end">
<search
@@ -41,6 +41,7 @@
hover
sort-icon-left
no-sort-reset
+ sort-desc
selectable
no-select-on-click
responsive="md"
@@ -121,6 +122,7 @@ import BVTableSelectableMixin, {
tableHeaderCheckboxModel,
tableHeaderCheckboxIndeterminate,
} from '@/components/Mixins/BVTableSelectableMixin';
+import BVToastMixin from '@/components/Mixins/BVToastMixin';
import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin';
import SearchFilterMixin, {
searchFilter,
@@ -141,6 +143,7 @@ export default {
},
mixins: [
BVTableSelectableMixin,
+ BVToastMixin,
LoadingBarMixin,
SearchFilterMixin,
TableFilterMixin,
@@ -202,7 +205,7 @@ export default {
},
computed: {
dumps() {
- return this.$store.getters['dumps/allDumps'];
+ return this.$store.getters['dumps/bmcDumps'];
},
tableItems() {
return this.dumps.map((item) => {
@@ -246,7 +249,7 @@ export default {
this.filterStartDate = fromDate;
this.filterEndDate = toDate;
},
- onTableRowAction(action) {
+ onTableRowAction(action, dump) {
if (action === 'delete') {
this.$bvModal
.msgBoxConfirm(this.$tc('pageDumps.modal.deleteDumpConfirmation'), {
@@ -255,7 +258,19 @@ export default {
cancelTitle: this.$t('global.action.cancel'),
})
.then((deleteConfrimed) => {
- if (deleteConfrimed); // delete dump
+ if (deleteConfrimed) {
+ this.$store
+ .dispatch('dumps/deleteDumps', [dump])
+ .then((messages) => {
+ messages.forEach(({ type, message }) => {
+ if (type === 'success') {
+ this.successToast(message);
+ } else if (type === 'error') {
+ this.errorToast(message);
+ }
+ });
+ });
+ }
});
}
},
@@ -280,7 +295,26 @@ export default {
}
)
.then((deleteConfrimed) => {
- if (deleteConfrimed); // delete dump
+ if (deleteConfrimed) {
+ if (this.selectedRows.length === this.dumps.length) {
+ this.$store
+ .dispatch('dumps/deleteAllDumps')
+ .then((success) => this.successToast(success))
+ .catch(({ message }) => this.errorToast(message));
+ } else {
+ this.$store
+ .dispatch('dumps/deleteDumps', this.selectedRows)
+ .then((messages) => {
+ messages.forEach(({ type, message }) => {
+ if (type === 'success') {
+ this.successToast(message);
+ } else if (type === 'error') {
+ this.errorToast(message);
+ }
+ });
+ });
+ }
+ }
});
}
},
diff --git a/src/env/components/Dumps/DumpsForm.vue b/src/env/components/Dumps/DumpsForm.vue
index ed81b3a8..9dc8bcb1 100644
--- a/src/env/components/Dumps/DumpsForm.vue
+++ b/src/env/components/Dumps/DumpsForm.vue
@@ -21,20 +21,28 @@
{{ $t('global.form.required') }}
</b-form-invalid-feedback>
</b-form-group>
+ <alert variant="info" class="mb-3" :show="selectedDumpType === 'system'">
+ {{ $t('pageDumps.form.systemDumpInfo') }}
+ </alert>
<b-button variant="primary" type="submit" form="form-new-dump">
- {{ $t('pageDumps.form.createNewDump') }}
+ {{ $t('pageDumps.form.initiateDump') }}
</b-button>
</b-form>
+ <modal-confirmation @ok="createSystemDump" />
</div>
</template>
<script>
import { required } from 'vuelidate/lib/validators';
+import ModalConfirmation from './DumpsModalConfirmation';
+import Alert from '@/components/Global/Alert';
+
import BVToastMixin from '@/components/Mixins/BVToastMixin';
import VuelidateMixin from '@/components/Mixins/VuelidateMixin.js';
export default {
+ components: { Alert, ModalConfirmation },
mixins: [BVToastMixin, VuelidateMixin],
data() {
return {
@@ -54,7 +62,33 @@ export default {
handleSubmit() {
this.$v.$touch();
if (this.$v.$invalid) return;
- this.successToast(this.$t('pageDumps.toast.successStartDump'));
+ if (this.selectedDumpType === 'system') {
+ this.showConfirmationModal();
+ } else {
+ this.$store
+ .dispatch('dumps/createBmcDump')
+ .then(() =>
+ this.infoToast(
+ this.$t('pageDumps.toast.successStartBmcDump'),
+ this.$t('pageDumps.toast.successStartBmcDumpTitle')
+ )
+ )
+ .catch(({ message }) => this.errorToast(message));
+ }
+ },
+ showConfirmationModal() {
+ this.$bvModal.show('modal-confirmation');
+ },
+ createSystemDump() {
+ this.$store
+ .dispatch('dumps/createSystemDump')
+ .then(() =>
+ this.infoToast(
+ this.$t('pageDumps.toast.successStartSystemDump'),
+ this.$t('pageDumps.toast.successStartSystemDumpTitle')
+ )
+ )
+ .catch(({ message }) => this.errorToast(message));
},
},
};
diff --git a/src/env/components/Dumps/DumpsModalConfirmation.vue b/src/env/components/Dumps/DumpsModalConfirmation.vue
new file mode 100644
index 00000000..f8e20cfd
--- /dev/null
+++ b/src/env/components/Dumps/DumpsModalConfirmation.vue
@@ -0,0 +1,75 @@
+<template>
+ <b-modal
+ id="modal-confirmation"
+ ref="modal"
+ :title="$t('pageDumps.modal.initiateSystemDump')"
+ @hidden="resetForm"
+ >
+ <p>
+ <strong>
+ {{ $t('pageDumps.modal.initiateSystemDumpMessage1') }}
+ </strong>
+ </p>
+ <p>
+ {{ $t('pageDumps.modal.initiateSystemDumpMessage2') }}
+ </p>
+ <p>
+ <status-icon status="danger" />
+ {{ $t('pageDumps.modal.initiateSystemDumpMessage3') }}
+ </p>
+ <b-form-checkbox v-model="confirmed" @input="$v.confirmed.$touch()">
+ {{ $t('pageDumps.modal.initiateSystemDumpMessage4') }}
+ </b-form-checkbox>
+ <b-form-invalid-feedback
+ :state="getValidationState($v.confirmed)"
+ role="alert"
+ >
+ {{ $t('global.form.required') }}
+ </b-form-invalid-feedback>
+ <template #modal-footer="{ cancel }">
+ <b-button variant="secondary" @click="cancel()">
+ {{ $t('global.action.cancel') }}
+ </b-button>
+ <b-button variant="danger" @click="handleSubmit">
+ {{ $t('pageDumps.form.initiateDump') }}
+ </b-button>
+ </template>
+ </b-modal>
+</template>
+
+<script>
+import StatusIcon from '@/components/Global/StatusIcon';
+import VuelidateMixin from '@/components/Mixins/VuelidateMixin.js';
+
+export default {
+ components: { StatusIcon },
+ mixins: [VuelidateMixin],
+ data() {
+ return {
+ confirmed: false,
+ };
+ },
+ validations: {
+ confirmed: {
+ mustBeTrue: (value) => value === true,
+ },
+ },
+ methods: {
+ closeModal() {
+ this.$nextTick(() => {
+ this.$refs.modal.hide();
+ });
+ },
+ handleSubmit() {
+ this.$v.$touch();
+ if (this.$v.$invalid) return;
+ this.$emit('ok');
+ this.closeModal();
+ },
+ resetForm() {
+ this.confirmed = false;
+ this.$v.$reset();
+ },
+ },
+};
+</script>
diff --git a/src/env/store/Dumps/DumpsStore.js b/src/env/store/Dumps/DumpsStore.js
index 45f446c0..3b91354b 100644
--- a/src/env/store/Dumps/DumpsStore.js
+++ b/src/env/store/Dumps/DumpsStore.js
@@ -1,4 +1,5 @@
-import api from '@/store/api';
+import api, { getResponseCount } from '@/store/api';
+import i18n from '@/i18n';
const DumpsStore = {
namespaced: true,
@@ -6,16 +7,17 @@ const DumpsStore = {
bmcDumps: [],
},
getters: {
- allDumps: (state) => state.bmcDumps,
+ bmcDumps: (state) => state.bmcDumps,
},
mutations: {
setBmcDumps: (state, dumps) => {
state.bmcDumps = dumps.map((dump) => ({
+ data: dump.AdditionalDataURI,
dateTime: new Date(dump.Created),
dumpType: dump.Name,
id: dump.Id,
+ location: dump['@odata.id'],
size: dump.AdditionalDataSizeBytes,
- data: dump.AdditionalDataURI,
}));
},
},
@@ -26,6 +28,89 @@ const DumpsStore = {
.then(({ data = {} }) => commit('setBmcDumps', data.Members || []))
.catch((error) => console.log(error));
},
+ async createBmcDump() {
+ return await api
+ .post(
+ '/redfish/v1/Managers/bmc/LogServices/Dump/Actions/LogService.CollectDiagnosticData',
+ {
+ DiagnosticDataType: 'Manager',
+ OEMDiagnosticDataType: '',
+ }
+ )
+ .catch((error) => {
+ console.log(error);
+ throw new Error(i18n.t('pageDumps.toast.errorStartBmcDump'));
+ });
+ },
+ async createSystemDump() {
+ return await api
+ .post(
+ '/redfish/v1/Systems/system/LogServices/Dump/Actions/LogService.CollectDiagnosticData',
+ {
+ DiagnosticDataType: 'OEM',
+ OEMDiagnosticDataType: 'System',
+ }
+ )
+ .catch((error) => {
+ console.log(error);
+ throw new Error(i18n.t('pageDumps.toast.errorStartSystemDump'));
+ });
+ },
+ async deleteDumps({ dispatch }, dumps) {
+ const promises = dumps.map(({ location }) =>
+ api.delete(location).catch((error) => {
+ console.log(error);
+ return error;
+ })
+ );
+ return await api
+ .all(promises)
+ .then((response) => {
+ dispatch('getBmcDumps');
+ return response;
+ })
+ .then(
+ api.spread((...responses) => {
+ const { successCount, errorCount } = getResponseCount(responses);
+ const toastMessages = [];
+
+ if (successCount) {
+ const message = i18n.tc(
+ 'pageDumps.toast.successDeleteDump',
+ successCount
+ );
+ toastMessages.push({ type: 'success', message });
+ }
+
+ if (errorCount) {
+ const message = i18n.tc(
+ 'pageDumps.toast.errorDeleteDump',
+ errorCount
+ );
+ toastMessages.push({ type: 'error', message });
+ }
+
+ return toastMessages;
+ })
+ );
+ },
+ async deleteAllDumps({ commit, state }) {
+ const totalDumpCount = state.bmcDumps.length;
+ return await api
+ .post(
+ '/redfish/v1/Managers/bmc/LogServices/Dump/Actions/LogService.ClearLog'
+ )
+ .then(() => {
+ commit('setBmcDumps', []);
+ return i18n.tc('pageDumps.toast.successDeleteDump', totalDumpCount);
+ })
+ .catch((error) => {
+ console.log(error);
+ throw new Error(
+ i18n.tc('pageDumps.toast.errorDeleteDump', totalDumpCount)
+ );
+ });
+ },
},
};
diff --git a/src/locales/en-US.json b/src/locales/en-US.json
index 1d564ca6..ab9d8238 100644
--- a/src/locales/en-US.json
+++ b/src/locales/en-US.json
@@ -201,17 +201,23 @@
}
},
"pageDumps": {
- "dumpHistory": "Dump history",
- "newDump": "New dump",
+ "dumpsAvailableOnBmc": "Dumps available on BMC",
+ "initiateDump": "Initiate dump",
"form": {
"bmcDump": "BMC dump",
- "createNewDump": "Create new dump",
+ "initiateDump": "Initiate dump",
"selectDumpType": "Select dump type",
- "systemDump": "System dump (disruptive)"
+ "systemDump": "System dump (disruptive)",
+ "systemDumpInfo": "System dumps will be offloaded to the operating system and will not appear in the table below."
},
"modal": {
"deleteDump": "Delete dump | Delete dumps",
- "deleteDumpConfirmation": "Are you sure you want to delete %{count} dump? This action cannot be undone. | Are you sure you want to delete %{count} dumps? This action cannot be undone."
+ "deleteDumpConfirmation": "Are you sure you want to delete %{count} dump? This action cannot be undone. | Are you sure you want to delete %{count} dumps? This action cannot be undone.",
+ "initiateSystemDump": "Initiate system dump",
+ "initiateSystemDumpMessage1": "Are you sure?",
+ "initiateSystemDumpMessage2": "You will not be able to initiate any other dumps while a system dump is in progress.",
+ "initiateSystemDumpMessage3": "Initiating a system dump will abnormally terminate all active system partitions.",
+ "initiateSystemDumpMessage4": "Proceed with dump initiation"
},
"table": {
"createdBy": "Created by",
@@ -222,7 +228,14 @@
"size": "Size"
},
"toast": {
- "successStartDump": "Successfully started new dump."
+ "errorDeleteDump": "Error deleting %{count} dump. | Error deleting %{count} dumps.",
+ "errorStartBmcDump": "Error starting new BMC dump.",
+ "errorStartSystemDump": "Error starting new System dump.",
+ "successDeleteDump": "Successfully deleted %{count} dump. | Successfully deleted %{count} dumps.",
+ "successStartBmcDump": "The dump will take some time to complete. Refresh the application to see the completed dump in the table.",
+ "successStartBmcDumpTitle": "BMC dump started",
+ "successStartSystemDump": "The dump will take some time to complete. The dump will be offloaded to the operating system.",
+ "successStartSystemDumpTitle": "System dump started"
}
},
"pageEventLogs": {