diff options
Diffstat (limited to 'src/views/Operations/ServerPowerOperations')
3 files changed, 402 insertions, 0 deletions
diff --git a/src/views/Operations/ServerPowerOperations/BootSettings.vue b/src/views/Operations/ServerPowerOperations/BootSettings.vue new file mode 100644 index 00000000..efd8d347 --- /dev/null +++ b/src/views/Operations/ServerPowerOperations/BootSettings.vue @@ -0,0 +1,140 @@ +<template> + <div class="form-background p-3"> + <b-form novalidate @submit.prevent="handleSubmit"> + <b-form-group + :label=" + $t('pageServerPowerOperations.bootSettings.bootSettingsOverride') + " + label-for="boot-option" + class="mb-3" + > + <b-form-select + id="boot-option" + v-model="form.bootOption" + :disabled="bootSourceOptions.length === 0" + :options="bootSourceOptions" + @change="onChangeSelect" + > + </b-form-select> + </b-form-group> + <b-form-checkbox + v-model="form.oneTimeBoot" + class="mb-4" + :disabled="form.bootOption === 'None'" + @change="$v.form.oneTimeBoot.$touch()" + > + {{ $t('pageServerPowerOperations.bootSettings.enableOneTimeBoot') }} + </b-form-checkbox> + <b-form-group + :label="$t('pageServerPowerOperations.bootSettings.tpmRequiredPolicy')" + > + <b-form-text id="tpm-required-policy-help-block"> + {{ + $t('pageServerPowerOperations.bootSettings.tpmRequiredPolicyHelper') + }} + </b-form-text> + <b-form-checkbox + id="tpm-required-policy" + v-model="form.tpmPolicyOn" + aria-describedby="tpm-required-policy-help-block" + @change="$v.form.tpmPolicyOn.$touch()" + > + {{ $t('global.status.enabled') }} + </b-form-checkbox> + </b-form-group> + <b-button variant="primary" type="submit" class="mb-3"> + {{ $t('global.action.save') }} + </b-button> + </b-form> + </div> +</template> + +<script> +import { mapState } from 'vuex'; +import BVToastMixin from '@/components/Mixins/BVToastMixin'; +import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin'; + +export default { + name: 'BootSettings', + mixins: [BVToastMixin, LoadingBarMixin], + data() { + return { + form: { + bootOption: this.$store.getters['serverBootSettings/bootSource'], + oneTimeBoot: this.$store.getters['serverBootSettings/overrideEnabled'], + tpmPolicyOn: this.$store.getters['serverBootSettings/tpmEnabled'], + }, + }; + }, + computed: { + ...mapState('serverBootSettings', [ + 'bootSourceOptions', + 'bootSource', + 'overrideEnabled', + 'tpmEnabled', + ]), + }, + watch: { + bootSource: function (value) { + this.form.bootOption = value; + }, + overrideEnabled: function (value) { + this.form.oneTimeBoot = value; + }, + tpmEnabled: function (value) { + this.form.tpmPolicyOn = value; + }, + }, + validations: { + // Empty validations to leverage vuelidate form states + // to check for changed values + form: { + bootOption: {}, + oneTimeBoot: {}, + tpmPolicyOn: {}, + }, + }, + created() { + this.$store + .dispatch('serverBootSettings/getTpmPolicy') + .finally(() => + this.$root.$emit('server-power-operations-boot-settings-complete') + ); + }, + methods: { + handleSubmit() { + this.startLoader(); + const bootSettingsChanged = + this.$v.form.bootOption.$dirty || this.$v.form.oneTimeBoot.$dirty; + const tpmPolicyChanged = this.$v.form.tpmPolicyOn.$dirty; + let settings; + let bootSource = null; + let overrideEnabled = null; + let tpmEnabled = null; + + if (bootSettingsChanged) { + // If bootSource or overrideEnabled changed get + // both current values to send with request + bootSource = this.form.bootOption; + overrideEnabled = this.form.oneTimeBoot; + } + if (tpmPolicyChanged) tpmEnabled = this.form.tpmPolicyOn; + settings = { bootSource, overrideEnabled, tpmEnabled }; + + this.$store + .dispatch('serverBootSettings/saveSettings', settings) + .then((message) => this.successToast(message)) + .catch(({ message }) => this.errorToast(message)) + .finally(() => { + this.$v.form.$reset(); + this.endLoader(); + }); + }, + onChangeSelect(selectedOption) { + this.$v.form.bootOption.$touch(); + // Disable one time boot if selected boot option is 'None' + if (selectedOption === 'None') this.form.oneTimeBoot = false; + }, + }, +}; +</script> diff --git a/src/views/Operations/ServerPowerOperations/ServerPowerOperations.vue b/src/views/Operations/ServerPowerOperations/ServerPowerOperations.vue new file mode 100644 index 00000000..9e030837 --- /dev/null +++ b/src/views/Operations/ServerPowerOperations/ServerPowerOperations.vue @@ -0,0 +1,260 @@ +<template> + <b-container fluid="xl"> + <page-title /> + <b-row class="mb-4"> + <b-col md="8" xl="6"> + <page-section + :section-title="$t('pageServerPowerOperations.currentStatus')" + > + <b-row> + <b-col> + <dl> + <dt>{{ $t('pageServerPowerOperations.serverStatus') }}</dt> + <dd + v-if="serverStatus === 'on'" + data-test-id="powerServerOps-text-hostStatus" + > + {{ $t('global.status.on') }} + </dd> + <dd + v-else-if="serverStatus === 'off'" + data-test-id="powerServerOps-text-hostStatus" + > + {{ $t('global.status.off') }} + </dd> + <dd v-else> + {{ $t('global.status.notAvailable') }} + </dd> + </dl> + </b-col> + </b-row> + <b-row> + <b-col> + <dl> + <dt> + {{ $t('pageServerPowerOperations.lastPowerOperation') }} + </dt> + <dd + v-if="lastPowerOperationTime" + data-test-id="powerServerOps-text-lastPowerOp" + > + {{ lastPowerOperationTime | formatDate }} + {{ lastPowerOperationTime | formatTime }} + </dd> + <dd v-else>--</dd> + </dl> + </b-col> + </b-row> + </page-section> + </b-col> + </b-row> + <b-row> + <b-col v-if="hasBootSourceOptions" sm="8" md="6" xl="4"> + <page-section + :section-title="$t('pageServerPowerOperations.serverBootSettings')" + > + <boot-settings /> + </page-section> + </b-col> + <b-col sm="8" md="6" xl="7"> + <page-section + :section-title="$t('pageServerPowerOperations.operations')" + > + <alert :show="oneTimeBootEnabled" variant="warning"> + {{ $t('pageServerPowerOperations.oneTimeBootWarning') }} + </alert> + <template v-if="isOperationInProgress"> + <alert variant="info"> + {{ $t('pageServerPowerOperations.operationInProgress') }} + </alert> + </template> + <template v-else-if="serverStatus === 'off'"> + <b-button + variant="primary" + data-test-id="serverPowerOperations-button-powerOn" + @click="powerOn" + > + {{ $t('pageServerPowerOperations.powerOn') }} + </b-button> + </template> + <template v-else> + <!-- Reboot server options --> + <b-form novalidate class="mb-5" @submit.prevent="rebootServer"> + <b-form-group + :label="$t('pageServerPowerOperations.rebootServer')" + > + <b-form-radio + v-model="form.rebootOption" + name="reboot-option" + data-test-id="serverPowerOperations-radio-rebootOrderly" + value="orderly" + > + {{ $t('pageServerPowerOperations.orderlyReboot') }} + </b-form-radio> + <b-form-radio + v-model="form.rebootOption" + name="reboot-option" + data-test-id="serverPowerOperations-radio-rebootImmediate" + value="immediate" + > + {{ $t('pageServerPowerOperations.immediateReboot') }} + </b-form-radio> + </b-form-group> + <b-button + variant="primary" + type="submit" + data-test-id="serverPowerOperations-button-reboot" + > + {{ $t('pageServerPowerOperations.reboot') }} + </b-button> + </b-form> + <!-- Shutdown server options --> + <b-form novalidate @submit.prevent="shutdownServer"> + <b-form-group + :label="$t('pageServerPowerOperations.shutdownServer')" + > + <b-form-radio + v-model="form.shutdownOption" + name="shutdown-option" + data-test-id="serverPowerOperations-radio-shutdownOrderly" + value="orderly" + > + {{ $t('pageServerPowerOperations.orderlyShutdown') }} + </b-form-radio> + <b-form-radio + v-model="form.shutdownOption" + name="shutdown-option" + data-test-id="serverPowerOperations-radio-shutdownImmediate" + value="immediate" + > + {{ $t('pageServerPowerOperations.immediateShutdown') }} + </b-form-radio> + </b-form-group> + <b-button + variant="primary" + type="submit" + data-test-id="serverPowerOperations-button-shutDown" + > + {{ $t('pageServerPowerOperations.shutDown') }} + </b-button> + </b-form> + </template> + </page-section> + </b-col> + </b-row> + </b-container> +</template> + +<script> +import PageTitle from '@/components/Global/PageTitle'; +import PageSection from '@/components/Global/PageSection'; +import BVToastMixin from '@/components/Mixins/BVToastMixin'; +import BootSettings from './BootSettings'; +import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin'; +import Alert from '@/components/Global/Alert'; + +export default { + name: 'ServerPowerOperations', + components: { PageTitle, PageSection, BootSettings, Alert }, + mixins: [BVToastMixin, LoadingBarMixin], + beforeRouteLeave(to, from, next) { + this.hideLoader(); + next(); + }, + data() { + return { + form: { + rebootOption: 'orderly', + shutdownOption: 'orderly', + }, + }; + }, + computed: { + serverStatus() { + return this.$store.getters['global/serverStatus']; + }, + isOperationInProgress() { + return this.$store.getters['controls/isOperationInProgress']; + }, + lastPowerOperationTime() { + return this.$store.getters['controls/lastPowerOperationTime']; + }, + oneTimeBootEnabled() { + return this.$store.getters['serverBootSettings/overrideEnabled']; + }, + hasBootSourceOptions() { + let bootOptions = this.$store.getters[ + 'serverBootSettings/bootSourceOptions' + ]; + return bootOptions.length !== 0; + }, + }, + created() { + this.startLoader(); + const bootSettingsPromise = new Promise((resolve) => { + this.$root.$on('server-power-operations-boot-settings-complete', () => + resolve() + ); + }); + Promise.all([ + this.$store.dispatch('serverBootSettings/getBootSettings'), + this.$store.dispatch('controls/getLastPowerOperationTime'), + bootSettingsPromise, + ]).finally(() => this.endLoader()); + }, + methods: { + powerOn() { + this.$store.dispatch('controls/serverPowerOn'); + }, + rebootServer() { + const modalMessage = this.$t( + 'pageServerPowerOperations.modal.confirmRebootMessage' + ); + const modalOptions = { + title: this.$t('pageServerPowerOperations.modal.confirmRebootTitle'), + okTitle: this.$t('global.action.confirm'), + cancelTitle: this.$t('global.action.cancel'), + }; + + if (this.form.rebootOption === 'orderly') { + this.$bvModal + .msgBoxConfirm(modalMessage, modalOptions) + .then((confirmed) => { + if (confirmed) this.$store.dispatch('controls/serverSoftReboot'); + }); + } else if (this.form.rebootOption === 'immediate') { + this.$bvModal + .msgBoxConfirm(modalMessage, modalOptions) + .then((confirmed) => { + if (confirmed) this.$store.dispatch('controls/serverHardReboot'); + }); + } + }, + shutdownServer() { + const modalMessage = this.$t( + 'pageServerPowerOperations.modal.confirmShutdownMessage' + ); + const modalOptions = { + title: this.$t('pageServerPowerOperations.modal.confirmShutdownTitle'), + okTitle: this.$t('global.action.confirm'), + cancelTitle: this.$t('global.action.cancel'), + }; + + if (this.form.shutdownOption === 'orderly') { + this.$bvModal + .msgBoxConfirm(modalMessage, modalOptions) + .then((confirmed) => { + if (confirmed) this.$store.dispatch('controls/serverSoftPowerOff'); + }); + } + if (this.form.shutdownOption === 'immediate') { + this.$bvModal + .msgBoxConfirm(modalMessage, modalOptions) + .then((confirmed) => { + if (confirmed) this.$store.dispatch('controls/serverHardPowerOff'); + }); + } + }, + }, +}; +</script> diff --git a/src/views/Operations/ServerPowerOperations/index.js b/src/views/Operations/ServerPowerOperations/index.js new file mode 100644 index 00000000..10430047 --- /dev/null +++ b/src/views/Operations/ServerPowerOperations/index.js @@ -0,0 +1,2 @@ +import ServerPowerOperations from './ServerPowerOperations.vue'; +export default ServerPowerOperations; |